// is_instance_of_n<A, B>::value is true, if type A is
// an instantiation of a template B, or A derives from an instantiation
// of template B
//
// n is the number of template arguments for B
//
// Example:
// is_instance_of_2<std::istream, basic_stream>::value == true
#ifndef BOOST_LAMBDA_IS_INSTANCE_OF #define BOOST_LAMBDA_IS_INSTANCE_OF #include "boost/config.hpp" // for BOOST_STATIC_CONSTANT #include "boost/type_traits/conversion_traits.hpp" // for is_convertible #include "boost/preprocessor/enum_shifted_params.hpp"
#include "boost/preprocessor/repeat_2nd.hpp"
// is_instance_of -------------------------------- //
// is_instance_of_n<A, B>::value is true, if type A is
// an instantiation of a template B, or A derives from an instantiation // of template B //
// n is the number of template arguments for B //
// Example:
// is_instance_of_2<std::istream, basic_stream>::value == true
// The original implementation was somewhat different, with different versions
// for different compilers. However, there was still a problem
// with gcc.3.0.2 and 3.0.3 compilers, which didn't think regard
// is_instance_of_N<...>::value was a constant.
// John Maddock suggested the way around this problem by building
// is_instance_of templates using boost::is_convertible.
// Now we only have one version of is_instance_of templates, which delagate
// all the nasty compiler tricks to is_convertible.
//BOOST_PP_COMMA_IF(N) 如果 cond 展开为 0, 则该宏展开为空。否则展开为一个逗号。
#define BOOST_LAMBDA_CLASS(z, N,A) BOOST_PP_COMMA_IF(N)
class #define BOOST_LAMBDA_CLASS_ARG(z, N,A)
BOOST_PP_COMMA_IF(N) class A##N
#define BOOST_LAMBDA_ARG(z, N,A) BOOST_PP_COMMA_IF(N) A##N
#define BOOST_LAMBDA_CLASS_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_CLASS, NAME) #define BOOST_LAMBDA_CLASS_ARG_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_CLASS_ARG, NAME) #define BOOST_LAMBDA_ARG_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_ARG, NAME) //假设 INDEX = 3, 下面的宏可以展示为:
// template< template<class,class, class> class F>
// struct conversion_tester_3{
// template<A0,A1,A2>
// conversion_tester_3(const F<A0,A1,A2>);
// }; //
// template<class From, template<class, class, class> class To>
// struct is_instance_of_3
// {
// private:
// typedef ::boost::is_convertible<
// From,
// detail::conversion_tester_3<To>
// >helper_type;
// public:
// BOOST_STATIC_CONSTANT(bool, value = helper_type::value);
//
};
// template <class From, class To>
// struct is_convertible : public true_type-or-false_type {};
//
//
// 继承:如果一个类型为 From 的 imaginary lvalue(假想左值)可以转换为类型 To,则从 true_type 继承,否则从 false_type 继承。
// is_convertible<int, double> 从 true_type 继承。
// // is_convertible<const int, double>::type 是 true_type 类型。
// // is_convertible<int* const, int*>::value 是一个求值为 true 的 integral constant expression(整常表达式)。
// // is_convertible<int const*, int*>::value 是一个求值为 false 的 integral constant expression(整常表达式):这个转换需要一个 const_cast。
// // is_convertible<int const&, long>::value 是一个求值为 true 的 integral constant expression(整常表达式)。
// // is_convertible<int>::value 是一个求值为 false 的 integral constant expression(整常表达式)。
// // is_convertible<T>::value_type 是 bool 类型。
namespace boost { namespace lambda { #define BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE(INDEX) / / namespace detail {
/ / template <template<BOOST_LAMBDA_CLASS_LIST(INDEX,T)> class F> / struct BOOST_PP_CAT(conversion_tester_,INDEX) { / template<BOOST_LAMBDA_CLASS_ARG_LIST(INDEX,A)> / BOOST_PP_CAT(conversion_tester_,INDEX) / (const F<BOOST_LAMBDA_ARG_LIST(INDEX,A)>&); / }; / / } /* end detail */ / / template <class From, template <BOOST_LAMBDA_CLASS_LIST(INDEX,T)> class To> / struct BOOST_PP_CAT(is_instance_of_,INDEX) / { / private: / typedef ::boost::is_convertible< / From, / BOOST_PP_CAT(detail::conversion_tester_,INDEX)<To> / > helper_type; / / public: / BOOST_STATIC_CONSTANT(bool, value = helper_type::value); / }; #define BOOST_LAMBDA_HELPER(z, N, A) BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( BOOST_PP_INC(N) ) // Generate the traits for 1-4 argument templates BOOST_PP_REPEAT_2ND(4,BOOST_LAMBDA_HELPER,FOO)
//BOOST_LAMBDA_HELPER(z,0,FOO),
//BOOST_LAMBDA_HELPER(z,1,FOO),
//BOOST_LAMBDA_HELPER(z,2,FOO),
//BOOST_LAMBDA_HELPER(z,3,FOO) //这样展开为:
//BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( 1 ),
//BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( 2 ),
//BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( 3 ),
//BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( 4 )
#undef BOOST_LAMBDA_HELPER
#undef BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE #undef BOOST_LAMBDA_CLASS
#undef BOOST_LAMBDA_ARG #undef BOOST_LAMBDA_CLASS_ARG #undef BOOST_LAMBDA_CLASS_LIST #undef BOOST_LAMBDA_ARG_LIST #undef BOOST_LAMBDA_CLASS_ARG_LIST } // lambda }
// boost #endif