Home | Info | Community | Development | myReactOS | Contact Us
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
1.7.6.1
|