<commit_before>// Copyright (C) 2011-2018 Roki. Distributed under the MIT License
#ifndef INCLUDED_SROOK_TMPL_VT_DETAIL_CONFIG_HPP
#define INCLUDED_SROOK_TMPL_VT_DETAIL_CONFIG_HPP

#include <srook/config.hpp>
#ifdef SROOK_CPP_VARIADIC_TEMPLATES
#if SROOK_HAS_INCLUDE(<tuple>)
#   include <tuple>
#   ifndef SROOK_HAS_STD_TUPLE
#       define SROOK_HAS_STD_TUPLE 1
#   endif
#elif SROOK_HAS_INCLUDE(<boost/tuple/tuple.hpp>)
#   include <boost/tuple/tuple.hpp>
#   ifndef SROOK_HAS_BOOST_TUPLE
#       define SROOK_HAS_BOOST_TUPLE 1
#   endif
#endif
#if !defined(BOOST_TYPE_INDEX_HPP) && SROOK_HAS_INCLUDE(<boost/type_index.hpp>)
#   include <boost/type_index.hpp>
#   include <string>
#   define SROOK_HAS_BOOST_TYPE_INDEX 1
#endif
#if defined(BOOST_TYPE_INDEX_HPP) && !defined(SROOK_HAS_BOOST_TYPE_INDEX)
#   define SROOK_HAS_BOOST_TYPE_INDEX 1
#endif

#include <srook/mpl/variadic_types.hpp>
#include <srook/type_traits/type_constant.hpp>
#include <srook/utility/index_sequence.hpp>
#include <srook/type_traits/integral_constant.hpp>
#include <srook/iterator/ostream_joiner.hpp>
#include <utility>

#if SROOK_CPLUSPLUS >= SROOK_CPLUSPLUS17_CONSTANT && SROOK_CPP_TEMPLATE_AUTO
#   include <srook/cxx17/mpl/any_pack.hpp>
#endif
#if !SROOK_CPP_FOLD_EXPRESSIONS
#   include <srook/mpl/constant_sequence/algorithm/reverse.hpp>
#endif

namespace srook {
namespace tmpl {
namespace vt {
SROOK_INLINE_NAMESPACE(v1)
namespace detail {

using srook::variadic_types::detail::At;
using srook::variadic_types::detail::Concat;
using srook::variadic_types::detail::Erase;
using srook::variadic_types::detail::EraseAll;
using srook::variadic_types::detail::First;
using srook::variadic_types::detail::IndexOf;
using srook::variadic_types::is_contained_in;
using srook::variadic_types::detail::Last;
using srook::variadic_types::detail::Length;
using srook::variadic_types::detail::NoDuplicate;
using srook::variadic_types::detail::PartialHead;
using srook::variadic_types::detail::PartialTail;
using srook::variadic_types::detail::PopBack;
using srook::variadic_types::detail::PopFront;
using srook::variadic_types::detail::Replace;
using srook::variadic_types::detail::ReplaceAll;
using srook::variadic_types::detail::Reverse;
using srook::variadic_types::detail::Size;
using srook::SwapAt_L_type;
using srook::SwapAt_R_type;
using srook::SwapAt_Specified_L_type;
using srook::SwapAt_Specified_R_type;
using srook::variadic_types::detail::Transfer;

} // namespace detail

// Inspired by N4115
template <class T>
struct packer_base {
protected:
#ifdef SROOK_HAS_BOOST_TYPE_INDEX
    SROOK_FORCE_INLINE static std::string& pretty_name()
    {
        static std::string name(boost::typeindex::type_id<T>().pretty_name());
        return name;
    }
#endif
};

template <class... Ts>
struct packer
    : public srook::pack<Ts...>
    , protected packer_base<packer<Ts...>>
#if SROOK_HAS_STD_TUPLE
    , public std::tuple<Ts...>
#elif SROOK_HAS_BOOST_TUPLE
    , public boost::tuple<Ts...>
#endif
{
#if SROOK_HAS_STD_TUPLE
    typedef std::tuple<Ts...> base_type;
    using base_type::base_type;
    using base_type::operator=;
    using base_type::swap;
#elif SROOK_HAS_BOOST_TUPLE
    typedef boost::tuple<Ts...> base_type;
    using base_type::base_type;
#else
    typedef void base_type;
#endif

#ifdef SROOK_HAS_BOOST_TYPE_INDEX
    using packer_base<packer<Ts...>>::pretty_name;
#endif
};

template <class Integral, Integral x>
struct packer<srook::integral_constant<Integral, x>>
    : protected packer_base<packer<srook::integral_constant<Integral, x>>> {
        typedef srook::integral_constant<Integral, x> pack_type;
#ifdef SROOK_HAS_BOOST_TYPE_INDEX
        using packer_base<packer<srook::integral_constant<Integral, x>>>::pretty_name;
#endif
        SROOK_FORCE_INLINE friend std::ostream& operator<<(std::ostream& os, const packer<srook::integral_constant<Integral, x>>&)
        {
            return os << x;
        }
};

#if !SROOK_CPP_FOLD_EXPRESSIONS
template <class T, class Integral, Integral... val>
SROOK_FORCE_INLINE void output_impl(srook::ostream_joiner<T>& os, const std::integer_sequence<Integral, val...>&)
{
#if SROOK_CPP_LAMBDAS
    [](...){}([](srook::ostream_joiner<T>& j, Integral v) -> srook::ostream_joiner<T>& { return j = v; }(os, val)...);
#else
    struct jt {
        SROOK_FORCE_INLINE jt(srook::ostream_joiner<char*>& oi, Integral x) { oi = x; }
    };
    struct nothingtodo { SROOK_CONSTEXPR SROOK_FORCE_INLINE nothingtodo(...) {} } ntd(jt(os, val)...);
#endif
}
#endif
template <class Integral, Integral... val>
SROOK_FORCE_INLINE std::ostream& operator<<(std::ostream& os, const packer<srook::utility::integer_sequence<Integral, val...>>&)
{
    srook::ostream_joiner<char*> joiner(os, ",");
#if SROOK_CPP_FOLD_EXPRESSIONS
    ((joiner = val), ...);
    return os;
#else
    typedef SROOK_DEDUCED_TYPENAME srook::constant_sequence::reverse<std::integer_sequence<Integral, val...>>::type revtype;
    output_impl(joiner, revtype());
    return os;
#endif
}

template <class Integral, Integral... val>
struct packer<srook::utility::integer_sequence<Integral, val...>>
    : protected packer_base<packer<srook::utility::integer_sequence<Integral, val...>>> {
    typedef srook::utility::integer_sequence<Integral, val...> pack_type;
#ifdef SROOK_HAS_BOOST_TYPE_INDEX
    using packer_base<packer<srook::utility::integer_sequence<Integral, val...>>>::pretty_name;
#endif
};

#if SROOK_CPLUSPLUS >= SROOK_CPLUSPLUS17_CONSTANT && SROOK_CPP_TEMPLATE_AUTO
template <auto... vals>
struct packer<srook::vmpl::any_pack<vals...>>
    : protected packer_base<packer<srook::vmpl::any_pack<vals...>>> {
    typedef srook::vmpl::any_pack<vals...> pack_type;
#ifdef SROOK_HAS_BOOST_TYPE_INDEX
    using packer_base<packer<srook::vmpl::any_pack<vals...>>>::pretty_name;
#endif
};
#if !SROOK_CPP_FOLD_EXPRESSIONS
struct nofold_lambda {
    template <class CharType, class T, class... Ts>
    SROOK_FORCE_INLINE static void dojoin(srook::ostream_joiner<CharType>& os, T&& x, Ts&&... val)
    {
        dojoin(os = x, srook::forward<Ts>(val)...);
    }
    template <class CharType>
    SROOK_FORCE_INLINE static void dojoin(srook::ostream_joiner<CharType>&) {}
};
#endif

template <auto... val>
SROOK_FORCE_INLINE std::ostream& operator<<(std::ostream& os, const packer<srook::vmpl::any_pack<val...>>&)
{
    srook::ostream_joiner<char*> joiner(os, ",");
#if SROOK_CPP_FOLD_EXPRESSIONS
    ((joiner = val), ...);
    return os;
#else
    nofold::dojoin(joiner, val...);
    return os;
#endif
}
#endif

#if SROOK_CPP_DEDUCTION_GUIDES
template <class... Ts> packer(Ts...) -> packer<Ts...>;
template <class L, class R> packer(std::pair<L, R>) -> packer<L, R>;
template <class Alloc, class... Ts> packer(std::allocator_arg_t, Alloc, Ts...) -> packer<Ts...>;
template <class Alloc, class L, class R> packer(std::allocator_arg_t, Alloc, std::pair<L, R>) -> packer<L, R>;
template <class Alloc, class... Ts> packer(std::allocator_arg_t, Alloc, packer<Ts...>) -> packer<Ts...>;

#if SROOK_HAS_STD_TUPLE
template <class Alloc, class... Ts> packer(std::allocator_arg_t, Alloc, std::tuple<Ts...>) -> packer<Ts...>;
#elif SROOK_HAS_BOOST_TUPLE
template <class Alloc, class... Ts> packer(std::allocator_arg_t, Alloc, boost::tuple<Ts...>) -> packer<Ts...>;
#endif
#endif

SROOK_INLINE_NAMESPACE_END
} // namespace vt
} // namespace tmpl
} // namespace srook

#else
#   error This feature needs to support variadic templates
#endif
#endif
<commit_msg>add specializing for index_sequence<commit_after>// Copyright (C) 2011-2018 Roki. Distributed under the MIT License
#ifndef INCLUDED_SROOK_TMPL_VT_DETAIL_CONFIG_HPP
#define INCLUDED_SROOK_TMPL_VT_DETAIL_CONFIG_HPP

#include <srook/config.hpp>
#ifdef SROOK_CPP_VARIADIC_TEMPLATES
#if SROOK_HAS_INCLUDE(<tuple>)
#   include <tuple>
#   ifndef SROOK_HAS_STD_TUPLE
#       define SROOK_HAS_STD_TUPLE 1
#   endif
#elif SROOK_HAS_INCLUDE(<boost/tuple/tuple.hpp>)
#   include <boost/tuple/tuple.hpp>
#   ifndef SROOK_HAS_BOOST_TUPLE
#       define SROOK_HAS_BOOST_TUPLE 1
#   endif
#endif
#if !defined(BOOST_TYPE_INDEX_HPP) && SROOK_HAS_INCLUDE(<boost/type_index.hpp>)
#   include <boost/type_index.hpp>
#   include <string>
#   define SROOK_HAS_BOOST_TYPE_INDEX 1
#endif
#if defined(BOOST_TYPE_INDEX_HPP) && !defined(SROOK_HAS_BOOST_TYPE_INDEX)
#   define SROOK_HAS_BOOST_TYPE_INDEX 1
#endif

#include <srook/mpl/variadic_types.hpp>
#include <srook/type_traits/type_constant.hpp>
#include <srook/utility/index_sequence.hpp>
#include <srook/type_traits/integral_constant.hpp>
#include <srook/iterator/ostream_joiner.hpp>
#include <utility>

#if SROOK_CPLUSPLUS >= SROOK_CPLUSPLUS17_CONSTANT && SROOK_CPP_TEMPLATE_AUTO
#   include <srook/cxx17/mpl/any_pack.hpp>
#endif
#if !SROOK_CPP_FOLD_EXPRESSIONS
#   include <srook/mpl/constant_sequence/algorithm/reverse.hpp>
#endif

