New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
has_xxx.hpp in vendors/XIOS/current/extern/boost/include/boost/mpl – NEMO

source: vendors/XIOS/current/extern/boost/include/boost/mpl/has_xxx.hpp @ 3408

Last change on this file since 3408 was 3408, checked in by rblod, 12 years ago

importing initial XIOS vendor drop

  • Property svn:keywords set to Id
File size: 21.3 KB
Line 
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$
16// $Date: 2010-07-18 20:46:31 -0400 (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
54namespace boost { namespace mpl { namespace aux {
55
56struct has_xxx_tag;
57
58#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
59template< typename U > struct msvc_incomplete_array
60{
61    typedef char (&type)[sizeof(U) + 1];
62};
63#endif
64
65template< typename T >
66struct 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
85template<>
86struct 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_) \
94template< typename T, typename name = ::boost::mpl::aux::has_xxx_tag > \
95struct 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\
109template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
110struct 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\
119BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, void) \
120BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, bool) \
121BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, char) \
122BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed char) \
123BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned char) \
124BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed short) \
125BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned short) \
126BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed int) \
127BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned int) \
128BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed long) \
129BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned long) \
130BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, float) \
131BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, double) \
132BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, long double) \
133/**/
134
135#   define BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, T) \
136template<> 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_) \
168template< typename T > \
169struct BOOST_PP_CAT(trait, _msvc_sfinae_helper) \
170{ \
171    typedef void type; \
172};\
173\
174template< typename T, typename U = void > \
175struct BOOST_PP_CAT(trait,_impl_) \
176{ \
177    BOOST_STATIC_CONSTANT(bool, value = false); \
178    typedef boost::mpl::bool_<value> type; \
179}; \
180\
181template< typename T > \
182struct 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\
191template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
192struct 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_) \
201template< typename T, bool IS_CLASS > \
202struct trait_tester \
203{ \
204    BOOST_STATIC_CONSTANT( bool,  value = false ); \
205}; \
206template< typename T > \
207struct 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}; \
219template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
220struct 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_) \
236template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
237struct 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_) \
267template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
268struct 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
Note: See TracBrowser for help on using the repository browser.