1 // Boost Lambda Library - is_instance_of.hpp --------------------- 2 3 // Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) 4 // 5 // Distributed under the Boost Software License, Version 1.0. (See 6 // accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // For more information, see www.boost.org 10 11 // --------------------------------------------------------------- 12 13 #ifndef BOOST_LAMBDA_IS_INSTANCE_OF 14 #define BOOST_LAMBDA_IS_INSTANCE_OF 15 16 #include "boost/config.hpp" // for BOOST_STATIC_CONSTANT 17 #include "boost/type_traits/conversion_traits.hpp" // for is_convertible 18 #include "boost/preprocessor/enum_shifted_params.hpp" 19 #include "boost/preprocessor/repeat_2nd.hpp" 20 21 // is_instance_of -------------------------------- 22 // 23 // is_instance_of_n<A, B>::value is true, if type A is 24 // an instantiation of a template B, or A derives from an instantiation 25 // of template B 26 // 27 // n is the number of template arguments for B 28 // 29 // Example: 30 // is_instance_of_2<std::istream, basic_stream>::value == true 31 32 // The original implementation was somewhat different, with different versions 33 // for different compilers. However, there was still a problem 34 // with gcc.3.0.2 and 3.0.3 compilers, which didn't think regard 35 // is_instance_of_N<...>::value was a constant. 36 // John Maddock suggested the way around this problem by building 37 // is_instance_of templates using boost::is_convertible. 38 // Now we only have one version of is_instance_of templates, which delagate 39 // all the nasty compiler tricks to is_convertible. 40 41 #define BOOST_LAMBDA_CLASS(z, N,A) BOOST_PP_COMMA_IF(N) class 42 #define BOOST_LAMBDA_CLASS_ARG(z, N,A) BOOST_PP_COMMA_IF(N) class A##N 43 #define BOOST_LAMBDA_ARG(z, N,A) BOOST_PP_COMMA_IF(N) A##N 44 45 #define BOOST_LAMBDA_CLASS_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_CLASS, NAME) 46 47 #define BOOST_LAMBDA_CLASS_ARG_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_CLASS_ARG, NAME) 48 49 #define BOOST_LAMBDA_ARG_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_ARG, NAME) 50 51 namespace boost { 52 namespace lambda { 53 54 #define BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE(INDEX) \ 55 \ 56 namespace detail { \ 57 \ 58 template <template<BOOST_LAMBDA_CLASS_LIST(INDEX,T)> class F> \ 59 struct BOOST_PP_CAT(conversion_tester_,INDEX) { \ 60 template<BOOST_LAMBDA_CLASS_ARG_LIST(INDEX,A)> \ 61 BOOST_PP_CAT(conversion_tester_,INDEX) \ 62 (const F<BOOST_LAMBDA_ARG_LIST(INDEX,A)>&); \ 63 }; \ 64 \ 65 } /* end detail */ \ 66 \ 67 template <class From, template <BOOST_LAMBDA_CLASS_LIST(INDEX,T)> class To> \ 68 struct BOOST_PP_CAT(is_instance_of_,INDEX) \ 69 { \ 70 private: \ 71 typedef ::boost::is_convertible< \ 72 From, \ 73 BOOST_PP_CAT(detail::conversion_tester_,INDEX)<To> \ 74 > helper_type; \ 75 \ 76 public: \ 77 BOOST_STATIC_CONSTANT(bool, value = helper_type::value); \ 78 }; 79 80 81 #define BOOST_LAMBDA_HELPER(z, N, A) BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( BOOST_PP_INC(N) ) 82 83 // Generate the traits for 1-4 argument templates 84 85 BOOST_PP_REPEAT_2ND(4,BOOST_LAMBDA_HELPER,FOO) 86 87 #undef BOOST_LAMBDA_HELPER 88 #undef BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE 89 #undef BOOST_LAMBDA_CLASS 90 #undef BOOST_LAMBDA_ARG 91 #undef BOOST_LAMBDA_CLASS_ARG 92 #undef BOOST_LAMBDA_CLASS_LIST 93 #undef BOOST_LAMBDA_ARG_LIST 94 #undef BOOST_LAMBDA_CLASS_ARG_LIST 95 96 } // lambda 97 } // boost 98 99 #endif 100 101 102 103 104 105