| [/ |
| (C) Copyright Edward Diener 2011,2012 |
| 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_static_member_function Introspecting static member function] |
| |
| The TTI macro [macroref BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION] introspects |
| a static member function of a class. |
| |
| BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION takes a single |
| parameter which is the name of an inner static member function whose existence |
| the programmer wants to check. The macro generates a metafunction |
| called 'has_static_member_function_'name_of_inner_static_member_function'. |
| |
| The metafunction can be invoked in two different ways. |
| |
| The first way is by passing it the enclosing type to introspect and a |
| signature for the static member function as separate template |
| arguments. The signature for the static member function consists of a return |
| type, optional parameter types in the form of a boost::mpl forward |
| sequence of types, and an optional Boost FunctionTypes tag type. A |
| typical boost::mpl forward sequence of types is a boost::mpl::vector<>. |
| |
| The second way is by passing it the enclosing type to introspect and a |
| signature for the static member function as a function. The function |
| has the form of: |
| |
| Return_Type ( Parameter_Types ) |
| |
| where the Parameter_Types may be empty, or a comma-separated |
| list of parameter types if there are more than one parameter type. |
| |
| 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 is true or false depending on whether the inner |
| static 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 static member function: |
| |
| BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(AStaticMemberFunction) |
| |
| generates a metafunction called 'has_static_member_function_AStaticMemberFunction' 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 static member function as a series of template |
| parameters. Alternatively you can invoke the metafunction by passing it an enclosing type |
| and the signature of the static member function as a single function type. |
| |
| A return value called 'value' is a compile time bool constant. |
| |
| has_static_member_function_AStaticMemberFunction |
| < |
| Enclosing_Type, |
| StaticMemberFunction_ReturnType, |
| boost::mpl::vector<StaticMemberFunction_ParameterTypes>, // optional, can be any mpl forward sequence |
| boost::function_types::SomeTagType // optional, can be any FunctionTypes tag type |
| >::value |
| |
| OR |
| |
| has_static_member_function_AStaticMemberFunction |
| < |
| Enclosing_Type, |
| Return_Type ( Parameter_Types ) |
| >::value |
| |
| [heading Examples] |
| |
| First we generate metafunctions for various inner static member function names: |
| |
| #include <boost/tti/has_static_member_function.hpp> |
| |
| BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(function1) |
| BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(function2) |
| BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(function3) |
| |
| Next let us create some user-defined types we want to introspect. |
| |
| struct AClass { }; |
| struct Top |
| { |
| static int function1(); |
| static AClass function2(double,short *); |
| }; |
| struct Top2 |
| { |
| static long function2(Top &,int,bool,short,float); |
| static 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_static_member_function_function1<Top,int>::value; // true |
| has_static_member_function_function1<Top,int ()>::value; // true |
| has_static_member_function_function1<Top2,int>::value; // false |
| |
| has_static_member_function_function2<Top,AClass,boost::mpl::vector<double,short *> >::value; // true |
| has_static_member_function_function2<Top2,AClass,boost::mpl::vector<double,short *> >::value; // false |
| has_static_member_function_function2<Top2,long (Top &,int,bool,short,float)>::value; // true |
| |
| has_static_member_function_function3<Top2,int ()>::value; // false |
| has_static_member_function_function3<Top2,Top * (long,int,AClass &)>::value; // true; |
| |
| [heading Metafunction re-use] |
| |
| The macro encodes only the name of the static member function |
| for which we are searching and the fact that we are |
| introspecting for a static member function within an enclosing type. |
| |
| Because of this, once we create our metafunction for |
| introspecting a static member function by name, we can reuse the |
| metafunction for introspecting any enclosing type, having any |
| static member function, for that name. |
| |
| [endsect] |