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