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