| 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, this could also be a class or a union

    struct AType
      {

      // Type

      typedef int AnIntType; // as a typedef

      // Class/Struct

      struct BType // as a nested struct
        {
        struct CType
          {
          };
        };

      class AClass // as a nested class
        {
        };

      // Enumeration

      enum EColor // as a nested enumeration
        {
        Red,
        Blue,
        Green
        };

      // Union

      union AUnion // as a nested union
        {
        int i;
        long l;
        };

      // Class 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; }

      // Const Function

      long AnotherFunction(bool,double) const { return 0L; }

      // Function Template

      template<class X, class Y, int Z> int MyFunctionTemplate(X *, Y &) { return Z; }

      // Const Function Template

      template<class X, int Y, class Z> int AnotherFunctionTemplate(X &, Z **) const { return Y; }

      // Static Data

      static short DSMember;

      // Static Function

      static int SIntFunction(long,double) { return 2; }

      // Static Function Template

      template<class A, class B> static long SFunctionTemplate(long &,A **,B,float) { return 20L; }

      };

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. Also in these examples we are showing results which return the compile time boolean result of 'true' to illustrate how our macro metafunctions work. We could just as well create examples which return the compile time boolean result of 'false' if we introspect for constructs that do not exist in our hypothetical type of T. We can validly return 'true' or 'false' without generating compiler errors as long as the types using in our macro metafunction invocations exist at the time we invoke the metafunction.

#### Type

C++ named types can be typedefs or type aliases, class, structs, unions, or enumerations

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
      >

Does T have a nested type called 'AClass' ?

    BOOST_TTI_HAS_TYPE(AClass)

    has_type_ACLass
      <
      T
      >

Does T have a nested type called 'EColor' ?

    BOOST_TTI_HAS_TYPE(EColor)

    has_type_EColor
      <
      T
      >

Does T have a nested type called 'AUnion' ?

    BOOST_TTI_HAS_TYPE(AUnion)

    has_type_AUnion
      <
      T
      >

#### Type checking the typedef using an MPL 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>
      >

#### Class/Struct

Does T have a nested class called 'AClass' ?

    BOOST_TTI_HAS_CLASS(AClass)

    has_class_AClass
      <
      T
      >

Does T have a nested struct called 'BType' ?

    BOOST_TTI_HAS_CLASS(BType)

    has_class_BType
      <
      T
      >

You can also use an MPL lambda expression with a class/struct just as you can with a general type.

#### Enumeration

Does T have a nested enumeration called 'EColor' ?

    BOOST_TTI_HAS_ENUM(EColor)

    has_enum_EColor
      <
      T
      >

You can also use an MPL lambda expression with an enumeration just as you can with a general type.

#### Union

Does T have a nested union called 'AUnion' ?

    BOOST_TTI_HAS_UNION(AUnion)

    has_union_AUnion
      <
      T
      >

You can also use an MPL lambda expression with a union just as you can with a general type.

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

#### Const member function with individual types

Does T have a member function called 'AnotherFunction' whose type is 'long (bool,double) const' ?

    BOOST_TTI_HAS_MEMBER_FUNCTION(AnotherFunction)

    has_member_function_AnotherFunction
      <
      T,
      long,
      boost::mpl::vector<bool,double>,
      boost::function_types::const_qualified
      >

#### Const member function with composite type

Does T have a member function called 'AnotherFunction' whose type is 'long (bool,double) const' ?

    BOOST_TTI_HAS_MEMBER_FUNCTION(AnotherFunction)

    has_member_function_AnotherFunction
      <
      long (T::*) (bool,double) const
      >

#### Member function template with individual types

Does T have a member function template called 'MyFunctionTemplate' woth an instantiated signature of 'int MyFunctionTemplate<short,float,579>(short *,float &)' ?

    BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(MyFunctionTemplate,short,float,579)

    has_member_function_MyFunctionTemplate
      <
      T,
      int,
      boost::mpl::vector<short *,float &>
      >

#### Member function template with composite type

Does T have a member function template called 'MyFunctionTemplate' woth an instantiated signature of 'int MyFunctionTemplate<int,long,183>(int *,long &)' ?

    BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(MyFunctionTemplate,int,long,183)

    has_member_function_template_MyFunctionTemplate
      <
      int (T::*)(int *,long &)
      >

#### Const member function template with individual types

Does T have a member function template called 'AnotherFunctionTemplate' with an instantiated signature of 'int AnotherFunctionTemplate<bool,8359,double>(bool &,double **) const' ?

    BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(AnotherFunctionTemplate,bool,8359,double)

    has_member_function_AnotherFunctionTemplate
      <
      T,
      int,
      boost::mpl::vector<bool &,double **>,
      boost::function_types::const_qualified
      >

#### Const member function template with composite type

Does T have a member function template called 'AnotherFunctionTemplate' with an instantiated signature of 'int AnotherFunctionTemplate<bool,8359,double>(bool &,double **) const' ?

    BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(AnotherFunctionTemplate,bool,8359,double)

    has_member_function_template_MyFunctionTemplate
      <
      int (T::*)(bool &,double **) const
      >

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

#### Static member function template with individual types

Does T have a static member function template called 'SFunctionTemplate' with an instantiated signature of 'long SFunctionTemplate<char,unsigned>(long &,char **,unsigned,float)' ?

    BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION_TEMPLATE(SFunctionTemplate,char,unsigned)

    has_static_member_function_template_SFunctionTemplate
      <
      T,
      long,
      boost::mpl::vector<long &,char **,unsigned,float>
      >

#### Static member function template with composite type

Does T have a static member function template called 'SFunctionTemplate' with an instantiated signature of 'long SFunctionTemplate<bool,int>(long &,bool **,int,float)' ?

    BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION_TEMPLATE(SFunctionTemplate,bool,int)

    has_static_member_function_template_SFunctionTemplate
      <
      T,
      long (long &,bool **,int,float)
      >

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

#### Function Template

Does T have a member function template or a static member function template called 'MyFunctionTemplate' with an instantiated signature of 'int MyFunctionTemplate<bool,short,3487>(bool *,short &)' ?

    BOOST_TTI_HAS_FUNCTION_TEMPLATE(MyFunctionTemplate,bool,short,3487)

    has_function_template_MyFunctionTemplate
      <
      T,
      int,
      boost::mpl::vector<bool *,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
      >