Chris@16: // Boost Lambda Library - is_instance_of.hpp --------------------- Chris@16: Chris@16: // Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // For more information, see www.boost.org Chris@16: Chris@16: // --------------------------------------------------------------- Chris@16: Chris@16: #ifndef BOOST_LAMBDA_IS_INSTANCE_OF Chris@16: #define BOOST_LAMBDA_IS_INSTANCE_OF Chris@16: Chris@16: #include "boost/config.hpp" // for BOOST_STATIC_CONSTANT Chris@16: #include "boost/type_traits/conversion_traits.hpp" // for is_convertible Chris@16: #include "boost/preprocessor/enum_shifted_params.hpp" Chris@16: #include "boost/preprocessor/repeat_2nd.hpp" Chris@16: Chris@16: // is_instance_of -------------------------------- Chris@16: // Chris@16: // is_instance_of_n::value is true, if type A is Chris@16: // an instantiation of a template B, or A derives from an instantiation Chris@16: // of template B Chris@16: // Chris@16: // n is the number of template arguments for B Chris@16: // Chris@16: // Example: Chris@16: // is_instance_of_2::value == true Chris@16: Chris@16: // The original implementation was somewhat different, with different versions Chris@16: // for different compilers. However, there was still a problem Chris@16: // with gcc.3.0.2 and 3.0.3 compilers, which didn't think regard Chris@16: // is_instance_of_N<...>::value was a constant. Chris@16: // John Maddock suggested the way around this problem by building Chris@16: // is_instance_of templates using boost::is_convertible. Chris@16: // Now we only have one version of is_instance_of templates, which delagate Chris@16: // all the nasty compiler tricks to is_convertible. Chris@16: Chris@16: #define BOOST_LAMBDA_CLASS(z, N,A) BOOST_PP_COMMA_IF(N) class Chris@16: #define BOOST_LAMBDA_CLASS_ARG(z, N,A) BOOST_PP_COMMA_IF(N) class A##N Chris@16: #define BOOST_LAMBDA_ARG(z, N,A) BOOST_PP_COMMA_IF(N) A##N Chris@16: Chris@16: #define BOOST_LAMBDA_CLASS_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_CLASS, NAME) Chris@16: Chris@16: #define BOOST_LAMBDA_CLASS_ARG_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_CLASS_ARG, NAME) Chris@16: Chris@16: #define BOOST_LAMBDA_ARG_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_ARG, NAME) Chris@16: Chris@16: namespace boost { Chris@16: namespace lambda { Chris@16: Chris@16: #define BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE(INDEX) \ Chris@16: \ Chris@16: namespace detail { \ Chris@16: \ Chris@16: template class F> \ Chris@16: struct BOOST_PP_CAT(conversion_tester_,INDEX) { \ Chris@16: template \ Chris@16: BOOST_PP_CAT(conversion_tester_,INDEX) \ Chris@16: (const F&); \ Chris@16: }; \ Chris@16: \ Chris@16: } /* end detail */ \ Chris@16: \ Chris@16: template class To> \ Chris@16: struct BOOST_PP_CAT(is_instance_of_,INDEX) \ Chris@16: { \ Chris@16: private: \ Chris@16: typedef ::boost::is_convertible< \ Chris@16: From, \ Chris@16: BOOST_PP_CAT(detail::conversion_tester_,INDEX) \ Chris@16: > helper_type; \ Chris@16: \ Chris@16: public: \ Chris@16: BOOST_STATIC_CONSTANT(bool, value = helper_type::value); \ Chris@16: }; Chris@16: Chris@16: Chris@16: #define BOOST_LAMBDA_HELPER(z, N, A) BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( BOOST_PP_INC(N) ) Chris@16: Chris@16: // Generate the traits for 1-4 argument templates Chris@16: Chris@16: BOOST_PP_REPEAT_2ND(4,BOOST_LAMBDA_HELPER,FOO) Chris@16: Chris@16: #undef BOOST_LAMBDA_HELPER Chris@16: #undef BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE Chris@16: #undef BOOST_LAMBDA_CLASS Chris@16: #undef BOOST_LAMBDA_ARG Chris@16: #undef BOOST_LAMBDA_CLASS_ARG Chris@16: #undef BOOST_LAMBDA_CLASS_LIST Chris@16: #undef BOOST_LAMBDA_ARG_LIST Chris@16: #undef BOOST_LAMBDA_CLASS_ARG_LIST Chris@16: Chris@16: } // lambda Chris@16: } // boost Chris@16: Chris@16: #endif Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: