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

source code of boost/boost/tti/has_template.hpp