namespace srook {
namespace tmpl {
namespace vt {
SROOK_INLINE_NAMESPACE(v1)
namespace detail {

using srook::variadic_types::detail::At;
using srook::variadic_types::detail::Concat;
using srook::variadic_types::detail::Erase;
using srook::variadic_types::detail::EraseAll;
using srook::variadic_types::detail::First;
using srook::variadic_types::detail::IndexOf;
using srook::variadic_types::is_contained_in;
using srook::variadic_types::detail::Last;
using srook::variadic_types::detail::Length;
using srook::variadic_types::detail::NoDuplicate;
using srook::variadic_types::detail::PartialHead;
using srook::variadic_types::detail::PartialTail;
using srook::variadic_types::detail::PopBack;
using srook::variadic_types::detail::PopFront;
using srook::variadic_types::detail::Replace;
using srook::variadic_types::detail::ReplaceAll;
using srook::variadic_types::detail::Reverse;
using srook::variadic_types::detail::Size;
using srook::SwapAt_L_type;
using srook::SwapAt_R_type;
using srook::SwapAt_Specified_L_type;
using srook::SwapAt_Specified_R_type;
using srook::variadic_types::detail::Transfer;

} // namespace detail

// Inspired by N4115
template <class T>
struct packer_base {
protected:
#ifdef SROOK_HAS_BOOST_TYPE_INDEX
    SROOK_FORCE_INLINE static std::string& pretty_name()
    {
        static std::string name(boost::typeindex::type_id<T>().pretty_name());
        return name;
    }
#endif
};

template <class... Ts>
struct packer
    : public srook::pack<Ts...>
    , protected packer_base<packer<Ts...>>
#if SROOK_HAS_STD_TUPLE
    , public std::tuple<Ts...>
#elif SROOK_HAS_BOOST_TUPLE
    , public boost::tuple<Ts...>
#endif
{
#if SROOK_HAS_STD_TUPLE
    typedef std::tuple<Ts...> base_type;
    using base_type::base_type;
    using base_type::operator=;
    using base_type::swap;
#elif SROOK_HAS_BOOST_TUPLE
    typedef boost::tuple<Ts...> base_type;
    using base_type::base_type;
#else
    typedef void base_type;
#endif

#ifdef SROOK_HAS_BOOST_TYPE_INDEX
    using packer_base<packer<Ts...>>::pretty_name;
#endif
};

template <class Integral, Integral x>
struct packer<srook::integral_constant<Integral, x>>
    : protected packer_base<packer<srook::integral_constant<Integral, x>>> {
        typedef srook::integral_constant<Integral, x> pack_type;
#ifdef SROOK_HAS_BOOST_TYPE_INDEX
        using packer_base<packer<srook::integral_constant<Integral, x>>>::pretty_name;
#endif
        SROOK_FORCE_INLINE friend std::ostream& operator<<(std::ostream& os, const packer<srook::integral_constant<Integral, x>>&)
        {
            return os << x;
        }
};

#if !SROOK_CPP_FOLD_EXPRESSIONS
template <class T, class Integral, Integral... val>
SROOK_FORCE_INLINE void output_impl(srook::ostream_joiner<T>& os, const std::integer_sequence<Integral, val...>&)
{
#if SROOK_CPP_LAMBDAS
    [](...){}([](srook::ostream_joiner<T>& j, Integral v) -> srook::ostream_joiner<T>& { return j = v; }(os, val)...);
#else
    struct jt {
        SROOK_FORCE_INLINE jt(srook::ostream_joiner<char*>& oi, Integral x) { oi = x; }
    };
    struct nothingtodo { SROOK_CONSTEXPR SROOK_FORCE_INLINE nothingtodo(...) {} } ntd(jt(os, val)...);
#endif
}
#endif

#if SROOK_CPP_FOLD_EXPRESSIONS
#define SROOK_DEF_OUTPUT_SHIFT(NAMESPACE)\
    template <class Integral, Integral... val>\
    SROOK_FORCE_INLINE std::ostream& operator<<(std::ostream& os, const packer<NAMESPACE::integer_sequence<Integral, val...>>&)\
    {\
        srook::ostream_joiner<char*> joiner(os, ",");\
        ((joiner = val), ...);\
        return os;\
    }
#else
#define SROOK_DEF_OUTPUT_SHIFT(NAMESPACE)\
    template <class Integral, Integral... val>\
    SROOK_FORCE_INLINE std::ostream& operator<<(std::ostream& os, const packer<NAMESPACE::integer_sequence<Integral, val...>>&)\
    {\
        srook::ostream_joiner<char*> joiner(os, ",");\
        typedef SROOK_DEDUCED_TYPENAME srook::constant_sequence::reverse<std::integer_sequence<Integral, val...>>::type revtype;\
        output_impl(joiner, revtype());\
        return os;\
    }
#endif

SROOK_DEF_OUTPUT_SHIFT(srook::utility)
SROOK_DEF_OUTPUT_SHIFT(std)
#undef SROOK_DEF_OUTPUT_SHIFT

template <class Integral, Integral... val>
struct packer<srook::utility::integer_sequence<Integral, val...>>
    : protected packer_base<packer<srook::utility::integer_sequence<Integral, val...>>> {
    typedef srook::utility::integer_sequence<Integral, val...> pack_type;
#ifdef SROOK_HAS_BOOST_TYPE_INDEX
    using packer_base<packer<srook::utility::integer_sequence<Integral, val...>>>::pretty_name;
#endif
};

template <class Integral, Integral... val>
struct packer<std::integer_sequence<Integral, val...>>
    : protected packer_base<packer<std::integer_sequence<Integral, val...>>> {
    typedef std::integer_sequence<Integral, val...> pack_type;
#ifdef SROOK_HAS_BOOST_TYPE_INDEX
    using packer_base<packer<std::integer_sequence<Integral, val...>>>::pretty_name;
#endif
};

#if SROOK_CPLUSPLUS >= SROOK_CPLUSPLUS17_CONSTANT && SROOK_CPP_TEMPLATE_AUTO
template <auto... vals>
struct packer<srook::vmpl::any_pack<vals...>>
    : protected packer_base<packer<srook::vmpl::any_pack<vals...>>> {
    typedef srook::vmpl::any_pack<vals...> pack_type;
#ifdef SROOK_HAS_BOOST_TYPE_INDEX
    using packer_base<packer<srook::vmpl::any_pack<vals...>>>::pretty_name;
#endif
};
#if !SROOK_CPP_FOLD_EXPRESSIONS
struct nofold_lambda {
    template <class CharType, class T, class... Ts>
    SROOK_FORCE_INLINE static void dojoin(srook::ostream_joiner<CharType>& os, T&& x, Ts&&... val)
    {
        dojoin(os = x, srook::forward<Ts>(val)...);
    }
    template <class CharType>
    SROOK_FORCE_INLINE static void dojoin(srook::ostream_joiner<CharType>&) {}
};
#endif

template <auto... val>
SROOK_FORCE_INLINE std::ostream& operator<<(std::ostream& os, const packer<srook::vmpl::any_pack<val...>>&)
{
    srook::ostream_joiner<char*> joiner(os, ",");
#if SROOK_CPP_FOLD_EXPRESSIONS
    ((joiner = val), ...);
    return os;
#else
    nofold::dojoin(joiner, val...);
    return os;
#endif
}
#endif

#if SROOK_CPP_DEDUCTION_GUIDES
template <class... Ts> packer(Ts...) -> packer<Ts...>;
template <class L, class R> packer(std::pair<L, R>) -> packer<L, R>;
template <class Alloc, class... Ts> packer(std::allocator_arg_t, Alloc, Ts...) -> packer<Ts...>;
template <class Alloc, class L, class R> packer(std::allocator_arg_t, Alloc, std::pair<L, R>) -> packer<L, R>;
template <class Alloc, class... Ts> packer(std::allocator_arg_t, Alloc, packer<Ts...>) -> packer<Ts...>;

#if SROOK_HAS_STD_TUPLE
template <class Alloc, class... Ts> packer(std::allocator_arg_t, Alloc, std::tuple<Ts...>) -> packer<Ts...>;
#elif SROOK_HAS_BOOST_TUPLE
template <class Alloc, class... Ts> packer(std::allocator_arg_t, Alloc, boost::tuple<Ts...>) -> packer<Ts...>;
#endif
#endif

SROOK_INLINE_NAMESPACE_END
} // namespace vt
} // namespace tmpl
} // namespace srook

#else
#   error This feature needs to support variadic templates
#endif
#endif
<|endoftext|>


<commit_before>//======================================================================//
// Copyright (C) 2016-2018 Jonathan Müller <jonathanmueller.dev@gmail.com>
//
// This software is provided 'as-is', without any express or
// implied warranty. In no event will the authors be held
// liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute
// it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but
//    is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any
//    source distribution.
//======================================================================//

#ifndef DEBUG_ASSERT_HPP_INCLUDED
#define DEBUG_ASSERT_HPP_INCLUDED

#include <cstdlib>

#ifndef DEBUG_ASSERT_NO_STDIO
#    include <cstdio>
#endif

#ifndef DEBUG_ASSERT_MARK_UNREACHABLE
#    ifdef __GNUC__
#        define DEBUG_ASSERT_MARK_UNREACHABLE __builtin_unreachable()
#    elif defined(_MSC_VER)
#        define DEBUG_ASSERT_MARK_UNREACHABLE __assume(0)
#    else
/// Hint to the compiler that a code branch is unreachable.
/// Define it yourself prior to including the header to override it.
/// \notes This must be usable in an expression.
#        define DEBUG_ASSERT_MARK_UNREACHABLE
#    endif
#endif

#ifndef DEBUG_ASSERT_FORCE_INLINE
#    ifdef __GNUC__
#        define DEBUG_ASSERT_FORCE_INLINE [[gnu::always_inline]] inline
#    elif defined(_MSC_VER)
#        define DEBUG_ASSERT_FORCE_INLINE __forceinline
#    else
/// Strong hint to the compiler to inline a function.
/// Define it yourself prior to including the header to override it.
#        define DEBUG_ASSERT_FORCE_INLINE inline
#    endif
#endif

namespace debug_assert
{
//=== source location ===//
/// Defines a location in the source code.
struct source_location
{
    const char* file_name;   ///< The file name.
    unsigned    line_number; ///< The line number.
};

/// Expands to the current [debug_assert::source_location]().
#define DEBUG_ASSERT_CUR_SOURCE_LOCATION                                                           \
    debug_assert::source_location                                                                  \
    {                                                                                \
        __FILE__, static_cast<unsigned>(__LINE__)                                                  \
    }

//=== level ===//
/// Tag type to indicate the level of an assertion.
template <unsigned Level>
struct level
{};

/// Helper class that sets a certain level.
/// Inherit from it in your module handler.
template <unsigned Level>
struct set_level
{
    static const unsigned level = Level;
};

template <unsigned Level>
const unsigned set_level<Level>::level;

/// Helper class that controls whether the handler can throw or not.
/// Inherit from it in your module handler.
/// If the module does not inherit from this class, it is assumed that
/// the handle does not throw.
struct allow_exception
{
    static const bool throwing_exception_is_allowed = true;
};

//=== handler ===//
/// Does not do anything to handle a failed assertion (except calling
/// [std::abort()]()).
/// Inherit from it in your module handler.
struct no_handler
{
    /// \effects Does nothing.
    /// \notes Can take any additional arguments.
    template <typename... Args>
    static void handle(const source_location&, const char*, Args&&...) noexcept
    {}
};

/// The default handler that writes a message to `stderr`.
/// Inherit from it in your module handler.
struct default_handler
{
    /// \effects Prints a message to `stderr`.
    /// \notes It can optionally accept an additional message string.
    /// \notes If `DEBUG_ASSERT_NO_STDIO` is defined, it will do nothing.
    static void handle(const source_location& loc, const char* expression,
                       const char* message = nullptr) noexcept
    {
#ifndef DEBUG_ASSERT_NO_STDIO
        if (*expression == '\0')
        {
            if (message)
                std::fprintf(stderr, "[debug assert] %s:%u: Unreachable code reached - %s.\n",
                             loc.file_name, loc.line_number, message);
            else
                std::fprintf(stderr, "[debug assert] %s:%u: Unreachable code reached.\n",
                             loc.file_name, loc.line_number);
        }
        else if (message)
            std::fprintf(stderr, "[debug assert] %s:%u: Assertion '%s' failed - %s.\n",
                         loc.file_name, loc.line_number, expression, message);
        else
            std::fprintf(stderr, "[debug assert] %s:%u: Assertion '%s' failed.\n", loc.file_name,
                         loc.line_number, expression);
#else
        (void)loc;
        (void)expression;
        (void)message;
#endif
    }
};

/// \exclude
namespace detail
{
    //=== boilerplate ===//
    // from http://en.cppreference.com/w/cpp/types/remove_reference
    template <typename T>
    struct remove_reference
    {
        using type = T;
    };

