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