Home | History | Annotate | Download | only in stl
      1 /*
      2  *
      3  * Copyright (c) 1996,1997
      4  * Silicon Graphics Computer Systems, Inc.
      5  *
      6  * Copyright (c) 1997
      7  * Moscow Center for SPARC Technology
      8  *
      9  * Copyright (c) 1999
     10  * Boris Fomitchev
     11  *
     12  * This material is provided "as is", with absolutely no warranty expressed
     13  * or implied. Any use is at your own risk.
     14  *
     15  * Permission to use or copy this software for any purpose is hereby granted
     16  * without fee, provided the above notices are retained on all copies.
     17  * Permission to modify the code and to distribute modified code is granted,
     18  * provided the above notices are retained, and a notice that the code was
     19  * modified is included with the above copyright notice.
     20  *
     21  */
     22 
     23 #ifndef _STLP_TYPE_TRAITS_H
     24 #define _STLP_TYPE_TRAITS_H
     25 
     26 /*
     27 This header file provides a framework for allowing compile time dispatch
     28 based on type attributes. This is useful when writing template code.
     29 For example, when making a copy of an array of an unknown type, it helps
     30 to know if the type has a trivial copy constructor or not, to help decide
     31 if a memcpy can be used.
     32 
     33 The class template __type_traits provides a series of typedefs each of
     34 which is either __true_type or __false_type. The argument to
     35 __type_traits can be any type. The typedefs within this template will
     36 attain their correct values by one of these means:
     37     1. The general instantiation contain conservative values which work
     38        for all types.
     39     2. Specializations may be declared to make distinctions between types.
     40     3. Some compilers (such as the Silicon Graphics N32 and N64 compilers)
     41        will automatically provide the appropriate specializations for all
     42        types.
     43 
     44 EXAMPLE:
     45 
     46 //Copy an array of elements which have non-trivial copy constructors
     47 template <class T> void copy(T* source, T* destination, int n, __false_type);
     48 //Copy an array of elements which have trivial copy constructors. Use memcpy.
     49 template <class T> void copy(T* source, T* destination, int n, __true_type);
     50 
     51 //Copy an array of any type by using the most efficient copy mechanism
     52 template <class T> inline void copy(T* source,T* destination,int n) {
     53    copy(source, destination, n,
     54         typename __type_traits<T>::has_trivial_copy_constructor());
     55 }
     56 */
     57 
     58 #ifdef __WATCOMC__
     59 #  include <stl/_cwchar.h>
     60 #endif
     61 
     62 #ifndef _STLP_TYPE_MANIPS_H
     63 #  include <stl/type_manips.h>
     64 #endif
     65 
     66 #ifdef _STLP_USE_BOOST_SUPPORT
     67 #  include <stl/boost_type_traits.h>
     68 #  include <boost/type_traits/add_reference.hpp>
     69 #  include <boost/type_traits/add_const.hpp>
     70 #endif /* _STLP_USE_BOOST_SUPPORT */
     71 
     72 _STLP_BEGIN_NAMESPACE
     73 
     74 #if !defined (_STLP_USE_BOOST_SUPPORT)
     75 
     76 // The following could be written in terms of numeric_limits.
     77 // We're doing it separately to reduce the number of dependencies.
     78 
     79 template <class _Tp> struct _IsIntegral
     80 { typedef __false_type _Ret; };
     81 
     82 #  ifndef _STLP_NO_BOOL
     83 _STLP_TEMPLATE_NULL struct _IsIntegral<bool>
     84 { typedef __true_type _Ret; };
     85 #  endif /* _STLP_NO_BOOL */
     86 
     87 _STLP_TEMPLATE_NULL struct _IsIntegral<char>
     88 { typedef __true_type _Ret; };
     89 
     90 #  ifndef _STLP_NO_SIGNED_BUILTINS
     91 _STLP_TEMPLATE_NULL struct _IsIntegral<signed char>
     92 { typedef __true_type _Ret; };
     93 #  endif
     94 
     95 _STLP_TEMPLATE_NULL struct _IsIntegral<unsigned char>
     96 { typedef __true_type _Ret; };
     97 
     98 #  if defined ( _STLP_HAS_WCHAR_T ) && ! defined (_STLP_WCHAR_T_IS_USHORT)
     99 _STLP_TEMPLATE_NULL struct _IsIntegral<wchar_t>
    100 { typedef __true_type _Ret; };
    101 #  endif /* _STLP_HAS_WCHAR_T */
    102 
    103 _STLP_TEMPLATE_NULL struct _IsIntegral<short>
    104 { typedef __true_type _Ret; };
    105 
    106 _STLP_TEMPLATE_NULL struct _IsIntegral<unsigned short>
    107 { typedef __true_type _Ret; };
    108 
    109 _STLP_TEMPLATE_NULL struct _IsIntegral<int>
    110 { typedef __true_type _Ret; };
    111 
    112 _STLP_TEMPLATE_NULL struct _IsIntegral<unsigned int>
    113 { typedef __true_type _Ret; };
    114 
    115 _STLP_TEMPLATE_NULL struct _IsIntegral<long>
    116 { typedef __true_type _Ret; };
    117 
    118 _STLP_TEMPLATE_NULL struct _IsIntegral<unsigned long>
    119 { typedef __true_type _Ret; };
    120 
    121 #  ifdef _STLP_LONG_LONG
    122 _STLP_TEMPLATE_NULL struct _IsIntegral<_STLP_LONG_LONG>
    123 { typedef __true_type _Ret; };
    124 
    125 _STLP_TEMPLATE_NULL struct _IsIntegral<unsigned _STLP_LONG_LONG>
    126 { typedef __true_type _Ret; };
    127 #  endif /* _STLP_LONG_LONG */
    128 
    129 template <class _Tp> struct _IsRational
    130 { typedef __false_type _Ret; };
    131 
    132 _STLP_TEMPLATE_NULL struct _IsRational<float>
    133 { typedef __true_type _Ret; };
    134 
    135 _STLP_TEMPLATE_NULL struct _IsRational<double>
    136 { typedef __true_type _Ret; };
    137 
    138 #  if !defined ( _STLP_NO_LONG_DOUBLE )
    139 _STLP_TEMPLATE_NULL struct _IsRational<long double>
    140 { typedef __true_type _Ret; };
    141 #  endif
    142 
    143 // Forward declarations.
    144 template <class _Tp> struct __type_traits;
    145 template <class _IsPOD> struct __type_traits_aux {
    146    typedef __false_type    has_trivial_default_constructor;
    147    typedef __false_type    has_trivial_copy_constructor;
    148    typedef __false_type    has_trivial_assignment_operator;
    149    typedef __false_type    has_trivial_destructor;
    150    typedef __false_type    is_POD_type;
    151 };
    152 
    153 _STLP_TEMPLATE_NULL
    154 struct __type_traits_aux<__false_type> {
    155    typedef __false_type    has_trivial_default_constructor;
    156    typedef __false_type    has_trivial_copy_constructor;
    157    typedef __false_type    has_trivial_assignment_operator;
    158    typedef __false_type    has_trivial_destructor;
    159    typedef __false_type    is_POD_type;
    160 };
    161 
    162 _STLP_TEMPLATE_NULL
    163 struct __type_traits_aux<__true_type> {
    164   typedef __true_type    has_trivial_default_constructor;
    165   typedef __true_type    has_trivial_copy_constructor;
    166   typedef __true_type    has_trivial_assignment_operator;
    167   typedef __true_type    has_trivial_destructor;
    168   typedef __true_type    is_POD_type;
    169 };
    170 
    171 template <class _Tp>
    172 struct _IsRef {
    173   typedef __false_type _Ret;
    174 };
    175 
    176 #  if defined (_STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS)
    177 /*
    178  * Boris : simulation technique is used here according to Adobe Open Source License Version 1.0.
    179  * Copyright 2000 Adobe Systems Incorporated and others. All rights reserved.
    180  * Authors: Mat Marcus and Jesse Jones
    181  * The original version of this source code may be found at
    182  * http://opensource.adobe.com.
    183  */
    184 
    185 struct _PointerShim {
    186   /*
    187    * Since the compiler only allows at most one non-trivial
    188    * implicit conversion we can make use of a shim class to
    189    * be sure that IsPtr below doesn't accept classes with
    190    * implicit pointer conversion operators
    191    */
    192   _PointerShim(const volatile void*); // no implementation
    193 };
    194 
    195 // These are the discriminating functions
    196 char _STLP_CALL _IsP(bool, _PointerShim);  // no implementation is required
    197 char* _STLP_CALL _IsP(bool, ...);          // no implementation is required
    198 
    199 template <class _Tp>
    200 struct _IsPtr {
    201   /*
    202    * This template meta function takes a type T
    203    * and returns true exactly when T is a pointer.
    204    * One can imagine meta-functions discriminating on
    205    * other criteria.
    206    */
    207   static _Tp& __null_rep();
    208   enum { _Ptr = (sizeof(_IsP(false,__null_rep())) == sizeof(char)) };
    209   typedef typename __bool2type<_Ptr>::_Ret _Ret;
    210 
    211 };
    212 
    213 // we make general case dependant on the fact the type is actually a pointer.
    214 template <class _Tp>
    215 struct __type_traits : __type_traits_aux<typename _IsPtr<_Tp>::_Ret> {};
    216 
    217 #  else /* _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS */
    218 
    219 template <class _Tp>  struct _IsPtr {
    220   typedef __false_type _Ret;
    221 };
    222 
    223 template <class _Tp>
    224 struct __type_traits {
    225    typedef __true_type     this_dummy_member_must_be_first;
    226                    /* Do not remove this member. It informs a compiler which
    227                       automatically specializes __type_traits that this
    228                       __type_traits template is special. It just makes sure that
    229                       things work if an implementation is using a template
    230                       called __type_traits for something unrelated. */
    231 
    232    /* The following restrictions should be observed for the sake of
    233       compilers which automatically produce type specific specializations
    234       of this class:
    235           - You may reorder the members below if you wish
    236           - You may remove any of the members below if you wish
    237           - You must not rename members without making the corresponding
    238             name change in the compiler
    239           - Members you add will be treated like regular members unless
    240 
    241             you add the appropriate support in the compiler. */
    242 #    if !defined (_STLP_HAS_TYPE_TRAITS_INTRINSICS)
    243    typedef __false_type    has_trivial_default_constructor;
    244    typedef __false_type    has_trivial_copy_constructor;
    245    typedef __false_type    has_trivial_assignment_operator;
    246    typedef __false_type    has_trivial_destructor;
    247    typedef __false_type    is_POD_type;
    248 #    else
    249    typedef typename __bool2type<_STLP_HAS_TRIVIAL_CONSTRUCTOR(_Tp)>::_Ret has_trivial_default_constructor;
    250    typedef typename __bool2type<_STLP_HAS_TRIVIAL_COPY(_Tp)>::_Ret has_trivial_copy_constructor;
    251    typedef typename __bool2type<_STLP_HAS_TRIVIAL_ASSIGN(_Tp)>::_Ret has_trivial_assignment_operator;
    252    typedef typename __bool2type<_STLP_HAS_TRIVIAL_DESTRUCTOR(_Tp)>::_Ret has_trivial_destructor;
    253    typedef typename __bool2type<_STLP_IS_POD(_Tp)>::_Ret is_POD_type;
    254 #    endif
    255 };
    256 
    257 #    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    258 template <class _Tp> struct _IsPtr<_Tp*>
    259 { typedef __true_type _Ret; };
    260 template <class _Tp> struct _IsRef<_Tp&>
    261 { typedef __true_type _Ret; };
    262 
    263 template <class _Tp> struct __type_traits<_Tp*> : __type_traits_aux<__true_type>
    264 {};
    265 #    endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
    266 
    267 #  endif /* _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS */
    268 
    269 // Provide some specializations.  This is harmless for compilers that
    270 //  have built-in __types_traits support, and essential for compilers
    271 //  that don't.
    272 #  if !defined (_STLP_QUALIFIED_SPECIALIZATION_BUG)
    273 #    define _STLP_DEFINE_TYPE_TRAITS_FOR(Type) \
    274 _STLP_TEMPLATE_NULL struct __type_traits< Type > : __type_traits_aux<__true_type> {}; \
    275 _STLP_TEMPLATE_NULL struct __type_traits< const Type > : __type_traits_aux<__true_type> {}; \
    276 _STLP_TEMPLATE_NULL struct __type_traits< volatile Type > : __type_traits_aux<__true_type> {}; \
    277 _STLP_TEMPLATE_NULL struct __type_traits< const volatile Type > : __type_traits_aux<__true_type> {}
    278 #  else
    279 #    define _STLP_DEFINE_TYPE_TRAITS_FOR(Type) \
    280 _STLP_TEMPLATE_NULL struct __type_traits< Type > : __type_traits_aux<__true_type> {};
    281 #  endif
    282 
    283 #  ifndef _STLP_NO_BOOL
    284 _STLP_DEFINE_TYPE_TRAITS_FOR(bool);
    285 #  endif /* _STLP_NO_BOOL */
    286 _STLP_DEFINE_TYPE_TRAITS_FOR(char);
    287 #  ifndef _STLP_NO_SIGNED_BUILTINS
    288 _STLP_DEFINE_TYPE_TRAITS_FOR(signed char);
    289 #  endif
    290 _STLP_DEFINE_TYPE_TRAITS_FOR(unsigned char);
    291 #  if defined ( _STLP_HAS_WCHAR_T ) && ! defined (_STLP_WCHAR_T_IS_USHORT)
    292 _STLP_DEFINE_TYPE_TRAITS_FOR(wchar_t);
    293 #  endif /* _STLP_HAS_WCHAR_T */
    294 
    295 _STLP_DEFINE_TYPE_TRAITS_FOR(short);
    296 _STLP_DEFINE_TYPE_TRAITS_FOR(unsigned short);
    297 _STLP_DEFINE_TYPE_TRAITS_FOR(int);
    298 _STLP_DEFINE_TYPE_TRAITS_FOR(unsigned int);
    299 _STLP_DEFINE_TYPE_TRAITS_FOR(long);
    300 _STLP_DEFINE_TYPE_TRAITS_FOR(unsigned long);
    301 
    302 #  ifdef _STLP_LONG_LONG
    303 _STLP_DEFINE_TYPE_TRAITS_FOR(_STLP_LONG_LONG);
    304 _STLP_DEFINE_TYPE_TRAITS_FOR(unsigned _STLP_LONG_LONG);
    305 #  endif /* _STLP_LONG_LONG */
    306 
    307 _STLP_DEFINE_TYPE_TRAITS_FOR(float);
    308 _STLP_DEFINE_TYPE_TRAITS_FOR(double);
    309 
    310 #  if !defined ( _STLP_NO_LONG_DOUBLE )
    311 _STLP_DEFINE_TYPE_TRAITS_FOR(long double);
    312 #  endif
    313 
    314 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    315 template <class _ArePtrs, class _Src, class _Dst>
    316 struct _IsCVConvertibleIf
    317 { typedef typename _IsCVConvertible<_Src, _Dst>::_Ret _Ret; };
    318 
    319 template <class _Src, class _Dst>
    320 struct _IsCVConvertibleIf<__false_type, _Src, _Dst>
    321 { typedef __false_type _Ret; };
    322 #  else
    323 #    if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
    324 template <class _ArePtrs>
    325 struct _IsCVConvertibleIfAux {
    326   template <class _Src, class _Dst>
    327   struct _In
    328   { typedef typename _IsCVConvertible<_Src, _Dst>::_Ret _Ret; };
    329 };
    330 
    331 _STLP_TEMPLATE_NULL
    332 struct _IsCVConvertibleIfAux<__false_type> {
    333   template <class _Src, class _Dst>
    334   struct _In
    335   { typedef __false_type _Ret; };
    336 };
    337 
    338 template <class _ArePtrs, class _Src, class _Dst>
    339 struct _IsCVConvertibleIf {
    340   typedef typename _IsCVConvertibleIfAux<_ArePtrs>::_STLP_TEMPLATE _In<_Src, _Dst>::_Ret _Ret;
    341 };
    342 #    else
    343 /* default behavior: we prefer to miss an optimization rather than taking the risk of
    344  * a compilation error if playing with types with exotic memory alignment.
    345  */
    346 template <class _ArePtrs, class _Src, class _Dst>
    347 struct _IsCVConvertibleIf
    348 { typedef __false_type _Ret; };
    349 #    endif
    350 #  endif
    351 
    352 template <class _Src, class _Dst>
    353 struct _TrivialNativeTypeCopy {
    354   typedef typename _IsPtr<_Src>::_Ret _Ptr1;
    355   typedef typename _IsPtr<_Dst>::_Ret _Ptr2;
    356   typedef typename _Land2<_Ptr1, _Ptr2>::_Ret _BothPtrs;
    357   typedef typename _IsCVConvertibleIf<_BothPtrs, _Src, _Dst>::_Ret _Convertible;
    358   typedef typename _Land2<_BothPtrs, _Convertible>::_Ret _Trivial1;
    359 
    360   typedef typename __bool2type<(sizeof(_Src) == sizeof(_Dst))>::_Ret _SameSize;
    361 
    362 #if !defined (__BORLANDC__) || (__BORLANDC__ < 0x564)
    363   typedef typename _IsIntegral<_Src>::_Ret _Int1;
    364 #else
    365   typedef typename _UnQual<_Src>::_Type _UnQuSrc;
    366   typedef typename _IsIntegral<_UnQuSrc>::_Ret _Int1;
    367 #endif
    368   typedef typename _IsIntegral<_Dst>::_Ret _Int2;
    369   typedef typename _Land2<_Int1, _Int2>::_Ret _BothInts;
    370 
    371   typedef typename _IsRational<_Src>::_Ret _Rat1;
    372   typedef typename _IsRational<_Dst>::_Ret _Rat2;
    373   typedef typename _Land2<_Rat1, _Rat2>::_Ret _BothRats;
    374 
    375   typedef typename _Lor2<_BothInts, _BothRats>::_Ret _BothNatives;
    376 #if !defined (__BORLANDC__) || (__BORLANDC__ >= 0x564)
    377   typedef typename _Land2<_BothNatives, _SameSize>::_Ret _Trivial2;
    378 #else
    379   typedef typename _IsUnQual<_Dst>::_Ret _UnQualDst;
    380   typedef typename _Land3<_BothNatives, _SameSize, _UnQualDst>::_Ret _Trivial2;
    381 #endif
    382   typedef typename _Lor2<_Trivial1, _Trivial2>::_Ret _Ret;
    383 };
    384 
    385 template <class _Src, class _Dst>
    386 struct _TrivialCopy {
    387   typedef typename _TrivialNativeTypeCopy<_Src, _Dst>::_Ret _NativeRet;
    388 #  if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
    389   typedef typename __type_traits<_Src>::has_trivial_assignment_operator _Tr1;
    390 #  else
    391   typedef typename _UnConstPtr<_Src*>::_Type _UnConstSrc;
    392   typedef typename __type_traits<_UnConstSrc>::has_trivial_assignment_operator _Tr1;
    393 #  endif
    394   typedef typename _AreCopyable<_Src, _Dst>::_Ret _Tr2;
    395   typedef typename _Land2<_Tr1, _Tr2>::_Ret _UserRet;
    396   typedef typename _Lor2<_NativeRet, _UserRet>::_Ret _Ret;
    397   static _Ret _Answer() { return _Ret(); }
    398 };
    399 
    400 template <class _Src, class _Dst>
    401 struct _TrivialUCopy {
    402   typedef typename _TrivialNativeTypeCopy<_Src, _Dst>::_Ret _NativeRet;
    403 #  if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
    404   typedef typename __type_traits<_Src>::has_trivial_copy_constructor _Tr1;
    405 #  else
    406   typedef typename _UnConstPtr<_Src*>::_Type _UnConstSrc;
    407   typedef typename __type_traits<_UnConstSrc>::has_trivial_copy_constructor _Tr1;
    408 #  endif
    409   typedef typename _AreCopyable<_Src, _Dst>::_Ret _Tr2;
    410   typedef typename _Land2<_Tr1, _Tr2>::_Ret _UserRet;
    411   typedef typename _Lor2<_NativeRet, _UserRet>::_Ret _Ret;
    412   static _Ret _Answer() { return _Ret(); }
    413 };
    414 
    415 template <class _Tp>
    416 struct _DefaultZeroValue {
    417   typedef typename _IsIntegral<_Tp>::_Ret _Tr1;
    418   typedef typename _IsRational<_Tp>::_Ret _Tr2;
    419   typedef typename _IsPtr<_Tp>::_Ret _Tr3;
    420   typedef typename _Lor3<_Tr1, _Tr2, _Tr3>::_Ret _Ret;
    421 };
    422 
    423 template <class _Tp>
    424 struct _TrivialInit {
    425 #  if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
    426   typedef typename __type_traits<_Tp>::has_trivial_default_constructor _Tr1;
    427 #  else
    428   typedef typename _UnConstPtr<_Tp*>::_Type _Tp1;
    429   typedef typename __type_traits<_Tp1>::has_trivial_copy_constructor _Tr1;
    430 #  endif
    431   typedef typename _DefaultZeroValue<_Tp>::_Ret _Tr2;
    432   typedef typename _Not<_Tr2>::_Ret _Tr3;
    433   typedef typename _Land2<_Tr1, _Tr3>::_Ret _Ret;
    434   static _Ret _Answer() { return _Ret(); }
    435 };
    436 
    437 #endif /* !_STLP_USE_BOOST_SUPPORT */
    438 
    439 template <class _Tp>
    440 struct _IsPtrType {
    441   typedef typename _IsPtr<_Tp>::_Ret _Type;
    442   static _Type _Ret() { return _Type(); }
    443 };
    444 
    445 template <class _Tp>
    446 struct _IsRefType {
    447   typedef typename _IsRef<_Tp>::_Ret _Type;
    448   static _Type _Ret() { return _Type();}
    449 };
    450 
    451 template <class _Tp>
    452 struct __call_traits {
    453 #if defined (_STLP_USE_BOOST_SUPPORT) && !defined (_STLP_NO_EXTENSIONS)
    454   typedef typename __select< ::boost::is_reference<_Tp>::value,
    455                              typename ::boost::add_const<_Tp>::type,
    456                              typename ::boost::add_reference< typename ::boost::add_const<_Tp>::type >::type>::_Ret const_param_type;
    457   typedef typename __select< ::boost::is_reference<_Tp>::value,
    458                              typename ::boost::remove_const<_Tp>::type,
    459                              typename ::boost::add_reference<_Tp>::type>::_Ret param_type;
    460 #else
    461   typedef const _Tp& const_param_type;
    462   typedef _Tp& param_type;
    463 #endif
    464 };
    465 
    466 #if !defined (_STLP_USE_BOOST_SUPPORT) && !defined (_STLP_NO_EXTENSIONS) && defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    467 template <class _Tp>
    468 struct __call_traits<_Tp&> {
    469   typedef _Tp& param_type;
    470   typedef const _Tp& const_param_type;
    471 };
    472 template <class _Tp>
    473 struct __call_traits<const _Tp&> {
    474   typedef _Tp& param_type;
    475   typedef const _Tp& const_param_type;
    476 };
    477 #endif
    478 
    479 template <class _Tp1, class _Tp2>
    480 struct _BothPtrType {
    481   typedef typename _IsPtr<_Tp1>::_Ret _IsPtr1;
    482   typedef typename _IsPtr<_Tp2>::_Ret _IsPtr2;
    483 
    484   typedef typename _Land2<_IsPtr1, _IsPtr2>::_Ret _Ret;
    485   static _Ret _Answer() { return _Ret(); }
    486 };
    487 
    488 template <class _Tp1, class _Tp2, class _IsRef1, class _IsRef2>
    489 struct _OKToSwap {
    490   typedef typename _AreSameTypes<_Tp1, _Tp2>::_Ret _Same;
    491   typedef typename _Land3<_Same, _IsRef1, _IsRef2>::_Ret _Type;
    492   static _Type _Answer() { return _Type(); }
    493 };
    494 
    495 template <class _Tp1, class _Tp2, class _IsRef1, class _IsRef2>
    496 inline _OKToSwap<_Tp1, _Tp2, _IsRef1, _IsRef2>
    497 _IsOKToSwap(_Tp1*, _Tp2*, const _IsRef1&, const _IsRef2&)
    498 { return _OKToSwap<_Tp1, _Tp2, _IsRef1, _IsRef2>(); }
    499 
    500 template <class _Src, class _Dst>
    501 inline _TrivialCopy<_Src, _Dst> _UseTrivialCopy(_Src*, _Dst*)
    502 { return _TrivialCopy<_Src, _Dst>(); }
    503 
    504 template <class _Src, class _Dst>
    505 inline _TrivialUCopy<_Src, _Dst> _UseTrivialUCopy(_Src*, _Dst*)
    506 { return _TrivialUCopy<_Src, _Dst>(); }
    507 
    508 #if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) || defined (__BORLANDC__) || \
    509     defined (__DMC__)
    510 struct _NegativeAnswer {
    511   typedef __false_type _Ret;
    512   static _Ret _Answer() { return _Ret(); }
    513 };
    514 
    515 template <class _Src, class _Dst>
    516 inline _NegativeAnswer _UseTrivialCopy(_Src*, const _Dst*)
    517 { return _NegativeAnswer(); }
    518 
    519 template <class _Src, class _Dst>
    520 inline _NegativeAnswer _UseTrivialCopy(_Src*, volatile _Dst*)
    521 { return _NegativeAnswer(); }
    522 
    523 template <class _Src, class _Dst>
    524 inline _NegativeAnswer _UseTrivialCopy(_Src*, const volatile _Dst*)
    525 { return _NegativeAnswer(); }
    526 
    527 template <class _Src, class _Dst>
    528 inline _NegativeAnswer _UseTrivialUCopy(_Src*, const _Dst*)
    529 { return _NegativeAnswer(); }
    530 
    531 template <class _Src, class _Dst>
    532 inline _NegativeAnswer _UseTrivialUCopy(_Src*, volatile _Dst*)
    533 { return _NegativeAnswer(); }
    534 
    535 template <class _Src, class _Dst>
    536 inline _NegativeAnswer _UseTrivialUCopy(_Src*, const volatile _Dst*)
    537 { return _NegativeAnswer(); }
    538 #endif
    539 
    540 template <class _Tp>
    541 inline _TrivialInit<_Tp> _UseTrivialInit(_Tp*)
    542 { return _TrivialInit<_Tp>(); }
    543 
    544 template <class _Tp>
    545 struct _IsPOD {
    546   typedef typename __type_traits<_Tp>::is_POD_type _Type;
    547   static _Type _Answer() { return _Type(); }
    548 };
    549 
    550 template <class _Tp>
    551 inline _IsPOD<_Tp> _Is_POD(_Tp*)
    552 { return _IsPOD<_Tp>(); }
    553 
    554 template <class _Tp>
    555 struct _DefaultZeroValueQuestion {
    556   typedef typename _DefaultZeroValue<_Tp>::_Ret _Ret;
    557   static _Ret _Answer() { return _Ret(); }
    558 };
    559 
    560 template <class _Tp>
    561 inline _DefaultZeroValueQuestion<_Tp> _HasDefaultZeroValue(_Tp*)
    562 { return _DefaultZeroValueQuestion<_Tp>(); }
    563 
    564 /*
    565  * Base class used:
    566  * - to simulate partial template specialization
    567  * - to simulate partial function ordering
    568  * - to recognize STLport class from user specialized one
    569  */
    570 template <class _Tp>
    571 struct __stlport_class
    572 { typedef _Tp _Type; };
    573 
    574 template <class _Tp>
    575 struct _IsSTLportClass {
    576   typedef typename _IsConvertible<_Tp, __stlport_class<_Tp> >::_Ret _Ret;
    577 #if defined (__BORLANDC__)
    578   enum { _Is = _IsConvertible<_Tp, __stlport_class<_Tp> >::value };
    579 #endif
    580 };
    581 
    582 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
    583 template <class _Tp>
    584 struct _SwapImplemented {
    585   typedef typename _IsSTLportClass<_Tp>::_Ret _Ret;
    586 #  if defined (__BORLANDC__)
    587   enum { _Is = _IsSTLportClass<_Tp>::_Is };
    588 #  endif
    589 };
    590 #endif
    591 
    592 template <class _Tp>
    593 class _TpWithState : private _Tp {
    594   _TpWithState();
    595   int _state;
    596 };
    597 
    598 /* This is an internal helper struct used to guess if we are working
    599  * on a stateless class. It can only be instanciated with a class type. */
    600 template <class _Tp>
    601 struct _IsStateless {
    602   enum { _Is = sizeof(_TpWithState<_Tp>) == sizeof(int) };
    603   typedef typename __bool2type<_Is>::_Ret _Ret;
    604 };
    605 
    606 _STLP_END_NAMESPACE
    607 
    608 #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
    609 #  if defined (__BORLANDC__) || \
    610       defined (__SUNPRO_CC) ||  \
    611      (defined (__MWERKS__) && (__MWERKS__ <= 0x2303)) || \
    612      (defined (__sgi) && defined (_COMPILER_VERSION)) || \
    613       defined (__DMC__)
    614 #    define _STLP_IS_POD_ITER(_It, _Tp) __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
    615 #  else
    616 #    define _STLP_IS_POD_ITER(_It, _Tp) typename __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
    617 #  endif
    618 #else
    619 #  define _STLP_IS_POD_ITER(_It, _Tp) _Is_POD( _STLP_VALUE_TYPE( _It, _Tp ) )._Answer()
    620 #endif
    621 
    622 #endif /* _STLP_TYPE_TRAITS_H */
    623 
    624 // Local Variables:
    625 // mode:C++
    626 // End:
    627