1 | |
2 | // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard |
3 | // Hinnant & John Maddock 2000. |
4 | // Use, modification and distribution are subject to the Boost Software License, |
5 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
6 | // http://www.boost.org/LICENSE_1_0.txt). |
7 | // |
8 | // See http://www.boost.org/libs/type_traits for most recent version including documentation. |
9 | |
10 | |
11 | #ifndef BOOST_TT_IS_ENUM_HPP_INCLUDED |
12 | #define BOOST_TT_IS_ENUM_HPP_INCLUDED |
13 | |
14 | #include <boost/type_traits/intrinsics.hpp> |
15 | #ifndef BOOST_IS_ENUM |
16 | #include <boost/type_traits/add_reference.hpp> |
17 | #include <boost/type_traits/is_arithmetic.hpp> |
18 | #include <boost/type_traits/is_reference.hpp> |
19 | #include <boost/type_traits/is_convertible.hpp> |
20 | #include <boost/type_traits/is_array.hpp> |
21 | #ifdef __GNUC__ |
22 | #include <boost/type_traits/is_function.hpp> |
23 | #endif |
24 | #include <boost/type_traits/config.hpp> |
25 | #if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION) |
26 | # include <boost/type_traits/is_class.hpp> |
27 | # include <boost/type_traits/is_union.hpp> |
28 | #endif |
29 | #endif |
30 | |
31 | // should be the last #include |
32 | #include <boost/type_traits/detail/bool_trait_def.hpp> |
33 | |
34 | namespace boost { |
35 | |
36 | #ifndef BOOST_IS_ENUM |
37 | #if !(defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)) |
38 | |
39 | namespace detail { |
40 | |
41 | #if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION) |
42 | |
43 | template <typename T> |
44 | struct is_class_or_union |
45 | { |
46 | BOOST_STATIC_CONSTANT(bool, value = |
47 | (::boost::type_traits::ice_or< |
48 | ::boost::is_class<T>::value |
49 | , ::boost::is_union<T>::value |
50 | >::value)); |
51 | }; |
52 | |
53 | #else |
54 | |
55 | template <typename T> |
56 | struct is_class_or_union |
57 | { |
58 | # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))// we simply can't detect it this way. |
59 | BOOST_STATIC_CONSTANT(bool, value = false); |
60 | # else |
61 | template <class U> static ::boost::type_traits::yes_type is_class_or_union_tester(void(U::*)(void)); |
62 | |
63 | # if BOOST_WORKAROUND(__MWERKS__, <= 0x3000) // no SFINAE |
64 | static ::boost::type_traits::no_type is_class_or_union_tester(...); |
65 | BOOST_STATIC_CONSTANT( |
66 | bool, value = sizeof(is_class_or_union_tester(0)) == sizeof(::boost::type_traits::yes_type)); |
67 | # else |
68 | template <class U> |
69 | static ::boost::type_traits::no_type is_class_or_union_tester(...); |
70 | BOOST_STATIC_CONSTANT( |
71 | bool, value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(::boost::type_traits::yes_type)); |
72 | # endif |
73 | # endif |
74 | }; |
75 | #endif |
76 | |
77 | struct int_convertible |
78 | { |
79 | int_convertible(int); |
80 | }; |
81 | |
82 | // Don't evaluate convertibility to int_convertible unless the type |
83 | // is non-arithmetic. This suppresses warnings with GCC. |
84 | template <bool is_typename_arithmetic_or_reference = true> |
85 | struct is_enum_helper |
86 | { |
87 | template <typename T> struct type |
88 | { |
89 | BOOST_STATIC_CONSTANT(bool, value = false); |
90 | }; |
91 | }; |
92 | |
93 | template <> |
94 | struct is_enum_helper<false> |
95 | { |
96 | template <typename T> struct type |
97 | : public ::boost::is_convertible<typename boost::add_reference<T>::type,::boost::detail::int_convertible> |
98 | { |
99 | }; |
100 | }; |
101 | |
102 | template <typename T> struct is_enum_impl |
103 | { |
104 | //typedef ::boost::add_reference<T> ar_t; |
105 | //typedef typename ar_t::type r_type; |
106 | |
107 | #if defined(__GNUC__) |
108 | |
109 | #ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION |
110 | |
111 | // We MUST check for is_class_or_union on conforming compilers in |
112 | // order to correctly deduce that noncopyable types are not enums |
113 | // (dwa 2002/04/15)... |
114 | BOOST_STATIC_CONSTANT(bool, selector = |
115 | (::boost::type_traits::ice_or< |
116 | ::boost::is_arithmetic<T>::value |
117 | , ::boost::is_reference<T>::value |
118 | , ::boost::is_function<T>::value |
119 | , is_class_or_union<T>::value |
120 | , is_array<T>::value |
121 | >::value)); |
122 | #else |
123 | // ...however, not checking is_class_or_union on non-conforming |
124 | // compilers prevents a dependency recursion. |
125 | BOOST_STATIC_CONSTANT(bool, selector = |
126 | (::boost::type_traits::ice_or< |
127 | ::boost::is_arithmetic<T>::value |
128 | , ::boost::is_reference<T>::value |
129 | , ::boost::is_function<T>::value |
130 | , is_array<T>::value |
131 | >::value)); |
132 | #endif // BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION |
133 | |
134 | #else // !defined(__GNUC__): |
135 | |
136 | BOOST_STATIC_CONSTANT(bool, selector = |
137 | (::boost::type_traits::ice_or< |
138 | ::boost::is_arithmetic<T>::value |
139 | , ::boost::is_reference<T>::value |
140 | , is_class_or_union<T>::value |
141 | , is_array<T>::value |
142 | >::value)); |
143 | |
144 | #endif |
145 | |
146 | #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) |
147 | typedef ::boost::detail::is_enum_helper< |
148 | ::boost::detail::is_enum_impl<T>::selector |
149 | > se_t; |
150 | #else |
151 | typedef ::boost::detail::is_enum_helper<selector> se_t; |
152 | #endif |
153 | |
154 | typedef typename se_t::template type<T> helper; |
155 | BOOST_STATIC_CONSTANT(bool, value = helper::value); |
156 | }; |
157 | |
158 | // these help on compilers with no partial specialization support: |
159 | BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_enum,void,false) |
160 | #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS |
161 | BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_enum,void const,false) |
162 | BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_enum,void volatile,false) |
163 | BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_enum,void const volatile,false) |
164 | #endif |
165 | |
166 | } // namespace detail |
167 | |
168 | BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_enum,T,::boost::detail::is_enum_impl<T>::value) |
169 | |
170 | #else // __BORLANDC__ |
171 | // |
172 | // buggy is_convertible prevents working |
173 | // implementation of is_enum: |
174 | BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_enum,T,false) |
175 | |
176 | #endif |
177 | |
178 | #else // BOOST_IS_ENUM |
179 | |
180 | BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_enum,T,BOOST_IS_ENUM(T)) |
181 | |
182 | #endif |
183 | |
184 | } // namespace boost |
185 | |
186 | #include <boost/type_traits/detail/bool_trait_undef.hpp> |
187 | |
188 | #endif // BOOST_TT_IS_ENUM_HPP_INCLUDED |
189 | |