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