An example using the Macro Metafunctions

| Home | Libraries | People | FAQ | More

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