New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
is_convertible.hpp in vendors/XIOS/current/extern/boost/include/boost/type_traits – NEMO

source: vendors/XIOS/current/extern/boost/include/boost/type_traits/is_convertible.hpp @ 3428

Last change on this file since 3428 was 3428, checked in by rblod, 12 years ago

importing initial XIOS vendor drop

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