/home/ntakagi/work/STLport-5.1.5/stlport/stl/pointers/_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 _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  doxygen 1.5.1