e781f75d7b
[SVN r84423]
316 lines
6.5 KiB
Plaintext
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]
|