has_template.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. // (C) Copyright Edward Diener 2011,2012
  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_HAS_TEMPLATE_HPP)
  6. #define BOOST_TTI_HAS_TEMPLATE_HPP
  7. /*
  8. The succeeding comments in this file are in doxygen format.
  9. */
  10. /** \file
  11. */
  12. #include <boost/tti/gen/has_template_gen.hpp>
  13. #include <boost/preprocessor/config/config.hpp>
  14. #include <boost/preprocessor/control/iif.hpp>
  15. #if BOOST_PP_VARIADICS
  16. #include <boost/preprocessor/comparison/equal.hpp>
  17. #include <boost/preprocessor/variadic/elem.hpp>
  18. #include <boost/preprocessor/variadic/size.hpp>
  19. #include <boost/tti/detail/dvm_template_params.hpp>
  20. /// A macro which expands to a metafunction which tests whether an inner class template with a particular name exists.
  21. /**
  22. BOOST_TTI_TRAIT_HAS_TEMPLATE is a macro which expands to a metafunction.
  23. The metafunction tests whether an inner class template with a particular name exists.
  24. The macro takes the form of BOOST_TTI_TRAIT_HAS_TEMPLATE(trait,...) where
  25. trait = the name of the metafunction <br/>
  26. ... = variadic parameters.
  27. The first variadic parameter is the inner class template name.
  28. Following variadic parameters are optional.
  29. If no following variadic parameters exist, then the inner class template
  30. being introspected must be all template type parameters ( template parameters
  31. starting with `class` or `typename` ) and any number of template type parameters
  32. can occur.
  33. If the second variadic parameter is BOOST_PP_NIL and no other variadic
  34. parameter is given, then just as in the previous case the inner class template
  35. being introspected must be all template type parameters ( template parameters
  36. starting with `class` or `typename` ) and any number of template type parameters
  37. can occur. This form is allowed in order to be consistent with using the
  38. non-variadic form of this macro.
  39. If the second variadic parameter is a Boost preprocessor library array and no other
  40. variadic parameter is given, then the inner class template must have its template
  41. parameters matching the sequence in the tuple portion of the Boost PP array. This
  42. form is allowed in order to be consistent with using the non-variadic form of this
  43. macro.
  44. Otherwise the inner class template must have its template parameters matching the
  45. sequence of the optional variadic parameters.
  46. BOOST_TTI_TRAIT_HAS_TEMPLATE generates a metafunction called "trait" where 'trait' is the first macro parameter.
  47. @code
  48. template<class BOOST_TTI_TP_T>
  49. struct trait
  50. {
  51. static const value = unspecified;
  52. typedef mpl::bool_<true-or-false> type;
  53. };
  54. The metafunction types and return:
  55. BOOST_TTI_TP_T = the enclosing type in which to look for our 'name'.
  56. The enclosing type can be a class, struct, or union.
  57. returns = 'value' is true if the 'name' template exists within the enclosing type,
  58. otherwise 'value' is false.
  59. @endcode
  60. Examples:
  61. @code
  62. 1) Search for an inner class template called 'MyTemplate', with all template type parameters,
  63. nested within the class 'MyClass' using a metafunction name of 'MyMeta'.
  64. BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate)
  65. or
  66. BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,BOOST_PP_NIL) // Non-variadic macro form
  67. MyMeta<MyClass>::value
  68. is a compile time boolean constant which is either 'true' or 'false'
  69. if the nested template exists.
  70. 2) Search for an inner class template called 'MyTemplate', with template parameters
  71. of 'class T,int x,template<class> class U', nested within the class 'MyClass'
  72. using a metafunction name of 'MyMeta'.
  73. BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,class,int,template<class> class)
  74. or
  75. BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,(3,(class,int,template<class> class))) // Non-variadic macro form
  76. MyMeta<MyClass>::value
  77. is a compile time boolean constant which is either 'true' or 'false'
  78. if the nested template exists.
  79. @endcode
  80. */
  81. #define BOOST_TTI_TRAIT_HAS_TEMPLATE(trait,...) \
  82. BOOST_PP_IIF \
  83. ( \
  84. BOOST_PP_EQUAL \
  85. ( \
  86. BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
  87. 1 \
  88. ), \
  89. BOOST_TTI_DETAIL_VM_TRAIT_HAS_TEMPLATE, \
  90. BOOST_TTI_DETAIL_VM_CHECK_MORE_THAN_TWO \
  91. ) \
  92. (trait,__VA_ARGS__) \
  93. /**/
  94. /// A macro which expands to a metafunction which tests whether an inner class template with a particular name exists.
  95. /**
  96. BOOST_TTI_HAS_TEMPLATE is a macro which expands to a metafunction.
  97. The metafunction tests whether an inner class template with a particular name exists.
  98. The macro takes the form of BOOST_TTI_HAS_TEMPLATE(...) where
  99. ... = variadic parameters.
  100. The first variadic parameter is the inner class template name.
  101. Following variadic parameters are optional.
  102. If no following variadic parameters exist, then the inner class template
  103. being introspected must be all template type parameters ( template parameters
  104. starting with `class` or `typename` ) and any number of template type parameters
  105. can occur.
  106. If the second variadic parameter is BOOST_PP_NIL and no other variadic
  107. parameter is given, then just as in the previous case the inner class template
  108. being introspected must be all template type parameters ( template parameters
  109. starting with `class` or `typename` ) and any number of template type parameters
  110. can occur. This form is allowed in order to be consistent with using the
  111. non-variadic form of this macro.
  112. If the second variadic parameter is a Boost preprocessor library array and no other
  113. variadic parameter is given, then the inner class template must have its template
  114. parameters matching the sequence in the tuple portion of the Boost PP array. This
  115. form is allowed in order to be consistent with using the non-variadic form of this
  116. macro.
  117. Otherwise the inner class template must have its template parameters matching the
  118. sequence of the optional variadic parameters.
  119. BOOST_TTI_HAS_TEMPLATE generates a metafunction called "has_template_'name'" where 'name' is the first variadic parameter.
  120. @code
  121. template<class BOOST_TTI_TP_T>
  122. struct has_template_'name'
  123. {
  124. static const value = unspecified;
  125. typedef mpl::bool_<true-or-false> type;
  126. };
  127. The metafunction types and return:
  128. BOOST_TTI_TP_T = the enclosing type in which to look for our 'name'.
  129. The enclosing type can be a class, struct, or union.
  130. returns = 'value' is true if the 'name' template exists within the enclosing type,
  131. otherwise 'value' is false.
  132. @endcode
  133. Examples:
  134. @code
  135. 1) Search for an inner class template called 'MyTemplate', with all template type parameters,
  136. nested within the class 'MyClass'.
  137. BOOST_TTI_HAS_TEMPLATE(MyTemplate)
  138. or
  139. BOOST_TTI_HAS_TEMPLATE(MyTemplate,BOOST_PP_NIL) // Non-variadic macro form
  140. has_template_MyTemplate<MyClass>::value
  141. is a compile time boolean constant which is either 'true' or 'false'
  142. if the nested template exists.
  143. 2) Search for an inner class template called 'MyTemplate' with template parameters
  144. of 'class T,int x,template<class> class U' nested within the class 'MyClass'.
  145. BOOST_TTI_HAS_TEMPLATE(MyTemplate,class,int,template<class> class)
  146. or
  147. BOOST_TTI_HAS_TEMPLATE(MyTemplate,(3,(class,int,template<class> class))) // Non-variadic macro form
  148. has_template_MyTemplate<MyClass>::value
  149. is a compile time boolean constant which is either 'true' or 'false'
  150. if the nested template exists.
  151. @endcode
  152. */
  153. #define BOOST_TTI_HAS_TEMPLATE(...) \
  154. BOOST_TTI_TRAIT_HAS_TEMPLATE \
  155. ( \
  156. BOOST_TTI_HAS_TEMPLATE_GEN \
  157. ( \
  158. BOOST_PP_VARIADIC_ELEM(0,__VA_ARGS__) \
  159. ), \
  160. __VA_ARGS__ \
  161. ) \
  162. /**/
  163. #else // !BOOST_PP_VARIADICS
  164. #include <boost/preprocessor/detail/is_binary.hpp>
  165. #include <boost/tti/detail/dtemplate.hpp>
  166. #include <boost/tti/detail/dtemplate_params.hpp>
  167. /// A macro which expands to a metafunction which tests whether an inner class template with a particular name exists.
  168. /**
  169. BOOST_TTI_TRAIT_HAS_TEMPLATE is a macro which expands to a metafunction.
  170. The metafunction tests whether an inner class template with a particular name exists.
  171. The macro takes the form of BOOST_TTI_TRAIT_HAS_TEMPLATE(trait,name,params) where
  172. trait = the name of the metafunction <br/>
  173. name = the inner class template name <br/>
  174. params = If the parameter is BOOST_PP_NIL the inner class template
  175. being introspected must be all template type parameters ( template parameters
  176. starting with `class` or `typename` ) and any number of template type parameters
  177. can occur.
  178. If the parameter is a Boost preprocessor library array, then the inner class
  179. template must have its template parameters matching the sequence in the tuple portion
  180. of the Boost PP array.
  181. If the parameter is anything else a compiler error occurs.
  182. BOOST_TTI_TRAIT_HAS_TEMPLATE generates a metafunction called "trait" where 'trait' is the first macro parameter.
  183. @code
  184. template<class BOOST_TTI_TP_T>
  185. struct trait
  186. {
  187. static const value = unspecified;
  188. typedef mpl::bool_<true-or-false> type;
  189. };
  190. The metafunction types and return:
  191. BOOST_TTI_TP_T = the enclosing type in which to look for our 'name'.
  192. The enclosing type can be a class, struct, or union.
  193. returns = 'value' is true if the 'name' template exists within the enclosing type,
  194. otherwise 'value' is false.
  195. @endcode
  196. Examples:
  197. @code
  198. 1) Search for an inner class template called 'MyTemplate', with all template type parameters,
  199. nested within the class 'MyClass' using a metafunction name of 'MyMeta'.
  200. BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,BOOST_PP_NIL)
  201. MyMeta<MyClass>::value
  202. is a compile time boolean constant which is either 'true' or 'false'
  203. if the nested template exists.
  204. 2) Search for an inner class template called 'MyTemplate', with template parameters
  205. of 'class T,int x,template<class> class U', nested within the class 'MyClass'
  206. using a metafunction name of 'MyMeta'.
  207. BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,(3,(class,int,template<class> class)))
  208. MyMeta<MyClass>::value
  209. is a compile time boolean constant which is either 'true' or 'false'
  210. if the nested template exists.
  211. @endcode
  212. */
  213. #define BOOST_TTI_TRAIT_HAS_TEMPLATE(trait,name,params) \
  214. BOOST_PP_IIF \
  215. ( \
  216. BOOST_PP_IS_BINARY(params), \
  217. BOOST_TTI_DETAIL_TRAIT_HAS_TEMPLATE_CHECK_PARAMS, \
  218. BOOST_TTI_DETAIL_TRAIT_CHECK_IS_NIL \
  219. ) \
  220. (trait,name,params) \
  221. /**/
  222. /// A macro which expands to a metafunction which tests whether an inner class template with a particular name exists.
  223. /**
  224. BOOST_TTI_HAS_TEMPLATE is a macro which expands to a metafunction.
  225. The metafunction tests whether an inner class template with a particular name exists.
  226. The macro takes the form of BOOST_TTI_HAS_TEMPLATE(name,params) where
  227. name = the inner class template name <br/>
  228. params = If the parameter is BOOST_PP_NIL the inner class template
  229. being introspected must be all template type parameters ( template parameters
  230. starting with `class` or `typename` ) and any number of template type parameters
  231. can occur.
  232. If the parameter is a Boost preprocessor library array, then the inner class
  233. template must have its template parameters matching the sequence in the tuple portion
  234. of the Boost PP array.
  235. If the parameter is anything else a compiler error occurs.
  236. BOOST_TTI_HAS_TEMPLATE generates a metafunction called "has_template_'name'" where 'name' is the first macro parameter.
  237. @code
  238. template<class BOOST_TTI_TP_T>
  239. struct has_template_'name'
  240. {
  241. static const value = unspecified;
  242. typedef mpl::bool_<true-or-false> type;
  243. };
  244. The metafunction types and return:
  245. BOOST_TTI_TP_T = the enclosing type in which to look for our 'name'.
  246. The enclosing type can be a class, struct, or union.
  247. returns = 'value' is true if the 'name' template exists within the enclosing type,
  248. otherwise 'value' is false.
  249. @endcode
  250. Examples:
  251. @code
  252. 1) Search for an inner class template called 'MyTemplate', with all template type parameters,
  253. nested within the class 'MyClass'.
  254. BOOST_TTI_HAS_TEMPLATE(MyTemplate,BOOST_PP_NIL)
  255. has_template_MyTemplate<MyClass>::value
  256. is a compile time boolean constant which is either 'true' or 'false'
  257. if the nested template exists.
  258. 2) Search for an inner class template called 'MyTemplate' with template parameters
  259. of 'class T,int x,template<class> class U' nested within the class 'MyClass'.
  260. BOOST_TTI_HAS_TEMPLATE(MyTemplate,(3,(class,int,template<class> class)))
  261. has_template_MyTemplate<MyClass>::value
  262. is a compile time boolean constant which is either 'true' or 'false'
  263. if the nested template exists.
  264. @endcode
  265. */
  266. #define BOOST_TTI_HAS_TEMPLATE(name,params) \
  267. BOOST_TTI_TRAIT_HAS_TEMPLATE \
  268. ( \
  269. BOOST_TTI_HAS_TEMPLATE_GEN(name), \
  270. name, \
  271. params \
  272. ) \
  273. /**/
  274. #endif // BOOST_PP_VARIADICS
  275. #endif // BOOST_TTI_HAS_TEMPLATE_HPP