116 lines
3.5 KiB
Plaintext
116 lines
3.5 KiB
Plaintext
[/
|
|
(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_member_data Introspecting member data]
|
|
|
|
The TTI macro [macroref BOOST_TTI_HAS_MEMBER_DATA] introspects
|
|
member data of a class.
|
|
|
|
BOOST_TTI_HAS_MEMBER_DATA macro takes a single
|
|
parameter which is the name of an inner member data whose existence
|
|
the programmer wants to check. The macro generates a metafunction
|
|
called "has_member_data_'name_of_inner_member_data'".
|
|
|
|
The metafunction can be invoked in two different ways.
|
|
|
|
The first way is by passing it two parameters. The first parameter
|
|
is the enclosing type to introspect and the second parameter is the
|
|
type of the member data.
|
|
|
|
The second way is by passing it a single parameter, which is a pointer
|
|
to member type. This type has the form of:
|
|
|
|
MemberData_Type Enclosing_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 value is true or false depending on whether the
|
|
inner member data, of the specified type, exists or not.
|
|
|
|
[heading Generating the metafunction]
|
|
|
|
You generate the metafunction by invoking the macro with the name
|
|
of an inner member data:
|
|
|
|
BOOST_TTI_HAS_MEMBER_DATA(AMemberData)
|
|
|
|
generates a metafunction called 'has_member_data_AMemberData' in the current scope.
|
|
|
|
[heading Invoking the metafunction]
|
|
|
|
You invoke the metafunction by instantiating the template with an enclosing
|
|
type to introspect and the type of the member data, or by instantiating the
|
|
template with a pointer to member data type. The return value called 'value'
|
|
is a compile time bool constant telling you whether or not the member data .
|
|
exists.
|
|
|
|
has_member_data_AMemberData<Enclosing_Type,MemberData_Type>::value
|
|
|
|
OR
|
|
|
|
has_member_data_AMemberData<MemberData_Type Enclosing_Type::*>::value
|
|
|
|
[heading Examples]
|
|
|
|
First we generate metafunctions for various inner member data names:
|
|
|
|
#include <boost/tti/has_member_data.hpp>
|
|
|
|
BOOST_TTI_HAS_MEMBER_DATA(data1)
|
|
BOOST_TTI_HAS_MEMBER_DATA(data2)
|
|
BOOST_TTI_HAS_MEMBER_DATA(data3)
|
|
|
|
Next let us create some user-defined types we want to introspect.
|
|
|
|
struct AClass
|
|
{
|
|
};
|
|
struct Top
|
|
{
|
|
int data1;
|
|
AClass * data2;
|
|
};
|
|
struct Top2
|
|
{
|
|
long data1;
|
|
Top data3;
|
|
};
|
|
|
|
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_data_data1<Top,int>::value; // true
|
|
has_member_data_data1<Top,long>::value; // false
|
|
|
|
has_member_data_data1<Top2,int>::value; // false
|
|
has_member_data_data1<long Top2::*>::value; // true
|
|
|
|
has_member_data_data2<AClass * Top::*>::value; // true
|
|
has_member_data_data2<Top,int *>::value; // false
|
|
|
|
has_member_data_data3<int Top2::*>::value; // false
|
|
has_member_data_data3<Top Top2::*>::value; // true;
|
|
|
|
[heading Metafunction re-use]
|
|
|
|
The macro encodes only the name of the member data for which
|
|
we are searching and the fact that we are introspecting for
|
|
member data within an enclosing type.
|
|
|
|
Because of this, once we create our metafunction for
|
|
introspecting an inner member data by name, we can reuse the
|
|
metafunction for introspecting any enclosing type, having any
|
|
inner member data type, for that name.
|
|
|
|
[endsect]
|