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 | |