Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

An example using the Macro Metafunctions

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.

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
  >

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>
  >

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
  >

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
  >

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
  >

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
  >

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
  >

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::*
  >

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>
  >

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)
  >

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
  >

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>
  >

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)
  >

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
  >

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>
  >

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

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
  >

PrevUpHomeNext