1[/ 2 (C) Copyright Edward Diener 2011,2012 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_functionality General Functionality] 9 10The elements of a type about which a template metaprogrammer might be interested in finding 11out at compile time are: 12 13* Does it have a nested type with a particular name ? 14* Does it have a nested type with a particular name which fulfills some other possibility for that nested type. 15* Does it have a particular user-defined nested type (struct/class, union, or enumaeration) with a particular name ? 16* Does it have a particular user-defined nested type with a particular name which fulfills some other possibility for that nested type. 17* Does it have a nested class template with a particular name ? 18* Does it have a nested class template with a particular name and a particular signature ? 19* Does it have a nested member function template with a particular name and a particular instantiated signature ? 20* Does it have a nested static function template with a particular name and a particular instantiated signature ? 21* Does it have a member function with a particular name and a particular signature ? 22* Does it have member data with a particular name and of a particular type ? 23* Does it have a static member function with a particular name and a particular signature ? 24* Does it have static member data with a particular name and of a particular type ? 25* Does it have either member data or static member data with a particular name and of a particular type ? 26* Does it have either a member function or static member function with a particular name and of a particular type ? 27 28These are some of the compile-time questions which the TTI library answers. It 29does this by creating metafunctions, which can be used at compile-time, using 30C++ macros. Each of the metafunctions created returns a compile time constant 31bool value which answers one of the above questions at compile time. When the 32particular element above exists the value is 'true', or more precisely 33boost::mpl::true_, while if the element does not exist the value is 'false', 34or more precisely boost::mpl::false_. In either case the type of this value 35is boost::mpl::bool_. 36 37This constant bool value, in the terminology of the Boost MPL library, is called an 'integral 38constant wrapper' and the metafunction generated is called a 'numerical metafunction'. The 39results from calling the metafunction can be passed to other metafunctions for type selection, 40the most popular of these being the boolean-valued operators in the Boost MPL library. 41 42All of the questions above attempt to find an answer about an inner element with 43a particular name. In order to do this using template metaprogramming, macros are used 44so that the name of the inner element can be passed to the macro. The macro will then 45generate an appropriate metafunction, which the template metaprogrammer can then use to 46introspect the information that is needed. The name itself of the inner element is always passed 47to the macro as a macro parameter, but other macro parameters may also be needed in some cases. 48 49All of the macros start with the prefix `BOOST_TTI_`, create their metafunctions as class 50templates in whatever scope the user invokes the macro, and come in two forms: 51 52# In the simplest macro form, which I call the simple macro form, the 'name' of the inner element 53 is used directly to generate the name of the metafunction as well as serving as the 'name' 54 to introspect. In generating the name of the metafunction from the macro name, the 55 `BOOST_TTI_` prefix is removed, the rest of the macro name is changed to lower case, and an 56 underscore ( '_' ) followed by the 'name' is appended. As an example, for the macro 57 `BOOST_TTI_HAS_TYPE(MyType)` the name of the metafunction is `has_type_MyType` and it will 58 look for an inner type called 'MyType'. 59# In a more complicated macro form, which I call the complex macro form, the macro starts with 60 `BOOST_TTI_TRAIT_` and a 'trait' name is passed as the first parameter, with the 'name' of the inner 61 element as the second parameter. The 'trait' name serves solely to completely name the metafunction in 62 whatever scope the macro is invoked. As an example, for the macro 63 `BOOST_TTI_TRAIT_HAS_TYPE(MyTrait,MyType)` the name of 64 the metafunction is `MyTrait` and it will look for an inner type called `MyType`. 65 66Every macro metafunction has a simple macro form and a corresponding complex macro form. 67Once either of these two macro forms are used for a particular type of inner element, the 68corresponding macro metafunction works exactly the same way and has the exact same functionality. 69 70In the succeeding documentation all macro metafunctions will be referred by their simple form 71name, but remember that the complex form can always be used instead. The complex form is useful 72whenever using the simple form could create a duplicate name in the same name space, thereby 73violating the C++ one definition rule. 74 75[heading Macro Metafunction Name Generation] 76 77For the simple macro form, even though it is fairly easy to remember the algorithm by which 78the generated metafunction is named, TTI also provides, for each macro metafunction, 79a corresponding 'naming' macro which the end-user can use and whose sole purpose 80is to expand to the metafunction name. The naming macro for each macro metafunction has the form: 81'corresponding-macro'_GEN(name). 82 83As an example, BOOST_TTI_HAS_TYPE(MyType) creates a metafunction 84which looks for a nested type called 'MyType' within some enclosing type. The name of the metafunction 85generated, given our rule above is 'has_type_MyType'. A corresponding macro called 86BOOST_TTI_HAS_TYPE_GEN, invoked as BOOST_TTI_HAS_TYPE_GEN(MyType) in our example, expands to the 87same 'has_type_MyType' name. These name generating macros, for each of the metafunction generating macros, 88are purely a convenience for end-users who find using them easier than remembering the name-generating 89rule given above. 90 91[section:tti_functionality_nm_gen Macro metafunction name generation considerations] 92 93Because having a double underscore ( __ ) in a name is reserved by the C++ implementation, 94creating C++ identifiers with double underscores should be avoided by the end-user. When using 95a TTI macro to generate a metafunction using the simple macro form, TTI appends a single 96underscore to the macro name preceding the name of the element that is being introspected. 97The reason for doing this is because Boost discourages as non-portable C++ identifiers with mixed 98case letters and the underscore then becomes the normal way to separate parts of an identifier 99name so that it looks understandable. Because of this decision to use the underscore to generate 100the metafunction name from the macro name, any inner element starting with an underscore will cause 101the identifier for the metafunction name being generated to contain a double underscore. 102 103A rule to avoid this problem is: 104 105* When the name of the inner element to be introspected begins with an underscore, use 106the complex macro form, where the name of the metafunction is specifically given. 107 108Furthermore because TTI often generates not only a metafunction for the end-user to use but some 109supporting detail metafunctions whose identifier, for reasons of programming clarity, is the same 110as the metafunction with further letters appended to it separated by an underscore, another rule is: 111 112* When using the complex macro form, which fully gives the name of the generated 113macro metafunction, that name should not end with an underscore. 114 115Following these two simple rules will avoid names with double underscores being 116generated by TTI. 117 118[heading Reusing the named metafunction] 119 120When the end-user uses the TTI macros to generate a metafunction for introspecting an inner 121element of a particular type, that metafunction can be re-used with any combination of valid 122template parameters which involve the same type of inner element of a particular name. 123 124As one example of this let's consider two different user-defined types called 125'AType' and 'BType', for each of which we want to determine whether an inner type called 126'InnerType' exists. For both these types we need only generate a single macro metafunction in 127the current scope by using: 128 129 BOOST_TTI_HAS_TYPE(InnerType) 130 131We now have a metafunction, which is a C++ class template, in the current scope whose C++ identifier 132is 'has_type_InnerType'. We can use this same metafunction to introspect the existence of the nested type 133'InnerType' in either 'AType' or 'BType' at compile time. Although the syntax for doing this has no yet 134been explained, I will give it here so that you can see how 'has_type_InnerType' is reused: 135 136# 'has_type_InnerType<AType>::value' is a compile time constant telling us whether 'InnerType' is a 137type which is nested within 'AType'. 138 139# 'has_type_InnerType<BType>::value' is a compile time constant telling us whether 'InnerType' is a 140type which is nested within 'BType'. 141 142As another example of metafunction reuse let's consider a single user-defined type, called 'CType', 143for which we want to determine if it has either of two overloaded member functions with the same name 144of 'AMemberFunction' but with the different function signatures of 'int (int)' and 'double (long)'. 145For both these member functions we need only generate a single macro metafunction in the current scope 146by using: 147 148 BOOST_TTI_HAS_MEMBER_FUNCTION(AMemberFunction) 149 150We now have a metafunction, which is a C++ class template, in the current scope whose C++ identifier 151is 'has_member_function_AMemberFunction'. We can use this same metafunction to introspect the 152existence of the member function 'AMemberFunction' with either the function signature of 153'int (int)' or 'double (long)' in 'CType' at compile time. Although the syntax for doing this has no yet 154been explained, I will give it here so that you can see how 'has_type_InnerType' is reused: 155 156# 'has_member_function_AMemberFunction<CType,int,boost::mpl::vector<int> >::value' is a 157compile time constant telling us whether 'AMemberFunction' is a member function of type 'CType' 158whose function signature is 'int (int)'. 159 160# 'has_member_function_AMemberFunction<CType,double,boost::mpl::vector<long> >::value' is a 161compile time constant telling us whether 'AMemberFunction' is a member function of type 'CType' 162whose function signature is 'double (long)'. 163 164These are just two examples of the ways a particular macro metafunction can be reused. The two 165'constants' when generating a macro metafunction are the 'name' and 'type of inner element'. Once 166the macro metafunction for a particular name and inner element type has been generated, it can be reused 167for introspecting the inner element(s) of any enclosing type which correspond to that name and 168inner element type. 169 170[heading Avoiding ODR violations] 171 172The TTI macro metafunctions are generating directly in the enclosing scope in which the 173corresponding macro is invoked. This can be any C++ scope in which a class template can 174be specified. Within this enclosing scope the name of the metafunction 175being generated must be unique or else a C++ ODR ( One Definition Rule ) violation will occur. 176This is extremely important to remember, especially when the enclosing scope can occur in 177more than one translation unit, which is the case for namespaces and the global scope. 178 179Because of ODR, and the way that the simple macro form metafunction name is directly dependent 180on the inner element and name of the element being introspected, it is the responsibility of the 181programmer, using the TTI macros to generate metafunctions, to avoid ODR within a module 182( application or library ). There are a few general methods for doing this: 183 184# Create unique namespace names in which to generate the macro metafunctions and/or generate 185the macro metafunctions in C++ scopes which can not extend across translation units. The most 186obvious example of this latter is within C++ classes. 187 188# Use the complex macro form to specifically name the metafunction generated in order to 189provide a unique name. 190 191# Avoid using the TTI macros in the global scope. 192 193For anyone using TTI in a library which others will eventually use, it is important 194to generate metafunction names which are unique to that library. 195 196TTI also reserves not only the name generated by the macro metafunction for its use 197but also any C++ identifier sequence which begins with that name. In other words 198if the metafunction being generated by TTI is named 'MyMetafunction' using the complex 199macro form, do not create any C++ construct with an identifier starting with 'MyMetaFunction', 200such as 'MyMetaFunction_Enumeration' or 'MyMetaFunctionHelper' in the same scope. 201All names starting with the metafunction name in the current scope should be considered 202out of bounds for the programmer using TTI. 203 204[endsect] 205 206[endsect] 207