X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=include%2Fc%2B%2B%2Fstl%2Fstl%2Fpointers%2F_tools.h;fp=include%2Fc%2B%2B%2Fstl%2Fstl%2Fpointers%2F_tools.h;h=e02fc42abdadf60f33b9cdedef3f8841fb3d6ebe;hp=0000000000000000000000000000000000000000;hb=173d8903eb9d51a4ea7d7fa3e52dc86c9bb6d4f1;hpb=b024710fe2b60cd4a42a8993b61333d6cdb56ca3 diff --git a/include/c++/stl/stl/pointers/_tools.h b/include/c++/stl/stl/pointers/_tools.h new file mode 100644 index 0000000..e02fc42 --- /dev/null +++ b/include/c++/stl/stl/pointers/_tools.h @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2003 + * Francois Dumont + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use or copy this software for any purpose is hereby granted + * without fee, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef _STLP_POINTERS_SPEC_TOOLS_H +#define _STLP_POINTERS_SPEC_TOOLS_H + +#ifndef _STLP_TYPE_TRAITS_H +# include +#endif + +_STLP_BEGIN_NAMESPACE + +//Some usefull declarations: +template struct less; + +_STLP_MOVE_TO_PRIV_NAMESPACE + +template +struct _BinaryPredWrapper; + +/* + * Since the compiler only allows at most one non-trivial + * implicit conversion we can make use of a shim class to + * be sure that functions below doesn't accept classes with + * implicit pointer conversion operators + */ +struct _ConstVolatileVoidPointerShim +{ _ConstVolatileVoidPointerShim(const volatile void*); }; + +//The dispatch functions: +struct _VoidPointerShim +{ _VoidPointerShim(void*); }; +struct _ConstVoidPointerShim +{ _ConstVoidPointerShim(const void*); }; +struct _VolatileVoidPointerShim +{ _VolatileVoidPointerShim(volatile void*); }; + +template +char _UseVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&); +char _UseVoidPtrStorageType(const __true_type& /*POD*/, ...); +char* _UseVoidPtrStorageType(const __true_type& /*POD*/, _VoidPointerShim); + +template +char _UseConstVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&); +char _UseConstVoidPtrStorageType(const __true_type& /*POD*/, ...); +char* _UseConstVoidPtrStorageType(const __true_type& /*POD*/, _ConstVoidPointerShim); + +template +char _UseVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&); +char _UseVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...); +char* _UseVolatileVoidPtrStorageType(const __true_type& /*POD*/, _VolatileVoidPointerShim); + +template +char _UseConstVolatileVoidPtrStorageType(const __false_type& /*POD*/, const _Tp&); +char _UseConstVolatileVoidPtrStorageType(const __true_type& /*POD*/, ...); +char* _UseConstVolatileVoidPtrStorageType(const __true_type& /*POD*/, _ConstVolatileVoidPointerShim); + +template +struct _StorageType { + typedef typename __type_traits<_Tp>::is_POD_type _PODType; + static _Tp __null_rep(); + + enum { use_void_ptr = (sizeof(_UseVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) }; + enum { use_const_void_ptr = (sizeof(_UseConstVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) }; + enum { use_volatile_void_ptr = (sizeof(_UseVolatileVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) }; + enum { use_const_volatile_void_ptr = (sizeof(_UseConstVolatileVoidPtrStorageType(_PODType(), __null_rep())) == sizeof(char*)) }; + + typedef typename __select::_Ret >::_Ret >::_Ret >::_Ret _QualifiedType; + +#if !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) + /* If the compiler do not support the iterator_traits structure we cannot wrap + * iterators pass to container template methods. The iterator dereferenced value + * has to be storable without any cast in the chosen storage type. To guaranty + * that the void pointer has to be correctly qualified. + */ + typedef _QualifiedType _Type; +#else + /* With iterator_traits we can wrap passed iterators and make the necessary casts. + * We can always use a simple void* storage type: + */ + typedef typename __select::_Ret _Type; +#endif +}; + +template +struct _AssocStorageTypes { + typedef _StorageType<_Tp> _StorageTypeInfo; + typedef typename _StorageTypeInfo::_Type _SType; + + //We need to also check that the comparison functor used to instanciate the assoc container + //is the default Standard less implementation: + typedef typename _IsSTLportClass<_Compare>::_Ret _STLportLess; + enum { is_default_less = __type2bool<_STLportLess>::_Ret }; + + typedef typename __select::_Ret _KeyStorageType; + enum { ptr_type = _StorageTypeInfo::use_const_volatile_void_ptr }; + typedef typename __select, + _Compare>::_Ret _CompareStorageType; +}; + + +#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) +/* + * Base struct to deal with qualifiers + */ +template +struct _VoidCastTraitsAux { + typedef _QualifiedStorageT void_cv_type; + typedef _StorageT void_type; + + static void_type * uncv_ptr(void_cv_type *__ptr) + { return __ptr; } + static void_type const* uncv_cptr(void_cv_type const*__ptr) + { return __ptr; } + static void_type ** uncv_pptr(void_cv_type **__ptr) + { return __ptr; } + static void_type & uncv_ref(void_cv_type & __ref) + { return __ref; } + static void_type const& uncv_cref(void_cv_type const& __ref) + { return __ref; } + static void_cv_type* cv_ptr(void_type *__ptr) + { return __ptr; } + static void_cv_type const* cv_cptr(void_type const*__ptr) + { return __ptr; } + static void_cv_type ** cv_pptr(void_type **__ptr) + { return __ptr; } + static void_cv_type & cv_ref(void_type & __ref) + { return __ref; } + static void_cv_type const& cv_cref(void_type const& __ref) + { return __ref; } +}; + +template +struct _VoidCastTraitsAuxBase { + typedef _VoidCVType* void_cv_type; + typedef void* void_type; + + static void_type* uncv_ptr(void_cv_type *__ptr) + { return __CONST_CAST(void_type*, __ptr); } + static void_type const* uncv_cptr(void_cv_type const*__ptr) + { return __CONST_CAST(void_type const*, __ptr); } + static void_type** uncv_pptr(void_cv_type **__ptr) + { return __CONST_CAST(void_type**, __ptr); } + static void_type& uncv_ref(void_cv_type &__ref) + { return __CONST_CAST(void_type&, __ref); } + static void_type const& uncv_cref(void_cv_type const& __ptr) + { return __CONST_CAST(void_type const&, __ptr); } + // The reverse versions + static void_cv_type * cv_ptr(void_type *__ptr) + { return __CONST_CAST(void_cv_type *, __ptr); } + static void_cv_type const* cv_cptr(void_type const*__ptr) + { return __CONST_CAST(void_cv_type const*, __ptr); } + static void_cv_type ** cv_pptr(void_type **__ptr) + { return __CONST_CAST(void_cv_type**, __ptr); } + static void_cv_type & cv_ref(void_type &__ref) + { return __CONST_CAST(void_cv_type &, __ref); } + static void_cv_type const& cv_cref(void_type const& __ref) + { return __CONST_CAST(void_cv_type const&, __ref); } +}; + +_STLP_TEMPLATE_NULL +struct _VoidCastTraitsAux : _VoidCastTraitsAuxBase +{}; +_STLP_TEMPLATE_NULL +struct _VoidCastTraitsAux : _VoidCastTraitsAuxBase +{}; +_STLP_TEMPLATE_NULL +struct _VoidCastTraitsAux : _VoidCastTraitsAuxBase +{}; + +template +struct _CastTraits { + typedef _ValueT value_type; + typedef typename _StorageType<_ValueT>::_QualifiedType _QualifiedStorageT; + typedef _VoidCastTraitsAux<_StorageT, _QualifiedStorageT> cv_traits; + typedef typename cv_traits::void_type void_type; + typedef typename cv_traits::void_cv_type void_cv_type; + + static value_type * to_value_type_ptr(void_type *__ptr) + { return __REINTERPRET_CAST(value_type *, cv_traits::cv_ptr(__ptr)); } + static value_type const* to_value_type_cptr(void_type const*__ptr) + { return __REINTERPRET_CAST(value_type const*, cv_traits::cv_cptr(__ptr)); } + static value_type ** to_value_type_pptr(void_type **__ptr) + { return __REINTERPRET_CAST(value_type **, cv_traits::cv_pptr(__ptr)); } + static value_type & to_value_type_ref(void_type &__ref) + { return __REINTERPRET_CAST(value_type &, cv_traits::cv_ref(__ref)); } + static value_type const& to_value_type_cref(void_type const& __ptr) + { return __REINTERPRET_CAST(value_type const&, cv_traits::cv_cref(__ptr)); } + // Reverse versions + static void_type * to_storage_type_ptr(value_type *__ptr) + { return cv_traits::uncv_ptr(__REINTERPRET_CAST(void_cv_type *, __ptr)); } + static void_type const* to_storage_type_cptr(value_type const*__ptr) + { return cv_traits::uncv_cptr(__REINTERPRET_CAST(void_cv_type const*, __ptr)); } + static void_type ** to_storage_type_pptr(value_type **__ptr) + { return cv_traits::uncv_pptr(__REINTERPRET_CAST(void_cv_type **, __ptr)); } + static void_type const& to_storage_type_cref(value_type const& __ref) + { return cv_traits::uncv_cref(__REINTERPRET_CAST(void_cv_type const&, __ref)); } + + //Method used to treat set container template method extension + static void_type const& to_storage_type_crefT(value_type const& __ref) + { return to_storage_type_cref(__ref); } +}; + +template +struct _CastTraits<_Tp, _Tp> { + typedef _Tp storage_type; + typedef _Tp value_type; + + static value_type * to_value_type_ptr(storage_type *__ptr) + { return __ptr; } + static value_type const* to_value_type_cptr(storage_type const*__ptr) + { return __ptr; } + static value_type ** to_value_type_pptr(storage_type **__ptr) + { return __ptr; } + static value_type & to_value_type_ref(storage_type &__ref) + { return __ref; } + static value_type const& to_value_type_cref(storage_type const&__ref) + { return __ref; } + // Reverse versions + static storage_type * to_storage_type_ptr(value_type *__ptr) + { return __ptr; } + static storage_type const* to_storage_type_cptr(value_type const*__ptr) + { return __ptr; } + static storage_type ** to_storage_type_pptr(value_type **__ptr) + { return __ptr; } + static storage_type const& to_storage_type_cref(value_type const& __ref) + { return __ref; } + + //Method used to treat set container template method extension + template + static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref) + { return __ref; } +}; + +#define _STLP_USE_ITERATOR_WRAPPER + +template +struct _IteWrapper { + typedef _CastTraits<_StorageT, _ValueT> cast_traits; + typedef iterator_traits<_Iterator> _IteTraits; + + typedef typename _IteTraits::iterator_category iterator_category; + typedef _StorageT value_type; + typedef typename _IteTraits::difference_type difference_type; + typedef value_type* pointer; + typedef value_type const& const_reference; + //This wrapper won't be used for input so to avoid surprise + //the reference type will be a const reference: + typedef const_reference reference; + + typedef _IteWrapper<_StorageT, _ValueT, _Iterator> _Self; + typedef _Self _Ite; + + _IteWrapper(_Iterator &__ite) : _M_ite(__ite) {} + + const_reference operator*() const { return cast_traits::to_storage_type_cref(*_M_ite); } + + _Self& operator= (_Self const& __rhs) { + _M_ite = __rhs._M_ite; + return *this; + } + + _Self& operator++() { + ++_M_ite; + return *this; + } + + _Self& operator--() { + --_M_ite; + return *this; + } + + _Self& operator += (difference_type __offset) { + _M_ite += __offset; + return *this; + } + difference_type operator -(_Self const& __other) const + { return _M_ite - __other._M_ite; } + + bool operator == (_Self const& __other) const + { return _M_ite == __other._M_ite; } + + bool operator != (_Self const& __other) const + { return _M_ite != __other._M_ite; } + + bool operator < (_Self const& __rhs) const + { return _M_ite < __rhs._M_ite; } + +private: + _Iterator _M_ite; +}; + +template +struct _IteWrapper<_Tp, _Tp, _Iterator> +{ typedef _Iterator _Ite; }; + +#else + +/* + * In this config the storage type is qualified in respect of the + * value_type qualification. Simple reinterpret_cast is enough. + */ +template +struct _CastTraits { + typedef _StorageT storage_type; + typedef _ValueT value_type; + + static value_type * to_value_type_ptr(storage_type *__ptr) + { return __REINTERPRET_CAST(value_type*, __ptr); } + static value_type const* to_value_type_cptr(storage_type const*__ptr) + { return __REINTERPRET_CAST(value_type const*, __ptr); } + static value_type ** to_value_type_pptr(storage_type **__ptr) + { return __REINTERPRET_CAST(value_type **, __ptr); } + static value_type & to_value_type_ref(storage_type &__ref) + { return __REINTERPRET_CAST(value_type&, __ref); } + static value_type const& to_value_type_cref(storage_type const&__ref) + { return __REINTERPRET_CAST(value_type const&, __ref); } + // Reverse versions + static storage_type * to_storage_type_ptr(value_type *__ptr) + { return __REINTERPRET_CAST(storage_type*, __ptr); } + static storage_type const* to_storage_type_cptr(value_type const*__ptr) + { return __REINTERPRET_CAST(storage_type const*, __ptr); } + static storage_type ** to_storage_type_pptr(value_type **__ptr) + { return __REINTERPRET_CAST(storage_type **, __ptr); } + static storage_type const& to_storage_type_cref(value_type const&__ref) + { return __REINTERPRET_CAST(storage_type const&, __ref); } + template + static _Tp1 const& to_storage_type_crefT(_Tp1 const& __ref) + { return __ref; } +}; + +#endif + +//Wrapper functors: +template +struct _UnaryPredWrapper { + typedef _CastTraits<_StorageT, _ValueT> cast_traits; + + _UnaryPredWrapper (_UnaryPredicate const& __pred) : _M_pred(__pred) {} + + bool operator () (_StorageT const& __ref) const + { return _M_pred(cast_traits::to_value_type_cref(__ref)); } + +private: + _UnaryPredicate _M_pred; +}; + +template +struct _BinaryPredWrapper { + typedef _CastTraits<_StorageT, _ValueT> cast_traits; + + _BinaryPredWrapper () {} + _BinaryPredWrapper (_BinaryPredicate const& __pred) : _M_pred(__pred) {} + + _BinaryPredicate get_pred() const { return _M_pred; } + + bool operator () (_StorageT const& __fst, _StorageT const& __snd) const + { return _M_pred(cast_traits::to_value_type_cref(__fst), cast_traits::to_value_type_cref(__snd)); } + + //Cast operator used to transparently access underlying predicate + //in set::key_comp() method + operator _BinaryPredicate() const + { return _M_pred; } + +private: + _BinaryPredicate _M_pred; +}; + +_STLP_MOVE_TO_STD_NAMESPACE + +_STLP_END_NAMESPACE + +#endif /* _STLP_POINTERS_SPEC_TOOLS_H */