mpl.hpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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, typename DefaultType> \
  80. struct boost_intrusive_default_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. struct DefaultWrap { typedef DefaultType TNAME; }; \
  89. \
  90. static const bool value = (1 == sizeof(test<T>(0, 0))); \
  91. \
  92. typedef typename \
  93. ::boost::intrusive::detail::if_c \
  94. <value, T, DefaultWrap>::type::TNAME type; \
  95. }; \
  96. //
  97. #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
  98. typename INSTANTIATION_NS_PREFIX \
  99. boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
  100. //
  101. #define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\
  102. template <typename T, typename DefaultType> \
  103. struct boost_intrusive_eval_default_type_ ## TNAME \
  104. { \
  105. template <typename X> \
  106. static char test(int, typename X::TNAME*); \
  107. \
  108. template <typename X> \
  109. static int test(...); \
  110. \
  111. struct DefaultWrap \
  112. { typedef typename DefaultType::type TNAME; }; \
  113. \
  114. static const bool value = (1 == sizeof(test<T>(0, 0))); \
  115. \
  116. typedef typename \
  117. ::boost::intrusive::detail::eval_if_c \
  118. < value \
  119. , ::boost::intrusive::detail::identity<T> \
  120. , ::boost::intrusive::detail::identity<DefaultWrap> \
  121. >::type::TNAME type; \
  122. }; \
  123. //
  124. #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
  125. typename INSTANTIATION_NS_PREFIX \
  126. boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \
  127. //
  128. #define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \
  129. template <class T>\
  130. struct TRAITS_PREFIX##_bool\
  131. {\
  132. template<bool Add>\
  133. struct two_or_three {yes_type _[2 + Add];};\
  134. template <class U> static yes_type test(...);\
  135. template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
  136. static const std::size_t value = sizeof(test<T>(0));\
  137. };\
  138. \
  139. template <class T>\
  140. struct TRAITS_PREFIX##_bool_is_true\
  141. {\
  142. static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\
  143. };\
  144. //
  145. #define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
  146. template <typename U, typename Signature> \
  147. class TRAITS_NAME \
  148. { \
  149. private: \
  150. template<Signature> struct helper;\
  151. template<typename T> \
  152. static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \
  153. template<typename T> static ::boost::intrusive::detail::no_type test(...); \
  154. public: \
  155. static const bool value = sizeof(test<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
  156. }; \
  157. //
  158. #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \
  159. template <typename Type> \
  160. struct TRAITS_NAME \
  161. { \
  162. struct BaseMixin \
  163. { \
  164. void FUNC_NAME(); \
  165. }; \
  166. struct Base : public Type, public BaseMixin { Base(); }; \
  167. template <typename T, T t> class Helper{}; \
  168. template <typename U> \
  169. static ::boost::intrusive::detail::no_type test(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
  170. static ::boost::intrusive::detail::yes_type test(...); \
  171. static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \
  172. };\
  173. //
  174. #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
  175. BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \
  176. \
  177. template <typename Type, class> \
  178. struct TRAITS_NAME \
  179. : public TRAITS_NAME##_ignore_signature<Type> \
  180. {};\
  181. //
  182. } //namespace detail
  183. } //namespace intrusive
  184. } //namespace boost
  185. #include <boost/intrusive/detail/config_end.hpp>
  186. #endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP