]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/tti/doc/tti_detail_has_type.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / tti / doc / tti_detail_has_type.qbk
CommitLineData
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_type Introspecting an inner type]
9
10The TTI macro [macroref BOOST_TTI_HAS_TYPE] introspects
11a nested type of a class.
12
13The BOOST_TTI_HAS_TYPE macro takes a single parameter which is the name of
14an inner type whose existence the programmer wants to check. The
15macro generates a metafunction called 'has_type_'name_of_inner_type'.
16
17The main purpose of the generated metafunction is to check for the existence by
18name of the inner type. The metafunction can also be used to invoke an MPL lambda
19expression which is passed the inner type. One of the most common usages of the added
20functionality is to check whether or not the inner type is a typedef for another type.
21
22The metafunction is invoked by passing it the enclosing type
23to introspect. A second type may be passed to the
24metafunction, an MPL lambda expression taking the inner type
25and returning a boolean constant.
26
27The metafunction returns a single type called 'type', which is a
28boost::mpl::bool_. As a convenience the metafunction
29returns the value of this type directly as a compile time bool constant
30called 'value'. This value is true or false depending on whether the inner
31type exists or not.
32
33If a second optional type is passed, this type must be an MPL lambda expression
34and the expression will be invoked only if the inner type exists. In that case the
35metafunction returns true or false depending on whether the lambda expression returns
36true or false. If the inner type does not exist, the lambda expression, even if
37specified, is never invoked and the metafunction returns false.
38
39[heading Generating the metafunction]
40
41You generate the metafunction by invoking the macro with the name
42of an inner type:
43
44 BOOST_TTI_HAS_TYPE(AType)
45
46generates a metafunction called 'has_type_AType' in the current scope.
47
48[heading Invoking the metafunction]
49
50You invoke the metafunction by instantiating the template with an enclosing
51type to introspect and, optionally, an MPL lambda expression.
52A return value called 'value' is a compile time bool constant.
53
54 has_type_AType<Enclosing_Type>::value
55 has_type_AType<Enclosing_Type,ALambdaExpression>::value
56
57[heading Examples]
58
59First we generate metafunctions for various inner type names:
60
61 #include <boost/tti/has_type.hpp>
62
63 BOOST_TTI_HAS_TYPE(MyTypeDef)
64 BOOST_TTI_HAS_TYPE(AType)
65 BOOST_TTI_HAS_TYPE(ATypeDef)
66 BOOST_TTI_HAS_TYPE(MyType)
67
68Next let us create some user-defined types we want to introspect.
69
70 struct Top
71 {
72 typedef int MyTypeDef;
73 struct AType { };
74 };
75 struct Top2
76 {
77 typedef long ATypeDef;
78 struct MyType { };
79 };
80
81Finally we invoke our metafunction and return our value.
82
83 has_type_MyTypeDef<Top>::value; // true
84 has_type_MyTypeDef<Top2>::value; // false
85
86 has_type_AType<Top>::value; // true
87 has_type_AType<Top2>::value; // false
88
89 has_type_ATypeDef<Top>::value; // false
90 has_type_ATypeDef<Top2>::value; // true
91
92 has_type_MyType<Top>::value; // false
93 has_type_MyType<Top2>::value; // true
94
95[heading Examples - using lambda expressions]
96
97We can further invoke our metafunction with a second type,
98which is an MPL lambda expression.
99
100An MPL lambda expression, an extremely useful technique in
101template metaprogramming, allows us to pass a metafunction to
102other metafunctions. The metafunction we pass can be in the form
103of a placeholder expression or a metafunction class. In our case
104the metafunction passed to our has_type_'name_of_inner_type'
105metafunction as a lambda expression must return a boolean constant
106expression.
107
108[heading Example - using a lambda expression with a placeholder expression]
109
110We will first illustrate the use of a lambda expression in the
111form of a placeholder expression being passed as the second template
112parameter to our has_type_'name_of_inner_type' metafunction.
113A popular and simple placeholder expression we can use is
114'boost::is_same<_1,SomeType>' to check if the inner type found is a
115particular type. This is particularly useful when the inner type
116is a typedef for some other type.
117
118First we include some more header files and a using declaration
119for convenience.
120
121 #include <boost/mpl/placeholders.hpp
122 #include <boost/type_traits/is_same.hpp
123 using namespace boost::mpl::placeholders;
124
125Next we invoke our metafunction:
126
127 has_type_MyTypeDef<Top,boost::is_same<_1,int> >::value; // true
128 has_type_MyTypeDef<Top,boost::is_same<_1,long> >::value; // false
129
130 has_type_ATypeDef<Top2,boost::is_same<_1,int> >::value; // false
131 has_type_ATypeDef<Top2,boost::is_same<_1,long> >::value; // true
132
133[heading Example - using a lambda expression with a metafunction class]
134
135We will next illustrate the use of a lambda expression in the
136form of a metafunction class being passed as the second template
137parameter to our has_type_'name_of_inner_type' metafunction.
138
139A metafunction class is a type which has a nested class template
140called 'apply'. For our metafunction class example we will check if the
141inner type is a built-in integer type. First let us write out
142metafunction class:
143
144 #include <boost/type_traits/is_integral.hpp>
145
146 class OurMetafunctionClass
147 {
148 template<class T> struct apply :
149 boost::is_integral<T>
150 {
151 };
152 };
153
154Now we can invoke our metafunction:
155
156 has_type_MyTypeDef<Top,OurMetafunctionClass>::value; // true
157 has_type_AType<Top,OurMetafunctionClass>::value; // false
158
159 has_type_ATypeDef<Top2,OurMetafunctionClass>::value; // true
160 has_type_MyType<Top2,OurMetafunctionClass>::value; // true
161
162[heading Metafunction re-use]
163
164The macro encodes only the name of the inner type for which
165we are searching and the fact that we are introspecting for
166an inner type within an enclosing type.
167
168Because of this, once we create our metafunction for
169introspecting an inner type by name, we can reuse the
170metafunction for introspecting any enclosing type, having
171any inner type, for that name.
172
173Furthermore since we have only encoded the name of the inner
174type for which we are introspecting, we can not only introspect
175for that inner type by name but add different lambda expressions
176to inspect that inner type for whatever we want to find out about
177it using the same metafunction.
178
179[endsect]