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