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 8 #ifndef BOOST_TT_IS_POLYMORPHIC_HPP 9 #define BOOST_TT_IS_POLYMORPHIC_HPP 10 11 #include <boost/type_traits/intrinsics.hpp> 12 #include <boost/type_traits/integral_constant.hpp> 13 #ifndef BOOST_IS_POLYMORPHIC 14 #include <boost/type_traits/is_class.hpp> 15 #endif 16 #include <boost/detail/workaround.hpp> 17 18 #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1700) 19 #pragma warning(push) 20 #pragma warning(disable:4250) 21 #endif 22 23 namespace boost{ 24 25 #ifndef BOOST_IS_POLYMORPHIC 26 27 namespace detail{ 28 29 template <class T> 30 struct is_polymorphic_imp1 31 { 32 # if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) // CWPro7 should return false always. 33 typedef char d1, (&d2)[2]; 34 # else 35 struct d1 : public T 36 { 37 d1(); 38 # if !defined(__GNUC__) // this raises warnings with some classes, and buys nothing with GCC 39 ~d1()throw(); 40 # endif 41 char padding[256]; 42 private: 43 // keep some picky compilers happy: 44 d1(const d1&); 45 d1& operator=(const d1&); 46 }; 47 struct d2 : public T 48 { 49 d2(); 50 virtual ~d2()throw(); 51 # if !defined(BOOST_MSVC) && !defined(__ICL) 52 // for some reason this messes up VC++ when T has virtual bases, 53 // probably likewise for compilers that use the same ABI: 54 struct unique{}; 55 virtual void unique_name_to_boost5487629(unique*); 56 # endif 57 char padding[256]; 58 private: 59 // keep some picky compilers happy: 60 d2(const d2&); 61 d2& operator=(const d2&); 62 }; 63 # endif 64 BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1))); 65 }; 66 67 template <class T> struct is_polymorphic_imp1<T const> : public is_polymorphic_imp1<T>{}; 68 template <class T> struct is_polymorphic_imp1<T const volatile> : public is_polymorphic_imp1<T>{}; 69 template <class T> struct is_polymorphic_imp1<T volatile> : public is_polymorphic_imp1<T>{}; 70 71 template <class T> 72 struct is_polymorphic_imp2 73 { 74 BOOST_STATIC_CONSTANT(bool, value = false); 75 }; 76 77 template <bool is_class> 78 struct is_polymorphic_selector 79 { 80 template <class T> 81 struct rebind 82 { 83 typedef is_polymorphic_imp2<T> type; 84 }; 85 }; 86 87 template <> 88 struct is_polymorphic_selector<true> 89 { 90 template <class T> 91 struct rebind 92 { 93 typedef is_polymorphic_imp1<T> type; 94 }; 95 }; 96 97 template <class T> 98 struct is_polymorphic_imp 99 { 100 typedef is_polymorphic_selector< ::boost::is_class<T>::value> selector; 101 typedef typename selector::template rebind<T> binder; 102 typedef typename binder::type imp_type; 103 BOOST_STATIC_CONSTANT(bool, value = imp_type::value); 104 }; 105 106 } // namespace detail 107 108 template <class T> struct is_polymorphic : public integral_constant<bool, ::boost::detail::is_polymorphic_imp<T>::value> {}; 109 110 #else // BOOST_IS_POLYMORPHIC 111 112 template <class T> struct is_polymorphic : public integral_constant<bool, BOOST_IS_POLYMORPHIC(T)> {}; 113 114 #endif 115 116 } // namespace boost 117 118 #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1700) 119 #pragma warning(pop) 120 #endif 121 122 #endif 123