code:
//
// Copyright (c) Antony Polukhin, 2012-2016.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
#define BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP

/// \file compile_time_type_info.hpp
/// \brief Contains helper macros and implementation details of boost::typeindex::ctti_type_index.
/// Not intended for inclusion from user's code.

#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/mpl/bool.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

/// @cond
#define BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(begin_skip, end_skip, runtime_skip, runtime_skip_until)   \
    namespace boost { namespace typeindex { namespace detail {                                                  \
        BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_begin  = begin_skip;                               \
        BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_end    = end_skip;                                 \
        BOOST_STATIC_CONSTEXPR bool ctti_skip_more_at_runtime       = runtime_skip;                             \
        BOOST_STATIC_CONSTEXPR char ctti_skip_until_runtime[]       = runtime_skip_until;                       \
    }}} /* namespace boost::typeindex::detail */                                                                \
    /**/
/// @endcond

#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
    /* Nothing to document. All the macro docs are moved to <boost/type_index.hpp> */
#elif defined(BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING)
#   include <boost/preprocessor/facilities/expand.hpp>
    BOOST_PP_EXPAND( BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING )
#elif defined(_MSC_VER) && defined (BOOST_NO_CXX11_NOEXCEPT)
    // sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void)") - 1
    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "")
#elif defined(_MSC_VER) && !defined (BOOST_NO_CXX11_NOEXCEPT)
    // sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void) noexcept") - 1
    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 19, false, "")
#elif defined(__clang__) && defined(__APPLE__)
    // Someone made __clang_major__ equal to LLVM version rather than compiler version
    // on APPLE platform.
    //
    // Using less efficient solution because there is no good way to detect real version of Clang.
    // sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "???????????>::n() [T = int"
    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
#elif defined(__clang__) && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ == 0))
    // sizeof("static const char *boost::detail::ctti<") - 1, sizeof(">::n()") - 1
    // note: checked on 3.0
    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "")
#elif defined(__clang__) && (__clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ > 0))
    // sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "int>::n() [T = int"
    // note: checked on 3.1, 3.4
    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
#elif defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
    // sizeof("static contexpr char boost::detail::ctti<T>::s() [with unsigned int I = 0u; T = ") - 1, sizeof("]") - 1
    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(81, 1, false, "")
#elif defined(__GNUC__) && defined(BOOST_NO_CXX14_CONSTEXPR)
    // sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
#else
    // Deafult code for other platforms... Just skip nothing!
    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "")
#endif

#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS

namespace boost { namespace typeindex { namespace detail {
    template <bool Condition>
    BOOST_CXX14_CONSTEXPR inline void assert_compile_time_legths() BOOST_NOEXCEPT {
        BOOST_STATIC_ASSERT_MSG(
            Condition,
            "TypeIndex library is misconfigured for your compiler. "
            "Please define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct values. See section "
            "'RTTI emulation limitations' of the documentation for more information."
        );
    }

    template <class T>
    BOOST_CXX14_CONSTEXPR inline void failed_to_get_function_name() BOOST_NOEXCEPT {
        BOOST_STATIC_ASSERT_MSG(
            sizeof(T) && false,
            "TypeIndex library could not detect your compiler. "
            "Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use "
            "correct compiler macro for getting the whole function name. "
            "Define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct value after that."
        );
    }

    template <unsigned int ArrayLength>
    BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::mpl::false_) BOOST_NOEXCEPT {
        return begin;
    }

    template<class ForwardIterator1, class ForwardIterator2>
    BOOST_CXX14_CONSTEXPR inline ForwardIterator1 constexpr_search(
        ForwardIterator1 first1,
        ForwardIterator1 last1,
        ForwardIterator2 first2,
        ForwardIterator2 last2) BOOST_NOEXCEPT
    {
        if (first2 == last2) {
            return first1;  // specified in C++11
        }

        while (first1 != last1) {
            ForwardIterator1 it1 = first1;
            ForwardIterator2 it2 = first2;

            while (*it1 == *it2) {
                ++it1;
                ++it2;
                if (it2 == last2) return first1;
                if (it1 == last1) return last1;
            }

            ++first1;
        }

        return last1;
    }

    BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp(const char *v1, const char *v2) BOOST_NOEXCEPT {
        while (*v1 != '\0' && *v1 == *v2) {
            ++v1;
            ++v2;
        };

        return static_cast<int>(*v1) - *v2;
    }

    template <unsigned int ArrayLength>
    BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::mpl::true_) BOOST_NOEXCEPT {
        const char* const it = constexpr_search(
            begin, begin + ArrayLength,
            ctti_skip_until_runtime, ctti_skip_until_runtime + sizeof(ctti_skip_until_runtime) - 1
        );
        return (it == begin + ArrayLength ? begin : it + sizeof(ctti_skip_until_runtime) - 1);
    }

    template <unsigned int ArrayLength>
    BOOST_CXX14_CONSTEXPR inline const char* skip_begining(const char* begin) BOOST_NOEXCEPT {
        assert_compile_time_legths<(ArrayLength > ctti_skip_size_at_begin + ctti_skip_size_at_end)>();
        return skip_begining_runtime<ArrayLength - ctti_skip_size_at_begin>(
            begin + ctti_skip_size_at_begin,
            boost::mpl::bool_<ctti_skip_more_at_runtime>()
        );
    }

#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
    template <unsigned int... I>
    struct index_seq {};

    template <typename Left, typename Right>
    struct make_index_sequence_join;

    template <unsigned int... Left, unsigned int... Right>
    struct make_index_sequence_join<index_seq<Left...>, index_seq<Right...> > {
        typedef index_seq<Left..., Right...> type;
    };

    template <unsigned int C, unsigned int D>
    struct make_index_seq_impl {
        typedef typename make_index_sequence_join<
            typename make_index_seq_impl<C, D / 2>::type,
            typename make_index_seq_impl<C + D / 2, (D + 1) / 2>::type
        >::type type;
    };

    template <unsigned int C>
    struct make_index_seq_impl<C, 0> {
        typedef index_seq<> type;
    };

    template <unsigned int C>
    struct make_index_seq_impl<C, 1> {
        typedef index_seq<C> type;
    };

    template <char... C>
    struct cstring {
        static constexpr unsigned int size_ = sizeof...(C);
        static constexpr char data_[size_] = { C... };
    };

    template <char... C>
    constexpr char cstring<C...>::data_[];
#endif

}}} // namespace boost::typeindex::detail

namespace boost { namespace detail {

/// Noncopyable type_info that does not require RTTI.
/// CTTI == Compile Time Type Info.
/// This name must be as short as possible, to avoid code bloat
template <class T>
struct ctti {

#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
    //helper functions
    template <unsigned int I>
    constexpr static char s() BOOST_NOEXCEPT { // step
        constexpr unsigned int offset =
                  (I >= 10u      ? 1u : 0u)
                + (I >= 100u     ? 1u : 0u)
                + (I >= 1000u    ? 1u : 0u)
                + (I >= 10000u   ? 1u : 0u)
                + (I >= 100000u  ? 1u : 0u)
                + (I >= 1000000u ? 1u : 0u)
        ;

    #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
        return BOOST_TYPE_INDEX_FUNCTION_SIGNATURE[I + offset];
    #elif defined(__FUNCSIG__)
        return __FUNCSIG__[I + offset];
    #else
        return __PRETTY_FUNCTION__[I + offset];
    #endif
    }

    template <unsigned int ...Indexes>
    constexpr static const char* impl(::boost::typeindex::detail::index_seq<Indexes...> ) BOOST_NOEXCEPT {
        return ::boost::typeindex::detail::cstring<s<Indexes>()...>::data_;
    }

    template <unsigned int D = 0> // `D` means `Dummy`
    constexpr static const char* n() BOOST_NOEXCEPT {
    #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
        constexpr unsigned int size = sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
    #elif defined(__FUNCSIG__)
        constexpr unsigned int size = sizeof(__FUNCSIG__);
    #elif defined(__PRETTY_FUNCTION__) \
                    || defined(__GNUC__) \
                    || (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
                    || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
                    || (defined(__ICC) && (__ICC >= 600)) \
                    || defined(__ghs__) \
                    || defined(__DMC__)
        constexpr unsigned int size = sizeof(__PRETTY_FUNCTION__);
    #else
        boost::typeindex::detail::failed_to_get_function_name();
    #endif

        boost::typeindex::detail::assert_compile_time_legths<
            (size > boost::typeindex::detail::ctti_skip_size_at_begin + boost::typeindex::detail::ctti_skip_size_at_end + sizeof("const *") - 1)
        >();
        static_assert(!boost::typeindex::detail::ctti_skip_more_at_runtime, "Skipping for GCC in C++14 mode is unsupported");

        typedef typename boost::typeindex::detail::make_index_seq_impl<
            boost::typeindex::detail::ctti_skip_size_at_begin,
            size - sizeof("const *") + 1 - boost::typeindex::detail::ctti_skip_size_at_begin
        >::type idx_seq;
        return impl(idx_seq());
    }
#else
    /// Returns raw name. Must be as short, as possible, to avoid code bloat
    BOOST_CXX14_CONSTEXPR static const char* n() BOOST_NOEXCEPT {
    #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
        return boost::typeindex::detail::skip_begining< sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) >(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
    #elif defined(__FUNCSIG__)
        return boost::typeindex::detail::skip_begining< sizeof(__FUNCSIG__) >(__FUNCSIG__);
    #elif defined(__PRETTY_FUNCTION__) \
                || defined(__GNUC__) \
                || (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
                || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
                || (defined(__ICC) && (__ICC >= 600)) \
                || defined(__ghs__) \
                || defined(__DMC__)
        return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__);
    #else
        boost::typeindex::detail::failed_to_get_function_name();
        return "";
    #endif
    }
#endif
};

}} // namespace boost::detail

#endif // BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP


code:
//
// Copyright (c) Antony Polukhin, 2013-2014.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
#define BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP

/// \file ctti_register_class.hpp
/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CLASS macro implementation that uses boost::typeindex::ctti_type_index.
/// Not intended for inclusion from user's code.

#include <boost/type_index/ctti_type_index.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

namespace boost { namespace typeindex { namespace detail {

template <class T>
inline const ctti_data& ctti_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
    return ctti_construct<T>();
}

}}} // namespace boost::typeindex::detail

