Skip to content

Commit

Permalink
Updated documentation for BOOST_HAS_DATA and BOOST_HAS_FUNCTION
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.boost.org/svn/boost/trunk@82186 b8fc166d-592f-0410-95f2-cb63ce0dd405
  • Loading branch information
eldiener committed Dec 23, 2012
1 parent 20bdb3f commit 8c74487
Show file tree
Hide file tree
Showing 14 changed files with 276 additions and 28 deletions.
2 changes: 2 additions & 0 deletions libs/tti/doc/tti.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
[include tti_detail_has_member_function.qbk]
[include tti_detail_has_static_member_data.qbk]
[include tti_detail_has_static_member_function.qbk]
[include tti_detail_has_data.qbk]
[include tti_detail_has_function.qbk]
[include tti_nested_type.qbk]
[include tti_nested_type_and_signatures.qbk]
[include tti_using_mm.qbk]
Expand Down
37 changes: 36 additions & 1 deletion libs/tti/doc/tti_detail.qbk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[/
(C) Copyright Edward Diener 2011
(C) Copyright Edward Diener 2011,2012
Use, modification and distribution are subject to 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).
Expand Down Expand Up @@ -205,6 +205,41 @@ of the boolean constant value. This is always boost::mpl::bool_.
]
[[headerref boost/tti/has_static_member_function.hpp `has_static_member_function.hpp`]]
]
[
[Data, either member data or static member data]
[
[macroref BOOST_TTI_HAS_DATA](name)
]
[
`has_data_'name'`

class TTI_T = enclosing type

class TTI_Type = data type
]
[[headerref boost/tti/has_data.hpp `has_data.hpp`]]
]
[
[Function, either member function or static member function]
[
[macroref BOOST_TTI_HAS_FUNCTION](name)
]
[
`has_function_'name'`

class TTI_T = enclosing type

class TTI_R = return type

class TTI_FS = (optional) function parameter types as a Boost MPL forward sequence.
If there are no function parameters, this does not have to be specified.
Defaults to boost::mpl::vector<>.

class TTI_TAG = (optional) Boost `function_types` tag type.
Defaults to `boost::function_types::null_tag`.
]
[[headerref boost/tti/has_function.hpp `has_function.hpp`]]
]
]

[endsect]
96 changes: 96 additions & 0 deletions libs/tti/doc/tti_detail_has_data.qbk
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
[/
(C) Copyright Edward Diener 2012
Use, modification and distribution are subject to 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]
104 changes: 104 additions & 0 deletions libs/tti/doc/tti_detail_has_function.qbk
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
[/
(C) Copyright Edward Diener 2012
Use, modification and distribution are subject to 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_function Introspecting an inner function]

The TTI macro [macroref BOOST_TTI_HAS_FUNCTION] introspects
an inner function of a class. The function can be either a member
function or a static member function.

BOOST_TTI_HAS_FUNCTION takes a single
parameter which is the name of an inner function whose existence
the programmer wants to check. The macro generates a metafunction
called 'has_function_'name_of_inner_function'.

The metafunction can be invoked by passing it the enclosing type to introspect and a
signature for the function as separate template arguments. The signature for the
function consists of a return type, optional parameter types in the form of a boost::mpl
forward sequence of types, and an optional Boost FunctionTypes tag type. A
typical boost::mpl forward sequence of types is a boost::mpl::vector<>.

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
function, of the specified signature, exists or not.

[heading Generating the metafunction]

You generate the metafunction by invoking the macro with the name
of an inner function:

BOOST_TTI_HAS_FUNCTION(AnInnerFunction)

generates a metafunction called 'has_function_AnInnerFunction' in the current scope.

[heading Invoking the metafunction]

You invoke the metafunction by instantiating the template with an enclosing
type to introspect and the signature of the function as a series of template
parameters.

A return value called 'value' is a compile time bool constant.

has_function_AnInnerFunction
<
Enclosing_Type,
Function_ReturnType,
boost::mpl::vector<Function_ParameterTypes>, // optional, can be any mpl forward sequence
boost::function_types::SomeTagType // optional, can be any FunctionTypes tag type
>::value

[heading Examples]

First we generate metafunctions for various inner function names:

#include <boost/tti/has_function.hpp>

BOOST_TTI_HAS_FUNCTION(function1)
BOOST_TTI_HAS_FUNCTION(function2)
BOOST_TTI_HAS_FUNCTION(function3)

Next let us create some user-defined types we want to introspect.

struct AClass { };
struct Top
{
static int function1();
AClass function2(double,short *);
};
struct Top2
{
long function2(Top &,int,bool,short,float);
static Top * function3(long,int,AClass &);
};

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_function_function1<Top,int>::value; // true
has_function_function1<Top2,int>::value; // false

has_function_function2<Top,AClass,boost::mpl::vector<double,short *> >::value; // true
has_function_function2<Top2,AClass,boost::mpl::vector<double,short *> >::value; // false

has_function_function3<Top2,int>::value; // false
has_function_function3<Top2,Top *,boost::mpl::vector<long,int,AClass &> >::value; // true;

[heading Metafunction re-use]

The macro encodes only the name of the function
for which we are searching and the fact that we are
introspecting for a function within an enclosing type.

