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