dtemplate_params.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // (C) Copyright Edward Diener 2011,2012,2013
  2. // Use, modification and distribution are subject to the Boost Software License,
  3. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt).
  5. #if !defined(BOOST_TTI_DETAIL_TEMPLATE_PARAMS_HPP)
  6. #define BOOST_TTI_DETAIL_TEMPLATE_PARAMS_HPP
  7. #include <boost/config.hpp>
  8. #include <boost/mpl/bool.hpp>
  9. #include <boost/mpl/has_xxx.hpp>
  10. #include <boost/preprocessor/arithmetic/add.hpp>
  11. #include <boost/preprocessor/arithmetic/sub.hpp>
  12. #include <boost/preprocessor/array/elem.hpp>
  13. #include <boost/preprocessor/cat.hpp>
  14. #include <boost/preprocessor/punctuation/comma_if.hpp>
  15. #include <boost/preprocessor/repetition/repeat.hpp>
  16. #include <boost/preprocessor/repetition/enum.hpp>
  17. #include <boost/preprocessor/array/enum.hpp>
  18. #include <boost/preprocessor/array/size.hpp>
  19. #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
  20. #define BOOST_TTI_DETAIL_TEMPLATE_PARAMETERS(z,n,args) \
  21. BOOST_PP_ARRAY_ELEM(BOOST_PP_ADD(4,n),args) \
  22. /**/
  23. #define BOOST_TTI_DETAIL_HAS_MEMBER_IMPLEMENTATION(args,introspect_macro) \
  24. template \
  25. < \
  26. typename BOOST_TTI_DETAIL_TP_T, \
  27. typename BOOST_TTI_DETAIL_TP_FALLBACK_ \
  28. = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \
  29. > \
  30. class BOOST_PP_ARRAY_ELEM(0, args) \
  31. { \
  32. introspect_macro(args) \
  33. public: \
  34. static const bool value \
  35. = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< BOOST_TTI_DETAIL_TP_T >::value; \
  36. typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
  37. < \
  38. BOOST_TTI_DETAIL_TP_T \
  39. >::type type; \
  40. }; \
  41. /**/
  42. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
  43. #define BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE(z,n,args) \
  44. template \
  45. < \
  46. template \
  47. < \
  48. BOOST_PP_ENUM_ ## z \
  49. ( \
  50. BOOST_PP_SUB \
  51. ( \
  52. BOOST_PP_ARRAY_SIZE(args), \
  53. 4 \
  54. ), \
  55. BOOST_TTI_DETAIL_TEMPLATE_PARAMETERS, \
  56. args \
  57. ) \
  58. > \
  59. class BOOST_TTI_DETAIL_TM_V \
  60. > \
  61. struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
  62. { \
  63. }; \
  64. /**/
  65. #define BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE(args) \
  66. BOOST_PP_REPEAT \
  67. ( \
  68. BOOST_PP_ARRAY_ELEM(2, args), \
  69. BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE, \
  70. args \
  71. ) \
  72. /**/
  73. #define BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT(args) \
  74. template< typename U > \
  75. struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
  76. { \
  77. BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE(args) \
  78. BOOST_MPL_HAS_MEMBER_REJECT(args, BOOST_PP_NIL) \
  79. BOOST_MPL_HAS_MEMBER_ACCEPT(args, BOOST_PP_NIL) \
  80. BOOST_STATIC_CONSTANT \
  81. ( \
  82. bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \
  83. ); \
  84. typedef boost::mpl::bool_< value > type; \
  85. }; \
  86. /**/
  87. #define BOOST_TTI_DETAIL_HAS_MEMBER_WITH_FUNCTION_SFINAE(args) \
  88. BOOST_TTI_DETAIL_HAS_MEMBER_IMPLEMENTATION \
  89. ( \
  90. args, \
  91. BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT \
  92. ) \
  93. /**/
  94. #else // !!BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
  95. #define BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE(z,n,args) \
  96. template \
  97. < \
  98. template \
  99. < \
  100. BOOST_PP_ENUM_ ## z \
  101. ( \
  102. BOOST_PP_SUB \
  103. ( \
  104. BOOST_PP_ARRAY_SIZE(args), \
  105. 4 \
  106. ), \
  107. BOOST_TTI_DETAIL_TEMPLATE_PARAMETERS, \
  108. args \
  109. ) \
  110. > \
  111. class BOOST_TTI_DETAIL_TM_U \
  112. > \
  113. struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE \
  114. ( \
  115. args, \
  116. n \
  117. ) \
  118. { \
  119. typedef \
  120. BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
  121. type; \
  122. }; \
  123. /**/
  124. #define BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE(args) \
  125. typedef void \
  126. BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \
  127. BOOST_PP_REPEAT \
  128. ( \
  129. BOOST_PP_ARRAY_ELEM(2, args), \
  130. BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE, \
  131. args \
  132. ) \
  133. /**/
  134. #define BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE(args) \
  135. BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args,BOOST_PP_NIL) \
  136. BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args,BOOST_PP_NIL) \
  137. template< typename BOOST_TTI_DETAIL_TP_U > \
  138. struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
  139. : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< BOOST_TTI_DETAIL_TP_U > { \
  140. }; \
  141. /**/
  142. #define BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE(args) \
  143. BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE \
  144. ( \
  145. args \
  146. ) \
  147. BOOST_TTI_DETAIL_HAS_MEMBER_IMPLEMENTATION \
  148. ( \
  149. args, \
  150. BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \
  151. ) \
  152. /**/
  153. #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
  154. #else // defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
  155. #define BOOST_TTI_DETAIL_SAME(trait,name) \
  156. BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF \
  157. ( \
  158. trait, \
  159. name, \
  160. false \
  161. ) \
  162. /**/
  163. #define BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tp) \
  164. BOOST_TTI_DETAIL_SAME(trait,name) \
  165. /**/
  166. #endif // !BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
  167. #define BOOST_TTI_DETAIL_TRAIT_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tpArray) \
  168. BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(BOOST_PP_CAT(trait,_detail),name,tpArray) \
  169. template<class BOOST_TTI_DETAIL_TP_T> \
  170. struct trait : \
  171. BOOST_PP_CAT(trait,_detail)<BOOST_TTI_DETAIL_TP_T> \
  172. { \
  173. }; \
  174. /**/
  175. #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
  176. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
  177. #define BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tpArray) \
  178. BOOST_TTI_DETAIL_HAS_MEMBER_WITH_FUNCTION_SFINAE \
  179. ( \
  180. ( BOOST_PP_ADD(BOOST_PP_ARRAY_SIZE(tpArray),4), ( trait, name, 1, false, BOOST_PP_ARRAY_ENUM(tpArray) ) ) \
  181. ) \
  182. /**/
  183. #else // BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
  184. #define BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tpArray) \
  185. BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE \
  186. ( \
  187. ( BOOST_PP_ADD(BOOST_PP_ARRAY_SIZE(tpArray),4), ( trait, name, 1, false, BOOST_PP_ARRAY_ENUM(tpArray) ) ) \
  188. ) \
  189. /**/
  190. #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
  191. #endif // !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
  192. #endif // BOOST_TTI_DETAIL_TEMPLATE_PARAMS_HPP