Chris@16: ///////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@101: // (C) Copyright Ion Gaztanaga 2006-2014 Chris@101: // (C) Copyright Microsoft Corporation 2014 Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org/libs/intrusive for documentation. Chris@16: // Chris@16: ///////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP Chris@16: #define BOOST_INTRUSIVE_DETAIL_MPL_HPP Chris@16: Chris@101: #ifndef BOOST_CONFIG_HPP Chris@101: # include Chris@101: #endif Chris@101: Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@101: # pragma once Chris@101: #endif Chris@101: Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace intrusive { Chris@16: namespace detail { Chris@16: Chris@101: template Chris@101: struct is_same Chris@101: { Chris@101: static const bool value = false; Chris@101: }; Chris@101: Chris@101: template Chris@101: struct is_same Chris@101: { Chris@101: static const bool value = true; Chris@101: }; Chris@101: Chris@101: template Chris@101: struct add_const Chris@101: { typedef const T type; }; Chris@101: Chris@101: template Chris@101: struct remove_const Chris@101: { typedef T type; }; Chris@101: Chris@101: template Chris@101: struct remove_const Chris@101: { typedef T type; }; Chris@101: Chris@101: template Chris@101: struct remove_cv Chris@101: { typedef T type; }; Chris@101: Chris@101: template Chris@101: struct remove_cv Chris@101: { typedef T type; }; Chris@101: Chris@101: template Chris@101: struct remove_cv Chris@101: { typedef T type; }; Chris@101: Chris@101: template Chris@101: struct remove_cv Chris@101: { typedef T type; }; Chris@101: Chris@101: template Chris@101: struct remove_reference Chris@101: { Chris@101: typedef T type; Chris@101: }; Chris@101: Chris@101: template Chris@101: struct remove_reference Chris@101: { Chris@101: typedef T type; Chris@101: }; Chris@101: Chris@101: template Chris@101: struct remove_pointer Chris@101: { Chris@101: typedef T type; Chris@101: }; Chris@101: Chris@101: template Chris@101: struct remove_pointer Chris@101: { Chris@101: typedef T type; Chris@101: }; Chris@101: Chris@101: template Chris@101: struct add_pointer Chris@101: { Chris@101: typedef T *type; Chris@101: }; Chris@101: Chris@16: typedef char one; Chris@16: struct two {one _[2];}; Chris@16: Chris@16: template< bool C_ > Chris@16: struct bool_ Chris@16: { Chris@16: static const bool value = C_; Chris@16: }; Chris@16: Chris@101: template< class Integer, Integer Value > Chris@101: struct integer Chris@101: { Chris@101: static const Integer value = Value; Chris@101: }; Chris@101: Chris@16: typedef bool_ true_; Chris@16: typedef bool_ false_; Chris@16: Chris@16: typedef true_ true_type; Chris@16: typedef false_ false_type; Chris@16: Chris@16: typedef char yes_type; Chris@16: struct no_type Chris@16: { Chris@16: char padding[8]; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct enable_if_c { Chris@16: typedef T type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct enable_if_c {}; Chris@16: Chris@16: template Chris@16: struct enable_if : public enable_if_c{}; Chris@16: Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename F::template apply::type type; Chris@16: }; Chris@16: Chris@101: #if defined(_MSC_VER) && (_MSC_VER >= 1400) Chris@101: Chris@101: template Chris@101: struct is_convertible Chris@101: { Chris@101: static const bool value = __is_convertible_to(T, U); Chris@101: }; Chris@101: Chris@101: #else Chris@101: Chris@16: template Chris@16: class is_convertible Chris@16: { Chris@16: typedef char true_t; Chris@16: class false_t { char dummy[2]; }; Chris@101: //use any_conversion as first parameter since in MSVC Chris@101: //overaligned types can't go through ellipsis Chris@16: static false_t dispatch(...); Chris@101: static true_t dispatch(U); Chris@101: static typename remove_reference::type &trigger(); Chris@16: public: Chris@16: static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t); Chris@16: }; Chris@16: Chris@101: #endif Chris@101: Chris@16: template< Chris@16: bool C Chris@16: , typename T1 Chris@16: , typename T2 Chris@16: > Chris@16: struct if_c Chris@16: { Chris@16: typedef T1 type; Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename T1 Chris@16: , typename T2 Chris@16: > Chris@16: struct if_c Chris@16: { Chris@16: typedef T2 type; Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename C Chris@16: , typename T1 Chris@16: , typename T2 Chris@16: > Chris@16: struct if_ Chris@16: { Chris@16: typedef typename if_c<0 != C::value, T1, T2>::type type; Chris@16: }; Chris@16: Chris@16: template< Chris@16: bool C Chris@16: , typename F1 Chris@16: , typename F2 Chris@16: > Chris@16: struct eval_if_c Chris@16: : if_c::type Chris@16: {}; Chris@16: Chris@16: template< Chris@16: typename C Chris@16: , typename T1 Chris@16: , typename T2 Chris@16: > Chris@16: struct eval_if Chris@16: : if_::type Chris@16: {}; Chris@16: Chris@16: // identity is an extension: it is not part of the standard. Chris@16: template Chris@16: struct identity Chris@16: { Chris@16: typedef T type; Chris@16: }; Chris@16: Chris@101: template Chris@101: struct add_const_if_c Chris@101: { Chris@101: typedef typename if_c Chris@101: < Add Chris@101: , typename add_const::type Chris@101: , T Chris@101: >::type type; Chris@101: }; Chris@16: Chris@16: Chris@16: //boost::alignment_of yields to 10K lines of preprocessed code, so we Chris@16: //need an alternative Chris@16: template struct alignment_of; Chris@16: Chris@16: template Chris@16: struct alignment_of_hack Chris@16: { Chris@16: char c; Chris@16: T t; Chris@16: alignment_of_hack(); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct alignment_logic Chris@16: { Chris@16: static const std::size_t value = A < S ? A : S; Chris@16: }; Chris@16: Chris@16: template< typename T > Chris@16: struct alignment_of Chris@16: { Chris@16: static const std::size_t value = alignment_logic Chris@16: < sizeof(alignment_of_hack) - sizeof(T) Chris@16: , sizeof(T) Chris@16: >::value; Chris@16: }; Chris@16: Chris@16: template Chris@16: class is_empty_class Chris@16: { Chris@16: template Chris@16: struct empty_helper_t1 : public T Chris@16: { Chris@16: empty_helper_t1(); Chris@16: int i[256]; Chris@16: }; Chris@16: Chris@16: struct empty_helper_t2 Chris@16: { int i[256]; }; Chris@16: Chris@16: public: Chris@16: static const bool value = sizeof(empty_helper_t1) == sizeof(empty_helper_t2); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct ls_zeros Chris@16: { Chris@16: static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value); Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct ls_zeros<0> Chris@16: { Chris@16: static const std::size_t value = 0; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct ls_zeros<1> Chris@16: { Chris@16: static const std::size_t value = 0; Chris@16: }; Chris@16: Chris@101: template struct unvoid_ref { typedef T &type; }; Chris@101: template <> struct unvoid_ref { struct type_impl { }; typedef type_impl & type; }; Chris@101: template <> struct unvoid_ref { struct type_impl { }; typedef type_impl & type; }; Chris@101: Chris@101: // Infrastructure for providing a default type for T::TNAME if absent. Chris@101: #define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \ Chris@101: template \ Chris@101: struct boost_intrusive_default_type_ ## TNAME \ Chris@101: { \ Chris@101: template \ Chris@101: static char test(int, typename X::TNAME*); \ Chris@101: \ Chris@101: template \ Chris@101: static int test(...); \ Chris@101: \ Chris@101: struct DefaultWrap { typedef DefaultType TNAME; }; \ Chris@101: \ Chris@101: static const bool value = (1 == sizeof(test(0, 0))); \ Chris@101: \ Chris@101: typedef typename \ Chris@101: ::boost::intrusive::detail::if_c \ Chris@101: ::type::TNAME type; \ Chris@101: }; \ Chris@101: // Chris@101: Chris@101: #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ Chris@101: typename INSTANTIATION_NS_PREFIX \ Chris@101: boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \ Chris@101: // Chris@101: Chris@101: #define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\ Chris@101: template \ Chris@101: struct boost_intrusive_eval_default_type_ ## TNAME \ Chris@101: { \ Chris@101: template \ Chris@101: static char test(int, typename X::TNAME*); \ Chris@101: \ Chris@101: template \ Chris@101: static int test(...); \ Chris@101: \ Chris@101: struct DefaultWrap \ Chris@101: { typedef typename DefaultType::type TNAME; }; \ Chris@101: \ Chris@101: static const bool value = (1 == sizeof(test(0, 0))); \ Chris@101: \ Chris@101: typedef typename \ Chris@101: ::boost::intrusive::detail::eval_if_c \ Chris@101: < value \ Chris@101: , ::boost::intrusive::detail::identity \ Chris@101: , ::boost::intrusive::detail::identity \ Chris@101: >::type::TNAME type; \ Chris@101: }; \ Chris@101: // Chris@101: Chris@101: #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ Chris@101: typename INSTANTIATION_NS_PREFIX \ Chris@101: boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \ Chris@101: // Chris@101: Chris@101: #define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \ Chris@101: template \ Chris@101: struct TRAITS_PREFIX##_bool\ Chris@101: {\ Chris@101: template\ Chris@101: struct two_or_three {one _[2 + Add];};\ Chris@101: template static one test(...);\ Chris@101: template static two_or_three test (int);\ Chris@101: static const std::size_t value = sizeof(test(0));\ Chris@101: };\ Chris@101: \ Chris@101: template \ Chris@101: struct TRAITS_PREFIX##_bool_is_true\ Chris@101: {\ Chris@101: static const bool value = TRAITS_PREFIX##_bool::value > sizeof(one)*2;\ Chris@101: };\ Chris@101: // Chris@101: Chris@101: #define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ Chris@101: template \ Chris@101: class TRAITS_NAME \ Chris@101: { \ Chris@101: private: \ Chris@101: template struct helper;\ Chris@101: template \ Chris@101: static ::boost::intrusive::detail::yes_type check(helper<&T::FUNC_NAME>*); \ Chris@101: template static ::boost::intrusive::detail::no_type check(...); \ Chris@101: public: \ Chris@101: static const bool value = sizeof(check(0)) == sizeof(::boost::intrusive::detail::yes_type); \ Chris@101: }; \ Chris@101: // Chris@101: Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \ Chris@101: template \ Chris@101: struct TRAITS_NAME \ Chris@101: { \ Chris@101: struct BaseMixin \ Chris@101: { \ Chris@101: void FUNC_NAME(); \ Chris@101: }; \ Chris@101: struct Base : public Type, public BaseMixin { Base(); }; \ Chris@101: template class Helper{}; \ Chris@101: template \ Chris@101: static ::boost::intrusive::detail::no_type check(U*, Helper* = 0); \ Chris@101: static ::boost::intrusive::detail::yes_type check(...); \ Chris@101: static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(check((Base*)(0))); \ Chris@101: };\ Chris@101: // Chris@101: Chris@101: #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ Chris@101: BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \ Chris@101: \ Chris@101: template \ Chris@101: struct TRAITS_NAME \ Chris@101: : public TRAITS_NAME##_ignore_signature \ Chris@101: {};\ Chris@101: // Chris@101: Chris@101: Chris@101: template Chris@101: inline T* addressof(T& obj) Chris@101: { Chris@101: return static_cast Chris@101: (static_cast Chris@101: (const_cast Chris@101: (&reinterpret_cast(obj)) Chris@101: ) Chris@101: ); Chris@101: } Chris@101: Chris@16: } //namespace detail Chris@16: } //namespace intrusive Chris@16: } //namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP