annotate DEPENDENCIES/generic/include/boost/mpl/has_xxx.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
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@101 15 // $Id$
Chris@101 16 // $Date$
Chris@101 17 // $Revision$
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@101 158 # elif BOOST_WORKAROUND(BOOST_MSVC, <= 1400) \
Chris@101 159 || (BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) && defined(__CUDACC__)) \
Chris@16 160 || BOOST_WORKAROUND(__IBMCPP__, <= 700)
Chris@16 161
Chris@101 162 // MSVC 7.1 & MSVC 8.0 & VACPP
Chris@16 163
Chris@16 164 // agurt, 15/jun/05: replace overload-based SFINAE implementation with SFINAE
Chris@16 165 // applied to partial specialization to fix some apparently random failures
Chris@16 166 // (thanks to Daniel Wallin for researching this!)
Chris@16 167
Chris@16 168 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
Chris@16 169 template< typename T > \
Chris@16 170 struct BOOST_PP_CAT(trait, _msvc_sfinae_helper) \
Chris@16 171 { \
Chris@16 172 typedef void type; \
Chris@16 173 };\
Chris@16 174 \
Chris@16 175 template< typename T, typename U = void > \
Chris@16 176 struct BOOST_PP_CAT(trait,_impl_) \
Chris@16 177 { \
Chris@16 178 BOOST_STATIC_CONSTANT(bool, value = false); \
Chris@16 179 typedef boost::mpl::bool_<value> type; \
Chris@16 180 }; \
Chris@16 181 \
Chris@16 182 template< typename T > \
Chris@16 183 struct BOOST_PP_CAT(trait,_impl_)< \
Chris@16 184 T \
Chris@16 185 , typename BOOST_PP_CAT(trait, _msvc_sfinae_helper)< typename T::name >::type \
Chris@16 186 > \
Chris@16 187 { \
Chris@16 188 BOOST_STATIC_CONSTANT(bool, value = true); \
Chris@16 189 typedef boost::mpl::bool_<value> type; \
Chris@16 190 }; \
Chris@16 191 \
Chris@16 192 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
Chris@16 193 struct trait \
Chris@16 194 : BOOST_PP_CAT(trait,_impl_)<T> \
Chris@16 195 { \
Chris@16 196 }; \
Chris@16 197 /**/
Chris@16 198
Chris@16 199 # elif BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) )
Chris@16 200
Chris@16 201 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF(trait, trait_tester, name, default_) \
Chris@16 202 template< typename T, bool IS_CLASS > \
Chris@16 203 struct trait_tester \
Chris@16 204 { \
Chris@16 205 BOOST_STATIC_CONSTANT( bool, value = false ); \
Chris@16 206 }; \
Chris@16 207 template< typename T > \
Chris@16 208 struct trait_tester< T, true > \
Chris@16 209 { \
Chris@16 210 struct trait_tester_impl \
Chris@16 211 { \
Chris@16 212 template < class U > \
Chris@16 213 static int resolve( boost::mpl::aux::type_wrapper<U> const volatile * \
Chris@16 214 , boost::mpl::aux::type_wrapper<typename U::name >* = 0 ); \
Chris@16 215 static char resolve( ... ); \
Chris@16 216 }; \
Chris@16 217 typedef boost::mpl::aux::type_wrapper<T> t_; \
Chris@16 218 BOOST_STATIC_CONSTANT( bool, value = ( sizeof( trait_tester_impl::resolve( static_cast< t_ * >(0) ) ) == sizeof(int) ) ); \
Chris@16 219 }; \
Chris@16 220 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
Chris@16 221 struct trait \
Chris@16 222 { \
Chris@16 223 BOOST_STATIC_CONSTANT( bool, value = (trait_tester< T, boost::is_class< T >::value >::value) ); \
Chris@16 224 typedef boost::mpl::bool_< trait< T, fallback_ >::value > type; \
Chris@16 225 };
Chris@16 226
Chris@16 227 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
Chris@16 228 BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF( trait \
Chris@16 229 , BOOST_PP_CAT(trait,_tester) \
Chris@16 230 , name \
Chris@16 231 , default_ ) \
Chris@16 232 /**/
Chris@16 233
Chris@16 234 # else // other SFINAE-capable compilers
Chris@16 235
Chris@16 236 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
Chris@16 237 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
Chris@16 238 struct trait \
Chris@16 239 { \
Chris@16 240 struct gcc_3_2_wknd \
Chris@16 241 { \
Chris@16 242 template< typename U > \
Chris@16 243 static boost::mpl::aux::yes_tag test( \
Chris@16 244 boost::mpl::aux::type_wrapper<U> const volatile* \
Chris@16 245 , boost::mpl::aux::type_wrapper<BOOST_MSVC_TYPENAME U::name>* = 0 \
Chris@16 246 ); \
Chris@16 247 \
Chris@16 248 static boost::mpl::aux::no_tag test(...); \
Chris@16 249 }; \
Chris@16 250 \
Chris@16 251 typedef boost::mpl::aux::type_wrapper<T> t_; \
Chris@16 252 BOOST_STATIC_CONSTANT(bool, value = \
Chris@16 253 sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) \
Chris@16 254 == sizeof(boost::mpl::aux::yes_tag) \
Chris@16 255 ); \
Chris@16 256 typedef boost::mpl::bool_<value> type; \
Chris@16 257 }; \
Chris@16 258 /**/
Chris@16 259
Chris@16 260 # endif // BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
Chris@16 261
Chris@16 262
Chris@16 263 #else // BOOST_MPL_CFG_NO_HAS_XXX
Chris@16 264
Chris@16 265 // placeholder implementation
Chris@16 266
Chris@16 267 # define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
Chris@16 268 template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
Chris@16 269 struct trait \
Chris@16 270 { \
Chris@16 271 BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
Chris@16 272 typedef fallback_ type; \
Chris@16 273 }; \
Chris@16 274 /**/
Chris@16 275
Chris@16 276 #endif
Chris@16 277
Chris@16 278 #define BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \
Chris@16 279 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \
Chris@16 280 /**/
Chris@16 281
Chris@16 282
Chris@16 283 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
Chris@16 284
Chris@16 285 // Create a boolean Metafunction to detect a nested template
Chris@16 286 // member. This implementation is based on a USENET newsgroup's
Chris@16 287 // posting by Aleksey Gurtovoy (comp.lang.c++.moderated, 2002-03-19),
Chris@16 288 // Rani Sharoni's USENET posting cited above, the non-template has_xxx
Chris@16 289 // implementations above, and discussion on the Boost mailing list.
Chris@16 290
Chris@16 291 # if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES)
Chris@16 292 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
Chris@16 293 # define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 1
Chris@101 294 # else
Chris@101 295 # define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 0
Chris@16 296 # endif
Chris@16 297 # endif
Chris@16 298
Chris@16 299 # if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION)
Chris@16 300 # if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS))
Chris@16 301 # define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1
Chris@101 302 # else
Chris@101 303 # define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 0
Chris@16 304 # endif
Chris@16 305 # endif
Chris@16 306
Chris@16 307 # if !defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE)
Chris@16 308 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
Chris@16 309 # define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1
Chris@101 310 # else
Chris@101 311 # define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 0
Chris@16 312 # endif
Chris@16 313 # endif
Chris@16 314
Chris@16 315 // NOTE: Many internal implementation macros take a Boost.Preprocessor
Chris@16 316 // array argument called args which is of the following form.
Chris@16 317 // ( 4, ( trait, name, max_arity, default_ ) )
Chris@16 318
Chris@16 319 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
Chris@16 320 BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _introspect) \
Chris@16 321 /**/
Chris@16 322
Chris@16 323 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
Chris@16 324 BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute), n) \
Chris@16 325 /**/
Chris@16 326
Chris@16 327 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \
Chris@16 328 BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _test) \
Chris@16 329 /**/
Chris@16 330
Chris@16 331 // Thanks to Guillaume Melquiond for pointing out the need for the
Chris@16 332 // "substitute" template as an argument to the overloaded test
Chris@16 333 // functions to get SFINAE to work for member templates with the
Chris@16 334 // correct name but different number of arguments.
Chris@16 335 # define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE(z, n, args) \
Chris@16 336 template< \
Chris@16 337 template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename V) > class V \
Chris@16 338 > \
Chris@16 339 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) { \
Chris@16 340 }; \
Chris@16 341 /**/
Chris@16 342
Chris@16 343 # define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \
Chris@16 344 BOOST_PP_REPEAT( \
Chris@16 345 BOOST_PP_ARRAY_ELEM(2, args) \
Chris@16 346 , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE \
Chris@16 347 , args \
Chris@16 348 ) \
Chris@16 349 /**/
Chris@16 350
Chris@16 351 # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
Chris@16 352 # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
Chris@16 353 template< typename V > \
Chris@16 354 static boost::mpl::aux::no_tag \
Chris@16 355 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
Chris@16 356 /**/
Chris@16 357 # else
Chris@16 358 # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
Chris@16 359 static boost::mpl::aux::no_tag \
Chris@16 360 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
Chris@16 361 /**/
Chris@16 362 # endif
Chris@16 363
Chris@16 364 # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
Chris@16 365 # define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT(z, n, args) \
Chris@16 366 template< typename V > \
Chris@16 367 static boost::mpl::aux::yes_tag \
Chris@16 368 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
Chris@16 369 boost::mpl::aux::type_wrapper< V > const volatile* \
Chris@16 370 , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) < \
Chris@16 371 V::template BOOST_PP_ARRAY_ELEM(1, args) \
Chris@16 372 >* = 0 \
Chris@16 373 ); \
Chris@16 374 /**/
Chris@16 375 # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
Chris@16 376 BOOST_PP_REPEAT( \
Chris@16 377 BOOST_PP_ARRAY_ELEM(2, args) \
Chris@16 378 , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT \
Chris@16 379 , args \
Chris@16 380 ) \
Chris@16 381 /**/
Chris@16 382 # else
Chris@16 383 # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
Chris@16 384 template< typename V > \
Chris@16 385 static boost::mpl::aux::yes_tag \
Chris@16 386 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
Chris@16 387 V const volatile* \
Chris@16 388 , member_macro(args, V, T)* = 0 \
Chris@16 389 ); \
Chris@16 390 /**/
Chris@16 391 # endif
Chris@16 392
Chris@16 393 # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
Chris@16 394 # define BOOST_MPL_HAS_MEMBER_TEST(args) \
Chris@16 395 sizeof(BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \
Chris@16 396 == sizeof(boost::mpl::aux::yes_tag) \
Chris@16 397 /**/
Chris@16 398 # else
Chris@16 399 # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
Chris@16 400 # define BOOST_MPL_HAS_MEMBER_TEST(args) \
Chris@16 401 sizeof( \
Chris@16 402 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
Chris@16 403 static_cast< boost::mpl::aux::type_wrapper< U >* >(0) \
Chris@16 404 ) \
Chris@16 405 ) == sizeof(boost::mpl::aux::yes_tag) \
Chris@16 406 /**/
Chris@16 407 # else
Chris@16 408 # define BOOST_MPL_HAS_MEMBER_TEST(args) \
Chris@16 409 sizeof( \
Chris@16 410 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
Chris@16 411 static_cast< U* >(0) \
Chris@16 412 ) \
Chris@16 413 ) == sizeof(boost::mpl::aux::yes_tag) \
Chris@16 414 /**/
Chris@16 415 # endif
Chris@16 416 # endif
Chris@16 417
Chris@16 418 # define BOOST_MPL_HAS_MEMBER_INTROSPECT( \
Chris@16 419 args, substitute_macro, member_macro \
Chris@16 420 ) \
Chris@16 421 template< typename U > \
Chris@16 422 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) { \
Chris@16 423 BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \
Chris@16 424 BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
Chris@16 425 BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
Chris@16 426 BOOST_STATIC_CONSTANT( \
Chris@16 427 bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \
Chris@16 428 ); \
Chris@16 429 typedef boost::mpl::bool_< value > type; \
Chris@16 430 }; \
Chris@16 431 /**/
Chris@16 432
Chris@16 433 # define BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
Chris@16 434 args, introspect_macro, substitute_macro, member_macro \
Chris@16 435 ) \
Chris@16 436 template< \
Chris@16 437 typename T \
Chris@16 438 , typename fallback_ \
Chris@16 439 = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \
Chris@16 440 > \
Chris@16 441 class BOOST_PP_ARRAY_ELEM(0, args) { \
Chris@16 442 introspect_macro(args, substitute_macro, member_macro) \
Chris@16 443 public: \
Chris@16 444 static const bool value \
Chris@16 445 = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< T >::value; \
Chris@16 446 typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< \
Chris@16 447 T \
Chris@16 448 >::type type; \
Chris@16 449 }; \
Chris@16 450 /**/
Chris@16 451
Chris@16 452 // BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE expands to the full
Chris@16 453 // implementation of the function-based metafunction. Compile with -E
Chris@16 454 // to see the preprocessor output for this macro.
Chris@16 455 # define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
Chris@16 456 args, substitute_macro, member_macro \
Chris@16 457 ) \
Chris@16 458 BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
Chris@16 459 args \
Chris@16 460 , BOOST_MPL_HAS_MEMBER_INTROSPECT \
Chris@16 461 , substitute_macro \
Chris@16 462 , member_macro \
Chris@16 463 ) \
Chris@16 464 /**/
Chris@16 465
Chris@16 466 # if BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
Chris@16 467
Chris@16 468 # if !defined(BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE)
Chris@16 469 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
Chris@16 470 # define BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 1
Chris@16 471 # endif
Chris@16 472 # endif
Chris@16 473
Chris@16 474 # if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE
Chris@16 475 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Chris@16 476 args, n \
Chris@16 477 ) \
Chris@16 478 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
Chris@16 479 /**/
Chris@16 480 # else
Chris@16 481 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Chris@16 482 args, n \
Chris@16 483 ) \
Chris@16 484 BOOST_PP_CAT( \
Chris@16 485 boost_mpl_has_xxx_ \
Chris@16 486 , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
Chris@16 487 ) \
Chris@16 488 /**/
Chris@16 489 # endif
Chris@16 490
Chris@16 491 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME( \
Chris@16 492 args \
Chris@16 493 ) \
Chris@16 494 BOOST_PP_CAT( \
Chris@16 495 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Chris@16 496 args, 0 \
Chris@16 497 ) \
Chris@16 498 , _tag \
Chris@16 499 ) \
Chris@16 500 /**/
Chris@16 501
Chris@16 502 # define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
Chris@16 503 z, n, args \
Chris@16 504 ) \
Chris@16 505 template< \
Chris@16 506 template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename U) > class U \
Chris@16 507 > \
Chris@16 508 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Chris@16 509 args, n \
Chris@16 510 ) { \
Chris@16 511 typedef \
Chris@16 512 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
Chris@16 513 type; \
Chris@16 514 }; \
Chris@16 515 /**/
Chris@16 516
Chris@16 517 # define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
Chris@16 518 args, substitute_macro \
Chris@16 519 ) \
Chris@16 520 typedef void \
Chris@16 521 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \
Chris@16 522 BOOST_PP_REPEAT( \
Chris@16 523 BOOST_PP_ARRAY_ELEM(2, args) \
Chris@16 524 , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE \
Chris@16 525 , args \
Chris@16 526 ) \
Chris@16 527 /**/
Chris@16 528
Chris@16 529 # define BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \
Chris@16 530 args, member_macro \
Chris@16 531 ) \
Chris@16 532 template< \
Chris@16 533 typename U \
Chris@16 534 , typename V \
Chris@16 535 = BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
Chris@16 536 > \
Chris@16 537 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) { \
Chris@16 538 BOOST_STATIC_CONSTANT(bool, value = false); \
Chris@16 539 typedef boost::mpl::bool_< value > type; \
Chris@16 540 }; \
Chris@16 541 /**/
Chris@16 542
Chris@16 543 # define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE( \
Chris@16 544 z, n, args \
Chris@16 545 ) \
Chris@16 546 template< typename U > \
Chris@16 547 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \
Chris@16 548 U \
Chris@16 549 , typename \
Chris@16 550 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
Chris@16 551 args, n \
Chris@16 552 )< \
Chris@16 553 BOOST_MSVC_TYPENAME U::BOOST_PP_ARRAY_ELEM(1, args)< > \
Chris@16 554 >::type \
Chris@16 555 > { \
Chris@16 556 BOOST_STATIC_CONSTANT(bool, value = true); \
Chris@16 557 typedef boost::mpl::bool_< value > type; \
Chris@16 558 }; \
Chris@16 559 /**/
Chris@16 560
Chris@16 561 # define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \
Chris@16 562 args, member_macro \
Chris@16 563 ) \
Chris@16 564 BOOST_PP_REPEAT( \
Chris@16 565 BOOST_PP_ARRAY_ELEM(2, args) \
Chris@16 566 , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE \
Chris@16 567 , args \
Chris@16 568 ) \
Chris@16 569 /**/
Chris@16 570
Chris@16 571 # define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \
Chris@16 572 args, substitute_macro, member_macro \
Chris@16 573 ) \
Chris@16 574 BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \
Chris@16 575 BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \
Chris@16 576 template< typename U > \
Chris@16 577 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
Chris@16 578 : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U > { \
Chris@16 579 }; \
Chris@16 580 /**/
Chris@16 581
Chris@16 582 // BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE expands to the full
Chris@16 583 // implementation of the template-based metafunction. Compile with -E
Chris@16 584 // to see the preprocessor output for this macro.
Chris@16 585 //
Chris@16 586 // Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is
Chris@16 587 // defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs
Chris@16 588 // to be expanded at namespace level before
Chris@16 589 // BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE can be used.
Chris@16 590 # define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \
Chris@16 591 args, substitute_macro, member_macro \
Chris@16 592 ) \
Chris@16 593 BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
Chris@16 594 args, substitute_macro \
Chris@16 595 ) \
Chris@16 596 BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
Chris@16 597 args \
Chris@16 598 , BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \
Chris@16 599 , substitute_macro \
Chris@16 600 , member_macro \
Chris@16 601 ) \
Chris@16 602 /**/
Chris@16 603
Chris@16 604 # endif // BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
Chris@16 605
Chris@16 606 // Note: In the current implementation the parameter and access macros
Chris@16 607 // are no longer expanded.
Chris@16 608 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
Chris@16 609 # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \
Chris@16 610 BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
Chris@16 611 ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \
Chris@16 612 , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \
Chris@16 613 , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \
Chris@16 614 ) \
Chris@16 615 /**/
Chris@16 616 # else
Chris@16 617 # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \
Chris@16 618 BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \
Chris@16 619 ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \
Chris@16 620 , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \
Chris@16 621 , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \
Chris@16 622 ) \
Chris@16 623 /**/
Chris@16 624 # endif
Chris@16 625
Chris@16 626 #else // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
Chris@16 627
Chris@16 628 // placeholder implementation
Chris@16 629
Chris@16 630 # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \
Chris@16 631 template< typename T \
Chris@16 632 , typename fallback_ = boost::mpl::bool_< default_ > > \
Chris@16 633 struct trait { \
Chris@16 634 BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
Chris@16 635 typedef fallback_ type; \
Chris@16 636 }; \
Chris@16 637 /**/
Chris@16 638
Chris@16 639 #endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
Chris@16 640
Chris@16 641 # define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \
Chris@16 642 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \
Chris@16 643 BOOST_PP_CAT(has_, name), name, false \
Chris@16 644 ) \
Chris@16 645 /**/
Chris@16 646
Chris@16 647 #endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED