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
23namespace boost{
24
25#ifndef BOOST_IS_POLYMORPHIC
26
27namespace detail{
28
29template <class T>
30struct 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
67template <class T> struct is_polymorphic_imp1<T const> : public is_polymorphic_imp1<T>{};
68template <class T> struct is_polymorphic_imp1<T const volatile> : public is_polymorphic_imp1<T>{};
69template <class T> struct is_polymorphic_imp1<T volatile> : public is_polymorphic_imp1<T>{};
70
71template <class T>
72struct is_polymorphic_imp2
73{
74 BOOST_STATIC_CONSTANT(bool, value = false);
75};
76
77template <bool is_class>
78struct is_polymorphic_selector
79{
80 template <class T>
81 struct rebind
82 {
83 typedef is_polymorphic_imp2<T> type;
84 };
85};
86
87template <>
88struct is_polymorphic_selector<true>
89{
90 template <class T>
91 struct rebind
92 {
93 typedef is_polymorphic_imp1<T> type;
94 };
95};
96
97template <class T>
98struct 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
108template <class T> struct is_polymorphic : public integral_constant<bool, ::boost::detail::is_polymorphic_imp<T>::value> {};
109
110#else // BOOST_IS_POLYMORPHIC
111
112template <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

source code of include/boost/type_traits/is_polymorphic.hpp