Chris@16: Chris@16: // (C) Copyright Edward Diener 2011,2012 Chris@16: // Use, modification and distribution are subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt). Chris@16: Chris@16: /* Chris@16: Chris@16: The succeeding comments in this file are in doxygen format. Chris@16: Chris@16: */ Chris@16: Chris@16: /** \file Chris@16: */ Chris@16: Chris@16: #if !defined(BOOST_TTI_HAS_TEMPLATE_HPP) Chris@16: #define BOOST_TTI_HAS_TEMPLATE_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if BOOST_PP_VARIADICS Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /// Expands to a metafunction which tests whether an inner class template with a particular name exists. Chris@16: /** Chris@16: Chris@16: trait = the name of the metafunction. Chris@16: ... = variadic parameters. Chris@16: Chris@16: The first variadic parameter is the inner class template name. Chris@16: Chris@16: Following variadic parameters are optional. Chris@16: Chris@16: If no following variadic parameters exist, then the inner class template Chris@16: being introspected must be all template type parameters ( template parameters Chris@16: starting with `class` or `typename` ) and any number of template type parameters Chris@16: can occur. Chris@16: Chris@16: If the second variadic parameter is BOOST_PP_NIL and no other variadic Chris@16: parameter is given, then just as in the previous case the inner class template Chris@16: being introspected must be all template type parameters ( template parameters Chris@16: starting with `class` or `typename` ) and any number of template type parameters Chris@16: can occur. This form is allowed in order to be consistent with using the Chris@16: non-variadic form of this macro. Chris@16: Chris@16: If the second variadic parameter is a Boost preprocessor library array and no other Chris@16: variadic parameter is given, then the inner class template must have its template Chris@16: parameters matching the sequence in the tuple portion of the Boost PP array. This Chris@16: form is allowed in order to be consistent with using the non-variadic form of this Chris@16: macro. Chris@16: Chris@16: Otherwise the inner class template must have its template parameters matching the Chris@16: sequence of the optional variadic parameters. Chris@16: Chris@16: generates a metafunction called "trait" where 'trait' is the first macro parameter. Chris@16: Chris@16: template Chris@16: struct trait Chris@16: { Chris@16: static const value = unspecified; Chris@16: typedef mpl::bool_ type; Chris@16: }; Chris@16: Chris@16: The metafunction types and return: Chris@16: Chris@16: BOOST_TTI_TP_T = the enclosing type in which to look for our 'name'. Chris@16: Chris@16: returns = 'value' is true if the 'name' template exists within the enclosing type, Chris@16: otherwise 'value' is false. Chris@16: Chris@16: Examples: Chris@16: Chris@16: 1) Search for an inner class template called 'MyTemplate', with all template type parameters, Chris@16: nested within the class 'MyClass' using a metafunction name of 'MyMeta'. Chris@16: Chris@16: BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate) Chris@16: Chris@16: or Chris@16: Chris@16: BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,BOOST_PP_NIL) // Non-variadic macro form Chris@16: Chris@16: MyMeta::value Chris@16: Chris@16: is a compile time boolean constant which is either 'true' or 'false' Chris@16: if the nested template exists. Chris@16: Chris@16: 2) Search for an inner class template called 'MyTemplate', with template parameters Chris@16: of 'class T,int x,template class U', nested within the class 'MyClass' Chris@16: using a metafunction name of 'MyMeta'. Chris@16: Chris@16: BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,class,int,template class) Chris@16: Chris@16: or Chris@16: Chris@16: BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,(3,(class,int,template class))) // Non-variadic macro form Chris@16: Chris@16: MyMeta::value Chris@16: Chris@16: is a compile time boolean constant which is either 'true' or 'false' Chris@16: if the nested template exists. Chris@16: Chris@16: */ Chris@16: #define BOOST_TTI_TRAIT_HAS_TEMPLATE(trait,...) \ Chris@16: BOOST_PP_IIF \ Chris@16: ( \ Chris@16: BOOST_PP_EQUAL \ Chris@16: ( \ Chris@16: BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \ Chris@16: 1 \ Chris@16: ), \ Chris@16: BOOST_TTI_DETAIL_VM_TRAIT_HAS_TEMPLATE, \ Chris@16: BOOST_TTI_DETAIL_VM_CHECK_MORE_THAN_TWO \ Chris@16: ) \ Chris@16: (trait,__VA_ARGS__) \ Chris@16: /**/ Chris@16: Chris@16: /// Expands to a metafunction which tests whether an inner class template with a particular name exists. Chris@16: /** Chris@16: Chris@16: ... = variadic parameters. Chris@16: Chris@16: The first variadic parameter is the inner class template name. Chris@16: Chris@16: Following variadic parameters are optional. Chris@16: Chris@16: If no following variadic parameters exist, then the inner class template Chris@16: being introspected must be all template type parameters ( template parameters Chris@16: starting with `class` or `typename` ) and any number of template type parameters Chris@16: can occur. Chris@16: Chris@16: If the second variadic parameter is BOOST_PP_NIL and no other variadic Chris@16: parameter is given, then just as in the previous case the inner class template Chris@16: being introspected must be all template type parameters ( template parameters Chris@16: starting with `class` or `typename` ) and any number of template type parameters Chris@16: can occur. This form is allowed in order to be consistent with using the Chris@16: non-variadic form of this macro. Chris@16: Chris@16: If the second variadic parameter is a Boost preprocessor library array and no other Chris@16: variadic parameter is given, then the inner class template must have its template Chris@16: parameters matching the sequence in the tuple portion of the Boost PP array. This Chris@16: form is allowed in order to be consistent with using the non-variadic form of this Chris@16: macro. Chris@16: Chris@16: Otherwise the inner class template must have its template parameters matching the Chris@16: sequence of the optional variadic parameters. Chris@16: Chris@16: generates a metafunction called "has_template_'name'" where 'name' is the first variadic parameter. Chris@16: Chris@16: template Chris@16: struct has_template_'name' Chris@16: { Chris@16: static const value = unspecified; Chris@16: typedef mpl::bool_ type; Chris@16: }; Chris@16: Chris@16: The metafunction types and return: Chris@16: Chris@16: BOOST_TTI_TP_T = the enclosing type in which to look for our 'name'. Chris@16: Chris@16: returns = 'value' is true if the 'name' template exists within the enclosing type, Chris@16: otherwise 'value' is false. Chris@16: Chris@16: Examples: Chris@16: Chris@16: 1) Search for an inner class template called 'MyTemplate', with all template type parameters, Chris@16: nested within the class 'MyClass'. Chris@16: Chris@16: BOOST_TTI_HAS_TEMPLATE(MyTemplate) Chris@16: Chris@16: or Chris@16: Chris@16: BOOST_TTI_HAS_TEMPLATE(MyTemplate,BOOST_PP_NIL) // Non-variadic macro form Chris@16: Chris@16: has_template_MyTemplate::value Chris@16: Chris@16: is a compile time boolean constant which is either 'true' or 'false' Chris@16: if the nested template exists. Chris@16: Chris@16: 2) Search for an inner class template called 'MyTemplate' with template parameters Chris@16: of 'class T,int x,template class U' nested within the class 'MyClass'. Chris@16: Chris@16: BOOST_TTI_HAS_TEMPLATE(MyTemplate,class,int,template class) Chris@16: Chris@16: or Chris@16: Chris@16: BOOST_TTI_HAS_TEMPLATE(MyTemplate,(3,(class,int,template class))) // Non-variadic macro form Chris@16: Chris@16: has_template_MyTemplate::value Chris@16: Chris@16: is a compile time boolean constant which is either 'true' or 'false' Chris@16: if the nested template exists. Chris@16: Chris@16: */ Chris@16: #define BOOST_TTI_HAS_TEMPLATE(...) \ Chris@16: BOOST_TTI_TRAIT_HAS_TEMPLATE \ Chris@16: ( \ Chris@16: BOOST_TTI_HAS_TEMPLATE_GEN \ Chris@16: ( \ Chris@16: BOOST_PP_VARIADIC_ELEM(0,__VA_ARGS__) \ Chris@16: ), \ Chris@16: __VA_ARGS__ \ Chris@16: ) \ Chris@16: /**/ Chris@16: Chris@16: #else // !BOOST_PP_VARIADICS Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /// Expands to a metafunction which tests whether an inner class template with a particular name exists. Chris@16: /** Chris@16: Chris@16: trait = the name of the metafunction. Chris@16: name = the inner class template name. Chris@16: params = If the parameter is BOOST_PP_NIL the inner class template Chris@16: being introspected must be all template type parameters ( template parameters Chris@16: starting with `class` or `typename` ) and any number of template type parameters Chris@16: can occur. Chris@16: Chris@16: If the parameter is a Boost preprocessor library array, then the inner class Chris@16: template must have its template parameters matching the sequence in the tuple portion Chris@16: of the Boost PP array. Chris@16: Chris@16: Otherwise a compiler error occurs. Chris@16: Chris@16: generates a metafunction called "trait" where 'trait' is the first macro parameter. Chris@16: Chris@16: template Chris@16: struct trait Chris@16: { Chris@16: static const value = unspecified; Chris@16: typedef mpl::bool_ type; Chris@16: }; Chris@16: Chris@16: The metafunction types and return: Chris@16: Chris@16: BOOST_TTI_TP_T = the enclosing type in which to look for our 'name'. Chris@16: Chris@16: returns = 'value' is true if the 'name' template exists within the enclosing type, Chris@16: otherwise 'value' is false. Chris@16: Chris@16: Examples: Chris@16: Chris@16: 1) Search for an inner class template called 'MyTemplate', with all template type parameters, Chris@16: nested within the class 'MyClass' using a metafunction name of 'MyMeta'. Chris@16: Chris@16: BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,BOOST_PP_NIL) Chris@16: Chris@16: MyMeta::value Chris@16: Chris@16: is a compile time boolean constant which is either 'true' or 'false' Chris@16: if the nested template exists. Chris@16: Chris@16: 2) Search for an inner class template called 'MyTemplate', with template parameters Chris@16: of 'class T,int x,template class U', nested within the class 'MyClass' Chris@16: using a metafunction name of 'MyMeta'. Chris@16: Chris@16: BOOST_TTI_TRAIT_HAS_TEMPLATE(MyMeta,MyTemplate,(3,(class,int,template class))) Chris@16: Chris@16: MyMeta::value Chris@16: Chris@16: is a compile time boolean constant which is either 'true' or 'false' Chris@16: if the nested template exists. Chris@16: Chris@16: */ Chris@16: #define BOOST_TTI_TRAIT_HAS_TEMPLATE(trait,name,params) \ Chris@16: BOOST_PP_IIF \ Chris@16: ( \ Chris@16: BOOST_PP_IS_BINARY(params), \ Chris@16: BOOST_TTI_DETAIL_TRAIT_HAS_TEMPLATE_CHECK_PARAMS, \ Chris@16: BOOST_TTI_DETAIL_TRAIT_CHECK_IS_NIL \ Chris@16: ) \ Chris@16: (trait,name,params) \ Chris@16: /**/ Chris@16: Chris@16: /// Expands to a metafunction which tests whether an inner class template with a particular name exists. Chris@16: /** Chris@16: Chris@16: name = the inner class template name. Chris@16: params = If the parameter is BOOST_PP_NIL the inner class template Chris@16: being introspected must be all template type parameters ( template parameters Chris@16: starting with `class` or `typename` ) and any number of template type parameters Chris@16: can occur. Chris@16: Chris@16: If the parameter is a Boost preprocessor library array, then the inner class Chris@16: template must have its template parameters matching the sequence in the tuple portion Chris@16: of the Boost PP array. Chris@16: Chris@16: Otherwise a compiler error occurs. Chris@16: Chris@16: generates a metafunction called "has_template_'name'" where 'name' is the first macro parameter. Chris@16: Chris@16: template Chris@16: struct trait Chris@16: { Chris@16: static const value = unspecified; Chris@16: typedef mpl::bool_ type; Chris@16: }; Chris@16: Chris@16: The metafunction types and return: Chris@16: Chris@16: BOOST_TTI_TP_T = the enclosing type in which to look for our 'name'. Chris@16: Chris@16: returns = 'value' is true if the 'name' template exists within the enclosing type, Chris@16: otherwise 'value' is false. Chris@16: Chris@16: Examples: Chris@16: Chris@16: 1) Search for an inner class template called 'MyTemplate', with all template type parameters, Chris@16: nested within the class 'MyClass'. Chris@16: Chris@16: BOOST_TTI_HAS_TEMPLATE(MyTemplate,BOOST_PP_NIL) Chris@16: Chris@16: has_template_MyTemplate::value Chris@16: Chris@16: is a compile time boolean constant which is either 'true' or 'false' Chris@16: if the nested template exists. Chris@16: Chris@16: 2) Search for an inner class template called 'MyTemplate' with template parameters Chris@16: of 'class T,int x,template class U' nested within the class 'MyClass'. Chris@16: Chris@16: BOOST_TTI_HAS_TEMPLATE(MyTemplate,(3,(class,int,template class))) Chris@16: Chris@16: has_template_MyTemplate::value Chris@16: Chris@16: is a compile time boolean constant which is either 'true' or 'false' Chris@16: if the nested template exists. Chris@16: Chris@16: */ Chris@16: #define BOOST_TTI_HAS_TEMPLATE(name,params) \ Chris@16: BOOST_TTI_TRAIT_HAS_TEMPLATE \ Chris@16: ( \ Chris@16: BOOST_TTI_HAS_TEMPLATE_GEN(name), \ Chris@16: name, \ Chris@16: params \ Chris@16: ) \ Chris@16: /**/ Chris@16: Chris@16: #endif // BOOST_PP_VARIADICS Chris@16: #endif // BOOST_TTI_HAS_TEMPLATE_HPP