mpl.hpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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::enable_if_c;
  38. using boost::move_detail::enable_if;
  39. using boost::move_detail::disable_if_c;
  40. using boost::move_detail::disable_if;
  41. using boost::move_detail::is_convertible;
  42. using boost::move_detail::if_c;
  43. using boost::move_detail::if_;
  44. using boost::move_detail::is_const;
  45. using boost::move_detail::identity;
  46. using boost::move_detail::alignment_of;
  47. using boost::move_detail::is_empty;
  48. using boost::move_detail::addressof;
  49. using boost::move_detail::integral_constant;
  50. using boost::move_detail::enable_if_convertible;
  51. using boost::move_detail::disable_if_convertible;
  52. using boost::move_detail::bool_;
  53. using boost::move_detail::true_;
  54. using boost::move_detail::false_;
  55. using boost::move_detail::yes_type;
  56. using boost::move_detail::no_type;
  57. using boost::move_detail::apply;
  58. using boost::move_detail::eval_if_c;
  59. using boost::move_detail::eval_if;
  60. using boost::move_detail::unvoid_ref;
  61. using boost::move_detail::add_const_if_c;
  62. template<std::size_t S>
  63. struct ls_zeros
  64. {
  65. static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value);
  66. };
  67. template<>
  68. struct ls_zeros<0>
  69. {
  70. static const std::size_t value = 0;
  71. };
  72. template<>
  73. struct ls_zeros<1>
  74. {
  75. static const std::size_t value = 0;
  76. };
  77. // Infrastructure for providing a default type for T::TNAME if absent.
  78. #define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
  79. template <typename T> \
  80. struct boost_intrusive_has_type_ ## TNAME \
  81. { \
  82. template <typename X> \
  83. static char test(int, typename X::TNAME*); \
  84. \
  85. template <typename X> \
  86. static int test(...); \
  87. \
  88. static const bool value = (1 == sizeof(test<T>(0, 0))); \
  89. }; \
  90. \
  91. template <typename T, typename DefaultType> \
  92. struct boost_intrusive_default_type_ ## TNAME \
  93. { \
  94. struct DefaultWrap { typedef DefaultType TNAME; }; \
  95. \
  96. typedef typename \
  97. ::boost::intrusive::detail::if_c \
  98. < boost_intrusive_has_type_ ## TNAME<T>::value \
  99. , T, DefaultWrap>::type::TNAME type; \
  100. }; \
  101. //
  102. #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
  103. typename INSTANTIATION_NS_PREFIX \
  104. boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
  105. //
  106. #define BOOST_INTRUSIVE_HAS_TYPE(INSTANTIATION_NS_PREFIX, T, TNAME) \
  107. INSTANTIATION_NS_PREFIX \
  108. boost_intrusive_has_type_ ## TNAME< T >::value \
  109. //
  110. #define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\
  111. template <typename T, typename DefaultType> \
  112. struct boost_intrusive_eval_default_type_ ## TNAME \
  113. { \
  114. template <typename X> \
  115. static char test(int, typename X::TNAME*); \
  116. \
  117. template <typename X> \
  118. static int test(...); \
  119. \
  120. struct DefaultWrap \
  121. { typedef typename DefaultType::type TNAME; }; \
  122. \
  123. static const bool value = (1 == sizeof(test<T>(0, 0))); \
  124. \
  125. typedef typename \
  126. ::boost::intrusive::detail::eval_if_c \
  127. < value \
  128. , ::boost::intrusive::detail::identity<T> \
  129. , ::boost::intrusive::detail::identity<DefaultWrap> \
  130. >::type::TNAME type; \
  131. }; \
  132. //
  133. #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
  134. typename INSTANTIATION_NS_PREFIX \
  135. boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \
  136. //
  137. #define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \
  138. template <class T>\
  139. struct TRAITS_PREFIX##_bool\
  140. {\
  141. template<bool Add>\
  142. struct two_or_three {yes_type _[2 + Add];};\
  143. template <class U> static yes_type test(...);\
  144. template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
  145. static const std::size_t value = sizeof(test<T>(0));\
  146. };\
  147. \
  148. template <class T>\
  149. struct TRAITS_PREFIX##_bool_is_true\
  150. {\
  151. static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\
  152. };\
  153. //
  154. #define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
  155. template <typename U, typename Signature> \
  156. class TRAITS_NAME \
  157. { \
  158. private: \
  159. template<Signature> struct helper;\
  160. template<typename T> \
  161. static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \
  162. template<typename T> static ::boost::intrusive::detail::no_type test(...); \
  163. public: \
  164. static const bool value = sizeof(test<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
  165. }; \
  166. //
  167. #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \
  168. template <typename Type> \
  169. struct TRAITS_NAME \
  170. { \
  171. struct BaseMixin \
  172. { \
  173. void FUNC_NAME(); \
  174. }; \
  175. struct Base : public Type, public BaseMixin { Base(); }; \
  176. template <typename T, T t> class Helper{}; \
  177. template <typename U> \
  178. static ::boost::intrusive::detail::no_type test(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
  179. static ::boost::intrusive::detail::yes_type test(...); \
  180. static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \
  181. };\
  182. //
  183. #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
  184. BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \
  185. \
  186. template <typename Type, class> \
  187. struct TRAITS_NAME \
  188. : public TRAITS_NAME##_ignore_signature<Type> \
  189. {};\
  190. //
  191. } //namespace detail
  192. } //namespace intrusive
  193. } //namespace boost
  194. #include <boost/intrusive/detail/config_end.hpp>
  195. #endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP