type_traits.h

00001 /*
00002  *
00003  * Copyright (c) 1996,1997
00004  * Silicon Graphics Computer Systems, Inc.
00005  *
00006  * Copyright (c) 1997
00007  * Moscow Center for SPARC Technology
00008  *
00009  * Copyright (c) 1999 
00010  * Boris Fomitchev
00011  *
00012  * This material is provided "as is", with absolutely no warranty expressed
00013  * or implied. Any use is at your own risk.
00014  *
00015  * Permission to use or copy this software for any purpose is hereby granted 
00016  * without fee, provided the above notices are retained on all copies.
00017  * Permission to modify the code and to distribute modified code is granted,
00018  * provided the above notices are retained, and a notice that the code was
00019  * modified is included with the above copyright notice.
00020  *
00021  */
00022 
00023 #ifndef _STLP_TYPE_TRAITS_H
00024 #define _STLP_TYPE_TRAITS_H
00025 
00026 /*
00027 This header file provides a framework for allowing compile time dispatch
00028 based on type attributes. This is useful when writing template code.
00029 For example, when making a copy of an array of an unknown type, it helps
00030 to know if the type has a trivial copy constructor or not, to help decide
00031 if a memcpy can be used.
00032 
00033 The class template __type_traits provides a series of typedefs each of
00034 which is either __true_type or __false_type. The argument to
00035 __type_traits can be any type. The typedefs within this template will
00036 attain their correct values by one of these means:
00037     1. The general instantiation contain conservative values which work
00038        for all types.
00039     2. Specializations may be declared to make distinctions between types.
00040     3. Some compilers (such as the Silicon Graphics N32 and N64 compilers)
00041        will automatically provide the appropriate specializations for all
00042        types.
00043 
00044 EXAMPLE:
00045 
00046 //Copy an array of elements which have non-trivial copy constructors
00047 template <class T> void copy(T* source, T* destination, int n, __false_type);
00048 //Copy an array of elements which have trivial copy constructors. Use memcpy.
00049 template <class T> void copy(T* source, T* destination, int n, __true_type);
00050 
00051 //Copy an array of any type by using the most efficient copy mechanism
00052 template <class T> inline void copy(T* source,T* destination,int n) {
00053    copy(source, destination, n,
00054         typename __type_traits<T>::has_trivial_copy_constructor());
00055 }
00056 */
00057 
00058 #ifdef __WATCOMC__
00059 # include <cwchar>
00060 #endif
00061 
00062 _STLP_BEGIN_NAMESPACE
00063 
00064 struct __true_type {};
00065 struct __false_type {};
00066 
00067 
00068 template <int _Is> struct __bool2type { };
00069 
00070 _STLP_TEMPLATE_NULL
00071 struct __bool2type<1> { typedef __true_type _Ret; };
00072 
00073 _STLP_TEMPLATE_NULL
00074 struct __bool2type<0> { typedef __false_type _Ret; };
00075 
00076 // logical end of 3 predicated
00077 template <class _P1, class _P2, class _P3>
00078 struct _Land3 {
00079   typedef __false_type _Ret;
00080 };
00081 
00082 _STLP_TEMPLATE_NULL
00083 struct _Land3<__true_type, __true_type, __true_type> {
00084   typedef __true_type _Ret;
00085 };
00086 
00087 
00088 // Forward declarations.
00089 template <class _Tp> struct __type_traits; 
00090 template <int _IsPOD> struct __type_traits_aux {
00091    typedef __false_type    has_trivial_default_constructor;
00092    typedef __false_type    has_trivial_copy_constructor;
00093    typedef __false_type    has_trivial_assignment_operator;
00094    typedef __false_type    has_trivial_destructor;
00095    typedef __false_type    is_POD_type;
00096 };
00097 
00098 _STLP_TEMPLATE_NULL
00099 struct __type_traits_aux<0> {
00100    typedef __false_type    has_trivial_default_constructor;
00101    typedef __false_type    has_trivial_copy_constructor;
00102    typedef __false_type    has_trivial_assignment_operator;
00103    typedef __false_type    has_trivial_destructor;
00104    typedef __false_type    is_POD_type;
00105 };
00106 
00107 _STLP_TEMPLATE_NULL
00108 struct __type_traits_aux<1> { 
00109    typedef __true_type    has_trivial_default_constructor;
00110    typedef __true_type    has_trivial_copy_constructor;
00111    typedef __true_type    has_trivial_assignment_operator;
00112    typedef __true_type    has_trivial_destructor;
00113    typedef __true_type    is_POD_type;
00114 };
00115 
00116 # ifdef _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS
00117 
00118 // Boris : simulation technique is used here according to Adobe Open Source License Version 1.0.
00119 // Copyright 2000 Adobe Systems Incorporated and others. All rights reserved.
00120 // Authors: Mat Marcus and Jesse Jones
00121 // The original version of this source code may be found at
00122 // http://opensource.adobe.com.
00123 
00124 struct _PointerShim {
00125   // Since the compiler only allows at most one non-trivial
00126   // implicit conversion we can make use of a shim class to
00127   // be sure that IsPtr below doesn't accept classes with
00128   // implicit pointer conversion operators
00129   _PointerShim(const volatile void*); // no implementation
00130 };
00131 
00132 // These are the discriminating functions
00133 
00134 char _STLP_CALL _IsP(bool, _PointerShim); // no implementation is required
00135 char* _STLP_CALL _IsP(bool, ...);          // no implementation is required
00136 
00137 template <class _Tp>
00138 struct _IsPtr {
00139   
00140   // This template meta function takes a type T
00141   // and returns true exactly when T is a pointer.
00142   // One can imagine meta-functions discriminating on
00143   // other criteria.
00144   static _Tp& __null_rep();
00145   enum { _Ret = (sizeof(_IsP(false,__null_rep())) == sizeof(char)) };
00146 
00147 };
00148 
00149 template <class _Tp>
00150 struct _IsPtrType {
00151   enum { _Is =  _IsPtr<_Tp>::_Ret } ;
00152   typedef __bool2type< _Is > _BT;
00153   typedef typename _BT::_Ret _Type;
00154   static _Type _Ret() { return _Type(); }
00155 };
00156 
00157 template <class _Tp1, class _Tp2>
00158 struct _BothPtrType {
00159   typedef __bool2type< _IsPtr<_Tp1>::_Ret> _B1;
00160   typedef __bool2type< _IsPtr<_Tp2>::_Ret> _B2;
00161   typedef typename _B1::_Ret _Type1;
00162   typedef typename _B2::_Ret _Type2;
00163   typedef typename _Land3<_Type1, _Type2, __true_type>::_Ret _Type;
00164   static _Type _Ret() { return _Type(); }
00165 };
00166 
00167 // we make general case dependant on the fact the type is actually a pointer.
00168  
00169 template <class _Tp>
00170 struct __type_traits : __type_traits_aux<_IsPtr<_Tp>::_Ret> {};
00171 
00172 # else
00173 
00174 template <class _Tp>
00175 struct __type_traits { 
00176    typedef __true_type     this_dummy_member_must_be_first;
00177                    /* Do not remove this member. It informs a compiler which
00178                       automatically specializes __type_traits that this
00179                       __type_traits template is special. It just makes sure that
00180                       things work if an implementation is using a template
00181                       called __type_traits for something unrelated. */
00182 
00183    /* The following restrictions should be observed for the sake of
00184       compilers which automatically produce type specific specializations 
00185       of this class:
00186           - You may reorder the members below if you wish
00187           - You may remove any of the members below if you wish
00188           - You must not rename members without making the corresponding
00189             name change in the compiler
00190           - Members you add will be treated like regular members unless
00191             you add the appropriate support in the compiler. */
00192    typedef __false_type    has_trivial_default_constructor;
00193    typedef __false_type    has_trivial_copy_constructor;
00194    typedef __false_type    has_trivial_assignment_operator;
00195    typedef __false_type    has_trivial_destructor;
00196    typedef __false_type    is_POD_type;
00197 };
00198 
00199 
00200 template <class _Tp>  struct _IsPtr { enum { _Ret = 0 }; };
00201 template <class _Tp>  struct _IsPtrType { 
00202   static __false_type _Ret() { return __false_type();} 
00203 };
00204 template <class _Tp1, class _Tp2>  struct _BothPtrType { 
00205   static __false_type _Ret() { return __false_type();} 
00206 };
00207 
00208 #  ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
00209 template <class _Tp>  struct _IsPtr<_Tp*> { enum { _Ret = 1 }; };
00210 template <class _Tp>  struct _IsPtrType<_Tp*> { 
00211   static __true_type _Ret() { return __true_type();} 
00212 };
00213 template <class _Tp1, class _Tp2>  struct _BothPtrType<_Tp1*, _Tp2*> { 
00214   static __true_type _Ret() { return __true_type();} 
00215 };
00216 #  endif
00217 
00218 # endif /* _STLP_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS */
00219 
00220 // Provide some specializations.  This is harmless for compilers that
00221 //  have built-in __types_traits support, and essential for compilers
00222 //  that don't.
00223 #ifndef _STLP_NO_BOOL
00224 _STLP_TEMPLATE_NULL struct __type_traits<bool> : __type_traits_aux<1> {};
00225 #endif /* _STLP_NO_BOOL */
00226 _STLP_TEMPLATE_NULL struct __type_traits<char> : __type_traits_aux<1> {};
00227 #ifndef _STLP_NO_SIGNED_BUILTINS
00228 _STLP_TEMPLATE_NULL struct __type_traits<signed char> : __type_traits_aux<1> {};
00229 # endif
00230 _STLP_TEMPLATE_NULL struct __type_traits<unsigned char> : __type_traits_aux<1> {};
00231 #if defined ( _STLP_HAS_WCHAR_T ) && ! defined (_STLP_WCHAR_T_IS_USHORT)
00232 _STLP_TEMPLATE_NULL struct __type_traits<wchar_t> : __type_traits_aux<1> {};
00233 #endif /* _STLP_HAS_WCHAR_T */
00234 
00235 _STLP_TEMPLATE_NULL struct __type_traits<short> : __type_traits_aux<1> {};
00236 _STLP_TEMPLATE_NULL struct __type_traits<unsigned short> : __type_traits_aux<1> {};
00237 _STLP_TEMPLATE_NULL struct __type_traits<int> : __type_traits_aux<1> {};
00238 _STLP_TEMPLATE_NULL struct __type_traits<unsigned int> : __type_traits_aux<1> {};
00239 _STLP_TEMPLATE_NULL struct __type_traits<long> : __type_traits_aux<1> {};
00240 _STLP_TEMPLATE_NULL struct __type_traits<unsigned long> : __type_traits_aux<1> {};
00241 
00242 #ifdef _STLP_LONG_LONG
00243 _STLP_TEMPLATE_NULL struct __type_traits<_STLP_LONG_LONG> : __type_traits_aux<1> {};
00244 _STLP_TEMPLATE_NULL struct __type_traits<unsigned _STLP_LONG_LONG> : __type_traits_aux<1> {};
00245 #endif /* _STLP_LONG_LONG */
00246 
00247 _STLP_TEMPLATE_NULL struct __type_traits<float> : __type_traits_aux<1> {};
00248 _STLP_TEMPLATE_NULL struct __type_traits<double> : __type_traits_aux<1> {};
00249 
00250 # if !defined ( _STLP_NO_LONG_DOUBLE )
00251 _STLP_TEMPLATE_NULL struct __type_traits<long double> : __type_traits_aux<1> {};
00252 # endif
00253 
00254 #ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
00255 template <class _Tp> struct __type_traits<_Tp*> : __type_traits_aux<1> {};
00256 #endif
00257 
00258 // The following could be written in terms of numeric_limits.  
00259 // We're doing it separately to reduce the number of dependencies.
00260 
00261 template <class _Tp> struct _Is_integer {
00262   typedef __false_type _Integral;
00263 };
00264 
00265 #ifndef _STLP_NO_BOOL
00266 
00267 _STLP_TEMPLATE_NULL struct _Is_integer<bool> {
00268   typedef __true_type _Integral;
00269 };
00270 
00271 #endif /* _STLP_NO_BOOL */
00272 
00273 _STLP_TEMPLATE_NULL struct _Is_integer<char> {
00274   typedef __true_type _Integral;
00275 };
00276 
00277 #ifndef _STLP_NO_SIGNED_BUILTINS
00278 
00279 _STLP_TEMPLATE_NULL struct _Is_integer<signed char> {
00280   typedef __true_type _Integral;
00281 };
00282 #endif
00283 
00284 _STLP_TEMPLATE_NULL struct _Is_integer<unsigned char> {
00285   typedef __true_type _Integral;
00286 };
00287 
00288 #if defined ( _STLP_HAS_WCHAR_T ) && ! defined (_STLP_WCHAR_T_IS_USHORT)
00289 
00290 _STLP_TEMPLATE_NULL struct _Is_integer<wchar_t> {
00291   typedef __true_type _Integral;
00292 };
00293 
00294 #endif /* _STLP_HAS_WCHAR_T */
00295 
00296 _STLP_TEMPLATE_NULL struct _Is_integer<short> {
00297   typedef __true_type _Integral;
00298 };
00299 
00300 _STLP_TEMPLATE_NULL struct _Is_integer<unsigned short> {
00301   typedef __true_type _Integral;
00302 };
00303 
00304 _STLP_TEMPLATE_NULL struct _Is_integer<int> {
00305   typedef __true_type _Integral;
00306 };
00307 
00308 _STLP_TEMPLATE_NULL struct _Is_integer<unsigned int> {
00309   typedef __true_type _Integral;
00310 };
00311 
00312 _STLP_TEMPLATE_NULL struct _Is_integer<long> {
00313   typedef __true_type _Integral;
00314 };
00315 
00316 _STLP_TEMPLATE_NULL struct _Is_integer<unsigned long> {
00317   typedef __true_type _Integral;
00318 };
00319 
00320 #ifdef _STLP_LONG_LONG
00321 
00322 _STLP_TEMPLATE_NULL struct _Is_integer<_STLP_LONG_LONG> {
00323   typedef __true_type _Integral;
00324 };
00325 
00326 _STLP_TEMPLATE_NULL struct _Is_integer<unsigned _STLP_LONG_LONG> {
00327   typedef __true_type _Integral;
00328 };
00329 
00330 #endif /* _STLP_LONG_LONG */
00331 
00332 template <class _Tp1, class _Tp2>
00333 struct _OKToMemCpy {
00334   enum { _SameSize = (sizeof(_Tp1) == sizeof(_Tp2)) } ;
00335   typedef typename __type_traits<_Tp1>::has_trivial_assignment_operator _Tr1;
00336   typedef typename __type_traits<_Tp2>::has_trivial_assignment_operator _Tr2;
00337   typedef typename __bool2type< _SameSize >::_Ret _Tr3;
00338   typedef typename _Land3<_Tr1, _Tr2, _Tr3>::_Ret _Type;
00339   static _Type _Ret() { return _Type(); }
00340 };
00341 
00342 template <class _Tp1, class _Tp2>
00343 inline _OKToMemCpy<_Tp1, _Tp2> _IsOKToMemCpy(_Tp1*, _Tp2*)  {
00344   return _OKToMemCpy<_Tp1, _Tp2>();
00345 }
00346 
00347 template <class _Tp> 
00348 struct _IsPOD {
00349   typedef typename __type_traits<_Tp>::is_POD_type _Type;
00350   static _Type _Ret() { return _Type(); }
00351 };
00352 
00353 template <class _Tp> 
00354 inline _IsPOD<_Tp>  _Is_POD (_Tp*) { return _IsPOD<_Tp>(); } 
00355 
00356 #  ifdef _STLP_CLASS_PARTIAL_SPECIALIZATION
00357 #   if defined (__BORLANDC__) || defined (__SUNPRO_CC) || ( defined (__MWERKS__) && (__MWERKS__ <= 0x2303)) || ( defined (__sgi) && defined (_COMPILER_VERSION))
00358 #   define _IS_POD_ITER(_It, _Tp) __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
00359 #   else
00360 #   define _IS_POD_ITER(_It, _Tp) typename __type_traits< typename iterator_traits< _Tp >::value_type >::is_POD_type()
00361 #   endif
00362 #  else
00363 #   define _IS_POD_ITER(_It, _Tp) _Is_POD( _STLP_VALUE_TYPE( _It, _Tp ) )._Ret()
00364 #  endif
00365 
00366 # ifdef _STLP_DEFAULT_CONSTRUCTOR_BUG
00367 // Those adaptors are here to fix common compiler bug regarding builtins:
00368 // expressions like int k = int() should initialize k to 0
00369 template <class _Tp>
00370 inline _Tp __default_constructed_aux(_Tp*, const __false_type&) {
00371   return _Tp();
00372 }
00373 template <class _Tp>
00374 inline _Tp __default_constructed_aux(_Tp*, const __true_type&) {
00375   return _Tp(0);
00376 }
00377 
00378 template <class _Tp>
00379 inline _Tp __default_constructed(_Tp* __p) {
00380   typedef typename _Is_integer<_Tp>::_Integral _Is_Integral;
00381   return __default_constructed_aux(__p, _Is_Integral());
00382 }
00383 
00384 #  define _STLP_DEFAULT_CONSTRUCTED(_TTp) __default_constructed((_TTp*)0)
00385 # else
00386 #  define _STLP_DEFAULT_CONSTRUCTED(_TTp) _TTp()
00387 # endif
00388 
00389 _STLP_END_NAMESPACE
00390 
00391 #endif /* __TYPE_TRAITS_H */
00392 
00393 // Local Variables:
00394 // mode:C++
00395 // End:
00396 

Generated on Mon Jun 5 10:20:45 2006 for Intelligence.kdevelop by  doxygen 1.4.6