has_xxx.hpp 21 KB

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