]> git.lyx.org Git - lyx.git/blob - boost/boost/type_traits/conversion_traits.hpp
update boost
[lyx.git] / boost / boost / type_traits / conversion_traits.hpp
1
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)
5 //
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.
11 //
12 // This software is provided "as is" without express or implied warranty, 
13 // and with no claim as to its suitability for any purpose.
14 //
15
16 #ifndef BOOST_CONVERSION_TYPE_TRAITS_HPP
17 #define BOOST_CONVERSION_TYPE_TRAITS_HPP
18
19 #ifndef BOOST_ICE_TYPE_TRAITS_HPP
20 #include <boost/type_traits/ice.hpp>
21 #endif
22 #ifndef BOOST_FWD_TYPE_TRAITS_HPP
23 #include <boost/type_traits/fwd.hpp>
24 #endif
25 #ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
26 #include <boost/type_traits/arithmetic_traits.hpp>
27 #endif
28 //
29 // is one type convertable to another?
30 //
31 // there are multiple versions of the is_convertible
32 // template, almost every compiler seems to require its
33 // own version.
34 //
35 // Thanks to Andrei Alexandrescu for the original version of the
36 // conversion detection technique!
37 //
38
39 namespace boost{
40
41 #if defined(BOOST_MSVC) 
42
43 //
44 // MS specific version:
45 //
46 namespace detail{
47
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;
53
54   struct from_not_void_conversion {
55     template <class From, class To>
56     struct n_bind {
57       static no_type BOOST_TT_DECL _m_check(...);
58       static yes_type BOOST_TT_DECL _m_check(To);
59     public:
60       void foo(); // avoid warning about all members being private
61       static From _m_from;
62       enum { exists = sizeof( _m_check(_m_from) ) == sizeof(yes_type) };
63     };
64   };
65   struct from_is_void_conversion {
66     template <class From, class To>
67     struct n_bind {
68        enum { exists = ::boost::is_void<To>::value };
69     };
70   };
71
72   template <class From>
73   struct conversion_helper {
74     typedef from_not_void_conversion type;
75   };
76   template <>
77   struct conversion_helper<void> {
78     typedef from_is_void_conversion type;
79   };
80 } // namespace detail
81
82 template <class From, class To>
83 struct is_convertible
84 {
85  typedef typename detail::conversion_helper<From>::type Selector;
86  typedef typename Selector::template n_bind<From,To> Conversion;
87 public:
88  enum { value = Conversion::exists };
89 };
90
91 #elif defined(__BORLANDC__)
92 //
93 // special version for Borland compilers
94 // this version breaks when used for some
95 // UDT conversions:
96 //
97 template <class From, class To>
98 struct is_convertible
99 {
100 private:
101 #pragma option push -w-8074
102    // This workaround for Borland breaks the EDG C++ frontend,
103    // so we only use it for Borland.
104    template <class T>
105    struct checker
106    {
107       static type_traits::no_type BOOST_TT_DECL _m_check(...);
108       static type_traits::yes_type BOOST_TT_DECL _m_check(T);
109    };
110    static From _m_from;
111 public:
112    static const bool value = sizeof( checker<To>::_m_check(_m_from) ) == sizeof(type_traits::yes_type);
113
114    void foo(); // avoid warning about all members being private
115 #pragma option pop
116 };
117
118 #elif defined(__GNUC__)
119 //
120 // special version for gcc compiler
121 //
122 namespace detail{
123    struct any_conversion
124    {
125       template <class T>
126       any_conversion(const T&);
127       template <class T>
128       any_conversion(T&);
129    };
130    template <class T>
131    struct checker
132    {
133       static boost::type_traits::no_type _m_check(any_conversion ...);
134       static boost::type_traits::yes_type _m_check(T, int);
135    };
136 } // namespace detail
137 template <class From, class To>
138 struct is_convertible
139 {
140 private:
141    static From _m_from;
142 public:
143    static const bool value = sizeof( detail::checker<To>::_m_check(_m_from, 0) ) == sizeof(type_traits::yes_type);
144
145    void foo(); // avoid warning about all members being private
146 };
147
148 // Declare specializations of is_convertible for all of the floating
149 // types to all of the integral types. This suppresses some nasty
150 // warnings
151
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)
156             
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)
164
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
180 #else
181
182 template <class From, class To>
183 struct is_convertible
184 {
185 private:
186    static type_traits::no_type BOOST_TT_DECL _m_check(...);
187    static type_traits::yes_type BOOST_TT_DECL _m_check(To);
188    static From _m_from;
189 public:
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
192 };
193
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;
198 #endif
199
200
201 #endif // is_convertible
202
203 //
204 // Now add the full and partial specialisations
205 // for void types, these are common to all the
206 // implementation above:
207 //
208 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
209 template <class From>
210 struct is_convertible<From, void>
211 {
212    BOOST_STATIC_CONSTANT(bool, value = false);
213 };
214 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
215 template <class From>
216 struct is_convertible<From, const void>
217 {
218    BOOST_STATIC_CONSTANT(bool, value = false);
219 };
220 template <class From>
221 struct is_convertible<From, volatile void>
222 {
223    BOOST_STATIC_CONSTANT(bool, value = false);
224 };
225 template <class From>
226 struct is_convertible<From, const volatile void>
227 {
228    BOOST_STATIC_CONSTANT(bool, value = false);
229 };
230 #endif // BOOST_NO_CV_VOID_SPECIALIZATIONS
231
232 template <class To>
233 struct is_convertible<void, To>
234 {
235    BOOST_STATIC_CONSTANT(bool, value = false);
236 };
237 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
238 template <class To>
239 struct is_convertible<const void, To>
240 {
241    BOOST_STATIC_CONSTANT(bool, value = false);
242 };
243 template <class To>
244 struct is_convertible<volatile void, To>
245 {
246    BOOST_STATIC_CONSTANT(bool, value = false);
247 };
248 template <class To>
249 struct is_convertible<const volatile void, To>
250 {
251    BOOST_STATIC_CONSTANT(bool, value = false);
252 };
253 #endif
254 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
255
256 template <>
257 struct is_convertible<void, void>
258 {
259    BOOST_STATIC_CONSTANT(bool, value = true);
260 };
261 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
262 template <>
263 struct is_convertible<void, const void>
264 {
265    BOOST_STATIC_CONSTANT(bool, value = true);
266 };
267 template <>
268 struct is_convertible<void, volatile void>
269 {
270    BOOST_STATIC_CONSTANT(bool, value = true);
271 };
272 template <>
273 struct is_convertible<void, const volatile void>
274 {
275    BOOST_STATIC_CONSTANT(bool, value = true);
276 };
277 template <>
278 struct is_convertible<const void, const void>
279 {
280    BOOST_STATIC_CONSTANT(bool, value = true);
281 };
282 template <>
283 struct is_convertible<const void, volatile void>
284 {
285    BOOST_STATIC_CONSTANT(bool, value = true);
286 };
287 template <>
288 struct is_convertible<const void, const volatile void>
289 {
290    BOOST_STATIC_CONSTANT(bool, value = true);
291 };
292 template <>
293 struct is_convertible<volatile void, const void>
294 {
295    BOOST_STATIC_CONSTANT(bool, value = true);
296 };
297 template <>
298 struct is_convertible<volatile void, volatile void>
299 {
300    BOOST_STATIC_CONSTANT(bool, value = true);
301 };
302 template <>
303 struct is_convertible<volatile void, const volatile void>
304 {
305    BOOST_STATIC_CONSTANT(bool, value = true);
306 };
307 template <>
308 struct is_convertible<const volatile void, const void>
309 {
310    BOOST_STATIC_CONSTANT(bool, value = true);
311 };
312 template <>
313 struct is_convertible<const volatile void, volatile void>
314 {
315    BOOST_STATIC_CONSTANT(bool, value = true);
316 };
317 template <>
318 struct is_convertible<const volatile void, const volatile void>
319 {
320    BOOST_STATIC_CONSTANT(bool, value = true);
321 };
322 #endif
323
324 } // namespace boost
325
326 #endif  // include guard
327
328