mpl.hpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. #ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP
  14. #define BOOST_INTRUSIVE_DETAIL_MPL_HPP
  15. #ifndef BOOST_CONFIG_HPP
  16. # include <boost/config.hpp>
  17. #endif
  18. #if defined(BOOST_HAS_PRAGMA_ONCE)
  19. # pragma once
  20. #endif
  21. #include <boost/intrusive/detail/config_begin.hpp>
  22. #include <boost/move/detail/type_traits.hpp>
  23. #include <cstddef>
  24. namespace boost {
  25. namespace intrusive {
  26. namespace detail {
  27. using boost::move_detail::is_same;
  28. using boost::move_detail::add_const;
  29. using boost::move_detail::remove_const;
  30. using boost::move_detail::remove_cv;
  31. using boost::move_detail::remove_reference;
  32. using boost::move_detail::add_reference;
  33. using boost::move_detail::remove_pointer;
  34. using boost::move_detail::add_pointer;
  35. using boost::move_detail::true_type;
  36. using boost::move_detail::false_type;
  37. using boost::move_detail::voider;
  38. using boost::move_detail::enable_if_c;
  39. using boost::move_detail::enable_if;
  40. using boost::move_detail::disable_if_c;
  41. using boost::move_detail::disable_if;
  42. using boost::move_detail::is_convertible;
  43. using boost::move_detail::if_c;
  44. using boost::move_detail::if_;
  45. using boost::move_detail::is_const;
  46. using boost::move_detail::identity;
  47. using boost::move_detail::alignment_of;
  48. using boost::move_detail::is_empty;
  49. using boost::move_detail::addressof;
  50. using boost::move_detail::integral_constant;
  51. using boost::move_detail::enable_if_convertible;
  52. using boost::move_detail::disable_if_convertible;
  53. using boost::move_detail::bool_;
  54. using boost::move_detail::true_;
  55. using boost::move_detail::false_;
  56. using boost::move_detail::yes_type;
  57. using boost::move_detail::no_type;
  58. using boost::move_detail::apply;
  59. using boost::move_detail::eval_if_c;
  60. using boost::move_detail::eval_if;
  61. using boost::move_detail::unvoid_ref;
  62. using boost::move_detail::add_const_if_c;
  63. using boost::move_detail::is_integral;
  64. using boost::move_detail::make_unsigned;
  65. using boost::move_detail::is_enum;
  66. using boost::move_detail::is_floating_point;
  67. using boost::move_detail::is_scalar;
  68. using boost::move_detail::is_unsigned;
  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. template<>
  75. struct ls_zeros<0>
  76. {
  77. static const std::size_t value = 0;
  78. };
  79. template<>
  80. struct ls_zeros<1>
  81. {
  82. static const std::size_t value = 0;
  83. };
  84. // Infrastructure for providing a default type for T::TNAME if absent.
  85. #define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
  86. template <typename T> \
  87. struct boost_intrusive_has_type_ ## TNAME \
  88. { \
  89. template <typename X> \
  90. static char test(int, typename X::TNAME*); \
  91. \
  92. template <typename X> \
  93. static int test(...); \
  94. \
  95. static const bool value = (1 == sizeof(test<T>(0, 0))); \
  96. }; \
  97. \
  98. template <typename T, typename DefaultType> \
  99. struct boost_intrusive_default_type_ ## TNAME \
  100. { \
  101. struct DefaultWrap { typedef DefaultType TNAME; }; \
  102. \
  103. typedef typename \
  104. ::boost::intrusive::detail::if_c \
  105. < boost_intrusive_has_type_ ## TNAME<T>::value \
  106. , T, DefaultWrap>::type::TNAME type; \
  107. }; \
  108. //
  109. #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
  110. typename INSTANTIATION_NS_PREFIX \
  111. boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
  112. //
  113. #define BOOST_INTRUSIVE_HAS_TYPE(INSTANTIATION_NS_PREFIX, T, TNAME) \
  114. INSTANTIATION_NS_PREFIX \
  115. boost_intrusive_has_type_ ## TNAME< T >::value \
  116. //
  117. #define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\
  118. template <typename T, typename DefaultType> \
  119. struct boost_intrusive_eval_default_type_ ## TNAME \
  120. { \
  121. template <typename X> \
  122. static char test(int, typename X::TNAME*); \
  123. \
  124. template <typename X> \
  125. static int test(...); \
  126. \
  127. struct DefaultWrap \
  128. { typedef typename DefaultType::type TNAME; }; \
  129. \
  130. static const bool value = (1 == sizeof(test<T>(0, 0))); \
  131. \
  132. typedef typename \
  133. ::boost::intrusive::detail::eval_if_c \
  134. < value \
  135. , ::boost::intrusive::detail::identity<T> \
  136. , ::boost::intrusive::detail::identity<DefaultWrap> \
  137. >::type::TNAME type; \
  138. }; \
  139. //
  140. #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
  141. typename INSTANTIATION_NS_PREFIX \
  142. boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \
  143. //
  144. #define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \
  145. template <class T>\
  146. struct TRAITS_PREFIX##_bool\
  147. {\
  148. template<bool Add>\
  149. struct two_or_three {yes_type _[2u + (unsigned)Add];};\
  150. template <class U> static yes_type test(...);\
  151. template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
  152. static const std::size_t value = sizeof(test<T>(0));\
  153. };\
  154. \
  155. template <class T>\
  156. struct TRAITS_PREFIX##_bool_is_true\
  157. {\
  158. static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\
  159. };\
  160. //
  161. #define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
  162. template <typename U, typename Signature> \
  163. class TRAITS_NAME \
  164. { \
  165. private: \
  166. template<Signature> struct helper;\
  167. template<typename T> \
  168. static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \
  169. template<typename T> static ::boost::intrusive::detail::no_type test(...); \
  170. public: \
  171. static const bool value = sizeof(test<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
  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. #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
  191. BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \
  192. \
  193. template <typename Type, class> \
  194. struct TRAITS_NAME \
  195. : public TRAITS_NAME##_ignore_signature<Type> \
  196. {};\
  197. //
  198. } //namespace detail
  199. } //namespace intrusive
  200. } //namespace boost
  201. #include <boost/intrusive/detail/config_end.hpp>
  202. #endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP