~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/type_traits/is_convertible.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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ļæ½rvi (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_TT_IS_CONVERTIBLE_HPP_INCLUDED
 
17
#define BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
 
18
 
 
19
#include "boost/type_traits/detail/yes_no_type.hpp"
 
20
#include "boost/type_traits/config.hpp"
 
21
#include "boost/type_traits/is_array.hpp"
 
22
#include "boost/type_traits/add_reference.hpp"
 
23
#include "boost/type_traits/ice.hpp"
 
24
 
 
25
#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
 
26
#   include "boost/type_traits/is_void.hpp"
 
27
#endif
 
28
 
 
29
// should be always the last #include directive
 
30
#include "boost/type_traits/detail/bool_trait_def.hpp"
 
31
 
 
32
namespace boost {
 
33
 
 
34
// is one type convertable to another?
 
35
//
 
36
// there are multiple versions of the is_convertible
 
37
// template, almost every compiler seems to require its
 
38
// own version.
 
39
//
 
40
// Thanks to Andrei Alexandrescu for the original version of the
 
41
// conversion detection technique!
 
42
//
 
43
 
 
44
namespace detail {
 
45
 
 
46
// MS specific version:
 
47
 
 
48
#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
 
49
 
 
50
// This workaround is necessary to handle when From is void
 
51
// which is normally taken care of by the partial specialization
 
52
// of the is_convertible typename.
 
53
using ::boost::type_traits::yes_type;
 
54
using ::boost::type_traits::no_type;
 
55
 
 
56
template< typename From >
 
57
struct does_conversion_exist
 
58
{
 
59
    template< typename To > struct result_
 
60
    {
 
61
        static no_type BOOST_TT_DECL _m_check(...);
 
62
        static yes_type BOOST_TT_DECL _m_check(To);
 
63
        static From _m_from;
 
64
        enum { value = sizeof( _m_check(_m_from) ) == sizeof(yes_type) };
 
65
    };
 
66
};
 
67
 
 
68
template<>
 
69
struct does_conversion_exist<void>
 
70
{
 
71
    template< typename To > struct result_
 
72
    {
 
73
        enum { value = ::boost::is_void<To>::value };
 
74
    };
 
75
};
 
76
 
 
77
template <typename From, typename To>
 
78
struct is_convertible_basic_impl
 
79
    : does_conversion_exist<From>::template result_<To>
 
80
{
 
81
};
 
82
 
 
83
#elif defined(__BORLANDC__) && (__BORLANDC__ < 0x560)
 
84
//
 
85
// special version for Borland compilers
 
86
// this version breaks when used for some
 
87
// UDT conversions:
 
88
//
 
89
template <typename From, typename To>
 
90
struct is_convertible_impl
 
91
{
 
92
#pragma option push -w-8074
 
93
    // This workaround for Borland breaks the EDG C++ frontend,
 
94
    // so we only use it for Borland.
 
95
    template <typename T> struct checker
 
96
    {
 
97
        static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
 
98
        static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(T);
 
99
    };
 
100
 
 
101
    static From _m_from;
 
102
    static bool const value = sizeof( checker<To>::_m_check(_m_from) ) 
 
103
        == sizeof(::boost::type_traits::yes_type);
 
104
#pragma option pop
 
105
};
 
106
 
 
107
#elif defined(__GNUC__) || defined(__BORLANDC__)
 
108
// special version for gcc compiler + recent Borland versions
 
109
// note that this does not pass UDT's through (...)
 
110
 
 
111
struct any_conversion
 
112
{
 
113
    template <typename T> any_conversion(const volatile T&);
 
114
    //template <typename T> any_conversion(T&);
 
115
};
 
116
 
 
117
template <typename T> struct checker
 
118
{
 
119
    static boost::type_traits::no_type _m_check(any_conversion ...);
 
120
    static boost::type_traits::yes_type _m_check(T, int);
 
121
};
 
122
 
 
123
template <typename From, typename To>
 
124
struct is_convertible_basic_impl
 
125
{
 
126
    static From _m_from;
 
127
    static bool const value = sizeof( detail::checker<To>::_m_check(_m_from, 0) ) 
 
128
        == sizeof(::boost::type_traits::yes_type);
 
129
};
 
130
 
 
131
#elif (defined(BOOST_MSVC) && (BOOST_MSVC > 1310)) \
 
132
      || (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL))
 
133
//
 
134
// This is *almost* an ideal world implementation as it doesn't rely
 
135
// on undefined behaviour by passing UDT's through (...).
 
136
// Unfortunately it doesn't quite pass all the tests for most compilers (sigh...)
 
137
// Enable this for your compiler if is_convertible_test.cpp will compile it...
 
138
//
 
139
struct any_conversion
 
140
{
 
141
    template <typename T> any_conversion(const volatile T&);
 
142
    // we need this constructor to catch references to functions
 
143
    // (which can not be cv-qualified):
 
144
    template <typename T> any_conversion(T&);
 
145
};
 
146
 
 
147
template <typename From, typename To>
 
148
struct is_convertible_basic_impl
 
149
{
 
150
    static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
 
151
    static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
 
152
            static From _m_from;
 
153
 
 
154
    BOOST_STATIC_CONSTANT(bool, value = 
 
155
        sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
 
156
        );
 
157
};
 
158
 
 
159
#else
 
160
 
 
161
//
 
162
// This version seems to work pretty well for a wide spectrum of compilers, 
 
163
// however it does rely on undefined behaviour by passing UDT's through (...).
 
164
//
 
165
template <typename From, typename To>
 
166
struct is_convertible_basic_impl
 
167
{
 
168
    static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
 
169
    static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
 
170
    static From _m_from;
 
171
 
 
172
    BOOST_STATIC_CONSTANT(bool, value =
 
173
        sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
 
174
        );
 
175
};
 
176
 
 
177
#endif // is_convertible_impl
 
178
 
 
179
#if !defined(__BORLANDC__) || __BORLANDC__ > 0x551
 
180
template <typename From, typename To>
 
181
struct is_convertible_impl
 
182
{
 
183
    typedef typename add_reference<From>::type ref_type;
 
184
    BOOST_STATIC_CONSTANT(bool, value =
 
185
        (::boost::type_traits::ice_and<
 
186
            ::boost::detail::is_convertible_basic_impl<ref_type,To>::value,
 
187
            ::boost::type_traits::ice_not<
 
188
               ::boost::is_array<To>::value
 
189
            >::value
 
190
        >::value)
 
191
        );
 
192
};
 
193
#endif
 
194
 
 
195
//
 
196
// Now add the full and partial specialisations
 
197
// for void types, these are common to all the
 
198
// implementation above:
 
199
//
 
200
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
 
201
#   define TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1,spec2,value) \
 
202
    BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2,value) \
 
203
    BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2 const,value) \
 
