Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/mpl/has_xxx.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 | |
2 #ifndef BOOST_MPL_HAS_XXX_HPP_INCLUDED | |
3 #define BOOST_MPL_HAS_XXX_HPP_INCLUDED | |
4 | |
5 // Copyright Aleksey Gurtovoy 2002-2006 | |
6 // Copyright David Abrahams 2002-2003 | |
7 // Copyright Daniel Walker 2007 | |
8 // | |
9 // Distributed under the Boost Software License, Version 1.0. | |
10 // (See accompanying file LICENSE_1_0.txt or copy at | |
11 // http://www.boost.org/LICENSE_1_0.txt) | |
12 // | |
13 // See http://www.boost.org/libs/mpl for documentation. | |
14 | |
15 // $Id: has_xxx.hpp 64146 2010-07-19 00:46:31Z djwalker $ | |
16 // $Date: 2010-07-18 17:46:31 -0700 (Sun, 18 Jul 2010) $ | |
17 // $Revision: 64146 $ | |
18 | |
19 #include <boost/mpl/bool.hpp> | |
20 #include <boost/mpl/aux_/na_spec.hpp> | |
21 #include <boost/mpl/aux_/type_wrapper.hpp> | |
22 #include <boost/mpl/aux_/yes_no.hpp> | |
23 #include <boost/mpl/aux_/config/gcc.hpp> | |
24 #include <boost/mpl/aux_/config/has_xxx.hpp> | |
25 #include <boost/mpl/aux_/config/msvc_typename.hpp> | |
26 #include <boost/mpl/aux_/config/msvc.hpp> | |
27 #include <boost/mpl/aux_/config/static_constant.hpp> | |
28 #include <boost/mpl/aux_/config/workaround.hpp> | |
29 | |
30 #include <boost/preprocessor/array/elem.hpp> | |
31 #include <boost/preprocessor/cat.hpp> | |
32 #include <boost/preprocessor/control/if.hpp> | |
33 #include <boost/preprocessor/repetition/enum_params.hpp> | |
34 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> | |
35 | |
36 #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) ) | |
37 # include <boost/type_traits/is_class.hpp> | |
38 #endif | |
39 | |
40 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX) | |
41 | |
42 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | |
43 | |
44 // agurt, 11/sep/02: MSVC-specific version (< 7.1), based on a USENET | |
45 // newsgroup's posting by John Madsen (comp.lang.c++.moderated, | |
46 // 1999-11-12 19:17:06 GMT); the code is _not_ standard-conforming, but | |
47 // it works way more reliably than the SFINAE-based implementation | |
48 | |
49 // Modified dwa 8/Oct/02 to handle reference types. | |
50 | |
51 # include <boost/mpl/if.hpp> | |
52 # include <boost/mpl/bool.hpp> | |
53 | |
54 namespace boost { namespace mpl { namespace aux { | |
55 | |
56 struct has_xxx_tag; | |
57 | |
58 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) | |
59 template< typename U > struct msvc_incomplete_array | |
60 { | |
61 typedef char (&type)[sizeof(U) + 1]; | |
62 }; | |
63 #endif | |
64 | |
65 template< typename T > | |
66 struct msvc_is_incomplete | |
67 { | |
68 // MSVC is capable of some kinds of SFINAE. If U is an incomplete | |
69 // type, it won't pick the second overload | |
70 static char tester(...); | |
71 | |
72 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) | |
73 template< typename U > | |
74 static typename msvc_incomplete_array<U>::type tester(type_wrapper<U>); | |
75 #else | |
76 template< typename U > | |
77 static char (& tester(type_wrapper<U>) )[sizeof(U)+1]; | |
78 #endif | |
79 | |
80 BOOST_STATIC_CONSTANT(bool, value = | |
81 sizeof(tester(type_wrapper<T>())) == 1 | |
82 ); | |
83 }; | |
84 | |
85 template<> | |
86 struct msvc_is_incomplete<int> | |
87 { | |
88 BOOST_STATIC_CONSTANT(bool, value = false); | |
89 }; | |
90 | |
91 }}} | |
92 | |
93 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, default_) \ | |
94 template< typename T, typename name = ::boost::mpl::aux::has_xxx_tag > \ | |
95 struct BOOST_PP_CAT(trait,_impl) : T \ | |
96 { \ | |
97 static boost::mpl::aux::no_tag \ | |
98 test(void(*)(::boost::mpl::aux::has_xxx_tag)); \ | |
99 \ | |
100 static boost::mpl::aux::yes_tag test(...); \ | |
101 \ | |
102 BOOST_STATIC_CONSTANT(bool, value = \ | |
103 sizeof(test(static_cast<void(*)(name)>(0))) \ | |
104 != sizeof(boost::mpl::aux::no_tag) \ | |
105 ); \ | |
106 typedef boost::mpl::bool_<value> type; \ | |
107 }; \ | |
108 \ | |
109 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \ | |
110 struct trait \ | |
111 : boost::mpl::if_c< \ | |
112 boost::mpl::aux::msvc_is_incomplete<T>::value \ | |
113 , boost::mpl::bool_<false> \ | |
114 , BOOST_PP_CAT(trait,_impl)<T> \ | |
115 >::type \ | |
116 { \ | |
117 }; \ | |
118 \ | |
119 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, void) \ | |
120 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, bool) \ | |
121 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, char) \ | |
122 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed char) \ | |
123 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned char) \ | |
124 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed short) \ | |
125 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned short) \ | |
126 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed int) \ | |
127 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned int) \ | |
128 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed long) \ | |
129 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned long) \ | |
130 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, float) \ | |
131 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, double) \ | |
132 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, long double) \ | |
133 /**/ | |
134 | |
135 # define BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, T) \ | |
136 template<> struct trait<T> \ | |
137 { \ | |
138 BOOST_STATIC_CONSTANT(bool, value = false); \ | |
139 typedef boost::mpl::bool_<false> type; \ | |
140 }; \ | |
141 /**/ | |
142 | |
143 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) | |
144 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \ | |
145 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \ | |
146 BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, wchar_t) \ | |
147 /**/ | |
148 #else | |
149 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \ | |
150 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \ | |
151 /**/ | |
152 #endif | |
153 | |
154 | |
155 // SFINAE-based implementations below are derived from a USENET newsgroup's | |
156 // posting by Rani Sharoni (comp.lang.c++.moderated, 2002-03-17 07:45:09 PST) | |
157 | |
158 # elif BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ | |
159 || BOOST_WORKAROUND(__IBMCPP__, <= 700) | |
160 | |
161 // MSVC 7.1+ & VACPP | |
162 | |
163 // agurt, 15/jun/05: replace overload-based SFINAE implementation with SFINAE | |
164 // applied to partial specialization to fix some apparently random failures | |
165 // (thanks to Daniel Wallin for researching this!) | |
166 | |
167 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \ | |
168 template< typename T > \ | |
169 struct BOOST_PP_CAT(trait, _msvc_sfinae_helper) \ | |
170 { \ | |
171 typedef void type; \ | |
172 };\ | |
173 \ | |
174 template< typename T, typename U = void > \ | |
175 struct BOOST_PP_CAT(trait,_impl_) \ | |
176 { \ | |
177 BOOST_STATIC_CONSTANT(bool, value = false); \ | |
178 typedef boost::mpl::bool_<value> type; \ | |
179 }; \ | |
180 \ | |
181 template< typename T > \ | |
182 struct BOOST_PP_CAT(trait,_impl_)< \ | |
183 T \ | |
184 , typename BOOST_PP_CAT(trait, _msvc_sfinae_helper)< typename T::name >::type \ | |
185 > \ | |
186 { \ | |
187 BOOST_STATIC_CONSTANT(bool, value = true); \ | |
188 typedef boost::mpl::bool_<value> type; \ | |
189 }; \ | |
190 \ | |
191 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \ | |
192 struct trait \ | |
193 : BOOST_PP_CAT(trait,_impl_)<T> \ | |
194 { \ | |
195 }; \ | |
196 /**/ | |
197 | |
198 # elif BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) ) | |
199 | |
200 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF(trait, trait_tester, name, default_) \ | |
201 template< typename T, bool IS_CLASS > \ | |
202 struct trait_tester \ | |
203 { \ | |
204 BOOST_STATIC_CONSTANT( bool, value = false ); \ | |
205 }; \ | |
206 template< typename T > \ | |
207 struct trait_tester< T, true > \ | |
208 { \ | |
209 struct trait_tester_impl \ | |
210 { \ | |
211 template < class U > \ | |
212 static int resolve( boost::mpl::aux::type_wrapper<U> const volatile * \ | |
213 , boost::mpl::aux::type_wrapper<typename U::name >* = 0 ); \ | |
214 static char resolve( ... ); \ | |
215 }; \ | |
216 typedef boost::mpl::aux::type_wrapper<T> t_; \ | |
217 BOOST_STATIC_CONSTANT( bool, value = ( sizeof( trait_tester_impl::resolve( static_cast< t_ * >(0) ) ) == sizeof(int) ) ); \ | |
218 }; \ | |
219 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \ | |
220 struct trait \ | |
221 { \ | |
222 BOOST_STATIC_CONSTANT( bool, value = (trait_tester< T, boost::is_class< T >::value >::value) ); \ | |
223 typedef boost::mpl::bool_< trait< T, fallback_ >::value > type; \ | |
224 }; | |
225 | |
226 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \ | |
227 BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF( trait \ | |
228 , BOOST_PP_CAT(trait,_tester) \ | |
229 , name \ | |
230 , default_ ) \ | |
231 /**/ | |
232 | |
233 # else // other SFINAE-capable compilers | |
234 | |
235 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \ | |
236 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \ | |
237 struct trait \ | |
238 { \ | |
239 struct gcc_3_2_wknd \ | |
240 { \ | |
241 template< typename U > \ | |
242 static boost::mpl::aux::yes_tag test( \ | |
243 boost::mpl::aux::type_wrapper<U> const volatile* \ | |
244 , boost::mpl::aux::type_wrapper<BOOST_MSVC_TYPENAME U::name>* = 0 \ | |
245 ); \ | |
246 \ | |
247 static boost::mpl::aux::no_tag test(...); \ | |
248 }; \ | |
249 \ | |
250 typedef boost::mpl::aux::type_wrapper<T> t_; \ | |
251 BOOST_STATIC_CONSTANT(bool, value = \ | |
252 sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) \ | |
253 == sizeof(boost::mpl::aux::yes_tag) \ | |
254 ); \ | |
255 typedef boost::mpl::bool_<value> type; \ | |
256 }; \ | |
257 /**/ | |
258 | |
259 # endif // BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | |
260 | |
261 | |
262 #else // BOOST_MPL_CFG_NO_HAS_XXX | |
263 | |
264 // placeholder implementation | |
265 | |
266 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \ | |
267 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \ | |
268 struct trait \ | |
269 { \ | |
270 BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \ | |
271 typedef fallback_ type; \ | |
272 }; \ | |
273 /**/ | |
274 | |
275 #endif | |
276 | |
277 #define BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \ | |
278 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \ | |
279 /**/ | |
280 | |
281 | |
282 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) | |
283 | |
284 // Create a boolean Metafunction to detect a nested template | |
285 // member. This implementation is based on a USENET newsgroup's | |
286 // posting by Aleksey Gurtovoy (comp.lang.c++.moderated, 2002-03-19), | |
287 // Rani Sharoni's USENET posting cited above, the non-template has_xxx | |
288 // implementations above, and discussion on the Boost mailing list. | |
289 | |
290 # if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES) | |
291 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) | |
292 # define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 1 | |
293 # endif | |
294 # endif | |
295 | |
296 # if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION) | |
297 # if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)) | |
298 # define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1 | |
299 # endif | |
300 # endif | |
301 | |
302 # if !defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE) | |
303 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) | |
304 # define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1 | |
305 # endif | |
306 # endif | |
307 | |
308 // NOTE: Many internal implementation macros take a Boost.Preprocessor | |
309 // array argument called args which is of the following form. | |
310 // ( 4, ( trait, name, max_arity, default_ ) ) | |
311 | |
312 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ | |
313 BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _introspect) \ | |
314 /**/ | |
315 | |
316 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ | |
317 BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute), n) \ | |
318 /**/ | |
319 | |
320 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \ | |
321 BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _test) \ | |
322 /**/ | |
323 | |
324 // Thanks to Guillaume Melquiond for pointing out the need for the | |
325 // "substitute" template as an argument to the overloaded test | |
326 // functions to get SFINAE to work for member templates with the | |
327 // correct name but different number of arguments. | |
328 # define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE(z, n, args) \ | |
329 template< \ | |
330 template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename V) > class V \ | |
331 > \ | |
332 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) { \ | |
333 }; \ | |
334 /**/ | |
335 | |
336 # define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ | |
337 BOOST_PP_REPEAT( \ | |
338 BOOST_PP_ARRAY_ELEM(2, args) \ | |
339 , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE \ | |
340 , args \ | |
341 ) \ | |
342 /**/ | |
343 | |
344 # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION | |
345 # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ | |
346 template< typename V > \ | |
347 static boost::mpl::aux::no_tag \ | |
348 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \ | |
349 /**/ | |
350 # else | |
351 # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ | |
352 static boost::mpl::aux::no_tag \ | |
353 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \ | |
354 /**/ | |
355 # endif | |
356 | |
357 # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES | |
358 # define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT(z, n, args) \ | |
359 template< typename V > \ | |
360 static boost::mpl::aux::yes_tag \ | |
361 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ | |
362 boost::mpl::aux::type_wrapper< V > const volatile* \ | |
363 , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) < \ | |
364 V::template BOOST_PP_ARRAY_ELEM(1, args) \ | |
365 >* = 0 \ | |
366 ); \ | |
367 /**/ | |
368 # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ | |
369 BOOST_PP_REPEAT( \ | |
370 BOOST_PP_ARRAY_ELEM(2, args) \ | |
371 , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT \ | |
372 , args \ | |
373 ) \ | |
374 /**/ | |
375 # else | |
376 # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ | |
377 template< typename V > \ | |
378 static boost::mpl::aux::yes_tag \ | |
379 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ | |
380 V const volatile* \ | |
381 , member_macro(args, V, T)* = 0 \ | |
382 ); \ | |
383 /**/ | |
384 # endif | |
385 | |
386 # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION | |
387 # define BOOST_MPL_HAS_MEMBER_TEST(args) \ | |
388 sizeof(BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \ | |
389 == sizeof(boost::mpl::aux::yes_tag) \ | |
390 /**/ | |
391 # else | |
392 # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES | |
393 # define BOOST_MPL_HAS_MEMBER_TEST(args) \ | |
394 sizeof( \ | |
395 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ | |
396 static_cast< boost::mpl::aux::type_wrapper< U >* >(0) \ | |
397 ) \ | |
398 ) == sizeof(boost::mpl::aux::yes_tag) \ | |
399 /**/ | |
400 # else | |
401 # define BOOST_MPL_HAS_MEMBER_TEST(args) \ | |
402 sizeof( \ | |
403 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ | |
404 static_cast< U* >(0) \ | |
405 ) \ | |
406 ) == sizeof(boost::mpl::aux::yes_tag) \ | |
407 /**/ | |
408 # endif | |
409 # endif | |
410 | |
411 # define BOOST_MPL_HAS_MEMBER_INTROSPECT( \ | |
412 args, substitute_macro, member_macro \ | |
413 ) \ | |
414 template< typename U > \ | |
415 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) { \ | |
416 BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ | |
417 BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ | |
418 BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ | |
419 BOOST_STATIC_CONSTANT( \ | |
420 bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \ | |
421 ); \ | |
422 typedef boost::mpl::bool_< value > type; \ | |
423 }; \ | |
424 /**/ | |
425 | |
426 # define BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ | |
427 args, introspect_macro, substitute_macro, member_macro \ | |
428 ) \ | |
429 template< \ | |
430 typename T \ | |
431 , typename fallback_ \ | |
432 = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \ | |
433 > \ | |
434 class BOOST_PP_ARRAY_ELEM(0, args) { \ | |
435 introspect_macro(args, substitute_macro, member_macro) \ | |
436 public: \ | |
437 static const bool value \ | |
438 = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< T >::value; \ | |
439 typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< \ | |
440 T \ | |
441 >::type type; \ | |
442 }; \ | |
443 /**/ | |
444 | |
445 // BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE expands to the full | |
446 // implementation of the function-based metafunction. Compile with -E | |
447 // to see the preprocessor output for this macro. | |
448 # define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ | |
449 args, substitute_macro, member_macro \ | |
450 ) \ | |
451 BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ | |
452 args \ | |
453 , BOOST_MPL_HAS_MEMBER_INTROSPECT \ | |
454 , substitute_macro \ | |
455 , member_macro \ | |
456 ) \ | |
457 /**/ | |
458 | |
459 # if BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE | |
460 | |
461 # if !defined(BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE) | |
462 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) | |
463 # define BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 1 | |
464 # endif | |
465 # endif | |
466 | |
467 # if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE | |
468 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ | |
469 args, n \ | |
470 ) \ | |
471 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ | |
472 /**/ | |
473 # else | |
474 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ | |
475 args, n \ | |
476 ) \ | |
477 BOOST_PP_CAT( \ | |
478 boost_mpl_has_xxx_ \ | |
479 , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ | |
480 ) \ | |
481 /**/ | |
482 # endif | |
483 | |
484 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME( \ | |
485 args \ | |
486 ) \ | |
487 BOOST_PP_CAT( \ | |
488 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ | |
489 args, 0 \ | |
490 ) \ | |
491 , _tag \ | |
492 ) \ | |
493 /**/ | |
494 | |
495 # define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ | |
496 z, n, args \ | |
497 ) \ | |
498 template< \ | |
499 template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename U) > class U \ | |
500 > \ | |
501 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ | |
502 args, n \ | |
503 ) { \ | |
504 typedef \ | |
505 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ | |
506 type; \ | |
507 }; \ | |
508 /**/ | |
509 | |
510 # define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ | |
511 args, substitute_macro \ | |
512 ) \ | |
513 typedef void \ | |
514 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \ | |
515 BOOST_PP_REPEAT( \ | |
516 BOOST_PP_ARRAY_ELEM(2, args) \ | |
517 , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE \ | |
518 , args \ | |
519 ) \ | |
520 /**/ | |
521 | |
522 # define BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \ | |
523 args, member_macro \ | |
524 ) \ | |
525 template< \ | |
526 typename U \ | |
527 , typename V \ | |
528 = BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ | |
529 > \ | |
530 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) { \ | |
531 BOOST_STATIC_CONSTANT(bool, value = false); \ | |
532 typedef boost::mpl::bool_< value > type; \ | |
533 }; \ | |
534 /**/ | |
535 | |
536 # define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE( \ | |
537 z, n, args \ | |
538 ) \ | |
539 template< typename U > \ | |
540 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \ | |
541 U \ | |
542 , typename \ | |
543 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ | |
544 args, n \ | |
545 )< \ | |
546 BOOST_MSVC_TYPENAME U::BOOST_PP_ARRAY_ELEM(1, args)< > \ | |
547 >::type \ | |
548 > { \ | |
549 BOOST_STATIC_CONSTANT(bool, value = true); \ | |
550 typedef boost::mpl::bool_< value > type; \ | |
551 }; \ | |
552 /**/ | |
553 | |
554 # define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \ | |
555 args, member_macro \ | |
556 ) \ | |
557 BOOST_PP_REPEAT( \ | |
558 BOOST_PP_ARRAY_ELEM(2, args) \ | |
559 , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE \ | |
560 , args \ | |
561 ) \ | |
562 /**/ | |
563 | |
564 # define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ | |
565 args, substitute_macro, member_macro \ | |
566 ) \ | |
567 BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \ | |
568 BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \ | |
569 template< typename U > \ | |
570 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ | |
571 : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U > { \ | |
572 }; \ | |
573 /**/ | |
574 | |
575 // BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE expands to the full | |
576 // implementation of the template-based metafunction. Compile with -E | |
577 // to see the preprocessor output for this macro. | |
578 // | |
579 // Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is | |
580 // defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs | |
581 // to be expanded at namespace level before | |
582 // BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE can be used. | |
583 # define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ | |
584 args, substitute_macro, member_macro \ | |
585 ) \ | |
586 BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ | |
587 args, substitute_macro \ | |
588 ) \ | |
589 BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ | |
590 args \ | |
591 , BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \ | |
592 , substitute_macro \ | |
593 , member_macro \ | |
594 ) \ | |
595 /**/ | |
596 | |
597 # endif // BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE | |
598 | |
599 // Note: In the current implementation the parameter and access macros | |
600 // are no longer expanded. | |
601 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) | |
602 # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ | |
603 BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ | |
604 ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ | |
605 , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ | |
606 , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ | |
607 ) \ | |
608 /**/ | |
609 # else | |
610 # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ | |
611 BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ | |
612 ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ | |
613 , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ | |
614 , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ | |
615 ) \ | |
616 /**/ | |
617 # endif | |
618 | |
619 #else // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE | |
620 | |
621 // placeholder implementation | |
622 | |
623 # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ | |
624 template< typename T \ | |
625 , typename fallback_ = boost::mpl::bool_< default_ > > \ | |
626 struct trait { \ | |
627 BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \ | |
628 typedef fallback_ type; \ | |
629 }; \ | |
630 /**/ | |
631 | |
632 #endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE | |
633 | |
634 # define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \ | |
635 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \ | |
636 BOOST_PP_CAT(has_, name), name, false \ | |
637 ) \ | |
638 /**/ | |
639 | |
640 #endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED |