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

source code of boost/libs/intrusive/include/boost/intrusive/detail/mpl.hpp