    template <typename T>
    struct remove_reference<T&>
    {
        using type = T;
    };

    template <typename T>
    struct remove_reference<T&&>
    {
        using type = T;
    };

    // from http://stackoverflow.com/a/27501759
    template <class T>
    T&& forward(typename remove_reference<T>::type& t)
    {
        return static_cast<T&&>(t);
    }

    template <class T>
    T&& forward(typename remove_reference<T>::type&& t)
    {
        return static_cast<T&&>(t);
    }

    template <bool Value, typename T = void>
    struct enable_if;

    template <typename T>
    struct enable_if<true, T>
    {
        using type = T;
    };

    template <typename T>
    struct enable_if<false, T>
    {};

    //=== helper class to check if throw is allowed ===//
    template <class Handler, typename = void>
    struct allows_exception
    {
        static const bool value = false;
    };

    template <class Handler>
    struct allows_exception<Handler,
                            typename enable_if<Handler::throwing_exception_is_allowed>::type>
    {
        static const bool value = Handler::throwing_exception_is_allowed;
    };

    //=== regular void fake ===//
    struct regular_void
    {
        constexpr regular_void() = default;

        // enable conversion to anything
        // conversion must not actually be used
        template <typename T>
        constexpr operator T&() const noexcept
        {
            // doesn't matter how to get the T
            return DEBUG_ASSERT_MARK_UNREACHABLE, *static_cast<T*>(nullptr);
        }
    };

    //=== assert implementation ===//
    // function name will be shown on constexpr assertion failure
    template <class Handler, typename... Args>
    regular_void debug_assertion_failed(const source_location& loc, const char* expression,
                                        Args&&... args)
    {
        return Handler::handle(loc, expression, detail::forward<Args>(args)...), std::abort(),
               regular_void();
    }

    // use enable if instead of tag dispatching
    // this removes on additional function and encourage optimization
    template <class Expr, class Handler, unsigned Level, typename... Args>
    constexpr auto do_assert(
        const Expr& expr, const source_location& loc, const char* expression, Handler, level<Level>,
        Args&&... args) noexcept(!allows_exception<Handler>::value
                                 || noexcept(Handler::handle(loc, expression,
                                                             detail::forward<Args>(args)...))) ->
        typename enable_if<Level <= Handler::level, regular_void>::type
    {
        static_assert(Level > 0, "level of an assertion must not be 0");
        return expr() ? regular_void()
                      : debug_assertion_failed<Handler>(loc, expression,
                                                        detail::forward<Args>(args)...);
    }

    template <class Expr, class Handler, unsigned Level, typename... Args>
    DEBUG_ASSERT_FORCE_INLINE constexpr auto do_assert(const Expr&, const source_location&,
                                                       const char*, Handler, level<Level>,
                                                       Args&&...) noexcept ->
        typename enable_if<(Level > Handler::level), regular_void>::type
    {
        return regular_void();
    }

    template <class Expr, class Handler, typename... Args>
    constexpr auto do_assert(
        const Expr& expr, const source_location& loc, const char* expression, Handler,
        Args&&... args) noexcept(!allows_exception<Handler>::value
                                 || noexcept(Handler::handle(loc, expression,
                                                             detail::forward<Args>(args)...))) ->
        typename enable_if<Handler::level != 0, regular_void>::type
    {
        return expr() ? regular_void()
                      : debug_assertion_failed<Handler>(loc, expression,
                                                        detail::forward<Args>(args)...);
    }

    template <class Expr, class Handler, typename... Args>
    DEBUG_ASSERT_FORCE_INLINE constexpr auto do_assert(const Expr&, const source_location&,
                                                       const char*, Handler, Args&&...) noexcept ->
        typename enable_if<Handler::level == 0, regular_void>::type
    {
        return regular_void();
    }

    constexpr bool always_false() noexcept
    {
        return false;
    }
} // namespace detail
} // namespace debug_assert

//=== assertion macros ===//
#ifndef DEBUG_ASSERT_DISABLE
/// The assertion macro.
//
/// Usage: `DEBUG_ASSERT(<expr>, <handler>, [<level>],
/// [<handler-specific-args>].
/// Where:
/// * `<expr>` - the expression to check for, the expression `!<expr>` must be
/// well-formed and contextually convertible to `bool`.
/// * `<handler>` - an object of the module specific handler
/// * `<level>` (optional, defaults to `1`) - the level of the assertion, must
/// be an object of type [debug_assert::level<Level>]().
/// * `<handler-specific-args>` (optional) - any additional arguments that are
/// just forwarded to the handler function.
///
/// It will only check the assertion if `<level>` is less than or equal to
/// `Handler::level`.
/// A failed assertion will call: `Handler::handle(location, expression, args)`.
/// `location` is the [debug_assert::source_location]() at the macro expansion,
/// `expression` is the stringified expression and `args` are the
/// `<handler-specific-args>` as-is.
/// If the handler function returns, it will call [std::abort()].
///
/// The macro will expand to a `void` expression.
///
/// \notes Define `DEBUG_ASSERT_DISABLE` to completely disable this macro, it
/// will expand to nothing.
/// This should not be necessary, the regular version is optimized away
/// completely.
#    define DEBUG_ASSERT(Expr, ...)                                                                \
        static_cast<void>(debug_assert::detail::do_assert(                                         \
            [&]() noexcept { return Expr; }, DEBUG_ASSERT_CUR_SOURCE_LOCATION, #Expr,              \
            __VA_ARGS__))

/// Marks a branch as unreachable.
///
/// Usage: `DEBUG_UNREACHABLE(<handler>, [<level>], [<handler-specific-args>])`
/// Where:
/// * `<handler>` - an object of the module specific handler
/// * `<level>` (optional, defaults to `1`) - the level of the assertion, must
/// be an object of type [debug_assert::level<Level>]().
/// * `<handler-specific-args>` (optional) - any additional arguments that are
/// just forwarded to the handler function.
///
/// It will only check the assertion if `<level>` is less than or equal to
/// `Handler::level`.
/// A failed assertion will call: `Handler::handle(location, "", args)`.
/// and `args` are the `<handler-specific-args>` as-is.
/// If the handler function returns, it will call [std::abort()].
///
/// This macro is also usable in a constant expression,
/// i.e. you can use it in a `constexpr` function to verify a condition like so:
/// `cond(val) ? do_sth(val) : DEBUG_UNREACHABLE(…)`.
/// You can't use `DEBUG_ASSERT` there.
///
/// The macro will expand to an expression convertible to any type,
/// although the resulting object is invalid,
/// which doesn't matter, as the statement is unreachable anyway.
///
/// \notes Define `DEBUG_ASSERT_DISABLE` to completely disable this macro, it
/// will expand to `DEBUG_ASSERT_MARK_UNREACHABLE`.
/// This should not be necessary, the regular version is optimized away
/// completely.
#    define DEBUG_UNREACHABLE(...)                                                                 \
        debug_assert::detail::do_assert(debug_assert::detail::always_false,                        \
                                        DEBUG_ASSERT_CUR_SOURCE_LOCATION, "", __VA_ARGS__)
#else
#    define DEBUG_ASSERT(Expr, ...) static_cast<void>(0)

#    define DEBUG_UNREACHABLE(...)                                                                 \
        (DEBUG_ASSERT_MARK_UNREACHABLE, debug_assert::detail::regular_void())
#endif

#endif // DEBUG_ASSERT_HPP_INCLUDED
<commit_msg>Update debug_assert<commit_after>//======================================================================//
// Copyright (C) 2016-2018 Jonathan Müller <jonathanmueller.dev@gmail.com>
//
// This software is provided 'as-is', without any express or
// implied warranty. In no event will the authors be held
// liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute
// it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but
//    is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any
//    source distribution.
//======================================================================//

#ifndef DEBUG_ASSERT_HPP_INCLUDED
#define DEBUG_ASSERT_HPP_INCLUDED

#include <cstdlib>

#ifndef DEBUG_ASSERT_NO_STDIO
#    include <cstdio>
#endif

#ifndef DEBUG_ASSERT_MARK_UNREACHABLE
#    ifdef __GNUC__
#        define DEBUG_ASSERT_MARK_UNREACHABLE __builtin_unreachable()
#    elif defined(_MSC_VER)
#        define DEBUG_ASSERT_MARK_UNREACHABLE __assume(0)
#    else
/// Hint to the compiler that a code branch is unreachable.
/// Define it yourself prior to including the header to override it.
/// \notes This must be usable in an expression.
#        define DEBUG_ASSERT_MARK_UNREACHABLE
#    endif
#endif

#ifndef DEBUG_ASSERT_FORCE_INLINE
#    ifdef __GNUC__
#        define DEBUG_ASSERT_FORCE_INLINE [[gnu::always_inline]] inline
#    elif defined(_MSC_VER)
#        define DEBUG_ASSERT_FORCE_INLINE __forceinline
#    else
/// Strong hint to the compiler to inline a function.
/// Define it yourself prior to including the header to override it.
#        define DEBUG_ASSERT_FORCE_INLINE inline
#    endif
#endif

namespace debug_assert
{
//=== source location ===//
/// Defines a location in the source code.
struct source_location
{
    const char* file_name;   ///< The file name.
    unsigned    line_number; ///< The line number.
};

/// Expands to the current [debug_assert::source_location]().
#define DEBUG_ASSERT_CUR_SOURCE_LOCATION                                                           \
    debug_assert::source_location                                                                  \
    {                                                                                \
        __FILE__, static_cast<unsigned>(__LINE__)                                                  \
    }

//=== level ===//
/// Tag type to indicate the level of an assertion.
template <unsigned Level>
struct level
{};

/// Helper class that sets a certain level.
/// Inherit from it in your module handler.
template <unsigned Level>
struct set_level
{
    static const unsigned level = Level;
};

template <unsigned Level>
const unsigned set_level<Level>::level;

/// Helper class that controls whether the handler can throw or not.
/// Inherit from it in your module handler.
/// If the module does not inherit from this class, it is assumed that
/// the handle does not throw.
struct allow_exception
{
    static const bool throwing_exception_is_allowed = true;
};

//=== handler ===//
/// Does not do anything to handle a failed assertion (except calling
/// [std::abort()]()).
/// Inherit from it in your module handler.
struct no_handler
{
    /// \effects Does nothing.
    /// \notes Can take any additional arguments.
    template <typename... Args>
    static void handle(const source_location&, const char*, Args&&...) noexcept
    {}
};

/// The default handler that writes a message to `stderr`.
/// Inherit from it in your module handler.
struct default_handler
{
    /// \effects Prints a message to `stderr`.
    /// \notes It can optionally accept an additional message string.
    /// \notes If `DEBUG_ASSERT_NO_STDIO` is defined, it will do nothing.
    static void handle(const source_location& loc, const char* expression,
                       const char* message = nullptr) noexcept
    {
#ifndef DEBUG_ASSERT_NO_STDIO
        if (*expression == '\0')
        {
            if (message)
                std::fprintf(stderr, "[debug assert] %s:%u: Unreachable code reached - %s.\n",
                             loc.file_name, loc.line_number, message);
            else
                std::fprintf(stderr, "[debug assert] %s:%u: Unreachable code reached.\n",
                             loc.file_name, loc.line_number);
        }
        else if (message)
            std::fprintf(stderr, "[debug assert] %s:%u: Assertion '%s' failed - %s.\n",
                         loc.file_name, loc.line_number, expression, message);
        else
            std::fprintf(stderr, "[debug assert] %s:%u: Assertion '%s' failed.\n", loc.file_name,
                         loc.line_number, expression);
#else
        (void)loc;
        (void)expression;
        (void)message;
#endif
    }
};

/// \exclude
namespace detail
{
    //=== boilerplate ===//
    // from http://en.cppreference.com/w/cpp/types/remove_reference
    template <typename T>
    struct remove_reference
    {
        using type = T;
    };

    template <typename T>
    struct remove_reference<T&>
    {
        using type = T;
    };

    template <typename T>
    struct remove_reference<T&&>
    {
        using type = T;
    };

    // from http://stackoverflow.com/a/27501759
    template <class T>
    T&& forward(typename remove_reference<T>::type& t)
    {
        return static_cast<T&&>(t);
    }

    template <class T>
    T&& forward(typename remove_reference<T>::type&& t)
    {
        return static_cast<T&&>(t);
    }

    template <bool Value, typename T = void>
    struct enable_if;

    template <typename T>
    struct enable_if<true, T>
    {
        using type = T;
    };

    template <typename T>
    struct enable_if<false, T>
    {};

    //=== helper class to check if throw is allowed ===//
    template <class Handler, typename = void>
    struct allows_exception
    {
        static const bool value = false;
    };

    template <class Handler>
    struct allows_exception<Handler,
                            typename enable_if<Handler::throwing_exception_is_allowed>::type>
    {
        static const bool value = Handler::throwing_exception_is_allowed;
    };

    //=== regular void fake ===//
    struct regular_void
    {
        constexpr regular_void() = default;

        // enable conversion to anything
        // conversion must not actually be used
        template <typename T>
        constexpr operator T&() const noexcept
        {
            // doesn't matter how to get the T
            return DEBUG_ASSERT_MARK_UNREACHABLE, *static_cast<T*>(nullptr);
        }
    };

    //=== assert implementation ===//
    // function name will be shown on constexpr assertion failure
    template <class Handler, typename... Args>
    regular_void debug_assertion_failed(const source_location& loc, const char* expression,
                                        Args&&... args)
    {
#if defined(_MSC_VER)
#    pragma warning(push)
#    pragma warning(disable : 4702)
#endif
        return Handler::handle(loc, expression, detail::forward<Args>(args)...), std::abort(),
               regular_void();
#if defined(_MSC_VER)
#    pragma warning(pop)
#endif
    }

    // use enable if instead of tag dispatching
    // this removes on additional function and encourage optimization
    template <class Expr, class Handler, unsigned Level, typename... Args>
    constexpr auto do_assert(
        const Expr& expr, const source_location& loc, const char* expression, Handler, level<Level>,
        Args&&... args) noexcept(!allows_exception<Handler>::value
                                 || noexcept(Handler::handle(loc, expression,
                                                             detail::forward<Args>(args)...))) ->
        typename enable_if<Level <= Handler::level, regular_void>::type
    {
        static_assert(Level > 0, "level of an assertion must not be 0");
        return expr() ? regular_void()
                      : debug_assertion_failed<Handler>(loc, expression,
                                                        detail::forward<Args>(args)...);
    }

    template <class Expr, class Handler, unsigned Level, typename... Args>
    DEBUG_ASSERT_FORCE_INLINE constexpr auto do_assert(const Expr&, const source_location&,
                                                       const char*, Handler, level<Level>,
                                                       Args&&...) noexcept ->
        typename enable_if<(Level > Handler::level), regular_void>::type
    {
        return regular_void();
    }

    template <class Expr, class Handler, typename... Args>
    constexpr auto do_assert(
        const Expr& expr, const source_location& loc, const char* expression, Handler,
        Args&&... args) noexcept(!allows_exception<Handler>::value
                                 || noexcept(Handler::handle(loc, expression,
                                                             detail::forward<Args>(args)...))) ->
        typename enable_if<Handler::level != 0, regular_void>::type
    {
        return expr() ? regular_void()
                      : debug_assertion_failed<Handler>(loc, expression,
                                                        detail::forward<Args>(args)...);
    }

    template <class Expr, class Handler, typename... Args>
    DEBUG_ASSERT_FORCE_INLINE constexpr auto do_assert(const Expr&, const source_location&,
                                                       const char*, Handler, Args&&...) noexcept ->
        typename enable_if<Handler::level == 0, regular_void>::type
    {
        return regular_void();
    }

    constexpr bool always_false() noexcept
    {
        return false;
    }
} // namespace detail
} // namespace debug_assert

//=== assertion macros ===//
#ifndef DEBUG_ASSERT_DISABLE
/// The assertion macro.
//
/// Usage: `DEBUG_ASSERT(<expr>, <handler>, [<level>],
/// [<handler-specific-args>].
/// Where:
/// * `<expr>` - the expression to check for, the expression `!<expr>` must be
/// well-formed and contextually convertible to `bool`.
/// * `<handler>` - an object of the module specific handler
/// * `<level>` (optional, defaults to `1`) - the level of the assertion, must
/// be an object of type [debug_assert::level<Level>]().
/// * `<handler-specific-args>` (optional) - any additional arguments that are
/// just forwarded to the handler function.
///
/// It will only check the assertion if `<level>` is less than or equal to
/// `Handler::level`.
/// A failed assertion will call: `Handler::handle(location, expression, args)`.
/// `location` is the [debug_assert::source_location]() at the macro expansion,
/// `expression` is the stringified expression and `args` are the
/// `<handler-specific-args>` as-is.
/// If the handler function returns, it will call [std::abort()].
///
/// The macro will expand to a `void` expression.
///
/// \notes Define `DEBUG_ASSERT_DISABLE` to completely disable this macro, it
/// will expand to nothing.
/// This should not be necessary, the regular version is optimized away
/// completely.
#    define DEBUG_ASSERT(Expr, ...)                                                                \
        static_cast<void>(debug_assert::detail::do_assert([&]() noexcept { return Expr; },         \
                                                          DEBUG_ASSERT_CUR_SOURCE_LOCATION, #Expr, \
                                                          __VA_ARGS__))

/// Marks a branch as unreachable.
///
/// Usage: `DEBUG_UNREACHABLE(<handler>, [<level>], [<handler-specific-args>])`
/// Where:
/// * `<handler>` - an object of the module specific handler
/// * `<level>` (optional, defaults to `1`) - the level of the assertion, must
/// be an object of type [debug_assert::level<Level>]().
/// * `<handler-specific-args>` (optional) - any additional arguments that are
/// just forwarded to the handler function.
///
/// It will only check the assertion if `<level>` is less than or equal to
/// `Handler::level`.
/// A failed assertion will call: `Handler::handle(location, "", args)`.
/// and `args` are the `<handler-specific-args>` as-is.
/// If the handler function returns, it will call [std::abort()].
///
/// This macro is also usable in a constant expression,
/// i.e. you can use it in a `constexpr` function to verify a condition like so:
/// `cond(val) ? do_sth(val) : DEBUG_UNREACHABLE(…)`.
/// You can't use `DEBUG_ASSERT` there.
///
/// The macro will expand to an expression convertible to any type,
/// although the resulting object is invalid,
/// which doesn't matter, as the statement is unreachable anyway.
///
/// \notes Define `DEBUG_ASSERT_DISABLE` to completely disable this macro, it
/// will expand to `DEBUG_ASSERT_MARK_UNREACHABLE`.
/// This should not be necessary, the regular version is optimized away
/// completely.
#    define DEBUG_UNREACHABLE(...)                                                                 \
        debug_assert::detail::do_assert(debug_assert::detail::always_false,                        \
                                        DEBUG_ASSERT_CUR_SOURCE_LOCATION, "", __VA_ARGS__)
#else
#    define DEBUG_ASSERT(Expr, ...) static_cast<void>(0)

#    define DEBUG_UNREACHABLE(...)                                                                 \
        (DEBUG_ASSERT_MARK_UNREACHABLE, debug_assert::detail::regular_void())
#endif

#endif // DEBUG_ASSERT_HPP_INCLUDED
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/focus/accelerator_handler.h"

#include <bitset>
#include <gtk/gtk.h>
#if defined(HAVE_XINPUT2)
#include <X11/extensions/XInput2.h>
#else
#include <X11/Xlib.h>
#endif

#include "views/accelerator.h"
#include "views/events/event.h"
#include "views/focus/focus_manager.h"
#include "views/ime/input_method.h"
#include "views/touchui/touch_factory.h"
#include "views/widget/root_view.h"

namespace views {

namespace {

Widget* FindWidgetForGdkWindow(GdkWindow* gdk_window) {
  gpointer data = NULL;
  gdk_window_get_user_data(gdk_window, &data);
  GtkWidget* gtk_widget = reinterpret_cast<GtkWidget*>(data);
  if (!gtk_widget || !GTK_IS_WIDGET(gtk_widget)) {
    DLOG(WARNING) << "no GtkWidget found for that GdkWindow";
    return NULL;
  }
  NativeWidget* widget = NativeWidget::GetNativeWidgetForNativeView(gtk_widget);

  if (!widget) {
    DLOG(WARNING) << "no NativeWidgetGtk found for that GtkWidget";
    return NULL;
  }
  return widget->GetWidget();
}

}  // namespace

#if defined(HAVE_XINPUT2)
bool DispatchX2Event(Widget* widget, XEvent* xev) {
  XGenericEventCookie* cookie = &xev->xcookie;
  switch (cookie->evtype) {
    case XI_KeyPress:
    case XI_KeyRelease: {
      // TODO(sad): We don't capture XInput2 events from keyboard yet.
      break;
    }
    case XI_ButtonPress:
    case XI_ButtonRelease:
    case XI_Motion: {
      XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(cookie->data);
      Event::FromNativeEvent2 from_native;

      // Scrolling the wheel generates press/release events with button id's 4
      // and 5. In case of a wheelscroll, we do not want to show the cursor.
      if (xievent->detail == 4 || xievent->detail == 5) {
        MouseWheelEvent wheelev(xev, from_native);
        return widget->OnMouseEvent(wheelev);
      }

      // Is the event coming from a touch device?
      if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) {
        // Hide the cursor when a touch event comes in.
        TouchFactory::GetInstance()->SetCursorVisible(false, false);

        // With XInput 2.0, XI_ButtonPress and XI_ButtonRelease events are
        // ignored, as XI_Motion events contain enough data to detect finger
        // press and release. See more notes in TouchFactory::TouchParam.
        if (cookie->evtype == XI_ButtonPress ||
            cookie->evtype == XI_ButtonRelease)
          return false;

        // If the TouchEvent is processed by |root|, then return. Otherwise let
        // it fall through so it can be used as a MouseEvent, if desired.
        TouchEvent touch(xev, from_native);
        RootView* root = widget->GetRootView();
        if (root->OnTouchEvent(touch) != views::View::TOUCH_STATUS_UNKNOWN)
          return true;

        // We do not want to generate a mouse event for an unprocessed touch
        // event here. That is already done by the gesture manager in
        // RootView::OnTouchEvent.
        return false;
      } else {
        MouseEvent mouseev(xev, from_native);

        // Show the cursor. Start a timer to hide the cursor after a delay on
        // move (not drag) events, or if the only button pressed is released.
        bool start_timer = mouseev.type() == ui::ET_MOUSE_MOVED;
        start_timer |= mouseev.type() == ui::ET_MOUSE_RELEASED &&
                       (mouseev.IsOnlyLeftMouseButton() ||
                        mouseev.IsOnlyMiddleMouseButton() ||
                        mouseev.IsOnlyRightMouseButton());
        TouchFactory::GetInstance()->SetCursorVisible(true, start_timer);

        return widget->OnMouseEvent(mouseev);
      }
    }
  }
  return false;
}

#endif  // HAVE_XINPUT2

bool DispatchXEvent(XEvent* xev) {
  GdkDisplay* gdisp = gdk_display_get_default();
  XID xwindow = xev->xany.window;

#if defined(HAVE_XINPUT2)
  if (xev->type == GenericEvent) {
    if (!TouchFactory::GetInstance()->ShouldProcessXI2Event(xev))
      return true;  // Consume the event.

    XGenericEventCookie* cookie = &xev->xcookie;
    if (cookie->evtype == XI_HierarchyChanged) {
      TouchFactory::GetInstance()->UpdateDeviceList(cookie->display);
      return true;
    }

    XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(cookie->data);
    xwindow = xiev->event;
  }
#endif

  GdkWindow* gwind = gdk_window_lookup_for_display(gdisp, xwindow);
  Widget* widget = FindWidgetForGdkWindow(gwind);
  if (widget) {
    Event::FromNativeEvent2 from_native;
    switch (xev->type) {
      case KeyPress:
      case KeyRelease: {
        KeyEvent keyev(xev, from_native);
        InputMethod* ime = widget->GetInputMethod();
        // Always dispatch key events to the input method first, to make sure
        // that the input method's hotkeys work all time.
        if (ime) {
          ime->DispatchKeyEvent(keyev);
          return true;
        }
        return widget->OnKeyEvent(keyev);
      }
      case ButtonPress:
      case ButtonRelease:
        if (xev->xbutton.button == 4 || xev->xbutton.button == 5) {
          // Scrolling the wheel triggers button press/release events.
          MouseWheelEvent wheelev(xev, from_native);
          return widget->OnMouseEvent(wheelev);
        }
        // fallthrough
      case MotionNotify: {
        MouseEvent mouseev(xev, from_native);
        return widget->OnMouseEvent(mouseev);
      }

#if defined(HAVE_XINPUT2)
      case GenericEvent: {
        return DispatchX2Event(widget, xev);
      }
#endif
    }
  }

  return false;
}

#if defined(HAVE_XINPUT2)
void SetTouchDeviceList(std::vector<unsigned int>& devices) {
  TouchFactory::GetInstance()->SetTouchDeviceList(devices);
}
#endif

AcceleratorHandler::AcceleratorHandler() {}

bool AcceleratorHandler::Dispatch(GdkEvent* event) {
  gtk_main_do_event(event);
  return true;
}

base::MessagePumpGlibXDispatcher::DispatchStatus
    AcceleratorHandler::DispatchX(XEvent* xev) {
  return DispatchXEvent(xev) ?
      base::MessagePumpGlibXDispatcher::EVENT_PROCESSED :
      base::MessagePumpGlibXDispatcher::EVENT_IGNORED;
}

}  // namespace views
<commit_msg>Fix touch compile after WidgetGtk/NativeWidgetGtk rename.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/focus/accelerator_handler.h"

#include <bitset>
#include <gtk/gtk.h>
#if defined(HAVE_XINPUT2)
#include <X11/extensions/XInput2.h>
#else
#include <X11/Xlib.h>
#endif

#include "views/accelerator.h"
#include "views/events/event.h"
#include "views/focus/focus_manager.h"
#include "views/ime/input_method.h"
#include "views/touchui/touch_factory.h"
#include "views/widget/native_widget.h"
#include "views/widget/root_view.h"

namespace views {

namespace {

Widget* FindWidgetForGdkWindow(GdkWindow* gdk_window) {
  gpointer data = NULL;
  gdk_window_get_user_data(gdk_window, &data);
  GtkWidget* gtk_widget = reinterpret_cast<GtkWidget*>(data);
  if (!gtk_widget || !GTK_IS_WIDGET(gtk_widget)) {
    DLOG(WARNING) << "no GtkWidget found for that GdkWindow";
    return NULL;
  }
  NativeWidget* widget = NativeWidget::GetNativeWidgetForNativeView(gtk_widget);

  if (!widget) {
    DLOG(WARNING) << "no NativeWidgetGtk found for that GtkWidget";
    return NULL;
  }
  return widget->GetWidget();
}

}  // namespace

#if defined(HAVE_XINPUT2)
bool DispatchX2Event(Widget* widget, XEvent* xev) {
  XGenericEventCookie* cookie = &xev->xcookie;
  switch (cookie->evtype) {
    case XI_KeyPress:
    case XI_KeyRelease: {
      // TODO(sad): We don't capture XInput2 events from keyboard yet.
      break;
    }
    case XI_ButtonPress:
    case XI_ButtonRelease:
    case XI_Motion: {
      XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(cookie->data);
      Event::FromNativeEvent2 from_native;

      // Scrolling the wheel generates press/release events with button id's 4
      // and 5. In case of a wheelscroll, we do not want to show the cursor.
      if (xievent->detail == 4 || xievent->detail == 5) {
        MouseWheelEvent wheelev(xev, from_native);
        return widget->OnMouseEvent(wheelev);
      }

      // Is the event coming from a touch device?
      if (TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid)) {
        // Hide the cursor when a touch event comes in.
        TouchFactory::GetInstance()->SetCursorVisible(false, false);

        // With XInput 2.0, XI_ButtonPress and XI_ButtonRelease events are
        // ignored, as XI_Motion events contain enough data to detect finger
        // press and release. See more notes in TouchFactory::TouchParam.
        if (cookie->evtype == XI_ButtonPress ||
            cookie->evtype == XI_ButtonRelease)
          return false;

        // If the TouchEvent is processed by |root|, then return. Otherwise let
        // it fall through so it can be used as a MouseEvent, if desired.
        TouchEvent touch(xev, from_native);
        RootView* root = widget->GetRootView();
        if (root->OnTouchEvent(touch) != views::View::TOUCH_STATUS_UNKNOWN)
          return true;

        // We do not want to generate a mouse event for an unprocessed touch
        // event here. That is already done by the gesture manager in
        // RootView::OnTouchEvent.
        return false;
      } else {
        MouseEvent mouseev(xev, from_native);

        // Show the cursor. Start a timer to hide the cursor after a delay on
        // move (not drag) events, or if the only button pressed is released.
        bool start_timer = mouseev.type() == ui::ET_MOUSE_MOVED;
        start_timer |= mouseev.type() == ui::ET_MOUSE_RELEASED &&
                       (mouseev.IsOnlyLeftMouseButton() ||
                        mouseev.IsOnlyMiddleMouseButton() ||
                        mouseev.IsOnlyRightMouseButton());
        TouchFactory::GetInstance()->SetCursorVisible(true, start_timer);

        return widget->OnMouseEvent(mouseev);
      }
    }
  }
  return false;
}

#endif  // HAVE_XINPUT2

bool DispatchXEvent(XEvent* xev) {
  GdkDisplay* gdisp = gdk_display_get_default();
  XID xwindow = xev->xany.window;

#if defined(HAVE_XINPUT2)
  if (xev->type == GenericEvent) {
    if (!TouchFactory::GetInstance()->ShouldProcessXI2Event(xev))
      return true;  // Consume the event.

    XGenericEventCookie* cookie = &xev->xcookie;
    if (cookie->evtype == XI_HierarchyChanged) {
      TouchFactory::GetInstance()->UpdateDeviceList(cookie->display);
      return true;
    }

    XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(cookie->data);
    xwindow = xiev->event;
  }
#endif

  GdkWindow* gwind = gdk_window_lookup_for_display(gdisp, xwindow);
  Widget* widget = FindWidgetForGdkWindow(gwind);
  if (widget) {
    Event::FromNativeEvent2 from_native;
    switch (xev->type) {
      case KeyPress:
      case KeyRelease: {
        KeyEvent keyev(xev, from_native);
        InputMethod* ime = widget->GetInputMethod();
        // Always dispatch key events to the input method first, to make sure
        // that the input method's hotkeys work all time.
        if (ime) {
          ime->DispatchKeyEvent(keyev);
          return true;
        }
        return widget->OnKeyEvent(keyev);
      }
      case ButtonPress:
      case ButtonRelease:
        if (xev->xbutton.button == 4 || xev->xbutton.button == 5) {
          // Scrolling the wheel triggers button press/release events.
          MouseWheelEvent wheelev(xev, from_native);
          return widget->OnMouseEvent(wheelev);
        }
        // fallthrough
      case MotionNotify: {
        MouseEvent mouseev(xev, from_native);
        return widget->OnMouseEvent(mouseev);
      }

#if defined(HAVE_XINPUT2)
      case GenericEvent: {
        return DispatchX2Event(widget, xev);
      }
#endif
    }
  }

  return false;
}

#if defined(HAVE_XINPUT2)
void SetTouchDeviceList(std::vector<unsigned int>& devices) {
  TouchFactory::GetInstance()->SetTouchDeviceList(devices);
}
#endif

AcceleratorHandler::AcceleratorHandler() {}

bool AcceleratorHandler::Dispatch(GdkEvent* event) {
  gtk_main_do_event(event);
  return true;
}

base::MessagePumpGlibXDispatcher::DispatchStatus
    AcceleratorHandler::DispatchX(XEvent* xev) {
  return DispatchXEvent(xev) ?
      base::MessagePumpGlibXDispatcher::EVENT_PROCESSED :
      base::MessagePumpGlibXDispatcher::EVENT_IGNORED;
}

}  // namespace views
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

#include "visualizer/event/eventMoveVisualizer.hpp"
#include <cassert>
#include "core/core.hpp"
#include "core/eventView.hpp"
#include "visualizer/vertexArray.hpp"
#include "visualizer/math.hpp"

EventMoveVisualizer::EventMoveVisualizer(Visualizer& visualizer, const EventMoveView& event)
  : EventVisualizer(visualizer),
    mEventMove(event),
    mCurrentMoveIndex(0)
{
  visualizer.cleanWalkableMapArray();
}

EventMoveVisualizer::~EventMoveVisualizer() {
}

int EventMoveVisualizer::framesCount() const {
  return (mEventMove.path().size() - 1) * moveSpeed;
}

bool EventMoveVisualizer::isFinished() const {
  assert(mCurrentMoveIndex <= framesCount());
  return (mCurrentMoveIndex == framesCount());
}

void EventMoveVisualizer::draw() {
  const Unit& unit = visualizer().core().id2unit(mEventMove.unitID());
  auto& node = visualizer().sceneManager().sceneNode(unit.id());
  node.mPosition = currentPos();
  node.mRotationAngle = currentAngle();
  ++mCurrentMoveIndex;
}

const V2i& EventMoveVisualizer::currentTile() const {
  return mEventMove.path()[currentTileIndex()];
}

const V2i& EventMoveVisualizer::nextTile() const {
  return mEventMove.path()[currentTileIndex() + 1];
}

void EventMoveVisualizer::endMovement() {
  Core& core = visualizer().core();
  Unit& u = core.id2unit(mEventMove.unitID());
  auto& node = visualizer().sceneManager().sceneNode(u.id());
  node.mPosition = visualizer().v2iToV2f(u.position());
  node.mRotationAngle = dirToAngle(u.direction());
  if (core.isAnyUnitSelected()) {
    visualizer().rebuildWalkableMapArray();
    visualizer().rebuildMapArray();
  }
}

int EventMoveVisualizer::currentTileIndex() const {
  return mCurrentMoveIndex / moveSpeed;
}

int EventMoveVisualizer::calculateNodeIndex() const {
  return mCurrentMoveIndex - currentTileIndex() * moveSpeed;
}

void EventMoveVisualizer::end() {
  endMovement();
}

float EventMoveVisualizer::currentAngle() const {
  return dirToAngle(Dir(currentTile(), nextTile()));
}

V2f EventMoveVisualizer::currentPos() const {
  V2f from = visualizer().v2iToV2f(currentTile());
  V2f to = visualizer().v2iToV2f(nextTile());
  V2f diff = (to - from) / moveSpeed;
  int nodeIndex = calculateNodeIndex();
  return from + (diff * nodeIndex);
}
<commit_msg>Fixed EventMoveVisualizer::endMovement()<commit_after>// See LICENSE file for copyright and license details.

#include "visualizer/event/eventMoveVisualizer.hpp"
#include <cassert>
#include "core/core.hpp"
#include "core/eventView.hpp"
#include "visualizer/vertexArray.hpp"
#include "visualizer/math.hpp"

EventMoveVisualizer::EventMoveVisualizer(Visualizer& visualizer, const EventMoveView& event)
  : EventVisualizer(visualizer),
    mEventMove(event),
    mCurrentMoveIndex(0)
{
  visualizer.cleanWalkableMapArray();
}

EventMoveVisualizer::~EventMoveVisualizer() {
}

int EventMoveVisualizer::framesCount() const {
  return (mEventMove.path().size() - 1) * moveSpeed;
}

bool EventMoveVisualizer::isFinished() const {
  assert(mCurrentMoveIndex <= framesCount());
  return (mCurrentMoveIndex == framesCount());
}

void EventMoveVisualizer::draw() {
  const Unit& unit = visualizer().core().id2unit(mEventMove.unitID());
  auto& node = visualizer().sceneManager().sceneNode(unit.id());
  node.mPosition = currentPos();
  node.mRotationAngle = currentAngle();
  ++mCurrentMoveIndex;
}

const V2i& EventMoveVisualizer::currentTile() const {
  return mEventMove.path()[currentTileIndex()];
}

const V2i& EventMoveVisualizer::nextTile() const {
  return mEventMove.path()[currentTileIndex() + 1];
}

void EventMoveVisualizer::endMovement() {
  Core& core = visualizer().core();
  Unit& u = core.id2unit(mEventMove.unitID());
  auto& node = visualizer().sceneManager().sceneNode(u.id());
  node.mPosition = visualizer().v2iToV2f(mEventMove.path().back());
  node.mRotationAngle = dirToAngle(u.direction());
  if (core.isAnyUnitSelected()) {
    visualizer().rebuildWalkableMapArray();
    visualizer().rebuildMapArray();
  }
}

int EventMoveVisualizer::currentTileIndex() const {
  return mCurrentMoveIndex / moveSpeed;
}

int EventMoveVisualizer::calculateNodeIndex() const {
  return mCurrentMoveIndex - currentTileIndex() * moveSpeed;
}

void EventMoveVisualizer::end() {
  endMovement();
}

float EventMoveVisualizer::currentAngle() const {
  return dirToAngle(Dir(currentTile(), nextTile()));
}

V2f EventMoveVisualizer::currentPos() const {
  V2f from = visualizer().v2iToV2f(currentTile());
  V2f to = visualizer().v2iToV2f(nextTile());
  V2f diff = (to - from) / moveSpeed;
  int nodeIndex = calculateNodeIndex();
  return from + (diff * nodeIndex);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015-2017 Nagisa Sekiguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef YDSH_MISC_BUFFER_HPP
#define YDSH_MISC_BUFFER_HPP

#include <cstring>
#include <type_traits>
#include <cassert>
#include <initializer_list>

#include "noncopyable.h"
#include "fatal.h"

namespace ydsh {

/**
 * only available POD type.
 * default maximum capacity is 4GB
 */
template <typename T, typename SIZE_T = unsigned int>
class FlexBuffer {
public:
    using size_type = SIZE_T;
    using iterator = T *;
    using const_iterator = const T *;
    using reference = T &;
    using const_reference = const T &;

    static constexpr size_type MINIMUM_CAPACITY = 8;
    static constexpr size_type MAXIMUM_CAPACITY = static_cast<SIZE_T>(-1);

private:
    static_assert(std::is_unsigned<SIZE_T>::value, "need unsigned type");

    static_assert(std::is_pod<T>::value, "forbidden type");

    size_type maxSize;
    size_type usedSize;

    T *data;

    /**
     * expand memory of old.
     * if old is null, only allocate.
     */
    static T *allocArray(T *old, SIZE_T size) noexcept {
        T *ptr = static_cast<T *>(realloc(old, sizeof(T) * size));
        if(ptr == nullptr) {
            fatal("memory allocation failed\n");
        }
        return ptr;
    }

    void moveElements(iterator src, iterator dest) noexcept {
        if(src == dest) {
            return;
        }

        memmove(dest, src, sizeof(T) * (this->end() - src));
        if(src < dest) {
            this->usedSize += (dest - src);
        } else {
            this->usedSize -= (src - dest);
        }
    }

    /**
     * if out of range, abort
     */
    void checkRange(size_type index) const noexcept;

    FlexBuffer &push_back_impl(const T &value) noexcept;

public:
    NON_COPYABLE(FlexBuffer);

    /**
     * default initial size is equivalent to MINIMUM_CAPACITY
     */
    explicit FlexBuffer(size_type initSize) :
            maxSize(initSize < MINIMUM_CAPACITY ? MINIMUM_CAPACITY : initSize),
            usedSize(0),
            data(allocArray(nullptr, this->maxSize)) { }

    FlexBuffer(std::initializer_list<T> list) : FlexBuffer(list.size()) {
        for(auto iter = list.begin(); iter != list.end(); ++iter) {
            this->data[this->usedSize++] = *iter;
        }
    }

    /**
     * for lazy allocation
     */
    FlexBuffer() noexcept : maxSize(0), usedSize(0), data(nullptr) { }

    FlexBuffer(FlexBuffer &&buffer) noexcept :
            maxSize(buffer.maxSize), usedSize(buffer.usedSize), data(extract(std::move(buffer))) { }

    ~FlexBuffer() {
        free(this->data);
    }

    FlexBuffer &operator=(FlexBuffer &&buffer) noexcept {
        FlexBuffer tmp(std::move(buffer));
        this->swap(tmp);
        return *this;
    }

    FlexBuffer &operator+=(const T &value) noexcept {
        return this->push_back_impl(value);
    }

    FlexBuffer &operator+=(T &&value) noexcept {
        return this->push_back_impl(value);
    }

    /**
     * buffer.data is not equivalent to this.data.
     */
    FlexBuffer &operator+=(const FlexBuffer &buffer) noexcept;

    FlexBuffer &operator+=(FlexBuffer &&buffer) noexcept;

    template <std::size_t N>
    FlexBuffer &operator+=(const T (&value)[N]) noexcept {
        return this->append(value, N);
    }

    /**
     * value is not equivalent to this.data.
     */
    FlexBuffer &append(const T *value, size_type size) noexcept;

    size_type capacity() const noexcept {
        return this->maxSize;
    }

    size_type size() const noexcept {
        return this->usedSize;
    }

    bool empty() const noexcept {
        return this->size() == 0;
    }

    const T *get() const noexcept {
        return this->data;
    }

    T *get() noexcept {
        return this->data;
    }

    void clear() noexcept {
        this->usedSize = 0;
    }

    void swap(FlexBuffer &buf) noexcept {
        std::swap(this->usedSize, buf.usedSize);
        std::swap(this->maxSize, buf.maxSize);
        std::swap(this->data, buf.data);
    }

    /**
     * capacity will be at least reservingSize.
     */
    void reserve(size_type reservingSize) noexcept;

    iterator begin() noexcept {
        return this->data;
    }

    iterator end() noexcept {
        return this->data + this->usedSize;
    }

    const_iterator begin() const noexcept {
        return this->data;
    }

    const_iterator end() const noexcept {
        return this->data + this->usedSize;
    }

    reference front() noexcept {
        return this->operator[](0);
    }

    const_reference front() const noexcept {
        return this->operator[](0);
    }

    reference back() noexcept {
        return this->operator[](this->usedSize - 1);
    }

    const_reference back() const noexcept {
        return this->operator[](this->usedSize - 1);
    }

    void push_back(const T &value) noexcept {
        this->push_back_impl(value);
    }

    void push_back(T &&value) noexcept {
        this->push_back_impl(value);
    }

    void pop_back() noexcept {
        this->usedSize--;
    }

    reference operator[](size_type index) noexcept {
        return this->data[index];
    }

    const_reference operator[](size_type index) const noexcept {
        return this->data[index];
    }

    reference at(size_type index) noexcept;

    const_reference at(size_type index) const noexcept;

    /**
     * pos (begin() <= pos <= end()).
     * return position inserted element.
     */
    iterator insert(const_iterator pos, const T &value) noexcept;

    /**
     * pos must not equivalent to this->end().
     */
    iterator erase(const_iterator pos) noexcept;

    /**
     * first must be last or less. (first <= last).
     * last must be this->end() or less. (last <= this->end())
     * first is inclusive, last is exclusive.
     */
    iterator erase(const_iterator first, const_iterator last) noexcept;

    void assign(size_type n, const T &value);

    bool operator==(const FlexBuffer &v) const noexcept {
        return this->size() == v.size() && memcmp(this->data, v.data, sizeof(T) * this->size()) == 0;
    }

    bool operator!=(const FlexBuffer &v) const noexcept {
        return !(*this == v);
    }

    /**
     * extract data. after call it, maxSize and usedSize is 0, and data is null.
     * call free() to release returned pointer.
     */
    friend T *extract(FlexBuffer &&buf) noexcept {
        buf.maxSize = 0;
        buf.usedSize = 0;
        T *ptr = buf.data;
        buf.data = nullptr;
        return ptr;
    }
};

// ########################
// ##     FlexBuffer     ##
// ########################

template <typename T, typename SIZE_T>
constexpr typename FlexBuffer<T, SIZE_T>::size_type FlexBuffer<T, SIZE_T>::MINIMUM_CAPACITY;

template <typename T, typename SIZE_T>
constexpr typename FlexBuffer<T, SIZE_T>::size_type FlexBuffer<T, SIZE_T>::MAXIMUM_CAPACITY;

template <typename T, typename SIZE_T>
void FlexBuffer<T, SIZE_T>::checkRange(size_type index) const noexcept {
    if(index >= this->usedSize) {
        fatal("size is: %d, but index is: %d\n", this->usedSize, index);
    }
}

template <typename T, typename SIZE_T>
FlexBuffer<T, SIZE_T> &FlexBuffer<T, SIZE_T>::push_back_impl(const T &value) noexcept {
    this->reserve(this->usedSize + 1);
    this->data[this->usedSize++] = value;
    return *this;
}

template <typename T, typename SIZE_T>
FlexBuffer<T, SIZE_T> &FlexBuffer<T, SIZE_T>::operator+=(const FlexBuffer<T, SIZE_T> &buffer) noexcept {
    return this->append(buffer.get(), buffer.size());
}

template <typename T, typename SIZE_T>
FlexBuffer<T, SIZE_T> &FlexBuffer<T, SIZE_T>::operator+=(FlexBuffer<T, SIZE_T> &&buffer) noexcept {
    FlexBuffer<T, SIZE_T> tmp(std::move(buffer));
    *this += tmp;
    return *this;
}

template <typename T, typename SIZE_T>
FlexBuffer<T, SIZE_T> &FlexBuffer<T, SIZE_T>::append(const T *value, size_type size) noexcept {
    if(this->data == value) {
        fatal("appending own buffer\n");
    }
    this->reserve(this->usedSize + size);
    memcpy(this->data + this->usedSize, value, sizeof(T) * size);
    this->usedSize += size;
    return *this;
}

template <typename T, typename SIZE_T>
void FlexBuffer<T, SIZE_T>::reserve(size_type reservingSize) noexcept {
    if(reservingSize > this->maxSize) {
        std::size_t newSize = (this->maxSize == 0 ? MINIMUM_CAPACITY : this->maxSize);
        while(newSize < reservingSize) {
            newSize += (newSize >> 1);
        }

        if(newSize > MAXIMUM_CAPACITY) {
            fatal("reach maximum capacity\n");
        }

        this->maxSize = newSize;
        this->data = allocArray(this->data, newSize);
    }
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::reference FlexBuffer<T, SIZE_T>::at(size_type index) noexcept {
    this->checkRange(index);
    return this->data[index];
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::const_reference FlexBuffer<T, SIZE_T>::at(size_type index) const noexcept {
    this->checkRange(index);
    return this->data[index];
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::iterator FlexBuffer<T, SIZE_T>::insert(const_iterator pos, const T &value) noexcept {
    assert(pos >= this->begin() && pos <= this->end());

    const size_type index = pos - this->begin();
    this->reserve(this->size() + 1);
    iterator iter = this->begin() + index;

    this->moveElements(iter, iter + 1);
    this->data[index] = value;

    return iter;
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::iterator FlexBuffer<T, SIZE_T>::erase(const_iterator pos) noexcept {
    assert(pos < this->end());

    const size_type index = pos - this->begin();
    iterator iter = this->begin() + index;

    this->moveElements(iter + 1, iter);

    return iter;
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::iterator FlexBuffer<T, SIZE_T>::erase(const_iterator first, const_iterator last) noexcept {
    assert(last <= this->end());
    assert(first <= last);

    const size_type index = first - this->begin();
    iterator iter = this->begin() + index;

    this->moveElements(iter + (last - first), iter);

    return iter;
}

template <typename T, typename SIZE_T>
void FlexBuffer<T, SIZE_T>::assign(size_type n, const T &value) {
    this->reserve(this->usedSize + n);
    for(unsigned int i = 0; i < n; i++) {
        this->data[this->usedSize++] = value;
    }
}

using ByteBuffer = FlexBuffer<char>;

// for byte reading
template <unsigned int N>
inline unsigned long readN(const unsigned char *ptr, unsigned int index) noexcept {
    static_assert(N > 0 && N < 9, "out of range");

    ptr += index;
    unsigned long v = 0;
    for(int i = N; i > 0; i--) {
        v |= static_cast<unsigned long>(*(ptr++)) << ((i - 1) * 8);
    }
    return v;
}

inline unsigned char read8(const unsigned char *const code, unsigned int index) noexcept {
    return readN<1>(code, index);
}

inline unsigned short read16(const unsigned char *const code, unsigned int index) noexcept {
    return readN<2>(code, index);
}

inline unsigned int read24(const unsigned char *const code, unsigned int index) noexcept {
    return readN<3>(code, index);
}

inline unsigned int read32(const unsigned char *const code, unsigned int index) noexcept {
    return readN<4>(code, index);
}

inline unsigned long read64(const unsigned char *const code, unsigned int index) noexcept {
    return readN<8>(code, index);
}

// for byte writing
template <unsigned int N>
inline void writeN(unsigned char *ptr, unsigned long b) noexcept {
    static_assert(N > 0 && N < 9, "out of range");

    for(unsigned int i = N; i > 0; --i) {
        const unsigned long mask = static_cast<unsigned long>(0xFF) << ((i - 1) * 8);
        *(ptr++) = (b & mask) >> ((i - 1) * 8);
    }
}

inline void write8(unsigned char *ptr, unsigned char b) noexcept {
    writeN<1>(ptr, b);
}

inline void write16(unsigned char *ptr, unsigned short b) noexcept {
    writeN<2>(ptr, b);
}

inline void write24(unsigned char *ptr, unsigned int b) noexcept {
    writeN<3>(ptr, b);
}

inline void write32(unsigned char *ptr, unsigned int b) noexcept {
    writeN<4>(ptr, b);
}

inline void write64(unsigned char *ptr, unsigned long b) noexcept {
    writeN<8>(ptr, b);
}

} // namespace ydsh

#endif //YDSH_MISC_BUFFER_HPP
<commit_msg>fix flex buffer api<commit_after>/*
 * Copyright (C) 2015-2017 Nagisa Sekiguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef YDSH_MISC_BUFFER_HPP
#define YDSH_MISC_BUFFER_HPP

#include <cstring>
#include <type_traits>
#include <cassert>
#include <initializer_list>

#include "noncopyable.h"
#include "fatal.h"

namespace ydsh {

/**
 * only available POD type.
 * default maximum capacity is 4GB
 */
template <typename T, typename SIZE_T = unsigned int>
class FlexBuffer {
public:
    using size_type = SIZE_T;
    using iterator = T *;
    using const_iterator = const T *;
    using reference = T &;
    using const_reference = const T &;

    static constexpr size_type MINIMUM_CAPACITY = 8;
    static constexpr size_type MAXIMUM_CAPACITY = static_cast<SIZE_T>(-1);

private:
    static_assert(std::is_unsigned<SIZE_T>::value, "need unsigned type");

    static_assert(std::is_pod<T>::value, "forbidden type");

    size_type maxSize;
    size_type usedSize;

    T *data;

    /**
     * expand memory of old.
     * if old is null, only allocate.
     */
    static T *allocArray(T *old, SIZE_T size) noexcept {
        T *ptr = static_cast<T *>(realloc(old, sizeof(T) * size));
        if(ptr == nullptr) {
            fatal("memory allocation failed\n");
        }
        return ptr;
    }

    void moveElements(iterator src, iterator dest) noexcept {
        if(src == dest) {
            return;
        }

        memmove(dest, src, sizeof(T) * (this->end() - src));
        if(src < dest) {
            this->usedSize += (dest - src);
        } else {
            this->usedSize -= (src - dest);
        }
    }

    /**
     * if out of range, abort
     */
    void checkRange(size_type index) const noexcept;

    FlexBuffer &push_back_impl(const T &value) noexcept;

public:
    NON_COPYABLE(FlexBuffer);

    /**
     * default initial size is equivalent to MINIMUM_CAPACITY
     */
    explicit FlexBuffer(size_type initSize) :
            maxSize(initSize < MINIMUM_CAPACITY ? MINIMUM_CAPACITY : initSize),
            usedSize(0),
            data(allocArray(nullptr, this->maxSize)) { }

    FlexBuffer(std::initializer_list<T> list) : FlexBuffer(list.size()) {
        for(auto iter = list.begin(); iter != list.end(); ++iter) {
            this->data[this->usedSize++] = *iter;
        }
    }

    /**
     * for lazy allocation
     */
    FlexBuffer() noexcept : maxSize(0), usedSize(0), data(nullptr) { }

    FlexBuffer(FlexBuffer &&buffer) noexcept :
            maxSize(buffer.maxSize), usedSize(buffer.usedSize), data(extract(std::move(buffer))) { }

    ~FlexBuffer() {
        free(this->data);
    }

    FlexBuffer &operator=(FlexBuffer &&buffer) noexcept {
        FlexBuffer tmp(std::move(buffer));
        this->swap(tmp);
        return *this;
    }

    FlexBuffer &operator+=(const T &value) noexcept {
        return this->push_back_impl(value);
    }

    FlexBuffer &operator+=(T &&value) noexcept {
        return this->push_back_impl(value);
    }

    /**
     * buffer.data is not equivalent to this.data.
     */
    FlexBuffer &operator+=(const FlexBuffer &buffer) noexcept;

    FlexBuffer &operator+=(FlexBuffer &&buffer) noexcept;

    template <std::size_t N>
    FlexBuffer &operator+=(const T (&value)[N]) noexcept {
        return this->append(value, N);
    }

    /**
     * value is not equivalent to this.data.
     */
    FlexBuffer &append(const T *value, size_type size) noexcept;

    template <typename Func>
    FlexBuffer &appendBy(size_type maxSize, Func func) noexcept {
        this->reserve(this->size() + maxSize);
        size_type actualSize = func(this->get() + this->size());
        this->usedSize += actualSize;
        return *this;
    }

    size_type capacity() const noexcept {
        return this->maxSize;
    }

    size_type size() const noexcept {
        return this->usedSize;
    }

    bool empty() const noexcept {
        return this->size() == 0;
    }

    const T *get() const noexcept {
        return this->data;
    }

    T *get() noexcept {
        return this->data;
    }

    void clear() noexcept {
        this->usedSize = 0;
    }

    void swap(FlexBuffer &buf) noexcept {
        std::swap(this->usedSize, buf.usedSize);
        std::swap(this->maxSize, buf.maxSize);
        std::swap(this->data, buf.data);
    }

    /**
     * capacity will be at least reservingSize.
     */
    void reserve(size_type reservingSize) noexcept;

    iterator begin() noexcept {
        return this->data;
    }

    iterator end() noexcept {
        return this->data + this->usedSize;
    }

    const_iterator begin() const noexcept {
        return this->data;
    }

    const_iterator end() const noexcept {
        return this->data + this->usedSize;
    }

    reference front() noexcept {
        return this->operator[](0);
    }

    const_reference front() const noexcept {
        return this->operator[](0);
    }

    reference back() noexcept {
        return this->operator[](this->usedSize - 1);
    }

    const_reference back() const noexcept {
        return this->operator[](this->usedSize - 1);
    }

    void push_back(const T &value) noexcept {
        this->push_back_impl(value);
    }

    void push_back(T &&value) noexcept {
        this->push_back_impl(value);
    }

    void pop_back() noexcept {
        this->usedSize--;
    }

    reference operator[](size_type index) noexcept {
        return this->data[index];
    }

    const_reference operator[](size_type index) const noexcept {
        return this->data[index];
    }

    reference at(size_type index) noexcept;

    const_reference at(size_type index) const noexcept;

    /**
     * pos (begin() <= pos <= end()).
     * return position inserted element.
     */
    iterator insert(const_iterator pos, const T &value) noexcept;

    /**
     * pos must not equivalent to this->end().
     */
    iterator erase(const_iterator pos) noexcept;

    /**
     * first must be last or less. (first <= last).
     * last must be this->end() or less. (last <= this->end())
     * first is inclusive, last is exclusive.
     */
    iterator erase(const_iterator first, const_iterator last) noexcept;

    void assign(size_type n, const T &value);

    bool operator==(const FlexBuffer &v) const noexcept {
        return this->size() == v.size() && memcmp(this->data, v.data, sizeof(T) * this->size()) == 0;
    }

    bool operator!=(const FlexBuffer &v) const noexcept {
        return !(*this == v);
    }

    /**
     * extract data. after call it, maxSize and usedSize is 0, and data is null.
     * call free() to release returned pointer.
     */
    friend T *extract(FlexBuffer &&buf) noexcept {
        buf.maxSize = 0;
        buf.usedSize = 0;
        T *ptr = buf.data;
        buf.data = nullptr;
        return ptr;
    }
};

// ########################
// ##     FlexBuffer     ##
// ########################

template <typename T, typename SIZE_T>
constexpr typename FlexBuffer<T, SIZE_T>::size_type FlexBuffer<T, SIZE_T>::MINIMUM_CAPACITY;

template <typename T, typename SIZE_T>
constexpr typename FlexBuffer<T, SIZE_T>::size_type FlexBuffer<T, SIZE_T>::MAXIMUM_CAPACITY;

template <typename T, typename SIZE_T>
void FlexBuffer<T, SIZE_T>::checkRange(size_type index) const noexcept {
    if(index >= this->usedSize) {
        fatal("size is: %d, but index is: %d\n", this->usedSize, index);
    }
}

template <typename T, typename SIZE_T>
FlexBuffer<T, SIZE_T> &FlexBuffer<T, SIZE_T>::push_back_impl(const T &value) noexcept {
    this->reserve(this->usedSize + 1);
    this->data[this->usedSize++] = value;
    return *this;
}

template <typename T, typename SIZE_T>
FlexBuffer<T, SIZE_T> &FlexBuffer<T, SIZE_T>::operator+=(const FlexBuffer<T, SIZE_T> &buffer) noexcept {
    return this->append(buffer.get(), buffer.size());
}

template <typename T, typename SIZE_T>
FlexBuffer<T, SIZE_T> &FlexBuffer<T, SIZE_T>::operator+=(FlexBuffer<T, SIZE_T> &&buffer) noexcept {
    FlexBuffer<T, SIZE_T> tmp(std::move(buffer));
    *this += tmp;
    return *this;
}

template <typename T, typename SIZE_T>
FlexBuffer<T, SIZE_T> &FlexBuffer<T, SIZE_T>::append(const T *value, size_type size) noexcept {
    if(this->data == value) {
        fatal("appending own buffer\n");
    }
    this->reserve(this->usedSize + size);
    memcpy(this->data + this->usedSize, value, sizeof(T) * size);
    this->usedSize += size;
    return *this;
}

template <typename T, typename SIZE_T>
void FlexBuffer<T, SIZE_T>::reserve(size_type reservingSize) noexcept {
    if(reservingSize > this->maxSize) {
        std::size_t newSize = (this->maxSize == 0 ? MINIMUM_CAPACITY : this->maxSize);
        while(newSize < reservingSize) {
            newSize += (newSize >> 1);
        }

        if(newSize > MAXIMUM_CAPACITY) {
            fatal("reach maximum capacity\n");
        }

        this->maxSize = newSize;
        this->data = allocArray(this->data, newSize);
    }
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::reference FlexBuffer<T, SIZE_T>::at(size_type index) noexcept {
    this->checkRange(index);
    return this->data[index];
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::const_reference FlexBuffer<T, SIZE_T>::at(size_type index) const noexcept {
    this->checkRange(index);
    return this->data[index];
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::iterator FlexBuffer<T, SIZE_T>::insert(const_iterator pos, const T &value) noexcept {
    assert(pos >= this->begin() && pos <= this->end());

    const size_type index = pos - this->begin();
    this->reserve(this->size() + 1);
    iterator iter = this->begin() + index;

    this->moveElements(iter, iter + 1);
    this->data[index] = value;

    return iter;
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::iterator FlexBuffer<T, SIZE_T>::erase(const_iterator pos) noexcept {
    assert(pos < this->end());

    const size_type index = pos - this->begin();
    iterator iter = this->begin() + index;

    this->moveElements(iter + 1, iter);

    return iter;
}

template <typename T, typename SIZE_T>
typename FlexBuffer<T, SIZE_T>::iterator FlexBuffer<T, SIZE_T>::erase(const_iterator first, const_iterator last) noexcept {
    assert(last <= this->end());
    assert(first <= last);

    const size_type index = first - this->begin();
    iterator iter = this->begin() + index;

    this->moveElements(iter + (last - first), iter);

    return iter;
}

template <typename T, typename SIZE_T>
void FlexBuffer<T, SIZE_T>::assign(size_type n, const T &value) {
    this->reserve(this->usedSize + n);
    for(unsigned int i = 0; i < n; i++) {
        this->data[this->usedSize++] = value;
    }
}

using ByteBuffer = FlexBuffer<char>;

// for byte reading
template <unsigned int N>
inline unsigned long readN(const unsigned char *ptr, unsigned int index) noexcept {
    static_assert(N > 0 && N < 9, "out of range");

    ptr += index;
    unsigned long v = 0;
    for(int i = N; i > 0; i--) {
        v |= static_cast<unsigned long>(*(ptr++)) << ((i - 1) * 8);
    }
    return v;
}

inline unsigned char read8(const unsigned char *const code, unsigned int index) noexcept {
    return readN<1>(code, index);
}

inline unsigned short read16(const unsigned char *const code, unsigned int index) noexcept {
    return readN<2>(code, index);
}

inline unsigned int read24(const unsigned char *const code, unsigned int index) noexcept {
    return readN<3>(code, index);
}

inline unsigned int read32(const unsigned char *const code, unsigned int index) noexcept {
    return readN<4>(code, index);
}

inline unsigned long read64(const unsigned char *const code, unsigned int index) noexcept {
    return readN<8>(code, index);
}

// for byte writing
template <unsigned int N>
inline void writeN(unsigned char *ptr, unsigned long b) noexcept {
    static_assert(N > 0 && N < 9, "out of range");

    for(unsigned int i = N; i > 0; --i) {
        const unsigned long mask = static_cast<unsigned long>(0xFF) << ((i - 1) * 8);
        *(ptr++) = (b & mask) >> ((i - 1) * 8);
    }
}

inline void write8(unsigned char *ptr, unsigned char b) noexcept {
    writeN<1>(ptr, b);
}

inline void write16(unsigned char *ptr, unsigned short b) noexcept {
    writeN<2>(ptr, b);
}

inline void write24(unsigned char *ptr, unsigned int b) noexcept {
    writeN<3>(ptr, b);
}

inline void write32(unsigned char *ptr, unsigned int b) noexcept {
    writeN<4>(ptr, b);
}

inline void write64(unsigned char *ptr, unsigned long b) noexcept {
    writeN<8>(ptr, b);
}

} // namespace ydsh

#endif //YDSH_MISC_BUFFER_HPP
<|endoftext|>


<commit_before>// See copyright notice in file Copyright in the root directory of this archive.

#include <utils/Debug.h>
#include "DVFSManagerFactory.h"
#include "RealDVFSManager.h"
#include "SimulatedDVFSManager.h"
#include "TimeWarpSimulationManager.h"
#include "SimulationConfiguration.h"

using std::cout;
using std::cerr;
using std::endl;

DVFSManagerFactory::DVFSManagerFactory(){}

DVFSManagerFactory::~DVFSManagerFactory(){}

// allocate a new manager of the type given in the configuration file
Configurable *
DVFSManagerFactory::allocate( SimulationConfiguration &configuration,
				Configurable *parent ) const {

  TimeWarpSimulationManager *mySimulationManager =
    dynamic_cast<TimeWarpSimulationManager *>( parent );
  ASSERT(mySimulationManager);

  string type = "NONE";
  configuration.getDVFSStringOption("Type", type);
  if(type == "NONE") {
    return NULL;
  }

  string metric = "ROLLBACKS";
  string opt = "PERFORMANCE";
  int p = 0;
  int firsize = 16;
  configuration.getDVFSIntOption("Period", p);
  configuration.getDVFSIntOption("FIRSize", firsize);
  configuration.getDVFSStringOption("UsefulWorkMetric", metric);
  configuration.getDVFSStringOption("OptimizeFor", opt);

  DVFSManager::UsefulWorkMetric uwm;
  if(metric == "ROLLBACKS")
    uwm = DVFSManager::ROLLBACKS;
  else if(metric == "ROLLBACKFRACTION")
    uwm = DVFSManager::ROLLBACK_FRACTION;
  else if(metric == "EFFECTIVEUTILIZATION")
    uwm = DVFSManager::EFFECTIVE_UTILIZATION;
  else {
    stringstream err;
    err << "DVFSManager: UsefulWorkMetric " << metric << " is invalid. "
        << "Valid metrics are Rollbacks | EffectiveUtilization "
        << "| RollbackFraction. Aborting simulation." << endl;
    mySimulationManager->shutdown(err.str());
  }

  DVFSManager::OptimizationGoal og;
  if(opt == "PERFORMANCE")
    og = DVFSManager::PERFORMANCE;
  else if(opt == "POWER")
    og = DVFSManager::POWER;
  else if(opt == "HYBRID")
    og = DVFSManager::HYBRID;
  else {
    stringstream err;
    err << "DVFSManager: OptimizeFor " << opt << " is invalid. "
        << "Valid options are Performance | Power | Hybrid. "
        << "Aborting simulation." << endl;
    mySimulationManager->shutdown(err.str());
  }

  const char* trueFalseOptions[] = {"Fixed", "DebugPrint"};
  int numTrueFalse = sizeof(trueFalseOptions) / sizeof(const char*);
  bool trueFalseValues[numTrueFalse];
  for(int i=0; i < numTrueFalse; i++) {
    string val = "FALSE";
    configuration.getDVFSStringOption(trueFalseOptions[i], val);
    if(val != "TRUE" && val != "FALSE") {
      stringstream err;
      err << "DVFSManager: option " << trueFalseOptions[i]
          << " is invalid. Expected True / False.  Aborting simulation."
          << endl;
      mySimulationManager->shutdown(err.str());
    }
    trueFalseValues[i] = val == "TRUE";
  }

  if( geteuid() !=  0 ) {
    stringstream err;
    err << "DVFSManager: To use DVFS, WARPED "
        << " must be run as root. Aborting simulation." << endl;
    mySimulationManager->shutdown(err.str());
  }

  if(type == "REAL" || type == "SIMULATED") {
    cout << "("
         << mySimulationManager->getSimulationManagerID()
         << ") configured a " << type << " DVFS Manager" << endl
         << "Fixed: " << (trueFalseValues[0] ? "True" : "False") << endl
         << "Period: " << p << endl
         << "FIR Size: " << firsize << endl
         << "Optimize for: " << opt << endl
         << "Useful work metric: " << metric << endl;
         if(trueFalseValues[1])
           cout <<  "Writing trace to csv" << endl;

    if(type == "REAL")
      return new RealDVFSManager(mySimulationManager,
                                 p,
                                 firsize,
                                 trueFalseValues[0],
                                 trueFalseValues[1],
                                 og,
                                 uwm);

    return new SimulatedDVFSManager(mySimulationManager,
                                    p,
                                    firsize,
                                    trueFalseValues[0],
                                    trueFalseValues[1],
                                    og,
                                    uwm);
  }
  else {
    stringstream err;
    cerr << "DVFSManager: invalid type '" << type << "'." << endl
         << "Valid types are None | Real | Simulated. Aborting simulation.";
    mySimulationManager->shutdown(err.str());
  }
}

const DVFSManagerFactory *
DVFSManagerFactory::instance(){
  static DVFSManagerFactory *singleton = new DVFSManagerFactory();
  return singleton;
}
<commit_msg>removing root restriction on DVFSManager<commit_after>// See copyright notice in file Copyright in the root directory of this archive.

#include <utils/Debug.h>
#include "DVFSManagerFactory.h"
#include "RealDVFSManager.h"
#include "SimulatedDVFSManager.h"
#include "TimeWarpSimulationManager.h"
#include "SimulationConfiguration.h"

using std::cout;
using std::cerr;
using std::endl;

DVFSManagerFactory::DVFSManagerFactory(){}

DVFSManagerFactory::~DVFSManagerFactory(){}

// allocate a new manager of the type given in the configuration file
Configurable *
DVFSManagerFactory::allocate( SimulationConfiguration &configuration,
				Configurable *parent ) const {

  TimeWarpSimulationManager *mySimulationManager =
    dynamic_cast<TimeWarpSimulationManager *>( parent );
  ASSERT(mySimulationManager);

  string type = "NONE";
  configuration.getDVFSStringOption("Type", type);
  if(type == "NONE") {
    return NULL;
  }

  string metric = "ROLLBACKS";
  string opt = "PERFORMANCE";
  int p = 0;
  int firsize = 16;
  configuration.getDVFSIntOption("Period", p);
  configuration.getDVFSIntOption("FIRSize", firsize);
  configuration.getDVFSStringOption("UsefulWorkMetric", metric);
  configuration.getDVFSStringOption("OptimizeFor", opt);

  DVFSManager::UsefulWorkMetric uwm;
  if(metric == "ROLLBACKS")
    uwm = DVFSManager::ROLLBACKS;
  else if(metric == "ROLLBACKFRACTION")
    uwm = DVFSManager::ROLLBACK_FRACTION;
  else if(metric == "EFFECTIVEUTILIZATION")
    uwm = DVFSManager::EFFECTIVE_UTILIZATION;
  else {
    stringstream err;
    err << "DVFSManager: UsefulWorkMetric " << metric << " is invalid. "
        << "Valid metrics are Rollbacks | EffectiveUtilization "
        << "| RollbackFraction. Aborting simulation." << endl;
    mySimulationManager->shutdown(err.str());
  }

  DVFSManager::OptimizationGoal og;
  if(opt == "PERFORMANCE")
    og = DVFSManager::PERFORMANCE;
  else if(opt == "POWER")
    og = DVFSManager::POWER;
  else if(opt == "HYBRID")
    og = DVFSManager::HYBRID;
  else {
    stringstream err;
    err << "DVFSManager: OptimizeFor " << opt << " is invalid. "
        << "Valid options are Performance | Power | Hybrid. "
        << "Aborting simulation." << endl;
    mySimulationManager->shutdown(err.str());
  }

  const char* trueFalseOptions[] = {"Fixed", "DebugPrint"};
  int numTrueFalse = sizeof(trueFalseOptions) / sizeof(const char*);
  bool trueFalseValues[numTrueFalse];
  for(int i=0; i < numTrueFalse; i++) {
    string val = "FALSE";
    configuration.getDVFSStringOption(trueFalseOptions[i], val);
    if(val != "TRUE" && val != "FALSE") {
      stringstream err;
      err << "DVFSManager: option " << trueFalseOptions[i]
          << " is invalid. Expected True / False.  Aborting simulation."
          << endl;
      mySimulationManager->shutdown(err.str());
    }
    trueFalseValues[i] = val == "TRUE";
  }

  if(type == "REAL" || type == "SIMULATED") {
    cout << "("
         << mySimulationManager->getSimulationManagerID()
         << ") configured a " << type << " DVFS Manager" << endl
         << "Fixed: " << (trueFalseValues[0] ? "True" : "False") << endl
         << "Period: " << p << endl
         << "FIR Size: " << firsize << endl
         << "Optimize for: " << opt << endl
         << "Useful work metric: " << metric << endl;
         if(trueFalseValues[1])
           cout <<  "Writing trace to csv" << endl;

    if(type == "REAL")
      return new RealDVFSManager(mySimulationManager,
                                 p,
                                 firsize,
                                 trueFalseValues[0],
                                 trueFalseValues[1],
                                 og,
                                 uwm);

    return new SimulatedDVFSManager(mySimulationManager,
                                    p,
                                    firsize,
                                    trueFalseValues[0],
                                    trueFalseValues[1],
                                    og,
                                    uwm);
  }
  else {
    stringstream err;
    cerr << "DVFSManager: invalid type '" << type << "'." << endl
         << "Valid types are None | Real | Simulated. Aborting simulation.";
    mySimulationManager->shutdown(err.str());
  }
}

const DVFSManagerFactory *
DVFSManagerFactory::instance(){
  static DVFSManagerFactory *singleton = new DVFSManagerFactory();
  return singleton;
}
<|endoftext|>