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