tti/doc/tti_using_mm.qbk
2013-05-22 18:30:10 +00:00

316 lines
6.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_usingMM An example using the Macro Metafunctions]
[#sectti_usingMM]
Using the macro metafunctions can be illustrated by first creating some hypothetical
user-defined type with corresponding nested types and other inner elements.
With this type we can illustrate the use of the macro metafunctions. This is
just meant to serve as a model for what a type T might entail from within
a class or function template where 'T' is a type passed to the template.
// An enclosing type
struct AType
{
// Type
typedef int AnIntType; // as a typedef
struct BType // as a nested type
{
struct CType
{
};
};
// Template
template <class> struct AMemberTemplate { };
template <class,class,class> struct AnotherMemberTemplate { };
template <class,class,int,class,template <class> class,class,long> struct ManyParameters { };
template <class,class,int,short,class,template <class,int> class,class> struct MoreParameters { };
// Data
BType IntBT;
// Function
int IntFunction(short) { return 0; }
// Static Data
static short DSMember;
// Static Function
static int SIntFunction(long,double) { return 2; }
};
I will be using the type above just to illustrate the sort of
metaprogramming questions we can ask of some type T which is passed
to the template programmer in a class template. Here is what the
class template might look like:
#include <boost/tti/tti.hpp>
template<class T>
struct OurTemplateClass
{
// compile-time template code regarding T
};
Now let us create and invoke the macro metafunctions for each of our inner element types,
to see if type T above corresponds to our hypothetical type above. Imagine this being
within 'OurTemplateClass' above. In the examples below the same macro is invoked just once
to avoid ODR violations.
[heading Type]
Does T have a nested type called 'AnIntType' ?
BOOST_TTI_HAS_TYPE(AnIntType)
has_type_AnIntType
<
T
>
Does T have a nested type called 'BType' ?
BOOST_TTI_HAS_TYPE(BType)
has_type_BType
<
T
>
[heading Type checking the typedef using a lambda expression]
Does T have a nested typedef called 'AnIntType' whose type is an 'int' ?
#include <boost/mpl/placeholders.hpp
#include <boost/type_traits/is_same.hpp
using namespace boost::mpl::placeholders;
has_type_AnIntType
<
T,
boost::is_same<_1,int>
>
[heading Template]
Does T have a nested class template called 'AMemberTemplate' whose template
parameters are all types ('class' or 'typename') ?
BOOST_TTI_HAS_TEMPLATE(AMemberTemplate,BOOST_PP_NIL)
has_template_AMemberTemplate
<
T
>
[heading Template using variadic macros]
Does T have a nested class template called 'AMemberTemplate' whose template
parameters are all types ('class' or 'typename') ?
BOOST_TTI_HAS_TEMPLATE(AnotherMemberTemplate)
has_template_AnotherMemberTemplate
<
T
>
[heading Template with params]
Does T have a nested class template called 'MoreParameters' whose template
parameters are specified exactly ?
BOOST_TTI_HAS_TEMPLATE(MoreParameters,(8,(class,class,int,short,class,template <class,int> class,class)))
has_template_MoreParameters
<
T
>
[heading Template with params using variadic macros]
Does T have a nested class template called 'ManyParameters' whose template
parameters are specified exactly ?
BOOST_TTI_HAS_TEMPLATE(ManyParameters,class,class,int,class,template <class> class,class,long)
has_template_ManyParameters
<
T
>
[heading Member data]
Does T have a member data called 'IntBT' whose type is 'AType::BType' ?
BOOST_TTI_HAS_MEMBER_DATA(IntBT)
has_member_data_IntBT
<
T,
AType::BType
>
[heading Member data with composite type]
Does T have a member data called 'IntBT' whose type is 'AType::BType' ?
BOOST_TTI_HAS_MEMBER_DATA(IntBT)
has_member_data_IntBT
<
AType::BType T::*
>
[heading Member function with individual types]
Does T have a member function called 'IntFunction' whose type is
'int (short)' ?
BOOST_TTI_HAS_MEMBER_FUNCTION(IntFunction)
has_member_function_IntFunction
<
T,
int,
boost::mpl::vector<short>
>
[heading Member function with composite type]
Does T have a member function called 'IntFunction' whose type is
'int (short)' ?
BOOST_TTI_HAS_MEMBER_FUNCTION(IntFunction)
has_member_function_IntFunction
<
int (T::*)(short)
>
[heading Static member data]
Does T have a static member data called 'DSMember' whose type is 'short' ?
BOOST_TTI_HAS_STATIC_MEMBER_DATA(DSMember)
has_static_member_data_DSMember
<
T,
short
>
[heading Static member function with individual types]
Does T have a static member function called 'SIntFunction' whose type
is 'int (long,double)' ?
BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(SIntFunction)
has_static_member_function_SIntFunction
<
T,
int,
boost::mpl::vector<long,double>
>
[heading Static member function with composite type]
Does T have a static member function called 'SIntFunction' whose type
is 'int (long,double)' ?
BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(SIntFunction)
has_static_member_function_SIntFunction
<
T,
int (long,double)
>
[heading Data]
Does T have a member data or static member data called 'DSMember' whose type is 'short' ?
BOOST_TTI_HAS_DATA(DSMember)
has_static_member_data_DSMember
<
T,
short
>
[heading Function]
Does T have a member function or a static member function called 'IntFunction' whose type is
'int (short)' ?
BOOST_TTI_HAS_FUNCTION(IntFunction)
has_function_IntFunction
<
T,
int,
boost::mpl::vector<short>
>
[heading Member type]
Create a nested type T::BType::CType without creating a compiler error
if T does not have the nested type BType::CType ?
BOOST_TTI_MEMBER_TYPE(BType)
BOOST_TTI_MEMBER_TYPE(CType)
typename
member_type_CType
<
typename
member_type_BType
<
T
>::type
>::type
[heading Member type existence]
Does a nested type T::BType::CType, created without creating a compiler error
if T does not have the nested type BType::CType, actually exist ?
BOOST_TTI_MEMBER_TYPE(BType)
BOOST_TTI_MEMBER_TYPE(CType)
typedef typename
member_type_CType
<
typename
member_type_BType
<
T
>::type
>::type
AType;
boost::tti::valid_member_type
<
AType
>
[endsect]