]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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_detail_has_static_member_function Introspecting static member function] | |
9 | ||
10 | The TTI macro [macroref BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION] introspects | |
11 | a static member function of a class. | |
12 | ||
13 | BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION takes a single | |
14 | parameter which is the name of an inner static member function whose existence | |
15 | the programmer wants to check. The macro generates a metafunction | |
16 | called 'has_static_member_function_'name_of_inner_static_member_function'. | |
17 | ||
18 | The metafunction can be invoked in two different ways. | |
19 | ||
20 | The first way is by passing it the enclosing type to introspect and a | |
21 | signature for the static member function as separate template | |
22 | arguments. The signature for the static member function consists of a return | |
23 | type, optional parameter types in the form of a boost::mpl forward | |
24 | sequence of types, and an optional Boost FunctionTypes tag type. A | |
25 | typical boost::mpl forward sequence of types is a boost::mpl::vector<>. | |
26 | ||
27 | The second way is by passing it the enclosing type to introspect and a | |
28 | signature for the static member function as a function. The function | |
29 | has the form of: | |
30 | ||
31 | Return_Type ( Parameter_Types ) | |
32 | ||
33 | where the Parameter_Types may be empty, or a comma-separated | |
34 | list of parameter types if there are more than one parameter type. | |
35 | ||
36 | The metafunction returns a single type called 'type', which is a | |
37 | boost::mpl::bool_. As a convenience the metafunction | |
38 | returns the value of this type directly as a compile time bool constant | |
39 | called 'value'. This is true or false depending on whether the inner | |
40 | static member function, of the specified signature, exists or not. | |
41 | ||
42 | [heading Generating the metafunction] | |
43 | ||
44 | You generate the metafunction by invoking the macro with the name | |
45 | of an inner static member function: | |
46 | ||
47 | BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(AStaticMemberFunction) | |
48 | ||
49 | generates a metafunction called 'has_static_member_function_AStaticMemberFunction' in the current scope. | |
50 | ||
51 | [heading Invoking the metafunction] | |
52 | ||
53 | You invoke the metafunction by instantiating the template with an enclosing | |
54 | type to introspect and the signature of the static member function as a series of template | |
55 | parameters. Alternatively you can invoke the metafunction by passing it an enclosing type | |
56 | and the signature of the static member function as a single function type. | |
57 | ||
58 | A return value called 'value' is a compile time bool constant. | |
59 | ||
60 | has_static_member_function_AStaticMemberFunction | |
61 | < | |
62 | Enclosing_Type, | |
63 | StaticMemberFunction_ReturnType, | |
64 | boost::mpl::vector<StaticMemberFunction_ParameterTypes>, // optional, can be any mpl forward sequence | |
65 | boost::function_types::SomeTagType // optional, can be any FunctionTypes tag type | |
66 | >::value | |
67 | ||
68 | OR | |
69 | ||
70 | has_static_member_function_AStaticMemberFunction | |
71 | < | |
72 | Enclosing_Type, | |
73 | Return_Type ( Parameter_Types ) | |
74 | >::value | |
75 | ||
76 | [heading Examples] | |
77 | ||
78 | First we generate metafunctions for various inner static member function names: | |
79 | ||
80 | #include <boost/tti/has_static_member_function.hpp> | |
81 | ||
82 | BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(function1) | |
83 | BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(function2) | |
84 | BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(function3) | |
85 | ||
86 | Next let us create some user-defined types we want to introspect. | |
87 | ||
88 | struct AClass { }; | |
89 | struct Top | |
90 | { | |
91 | static int function1(); | |
92 | static AClass function2(double,short *); | |
93 | }; | |
94 | struct Top2 | |
95 | { | |
96 | static long function2(Top &,int,bool,short,float); | |
97 | static Top * function3(long,int,AClass &); | |
98 | }; | |
99 | ||
100 | Finally we invoke our metafunction and return our value. | |
101 | This all happens at compile time, and can be used by | |
102 | programmers doing compile time template metaprogramming. | |
103 | ||
104 | We will show both forms in the following examples. | |
105 | Both forms are completely interchangeable as to the result | |
106 | desired. | |
107 | ||
108 | has_static_member_function_function1<Top,int>::value; // true | |
109 | has_static_member_function_function1<Top,int ()>::value; // true | |
110 | has_static_member_function_function1<Top2,int>::value; // false | |
111 | ||
112 | has_static_member_function_function2<Top,AClass,boost::mpl::vector<double,short *> >::value; // true | |
113 | has_static_member_function_function2<Top2,AClass,boost::mpl::vector<double,short *> >::value; // false | |
114 | has_static_member_function_function2<Top2,long (Top &,int,bool,short,float)>::value; // true | |
115 | ||
116 | has_static_member_function_function3<Top2,int ()>::value; // false | |
117 | has_static_member_function_function3<Top2,Top * (long,int,AClass &)>::value; // true; | |
118 | ||
119 | [heading Metafunction re-use] | |
120 | ||
121 | The macro encodes only the name of the static member function | |
122 | for which we are searching and the fact that we are | |
123 | introspecting for a static member function within an enclosing type. | |
124 | ||
125 | Because of this, once we create our metafunction for | |
126 | introspecting a static member function by name, we can reuse the | |
127 | metafunction for introspecting any enclosing type, having any | |
128 | static member function, for that name. | |
129 | ||
130 | [endsect] |