1[/ 2 (C) Copyright Edward Diener 2011,2012,2020 3 Distributed under the Boost Software License, Version 1.0. 4 (See accompanying file LICENSE_1_0.txt or copy at 5 http://www.boost.org/LICENSE_1_0.txt). 6] 7 8[section:tti_usingMM An example using the macro metafunctions] 9[#sectti_usingMM] 10 11Using the macro metafunctions can be illustrated by first creating some hypothetical 12user-defined type with corresponding nested types and other inner elements. 13With this type we can illustrate the use of the macro metafunctions. This is 14just meant to serve as a model for what a type T might entail from within 15a class or function template where 'T' is a type passed to the template. 16 17 // An enclosing type, this could also be a class or a union 18 19 struct AType 20 { 21 22 // Type 23 24 typedef int AnIntType; // as a typedef 25 26 // Class/Struct 27 28 struct BType // as a nested struct 29 { 30 struct CType 31 { 32 }; 33 }; 34 35 class AClass // as a nested class 36 { 37 }; 38 39 // Enumeration 40 41 enum EColor // as a nested enumeration 42 { 43 Red, 44 Blue, 45 Green 46 }; 47 48 // Union 49 50 union AUnion // as a nested union 51 { 52 int i; 53 long l; 54 }; 55 56 // Class Template 57 58 template <class> struct AMemberTemplate { }; 59 template <class,class,class> struct AnotherMemberTemplate { }; 60 template <class,class,int,class,template <class> class,class,long> struct ManyParameters { }; 61 template <class,class,int,short,class,template <class,int> class,class> struct MoreParameters { }; 62 63 // Data 64 65 BType IntBT; 66 67 // Function 68 69 int IntFunction(short) { return 0; } 70 71 // Const Function 72 73 long AnotherFunction(bool,double) const { return 0L; } 74 75 // Function Template 76 77 template<class X, class Y, int Z> int MyFunctionTemplate(X *, Y &) { return Z; } 78 79 // Const Function Template 80 81 template<class X, int Y, class Z> int AnotherFunctionTemplate(X &, Z **) const { return Y; } 82 83 // Static Data 84 85 static short DSMember; 86 87 // Static Function 88 89 static int SIntFunction(long,double) { return 2; } 90 91 // Static Function Template 92 93 template<class A, class B> static long SFunctionTemplate(long &,A **,B,float) { return 20L; } 94 95 }; 96 97I will be using the type above just to illustrate the sort of 98metaprogramming questions we can ask of some type T which is passed 99to the template programmer in a class template. Here is what the 100class template might look like: 101 102 #include <boost/tti/tti.hpp> 103 104 template<class T> 105 struct OurTemplateClass 106 { 107 108 // compile-time template code regarding T 109 110 }; 111 112Now let us create and invoke the macro metafunctions for each of our inner element types, 113to see if type T above corresponds to our hypothetical type above. Imagine this being 114within 'OurTemplateClass' above. In the examples below the same macro is invoked just once 115to avoid ODR violations. Also in these examples we are showing results which return 116the compile time boolean result of 'true' to illustrate how our macro metafunctions work. 117We could just as well create examples which return the compile time boolean result of 118'false' if we introspect for constructs that do not exist in our hypothetical type of T. 119We can validly return 'true' or 'false' without generating compiler errors as long as the 120types using in our macro metafunction invocations exist at the time we invoke the 121metafunction. 122 123[heading Type] 124 125C++ named types can be typedefs or type aliases, class, structs, unions, or enumerations 126 127Does T have a nested type called 'AnIntType' ? 128 129 BOOST_TTI_HAS_TYPE(AnIntType) 130 131 has_type_AnIntType 132 < 133 T 134 > 135 136Does T have a nested type called 'BType' ? 137 138 BOOST_TTI_HAS_TYPE(BType) 139 140 has_type_BType 141 < 142 T 143 > 144 145Does T have a nested type called 'AClass' ? 146 147 BOOST_TTI_HAS_TYPE(AClass) 148 149 has_type_ACLass 150 < 151 T 152 > 153 154Does T have a nested type called 'EColor' ? 155 156 BOOST_TTI_HAS_TYPE(EColor) 157 158 has_type_EColor 159 < 160 T 161 > 162 163Does T have a nested type called 'AUnion' ? 164 165 BOOST_TTI_HAS_TYPE(AUnion) 166 167 has_type_AUnion 168 < 169 T 170 > 171 172[heading Type checking the typedef using an MPL lambda expression] 173 174Does T have a nested typedef called 'AnIntType' whose type is an 'int' ? 175 176 #include <boost/mpl/placeholders.hpp 177 #include <boost/type_traits/is_same.hpp 178 using namespace boost::mpl::placeholders; 179 180 has_type_AnIntType 181 < 182 T, 183 boost::is_same<_1,int> 184 > 185 186[heading Class/Struct] 187 188Does T have a nested class called 'AClass' ? 189 190 BOOST_TTI_HAS_CLASS(AClass) 191 192 has_class_AClass 193 < 194 T 195 > 196 197Does T have a nested struct called 'BType' ? 198 199 BOOST_TTI_HAS_CLASS(BType) 200 201 has_class_BType 202 < 203 T 204 > 205 206You can also use an MPL lambda expression with a class/struct just as you can with a general type. 207 208[heading Enumeration] 209 210Does T have a nested enumeration called 'EColor' ? 211 212 BOOST_TTI_HAS_ENUM(EColor) 213 214 has_enum_EColor 215 < 216 T 217 > 218 219You can also use an MPL lambda expression with an enumeration just as you can with a general type. 220 221[heading Union] 222 223Does T have a nested union called 'AUnion' ? 224 225 BOOST_TTI_HAS_UNION(AUnion) 226 227 has_union_AUnion 228 < 229 T 230 > 231 232You can also use an MPL lambda expression with a union just as you can with a general type. 233 234[heading Template] 235 236Does T have a nested class template called 'AMemberTemplate' whose template 237parameters are all types ('class' or 'typename') ? 238 239 BOOST_TTI_HAS_TEMPLATE(AMemberTemplate,BOOST_PP_NIL) 240 241 has_template_AMemberTemplate 242 < 243 T 244 > 245 246[heading Template using variadic macros] 247 248Does T have a nested class template called 'AMemberTemplate' whose template 249parameters are all types ('class' or 'typename') ? 250 251 BOOST_TTI_HAS_TEMPLATE(AnotherMemberTemplate) 252 253 has_template_AnotherMemberTemplate 254 < 255 T 256 > 257 258[heading Template with params] 259 260Does T have a nested class template called 'MoreParameters' whose template 261parameters are specified exactly ? 262 263 BOOST_TTI_HAS_TEMPLATE(MoreParameters,(8,(class,class,int,short,class,template <class,int> class,class))) 264 265 has_template_MoreParameters 266 < 267 T 268 > 269 270[heading Template with params using variadic macros] 271 272Does T have a nested class template called 'ManyParameters' whose template 273parameters are specified exactly ? 274 275 BOOST_TTI_HAS_TEMPLATE(ManyParameters,class,class,int,class,template <class> class,class,long) 276 277 has_template_ManyParameters 278 < 279 T 280 > 281 282[heading Member data] 283 284Does T have a member data called 'IntBT' whose type is 'AType::BType' ? 285 286 BOOST_TTI_HAS_MEMBER_DATA(IntBT) 287 288 has_member_data_IntBT 289 < 290 T, 291 AType::BType 292 > 293 294[heading Member data with composite type] 295 296Does T have a member data called 'IntBT' whose type is 'AType::BType' ? 297 298 BOOST_TTI_HAS_MEMBER_DATA(IntBT) 299 300 has_member_data_IntBT 301 < 302 AType::BType T::* 303 > 304 305[heading Member function with individual types] 306 307Does T have a member function called 'IntFunction' whose type is 308'int (short)' ? 309 310 BOOST_TTI_HAS_MEMBER_FUNCTION(IntFunction) 311 312 has_member_function_IntFunction 313 < 314 T, 315 int, 316 boost::mpl::vector<short> 317 > 318 319[heading Member function with composite type] 320 321Does T have a member function called 'IntFunction' whose type is 322'int (short)' ? 323 324 BOOST_TTI_HAS_MEMBER_FUNCTION(IntFunction) 325 326 has_member_function_IntFunction 327 < 328 int (T::*) (short) 329 > 330 331[heading Const member function with individual types] 332 333Does T have a member function called 'AnotherFunction' whose type is 334'long (bool,double) const' ? 335 336 BOOST_TTI_HAS_MEMBER_FUNCTION(AnotherFunction) 337 338 has_member_function_AnotherFunction 339 < 340 T, 341 long, 342 boost::mpl::vector<bool,double>, 343 boost::function_types::const_qualified 344 > 345 346[heading Const member function with composite type] 347 348Does T have a member function called 'AnotherFunction' whose type is 349'long (bool,double) const' ? 350 351 BOOST_TTI_HAS_MEMBER_FUNCTION(AnotherFunction) 352 353 has_member_function_AnotherFunction 354 < 355 long (T::*) (bool,double) const 356 > 357 358[heading Member function template with individual types] 359 360Does T have a member function template called 'MyFunctionTemplate' woth an instantiated 361signature of 'int MyFunctionTemplate<short,float,579>(short *,float &)' ? 362 363 BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(MyFunctionTemplate,short,float,579) 364 365 has_member_function_MyFunctionTemplate 366 < 367 T, 368 int, 369 boost::mpl::vector<short *,float &> 370 > 371 372[heading Member function template with composite type] 373 374Does T have a member function template called 'MyFunctionTemplate' woth an instantiated 375signature of 'int MyFunctionTemplate<int,long,183>(int *,long &)' ? 376 377 BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(MyFunctionTemplate,int,long,183) 378 379 has_member_function_template_MyFunctionTemplate 380 < 381 int (T::*)(int *,long &) 382 > 383 384[heading Const member function template with individual types] 385 386Does T have a member function template called 'AnotherFunctionTemplate' with an instantiated 387signature of 'int AnotherFunctionTemplate<bool,8359,double>(bool &,double **) const' ? 388 389 BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(AnotherFunctionTemplate,bool,8359,double) 390 391 has_member_function_AnotherFunctionTemplate 392 < 393 T, 394 int, 395 boost::mpl::vector<bool &,double **>, 396 boost::function_types::const_qualified 397 > 398 399[heading Const member function template with composite type] 400 401Does T have a member function template called 'AnotherFunctionTemplate' with an instantiated 402signature of 'int AnotherFunctionTemplate<bool,8359,double>(bool &,double **) const' ? 403 404 BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(AnotherFunctionTemplate,bool,8359,double) 405 406 has_member_function_template_MyFunctionTemplate 407 < 408 int (T::*)(bool &,double **) const 409 > 410 411[heading Static member data] 412 413Does T have a static member data called 'DSMember' whose type is 'short' ? 414 415 BOOST_TTI_HAS_STATIC_MEMBER_DATA(DSMember) 416 417 has_static_member_data_DSMember 418 < 419 T, 420 short 421 > 422 423[heading Static member function with individual types] 424 425Does T have a static member function called 'SIntFunction' whose type 426is 'int (long,double)' ? 427 428 BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(SIntFunction) 429 430 has_static_member_function_SIntFunction 431 < 432 T, 433 int, 434 boost::mpl::vector<long,double> 435 > 436 437[heading Static member function with composite type] 438 439Does T have a static member function called 'SIntFunction' whose type 440is 'int (long,double)' ? 441 442 BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(SIntFunction) 443 444 has_static_member_function_SIntFunction 445 < 446 T, 447 int (long,double) 448 > 449 450[heading Static member function template with individual types] 451 452Does T have a static member function template called 'SFunctionTemplate' with an 453instantiated signature of 'long SFunctionTemplate<char,unsigned>(long &,char **,unsigned,float)' ? 454 455 BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION_TEMPLATE(SFunctionTemplate,char,unsigned) 456 457 has_static_member_function_template_SFunctionTemplate 458 < 459 T, 460 long, 461 boost::mpl::vector<long &,char **,unsigned,float> 462 > 463 464[heading Static member function template with composite type] 465 466Does T have a static member function template called 'SFunctionTemplate' with an 467instantiated signature of 'long SFunctionTemplate<bool,int>(long &,bool **,int,float)' ? 468 469 BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION_TEMPLATE(SFunctionTemplate,bool,int) 470 471 has_static_member_function_template_SFunctionTemplate 472 < 473 T, 474 long (long &,bool **,int,float) 475 > 476 477[heading Data] 478 479Does T have a member data or static member data called 'DSMember' whose type is 'short' ? 480 481 BOOST_TTI_HAS_DATA(DSMember) 482 483 has_static_member_data_DSMember 484 < 485 T, 486 short 487 > 488 489[heading Function] 490 491Does T have a member function or a static member function called 'IntFunction' whose type is 492'int (short)' ? 493 494 BOOST_TTI_HAS_FUNCTION(IntFunction) 495 496 has_function_IntFunction 497 < 498 T, 499 int, 500 boost::mpl::vector<short> 501 > 502 503[heading Function Template] 504 505Does T have a member function template or a static member function template called 'MyFunctionTemplate' 506with an instantiated signature of 'int MyFunctionTemplate<bool,short,3487>(bool *,short &)' ? 507 508 BOOST_TTI_HAS_FUNCTION_TEMPLATE(MyFunctionTemplate,bool,short,3487) 509 510 has_function_template_MyFunctionTemplate 511 < 512 T, 513 int, 514 boost::mpl::vector<bool *,short &> 515 > 516 517[heading Member type] 518 519Create a nested type T::BType::CType without creating a compiler error 520if T does not have the nested type BType::CType ? 521 522 BOOST_TTI_MEMBER_TYPE(BType) 523 BOOST_TTI_MEMBER_TYPE(CType) 524 525 typename 526 member_type_CType 527 < 528 typename 529 member_type_BType 530 < 531 T 532 >::type 533 >::type 534 535[heading Member type existence] 536 537Does a nested type T::BType::CType, created without creating a compiler error 538if T does not have the nested type BType::CType, actually exist ? 539 540 BOOST_TTI_MEMBER_TYPE(BType) 541 BOOST_TTI_MEMBER_TYPE(CType) 542 543 typedef typename 544 member_type_CType 545 < 546 typename 547 member_type_BType 548 < 549 T 550 >::type 551 >::type 552 AType; 553 554 boost::tti::valid_member_type 555 < 556 AType 557 > 558 559[endsect] 560