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