is_instance_of.hpp 4.3 KB

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