dtemplate_params.hpp 6.8 KB

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