Because of this, once we create our metafunction for
introspecting a function by name, we can reuse the
metafunction for introspecting any enclosing type, having any
function, for that name.

[endsect]
2 changes: 1 addition & 1 deletion libs/tti/doc/tti_detail_has_member_data.qbk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[/
(C) Copyright Edward Diener 2011
(C) Copyright Edward Diener 2011,2012
Use, modification and distribution are subject to 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).
Expand Down
2 changes: 1 addition & 1 deletion libs/tti/doc/tti_detail_has_member_function.qbk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[/
(C) Copyright Edward Diener 2011
(C) Copyright Edward Diener 2011,2012
Use, modification and distribution are subject to 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).
Expand Down
2 changes: 1 addition & 1 deletion libs/tti/doc/tti_detail_has_static_member_data.qbk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[/
(C) Copyright Edward Diener 2011
(C) Copyright Edward Diener 2011,2012
Use, modification and distribution are subject to 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).
Expand Down
2 changes: 1 addition & 1 deletion libs/tti/doc/tti_detail_has_static_member_function.qbk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[/
(C) Copyright Edward Diener 2011
(C) Copyright Edward Diener 2011,2012
Use, modification and distribution are subject to 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).
Expand Down
2 changes: 1 addition & 1 deletion libs/tti/doc/tti_detail_has_template.qbk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[/
(C) Copyright Edward Diener 2011
(C) Copyright Edward Diener 2011,2012
Use, modification and distribution are subject to 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).
Expand Down
33 changes: 18 additions & 15 deletions libs/tti/doc/tti_functionality.qbk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[/
(C) Copyright Edward Diener 2011
(C) Copyright Edward Diener 2011,2012
Use, modification and distribution are subject to 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).
Expand All @@ -11,21 +11,24 @@ The elements of a type about which a template metaprogrammer might be interested
out at compile time are:

* Does it have a nested type with a particular name ?
* Does it have a nested type with a particular name which is also a typedef for a particular type ?
* Does it have a nested type with a particular name which fulfills some other possibility for that nested type.
* Does it have a nested class template with a particular name ?
* Does it have a nested class template with a particular name and a particular signature ?
* Does it have a member function with a particular name and a particular signature ?
* Does it have a member data with a particular name and of a particular type ?
* Does it have member data with a particular name and of a particular type ?
* Does it have a static member function with a particular name and a particular signature ?
* Does it have a static member data with a particular name and of a particular type ?

These are the compile-time questions which the TTI library answers. It does this
by creating metafunctions, which can be used at compile-time, using C++ macros.
Each of the metafunctions created returns a compile time constant bool value
which answers one of the above questions at compile time. When the particular
element above exists the value is 'true', or more precisely boost::mpl::true_,
while if the element does not exist the value is 'false', or more precisely
boost::mpl::false_. In either case the type of this value is boost::mpl::bool_.
* Does it have static member data with a particular name and of a particular type ?
* Does it have either member data or static member data with a particular name and of a particular type ?
* Does it have either a member function or static member function with a particular name and of a particular type ?

These are some of the compile-time questions which the TTI library answers. It
does this by creating metafunctions, which can be used at compile-time, using
C++ macros. Each of the metafunctions created returns a compile time constant
bool value which answers one of the above questions at compile time. When the
particular element above exists the value is 'true', or more precisely
boost::mpl::true_, while if the element does not exist the value is 'false',
or more precisely boost::mpl::false_. In either case the type of this value
is boost::mpl::bool_.

This constant bool value, in the terminology of the Boost MPL library, is called an 'integral
constant wrapper' and the metafunction generated is called a 'numerical metafunction'. The
Expand Down Expand Up @@ -75,11 +78,11 @@ is to expand to the metafunction name. The naming macro for each macro metafunct

As an example, BOOST_TTI_HAS_TYPE(MyType) creates a metafunction
which looks for a nested type called 'MyType' within some enclosing type. The name of the metafunction
generated, given our algorithm above is 'has_type_MyType'. A corresponding macro called
generated, given our rule above is 'has_type_MyType'. A corresponding macro called
BOOST_TTI_HAS_TYPE_GEN, invoked as BOOST_TTI_HAS_TYPE_GEN(MyType) in our example, expands to the
same 'has_type_MyType' name. These name generating macros, for each of the metafunction generating macros,
are purely a convenience for end-users who find using them easier than remembering the name-generating
algorithm given above.
rule given above.

[section:tti_functionality_nm_gen Macro metafunction name generation considerations]

Expand Down Expand Up @@ -132,7 +135,7 @@ type which is nested within 'AType'.
# 'has_type_InnerType<BType>::value' is a compile time constant telling us whether 'InnerType' is a
type which is nested within 'BType'.

As another example of this let's consider a single type, called 'CType', for which we want to
As another example of metafunction reuse let's consider a single type, called 'CType', for which we want to
determine if it has either of two overloaded member functions with the same name of 'AMemberFunction'
but with the different function signatures of 'int (int)' and 'double (long)'. For both these
member functions we need only generate a single macro metafunction in the current scope by using:
Expand Down
Loading

0 comments on commit 8c74487

Please sign in to comment.