| [/ |
| (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] |