is_polymorphic.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // (C) Copyright John Maddock 2000.
  2. // Use, modification and distribution are subject to the Boost Software License,
  3. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt).
  5. //
  6. // See http://www.boost.org/libs/type_traits for most recent version including documentation.
  7. #ifndef BOOST_TT_IS_POLYMORPHIC_HPP
  8. #define BOOST_TT_IS_POLYMORPHIC_HPP
  9. #include <boost/type_traits/intrinsics.hpp>
  10. #include <boost/type_traits/integral_constant.hpp>
  11. #ifndef BOOST_IS_POLYMORPHIC
  12. #include <boost/type_traits/is_class.hpp>
  13. #endif
  14. #include <boost/detail/workaround.hpp>
  15. #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1700)
  16. #pragma warning(push)
  17. #pragma warning(disable:4250)
  18. #endif
  19. namespace boost{
  20. #ifndef BOOST_IS_POLYMORPHIC
  21. namespace detail{
  22. template <class T>
  23. struct is_polymorphic_imp1
  24. {
  25. # if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) // CWPro7 should return false always.
  26. typedef char d1, (&d2)[2];
  27. # else
  28. struct d1 : public T
  29. {
  30. d1();
  31. # if !defined(__GNUC__) // this raises warnings with some classes, and buys nothing with GCC
  32. ~d1()throw();
  33. # endif
  34. char padding[256];
  35. private:
  36. // keep some picky compilers happy:
  37. d1(const d1&);
  38. d1& operator=(const d1&);
  39. };
  40. struct d2 : public T
  41. {
  42. d2();
  43. virtual ~d2()throw();
  44. # if !defined(BOOST_MSVC) && !defined(__ICL)
  45. // for some reason this messes up VC++ when T has virtual bases,
  46. // probably likewise for compilers that use the same ABI:
  47. struct unique{};
  48. virtual void unique_name_to_boost5487629(unique*);
  49. # endif
  50. char padding[256];
  51. private:
  52. // keep some picky compilers happy:
  53. d2(const d2&);
  54. d2& operator=(const d2&);
  55. };
  56. # endif
  57. BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1)));
  58. };
  59. template <class T> struct is_polymorphic_imp1<T const> : public is_polymorphic_imp1<T>{};
  60. template <class T> struct is_polymorphic_imp1<T const volatile> : public is_polymorphic_imp1<T>{};
  61. template <class T> struct is_polymorphic_imp1<T volatile> : public is_polymorphic_imp1<T>{};
  62. template <class T>
  63. struct is_polymorphic_imp2
  64. {
  65. BOOST_STATIC_CONSTANT(bool, value = false);
  66. };
  67. template <bool is_class>
  68. struct is_polymorphic_selector
  69. {
  70. template <class T>
  71. struct rebind
  72. {
  73. typedef is_polymorphic_imp2<T> type;
  74. };
  75. };
  76. template <>
  77. struct is_polymorphic_selector<true>
  78. {
  79. template <class T>
  80. struct rebind
  81. {
  82. typedef is_polymorphic_imp1<T> type;
  83. };
  84. };
  85. template <class T>
  86. struct is_polymorphic_imp
  87. {
  88. typedef is_polymorphic_selector< ::boost::is_class<T>::value> selector;
  89. typedef typename selector::template rebind<T> binder;
  90. typedef typename binder::type imp_type;
  91. BOOST_STATIC_CONSTANT(bool, value = imp_type::value);
  92. };
  93. } // namespace detail
  94. template <class T> struct is_polymorphic : public integral_constant<bool, ::boost::detail::is_polymorphic_imp<T>::value> {};
  95. #else // BOOST_IS_POLYMORPHIC
  96. template <class T> struct is_polymorphic : public integral_constant<bool, BOOST_IS_POLYMORPHIC(T)> {};
  97. #endif
  98. } // namespace boost
  99. #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1700)
  100. #pragma warning(pop)
  101. #endif
  102. #endif