dtemplate_params.hpp 6.9 KB

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