| [/ |
| (C) Copyright Edward Diener 2011,2012,2014 |
| Distributed under the Boost Software License, Version 1.0. |
| (See accompanying file LICENSE_1_0.txt or copy at |
| http://www.boost.org/LICENSE_1_0.txt). |
| ] |
| |
| [section:tti_detail_has_member_function Introspecting member function] |
| |
| The TTI macro [macroref BOOST_TTI_HAS_MEMBER_FUNCTION] introspects |
| a member function of a class. |
| |
| BOOST_TTI_HAS_MEMBER_FUNCTION takes a single |
| parameter which is the name of an inner member function whose existence |
| the programmer wants to check. The macro generates a metafunction |
| called 'has_member_function_'name_of_inner_member_function'. |
| |
| The metafunction can be invoked in two different ways. |
| |
| The first way of invoking the metafunction is by passing it the enclosing |
| type to introspect and a signature for the member function as a series of |
| separate template arguments. The signature for the member function consists |
| of the template arguments of a return type, of optional parameter types in |
| the form of a boost::mpl forward sequence of types, and of an optional Boost |
| FunctionTypes tag type. A typical boost::mpl forward sequence of types is |
| a boost::mpl::vector<>. |
| |
| The optional Boost FunctionTypes tag type may be used to specify |
| cv-qualification. This means you can add 'const', 'volatile', or both by |
| specifying an appropriate tag type. An alternate to using the tag type |
| is to specify the enclosing type as 'const', 'volatile', or both. |
| As an example if you specify the tag type as |
| 'boost::function_types::const_qualified' or if you specify the enclosing |
| type as 'const T', the member function which you are introspecting |
| must be a const function. |
| |
| The second way of invoking the metafunction is by passing it a single |
| parameter, which is a pointer to member function. This type has the form of: |
| |
| Return_Type ( Enclosing_Type::* ) ( Parameter_Types ) cv_qualifier(s) |
| |
| where the Parameter_Types may be empty, or a comma-separated |
| list of parameter types if there are more than one parameter type. |
| The cv-qualifier may be 'const', 'volatile', or 'const volatile'. |
| |
| The metafunction returns a single type called 'type', which is a |
| boost::mpl::bool_. As a convenience the metafunction |
| returns the value of this type directly as a compile time bool constant |
| called 'value'. This 'value' is true or false depending on whether the inner |
| member function, of the specified signature, exists or not. |
| |
| [heading Generating the metafunction] |
| |
| You generate the metafunction by invoking the macro with the name |
| of an inner member function: |
| |
| BOOST_TTI_HAS_MEMBER_FUNCTION(AMemberFunction) |
| |
| generates a metafunction called 'has_member_function_AMemberFunction' in the current scope. |
| |
| [heading Invoking the metafunction] |
| |
| You invoke the metafunction by instantiating the template with an enclosing |
| type to introspect and the signature of the member function as a series of template |
| parameters. Alternatively you can invoke the metafunction by passing it a single |
| type which is a pointer to member function. |
| |
| A return value called 'value' is a compile time bool constant. |
| |
| has_member_function_AMemberFunction |
| < |
| Enclosing_Type, |
| MemberFunction_ReturnType, |
| boost::mpl::vector<MemberFunction_ParameterTypes>, // optional, can be any mpl forward sequence |
| boost::function_types::SomeTagType // optional, can be any FunctionTypes tag type |
| >::value |
| |
| OR |
| |
| has_member_function_AMemberFunction |
| < |
| MemberFunction_ReturnType (Enclosing_Type::*) (MemberFunction_ParameterTypes) optional_cv_qualification |
| >::value |
| |
| [heading Examples] |
| |
| First we generate metafunctions for various inner member function names: |
| |
| #include <boost/tti/has_member_function.hpp> |
| |
| BOOST_TTI_HAS_MEMBER_FUNCTION(function1) |
| BOOST_TTI_HAS_MEMBER_FUNCTION(function2) |
| BOOST_TTI_HAS_MEMBER_FUNCTION(function3) |
| |
| Next let us create some user-defined types we want to introspect. |
| |
| struct AClass |
| { |
| }; |
| struct Top |
| { |
| int function1(); |
| AClass function2(double,short *); |
| }; |
| struct Top2 |
| { |
| long function2(Top &,int,bool,short,float); |
| Top * function3(long,int,AClass &); |
| }; |
| |
| Finally we invoke our metafunction and return our value. |
| This all happens at compile time, and can be used by |
| programmers doing compile time template metaprogramming. |
| |
| We will show both forms in the following examples. |
| Both forms are completely interchangeable as to the result |
| desired. |
| |
| has_member_function_function1<Top,int>::value; // true |
| has_member_function_function1<Top,int,boost::mpl::vector<> >::value; // true |
| has_member_function_function1<Top2,int>::value; // false |
| |
| has_member_function_function2<AClass (Top::*) (double,short *)>::value; // true |
| has_member_function_function2<AClass (Top2::*) (double,short *)>::value; // false |
| has_member_function_function2<long (Top2::*) (Top &,int,bool,short,float)>::value; // true |
| |
| has_member_function_function3<int (Top2::*) ()>::value; // false |
| has_member_function_function3<Top2,Top *,boost::mpl::vector<long,int,AClass &> >::value; // true; |
| |
| [heading Metafunction re-use] |
| |
| The macro encodes only the name of the member function for which |
| we are searching and the fact that we are introspecting for a |
| member function within an enclosing type. |
| |
| Because of this, once we create our metafunction for |
| introspecting a member function by name, we can reuse the |
| metafunction for introspecting any enclosing type, having any |
| member function, for that name. |
| |
| [endsect] |