ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

_tools.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2003
00003  * Francois Dumont
00004  *
00005  * This material is provided "as is", with absolutely no warranty expressed
00006  * or implied. Any use is at your own risk.
00007  *
00008  * Permission to use or copy this software for any purpose is hereby granted
00009  * without fee, provided the above notices are retained on all copies.
00010  * Permission to modify the code and to distribute modified code is granted,
00011  * provided the above notices are retained, and a notice that the code was
00012  * modified is included with the above copyright notice.
00013  *
00014  */
00015 
00016 /* NOTE: This is an internal header file, included by other STL headers.
00017  *   You should not attempt to use it directly.
00018  */
00019 
00020 #ifndef _STLP_POINTERS_SPEC_TOOLS_H
00021 #define _STLP_POINTERS_SPEC_TOOLS_H
00022 
00023 #ifndef _STLP_TYPE_TRAITS_H
00024 #  include <stl/type_traits.h>
00025 #endif
00026 
00027 _STLP_BEGIN_NAMESPACE
00028 
00029 //Some usefull declarations:
00030 template <class _Tp> struct less;
00031 
00032 _STLP_MOVE_TO_PRIV_NAMESPACE
00033 
00034 template <class _StorageT, class _ValueT, class _BinaryPredicate>
00035 struct _BinaryPredWrapper;
00036 
00037 /*
00038  * Since the compiler only allows at most one non-trivial
00039  * implicit conversion we can make use of a shim class to
00040  * be sure that functions below doesn't accept classes with
00041  * implicit pointer conversion operators
00042  */
00043 struct _VoidPointerShim
00044 { _VoidPointerShim(void*); };
00045 struct _ConstVoidPointerShim
00046 { _ConstVoidPointerShim(const void*); };
00047 struct _VolatileVoidPointerShim
00048 { _VolatileVoidPointerShim(volatile void*); };
00049 struct _ConstVolatileVoidPointerShim
00050 { _ConstVolatileVoidPointerShim(const volatile void*); };
00051 
00052 //The dispatch functions:
00053 template <class _Tp>
00054 char _UseVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
00055 char _UseVoidPtrStorageType(const __true_type& /*POD*/, ...);
00056 char* _UseVoidPtrStorageType(const __true_type& /*POD*/, _VoidPointerShim);
00057 
00058 template <class _Tp>
00059 char _UseConstVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
00060 char _UseConstVoidPtrStorageType(const __true_type& /*POD*/, ...);
00061 char* _UseConstVoidPtrStorageType(const __true_type& /*POD*/, _ConstVoidPointerShim);
00062 
00063 template <class _Tp>
00064 char _UseVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
00065 char _UseVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...);
00066 char* _UseVolatileVoidPtrStorageType(const __true_type& /*POD*/, _VolatileVoidPointerShim);
00067 
00068 template <class _Tp>
00069 char _UseConstVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&);
00070 char _UseConstVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...);
00071 char* _UseConstVolatileVoidPtrStorageType(const __true_type& /*POD*/, _ConstVolatileVoidPointerShim);
00072 
00073 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00074 /* Thanks to class partial specialization the pointer specialization feature can even be used in
00075  * presence of incomplete type:
00076  * struct MyStruct {
00077  *   typedef vector<MyStruct> MyStructContainer;
00078  *   typedef MyStructContainer::iterator MyStructIterator;
00079  * };
00080  */
00081 
00082 template <class _Tp>
00083 struct _StorageType {
00084   typedef _Tp _QualifiedType;
00085   typedef _Tp _Type;
00086   enum { use_const_volatile_void_ptr = 0 };
00087 };
00088 
00089 template <class _Tp>
00090 struct _StorageType<_Tp*> {
00091   // Even if we detect a pointer type we use dispatch function to consider if it can be stored as a void*.
00092   // For instance function pointer might not necessarily be convertible to void*.
00093   enum { use_void_ptr = (sizeof(_UseVoidPtrStorageType(__true_type(),
00094                                                        __STATIC_CAST(_Tp*, 0))) == sizeof(char*)) };
00095   enum { use_const_volatile_void_ptr = use_void_ptr };
00096   typedef typename __select<use_void_ptr,
00097                             void*,
00098                             _Tp*>::_Ret _QualifiedType;
00099   typedef _QualifiedType _Type;
00100 };
00101 
00102 template <class _Tp>
00103 struct _StorageType<_Tp const*> {
00104   enum { use_void_ptr = (sizeof(_UseConstVoidPtrStorageType(__true_type(),
00105                                                             __STATIC_CAST(const _Tp*, 0))) == sizeof(char*)) };
00106   enum { use_const_volatile_void_ptr = use_void_ptr };
00107   typedef typename __select<use_void_ptr,
00108                             const void*,
00109                             const _Tp*>::_Ret _QualifiedType;
00110   typedef typename __select<use_void_ptr,
00111                             void*,
00112                             const _Tp*>::_Ret _Type;
00113 };
00114 
00115 template <class _Tp>
00116 struct _StorageType<_Tp volatile*> {
00117   enum { use_void_ptr = (sizeof(_UseVolatileVoidPtrStorageType(__true_type(),
00118                                                                __STATIC_CAST(_Tp volatile*, 0))) == sizeof(char*)) };
00119   enum { use_const_volatile_void_ptr = use_void_ptr };
00120   typedef typename __select<use_void_ptr,
00121                             volatile void*,
00122                             volatile _Tp*>::_Ret _QualifiedType;
00123   typedef typename __select<use_void_ptr,
00124                             void*,
00125                             volatile _Tp*>::_Ret _Type;
00126 };
00127 
00128 template <class _Tp>
00129 struct _StorageType<_Tp const volatile*> {
00130   enum { use_void_ptr = (sizeof(_UseConstVolatileVoidPtrStorageType(__true_type(),
00131                                                                     __STATIC_CAST(_Tp const volatile*, 0))) == sizeof(char*)) };
00132   enum { use_const_volatile_void_ptr = use_void_ptr };
00133   typedef typename __select<use_void_ptr,
00134                             const volatile void*,
00135                             const volatile _Tp*>::_Ret _QualifiedType;
00136   typedef typename __select<use_void_ptr,
00137                             void*,
00138                             const volatile _Tp*>::_Ret _Type;
00139 };
00140 #else
00141 template <class _Tp>
00142 struct _StorageType {
00143   typedef typename __type_traits<_Tp>::is_POD_type _PODType;
00144 
00145 #if !defined (__BORLANDC__) || (__BORLANDC__ != 0x560)
00146   static _Tp __null_rep();
00147 #else
00148   static _Tp __null_rep;
00149 #endif
00150   enum { use_void_ptr = (sizeof(_UseVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
00151   enum { use_const_void_ptr = (sizeof(_UseConstVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
00152   enum { use_volatile_void_ptr = (sizeof(_UseVolatileVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
00153   enum { use_const_volatile_void_ptr = (sizeof(_UseConstVolatileVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) };
00154 
00155   typedef typename __select<!use_const_volatile_void_ptr,
00156                             _Tp,
00157           typename __select<use_void_ptr,
00158                             void*,
00159           typename __select<use_const_void_ptr,
00160                             const void*,
00161           typename __select<use_volatile_void_ptr,
00162                             volatile void*,
00163                             const volatile void*>::_Ret >::_Ret >::_Ret >::_Ret _QualifiedType;
00164 
00165 #if !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00166   /* If the compiler do not support the iterator_traits structure we cannot wrap
00167    * iterators pass to container template methods. The iterator dereferenced value
00168    * has to be storable without any cast in the chosen storage type. To guaranty
00169    * that the void pointer has to be correctly qualified.
00170    */
00171   typedef _QualifiedType _Type;
00172 #else
00173   /* With iterator_traits we can wrap passed iterators and make the necessary casts.
00174    * We can always use a simple void* storage type:
00175    */
00176   typedef typename __select<use_const_volatile_void_ptr,
00177                             void*,
00178                             _Tp>::_Ret _Type;
00179 #endif
00180 };
00181 #endif
00182 
00183 template <class _Tp, class _Compare>
00184 struct _AssocStorageTypes {
00185   typedef _StorageType<_Tp> _StorageTypeInfo;
00186   typedef typename _StorageTypeInfo::_Type _SType;
00187 
00188   //We need to also check that the comparison functor used to instanciate the assoc container
00189   //is the default Standard less implementation:
00190   enum { ptr_type = _StorageTypeInfo::use_const_volatile_void_ptr };
00191   typedef typename _IsSTLportClass<_Compare>::_Ret _STLportLess;
00192   enum { is_default_less = __type2bool<_STLportLess>::_Ret };
00193   typedef typename __select<is_default_less, _SType, _Tp>::_Ret _KeyStorageType;
00194   typedef typename __select<is_default_less && ptr_type,
00195                             _BinaryPredWrapper<_KeyStorageType, _Tp, _Compare>,
00196                             _Compare>::_Ret _CompareStorageType;
00197 };
00198 
00199 
00200 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00201 /*
00202  * Base struct to deal with qualifiers
00203  */
00204 template <class _StorageT, class _QualifiedStorageT>
00205 struct _VoidCastTraitsAux {
00206   typedef _QualifiedStorageT void_cv_type;
00207   typedef _StorageT void_type;
00208 
00209   static void_type * uncv_ptr(void_cv_type *__ptr)
00210   { return __ptr; }
00211   static void_type const* uncv_cptr(void_cv_type const*__ptr)
00212   { return __ptr; }
00213   static void_type ** uncv_pptr(void_cv_type **__ptr)
00214   { return __ptr; }
00215   static void_type & uncv_ref(void_cv_type & __ref)
00216   { return __ref; }
00217   static void_type const& uncv_cref(void_cv_type const& __ref)
00218   { return __ref; }
00219   static void_cv_type* cv_ptr(void_type *__ptr)
00220   { return __ptr; }
00221   static void_cv_type const* cv_cptr(void_type const*__ptr)
00222   { return __ptr; }
00223   static void_cv_type ** cv_pptr(void_type **__ptr)
00224   { return __ptr; }
00225   static void_cv_type & cv_ref(void_type & __ref)
00226   { return __ref; }
00227   static void_cv_type const& cv_cref(void_type const& __ref)
00228   { return __ref; }
00229 };
00230 
00231 template <class _VoidCVType>
00232 struct _VoidCastTraitsAuxBase {
00233   typedef _VoidCVType* void_cv_type;
00234   typedef void* void_type;
00235 
00236   static void_type* uncv_ptr(void_cv_type *__ptr)
00237   { return __CONST_CAST(void_type*, __ptr); }
00238   static void_type const* uncv_cptr(void_cv_type const*__ptr)
00239   { return __CONST_CAST(void_type const*, __ptr); }
00240   static void_type** uncv_pptr(void_cv_type **__ptr)
00241   { return __CONST_CAST(void_type**, __ptr); }
00242   static void_type& uncv_ref(void_cv_type &__ref)
00243   { return __CONST_CAST(void_type&, __ref); }
00244   static void_type const& uncv_cref(void_cv_type const& __ptr)
00245   { return __CONST_CAST(void_type const&, __ptr); }
00246   // The reverse versions
00247   static void_cv_type * cv_ptr(void_type *__ptr)
00248   { return __CONST_CAST(void_cv_type *, __ptr); }
00249   static void_cv_type const* cv_cptr(void_type const*__ptr)
00250   { return __CONST_CAST(void_cv_type const*, __ptr); }
00251   static void_cv_type ** cv_pptr(void_type **__ptr)
00252   { return __CONST_CAST(void_cv_type**, __ptr); }
00253   static void_cv_type & cv_ref(void_type &__ref)
00254   { return __CONST_CAST(void_cv_type &, __ref); }
00255   static void_cv_type const& cv_cref(void_type const& __ref)
00256   { return __CONST_CAST(void_cv_type const&, __ref); }
00257 };
00258 
00259 _STLP_TEMPLATE_NULL
00260 struct _VoidCastTraitsAux<void*, const void*> : _VoidCastTraitsAuxBase<void const>
00261 {};
00262 _STLP_TEMPLATE_NULL
00263 struct _VoidCastTraitsAux<void*, volatile void*> : _VoidCastTraitsAuxBase<void volatile>
00264 {};
00265 _STLP_TEMPLATE_NULL
00266 struct _VoidCastTraitsAux<void*, const volatile void*> : _VoidCastTraitsAuxBase<void const volatile>
00267 {};
00268 
00269 template <class _StorageT, class _ValueT>
00270 struct _CastTraits {
00271   typedef _ValueT value_type;
00272   typedef typename _StorageType<_ValueT>::_QualifiedType _QualifiedStorageT;
00273   typedef _VoidCastTraitsAux<_StorageT, _QualifiedStorageT> cv_traits;
00274   typedef typename cv_traits::void_type void_type;
00275   typedef typename cv_traits::void_cv_type void_cv_type;
00276 
00277   static value_type * to_value_type_ptr(void_type *__ptr)
00278   { return __REINTERPRET_CAST(value_type *, cv_traits::cv_ptr(__ptr)); }
00279   static value_type const* to_value_type_cptr(void_type const*__ptr)
00280   { return __REINTERPRET_CAST(value_type const*, cv_traits::cv_cptr(__ptr)); }
00281   static value_type ** to_value_type_pptr(void_type **__ptr)
00282   { return __REINTERPRET_CAST(value_type **, cv_traits::cv_pptr(__ptr)); }
00283   static value_type & to_value_type_ref(void_type &__ref)
00284   { return __REINTERPRET_CAST(value_type &, cv_traits::cv_ref(__ref)); }
00285   static value_type const& to_value_type_cref(void_type const& __ptr)
00286   { return __REINTERPRET_CAST(value_type const&, cv_traits::cv_cref(__ptr)); }
00287   // Reverse versions
00288   static void_type * to_storage_type_ptr(value_type *__ptr)
00289   { return cv_traits::uncv_ptr(__REINTERPRET_CAST(void_cv_type *, __ptr)); }
00290   static void_type const* to_storage_type_cptr(value_type const*__ptr)
00291   { return cv_traits::uncv_cptr(__REINTERPRET_CAST(void_cv_type const*, __ptr)); }
00292   static void_type ** to_storage_type_pptr(value_type **__ptr)
00293   { return cv_traits::uncv_pptr(__REINTERPRET_CAST(void_cv_type **, __ptr)); }
00294   static void_type const& to_storage_type_cref(value_type const& __ref)
00295   { return cv_traits::uncv_cref(__REINTERPRET_CAST(void_cv_type const&, __ref)); }
00296 
00297   //Method used to treat set container template method extension
00298   static void_type const& to_storage_type_crefT(value_type const& __ref)
00299   { return to_storage_type_cref(__ref); }
00300 };
00301 
00302 template <class _Tp>
00303 struct _CastTraits<_Tp, _Tp> {
00304   typedef _Tp storage_type;
00305   typedef _Tp value_type;
00306 
00307   static value_type * to_value_type_ptr(storage_type *__ptr)
00308   { return __ptr; }
00309   static value_type const* to_value_type_cptr(storage_type const*__ptr)
00310   { return __ptr; }
00311   static value_type ** to_value_type_pptr(storage_type **__ptr)
00312   { return __ptr; }
00313   static value_type & to_value_type_ref(storage_type &__ref)
00314   { return __ref; }
00315   static value_type const& to_value_type_cref(storage_type const&__ref)
00316   { return __ref; }
00317   // Reverse versions
00318   static storage_type * to_storage_type_ptr(value_type *__ptr)
00319   { return __ptr; }
00320   static storage_type const* to_storage_type_cptr(value_type const*__ptr)
00321   { return __ptr; }
00322   static storage_type ** to_storage_type_pptr(value_type **__ptr)
00323   { return __ptr; }
00324   static storage_type const& to_storage_type_cref(value_type const& __ref)
00325   { return __ref; }
00326 
00327   //Method used to treat set container template method extension
00328   template <class _Tp1>
00329   static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref)
00330   { return __ref; }
00331 };
00332 
00333 #define _STLP_USE_ITERATOR_WRAPPER
00334 
00335 template <class _StorageT, class _ValueT, class _Iterator>
00336 struct _IteWrapper {
00337   typedef _CastTraits<_StorageT, _ValueT> cast_traits;
00338   typedef iterator_traits<_Iterator> _IteTraits;
00339 
00340   typedef typename _IteTraits::iterator_category iterator_category;
00341   typedef _StorageT value_type;
00342   typedef typename _IteTraits::difference_type difference_type;
00343   typedef value_type* pointer;
00344   typedef value_type const& const_reference;
00345   //This wrapper won't be used for input so to avoid surprise
00346   //the reference type will be a const reference:
00347   typedef const_reference reference;
00348 
00349   typedef _IteWrapper<_StorageT, _ValueT, _Iterator> _Self;
00350   typedef _Self _Ite;
00351 
00352   _IteWrapper(_Iterator &__ite) : _M_ite(__ite) {}
00353 
00354   const_reference operator*() const { return cast_traits::to_storage_type_cref(*_M_ite); }
00355 
00356   _Self& operator= (_Self const& __rhs) {
00357     _M_ite = __rhs._M_ite;
00358     return *this;
00359   }
00360 
00361   _Self& operator++() {
00362     ++_M_ite;
00363     return *this;
00364   }
00365 
00366   _Self& operator--() {
00367     --_M_ite;
00368     return *this;
00369   }
00370 
00371   _Self& operator += (difference_type __offset) {
00372     _M_ite += __offset;
00373     return *this;
00374   }
00375   difference_type operator -(_Self const& __other) const
00376   { return _M_ite - __other._M_ite; }
00377 
00378   bool operator == (_Self const& __other) const
00379   { return _M_ite == __other._M_ite; }
00380 
00381   bool operator != (_Self const& __other) const
00382   { return _M_ite != __other._M_ite; }
00383 
00384   bool operator < (_Self const& __rhs) const
00385   { return _M_ite < __rhs._M_ite; }
00386 
00387 private:
00388   _Iterator _M_ite;
00389 };
00390 
00391 template <class _Tp, class _Iterator>
00392 struct _IteWrapper<_Tp, _Tp, _Iterator>
00393 { typedef _Iterator _Ite; };
00394 
00395 #else
00396 
00397 /*
00398  * In this config the storage type is qualified in respect of the
00399  * value_type qualification. Simple reinterpret_cast is enough.
00400  */
00401 template <class _StorageT, class _ValueT>
00402 struct _CastTraits {
00403   typedef _StorageT storage_type;
00404   typedef _ValueT value_type;
00405 
00406   static value_type * to_value_type_ptr(storage_type *__ptr)
00407   { return __REINTERPRET_CAST(value_type*, __ptr); }
00408   static value_type const* to_value_type_cptr(storage_type const*__ptr)
00409   { return __REINTERPRET_CAST(value_type const*, __ptr); }
00410   static value_type ** to_value_type_pptr(storage_type **__ptr)
00411   { return __REINTERPRET_CAST(value_type **, __ptr); }
00412   static value_type & to_value_type_ref(storage_type &__ref)
00413   { return __REINTERPRET_CAST(value_type&, __ref); }
00414   static value_type const& to_value_type_cref(storage_type const&__ref)
00415   { return __REINTERPRET_CAST(value_type const&, __ref); }
00416   // Reverse versions
00417   static storage_type * to_storage_type_ptr(value_type *__ptr)
00418   { return __REINTERPRET_CAST(storage_type*, __ptr); }
00419   static storage_type const* to_storage_type_cptr(value_type const*__ptr)
00420   { return __REINTERPRET_CAST(storage_type const*, __ptr); }
00421   static storage_type ** to_storage_type_pptr(value_type **__ptr)
00422   { return __REINTERPRET_CAST(storage_type **, __ptr); }
00423   static storage_type const& to_storage_type_cref(value_type const&__ref)
00424   { return __REINTERPRET_CAST(storage_type const&, __ref); }
00425   template <class _Tp1>
00426   static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref)
00427   { return __ref; }
00428 };
00429 
00430 #endif
00431 
00432 //Wrapper functors:
00433 template <class _StorageT, class _ValueT, class _UnaryPredicate>
00434 struct _UnaryPredWrapper {
00435   typedef _CastTraits<_StorageT, _ValueT> cast_traits;
00436 
00437   _UnaryPredWrapper (_UnaryPredicate const& __pred) : _M_pred(__pred) {}
00438 
00439   bool operator () (_StorageT const& __ref) const
00440   { return _M_pred(cast_traits::to_value_type_cref(__ref)); }
00441 
00442 private:
00443   _UnaryPredicate _M_pred;
00444 };
00445 
00446 template <class _StorageT, class _ValueT, class _BinaryPredicate>
00447 struct _BinaryPredWrapper {
00448   typedef _CastTraits<_StorageT, _ValueT> cast_traits;
00449 
00450   _BinaryPredWrapper () {}
00451   _BinaryPredWrapper (_BinaryPredicate const& __pred) : _M_pred(__pred) {}
00452 
00453   _BinaryPredicate get_pred() const { return _M_pred; }
00454 
00455   bool operator () (_StorageT const& __fst, _StorageT const& __snd) const
00456   { return _M_pred(cast_traits::to_value_type_cref(__fst), cast_traits::to_value_type_cref(__snd)); }
00457 
00458   //Cast operator used to transparently access underlying predicate
00459   //in set::key_comp() method
00460   operator _BinaryPredicate() const
00461   { return _M_pred; }
00462 
00463 private:
00464   _BinaryPredicate _M_pred;
00465 };
00466 
00467 _STLP_MOVE_TO_STD_NAMESPACE
00468 
00469 _STLP_END_NAMESPACE
00470 
00471 #endif /* _STLP_POINTERS_SPEC_TOOLS_H */

Generated on Sat May 26 2012 04:28:24 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.