...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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.
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 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> >
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 >
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 >
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 >
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 >
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 >
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::* >
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> >
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) >
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 >
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> >
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) >
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 >
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> >
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
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 >