| [/ |
| (C) Copyright Edward Diener 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_data Introspecting inner data] |
| |
| The TTI macro [macroref BOOST_TTI_HAS_DATA] introspects the data of a class. |
| The data can be member data or static member data. |
| |
| BOOST_TTI_HAS_DATA macro takes a single parameter, which is the name |
| of an inner member data or static member data, whose existence |
| the programmer wants to check. The macro generates a metafunction |
| called 'has_data_'name_of_inner_data'. |
| |
| The metafunction can be invoked by passing it the enclosing type |
| to introspect and the type of the data. |
| |
| 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 is true or false depending on whether the inner |
| 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 data member: |
| |
| BOOST_TTI_HAS_DATA(AData) |
| |
| generates a metafunction called 'has_data_AStaticMemberData' 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 data. A return value called |
| 'value' is a compile time bool constant. |
| |
| has_data_AData<Enclosing_Type,Data_Type>::value |
| |
| [heading Examples] |
| |
| First we generate metafunctions for various inner data names: |
| |
| #include <boost/tti/has_data.hpp> |
| |
| BOOST_TTI_HAS_DATA(data1) |
| BOOST_TTI_HAS_DATA(data2) |
| BOOST_TTI_HAS_DATA(data3) |
| |
| Next let us create some user-defined types we want to introspect. |
| |
| struct AClass |
| { |
| }; |
| struct Top |
| { |
| int data1; |
| static AClass * data2; |
| }; |
| struct Top2 |
| { |
| static 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. |
| |
| has_data_data1<Top,int>::value; // true |
| has_data_data1<Top,long>::value; // false |
| has_data_data1<Top2,int>::value; // false |
| has_data_data1<Top2,long>::value; // true |
| |
| has_data_data2<Top,AClass *>::value; // true |
| has_data_data2<Top,int *>::value; // false |
| |
| has_data_data3<Top2,int>::value; // false |
| has_data_data3<Top2,Top>::value; // true; |
| |
| [heading Metafunction re-use] |
| |
| The macro encodes only the name of the data for |
| which we are searching and the fact that we are introspecting |
| for data within an enclosing type. |
| |
| Because of this, once we create our metafunction for |
| introspecting an inner data by name, we can reuse |
| the metafunction for introspecting any enclosing type, having |
| any inner data type, for that name. |
| |
| [endsect] |