Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / detail / indirect_traits.hpp
1 // Copyright David Abrahams 2002.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #ifndef INDIRECT_TRAITS_DWA2002131_HPP
6 # define INDIRECT_TRAITS_DWA2002131_HPP
7 # include <boost/type_traits/is_function.hpp>
8 # include <boost/type_traits/is_reference.hpp>
9 # include <boost/type_traits/is_pointer.hpp>
10 # include <boost/type_traits/is_class.hpp>
11 # include <boost/type_traits/is_const.hpp>
12 # include <boost/type_traits/is_volatile.hpp>
13 # include <boost/type_traits/is_member_function_pointer.hpp>
14 # include <boost/type_traits/is_member_pointer.hpp>
15 # include <boost/type_traits/remove_cv.hpp>
16 # include <boost/type_traits/remove_reference.hpp>
17 # include <boost/type_traits/remove_pointer.hpp>
18
19 # include <boost/type_traits/detail/ice_and.hpp>
20 # include <boost/detail/workaround.hpp>
21
22 # include <boost/mpl/eval_if.hpp>
23 # include <boost/mpl/if.hpp>
24 # include <boost/mpl/bool.hpp>
25 # include <boost/mpl/and.hpp>
26 # include <boost/mpl/not.hpp>
27 # include <boost/mpl/aux_/lambda_support.hpp>
28
29 #  ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
30 #   include <boost/detail/is_function_ref_tester.hpp>
31 #  endif 
32
33 namespace boost { namespace detail {
34
35 namespace indirect_traits {
36
37 #  ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
38 template <class T>
39 struct is_reference_to_const : mpl::false_
40 {
41 };
42
43 template <class T>
44 struct is_reference_to_const<T const&> : mpl::true_
45 {
46 };
47
48 #   if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround
49 template<class T>
50 struct is_reference_to_const<T const volatile&> : mpl::true_
51 {
52 };
53 #   endif 
54
55 template <class T>
56 struct is_reference_to_function : mpl::false_
57 {
58 };
59
60 template <class T>
61 struct is_reference_to_function<T&> : is_function<T>
62 {
63 };
64
65 template <class T>
66 struct is_pointer_to_function : mpl::false_
67 {
68 };
69
70 // There's no such thing as a pointer-to-cv-function, so we don't need
71 // specializations for those
72 template <class T>
73 struct is_pointer_to_function<T*> : is_function<T>
74 {
75 };
76
77 template <class T>
78 struct is_reference_to_member_function_pointer_impl : mpl::false_
79 {
80 };
81
82 template <class T>
83 struct is_reference_to_member_function_pointer_impl<T&>
84     : is_member_function_pointer<typename remove_cv<T>::type>
85 {
86 };
87
88
89 template <class T>
90 struct is_reference_to_member_function_pointer
91     : is_reference_to_member_function_pointer_impl<T>
92 {
93     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T))
94 };
95
96 template <class T>
97 struct is_reference_to_function_pointer_aux
98     : mpl::and_<
99           is_reference<T>
100         , is_pointer_to_function<
101               typename remove_cv<
102                   typename remove_reference<T>::type
103               >::type
104           >
105       >
106 {
107     // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those
108 };
109
110 template <class T>
111 struct is_reference_to_function_pointer
112     : mpl::if_<
113           is_reference_to_function<T>
114         , mpl::false_
115         , is_reference_to_function_pointer_aux<T>
116      >::type
117 {
118 };
119
120 template <class T>
121 struct is_reference_to_non_const
122     : mpl::and_<
123           is_reference<T>
124         , mpl::not_<
125              is_reference_to_const<T>
126           >
127       >
128 {
129 };
130
131 template <class T>
132 struct is_reference_to_volatile : mpl::false_
133 {
134 };
135
136 template <class T>
137 struct is_reference_to_volatile<T volatile&> : mpl::true_
138 {
139 };
140
141 #   if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround
142 template <class T>
143 struct is_reference_to_volatile<T const volatile&> : mpl::true_
144 {
145 };
146 #   endif 
147
148
149 template <class T>
150 struct is_reference_to_pointer : mpl::false_
151 {
152 };
153
154 template <class T>
155 struct is_reference_to_pointer<T*&> : mpl::true_
156 {
157 };
158
159 template <class T>
160 struct is_reference_to_pointer<T* const&> : mpl::true_
161 {
162 };
163
164 template <class T>
165 struct is_reference_to_pointer<T* volatile&> : mpl::true_
166 {
167 };
168
169 template <class T>
170 struct is_reference_to_pointer<T* const volatile&> : mpl::true_
171 {
172 };
173
174 template <class T>
175 struct is_reference_to_class
176     : mpl::and_<
177           is_reference<T>
178         , is_class<
179               typename remove_cv<
180                   typename remove_reference<T>::type
181               >::type
182           >
183       >
184 {
185     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T))
186 };
187
188 template <class T>
189 struct is_pointer_to_class
190     : mpl::and_<
191           is_pointer<T>
192         , is_class<
193               typename remove_cv<
194                   typename remove_pointer<T>::type
195               >::type
196           >
197       >
198 {
199     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T))
200 };
201
202 #  else
203
204 using namespace boost::detail::is_function_ref_tester_;
205
206 typedef char (&inner_yes_type)[3];
207 typedef char (&inner_no_type)[2];
208 typedef char (&outer_no_type)[1];
209
210 template <typename V>
211 struct is_const_help
212 {
213     typedef typename mpl::if_<
214           is_const<V>
215         , inner_yes_type
216         , inner_no_type
217         >::type type;
218 };
219
220 template <typename V>
221 struct is_volatile_help
222 {
223     typedef typename mpl::if_<
224           is_volatile<V>
225         , inner_yes_type
226         , inner_no_type
227         >::type type;
228 };
229
230 template <typename V>
231 struct is_pointer_help
232 {
233     typedef typename mpl::if_<
234           is_pointer<V>
235         , inner_yes_type
236         , inner_no_type
237         >::type type;
238 };
239
240 template <typename V>
241 struct is_class_help
242 {
243     typedef typename mpl::if_<
244           is_class<V>
245         , inner_yes_type
246         , inner_no_type
247         >::type type;
248 };
249
250 template <class T>
251 struct is_reference_to_function_aux
252 {
253     static T t;
254     BOOST_STATIC_CONSTANT(
255         bool, value = sizeof(detail::is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type));
256     typedef mpl::bool_<value> type;
257  };
258
259 template <class T>
260 struct is_reference_to_function
261     : mpl::if_<is_reference<T>, is_reference_to_function_aux<T>, mpl::bool_<false> >::type
262 {
263 };
264
265 template <class T>
266 struct is_pointer_to_function_aux
267 {
268     static T t;
269     BOOST_STATIC_CONSTANT(
270         bool, value
271         = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type));
272     typedef mpl::bool_<value> type;
273 };
274
275 template <class T>
276 struct is_pointer_to_function
277     : mpl::if_<is_pointer<T>, is_pointer_to_function_aux<T>, mpl::bool_<false> >::type
278 {
279     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T))
280 };
281
282 struct false_helper1
283 {
284     template <class T>
285     struct apply : mpl::false_
286     {
287     };
288 };
289
290 template <typename V>
291 typename is_const_help<V>::type reference_to_const_helper(V&);    
292 outer_no_type
293 reference_to_const_helper(...);
294
295 struct true_helper1
296 {
297     template <class T>
298     struct apply
299     {
300         static T t;
301         BOOST_STATIC_CONSTANT(
302             bool, value
303             = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type));
304         typedef mpl::bool_<value> type;
305     };
306 };
307
308 template <bool ref = true>
309 struct is_reference_to_const_helper1 : true_helper1
310 {
311 };
312
313 template <>
314 struct is_reference_to_const_helper1<false> : false_helper1
315 {
316 };
317
318
319 template <class T>
320 struct is_reference_to_const
321     : is_reference_to_const_helper1<is_reference<T>::value>::template apply<T>
322 {
323 };
324
325
326 template <bool ref = true>
327 struct is_reference_to_non_const_helper1
328 {
329     template <class T>
330     struct apply
331     {
332         static T t;
333         BOOST_STATIC_CONSTANT(
334             bool, value
335             = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type));
336         
337         typedef mpl::bool_<value> type;
338     };
339 };
340
341 template <>
342 struct is_reference_to_non_const_helper1<false> : false_helper1
343 {
344 };
345
346
347 template <class T>
348 struct is_reference_to_non_const
349     : is_reference_to_non_const_helper1<is_reference<T>::value>::template apply<T>
350 {
351     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_non_const,(T))
352 };
353
354
355 template <typename V>
356 typename is_volatile_help<V>::type reference_to_volatile_helper(V&);    
357 outer_no_type
358 reference_to_volatile_helper(...);
359
360 template <bool ref = true>
361 struct is_reference_to_volatile_helper1
362 {
363     template <class T>
364     struct apply
365     {
366         static T t;
367         BOOST_STATIC_CONSTANT(
368             bool, value
369             = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type));
370         typedef mpl::bool_<value> type;
371     };
372 };
373
374 template <>
375 struct is_reference_to_volatile_helper1<false> : false_helper1
376 {
377 };
378
379
380 template <class T>
381 struct is_reference_to_volatile
382     : is_reference_to_volatile_helper1<is_reference<T>::value>::template apply<T>
383 {
384 };
385
386 template <typename V>
387 typename is_pointer_help<V>::type reference_to_pointer_helper(V&);
388 outer_no_type reference_to_pointer_helper(...);
389
390 template <class T>
391 struct is_reference_to_pointer
392 {
393     static T t;
394     BOOST_STATIC_CONSTANT(
395         bool, value
396         = (is_reference<T>::value
397            && sizeof((reference_to_pointer_helper)(t)) == sizeof(inner_yes_type))
398         );
399     
400     typedef mpl::bool_<value> type;
401     
402     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_pointer,(T))
403 };
404
405 template <class T>
406 struct is_reference_to_function_pointer
407     : mpl::if_<
408           is_reference<T>
409         , is_pointer_to_function_aux<T>
410         , mpl::bool_<false>
411      >::type
412 {
413     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T))
414 };
415
416
417 template <class T>
418 struct is_member_function_pointer_help
419     : mpl::if_<is_member_function_pointer<T>, inner_yes_type, inner_no_type>
420 {};
421
422 template <typename V>
423 typename is_member_function_pointer_help<V>::type member_function_pointer_helper(V&);
424 outer_no_type member_function_pointer_helper(...);
425
426 template <class T>
427 struct is_pointer_to_member_function_aux
428 {
429     static T t;
430     BOOST_STATIC_CONSTANT(
431         bool, value
432         = sizeof((member_function_pointer_helper)(t)) == sizeof(inner_yes_type));
433     typedef mpl::bool_<value> type;
434 };
435
436 template <class T>
437 struct is_reference_to_member_function_pointer
438     : mpl::if_<
439         is_reference<T>
440         , is_pointer_to_member_function_aux<T>
441         , mpl::bool_<false>
442      >::type
443 {
444     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T))
445 };
446
447 template <typename V>
448 typename is_class_help<V>::type reference_to_class_helper(V const volatile&);
449 outer_no_type reference_to_class_helper(...);
450
451 template <class T>
452 struct is_reference_to_class
453 {
454     static T t;
455     BOOST_STATIC_CONSTANT(
456         bool, value
457         = (is_reference<T>::value
458            & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type)))
459         );
460     typedef mpl::bool_<value> type;
461     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T))
462 };
463
464 template <typename V>
465 typename is_class_help<V>::type pointer_to_class_helper(V const volatile*);
466 outer_no_type pointer_to_class_helper(...);
467
468 template <class T>
469 struct is_pointer_to_class
470 {
471     static T t;
472     BOOST_STATIC_CONSTANT(
473         bool, value
474         = (is_pointer<T>::value
475            && sizeof(pointer_to_class_helper(t)) == sizeof(inner_yes_type))
476         );
477     typedef mpl::bool_<value> type;
478 };
479 #  endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 
480
481 }
482
483 using namespace indirect_traits;
484
485 }} // namespace boost::python::detail
486
487 #endif // INDIRECT_TRAITS_DWA2002131_HPP