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