]> git.lyx.org Git - lyx.git/blob - boost/boost/type_traits/is_convertible.hpp
remove unused boost files (~520)
[lyx.git] / boost / boost / type_traits / is_convertible.hpp
1
2 // Copyright 2000 John Maddock (john@johnmaddock.co.uk)
3 // Copyright 2000 Jeremy Siek (jsiek@lsc.nd.edu)
4 // Copyright 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
5 //
6 //  Use, modification and distribution are subject to the Boost Software License,
7 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 //  http://www.boost.org/LICENSE_1_0.txt).
9 //
10 //  See http://www.boost.org/libs/type_traits for most recent version including documentation.
11
12 #ifndef BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
13 #define BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
14
15 #include <boost/type_traits/intrinsics.hpp>
16 #ifndef BOOST_IS_CONVERTIBLE
17 #include <boost/type_traits/detail/yes_no_type.hpp>
18 #include <boost/type_traits/config.hpp>
19 #include <boost/type_traits/is_array.hpp>
20 #include <boost/type_traits/add_reference.hpp>
21 #include <boost/type_traits/ice.hpp>
22 #include <boost/type_traits/is_arithmetic.hpp>
23 #include <boost/type_traits/is_void.hpp>
24 #ifndef BOOST_NO_IS_ABSTRACT
25 #include <boost/type_traits/is_abstract.hpp>
26 #endif
27 #include <boost/type_traits/add_rvalue_reference.hpp>
28
29 #if defined(__MWERKS__)
30 #include <boost/type_traits/is_function.hpp>
31 #include <boost/type_traits/remove_reference.hpp>
32 #endif
33
34 #endif // BOOST_IS_CONVERTIBLE
35
36 // should be always the last #include directive
37 #include <boost/type_traits/detail/bool_trait_def.hpp>
38
39 namespace boost {
40
41 #ifndef BOOST_IS_CONVERTIBLE
42
43 // is one type convertable to another?
44 //
45 // there are multiple versions of the is_convertible
46 // template, almost every compiler seems to require its
47 // own version.
48 //
49 // Thanks to Andrei Alexandrescu for the original version of the
50 // conversion detection technique!
51 //
52
53 namespace detail {
54
55 // MS specific version:
56
57 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
58
59 // This workaround is necessary to handle when From is void
60 // which is normally taken care of by the partial specialization
61 // of the is_convertible typename.
62 using ::boost::type_traits::yes_type;
63 using ::boost::type_traits::no_type;
64
65 template< typename From >
66 struct does_conversion_exist
67 {
68     template< typename To > struct result_
69     {
70         static no_type BOOST_TT_DECL _m_check(...);
71         static yes_type BOOST_TT_DECL _m_check(To);
72         static typename add_rvalue_reference<From>::type  _m_from;
73         enum { value = sizeof( _m_check(_m_from) ) == sizeof(yes_type) };
74     };
75 };
76
77 template<>
78 struct does_conversion_exist<void>
79 {
80     template< typename To > struct result_
81     {
82         enum { value = ::boost::is_void<To>::value };
83     };
84 };
85
86 template <typename From, typename To>
87 struct is_convertible_basic_impl
88     : public does_conversion_exist<From>::template result_<To>
89 {
90 };
91
92 #elif defined(__BORLANDC__) && (__BORLANDC__ < 0x560)
93 //
94 // special version for Borland compilers
95 // this version breaks when used for some
96 // UDT conversions:
97 //
98 template <typename From, typename To>
99 struct is_convertible_impl
100 {
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 <typename T> struct checker
105     {
106         static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
107         static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(T);
108     };
109
110     static typename add_rvalue_reference<From>::type  _m_from;
111     static bool const value = sizeof( checker<To>::_m_check(_m_from) )
112         == sizeof(::boost::type_traits::yes_type);
113 #pragma option pop
114 };
115
116 #elif defined(__GNUC__) || defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
117 // special version for gcc compiler + recent Borland versions
118 // note that this does not pass UDT's through (...)
119
120 struct any_conversion
121 {
122     template <typename T> any_conversion(const volatile T&);
123     template <typename T> any_conversion(T&);
124 };
125
126 template <typename T> struct checker
127 {
128     static boost::type_traits::no_type _m_check(any_conversion ...);
129     static boost::type_traits::yes_type _m_check(T, int);
130 };
131
132 template <typename From, typename To>
133 struct is_convertible_basic_impl
134 {
135     static typename add_rvalue_reference<From>::type  _m_from;
136     static bool const value = sizeof( boost::detail::checker<To>::_m_check(_m_from, 0) )
137         == sizeof(::boost::type_traits::yes_type);
138 };
139
140 #elif (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL)) \
141       || defined(__IBMCPP__) || defined(__HP_aCC)
142 //
143 // This is *almost* an ideal world implementation as it doesn't rely
144 // on undefined behaviour by passing UDT's through (...).
145 // Unfortunately it doesn't quite pass all the tests for most compilers (sigh...)
146 // Enable this for your compiler if is_convertible_test.cpp will compile it...
147 //
148 // Note we do not enable this for VC7.1, because even though it passes all the
149 // type_traits tests it is known to cause problems when instantiation occurs
150 // deep within the instantiation tree :-(
151 //
152 struct any_conversion
153 {
154     template <typename T> any_conversion(const volatile T&);
155     // we need this constructor to catch references to functions
156     // (which can not be cv-qualified):
157     template <typename T> any_conversion(T&);
158 };
159
160 template <typename From, typename To>
161 struct is_convertible_basic_impl
162 {
163     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
164     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
165     static typename add_rvalue_reference<From>::type  _m_from;
166
167     BOOST_STATIC_CONSTANT(bool, value =
168         sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
169         );
170 };
171
172 #elif defined(__DMC__)
173
174 struct any_conversion
175 {
176     template <typename T> any_conversion(const volatile T&);
177     // we need this constructor to catch references to functions
178     // (which can not be cv-qualified):
179     template <typename T> any_conversion(T&);
180 };
181
182 template <typename From, typename To>
183 struct is_convertible_basic_impl
184 {
185     // Using '...' doesn't always work on Digital Mars. This version seems to.
186     template <class T>
187     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion,  float, T);
188     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int, int);
189     static typename add_rvalue_reference<From>::type  _m_from;
190
191     // Static constants sometime cause the conversion of _m_from to To to be
192     // called. This doesn't happen with an enum.
193     enum { value =
194         sizeof( _m_check(_m_from, 0, 0) ) == sizeof(::boost::type_traits::yes_type)
195         };
196 };
197
198 #elif defined(__MWERKS__)
199 // 
200 // CW works with the technique implemented above for EDG, except when From
201 // is a function type (or a reference to such a type), in which case
202 // any_conversion won't be accepted as a valid conversion. We detect this
203 // exceptional situation and channel it through an alternative algorithm.
204 //
205
206 template <typename From, typename To,bool FromIsFunctionRef>
207 struct is_convertible_basic_impl_aux;
208
209 struct any_conversion
210 {
211     template <typename T> any_conversion(const volatile T&);
212 };
213
214 template <typename From, typename To>
215 struct is_convertible_basic_impl_aux<From,To,false /*FromIsFunctionRef*/>
216 {
217     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
218     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
219     static typename add_rvalue_reference<From>::type  _m_from;
220
221     BOOST_STATIC_CONSTANT(bool, value =
222         sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
223         );
224 };
225
226 template <typename From, typename To>
227 struct is_convertible_basic_impl_aux<From,To,true /*FromIsFunctionRef*/>
228 {
229     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
230     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
231     static typename add_rvalue_reference<From>::type  _m_from;
232     BOOST_STATIC_CONSTANT(bool, value =
233         sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
234         );
235 };
236
237 template <typename From, typename To>
238 struct is_convertible_basic_impl:
239   is_convertible_basic_impl_aux<
240     From,To,
241     ::boost::is_function<typename ::boost::remove_reference<From>::type>::value
242   >
243 {};
244
245 #else
246
247 //
248 // This version seems to work pretty well for a wide spectrum of compilers,
249 // however it does rely on undefined behaviour by passing UDT's through (...).
250 //
251 template <typename From, typename To>
252 struct is_convertible_basic_impl
253 {
254     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
255     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
256     static typename add_rvalue_reference<From>::type  _m_from;
257 #ifdef BOOST_MSVC
258 #pragma warning(push)
259 #pragma warning(disable:4244)
260 #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
261 #pragma warning(disable:6334)
262 #endif
263 #endif
264     BOOST_STATIC_CONSTANT(bool, value =
265         sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
266         );
267 #ifdef BOOST_MSVC
268 #pragma warning(pop)
269 #endif
270 };
271
272 #endif // is_convertible_impl
273
274 #if defined(__DMC__)
275 // As before, a static constant sometimes causes errors on Digital Mars.
276 template <typename From, typename To>
277 struct is_convertible_impl
278 {
279     typedef typename add_reference<From>::type ref_type;
280     enum { value =
281         (::boost::type_traits::ice_and<
282             ::boost::type_traits::ice_or<
283                ::boost::detail::is_convertible_basic_impl<ref_type,To>::value,
284                ::boost::is_void<To>::value
285             >::value,
286             ::boost::type_traits::ice_not<
287                ::boost::is_array<To>::value
288             >::value
289         >::value) };
290 };
291 #elif !defined(__BORLANDC__) || __BORLANDC__ > 0x551
292 template <typename From, typename To>
293 struct is_convertible_impl
294 {
295     typedef typename add_reference<From>::type ref_type;
296     BOOST_STATIC_CONSTANT(bool, value =
297         (::boost::type_traits::ice_and<
298             ::boost::type_traits::ice_or<
299                ::boost::detail::is_convertible_basic_impl<ref_type,To>::value,
300                ::boost::is_void<To>::value
301             >::value,
302             ::boost::type_traits::ice_not<
303                ::boost::is_array<To>::value
304             >::value
305         >::value)
306         );
307 };
308 #endif
309
310 template <bool trivial1, bool trivial2, bool abstract_target>
311 struct is_convertible_impl_select
312 {
313    template <class From, class To>
314    struct rebind
315    {
316       typedef is_convertible_impl<From, To> type;
317    };
318 };
319
320 template <>
321 struct is_convertible_impl_select<true, true, false>
322 {
323    template <class From, class To>
324    struct rebind
325    {
326       typedef true_type type;
327    };
328 };
329
330 template <>
331 struct is_convertible_impl_select<false, false, true>
332 {
333    template <class From, class To>
334    struct rebind
335    {
336       typedef false_type type;
337    };
338 };
339
340 template <>
341 struct is_convertible_impl_select<true, false, true>
342 {
343    template <class From, class To>
344    struct rebind
345    {
346       typedef false_type type;
347    };
348 };
349
350 template <typename From, typename To>
351 struct is_convertible_impl_dispatch_base
352 {
353 #if !BOOST_WORKAROUND(__HP_aCC, < 60700)
354    typedef is_convertible_impl_select< 
355       ::boost::is_arithmetic<From>::value, 
356       ::boost::is_arithmetic<To>::value,
357 #ifndef BOOST_NO_IS_ABSTRACT
358       ::boost::is_abstract<To>::value
359 #else
360       false
361 #endif
362    > selector;
363 #else
364    typedef is_convertible_impl_select<false, false, false> selector;
365 #endif
366    typedef typename selector::template rebind<From, To> isc_binder;
367    typedef typename isc_binder::type type;
368 };
369
370 template <typename From, typename To>
371 struct is_convertible_impl_dispatch 
372    : public is_convertible_impl_dispatch_base<From, To>::type
373 {};
374
375 //
376 // Now add the full and partial specialisations
377 // for void types, these are common to all the
378 // implementation above:
379 //
380 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
381 #   define TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1,spec2,value) \
382     BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2,value) \
383     BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2 const,value) \
384     BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2 volatile,value) \
385     BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2 const volatile,value) \
386     /**/
387
388 #   define TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2(trait,spec1,spec2,value) \
389     TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1,spec2,value) \
390     TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1 const,spec2,value) \
391     TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1 volatile,spec2,value) \
392     TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1 const volatile,spec2,value) \
393     /**/
394
395     TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2(is_convertible,void,void,true)
396
397 #   undef TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2
398 #   undef TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1
399
400 #else
401     BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(is_convertible,void,void,true)
402 #endif // BOOST_NO_CV_VOID_SPECIALIZATIONS
403
404 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
405 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void,To,false)
406 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void,false)
407 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
408 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void const,To,false)
409 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void volatile,To,false)
410 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void const volatile,To,false)
411 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const,false)
412 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void volatile,false)
413 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const volatile,false)
414 #endif
415 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
416
417 } // namespace detail
418
419 BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,(::boost::detail::is_convertible_impl_dispatch<From,To>::value))
420
421 #else
422
423 BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,BOOST_IS_CONVERTIBLE(From,To))
424
425 #endif
426
427 } // namespace boost
428
429 #include <boost/type_traits/detail/bool_trait_undef.hpp>
430
431 #endif // BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED