]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/ |
2 | (C) Copyright Edward Diener 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_function Introspecting an inner function] | |
9 | ||
10 | The TTI macro [macroref BOOST_TTI_HAS_FUNCTION] introspects | |
11 | an inner function of a class. The function can be either a member | |
12 | function or a static member function. | |
13 | ||
14 | BOOST_TTI_HAS_FUNCTION takes a single | |
15 | parameter which is the name of an inner function whose existence | |
16 | the programmer wants to check. The macro generates a metafunction | |
17 | called 'has_function_'name_of_inner_function'. | |
18 | ||
19 | The metafunction can be invoked by passing it the enclosing type to introspect and a | |
20 | signature for the function as separate template arguments. The signature for the | |
21 | function consists of a return type, optional parameter types in the form of a boost::mpl | |
22 | forward sequence of types, and an optional Boost FunctionTypes tag type. A | |
23 | typical boost::mpl forward sequence of types is a boost::mpl::vector<>. | |
24 | ||
25 | The metafunction returns a single type called 'type', which is a | |
26 | boost::mpl::bool_. As a convenience the metafunction | |
27 | returns the value of this type directly as a compile time bool constant | |
28 | called 'value'. This is true or false depending on whether the inner | |
29 | function, of the specified signature, exists or not. | |
30 | ||
31 | [heading Generating the metafunction] | |
32 | ||
33 | You generate the metafunction by invoking the macro with the name | |
34 | of an inner function: | |
35 | ||
36 | BOOST_TTI_HAS_FUNCTION(AnInnerFunction) | |
37 | ||
38 | generates a metafunction called 'has_function_AnInnerFunction' in the current scope. | |
39 | ||
40 | [heading Invoking the metafunction] | |
41 | ||
42 | You invoke the metafunction by instantiating the template with an enclosing | |
43 | type to introspect and the signature of the function as a series of template | |
44 | parameters. | |
45 | ||
46 | A return value called 'value' is a compile time bool constant. | |
47 | ||
48 | has_function_AnInnerFunction | |
49 | < | |
50 | Enclosing_Type, | |
51 | Function_ReturnType, | |
52 | boost::mpl::vector<Function_ParameterTypes>, // optional, can be any mpl forward sequence | |
53 | boost::function_types::SomeTagType // optional, can be any FunctionTypes tag type | |
54 | >::value | |
55 | ||
56 | [heading Examples] | |
57 | ||
58 | First we generate metafunctions for various inner function names: | |
59 | ||
60 | #include <boost/tti/has_function.hpp> | |
61 | ||
62 | BOOST_TTI_HAS_FUNCTION(function1) | |
63 | BOOST_TTI_HAS_FUNCTION(function2) | |
64 | BOOST_TTI_HAS_FUNCTION(function3) | |
65 | ||
66 | Next let us create some user-defined types we want to introspect. | |
67 | ||
68 | struct AClass { }; | |
69 | struct Top | |
70 | { | |
71 | static int function1(); | |
72 | AClass function2(double,short *); | |
73 | }; | |
74 | struct Top2 | |
75 | { | |
76 | long function2(Top &,int,bool,short,float); | |
77 | static Top * function3(long,int,AClass &); | |
78 | }; | |
79 | ||
80 | Finally we invoke our metafunction and return our value. | |
81 | This all happens at compile time, and can be used by | |
82 | programmers doing compile time template metaprogramming. | |
83 | ||
84 | has_function_function1<Top,int>::value; // true | |
85 | has_function_function1<Top2,int>::value; // false | |
86 | ||
87 | has_function_function2<Top,AClass,boost::mpl::vector<double,short *> >::value; // true | |
88 | has_function_function2<Top2,AClass,boost::mpl::vector<double,short *> >::value; // false | |
89 | ||
90 | has_function_function3<Top2,int>::value; // false | |
91 | has_function_function3<Top2,Top *,boost::mpl::vector<long,int,AClass &> >::value; // true; | |
92 | ||
93 | [heading Metafunction re-use] | |
94 | ||
95 | The macro encodes only the name of the function | |
96 | for which we are searching and the fact that we are | |
97 | introspecting for a function within an enclosing type. | |
98 | ||
99 | Because of this, once we create our metafunction for | |
100 | introspecting a function by name, we can reuse the | |
101 | metafunction for introspecting any enclosing type, having any | |
102 | function, for that name. | |
103 | ||
104 | [endsect] |