has_xxx.hpp 22 KB

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