2 // Copyright (C) 2000 John Maddock (john_maddock@compuserve.com)
3 // Copyright (C) 2000 Jeremy Siek (jsiek@lsc.nd.edu)
4 // Copyright (C) 1999, 2000 Jaakko J
\84rvi (jaakko.jarvi@cs.utu.fi)
6 // Permission to copy and use this software is granted,
7 // provided this copyright notice appears in all copies.
8 // Permission to modify the code and to distribute modified code is granted,
9 // provided this copyright notice appears in all copies, and a notice
10 // that the code was modified is included with the copyright notice.
12 // This software is provided "as is" without express or implied warranty,
13 // and with no claim as to its suitability for any purpose.
16 #ifndef BOOST_CONVERSION_TYPE_TRAITS_HPP
17 #define BOOST_CONVERSION_TYPE_TRAITS_HPP
19 #ifndef BOOST_ICE_TYPE_TRAITS_HPP
20 #include <boost/type_traits/ice.hpp>
22 #ifndef BOOST_FWD_TYPE_TRAITS_HPP
23 #include <boost/type_traits/fwd.hpp>
25 #ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
26 #include <boost/type_traits/arithmetic_traits.hpp>
29 // is one type convertable to another?
31 // there are multiple versions of the is_convertible
32 // template, almost every compiler seems to require its
35 // Thanks to Andrei Alexandrescu for the original version of the
36 // conversion detection technique!
41 #if defined(BOOST_MSVC)
44 // MS specific version:
48 // This workaround is necessary to handle when From is void
49 // which is normally taken care of by the partial specialization
50 // of the is_convertible class.
51 using ::boost::type_traits::yes_type;
52 using ::boost::type_traits::no_type;
54 struct from_not_void_conversion {
55 template <class From, class To>
57 static no_type BOOST_TT_DECL _m_check(...);
58 static yes_type BOOST_TT_DECL _m_check(To);
60 void foo(); // avoid warning about all members being private
62 enum { exists = sizeof( _m_check(_m_from) ) == sizeof(yes_type) };
65 struct from_is_void_conversion {
66 template <class From, class To>
68 enum { exists = ::boost::is_void<To>::value };
73 struct conversion_helper {
74 typedef from_not_void_conversion type;
77 struct conversion_helper<void> {
78 typedef from_is_void_conversion type;
82 template <class From, class To>
85 typedef typename detail::conversion_helper<From>::type Selector;
86 typedef typename Selector::template n_bind<From,To> Conversion;
88 enum { value = Conversion::exists };
91 #elif defined(__BORLANDC__)
93 // special version for Borland compilers
94 // this version breaks when used for some
97 template <class From, class To>
101 #pragma option push -w-8074
102 // This workaround for Borland breaks the EDG C++ frontend,
103 // so we only use it for Borland.
107 static type_traits::no_type BOOST_TT_DECL _m_check(...);
108 static type_traits::yes_type BOOST_TT_DECL _m_check(T);
112 static const bool value = sizeof( checker<To>::_m_check(_m_from) ) == sizeof(type_traits::yes_type);
114 void foo(); // avoid warning about all members being private
118 #elif defined(__GNUC__)
120 // special version for gcc compiler
123 struct any_conversion
126 any_conversion(const T&);
133 static boost::type_traits::no_type _m_check(any_conversion ...);
134 static boost::type_traits::yes_type _m_check(T, int);
136 } // namespace detail
137 template <class From, class To>
138 struct is_convertible
143 static const bool value = sizeof( detail::checker<To>::_m_check(_m_from, 0) ) == sizeof(type_traits::yes_type);
145 void foo(); // avoid warning about all members being private
148 // Declare specializations of is_convertible for all of the floating
149 // types to all of the integral types. This suppresses some nasty
152 # define BOOST_IS_CONVERTIBLE(T1,T2) template<>struct is_convertible<T1,T2>{static const bool value=true;};
153 # define BOOST_IS_CONVERTIBLE2(T1,T2) \
154 BOOST_IS_CONVERTIBLE(T1,signed T2) \
155 BOOST_IS_CONVERTIBLE(T1,unsigned T2)
157 # define BOOST_FLOAT_IS_CONVERTIBLE(F) \
158 BOOST_IS_CONVERTIBLE(F,char) \
159 BOOST_IS_CONVERTIBLE2(F,char) \
160 BOOST_IS_CONVERTIBLE2(F,short) \
161 BOOST_IS_CONVERTIBLE2(F,int) \
162 BOOST_IS_CONVERTIBLE2(F,long) \
163 BOOST_IS_CONVERTIBLE2(F,long long)
165 BOOST_FLOAT_IS_CONVERTIBLE(float)
166 BOOST_FLOAT_IS_CONVERTIBLE(double)
167 BOOST_FLOAT_IS_CONVERTIBLE(long double)
168 BOOST_FLOAT_IS_CONVERTIBLE(float const)
169 BOOST_FLOAT_IS_CONVERTIBLE(double const)
170 BOOST_FLOAT_IS_CONVERTIBLE(long double const)
171 BOOST_FLOAT_IS_CONVERTIBLE(float volatile)
172 BOOST_FLOAT_IS_CONVERTIBLE(double volatile)
173 BOOST_FLOAT_IS_CONVERTIBLE(long double volatile)
174 BOOST_FLOAT_IS_CONVERTIBLE(float const volatile)
175 BOOST_FLOAT_IS_CONVERTIBLE(double const volatile)
176 BOOST_FLOAT_IS_CONVERTIBLE(long double const volatile)
177 # undef BOOST_FLOAT_IS_CONVERTIBLE
178 # undef BOOST_IS_CONVERTIBLE2
179 # undef BOOST_IS_CONVERTIBLE
182 template <class From, class To>
183 struct is_convertible
186 static type_traits::no_type BOOST_TT_DECL _m_check(...);
187 static type_traits::yes_type BOOST_TT_DECL _m_check(To);
190 BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(_m_from) ) == sizeof(type_traits::yes_type));
191 void foo(); // avoid warning about all members being private
194 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
195 // A definition is required even for integral static constants
196 template <class From, class To>
197 const bool is_convertible<From, To>::value;
201 #endif // is_convertible
204 // Now add the full and partial specialisations
205 // for void types, these are common to all the
206 // implementation above:
208 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
209 template <class From>
210 struct is_convertible<From, void>
212 BOOST_STATIC_CONSTANT(bool, value = false);
214 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
215 template <class From>
216 struct is_convertible<From, const void>
218 BOOST_STATIC_CONSTANT(bool, value = false);
220 template <class From>
221 struct is_convertible<From, volatile void>
223 BOOST_STATIC_CONSTANT(bool, value = false);
225 template <class From>
226 struct is_convertible<From, const volatile void>
228 BOOST_STATIC_CONSTANT(bool, value = false);
230 #endif // BOOST_NO_CV_VOID_SPECIALIZATIONS
233 struct is_convertible<void, To>
235 BOOST_STATIC_CONSTANT(bool, value = false);
237 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
239 struct is_convertible<const void, To>
241 BOOST_STATIC_CONSTANT(bool, value = false);
244 struct is_convertible<volatile void, To>
246 BOOST_STATIC_CONSTANT(bool, value = false);
249 struct is_convertible<const volatile void, To>
251 BOOST_STATIC_CONSTANT(bool, value = false);
254 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
257 struct is_convertible<void, void>
259 BOOST_STATIC_CONSTANT(bool, value = true);
261 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
263 struct is_convertible<void, const void>
265 BOOST_STATIC_CONSTANT(bool, value = true);
268 struct is_convertible<void, volatile void>
270 BOOST_STATIC_CONSTANT(bool, value = true);
273 struct is_convertible<void, const volatile void>
275 BOOST_STATIC_CONSTANT(bool, value = true);
278 struct is_convertible<const void, const void>
280 BOOST_STATIC_CONSTANT(bool, value = true);
283 struct is_convertible<const void, volatile void>
285 BOOST_STATIC_CONSTANT(bool, value = true);
288 struct is_convertible<const void, const volatile void>
290 BOOST_STATIC_CONSTANT(bool, value = true);
293 struct is_convertible<volatile void, const void>
295 BOOST_STATIC_CONSTANT(bool, value = true);
298 struct is_convertible<volatile void, volatile void>
300 BOOST_STATIC_CONSTANT(bool, value = true);
303 struct is_convertible<volatile void, const volatile void>
305 BOOST_STATIC_CONSTANT(bool, value = true);
308 struct is_convertible<const volatile void, const void>
310 BOOST_STATIC_CONSTANT(bool, value = true);
313 struct is_convertible<const volatile void, volatile void>
315 BOOST_STATIC_CONSTANT(bool, value = true);
318 struct is_convertible<const volatile void, const volatile void>
320 BOOST_STATIC_CONSTANT(bool, value = true);
326 #endif // include guard