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