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