/home/ntakagi/work/STLport-5.1.5/stlport/stl/pointers/_tools.hGo 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 _ConstVolatileVoidPointerShim 00044 { _ConstVolatileVoidPointerShim(const volatile void*); }; 00045 00046 //The dispatch functions: 00047 struct _VoidPointerShim 00048 { _VoidPointerShim(void*); }; 00049 struct _ConstVoidPointerShim 00050 { _ConstVoidPointerShim(const void*); }; 00051 struct _VolatileVoidPointerShim 00052 { _VolatileVoidPointerShim(volatile void*); }; 00053 00054 template <class _Tp> 00055 char _UseVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&); 00056 char _UseVoidPtrStorageType(const __true_type& /*POD*/, ...); 00057 char* _UseVoidPtrStorageType(const __true_type& /*POD*/, _VoidPointerShim); 00058 00059 template <class _Tp> 00060 char _UseConstVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&); 00061 char _UseConstVoidPtrStorageType(const __true_type& /*POD*/, ...); 00062 char* _UseConstVoidPtrStorageType(const __true_type& /*POD*/, _ConstVoidPointerShim); 00063 00064 template <class _Tp> 00065 char _UseVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&); 00066 char _UseVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...); 00067 char* _UseVolatileVoidPtrStorageType(const __true_type& /*POD*/, _VolatileVoidPointerShim); 00068 00069 template <class _Tp> 00070 char _UseConstVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&); 00071 char _UseConstVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...); 00072 char* _UseConstVolatileVoidPtrStorageType(const __true_type& /*POD*/, _ConstVolatileVoidPointerShim); 00073 00074 template <class _Tp> 00075 struct _StorageType { 00076 typedef typename __type_traits<_Tp>::is_POD_type _PODType; 00077 static _Tp __null_rep(); 00078 00079 enum { use_void_ptr = (sizeof(_UseVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) }; 00080 enum { use_const_void_ptr = (sizeof(_UseConstVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) }; 00081 enum { use_volatile_void_ptr = (sizeof(_UseVolatileVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) }; 00082 enum { use_const_volatile_void_ptr = (sizeof(_UseConstVolatileVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) }; 00083 00084 typedef typename __select<!use_const_volatile_void_ptr, 00085 _Tp, 00086 typename __select<use_void_ptr, 00087 void*, 00088 typename __select<use_const_void_ptr, 00089 const void*, 00090 typename __select<use_volatile_void_ptr, 00091 volatile void*, 00092 const volatile void*>::_Ret >::_Ret >::_Ret >::_Ret _QualifiedType; 00093 00094 #if !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 00095 /* If the compiler do not support the iterator_traits structure we cannot wrap 00096 * iterators pass to container template methods. The iterator dereferenced value 00097 * has to be storable without any cast in the chosen storage type. To guaranty 00098 * that the void pointer has to be correctly qualified. 00099 */ 00100 typedef _QualifiedType _Type; 00101 #else 00102 /* With iterator_traits we can wrap passed iterators and make the necessary casts. 00103 * We can always use a simple void* storage type: 00104 */ 00105 typedef typename __select<use_const_volatile_void_ptr, 00106 void*, 00107 _Tp>::_Ret _Type; 00108 #endif 00109 }; 00110 00111 template <class _Tp, class _Compare> 00112 struct _AssocStorageTypes { 00113 typedef _StorageType<_Tp> _StorageTypeInfo; 00114 typedef typename _StorageTypeInfo::_Type _SType; 00115 00116 //We need to also check that the comparison functor used to instanciate the assoc container 00117 //is the default Standard less implementation: 00118 typedef typename _IsSTLportClass<_Compare>::_Ret _STLportLess; 00119 enum { is_default_less = __type2bool<_STLportLess>::_Ret }; 00120 00121 typedef typename __select<is_default_less, _SType, _Tp>::_Ret _KeyStorageType; 00122 enum { ptr_type = _StorageTypeInfo::use_const_volatile_void_ptr }; 00123 typedef typename __select<is_default_less && ptr_type, 00124 _BinaryPredWrapper<_KeyStorageType, _Tp, _Compare>, 00125 _Compare>::_Ret _CompareStorageType; 00126 }; 00127 00128 00129 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 00130 /* 00131 * Base struct to deal with qualifiers 00132 */ 00133 template <class _StorageT, class _QualifiedStorageT> 00134 struct _VoidCastTraitsAux { 00135 typedef _QualifiedStorageT void_cv_type; 00136 typedef _StorageT void_type; 00137 00138 static void_type * uncv_ptr(void_cv_type *__ptr) 00139 { return __ptr; } 00140 static void_type const* uncv_cptr(void_cv_type const*__ptr) 00141 { return __ptr; } 00142 static void_type ** uncv_pptr(void_cv_type **__ptr) 00143 { return __ptr; } 00144 static void_type & uncv_ref(void_cv_type & __ref) 00145 { return __ref; } 00146 static void_type const& uncv_cref(void_cv_type const& __ref) 00147 { return __ref; } 00148 static void_cv_type* cv_ptr(void_type *__ptr) 00149 { return __ptr; } 00150 static void_cv_type const* cv_cptr(void_type const*__ptr) 00151 { return __ptr; } 00152 static void_cv_type ** cv_pptr(void_type **__ptr) 00153 { return __ptr; } 00154 static void_cv_type & cv_ref(void_type & __ref) 00155 { return __ref; } 00156 static void_cv_type const& cv_cref(void_type const& __ref) 00157 { return __ref; } 00158 }; 00159 00160 template <class _VoidCVType> 00161 struct _VoidCastTraitsAuxBase { 00162 typedef _VoidCVType* void_cv_type; 00163 typedef void* void_type; 00164 00165 static void_type* uncv_ptr(void_cv_type *__ptr) 00166 { return __CONST_CAST(void_type*, __ptr); } 00167 static void_type const* uncv_cptr(void_cv_type const*__ptr) 00168 { return __CONST_CAST(void_type const*, __ptr); } 00169 static void_type** uncv_pptr(void_cv_type **__ptr) 00170 { return __CONST_CAST(void_type**, __ptr); } 00171 static void_type& uncv_ref(void_cv_type &__ref) 00172 { return __CONST_CAST(void_type&, __ref); } 00173 static void_type const& uncv_cref(void_cv_type const& __ptr) 00174 { return __CONST_CAST(void_type const&, __ptr); } 00175 // The reverse versions 00176 static void_cv_type * cv_ptr(void_type *__ptr) 00177 { return __CONST_CAST(void_cv_type *, __ptr); } 00178 static void_cv_type const* cv_cptr(void_type const*__ptr) 00179 { return __CONST_CAST(void_cv_type const*, __ptr); } 00180 static void_cv_type ** cv_pptr(void_type **__ptr) 00181 { return __CONST_CAST(void_cv_type**, __ptr); } 00182 static void_cv_type & cv_ref(void_type &__ref) 00183 { return __CONST_CAST(void_cv_type &, __ref); } 00184 static void_cv_type const& cv_cref(void_type const& __ref) 00185 { return __CONST_CAST(void_cv_type const&, __ref); } 00186 }; 00187 00188 _STLP_TEMPLATE_NULL 00189 struct _VoidCastTraitsAux<void*, const void*> : _VoidCastTraitsAuxBase<void const> 00190 {}; 00191 _STLP_TEMPLATE_NULL 00192 struct _VoidCastTraitsAux<void*, volatile void*> : _VoidCastTraitsAuxBase<void volatile> 00193 {}; 00194 _STLP_TEMPLATE_NULL 00195 struct _VoidCastTraitsAux<void*, const volatile void*> : _VoidCastTraitsAuxBase<void const volatile> 00196 {}; 00197 00198 template <class _StorageT, class _ValueT> 00199 struct _CastTraits { 00200 typedef _ValueT value_type; 00201 typedef typename _StorageType<_ValueT>::_QualifiedType _QualifiedStorageT; 00202 typedef _VoidCastTraitsAux<_StorageT, _QualifiedStorageT> cv_traits; 00203 typedef typename cv_traits::void_type void_type; 00204 typedef typename cv_traits::void_cv_type void_cv_type; 00205 00206 static value_type * to_value_type_ptr(void_type *__ptr) 00207 { return __REINTERPRET_CAST(value_type *, cv_traits::cv_ptr(__ptr)); } 00208 static value_type const* to_value_type_cptr(void_type const*__ptr) 00209 { return __REINTERPRET_CAST(value_type const*, cv_traits::cv_cptr(__ptr)); } 00210 static value_type ** to_value_type_pptr(void_type **__ptr) 00211 { return __REINTERPRET_CAST(value_type **, cv_traits::cv_pptr(__ptr)); } 00212 static value_type & to_value_type_ref(void_type &__ref) 00213 { return __REINTERPRET_CAST(value_type &, cv_traits::cv_ref(__ref)); } 00214 static value_type const& to_value_type_cref(void_type const& __ptr) 00215 { return __REINTERPRET_CAST(value_type const&, cv_traits::cv_cref(__ptr)); } 00216 // Reverse versions 00217 static void_type * to_storage_type_ptr(value_type *__ptr) 00218 { return cv_traits::uncv_ptr(__REINTERPRET_CAST(void_cv_type *, __ptr)); } 00219 static void_type const* to_storage_type_cptr(value_type const*__ptr) 00220 { return cv_traits::uncv_cptr(__REINTERPRET_CAST(void_cv_type const*, __ptr)); } 00221 static void_type ** to_storage_type_pptr(value_type **__ptr) 00222 { return cv_traits::uncv_pptr(__REINTERPRET_CAST(void_cv_type **, __ptr)); } 00223 static void_type const& to_storage_type_cref(value_type const& __ref) 00224 { return cv_traits::uncv_cref(__REINTERPRET_CAST(void_cv_type const&, __ref)); } 00225 00226 //Method used to treat set container template method extension 00227 static void_type const& to_storage_type_crefT(value_type const& __ref) 00228 { return to_storage_type_cref(__ref); } 00229 }; 00230 00231 template <class _Tp> 00232 struct _CastTraits<_Tp, _Tp> { 00233 typedef _Tp storage_type; 00234 typedef _Tp value_type; 00235 00236 static value_type * to_value_type_ptr(storage_type *__ptr) 00237 { return __ptr; } 00238 static value_type const* to_value_type_cptr(storage_type const*__ptr) 00239 { return __ptr; } 00240 static value_type ** to_value_type_pptr(storage_type **__ptr) 00241 { return __ptr; } 00242 static value_type & to_value_type_ref(storage_type &__ref) 00243 { return __ref; } 00244 static value_type const& to_value_type_cref(storage_type const&__ref) 00245 { return __ref; } 00246 // Reverse versions 00247 static storage_type * to_storage_type_ptr(value_type *__ptr) 00248 { return __ptr; } 00249 static storage_type const* to_storage_type_cptr(value_type const*__ptr) 00250 { return __ptr; } 00251 static storage_type ** to_storage_type_pptr(value_type **__ptr) 00252 { return __ptr; } 00253 static storage_type const& to_storage_type_cref(value_type const& __ref) 00254 { return __ref; } 00255 00256 //Method used to treat set container template method extension 00257 template <class _Tp1> 00258 static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref) 00259 { return __ref; } 00260 }; 00261 00262 #define _STLP_USE_ITERATOR_WRAPPER 00263 00264 template <class _StorageT, class _ValueT, class _Iterator> 00265 struct _IteWrapper { 00266 typedef _CastTraits<_StorageT, _ValueT> cast_traits; 00267 typedef iterator_traits<_Iterator> _IteTraits; 00268 00269 typedef typename _IteTraits::iterator_category iterator_category; 00270 typedef _StorageT value_type; 00271 typedef typename _IteTraits::difference_type difference_type; 00272 typedef value_type* pointer; 00273 typedef value_type const& const_reference; 00274 //This wrapper won't be used for input so to avoid surprise 00275 //the reference type will be a const reference: 00276 typedef const_reference reference; 00277 00278 typedef _IteWrapper<_StorageT, _ValueT, _Iterator> _Self; 00279 typedef _Self _Ite; 00280 00281 _IteWrapper(_Iterator &__ite) : _M_ite(__ite) {} 00282 00283 const_reference operator*() const { return cast_traits::to_storage_type_cref(*_M_ite); } 00284 00285 _Self& operator= (_Self const& __rhs) { 00286 _M_ite = __rhs._M_ite; 00287 return *this; 00288 } 00289 00290 _Self& operator++() { 00291 ++_M_ite; 00292 return *this; 00293 } 00294 00295 _Self& operator--() { 00296 --_M_ite; 00297 return *this; 00298 } 00299 00300 _Self& operator += (difference_type __offset) { 00301 _M_ite += __offset; 00302 return *this; 00303 } 00304 difference_type operator -(_Self const& __other) const 00305 { return _M_ite - __other._M_ite; } 00306 00307 bool operator == (_Self const& __other) const 00308 { return _M_ite == __other._M_ite; } 00309 00310 bool operator != (_Self const& __other) const 00311 { return _M_ite != __other._M_ite; } 00312 00313 bool operator < (_Self const& __rhs) const 00314 { return _M_ite < __rhs._M_ite; } 00315 00316 private: 00317 _Iterator _M_ite; 00318 }; 00319 00320 template <class _Tp, class _Iterator> 00321 struct _IteWrapper<_Tp, _Tp, _Iterator> 00322 { typedef _Iterator _Ite; }; 00323 00324 #else 00325 00326 /* 00327 * In this config the storage type is qualified in respect of the 00328 * value_type qualification. Simple reinterpret_cast is enough. 00329 */ 00330 template <class _StorageT, class _ValueT> 00331 struct _CastTraits { 00332 typedef _StorageT storage_type; 00333 typedef _ValueT value_type; 00334 00335 static value_type * to_value_type_ptr(storage_type *__ptr) 00336 { return __REINTERPRET_CAST(value_type*, __ptr); } 00337 static value_type const* to_value_type_cptr(storage_type const*__ptr) 00338 { return __REINTERPRET_CAST(value_type const*, __ptr); } 00339 static value_type ** to_value_type_pptr(storage_type **__ptr) 00340 { return __REINTERPRET_CAST(value_type **, __ptr); } 00341 static value_type & to_value_type_ref(storage_type &__ref) 00342 { return __REINTERPRET_CAST(value_type&, __ref); } 00343 static value_type const& to_value_type_cref(storage_type const&__ref) 00344 { return __REINTERPRET_CAST(value_type const&, __ref); } 00345 // Reverse versions 00346 static storage_type * to_storage_type_ptr(value_type *__ptr) 00347 { return __REINTERPRET_CAST(storage_type*, __ptr); } 00348 static storage_type const* to_storage_type_cptr(value_type const*__ptr) 00349 { return __REINTERPRET_CAST(storage_type const*, __ptr); } 00350 static storage_type ** to_storage_type_pptr(value_type **__ptr) 00351 { return __REINTERPRET_CAST(storage_type **, __ptr); } 00352 static storage_type const& to_storage_type_cref(value_type const&__ref) 00353 { return __REINTERPRET_CAST(storage_type const&, __ref); } 00354 template <class _Tp1> 00355 static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref) 00356 { return __ref; } 00357 }; 00358 00359 #endif 00360 00361 //Wrapper functors: 00362 template <class _StorageT, class _ValueT, class _UnaryPredicate> 00363 struct _UnaryPredWrapper { 00364 typedef _CastTraits<_StorageT, _ValueT> cast_traits; 00365 00366 _UnaryPredWrapper (_UnaryPredicate const& __pred) : _M_pred(__pred) {} 00367 00368 bool operator () (_StorageT const& __ref) const 00369 { return _M_pred(cast_traits::to_value_type_cref(__ref)); } 00370 00371 private: 00372 _UnaryPredicate _M_pred; 00373 }; 00374 00375 template <class _StorageT, class _ValueT, class _BinaryPredicate> 00376 struct _BinaryPredWrapper { 00377 typedef _CastTraits<_StorageT, _ValueT> cast_traits; 00378 00379 _BinaryPredWrapper () {} 00380 _BinaryPredWrapper (_BinaryPredicate const& __pred) : _M_pred(__pred) {} 00381 00382 _BinaryPredicate get_pred() const { return _M_pred; } 00383 00384 bool operator () (_StorageT const& __fst, _StorageT const& __snd) const 00385 { return _M_pred(cast_traits::to_value_type_cref(__fst), cast_traits::to_value_type_cref(__snd)); } 00386 00387 //Cast operator used to transparently access underlying predicate 00388 //in set::key_comp() method 00389 operator _BinaryPredicate() const 00390 { return _M_pred; } 00391 00392 private: 00393 _BinaryPredicate _M_pred; 00394 }; 00395 00396 _STLP_MOVE_TO_STD_NAMESPACE 00397 00398 _STLP_END_NAMESPACE 00399 00400 #endif /* _STLP_POINTERS_SPEC_TOOLS_H */
Generated on Mon Mar 10 15:32:46 2008 by ![]() |