Chris@16
|
1 /////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@101
|
3 // (C) Copyright Ion Gaztanaga 2006-2014
|
Chris@101
|
4 // (C) Copyright Microsoft Corporation 2014
|
Chris@16
|
5 //
|
Chris@16
|
6 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
7 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
8 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 //
|
Chris@16
|
10 // See http://www.boost.org/libs/intrusive for documentation.
|
Chris@16
|
11 //
|
Chris@16
|
12 /////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
13
|
Chris@16
|
14 #ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP
|
Chris@16
|
15 #define BOOST_INTRUSIVE_DETAIL_MPL_HPP
|
Chris@16
|
16
|
Chris@101
|
17 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
18 # include <boost/config.hpp>
|
Chris@101
|
19 #endif
|
Chris@101
|
20
|
Chris@101
|
21 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@101
|
22 # pragma once
|
Chris@101
|
23 #endif
|
Chris@101
|
24
|
Chris@16
|
25 #include <boost/intrusive/detail/config_begin.hpp>
|
Chris@16
|
26 #include <cstddef>
|
Chris@16
|
27
|
Chris@16
|
28 namespace boost {
|
Chris@16
|
29 namespace intrusive {
|
Chris@16
|
30 namespace detail {
|
Chris@16
|
31
|
Chris@101
|
32 template <typename T, typename U>
|
Chris@101
|
33 struct is_same
|
Chris@101
|
34 {
|
Chris@101
|
35 static const bool value = false;
|
Chris@101
|
36 };
|
Chris@101
|
37
|
Chris@101
|
38 template <typename T>
|
Chris@101
|
39 struct is_same<T, T>
|
Chris@101
|
40 {
|
Chris@101
|
41 static const bool value = true;
|
Chris@101
|
42 };
|
Chris@101
|
43
|
Chris@101
|
44 template<typename T>
|
Chris@101
|
45 struct add_const
|
Chris@101
|
46 { typedef const T type; };
|
Chris@101
|
47
|
Chris@101
|
48 template<typename T>
|
Chris@101
|
49 struct remove_const
|
Chris@101
|
50 { typedef T type; };
|
Chris@101
|
51
|
Chris@101
|
52 template<typename T>
|
Chris@101
|
53 struct remove_const<const T>
|
Chris@101
|
54 { typedef T type; };
|
Chris@101
|
55
|
Chris@101
|
56 template<typename T>
|
Chris@101
|
57 struct remove_cv
|
Chris@101
|
58 { typedef T type; };
|
Chris@101
|
59
|
Chris@101
|
60 template<typename T>
|
Chris@101
|
61 struct remove_cv<const T>
|
Chris@101
|
62 { typedef T type; };
|
Chris@101
|
63
|
Chris@101
|
64 template<typename T>
|
Chris@101
|
65 struct remove_cv<const volatile T>
|
Chris@101
|
66 { typedef T type; };
|
Chris@101
|
67
|
Chris@101
|
68 template<typename T>
|
Chris@101
|
69 struct remove_cv<volatile T>
|
Chris@101
|
70 { typedef T type; };
|
Chris@101
|
71
|
Chris@101
|
72 template<class T>
|
Chris@101
|
73 struct remove_reference
|
Chris@101
|
74 {
|
Chris@101
|
75 typedef T type;
|
Chris@101
|
76 };
|
Chris@101
|
77
|
Chris@101
|
78 template<class T>
|
Chris@101
|
79 struct remove_reference<T&>
|
Chris@101
|
80 {
|
Chris@101
|
81 typedef T type;
|
Chris@101
|
82 };
|
Chris@101
|
83
|
Chris@101
|
84 template<class T>
|
Chris@101
|
85 struct remove_pointer
|
Chris@101
|
86 {
|
Chris@101
|
87 typedef T type;
|
Chris@101
|
88 };
|
Chris@101
|
89
|
Chris@101
|
90 template<class T>
|
Chris@101
|
91 struct remove_pointer<T*>
|
Chris@101
|
92 {
|
Chris@101
|
93 typedef T type;
|
Chris@101
|
94 };
|
Chris@101
|
95
|
Chris@101
|
96 template<class T>
|
Chris@101
|
97 struct add_pointer
|
Chris@101
|
98 {
|
Chris@101
|
99 typedef T *type;
|
Chris@101
|
100 };
|
Chris@101
|
101
|
Chris@16
|
102 typedef char one;
|
Chris@16
|
103 struct two {one _[2];};
|
Chris@16
|
104
|
Chris@16
|
105 template< bool C_ >
|
Chris@16
|
106 struct bool_
|
Chris@16
|
107 {
|
Chris@16
|
108 static const bool value = C_;
|
Chris@16
|
109 };
|
Chris@16
|
110
|
Chris@101
|
111 template< class Integer, Integer Value >
|
Chris@101
|
112 struct integer
|
Chris@101
|
113 {
|
Chris@101
|
114 static const Integer value = Value;
|
Chris@101
|
115 };
|
Chris@101
|
116
|
Chris@16
|
117 typedef bool_<true> true_;
|
Chris@16
|
118 typedef bool_<false> false_;
|
Chris@16
|
119
|
Chris@16
|
120 typedef true_ true_type;
|
Chris@16
|
121 typedef false_ false_type;
|
Chris@16
|
122
|
Chris@16
|
123 typedef char yes_type;
|
Chris@16
|
124 struct no_type
|
Chris@16
|
125 {
|
Chris@16
|
126 char padding[8];
|
Chris@16
|
127 };
|
Chris@16
|
128
|
Chris@16
|
129 template <bool B, class T = void>
|
Chris@16
|
130 struct enable_if_c {
|
Chris@16
|
131 typedef T type;
|
Chris@16
|
132 };
|
Chris@16
|
133
|
Chris@16
|
134 template <class T>
|
Chris@16
|
135 struct enable_if_c<false, T> {};
|
Chris@16
|
136
|
Chris@16
|
137 template <class Cond, class T = void>
|
Chris@16
|
138 struct enable_if : public enable_if_c<Cond::value, T>{};
|
Chris@16
|
139
|
Chris@16
|
140 template<class F, class Param>
|
Chris@16
|
141 struct apply
|
Chris@16
|
142 {
|
Chris@16
|
143 typedef typename F::template apply<Param>::type type;
|
Chris@16
|
144 };
|
Chris@16
|
145
|
Chris@101
|
146 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
Chris@101
|
147
|
Chris@101
|
148 template <class T, class U>
|
Chris@101
|
149 struct is_convertible
|
Chris@101
|
150 {
|
Chris@101
|
151 static const bool value = __is_convertible_to(T, U);
|
Chris@101
|
152 };
|
Chris@101
|
153
|
Chris@101
|
154 #else
|
Chris@101
|
155
|
Chris@16
|
156 template <class T, class U>
|
Chris@16
|
157 class is_convertible
|
Chris@16
|
158 {
|
Chris@16
|
159 typedef char true_t;
|
Chris@16
|
160 class false_t { char dummy[2]; };
|
Chris@101
|
161 //use any_conversion as first parameter since in MSVC
|
Chris@101
|
162 //overaligned types can't go through ellipsis
|
Chris@16
|
163 static false_t dispatch(...);
|
Chris@101
|
164 static true_t dispatch(U);
|
Chris@101
|
165 static typename remove_reference<T>::type &trigger();
|
Chris@16
|
166 public:
|
Chris@16
|
167 static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
|
Chris@16
|
168 };
|
Chris@16
|
169
|
Chris@101
|
170 #endif
|
Chris@101
|
171
|
Chris@16
|
172 template<
|
Chris@16
|
173 bool C
|
Chris@16
|
174 , typename T1
|
Chris@16
|
175 , typename T2
|
Chris@16
|
176 >
|
Chris@16
|
177 struct if_c
|
Chris@16
|
178 {
|
Chris@16
|
179 typedef T1 type;
|
Chris@16
|
180 };
|
Chris@16
|
181
|
Chris@16
|
182 template<
|
Chris@16
|
183 typename T1
|
Chris@16
|
184 , typename T2
|
Chris@16
|
185 >
|
Chris@16
|
186 struct if_c<false,T1,T2>
|
Chris@16
|
187 {
|
Chris@16
|
188 typedef T2 type;
|
Chris@16
|
189 };
|
Chris@16
|
190
|
Chris@16
|
191 template<
|
Chris@16
|
192 typename C
|
Chris@16
|
193 , typename T1
|
Chris@16
|
194 , typename T2
|
Chris@16
|
195 >
|
Chris@16
|
196 struct if_
|
Chris@16
|
197 {
|
Chris@16
|
198 typedef typename if_c<0 != C::value, T1, T2>::type type;
|
Chris@16
|
199 };
|
Chris@16
|
200
|
Chris@16
|
201 template<
|
Chris@16
|
202 bool C
|
Chris@16
|
203 , typename F1
|
Chris@16
|
204 , typename F2
|
Chris@16
|
205 >
|
Chris@16
|
206 struct eval_if_c
|
Chris@16
|
207 : if_c<C,F1,F2>::type
|
Chris@16
|
208 {};
|
Chris@16
|
209
|
Chris@16
|
210 template<
|
Chris@16
|
211 typename C
|
Chris@16
|
212 , typename T1
|
Chris@16
|
213 , typename T2
|
Chris@16
|
214 >
|
Chris@16
|
215 struct eval_if
|
Chris@16
|
216 : if_<C,T1,T2>::type
|
Chris@16
|
217 {};
|
Chris@16
|
218
|
Chris@16
|
219 // identity is an extension: it is not part of the standard.
|
Chris@16
|
220 template <class T>
|
Chris@16
|
221 struct identity
|
Chris@16
|
222 {
|
Chris@16
|
223 typedef T type;
|
Chris@16
|
224 };
|
Chris@16
|
225
|
Chris@101
|
226 template<class T, bool Add>
|
Chris@101
|
227 struct add_const_if_c
|
Chris@101
|
228 {
|
Chris@101
|
229 typedef typename if_c
|
Chris@101
|
230 < Add
|
Chris@101
|
231 , typename add_const<T>::type
|
Chris@101
|
232 , T
|
Chris@101
|
233 >::type type;
|
Chris@101
|
234 };
|
Chris@16
|
235
|
Chris@16
|
236
|
Chris@16
|
237 //boost::alignment_of yields to 10K lines of preprocessed code, so we
|
Chris@16
|
238 //need an alternative
|
Chris@16
|
239 template <typename T> struct alignment_of;
|
Chris@16
|
240
|
Chris@16
|
241 template <typename T>
|
Chris@16
|
242 struct alignment_of_hack
|
Chris@16
|
243 {
|
Chris@16
|
244 char c;
|
Chris@16
|
245 T t;
|
Chris@16
|
246 alignment_of_hack();
|
Chris@16
|
247 };
|
Chris@16
|
248
|
Chris@16
|
249 template <unsigned A, unsigned S>
|
Chris@16
|
250 struct alignment_logic
|
Chris@16
|
251 {
|
Chris@16
|
252 static const std::size_t value = A < S ? A : S;
|
Chris@16
|
253 };
|
Chris@16
|
254
|
Chris@16
|
255 template< typename T >
|
Chris@16
|
256 struct alignment_of
|
Chris@16
|
257 {
|
Chris@16
|
258 static const std::size_t value = alignment_logic
|
Chris@16
|
259 < sizeof(alignment_of_hack<T>) - sizeof(T)
|
Chris@16
|
260 , sizeof(T)
|
Chris@16
|
261 >::value;
|
Chris@16
|
262 };
|
Chris@16
|
263
|
Chris@16
|
264 template<class Class>
|
Chris@16
|
265 class is_empty_class
|
Chris@16
|
266 {
|
Chris@16
|
267 template <typename T>
|
Chris@16
|
268 struct empty_helper_t1 : public T
|
Chris@16
|
269 {
|
Chris@16
|
270 empty_helper_t1();
|
Chris@16
|
271 int i[256];
|
Chris@16
|
272 };
|
Chris@16
|
273
|
Chris@16
|
274 struct empty_helper_t2
|
Chris@16
|
275 { int i[256]; };
|
Chris@16
|
276
|
Chris@16
|
277 public:
|
Chris@16
|
278 static const bool value = sizeof(empty_helper_t1<Class>) == sizeof(empty_helper_t2);
|
Chris@16
|
279 };
|
Chris@16
|
280
|
Chris@16
|
281 template<std::size_t S>
|
Chris@16
|
282 struct ls_zeros
|
Chris@16
|
283 {
|
Chris@16
|
284 static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value);
|
Chris@16
|
285 };
|
Chris@16
|
286
|
Chris@16
|
287 template<>
|
Chris@16
|
288 struct ls_zeros<0>
|
Chris@16
|
289 {
|
Chris@16
|
290 static const std::size_t value = 0;
|
Chris@16
|
291 };
|
Chris@16
|
292
|
Chris@16
|
293 template<>
|
Chris@16
|
294 struct ls_zeros<1>
|
Chris@16
|
295 {
|
Chris@16
|
296 static const std::size_t value = 0;
|
Chris@16
|
297 };
|
Chris@16
|
298
|
Chris@101
|
299 template <typename T> struct unvoid_ref { typedef T &type; };
|
Chris@101
|
300 template <> struct unvoid_ref<void> { struct type_impl { }; typedef type_impl & type; };
|
Chris@101
|
301 template <> struct unvoid_ref<const void> { struct type_impl { }; typedef type_impl & type; };
|
Chris@101
|
302
|
Chris@101
|
303 // Infrastructure for providing a default type for T::TNAME if absent.
|
Chris@101
|
304 #define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
|
Chris@101
|
305 template <typename T, typename DefaultType> \
|
Chris@101
|
306 struct boost_intrusive_default_type_ ## TNAME \
|
Chris@101
|
307 { \
|
Chris@101
|
308 template <typename X> \
|
Chris@101
|
309 static char test(int, typename X::TNAME*); \
|
Chris@101
|
310 \
|
Chris@101
|
311 template <typename X> \
|
Chris@101
|
312 static int test(...); \
|
Chris@101
|
313 \
|
Chris@101
|
314 struct DefaultWrap { typedef DefaultType TNAME; }; \
|
Chris@101
|
315 \
|
Chris@101
|
316 static const bool value = (1 == sizeof(test<T>(0, 0))); \
|
Chris@101
|
317 \
|
Chris@101
|
318 typedef typename \
|
Chris@101
|
319 ::boost::intrusive::detail::if_c \
|
Chris@101
|
320 <value, T, DefaultWrap>::type::TNAME type; \
|
Chris@101
|
321 }; \
|
Chris@101
|
322 //
|
Chris@101
|
323
|
Chris@101
|
324 #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
|
Chris@101
|
325 typename INSTANTIATION_NS_PREFIX \
|
Chris@101
|
326 boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
|
Chris@101
|
327 //
|
Chris@101
|
328
|
Chris@101
|
329 #define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\
|
Chris@101
|
330 template <typename T, typename DefaultType> \
|
Chris@101
|
331 struct boost_intrusive_eval_default_type_ ## TNAME \
|
Chris@101
|
332 { \
|
Chris@101
|
333 template <typename X> \
|
Chris@101
|
334 static char test(int, typename X::TNAME*); \
|
Chris@101
|
335 \
|
Chris@101
|
336 template <typename X> \
|
Chris@101
|
337 static int test(...); \
|
Chris@101
|
338 \
|
Chris@101
|
339 struct DefaultWrap \
|
Chris@101
|
340 { typedef typename DefaultType::type TNAME; }; \
|
Chris@101
|
341 \
|
Chris@101
|
342 static const bool value = (1 == sizeof(test<T>(0, 0))); \
|
Chris@101
|
343 \
|
Chris@101
|
344 typedef typename \
|
Chris@101
|
345 ::boost::intrusive::detail::eval_if_c \
|
Chris@101
|
346 < value \
|
Chris@101
|
347 , ::boost::intrusive::detail::identity<T> \
|
Chris@101
|
348 , ::boost::intrusive::detail::identity<DefaultWrap> \
|
Chris@101
|
349 >::type::TNAME type; \
|
Chris@101
|
350 }; \
|
Chris@101
|
351 //
|
Chris@101
|
352
|
Chris@101
|
353 #define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
|
Chris@101
|
354 typename INSTANTIATION_NS_PREFIX \
|
Chris@101
|
355 boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \
|
Chris@101
|
356 //
|
Chris@101
|
357
|
Chris@101
|
358 #define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \
|
Chris@101
|
359 template <class T>\
|
Chris@101
|
360 struct TRAITS_PREFIX##_bool\
|
Chris@101
|
361 {\
|
Chris@101
|
362 template<bool Add>\
|
Chris@101
|
363 struct two_or_three {one _[2 + Add];};\
|
Chris@101
|
364 template <class U> static one test(...);\
|
Chris@101
|
365 template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
|
Chris@101
|
366 static const std::size_t value = sizeof(test<T>(0));\
|
Chris@101
|
367 };\
|
Chris@101
|
368 \
|
Chris@101
|
369 template <class T>\
|
Chris@101
|
370 struct TRAITS_PREFIX##_bool_is_true\
|
Chris@101
|
371 {\
|
Chris@101
|
372 static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(one)*2;\
|
Chris@101
|
373 };\
|
Chris@101
|
374 //
|
Chris@101
|
375
|
Chris@101
|
376 #define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
|
Chris@101
|
377 template <typename U, typename Signature> \
|
Chris@101
|
378 class TRAITS_NAME \
|
Chris@101
|
379 { \
|
Chris@101
|
380 private: \
|
Chris@101
|
381 template<Signature> struct helper;\
|
Chris@101
|
382 template<typename T> \
|
Chris@101
|
383 static ::boost::intrusive::detail::yes_type check(helper<&T::FUNC_NAME>*); \
|
Chris@101
|
384 template<typename T> static ::boost::intrusive::detail::no_type check(...); \
|
Chris@101
|
385 public: \
|
Chris@101
|
386 static const bool value = sizeof(check<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
|
Chris@101
|
387 }; \
|
Chris@101
|
388 //
|
Chris@101
|
389
|
Chris@101
|
390 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \
|
Chris@101
|
391 template <typename Type> \
|
Chris@101
|
392 struct TRAITS_NAME \
|
Chris@101
|
393 { \
|
Chris@101
|
394 struct BaseMixin \
|
Chris@101
|
395 { \
|
Chris@101
|
396 void FUNC_NAME(); \
|
Chris@101
|
397 }; \
|
Chris@101
|
398 struct Base : public Type, public BaseMixin { Base(); }; \
|
Chris@101
|
399 template <typename T, T t> class Helper{}; \
|
Chris@101
|
400 template <typename U> \
|
Chris@101
|
401 static ::boost::intrusive::detail::no_type check(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
|
Chris@101
|
402 static ::boost::intrusive::detail::yes_type check(...); \
|
Chris@101
|
403 static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(check((Base*)(0))); \
|
Chris@101
|
404 };\
|
Chris@101
|
405 //
|
Chris@101
|
406
|
Chris@101
|
407 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \
|
Chris@101
|
408 BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \
|
Chris@101
|
409 \
|
Chris@101
|
410 template <typename Type, class> \
|
Chris@101
|
411 struct TRAITS_NAME \
|
Chris@101
|
412 : public TRAITS_NAME##_ignore_signature<Type> \
|
Chris@101
|
413 {};\
|
Chris@101
|
414 //
|
Chris@101
|
415
|
Chris@101
|
416
|
Chris@101
|
417 template <typename T>
|
Chris@101
|
418 inline T* addressof(T& obj)
|
Chris@101
|
419 {
|
Chris@101
|
420 return static_cast<T*>
|
Chris@101
|
421 (static_cast<void*>
|
Chris@101
|
422 (const_cast<char*>
|
Chris@101
|
423 (&reinterpret_cast<const char&>(obj))
|
Chris@101
|
424 )
|
Chris@101
|
425 );
|
Chris@101
|
426 }
|
Chris@101
|
427
|
Chris@16
|
428 } //namespace detail
|
Chris@16
|
429 } //namespace intrusive
|
Chris@16
|
430 } //namespace boost
|
Chris@16
|
431
|
Chris@16
|
432 #include <boost/intrusive/detail/config_end.hpp>
|
Chris@16
|
433
|
Chris@16
|
434 #endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP
|