/// @cond
#define BOOST_TYPE_INDEX_REGISTER_CLASS                                                                             \
    virtual const boost::typeindex::detail::ctti_data& boost_type_index_type_id_runtime_() const BOOST_NOEXCEPT {   \
        return boost::typeindex::detail::ctti_construct_typeid_ref(this);                                           \
    }                                                                                \
/**/
/// @endcond

#endif // BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP

license: mit


code:
//
// Copyright (c) Antony Polukhin, 2013-2014.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP
#define BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP

/// \file stl_register_class.hpp
/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CLASS macro implementation that uses boost::typeindex::stl_type_index.
/// Not intended for inclusion from user's code.

#include <boost/type_index/stl_type_index.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

namespace boost { namespace typeindex { namespace detail {

template <class T>
inline const stl_type_index::type_info_t& stl_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
    return typeid(T);
}

}}} // namespace boost::typeindex::detail

/// @cond
#define BOOST_TYPE_INDEX_REGISTER_CLASS                                                                                \
    virtual const boost::typeindex::stl_type_index::type_info_t& boost_type_index_type_id_runtime_() const BOOST_NOEXCEPT { \
        return boost::typeindex::detail::stl_construct_typeid_ref(this);                                                    \
    }                                                                                \
/**/
/// @endcond

#endif // BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP


code:
//
// Copyright (c) Antony Polukhin, 2013-2015.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP

/// \file stl_type_index.hpp
/// \brief Contains boost::typeindex::stl_type_index class.
///
/// boost::typeindex::stl_type_index class can be used as a drop-in replacement
/// for std::type_index.
///
/// It is used in situations when RTTI is enabled or typeid() method is available.
/// When typeid() is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro
/// is defined boost::typeindex::ctti is usually used instead of boost::typeindex::stl_type_index.

#include <boost/type_index/type_index_facade.hpp>

// MSVC is capable of calling typeid(T) even when RTTI is off
#if defined(BOOST_NO_RTTI) && !defined(BOOST_MSVC)
#error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available."
#endif

#include <typeinfo>
#include <cstring>                                  // std::strcmp, std::strlen, std::strstr
#include <stdexcept>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
#include <boost/core/demangle.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>

#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
        || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
#   include <boost/type_traits/is_signed.hpp>
#   include <boost/type_traits/make_signed.hpp>
#   include <boost/mpl/identity.hpp>
#endif

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

namespace boost { namespace typeindex {

/// \class stl_type_index
/// This class is a wrapper around std::type_info, that workarounds issues and provides
/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade.
///
/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index.
class stl_type_index
    : public type_index_facade<
        stl_type_index,
        #ifdef BOOST_NO_STD_TYPEINFO
            type_info
        #else
            std::type_info
        #endif
    >
{
public:
#ifdef BOOST_NO_STD_TYPEINFO
    typedef type_info type_info_t;
#else
    typedef std::type_info type_info_t;
#endif

private:
    const type_info_t* data_;

public:
    inline stl_type_index() BOOST_NOEXCEPT
        : data_(&typeid(void))
    {}

    inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT
        : data_(&data)
    {}

    inline const type_info_t&  type_info() const BOOST_NOEXCEPT;

    inline const char*  raw_name() const BOOST_NOEXCEPT;
    inline const char*  name() const BOOST_NOEXCEPT;
    inline std::string  pretty_name() const;

    inline std::size_t  hash_code() const BOOST_NOEXCEPT;
    inline bool         equal(const stl_type_index& rhs) const BOOST_NOEXCEPT;
    inline bool         before(const stl_type_index& rhs) const BOOST_NOEXCEPT;

    template <class T>
    inline static stl_type_index type_id() BOOST_NOEXCEPT;

    template <class T>
    inline static stl_type_index type_id_with_cvr() BOOST_NOEXCEPT;

    template <class T>
    inline static stl_type_index type_id_runtime(const T& value) BOOST_NOEXCEPT;
};

inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT {
    return *data_;
}

inline const char* stl_type_index::raw_name() const BOOST_NOEXCEPT {
#ifdef _MSC_VER
    return data_->raw_name();
#else
    return data_->name();
#endif
}

inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
    return data_->name();
}

inline std::string stl_type_index::pretty_name() const {
    static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
    static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1;

    // In case of MSVC demangle() is a no-op, and name() already returns demangled name.
    // In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it.
    const boost::core::scoped_demangled_name demangled_name(data_->name());

    const char* begin = demangled_name.get();
    if (!begin) {
        boost::throw_exception(std::runtime_error("Type name demangling failed"));
    }

    const std::string::size_type len = std::strlen(begin);
    const char* end = begin + len;

    if (len > cvr_saver_name_len) {
        const char* b = std::strstr(begin, cvr_saver_name);
        if (b) {
            b += cvr_saver_name_len;

            // Trim leading spaces
            while (*b == ' ') {         // the string is zero terminated, we won't exceed the buffer size
                ++ b;
            }

            // Skip the closing angle bracket
            const char* e = end - 1;
            while (e > b && *e != '>') {
                -- e;
            }

            // Trim trailing spaces
            while (e > b && *(e - 1) == ' ') {
                -- e;
            }

            if (b < e) {
                // Parsing seems to have succeeded, the type name is not empty
                begin = b;
                end = e;
            }
        }
    }

    return std::string(begin, end);
}

inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
#if _MSC_VER > 1600 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__))
    return data_->hash_code();
#else
    return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
#endif
}

/// @cond

// for this compiler at least, cross-shared-library type_info
// comparisons don't work, so we are using typeid(x).name() instead.
# if (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))) \
    || defined(_AIX) \
    || (defined(__sgi) && defined(__host_mips)) \
    || (defined(__hpux) && defined(__HP_aCC)) \
    || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
#  define BOOST_CLASSINFO_COMPARE_BY_NAMES
# endif

/// @endcond

inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEPT {
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
    return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
#else
    return !!(*data_ == *rhs.data_);
#endif
}

inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT {
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
    return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
#else
    return !!data_->before(*rhs.data_);
#endif
}

#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
#undef BOOST_CLASSINFO_COMPARE_BY_NAMES
#endif

template <class T>
inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT {
    typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
    typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_prefinal_t;

    #  if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
        || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)

        // Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral'
        // in typeid() expressions. Full template specialization for 'integral' fixes that issue:
        typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
            boost::is_signed<no_cvr_prefinal_t>,
            boost::make_signed<no_cvr_prefinal_t>,
            boost::mpl::identity<no_cvr_prefinal_t>
        >::type no_cvr_prefinal_lazy_t;

        typedef BOOST_DEDUCED_TYPENAME no_cvr_prefinal_t::type no_cvr_t;
    #else
        typedef no_cvr_prefinal_t no_cvr_t;
    #endif

    return typeid(no_cvr_t);
}

namespace detail {
    template <class T> class cvr_saver{};
}

template <class T>
inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
    typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
        boost::mpl::or_<boost::is_reference<T>, boost::is_const<T>, boost::is_volatile<T> >,
        detail::cvr_saver<T>,
        T
    >::type type;

    return typeid(type);
}

template <class T>
inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEXCEPT {
#ifdef BOOST_NO_RTTI
    return value.boost_type_index_type_id_runtime_();
#else
    return typeid(value);
#endif
}

}} // namespace boost::typeindex

#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP


code:
//
// Copyright (c) Antony Polukhin, 2013-2015.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP

#include <boost/config.hpp>
#include <string>
#include <cstring>

#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
#include <iosfwd>               // for std::basic_ostream
#else
#include <ostream>
#endif
#endif

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

// Forward declaration from #include <boost/functional/hash_fwd.hpp>
namespace boost {
    template <class It> std::size_t hash_range(It, It);
}

namespace boost { namespace typeindex {

/// \class type_index_facade
///
/// This class takes care about the comparison operators, hash functions and
/// ostream operators. Use this class as a public base class for defining new
/// type_info-conforming classes.
///
/// \b Example:
/// \code
/// class stl_type_index: public type_index_facade<stl_type_index, std::type_info>
/// {
/// public:
///     typedef std::type_info type_info_t;
/// private:
///     const type_info_t* data_;
///
/// public:
///     stl_type_index(const type_info_t& data) noexcept
///         : data_(&data)
///     {}
/// // ...
/// };
/// \endcode
///
/// \tparam Derived Class derived from type_index_facade.
/// \tparam TypeInfo Class that will be used as a base type_info class.
/// \note Take a look at the protected methods. They are \b not \b defined in type_index_facade.
/// Protected member functions raw_name() \b must be defined in Derived class. All the other
/// methods are mandatory.
/// \see 'Making a custom type_index' section for more information about
/// creating your own type_index using type_index_facade.
template <class Derived, class TypeInfo>
class type_index_facade {
private:
    /// @cond
    BOOST_CXX14_CONSTEXPR const Derived & derived() const BOOST_NOEXCEPT {
      return *static_cast<Derived const*>(this);
    }
    /// @endcond
public:
    typedef TypeInfo                                type_info_t;

    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
    /// \return Name of a type. By default returns Derived::raw_name().
    inline const char* name() const BOOST_NOEXCEPT {
        return derived().raw_name();
    }

    /// \b Override: This function \b may be redefined in Derived class. Overrides may throw.
    /// \return Human readable type name. By default returns Derived::name().
    inline std::string pretty_name() const {
        return derived().name();
    }

    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
    /// \return True if two types are equal. By default compares types by raw_name().
    inline bool equal(const Derived& rhs) const BOOST_NOEXCEPT {
        const char* const left = derived().raw_name();
        const char* const right = rhs.raw_name();
        return left == right || !std::strcmp(left, right);
    }

    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
    /// \return True if rhs is greater than this. By default compares types by raw_name().
    inline bool before(const Derived& rhs) const BOOST_NOEXCEPT {
        const char* const left = derived().raw_name();
        const char* const right = rhs.raw_name();
        return left != right && std::strcmp(left, right) < 0;
    }

    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
    /// \return Hash code of a type. By default hashes types by raw_name().
    /// \note <boost/functional/hash.hpp> has to be included if this function is used.
    inline std::size_t hash_code() const BOOST_NOEXCEPT {
        const char* const name_raw = derived().raw_name();
        return boost::hash_range(name_raw, name_raw + std::strlen(name_raw));
    }

#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
protected:
    /// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
    /// \return Pointer to unredable/raw type name.
    inline const char* raw_name() const BOOST_NOEXCEPT;

    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
    /// \return Const reference to underlying low level type_info_t.
    inline const type_info_t& type_info() const BOOST_NOEXCEPT;

    /// This is a factory method that is used to create instances of Derived classes.
    /// boost::typeindex::type_id() will call this method, if Derived has same type as boost::typeindex::type_index.
    ///
    /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
    /// Overrides \b must remove const, volatile && and & modifiers from T.
    /// \tparam T Type for which type_index must be created.
    /// \return type_index for type T.
    template <class T>
    static Derived type_id() BOOST_NOEXCEPT;

    /// This is a factory method that is used to create instances of Derived classes.
    /// boost::typeindex::type_id_with_cvr() will call this method, if Derived has same type as boost::typeindex::type_index.
    ///
    /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
    /// Overrides \b must \b not remove const, volatile && and & modifiers from T.
    /// \tparam T Type for which type_index must be created.
    /// \return type_index for type T.
    template <class T>
    static Derived type_id_with_cvr() BOOST_NOEXCEPT;

    /// This is a factory method that is used to create instances of Derived classes.
    /// boost::typeindex::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeindex::type_index.
    ///
    /// \b Override: This function \b may be redefined and made public in Derived class.
    /// \param variable Variable which runtime type will be stored in type_index.
    /// \return type_index with runtime type of variable.
    template <class T>
    static Derived type_id_runtime(const T& variable) BOOST_NOEXCEPT;

#endif

};

/// @cond
template <class Derived, class TypeInfo>
BOOST_CXX14_CONSTEXPR inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return static_cast<Derived const&>(lhs).equal(static_cast<Derived const&>(rhs));
}

template <class Derived, class TypeInfo>
BOOST_CXX14_CONSTEXPR inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return static_cast<Derived const&>(lhs).before(static_cast<Derived const&>(rhs));
}

template <class Derived, class TypeInfo>
BOOST_CXX14_CONSTEXPR inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return rhs < lhs;
}

template <class Derived, class TypeInfo>
BOOST_CXX14_CONSTEXPR inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return !(lhs > rhs);
}

template <class Derived, class TypeInfo>
BOOST_CXX14_CONSTEXPR inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return !(lhs < rhs);
}

template <class Derived, class TypeInfo>
BOOST_CXX14_CONSTEXPR inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return !(lhs == rhs);
}

// ######################### COMPARISONS with Derived ############################ //
template <class Derived, class TypeInfo>
inline bool operator == (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return Derived(lhs) == rhs;
}

template <class Derived, class TypeInfo>
inline bool operator < (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return Derived(lhs) < rhs;
}

template <class Derived, class TypeInfo>
inline bool operator > (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return rhs < Derived(lhs);
}

template <class Derived, class TypeInfo>
inline bool operator <= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return !(Derived(lhs) > rhs);
}

template <class Derived, class TypeInfo>
inline bool operator >= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return !(Derived(lhs) < rhs);
}

template <class Derived, class TypeInfo>
inline bool operator != (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
    return !(Derived(lhs) == rhs);
}

template <class Derived, class TypeInfo>
inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
    return lhs == Derived(rhs);
}

template <class Derived, class TypeInfo>
inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
    return lhs < Derived(rhs);
}

template <class Derived, class TypeInfo>
inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
    return Derived(rhs) < lhs;
}

template <class Derived, class TypeInfo>
inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
    return !(lhs > Derived(rhs));
}

template <class Derived, class TypeInfo>
inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
    return !(lhs < Derived(rhs));
}

template <class Derived, class TypeInfo>
inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
    return !(lhs == Derived(rhs));
}

// ######################### COMPARISONS with Derived END ############################ //

/// @endcond

#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)

/// noexcept comparison operators for type_index_facade classes.
bool operator ==, !=, <, ... (const type_index_facade& lhs, const type_index_facade& rhs) noexcept;

/// noexcept comparison operators for type_index_facade and it's TypeInfo classes.
bool operator ==, !=, <, ... (const type_index_facade& lhs, const TypeInfo& rhs) noexcept;

/// noexcept comparison operators for type_index_facade's TypeInfo and type_index_facade classes.
bool operator ==, !=, <, ... (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;

#endif

#ifndef BOOST_NO_IOSTREAM
#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
/// @cond
/// Ostream operator that will output demangled name
template <class Derived, class TypeInfo>
inline std::ostream& operator<<(std::ostream& ostr, const type_index_facade<Derived, TypeInfo>& ind) {
    ostr << static_cast<Derived const&>(ind).pretty_name();
    return ostr;
}
/// @endcond
#else
/// Ostream operator that will output demangled name.
template <class CharT, class TriatT, class Derived, class TypeInfo>
inline std::basic_ostream<CharT, TriatT>& operator<<(
    std::basic_ostream<CharT, TriatT>& ostr,
    const type_index_facade<Derived, TypeInfo>& ind)
{
    ostr << static_cast<Derived const&>(ind).pretty_name();
    return ostr;
}
#endif // BOOST_NO_TEMPLATED_IOSTREAMS
#endif // BOOST_NO_IOSTREAM

/// This free function is used by Boost's unordered containers.
/// \note <boost/functional/hash.hpp> has to be included if this function is used.
template <class Derived, class TypeInfo>
inline std::size_t hash_value(const type_index_facade<Derived, TypeInfo>& lhs) BOOST_NOEXCEPT {
    return static_cast<Derived const&>(lhs).hash_code();
}

}} // namespace boost::typeindex

#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP


code:
//  (C) Copyright John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

//  See boost/type_traits/*.hpp for full copyright notices.

#ifndef BOOST_TYPE_TRAITS_HPP
#define BOOST_TYPE_TRAITS_HPP

#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_cv.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_rvalue_reference.hpp>
#include <boost/type_traits/add_volatile.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/common_type.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/copy_cv.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/extent.hpp>
#include <boost/type_traits/floating_point_promotion.hpp>
#include <boost/type_traits/function_traits.hpp>

#include <boost/type_traits/has_bit_and.hpp>
#include <boost/type_traits/has_bit_and_assign.hpp>
#include <boost/type_traits/has_bit_or.hpp>
#include <boost/type_traits/has_bit_or_assign.hpp>
#include <boost/type_traits/has_bit_xor.hpp>
#include <boost/type_traits/has_bit_xor_assign.hpp>
#include <boost/type_traits/has_complement.hpp>
#include <boost/type_traits/has_dereference.hpp>
#include <boost/type_traits/has_divides.hpp>
#include <boost/type_traits/has_divides_assign.hpp>
#include <boost/type_traits/has_equal_to.hpp>
#include <boost/type_traits/has_greater.hpp>
#include <boost/type_traits/has_greater_equal.hpp>
#include <boost/type_traits/has_left_shift.hpp>
#include <boost/type_traits/has_left_shift_assign.hpp>
#include <boost/type_traits/has_less.hpp>
#include <boost/type_traits/has_less_equal.hpp>
#include <boost/type_traits/has_logical_and.hpp>
#include <boost/type_traits/has_logical_not.hpp>
#include <boost/type_traits/has_logical_or.hpp>
#include <boost/type_traits/has_minus.hpp>
#include <boost/type_traits/has_minus_assign.hpp>
#include <boost/type_traits/has_modulus.hpp>
#include <boost/type_traits/has_modulus_assign.hpp>
#include <boost/type_traits/has_multiplies.hpp>
#include <boost/type_traits/has_multiplies_assign.hpp>
#include <boost/type_traits/has_negate.hpp>
#if !defined(__BORLANDC__) && !defined(__CUDACC__)
#include <boost/type_traits/has_new_operator.hpp>
#endif
#include <boost/type_traits/has_not_equal_to.hpp>
#include <boost/type_traits/has_nothrow_assign.hpp>
#include <boost/type_traits/has_nothrow_constructor.hpp>
#include <boost/type_traits/has_nothrow_copy.hpp>
#include <boost/type_traits/has_nothrow_destructor.hpp>
#include <boost/type_traits/has_plus.hpp>
#include <boost/type_traits/has_plus_assign.hpp>
#include <boost/type_traits/has_post_decrement.hpp>
#include <boost/type_traits/has_post_increment.hpp>
#include <boost/type_traits/has_pre_decrement.hpp>
#include <boost/type_traits/has_pre_increment.hpp>
#include <boost/type_traits/has_right_shift.hpp>
#include <boost/type_traits/has_right_shift_assign.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/has_trivial_move_assign.hpp>
#include <boost/type_traits/has_trivial_move_constructor.hpp>
#include <boost/type_traits/has_unary_minus.hpp>
#include <boost/type_traits/has_unary_plus.hpp>
#include <boost/type_traits/has_virtual_destructor.hpp>

#include <boost/type_traits/integral_constant.hpp>

#include <boost/type_traits/is_abstract.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_assignable.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_complex.hpp>
#include <boost/type_traits/is_compound.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_constructible.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_copy_assignable.hpp>
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/type_traits/is_default_constructible.hpp>
#include <boost/type_traits/is_destructible.hpp>
#include <boost/type_traits/is_empty.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_final.hpp>
#include <boost/type_traits/is_float.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/type_traits/is_member_object_pointer.hpp>
#include <boost/type_traits/is_member_pointer.hpp>
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include <boost/type_traits/is_object.hpp>
#include <boost/type_traits/is_pod.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_rvalue_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/is_stateless.hpp>
#include <boost/type_traits/is_union.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/type_traits/is_virtual_base_of.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/make_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/rank.hpp>
#include <boost/type_traits/remove_all_extents.hpp>
#include <boost/type_traits/remove_bounds.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_volatile.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/type_traits/type_with_alignment.hpp>

#if !(defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238))
#include <boost/type_traits/integral_promotion.hpp>
#include <boost/type_traits/promote.hpp>
#endif

#endif // BOOST_TYPE_TRAITS_HPP


code:
//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
//  Hinnant & John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_ADD_CONST_HPP_INCLUDED
#define BOOST_TT_ADD_CONST_HPP_INCLUDED

#include <boost/type_traits/detail/config.hpp>

namespace boost {

// * convert a type T to const type - add_const<T>
// this is not required since the result is always
// the same as "T const", but it does suppress warnings
// from some compilers:

#if defined(BOOST_MSVC)
// This bogus warning will appear when add_const is applied to a
// const volatile reference because we can't detect const volatile
// references with MSVC6.
#   pragma warning(push)
#   pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored
#endif

   template <class T> struct add_const
   {
      typedef T const type;
   };

#if defined(BOOST_MSVC)
#   pragma warning(pop)
#endif

   template <class T> struct add_const<T&>
   {
      typedef T& type;
   };

} // namespace boost

#endif // BOOST_TT_ADD_CONST_HPP_INCLUDED


code:
//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
//  Hinnant & John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_ADD_CV_HPP_INCLUDED
#define BOOST_TT_ADD_CV_HPP_INCLUDED

#include <boost/config.hpp>

namespace boost {

// * convert a type T to a const volatile type - add_cv<T>
// this is not required since the result is always
// the same as "T const volatile", but it does suppress warnings
// from some compilers:

#if defined(BOOST_MSVC)
// This bogus warning will appear when add_volatile is applied to a
// const volatile reference because we can't detect const volatile
// references with MSVC6.
#   pragma warning(push)
#   pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored
#endif

template <class T> struct add_cv{ typedef T const volatile type; };

#if defined(BOOST_MSVC)
#   pragma warning(pop)
#endif

template <class T> struct add_cv<T&>{ typedef T& type; };

} // namespace boost

#endif // BOOST_TT_ADD_CV_HPP_INCLUDED


code:
//  Copyright 2010 John Maddock

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

#ifndef BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP
#define BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP

#include <boost/type_traits/add_reference.hpp>

namespace boost{

template <class T> struct add_lvalue_reference
{
   typedef typename boost::add_reference<T>::type type;
};

#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class T> struct add_lvalue_reference<T&&>
{
   typedef T& type;
};
#endif

}

#endif  // BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP


code:
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_ADD_POINTER_HPP_INCLUDED
#define BOOST_TT_ADD_POINTER_HPP_INCLUDED

#include <boost/type_traits/remove_reference.hpp>

namespace boost {

#if defined(__BORLANDC__) && (__BORLANDC__ < 0x5A0)
//
// For some reason this implementation stops Borlands compiler
// from dropping cv-qualifiers, it still fails with references
// to arrays for some reason though (shrug...) (JM 20021104)
//
template <typename T>
struct add_pointer
{
    typedef T* type;
};
template <typename T>
struct add_pointer<T&>
{
    typedef T* type;
};
template <typename T>
struct add_pointer<T&const>
{
    typedef T* type;
};
template <typename T>
struct add_pointer<T&volatile>
{
    typedef T* type;
};
template <typename T>
struct add_pointer<T&const volatile>
{
    typedef T* type;
};

#else

template <typename T>
struct add_pointer
{
    typedef typename remove_reference<T>::type no_ref_type;
    typedef no_ref_type* type;
};

#endif

} // namespace boost

#endif // BOOST_TT_ADD_POINTER_HPP_INCLUDED


code:
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_ADD_REFERENCE_HPP_INCLUDED
#define BOOST_TT_ADD_REFERENCE_HPP_INCLUDED

#include <boost/detail/workaround.hpp>
#include <boost/config.hpp>

namespace boost {

namespace detail {

//
// We can't filter out rvalue_references at the same level as
// references or we get ambiguities from msvc:
//

template <typename T>
struct add_reference_impl
{
    typedef T& type;
};

#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename T>
struct add_reference_impl<T&&>
{
    typedef T&& type;
};
#endif

} // namespace detail

template <class T> struct add_reference
{
   typedef typename boost::detail::add_reference_impl<T>::type type;
};
template <class T> struct add_reference<T&>
{
   typedef T& type;
};

// these full specialisations are always required:
template <> struct add_reference<void> { typedef void type; };
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
template <> struct add_reference<const void> { typedef const void type; };
template <> struct add_reference<const volatile void> { typedef const volatile void type; };
template <> struct add_reference<volatile void> { typedef volatile void type; };
#endif

} // namespace boost

#endif // BOOST_TT_ADD_REFERENCE_HPP_INCLUDED


code:
//  add_rvalue_reference.hpp  ---------------------------------------------------------//

//  Copyright 2010 Vicente J. Botet Escriba

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

#ifndef BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP
#define BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP

#include <boost/config.hpp>

//----------------------------------------------------------------------------//

#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_reference.hpp>

//----------------------------------------------------------------------------//
//                                                                            //
//                           C++03 implementation of                          //
//             20.9.7.2 Reference modifications [meta.trans.ref]              //
//                          Written by Vicente J. Botet Escriba               //
//                                                                            //
// If T names an object or function type then the member typedef type
// shall name T&&; otherwise, type shall name T. [ Note: This rule reflects
// the semantics of reference collapsing. For example, when a type T names
// a type T1&, the type add_rvalue_reference<T>::type is not an rvalue
// reference. -end note ]
//----------------------------------------------------------------------------//

namespace boost {

namespace type_traits_detail {

    template <typename T, bool b>
    struct add_rvalue_reference_helper
    { typedef T   type; };

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    template <typename T>
    struct add_rvalue_reference_helper<T, true>
    {
        typedef T&&   type;
    };
#endif

    template <typename T>
    struct add_rvalue_reference_imp
    {
       typedef typename boost::type_traits_detail::add_rvalue_reference_helper
                  <T, (is_void<T>::value == false && is_reference<T>::value == false) >::type type;
    };

}

template <class T> struct add_rvalue_reference
{
   typedef typename boost::type_traits_detail::add_rvalue_reference_imp<T>::type type;
};

}  // namespace boost

#endif  // BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP


code:
//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
//  Hinnant & John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_ADD_VOLATILE_HPP_INCLUDED
#define BOOST_TT_ADD_VOLATILE_HPP_INCLUDED

#include <boost/config.hpp>

namespace boost {

// * convert a type T to volatile type - add_volatile<T>
// this is not required since the result is always
// the same as "T volatile", but it does suppress warnings
// from some compilers:

#if defined(BOOST_MSVC)
// This bogus warning will appear when add_volatile is applied to a
// const volatile reference because we can't detect const volatile
// references with MSVC6.
#   pragma warning(push)
#   pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored
#endif

template <class T> struct add_volatile{ typedef T volatile type; };

#if defined(BOOST_MSVC)
#   pragma warning(pop)
#endif

template <class T> struct add_volatile<T&>{ typedef T& type; };

} // namespace boost

#endif // BOOST_TT_ADD_VOLATILE_HPP_INCLUDED


code:
//-----------------------------------------------------------------------------
// boost aligned_storage.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2002-2003
// Eric Friedman, Itay Maman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_TT_ALIGNED_STORAGE_HPP
#define BOOST_TT_ALIGNED_STORAGE_HPP

#include <cstddef> // for std::size_t

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/type_traits/is_pod.hpp>
#include <boost/type_traits/conditional.hpp>

namespace boost {

namespace detail { namespace aligned_storage {

BOOST_STATIC_CONSTANT(
      std::size_t
    , alignment_of_max_align = ::boost::alignment_of<boost::detail::max_align>::value
    );

//
// To be TR1 conforming this must be a POD type:
//
template <
      std::size_t size_
    , std::size_t alignment_
>
struct aligned_storage_imp
{
    union data_t
    {
        char buf[size_];

        typename ::boost::type_with_alignment<alignment_>::type align_;
    } data_;
    void* address() const { return const_cast<aligned_storage_imp*>(this); }
};
template <std::size_t size>
struct aligned_storage_imp<size, std::size_t(-1)>
{
   union data_t
   {
      char buf[size];
      ::boost::detail::max_align align_;
   } data_;
   void* address() const { return const_cast<aligned_storage_imp*>(this); }
};

template< std::size_t alignment_ >
struct aligned_storage_imp<0u,alignment_>
{
    /* intentionally empty */
    void* address() const { return 0; }
};

}} // namespace detail::aligned_storage

template <
      std::size_t size_
    , std::size_t alignment_ = std::size_t(-1)
>
class aligned_storage :
#ifndef __BORLANDC__
   private
#else
   public
#endif
   ::boost::detail::aligned_storage::aligned_storage_imp<size_, alignment_>
{

public: // constants

    typedef ::boost::detail::aligned_storage::aligned_storage_imp<size_, alignment_> type;

    BOOST_STATIC_CONSTANT(
          std::size_t
        , size = size_
        );
    BOOST_STATIC_CONSTANT(
          std::size_t
        , alignment = (
              alignment_ == std::size_t(-1)
            ? ::boost::detail::aligned_storage::alignment_of_max_align
            : alignment_
            )
        );

private: // noncopyable

    aligned_storage(const aligned_storage&);
    aligned_storage& operator=(const aligned_storage&);

public: // structors

    aligned_storage()
    {
    }

    ~aligned_storage()
    {
    }

public: // accessors

    void* address()
    {
        return static_cast<type*>(this)->address();
    }

    const void* address() const
    {
        return static_cast<const type*>(this)->address();
    }
};

//
// Make sure that is_pod recognises aligned_storage<>::type
// as a POD (Note that aligned_storage<> itself is not a POD):
//
template <std::size_t size_, std::size_t alignment_>
struct is_pod< ::boost::detail::aligned_storage::aligned_storage_imp<size_, alignment_> > : public true_type{};

} // namespace boost

#endif // BOOST_ALIGNED_STORAGE_HPP


code:
//  (C) Copyright John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED
#define BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED

#include <boost/config.hpp>
#include <cstddef>

#include <boost/type_traits/intrinsics.hpp>
#include <boost/type_traits/integral_constant.hpp>

#ifdef BOOST_MSVC
#   pragma warning(push)
#   pragma warning(disable: 4121 4512) // alignment is sensitive to packing
#endif
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
#pragma option push -Vx- -Ve-
#endif

namespace boost {

template <typename T> struct alignment_of;

// get the alignment of some arbitrary type:
namespace detail {

#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4324) // structure was padded due to __declspec(align())
#endif
template <typename T>
struct alignment_of_hack
{
    char c;
    T t;
    alignment_of_hack();
};
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif

template <unsigned A, unsigned S>
struct alignment_logic
{
    BOOST_STATIC_CONSTANT(std::size_t, value = A < S ? A : S);
};

template< typename T >
struct alignment_of_impl
{
#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
    //
    // With MSVC both the native __alignof operator
    // and our own logic gets things wrong from time to time :-(
    // Using a combination of the two seems to make the most of a bad job:
    //
    BOOST_STATIC_CONSTANT(std::size_t, value =
        (::boost::detail::alignment_logic<
            sizeof(::boost::detail::alignment_of_hack<T>) - sizeof(T),
            __alignof(T)
        >::value));
#elif !defined(BOOST_ALIGNMENT_OF)
    BOOST_STATIC_CONSTANT(std::size_t, value =
        (::boost::detail::alignment_logic<
            sizeof(::boost::detail::alignment_of_hack<T>) - sizeof(T),
            sizeof(T)
        >::value));
#else
   //
   // We put this here, rather than in the definition of
   // alignment_of below, because MSVC's __alignof doesn't
   // always work in that context for some unexplained reason.
   // (See type_with_alignment tests for test cases).
   //
   BOOST_STATIC_CONSTANT(std::size_t, value = BOOST_ALIGNMENT_OF(T));
#endif
};

} // namespace detail

template <class T> struct alignment_of : public integral_constant<std::size_t, ::boost::detail::alignment_of_impl<T>::value>{};

// references have to be treated specially, assume
// that a reference is just a special pointer:
template <typename T> struct alignment_of<T&> : public alignment_of<T*>{};

#ifdef __BORLANDC__
// long double gives an incorrect value of 10 (!)
// unless we do this...
struct long_double_wrapper{ long double ld; };
template<> struct alignment_of<long double> : public alignment_of<long_double_wrapper>{};
#endif

// void has to be treated specially:
template<> struct alignment_of<void> : integral_constant<std::size_t, 0>{};
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
template<> struct alignment_of<void const> : integral_constant<std::size_t, 0>{};
template<> struct alignment_of<void const volatile> : integral_constant<std::size_t, 0>{};
template<> struct alignment_of<void volatile> : integral_constant<std::size_t, 0>{};
#endif

} // namespace boost

#if defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
#pragma option pop
#endif
#ifdef BOOST_MSVC
#   pragma warning(pop)
#endif

#endif // BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED


code:
//  (C) Copyright John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_ALIGNMENT_TRAITS_HPP_INCLUDED
#define BOOST_TT_ALIGNMENT_TRAITS_HPP_INCLUDED

#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/type_with_alignment.hpp>

#endif // BOOST_TT_ALIGNMENT_TRAITS_HPP_INCLUDED


code:
//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
//  Hinnant & John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_ARRAY_TRAITS_HPP_INCLUDED
#define BOOST_TT_ARRAY_TRAITS_HPP_INCLUDED

#include <boost/type_traits/is_array.hpp>

#endif // BOOST_TT_ARRAY_TRAITS_HPP_INCLUDED


code:
#ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED
#define BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED

//
//  Copyright 2015 Peter Dimov
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt
//

#include <boost/config.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/detail/workaround.hpp>

#if defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/type_traits/detail/common_type_impl.hpp>
#endif

#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/type_traits/detail/mp_defer.hpp>
#endif

namespace boost
{

// variadic common_type

#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)

template<class... T> struct common_type
{
};

#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)

template<class... T> using common_type_t = typename common_type<T...>::type;

namespace type_traits_detail
{

template<class T1, class T2, class... T> using common_type_fold = common_type_t<common_type_t<T1, T2>, T...>;

} // namespace type_traits_detail

template<class T1, class T2, class... T>
struct common_type<T1, T2, T...>: type_traits_detail::mp_defer<type_traits_detail::common_type_fold, T1, T2, T...>
{
};

#else

template<class T1, class T2, class... T>
struct common_type<T1, T2, T...>: common_type<typename common_type<T1, T2>::type, T...>
{
};

#endif // !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)

#else

template<
    class T1 = void, class T2 = void, class T3 = void,
    class T4 = void, class T5 = void, class T6 = void,
    class T7 = void, class T8 = void, class T9 = void
>
struct common_type: common_type<typename common_type<T1, T2>::type, T3, T4, T5, T6, T7, T8, T9>
{
};

#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)

// one argument

template<class T> struct common_type<T>: boost::decay<T>
{
};

// two arguments

namespace type_traits_detail
{

// binary common_type

#if !defined(BOOST_NO_CXX11_DECLTYPE)

#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)

#if !defined(BOOST_MSVC) || BOOST_MSVC > 1800

// internal compiler error on msvc-12.0

template<class T1, class T2> using builtin_common_type = typename boost::decay<decltype( boost::declval<bool>()? boost::declval<T1>(): boost::declval<T2>() )>::type;

template<class T1, class T2> struct common_type_impl: mp_defer<builtin_common_type, T1, T2>
{
};

#else

template<class T1, class T2> using builtin_common_type = decltype( boost::declval<bool>()? boost::declval<T1>(): boost::declval<T2>() );

template<class T1, class T2> struct common_type_impl_2: mp_defer<builtin_common_type, T1, T2>
{
};

template<class T1, class T2> using decay_common_type = typename boost::decay<typename common_type_impl_2<T1, T2>::type>::type;

template<class T1, class T2> struct common_type_impl: mp_defer<decay_common_type, T1, T2>
{
};

#endif // !defined(BOOST_MSVC) || BOOST_MSVC > 1800

#else

template<class T1, class T2> struct common_type_impl: boost::decay<decltype( boost::declval<bool>()? boost::declval<T1>(): boost::declval<T2>() )>
{
};

#endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)

#endif // #if !defined(BOOST_NO_CXX11_DECLTYPE)

// decay helper

template<class T1, class T2, class T1d = typename boost::decay<T1>::type, class T2d = typename boost::decay<T2>::type> struct common_type_decay_helper: boost::common_type<T1d, T2d>
{
};

template<class T1, class T2> struct common_type_decay_helper<T1, T2, T1, T2>: common_type_impl<T1, T2>
{
};

} // type_traits_detail

template<class T1, class T2> struct common_type<T1, T2>: type_traits_detail::common_type_decay_helper<T1, T2>
{
};

} // namespace boost

#endif // #ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP_INCLUDED


code:
//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
//  Hinnant & John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
//
//  defines traits classes for composite types:
//  is_array, is_pointer, is_reference, is_member_pointer, is_enum, is_union.
//

#ifndef BOOST_TT_COMPOSITE_TRAITS_HPP_INCLUDED
#define BOOST_TT_COMPOSITE_TRAITS_HPP_INCLUDED

#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_member_pointer.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_union.hpp>

#endif // BOOST_TT_COMPOSITE_TRAITS_HPP_INCLUDED


code:
//  (C) Copyright John Maddock 2010.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_CONDITIONAL_HPP_INCLUDED
#define BOOST_TT_CONDITIONAL_HPP_INCLUDED

namespace boost {

template <bool b, class T, class U> struct conditional { typedef T type; };
template <class T, class U> struct conditional<false, T, U> { typedef U type; };

} // namespace boost

#endif // BOOST_TT_CONDITIONAL_HPP_INCLUDED


code:
// Copyright 2000 John Maddock (john@johnmaddock.co.uk)
// Copyright 2000 Jeremy Siek (jsiek@lsc.nd.edu)
// Copyright 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_CONVERSION_TRAITS_HPP_INCLUDED
#define BOOST_TT_CONVERSION_TRAITS_HPP_INCLUDED

#include <boost/type_traits/is_convertible.hpp>

#endif // BOOST_TT_CONVERSION_TRAITS_HPP_INCLUDED


code:
#ifndef BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED
#define BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED

//
//  Copyright 2015 Peter Dimov
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt
//

#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_volatile.hpp>
#include <boost/type_traits/conditional.hpp>

namespace boost
{

template<class T, class U> struct copy_cv
{
private:

    typedef typename boost::conditional<boost::is_const<U>::value, typename boost::add_const<T>::type, T>::type CT;

public:

    typedef typename boost::conditional<boost::is_volatile<U>::value, typename boost::add_volatile<CT>::type, CT>::type type;
};

} // namespace boost

#endif // #ifndef BOOST_TYPE_TRAITS_COPY_CV_HPP_INCLUDED


code:
//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
//  Hinnant & John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
//
//  defines traits classes for cv-qualified types:
//  is_const, is_volatile, remove_const, remove_volatile, remove_cv.

#ifndef BOOST_TT_CV_TRAITS_HPP_INCLUDED
#define BOOST_TT_CV_TRAITS_HPP_INCLUDED

#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_volatile.hpp>
#include <boost/type_traits/add_cv.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_volatile.hpp>
#include <boost/type_traits/remove_cv.hpp>

#endif // BOOST_TT_CV_TRAITS_HPP_INCLUDED


code:
//  (C) Copyright John Maddock & Thorsten Ottosen 2005.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_DECAY_HPP_INCLUDED
#define BOOST_TT_DECAY_HPP_INCLUDED

#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/remove_bounds.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>

namespace boost
{

   namespace detail
   {

      template <class T, bool Array, bool Function> struct decay_imp { typedef typename remove_cv<T>::type type; };
      template <class T> struct decay_imp<T, true, false> { typedef typename remove_bounds<T>::type* type; };
      template <class T> struct decay_imp<T, false, true> { typedef T* type; };

   }

    template< class T >
    struct decay
    {
    private:
        typedef typename remove_reference<T>::type Ty;
    public:
       typedef typename boost::detail::decay_imp<Ty, boost::is_array<Ty>::value, boost::is_function<Ty>::value>::type type;
    };

} // namespace boost

#endif // BOOST_TT_DECAY_HPP_INCLUDED


code:
//  declval.hpp  -------------------------------------------------------------//

//  Copyright 2010 Vicente J. Botet Escriba

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

#ifndef BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED
#define BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED

#include <boost/config.hpp>

//----------------------------------------------------------------------------//

#include <boost/type_traits/add_rvalue_reference.hpp>

//----------------------------------------------------------------------------//
//                                                                            //
//                           C++03 implementation of                          //
//                   20.2.4 Function template declval [declval]               //
//                          Written by Vicente J. Botet Escriba               //
//                                                                            //
// 1 The library provides the function template declval to simplify the
// definition of expressions which occur as unevaluated operands.
// 2 Remarks: If this function is used, the program is ill-formed.
// 3 Remarks: The template parameter T of declval may be an incomplete type.
// [ Example:
//
// template <class To, class From>
// decltype(static_cast<To>(declval<From>())) convert(From&&);
//
// declares a function template convert which only participates in overloading
// if the type From can be explicitly converted to type To. For another example
// see class template common_type (20.9.7.6). -end example ]
//----------------------------------------------------------------------------//

namespace boost {

    template <typename T>
    typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand

}  // namespace boost

#endif  // BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED


code:
// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION

// Copyright Aleksey Gurtovoy 2002-2004
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// $Source$
// $Date$
// $Revision$

#undef BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL
#undef BOOST_TT_AUX_BOOL_C_BASE
#undef BOOST_TT_AUX_BOOL_TRAIT_DEF1
#undef BOOST_TT_AUX_BOOL_TRAIT_DEF2
#undef BOOST_TT_AUX_BOOL_TRAIT_DEF3
#undef BOOST_TT_AUX_BOOL_TRAIT_SPEC1
#undef BOOST_TT_AUX_BOOL_TRAIT_SPEC2
#undef BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1
#undef BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2
#undef BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1
#undef BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_2
#undef BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_1
#undef BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_2
#undef BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1
#undef BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1


code:
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED
#define BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED

//
//  Copyright 2015 Peter Dimov
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt
//

#include <boost/config.hpp>

namespace boost
{

namespace type_traits_detail
{

template<int I> struct arithmetic_type;

// Types bool, char, char16_t, char32_t, wchar_t,
// and the signed and unsigned integer types are
// collectively called integral types

template<> struct arithmetic_type<1>
{
    typedef bool type;
    typedef char (&result_type) [1];
};

template<> struct arithmetic_type<2>
{
    typedef char type;
    typedef char (&result_type) [2];
};

#ifndef BOOST_NO_INTRINSIC_WCHAR_T

template<> struct arithmetic_type<3>
{
    typedef wchar_t type;
    typedef char (&result_type) [3];
};

#endif

// There are five standard signed integer types:
// “signed char”, “short int”, “int”, “long int”, and “long long int”.

template<> struct arithmetic_type<4>
{
    typedef signed char type;
    typedef char (&result_type) [4];
};

template<> struct arithmetic_type<5>
{
    typedef short type;
    typedef char (&result_type) [5];
};

template<> struct arithmetic_type<6>
{
    typedef int type;
    typedef char (&result_type) [6];
};

template<> struct arithmetic_type<7>
{
    typedef long type;
    typedef char (&result_type) [7];
};

template<> struct arithmetic_type<8>
{
    typedef boost::long_long_type type;
    typedef char (&result_type) [8];
};

// For each of the standard signed integer types, there exists a corresponding
// (but different) standard unsigned integer type: “unsigned char”, “unsigned short int”,
// “unsigned int”, “unsigned long int”, and “unsigned long long int”

template<> struct arithmetic_type<9>
{
    typedef unsigned char type;
    typedef char (&result_type) [9];
};

template<> struct arithmetic_type<10>
{
    typedef unsigned short type;
    typedef char (&result_type) [10];
};

template<> struct arithmetic_type<11>
{
    typedef unsigned int type;
    typedef char (&result_type) [11];
};

template<> struct arithmetic_type<12>
{
    typedef unsigned long type;
    typedef char (&result_type) [12];
};

template<> struct arithmetic_type<13>
{
    typedef boost::ulong_long_type type;
    typedef char (&result_type) [13];
};

// There are three floating point types: float, double, and long double.

template<> struct arithmetic_type<14>
{
    typedef float type;
    typedef char (&result_type) [14];
};

template<> struct arithmetic_type<15>
{
    typedef double type;
    typedef char (&result_type) [15];
};

template<> struct arithmetic_type<16>
{
    typedef long double type;
    typedef char (&result_type) [16];
};

#if !defined( BOOST_NO_CXX11_CHAR16_T )

template<> struct arithmetic_type<17>
{
    typedef char16_t type;
    typedef char (&result_type) [17];
};

#endif

#if !defined( BOOST_NO_CXX11_CHAR32_T )

template<> struct arithmetic_type<18>
{
    typedef char32_t type;
    typedef char (&result_type) [18];
};

#endif

#if defined( BOOST_HAS_INT128 )

template<> struct arithmetic_type<19>
{
    typedef boost::int128_type type;
    typedef char (&result_type) [19];
};

template<> struct arithmetic_type<20>
{
    typedef boost::uint128_type type;
    typedef char (&result_type) [20];
};

#endif

template<class T, class U> class common_arithmetic_type
{
private:

    static arithmetic_type<1>::result_type select( arithmetic_type<1>::type );
    static arithmetic_type<2>::result_type select( arithmetic_type<2>::type );
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
    static arithmetic_type<3>::result_type select( arithmetic_type<3>::type );
#endif
    static arithmetic_type<4>::result_type select( arithmetic_type<4>::type );
    static arithmetic_type<5>::result_type select( arithmetic_type<5>::type );
    static arithmetic_type<6>::result_type select( arithmetic_type<6>::type );
    static arithmetic_type<7>::result_type select( arithmetic_type<7>::type );
    static arithmetic_type<8>::result_type select( arithmetic_type<8>::type );
    static arithmetic_type<9>::result_type select( arithmetic_type<9>::type );
    static arithmetic_type<10>::result_type select( arithmetic_type<10>::type );
    static arithmetic_type<11>::result_type select( arithmetic_type<11>::type );
    static arithmetic_type<12>::result_type select( arithmetic_type<12>::type );
    static arithmetic_type<13>::result_type select( arithmetic_type<13>::type );
    static arithmetic_type<14>::result_type select( arithmetic_type<14>::type );
    static arithmetic_type<15>::result_type select( arithmetic_type<15>::type );
    static arithmetic_type<16>::result_type select( arithmetic_type<16>::type );

#if !defined( BOOST_NO_CXX11_CHAR16_T )
    static arithmetic_type<17>::result_type select( arithmetic_type<17>::type );
#endif

#if !defined( BOOST_NO_CXX11_CHAR32_T )
    static arithmetic_type<18>::result_type select( arithmetic_type<18>::type );
#endif

#if defined( BOOST_HAS_INT128 )
    static arithmetic_type<19>::result_type select( arithmetic_type<19>::type );
    static arithmetic_type<20>::result_type select( arithmetic_type<20>::type );
#endif

    static bool cond();

public:

    typedef typename arithmetic_type< sizeof(select( cond()? T(): U() )) >::type type;
};

} // namespace type_traits_detail

} // namespace boost

#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_ARITHMETIC_TYPE_HPP_INCLUDED


code:
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED
#define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED

//
//  Copyright 2015 Peter Dimov
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt
//

#include <boost/type_traits/detail/common_arithmetic_type.hpp>
#include <boost/type_traits/detail/composite_pointer_type.hpp>
#include <boost/type_traits/detail/composite_member_pointer_type.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_union.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_pointer.hpp>
#include <boost/type_traits/conditional.hpp>

namespace boost
{

namespace type_traits_detail
{

// the arguments to common_type_impl have already been passed through decay<>

template<class T, class U> struct common_type_impl;

// same type

template<class T> struct common_type_impl<T, T>
{
    typedef T type;
};

// one of the operands is a class type, try conversions in both directions

template<class T, class U> struct ct_class
{
    BOOST_STATIC_CONSTANT( bool, ct = boost::is_class<T>::value || boost::is_union<T>::value );
    BOOST_STATIC_CONSTANT( bool, cu = boost::is_class<U>::value || boost::is_union<U>::value );

    BOOST_STATIC_CONSTANT( bool, value = ct || cu );
};

template<class T, class U> struct common_type_impl3;

template<class T, class U> struct common_type_class: public boost::conditional<

    boost::is_convertible<T, U>::value && !boost::is_convertible<U, T>::value,
    boost::type_identity<U>,

    typename boost::conditional<

        boost::is_convertible<U, T>::value && !boost::is_convertible<T, U>::value,
        boost::type_identity<T>,

        common_type_impl3<T, U>
    >::type
>::type
{
};

template<class T, class U> struct common_type_impl: public boost::conditional<
    ct_class<T, U>::value,
    common_type_class<T, U>,
    common_type_impl3<T, U> >::type
{
};

// pointers

template<class T, class U> struct common_type_impl4;

template<class T, class U> struct common_type_impl3: public boost::conditional<
    boost::is_pointer<T>::value || boost::is_pointer<U>::value,
    composite_pointer_type<T, U>,
    common_type_impl4<T, U> >::type
{
};

// pointers to members

template<class T, class U> struct common_type_impl5;

template<class T, class U> struct common_type_impl4: public boost::conditional<
    boost::is_member_pointer<T>::value || boost::is_member_pointer<U>::value,
    composite_member_pointer_type<T, U>,
    common_type_impl5<T, U> >::type
{
};

// arithmetic types (including class types w/ conversions to arithmetic and enums)

template<class T, class U> struct common_type_impl5: public common_arithmetic_type<T, U>
{
};

} // namespace type_traits_detail

} // namespace boost

#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMPL_HPP_INCLUDED


code:
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED
#define BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED

//
//  Copyright 2015 Peter Dimov
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt
//

#include <boost/type_traits/detail/composite_pointer_type.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/config.hpp>
#include <cstddef>

namespace boost
{

namespace type_traits_detail
{

template<class T, class U> struct composite_member_pointer_type;

// nullptr_t

#if !defined( BOOST_NO_CXX11_NULLPTR )

#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )

template<class C, class T> struct composite_member_pointer_type<T C::*, decltype(nullptr)>
{
    typedef T C::* type;
};

template<class C, class T> struct composite_member_pointer_type<decltype(nullptr), T C::*>
{
    typedef T C::* type;
};

template<> struct composite_member_pointer_type<decltype(nullptr), decltype(nullptr)>
{
    typedef decltype(nullptr) type;
};

#else

template<class C, class T> struct composite_member_pointer_type<T C::*, std::nullptr_t>
{
    typedef T C::* type;
};

template<class C, class T> struct composite_member_pointer_type<std::nullptr_t, T C::*>
{
    typedef T C::* type;
};

template<> struct composite_member_pointer_type<std::nullptr_t, std::nullptr_t>
{
    typedef std::nullptr_t type;
};

#endif

#endif // !defined( BOOST_NO_CXX11_NULLPTR )

template<class C1, class C2> struct common_member_class;

template<class C> struct common_member_class<C, C>
{
    typedef C type;
};

template<class C1, class C2> struct common_member_class
{
    typedef typename boost::conditional<

        boost::is_base_of<C1, C2>::value,
        C2,
        typename boost::conditional<boost::is_base_of<C2, C1>::value, C1, void>::type

    >::type type;
};

//This indirection avoids compilation errors on some older
//compilers like MSVC 7.1
template<class CT, class CB>
struct common_member_class_pointer_to_member
{
    typedef CT CB::* type;
};

template<class C1, class T1, class C2, class T2> struct composite_member_pointer_type<T1 C1::*, T2 C2::*>
{
private:

    typedef typename composite_pointer_type<T1*, T2*>::type CPT;
    typedef typename boost::remove_pointer<CPT>::type CT;

    typedef typename common_member_class<C1, C2>::type CB;

public:

    typedef typename common_member_class_pointer_to_member<CT, CB>::type type;
};

} // namespace type_traits_detail

} // namespace boost

#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_MEMBER_POINTER_TYPE_HPP_INCLUDED


code:
#ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED
#define BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED

//
//  Copyright 2015 Peter Dimov
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt
//

#include <boost/type_traits/copy_cv.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/config.hpp>
#include <cstddef>

namespace boost
{

namespace type_traits_detail
{

template<class T, class U> struct composite_pointer_type;

// same type

template<class T> struct composite_pointer_type<T*, T*>
{
    typedef T* type;
};

// nullptr_t

#if !defined( BOOST_NO_CXX11_NULLPTR )

#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )

template<class T> struct composite_pointer_type<T*, decltype(nullptr)>
{
    typedef T* type;
};

template<class T> struct composite_pointer_type<decltype(nullptr), T*>
{
    typedef T* type;
};

template<> struct composite_pointer_type<decltype(nullptr), decltype(nullptr)>
{
    typedef decltype(nullptr) type;
};

#else

template<class T> struct composite_pointer_type<T*, std::nullptr_t>
{
    typedef T* type;
};

template<class T> struct composite_pointer_type<std::nullptr_t, T*>
{
    typedef T* type;
};

template<> struct composite_pointer_type<std::nullptr_t, std::nullptr_t>
{
    typedef std::nullptr_t type;
};

#endif

#endif // !defined( BOOST_NO_CXX11_NULLPTR )

namespace detail
{

template<class T, class U> struct has_common_pointee
{
private:

    typedef typename boost::remove_cv<T>::type T2;
    typedef typename boost::remove_cv<U>::type U2;

public:

    BOOST_STATIC_CONSTANT( bool, value =
        (boost::is_same<T2, U2>::value)
        || boost::is_void<T2>::value
        || boost::is_void<U2>::value
        || (boost::is_base_of<T2, U2>::value)
        || (boost::is_base_of<U2, T2>::value) );
};

template<class T, class U> struct common_pointee
{
private:

    typedef typename boost::remove_cv<T>::type T2;
    typedef typename boost::remove_cv<U>::type U2;

public:

    typedef typename boost::conditional<

        boost::is_same<T2, U2>::value || boost::is_void<T2>::value || boost::is_base_of<T2, U2>::value,
        typename boost::copy_cv<T, U>::type,
        typename boost::copy_cv<U, T>::type

    >::type type;
};

template<class T, class U> struct composite_pointer_impl
{
private:

    typedef typename boost::remove_cv<T>::type T2;
    typedef typename boost::remove_cv<U>::type U2;

public:

    typedef typename boost::copy_cv<typename boost::copy_cv<typename composite_pointer_type<T2, U2>::type const, T>::type, U>::type type;
};

//Old compilers like MSVC-7.1 have problems using boost::conditional in
//composite_pointer_type. Partially specializing on has_common_pointee<T, U>::value
//seems to make their life easier
template<class T, class U, bool = has_common_pointee<T, U>::value >
struct composite_pointer_type_dispatch
   : common_pointee<T, U>
{};

template<class T, class U>
struct composite_pointer_type_dispatch<T, U, false>
   : composite_pointer_impl<T, U>
{};

} // detail

template<class T, class U> struct composite_pointer_type<T*, U*>
{
    typedef typename detail::composite_pointer_type_dispatch<T, U>::type* type;
};

} // namespace type_traits_detail

} // namespace boost

#endif // #ifndef BOOST_TYPE_TRAITS_DETAIL_COMPOSITE_POINTER_TYPE_HPP_INCLUDED


code:
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_CONFIG_HPP_INCLUDED
#define BOOST_TT_CONFIG_HPP_INCLUDED

#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
#include <boost/version.hpp>
#include <boost/detail/workaround.hpp>

//
// whenever we have a conversion function with ellipses
// it needs to be declared __cdecl to suppress compiler
// warnings from MS and Borland compilers (this *must*
// appear before we include is_same.hpp below):
#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32))
#   define BOOST_TT_DECL __cdecl
#else
#   define BOOST_TT_DECL /**/
#endif

# if (BOOST_WORKAROUND(__MWERKS__, < 0x3000)                         \
    || BOOST_WORKAROUND(__IBMCPP__, < 600 )                         \
    || BOOST_WORKAROUND(__BORLANDC__, < 0x5A0)                      \
    || defined(__ghs)                                               \
    || BOOST_WORKAROUND(__HP_aCC, < 60700)           \
    || BOOST_WORKAROUND(MPW_CPLUS, BOOST_TESTED_AT(0x890))          \
    || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)))       \
    && defined(BOOST_NO_IS_ABSTRACT)

#   define BOOST_TT_NO_CONFORMING_IS_CLASS_IMPLEMENTATION 1

#endif

#ifndef BOOST_TT_NO_CONFORMING_IS_CLASS_IMPLEMENTATION
# define BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION 1
#endif

//
// define BOOST_TT_TEST_MS_FUNC_SIGS
// when we want to test __stdcall etc function types with is_function etc
// (Note, does not work with Borland, even though it does support __stdcall etc):
//
#if defined(_MSC_EXTENSIONS) && !defined(__BORLANDC__)
#  define BOOST_TT_TEST_MS_FUNC_SIGS
#endif

//
// define BOOST_TT_NO_CV_FUNC_TEST
// if tests for cv-qualified member functions don't
// work in is_member_function_pointer
//
#if BOOST_WORKAROUND(__MWERKS__, < 0x3000) || BOOST_WORKAROUND(__IBMCPP__, <= 600)
#  define BOOST_TT_NO_CV_FUNC_TEST
#endif

//
// Macros that have been deprecated, defined here for backwards compatibility:
//
#define BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(x)
#define BOOST_TT_BROKEN_COMPILER_SPEC(x)

#endif // BOOST_TT_CONFIG_HPP_INCLUDED


code:
//  (C) Copyright 2009-2011 Frederic Bron, Robert Stewart, Steven Watanabe & Roman Perepelitsa.
//
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#include <boost/config.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_reference.hpp>

// cannot include this header without getting warnings of the kind:
// gcc:
//    warning: value computed is not used
//    warning: comparison between signed and unsigned integer expressions
// msvc:
//    warning C4018: '<' : signed/unsigned mismatch
//    warning C4244: '+=' : conversion from 'double' to 'char', possible loss of data
//    warning C4547: '*' : operator before comma has no effect; expected operator with side-effect
//    warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
//    warning C4804: '<' : unsafe use of type 'bool' in operation
//    warning C4805: '==' : unsafe mix of type 'bool' and type 'char' in operation
// cannot find another implementation -> declared as system header to suppress these warnings.
#if defined(__GNUC__)
#   pragma GCC system_header
#elif defined(BOOST_MSVC)
#   pragma warning ( push )
#   pragma warning ( disable : 4018 4244 4547 4800 4804 4805 4913)
#   if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
#       pragma warning ( disable : 6334)
#   endif
#endif

namespace boost {
namespace detail {

// This namespace ensures that argument-dependent name lookup does not mess things up.
namespace BOOST_JOIN(BOOST_TT_TRAIT_NAME,_impl) {

// 1. a function to have an instance of type T without requiring T to be default
// constructible
template <typename T> T &make();

// 2. we provide our operator definition for types that do not have one already

// a type returned from operator BOOST_TT_TRAIT_OP when no such operator is
// found in the type's own namespace (our own operator is used) so that we have
// a means to know that our operator was used
struct no_operator { };

// this class allows implicit conversions and makes the following operator
// definition less-preferred than any other such operators that might be found
// via argument-dependent name lookup
struct any { template <class T> any(T const&); };

// when operator BOOST_TT_TRAIT_OP is not available, this one is used
no_operator operator BOOST_TT_TRAIT_OP (const any&, const any&);

// 3. checks if the operator returns void or not
// conditions: Lhs!=void and Rhs!=void

// we first redefine "operator," so that we have no compilation error if
// operator BOOST_TT_TRAIT_OP returns void and we can use the return type of
// (lhs BOOST_TT_TRAIT_OP rhs, returns_void_t()) to deduce if
// operator BOOST_TT_TRAIT_OP returns void or not:
// - operator BOOST_TT_TRAIT_OP returns void   -> (lhs BOOST_TT_TRAIT_OP rhs, returns_void_t()) returns returns_void_t
// - operator BOOST_TT_TRAIT_OP returns !=void -> (lhs BOOST_TT_TRAIT_OP rhs, returns_void_t()) returns int
struct returns_void_t { };
template <typename T> int operator,(const T&, returns_void_t);
template <typename T> int operator,(const volatile T&, returns_void_t);

// this intermediate trait has member value of type bool:
// - value==true -> operator BOOST_TT_TRAIT_OP returns void
// - value==false -> operator BOOST_TT_TRAIT_OP does not return void
template < typename Lhs, typename Rhs >
struct operator_returns_void {
   // overloads of function returns_void make the difference
   // yes_type and no_type have different size by construction
   static ::boost::type_traits::yes_type returns_void(returns_void_t);
   static ::boost::type_traits::no_type returns_void(int);
   BOOST_STATIC_CONSTANT(bool, value = (sizeof(::boost::type_traits::yes_type)==sizeof(returns_void((make<Lhs>() BOOST_TT_TRAIT_OP make<Rhs>(),returns_void_t())))));
};

// 4. checks if the return type is Ret or Ret==dont_care
// conditions: Lhs!=void and Rhs!=void

struct dont_care { };

template < typename Lhs, typename Rhs, typename Ret, bool Returns_void >
struct operator_returns_Ret;

template < typename Lhs, typename Rhs >
struct operator_returns_Ret < Lhs, Rhs, dont_care, true > {
   BOOST_STATIC_CONSTANT(bool, value = true);
};

template < typename Lhs, typename Rhs >
struct operator_returns_Ret < Lhs, Rhs, dont_care, false > {
   BOOST_STATIC_CONSTANT(bool, value = true);
};

template < typename Lhs, typename Rhs >
struct operator_returns_Ret < Lhs, Rhs, void, true > {
   BOOST_STATIC_CONSTANT(bool, value = true);
};

template < typename Lhs, typename Rhs >
struct operator_returns_Ret < Lhs, Rhs, void, false > {
   BOOST_STATIC_CONSTANT(bool, value = false);
};

template < typename Lhs, typename Rhs, typename Ret >
struct operator_returns_Ret < Lhs, Rhs, Ret, true > {
   BOOST_STATIC_CONSTANT(bool, value = false);
};

// otherwise checks if it is convertible to Ret using the sizeof trick
// based on overload resolution
// condition: Ret!=void and Ret!=dont_care and the operator does not return void
template < typename Lhs, typename Rhs, typename Ret >
struct operator_returns_Ret < Lhs, Rhs, Ret, false > {
   static ::boost::type_traits::yes_type is_convertible_to_Ret(Ret); // this version is preferred for types convertible to Ret
   static ::boost::type_traits::no_type is_convertible_to_Ret(...); // this version is used otherwise

   BOOST_STATIC_CONSTANT(bool, value = (sizeof(is_convertible_to_Ret(make<Lhs>() BOOST_TT_TRAIT_OP make<Rhs>()))==sizeof(::boost::type_traits::yes_type)));
};

// 5. checks for operator existence
// condition: Lhs!=void and Rhs!=void

// checks if our definition of operator BOOST_TT_TRAIT_OP is used or an other
// existing one;
// this is done with redefinition of "operator," that returns no_operator or has_operator
struct has_operator { };
no_operator operator,(no_operator, has_operator);

template < typename Lhs, typename Rhs >
struct operator_exists {
   static ::boost::type_traits::yes_type s_check(has_operator); // this version is preferred when operator exists
   static ::boost::type_traits::no_type s_check(no_operator); // this version is used otherwise

   BOOST_STATIC_CONSTANT(bool, value = (sizeof(s_check(((make<Lhs>() BOOST_TT_TRAIT_OP make<Rhs>()),make<has_operator>())))==sizeof(::boost::type_traits::yes_type)));
};

// 6. main trait: to avoid any compilation error, this class behaves
// differently when operator BOOST_TT_TRAIT_OP(Lhs, Rhs) is forbidden by the
// standard.
// Forbidden_if is a bool that is:
// - true when the operator BOOST_TT_TRAIT_OP(Lhs, Rhs) is forbidden by the standard
//   (would yield compilation error if used)
// - false otherwise
template < typename Lhs, typename Rhs, typename Ret, bool Forbidden_if >
struct trait_impl1;

template < typename Lhs, typename Rhs, typename Ret >
struct trait_impl1 < Lhs, Rhs, Ret, true > {
   BOOST_STATIC_CONSTANT(bool, value = false);
};

template < typename Lhs, typename Rhs, typename Ret >
struct trait_impl1 < Lhs, Rhs, Ret, false > {
   BOOST_STATIC_CONSTANT(bool,
      value = (operator_exists < Lhs, Rhs >::value && operator_returns_Ret < Lhs, Rhs, Ret, operator_returns_void < Lhs, Rhs >::value >::value));
};

// some specializations needs to be declared for the special void case
template < typename Rhs, typename Ret >
struct trait_impl1 < void, Rhs, Ret, false > {
   BOOST_STATIC_CONSTANT(bool, value = false);
};

template < typename Lhs, typename Ret >
struct trait_impl1 < Lhs, void, Ret, false > {
   BOOST_STATIC_CONSTANT(bool, value = false);
};

template < typename Ret >
struct trait_impl1 < void, void, Ret, false > {
   BOOST_STATIC_CONSTANT(bool, value = false);
};

// defines some typedef for convenience
template < typename Lhs, typename Rhs, typename Ret >
struct trait_impl {
   typedef typename ::boost::remove_reference<Lhs>::type Lhs_noref;
   typedef typename ::boost::remove_reference<Rhs>::type Rhs_noref;
   typedef typename ::boost::remove_cv<Lhs_noref>::type Lhs_nocv;
   typedef typename ::boost::remove_cv<Rhs_noref>::type Rhs_nocv;
   typedef typename ::boost::remove_cv< typename ::boost::remove_reference< typename ::boost::remove_pointer<Lhs_noref>::type >::type >::type Lhs_noptr;
   typedef typename ::boost::remove_cv< typename ::boost::remove_reference< typename ::boost::remove_pointer<Rhs_noref>::type >::type >::type Rhs_noptr;
   BOOST_STATIC_CONSTANT(bool, value = (trait_impl1 < Lhs_noref, Rhs_noref, Ret, BOOST_TT_FORBIDDEN_IF >::value));
};

} // namespace impl
} // namespace detail

// this is the accessible definition of the trait to end user
template <class Lhs, class Rhs=Lhs, class Ret=::boost::detail::BOOST_JOIN(BOOST_TT_TRAIT_NAME,_impl)::dont_care>
struct BOOST_TT_TRAIT_NAME : public integral_constant<bool, (::boost::detail::BOOST_JOIN(BOOST_TT_TRAIT_NAME, _impl)::trait_impl < Lhs, Rhs, Ret >::value)>{};

} // namespace boost

#if defined(BOOST_MSVC)
#   pragma warning ( pop )
#endif