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 | |