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