204
    BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2 volatile,value) \
 
205
    BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(trait,spec1,spec2 const volatile,value) \
 
206
    /**/
 
207
 
 
208
#   define TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2(trait,spec1,spec2,value) \
 
209
    TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1,spec2,value) \
 
210
    TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1 const,spec2,value) \
 
211
    TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1 volatile,spec2,value) \
 
212
    TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1(trait,spec1 const volatile,spec2,value) \
 
213
    /**/
 
214
 
 
215
    TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2(is_convertible,void,void,true)
 
216
 
 
217
#   undef TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2
 
218
#   undef TT_AUX_BOOL_CV_VOID_TRAIT_SPEC2_PART1
 
219
 
 
220
#else
 
221
    BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC2(is_convertible,void,void,true)
 
222
#endif // BOOST_NO_CV_VOID_SPECIALIZATIONS
 
223
 
 
224
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 
225
BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void,To,false)
 
226
BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void,false)
 
227
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
 
228
BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void const,To,false)
 
229
BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void volatile,To,false)
 
230
BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void const volatile,To,false)
 
231
BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const,false)
 
232
BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void volatile,false)
 
233
BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const volatile,false)
 
234
#endif
 
235
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 
236
 
 
237
} // namespace detail
 
238
 
 
239
BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,(::boost::detail::is_convertible_impl<From,To>::value))
 
240
 
 
241
 
 
242
#if defined(__GNUC__)
 
243
 
 
244
// Declare specializations of is_convertible for all of the floating
 
245
// types to all of the integral types. This suppresses some nasty
 
246
// warnings
 
247
 
 
248
#   define TT_AUX_IS_CONVERTIBLE_SPEC(T1,T2) \
 
249
    BOOST_TT_AUX_BOOL_TRAIT_SPEC2(is_convertible,T1,T2,true) \
 
250
    /**/
 
251
 
 
252
#   define TT_AUX_IS_CONVERTIBLE_SPEC_2(T1,T2) \
 
253
    TT_AUX_IS_CONVERTIBLE_SPEC(T1,signed T2) \
 
254
    TT_AUX_IS_CONVERTIBLE_SPEC(T1,unsigned T2) \
 
255
    /**/
 
256
 
 
257
#   define TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC(F) \
 
258
    TT_AUX_IS_CONVERTIBLE_SPEC(F,char) \
 
259
    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,char) \
 
260
    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,short) \
 
261
    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,int) \
 
262
    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,long) \
 
263
    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,long long) \
 
264
    /**/
 
265
 
 
266
#   define TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(F) \
 
267
    TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC(F const) \
 
268
    TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC(F volatile) \
 
269
    TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC(F const volatile) \
 
270
    /**/
 
271
 
 
272
TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(float)
 
273
TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(double)
 
274
TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(long double)
 
275
 
 
276
#   undef TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC
 
277
#   undef TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC
 
278
#   undef TT_AUX_IS_CONVERTIBLE_SPEC_2
 
279
#   undef TT_AUX_IS_CONVERTIBLE_SPEC
 
280
 
 
281
#endif // __GNUC__
 
282
 
 
283
} // namespace boost
 
284
 
 
285
#include "boost/type_traits/detail/bool_trait_undef.hpp"
 
286
 
 
287
#endif // BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED