1 ///////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2006-2014 4 // (C) Copyright Microsoft Corporation 2014 5 // 6 // Distributed under the Boost Software License, Version 1.0. 7 // (See accompanying file LICENSE_1_0.txt or copy at 8 // http://www.boost.org/LICENSE_1_0.txt) 9 // 10 // See http://www.boost.org/libs/intrusive for documentation. 11 // 12 ///////////////////////////////////////////////////////////////////////////// 13 14 #ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP 15 #define BOOST_INTRUSIVE_DETAIL_MPL_HPP 16 17 #ifndef BOOST_CONFIG_HPP 18 # include <boost/config.hpp> 19 #endif 20 21 #if defined(BOOST_HAS_PRAGMA_ONCE) 22 # pragma once 23 #endif 24 25 #include <boost/intrusive/detail/config_begin.hpp> 26 #include <boost/move/detail/type_traits.hpp> 27 #include <cstddef> 28 29 namespace boost { 30 namespace intrusive { 31 namespace detail { 32 33 using boost::move_detail::is_same; 34 using boost::move_detail::add_const; 35 using boost::move_detail::remove_const; 36 using boost::move_detail::remove_cv; 37 using boost::move_detail::remove_reference; 38 using boost::move_detail::add_reference; 39 using boost::move_detail::remove_pointer; 40 using boost::move_detail::add_pointer; 41 using boost::move_detail::true_type; 42 using boost::move_detail::false_type; 43 using boost::move_detail::enable_if_c; 44 using boost::move_detail::enable_if; 45 using boost::move_detail::disable_if_c; 46 using boost::move_detail::disable_if; 47 using boost::move_detail::is_convertible; 48 using boost::move_detail::if_c; 49 using boost::move_detail::if_; 50 using boost::move_detail::is_const; 51 using boost::move_detail::identity; 52 using boost::move_detail::alignment_of; 53 using boost::move_detail::is_empty; 54 using boost::move_detail::addressof; 55 using boost::move_detail::integral_constant; 56 using boost::move_detail::enable_if_convertible; 57 using boost::move_detail::disable_if_convertible; 58 using boost::move_detail::bool_; 59 using boost::move_detail::true_; 60 using boost::move_detail::false_; 61 using boost::move_detail::yes_type; 62 using boost::move_detail::no_type; 63 using boost::move_detail::apply; 64 using boost::move_detail::eval_if_c; 65 using boost::move_detail::eval_if; 66 using boost::move_detail::unvoid_ref; 67 using boost::move_detail::add_const_if_c; 68 69 template<std::size_t S> 70 struct ls_zeros 71 { 72 static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value); 73 }; 74 75 template<> 76 struct ls_zeros<0> 77 { 78 static const std::size_t value = 0; 79 }; 80 81 template<> 82 struct ls_zeros<1> 83 { 84 static const std::size_t value = 0; 85 }; 86 87 // Infrastructure for providing a default type for T::TNAME if absent. 88 #define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \ 89 template <typename T, typename DefaultType> \ 90 struct boost_intrusive_default_type_ ## TNAME \ 91 { \ 92 template <typename X> \ 93 static char test(int, typename X::TNAME*); \ 94 \ 95 template <typename X> \ 96 static int test(...); \ 97 \ 98 struct DefaultWrap { typedef DefaultType TNAME; }; \ 99 \ 100 static const bool value = (1 == sizeof(test<T>(0, 0))); \ 101 \ 102 typedef typename \ 103 ::boost::intrusive::detail::if_c \ 104 <value, T, DefaultWrap>::type::TNAME type; \ 105 }; \ 106 // 107 108 #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ 109 typename INSTANTIATION_NS_PREFIX \ 110 boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \ 111 // 112 113 #define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\ 114 template <typename T, typename DefaultType> \ 115 struct boost_intrusive_eval_default_type_ ## TNAME \ 116 { \ 117 template <typename X> \ 118 static char test(int, typename X::TNAME*); \ 119 \ 120 template <typename X> \ 121 static int test(...); \ 122 \ 123 struct DefaultWrap \ 124 { typedef typename DefaultType::type TNAME; }; \ 125 \ 126 static const bool value = (1 == sizeof(test<T>(0, 0))); \ 127 \ 128 typedef typename \ 129 ::boost::intrusive::detail::eval_if_c \ 130 < value \ 131 , ::boost::intrusive::detail::identity<T> \ 132 , ::boost::intrusive::detail::identity<DefaultWrap> \ 133 >::type::TNAME type; \ 134 }; \ 135 // 136 137 #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ 138 typename INSTANTIATION_NS_PREFIX \ 139 boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \ 140 // 141 142 #define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \ 143 template <class T>\ 144 struct TRAITS_PREFIX##_bool\ 145 {\ 146 template<bool Add>\ 147 struct two_or_three {yes_type _[2 + Add];};\ 148 template <class U> static yes_type test(...);\ 149 template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\ 150 static const std::size_t value = sizeof(test<T>(0));\ 151 };\ 152 \ 153 template <class T>\ 154 struct TRAITS_PREFIX##_bool_is_true\ 155 {\ 156 static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\ 157 };\ 158 // 159 160 #define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ 161 template <typename U, typename Signature> \ 162 class TRAITS_NAME \ 163 { \ 164 private: \ 165 template<Signature> struct helper;\ 166 template<typename T> \ 167 static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \ 168 template<typename T> static ::boost::intrusive::detail::no_type test(...); \ 169 public: \ 170 static const bool value = sizeof(test<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \ 171 }; \ 172 // 173 174 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \ 175 template <typename Type> \ 176 struct TRAITS_NAME \ 177 { \ 178 struct BaseMixin \ 179 { \ 180 void FUNC_NAME(); \ 181 }; \ 182 struct Base : public Type, public BaseMixin { Base(); }; \ 183 template <typename T, T t> class Helper{}; \ 184 template <typename U> \ 185 static ::boost::intrusive::detail::no_type test(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \ 186 static ::boost::intrusive::detail::yes_type test(...); \ 187 static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \ 188 };\ 189 // 190 191 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ 192 BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \ 193 \ 194 template <typename Type, class> \ 195 struct TRAITS_NAME \ 196 : public TRAITS_NAME##_ignore_signature<Type> \ 197 {};\ 198 // 199 200 } //namespace detail 201 } //namespace intrusive 202 } //namespace boost 203 204 #include <boost/intrusive/detail/config_end.hpp> 205 206 #endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP 207