blob: cfe340c903376f0c54dd96c8c16a7af3d10f2eb0 [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001/////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2006-2012
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// See http://www.boost.org/libs/intrusive for documentation.
10//
11/////////////////////////////////////////////////////////////////////////////
12
Jeff Thompson3d613fd2013-10-15 15:39:04 -070013#ifndef NDNBOOST_INTRUSIVE_DETAIL_MPL_HPP
14#define NDNBOOST_INTRUSIVE_DETAIL_MPL_HPP
Jeff Thompsona28eed82013-08-22 16:21:10 -070015
16#include <ndnboost/intrusive/detail/config_begin.hpp>
17#include <cstddef>
18
19namespace ndnboost {
20namespace intrusive {
21namespace detail {
22
23typedef char one;
24struct two {one _[2];};
25
26template< bool C_ >
27struct bool_
28{
29 static const bool value = C_;
30};
31
32typedef bool_<true> true_;
33typedef bool_<false> false_;
34
35typedef true_ true_type;
36typedef false_ false_type;
37
38typedef char yes_type;
39struct no_type
40{
41 char padding[8];
42};
43
44template <bool B, class T = void>
45struct enable_if_c {
46 typedef T type;
47};
48
49template <class T>
50struct enable_if_c<false, T> {};
51
52template <class Cond, class T = void>
53struct enable_if : public enable_if_c<Cond::value, T>{};
54
55template<class F, class Param>
56struct apply
57{
58 typedef typename F::template apply<Param>::type type;
59};
60
61template <class T, class U>
62class is_convertible
63{
64 typedef char true_t;
65 class false_t { char dummy[2]; };
66 static true_t dispatch(U);
67 static false_t dispatch(...);
68 static const T &trigger();
69 public:
70 static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
71};
72
73template<
74 bool C
75 , typename T1
76 , typename T2
77 >
78struct if_c
79{
80 typedef T1 type;
81};
82
83template<
84 typename T1
85 , typename T2
86 >
87struct if_c<false,T1,T2>
88{
89 typedef T2 type;
90};
91
92template<
93 typename C
94 , typename T1
95 , typename T2
96 >
97struct if_
98{
99 typedef typename if_c<0 != C::value, T1, T2>::type type;
100};
101
102template<
103 bool C
104 , typename F1
105 , typename F2
106 >
107struct eval_if_c
108 : if_c<C,F1,F2>::type
109{};
110
111template<
112 typename C
113 , typename T1
114 , typename T2
115 >
116struct eval_if
117 : if_<C,T1,T2>::type
118{};
119
120// identity is an extension: it is not part of the standard.
121template <class T>
122struct identity
123{
124 typedef T type;
125};
126
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700127#if defined(NDNBOOST_MSVC) || defined(__BORLANDC_)
128#define NDNBOOST_INTRUSIVE_TT_DECL __cdecl
Jeff Thompsona28eed82013-08-22 16:21:10 -0700129#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700130#define NDNBOOST_INTRUSIVE_TT_DECL
Jeff Thompsona28eed82013-08-22 16:21:10 -0700131#endif
132
133#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(UNDER_CE)
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700134#define NDNBOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700135#endif
136
137template <typename T>
138struct is_unary_or_binary_function_impl
139{ static const bool value = false; };
140
141// see boost ticket #4094
142// avoid duplicate definitions of is_unary_or_binary_function_impl
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700143#ifndef NDNBOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700144
145template <typename R>
146struct is_unary_or_binary_function_impl<R (*)()>
147{ static const bool value = true; };
148
149template <typename R>
150struct is_unary_or_binary_function_impl<R (*)(...)>
151{ static const bool value = true; };
152
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700153#else // NDNBOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700154
155template <typename R>
156struct is_unary_or_binary_function_impl<R (__stdcall*)()>
157{ static const bool value = true; };
158
159#ifndef _MANAGED
160
161template <typename R>
162struct is_unary_or_binary_function_impl<R (__fastcall*)()>
163{ static const bool value = true; };
164
165#endif
166
167template <typename R>
168struct is_unary_or_binary_function_impl<R (__cdecl*)()>
169{ static const bool value = true; };
170
171template <typename R>
172struct is_unary_or_binary_function_impl<R (__cdecl*)(...)>
173{ static const bool value = true; };
174
175#endif
176
177// see boost ticket #4094
178// avoid duplicate definitions of is_unary_or_binary_function_impl
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700179#ifndef NDNBOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700180
181template <typename R, class T0>
182struct is_unary_or_binary_function_impl<R (*)(T0)>
183{ static const bool value = true; };
184
185template <typename R, class T0>
186struct is_unary_or_binary_function_impl<R (*)(T0...)>
187{ static const bool value = true; };
188
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700189#else // NDNBOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700190
191template <typename R, class T0>
192struct is_unary_or_binary_function_impl<R (__stdcall*)(T0)>
193{ static const bool value = true; };
194
195#ifndef _MANAGED
196
197template <typename R, class T0>
198struct is_unary_or_binary_function_impl<R (__fastcall*)(T0)>
199{ static const bool value = true; };
200
201#endif
202
203template <typename R, class T0>
204struct is_unary_or_binary_function_impl<R (__cdecl*)(T0)>
205{ static const bool value = true; };
206
207template <typename R, class T0>
208struct is_unary_or_binary_function_impl<R (__cdecl*)(T0...)>
209{ static const bool value = true; };
210
211#endif
212
213// see boost ticket #4094
214// avoid duplicate definitions of is_unary_or_binary_function_impl
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700215#ifndef NDNBOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700216
217template <typename R, class T0, class T1>
218struct is_unary_or_binary_function_impl<R (*)(T0, T1)>
219{ static const bool value = true; };
220
221template <typename R, class T0, class T1>
222struct is_unary_or_binary_function_impl<R (*)(T0, T1...)>
223{ static const bool value = true; };
224
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700225#else // NDNBOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700226
227template <typename R, class T0, class T1>
228struct is_unary_or_binary_function_impl<R (__stdcall*)(T0, T1)>
229{ static const bool value = true; };
230
231#ifndef _MANAGED
232
233template <typename R, class T0, class T1>
234struct is_unary_or_binary_function_impl<R (__fastcall*)(T0, T1)>
235{ static const bool value = true; };
236
237#endif
238
239template <typename R, class T0, class T1>
240struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1)>
241{ static const bool value = true; };
242
243template <typename R, class T0, class T1>
244struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1...)>
245{ static const bool value = true; };
246#endif
247
248template <typename T>
249struct is_unary_or_binary_function_impl<T&>
250{ static const bool value = false; };
251
252template<typename T>
253struct is_unary_or_binary_function
254{ static const bool value = is_unary_or_binary_function_impl<T>::value; };
255
256//ndnboost::alignment_of yields to 10K lines of preprocessed code, so we
257//need an alternative
258template <typename T> struct alignment_of;
259
260template <typename T>
261struct alignment_of_hack
262{
263 char c;
264 T t;
265 alignment_of_hack();
266};
267
268template <unsigned A, unsigned S>
269struct alignment_logic
270{
271 static const std::size_t value = A < S ? A : S;
272};
273
274template< typename T >
275struct alignment_of
276{
277 static const std::size_t value = alignment_logic
278 < sizeof(alignment_of_hack<T>) - sizeof(T)
279 , sizeof(T)
280 >::value;
281};
282
283template <typename T, typename U>
284struct is_same
285{
286 typedef char yes_type;
287 struct no_type
288 {
289 char padding[8];
290 };
291
292 template <typename V>
293 static yes_type is_same_tester(V*, V*);
294 static no_type is_same_tester(...);
295
296 static T *t;
297 static U *u;
298
299 static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
300};
301
302template<typename T>
303struct add_const
304{ typedef const T type; };
305
306template<typename T>
307struct remove_const
308{ typedef T type; };
309
310template<typename T>
311struct remove_const<const T>
312{ typedef T type; };
313
314template<typename T>
315struct remove_cv
316{ typedef T type; };
317
318template<typename T>
319struct remove_cv<const T>
320{ typedef T type; };
321
322template<typename T>
323struct remove_cv<const volatile T>
324{ typedef T type; };
325
326template<typename T>
327struct remove_cv<volatile T>
328{ typedef T type; };
329
330template<class T>
331struct remove_reference
332{
333 typedef T type;
334};
335
336template<class T>
337struct remove_reference<T&>
338{
339 typedef T type;
340};
341
342template<class Class>
343class is_empty_class
344{
345 template <typename T>
346 struct empty_helper_t1 : public T
347 {
348 empty_helper_t1();
349 int i[256];
350 };
351
352 struct empty_helper_t2
353 { int i[256]; };
354
355 public:
356 static const bool value = sizeof(empty_helper_t1<Class>) == sizeof(empty_helper_t2);
357};
358
359template<std::size_t S>
360struct ls_zeros
361{
362 static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value);
363};
364
365template<>
366struct ls_zeros<0>
367{
368 static const std::size_t value = 0;
369};
370
371template<>
372struct ls_zeros<1>
373{
374 static const std::size_t value = 0;
375};
376
377} //namespace detail
378} //namespace intrusive
379} //namespace ndnboost
380
381#include <ndnboost/intrusive/detail/config_end.hpp>
382
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700383#endif //NDNBOOST_INTRUSIVE_DETAIL_MPL_HPP