Index: include/ext/cast.h =================================================================== *** include/ext/cast.h (revision 141739) --- include/ext/cast.h (working copy) *************** *** 27,34 **** // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. ! #ifndef _EXT_CAST_ ! #define _EXT_CAST_ 1 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx); --- 27,34 ---- // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. ! #ifndef _CAST_H ! #define _CAST_H 1 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx); *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx); *** 48,61 **** */ template struct _Caster ! { ! typedef typename _ToType::element_type* type; ! }; template struct _Caster<_ToType*> ! { ! typedef _ToType* type; ! }; /** * Casting operations for cases where _FromType is not a standard pointer. --- 48,58 ---- */ template struct _Caster ! { typedef typename _ToType::element_type* type; }; ! template struct _Caster<_ToType*> ! { typedef _ToType* type; }; /** * Casting operations for cases where _FromType is not a standard pointer. *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx); *** 118,121 **** _GLIBCXX_END_NAMESPACE ! #endif --- 115,118 ---- _GLIBCXX_END_NAMESPACE ! #endif // _CAST_H Index: include/ext/pointer.h =================================================================== *** include/ext/pointer.h (revision 141739) --- include/ext/pointer.h (working copy) *************** *** 1,7 **** // Custom pointer adapter and sample storage policies ! // Copyright (C) 2008 ! // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the --- 1,6 ---- // Custom pointer adapter and sample storage policies ! // Copyright (C) 2008 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the *************** *** 33,55 **** * @author Bob Walters * * Provides reusable _Pointer_adapter for assisting in the development of ! * custom pointer types that can be used with libstdc++ STL containers via * the allocator::pointer and allocator::const_pointer typedefs. */ ! #ifndef _EXT_POINTER_ADAPTER ! #define _EXT_POINTER_ADAPTER 1 ! #include #include - #include - - - // forward declaration of the iterator tag - namespace std { - struct random_access_iterator_tag; - }; - _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) --- 32,47 ---- * @author Bob Walters * * Provides reusable _Pointer_adapter for assisting in the development of ! * custom pointer types that can be used with the standard containers via * the allocator::pointer and allocator::const_pointer typedefs. */ ! #ifndef _POINTER_H ! #define _POINTER_H 1 ! #include ! #include #include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 64,78 **** * 4) An operator<() to support pointer comparison. * 5) An operator==() to support pointer comparison. */ ! template class _Std_pointer_impl { public: // the type this pointer points to. ! typedef _Type element_type; // A method to fetch the pointer value as a standard T* value; ! inline _Type* get() const { return _M_value; } --- 56,70 ---- * 4) An operator<() to support pointer comparison. * 5) An operator==() to support pointer comparison. */ ! template class _Std_pointer_impl { public: // the type this pointer points to. ! typedef _Tp element_type; // A method to fetch the pointer value as a standard T* value; ! inline _Tp* get() const { return _M_value; } *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 94,100 **** element_type* _M_value; }; - /** * @brief A storage policy for use with _Pointer_adapter<> which stores * the pointer's address as an offset value which is relative to --- 86,91 ---- *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 108,134 **** * As there is no reason why any normal pointer would point 1 byte into * its own pointer address. */ ! template class _Relative_pointer_impl { public: ! typedef _Type element_type; ! _Type* get() const { if (_M_diff == 1) ! return NULL; else ! return reinterpret_cast<_Type*>( const_cast(reinterpret_cast(this)) + _M_diff); } void ! set(_Type* __arg) { ! if (__arg == NULL) _M_diff = 1; else _M_diff = reinterpret_cast(__arg) --- 99,125 ---- * As there is no reason why any normal pointer would point 1 byte into * its own pointer address. */ ! template class _Relative_pointer_impl { public: ! typedef _Tp element_type; ! _Tp* get() const { if (_M_diff == 1) ! return 0; else ! return reinterpret_cast<_Tp*>( const_cast(reinterpret_cast(this)) + _M_diff); } void ! set(_Tp* __arg) { ! if (!__arg) _M_diff = 1; else _M_diff = reinterpret_cast(__arg) *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 145,177 **** { return (this->get() == __rarg.get()); } private: ! ptrdiff_t _M_diff; }; /** * Relative_pointer_impl needs a specialization for const T because of * the casting done during pointer arithmetic. */ ! template ! class _Relative_pointer_impl { public: ! typedef const _Type element_type; ! const _Type* get() const { if (_M_diff == 1) ! return NULL; else ! return reinterpret_cast( (reinterpret_cast(this)) + _M_diff); } void ! set(const _Type* __arg) { ! if (__arg == NULL) _M_diff = 1; else _M_diff = reinterpret_cast(__arg) --- 136,168 ---- { return (this->get() == __rarg.get()); } private: ! std::ptrdiff_t _M_diff; }; /** * Relative_pointer_impl needs a specialization for const T because of * the casting done during pointer arithmetic. */ ! template ! class _Relative_pointer_impl { public: ! typedef const _Tp element_type; ! const _Tp* get() const { if (_M_diff == 1) ! return 0; else ! return reinterpret_cast( (reinterpret_cast(this)) + _M_diff); } void ! set(const _Tp* __arg) { ! if (!__arg) _M_diff = 1; else _M_diff = reinterpret_cast(__arg) *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 188,197 **** { return (this->get() == __rarg.get()); } private: ! ptrdiff_t _M_diff; }; - /** * The specialization on this type helps resolve the problem of * reference to void, and eliminates the need to specialize _Pointer_adapter --- 179,187 ---- { return (this->get() == __rarg.get()); } private: ! std::ptrdiff_t _M_diff; }; /** * The specialization on this type helps resolve the problem of * reference to void, and eliminates the need to specialize _Pointer_adapter *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 201,234 **** template struct _Reference_type ! { ! typedef _Tp& reference; ! }; template<> struct _Reference_type ! { ! typedef _Invalid_type& reference; ! }; template<> struct _Reference_type ! { ! typedef const _Invalid_type& reference; ! }; template<> struct _Reference_type ! { ! typedef volatile _Invalid_type& reference; ! }; template<> struct _Reference_type ! { ! typedef const volatile _Invalid_type& reference; ! }; ! /** * This structure accomodates the way in which std::iterator_traits<> --- 191,213 ---- template struct _Reference_type ! { typedef _Tp& reference; }; template<> struct _Reference_type ! { typedef _Invalid_type& reference; }; template<> struct _Reference_type ! { typedef const _Invalid_type& reference; }; template<> struct _Reference_type ! { typedef volatile _Invalid_type& reference; }; template<> struct _Reference_type ! { typedef const volatile _Invalid_type& reference; }; /** * This structure accomodates the way in which std::iterator_traits<> *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 236,270 **** */ template struct _Unqualified_type ! { ! typedef _Tp type; ! }; template struct _Unqualified_type ! { ! typedef _Tp type; ! }; template struct _Unqualified_type ! { ! typedef volatile _Tp type; ! }; template struct _Unqualified_type ! { ! typedef volatile _Tp type; ! }; ! ! /** ! * The following provides an 'alternative pointer' that works with ! * libstdc++-v3 containers when specified as the pointer typedef of the ! * allocator. ! * * The pointer type used with the containers doesn't have to be this class, * but it must support the implicit conversions, pointer arithmetic, * comparison operators, etc. that are supported by this class, and avoid --- 215,238 ---- */ template struct _Unqualified_type ! { typedef _Tp type; }; template struct _Unqualified_type ! { typedef _Tp type; }; template struct _Unqualified_type ! { typedef volatile _Tp type; }; template struct _Unqualified_type ! { typedef volatile _Tp type; }; /** ! * The following provides an 'alternative pointer' that works with the ! * containers when specified as the pointer typedef of the allocator. ! * * The pointer type used with the containers doesn't have to be this class, * but it must support the implicit conversions, pointer arithmetic, * comparison operators, etc. that are supported by this class, and avoid *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 290,339 **** * _Tp* const == const _Pointer_adapter<_Std_pointer_impl<_Tp> >; * const _Tp* const == const _Pointer_adapter<_Std_pointer_impl >; */ ! ! template class _Pointer_adapter : public _Storage_policy { public: typedef typename _Storage_policy::element_type element_type; ! // These are needed for iterator_traits typedef std::random_access_iterator_tag iterator_category; typedef typename _Unqualified_type::type value_type; ! typedef ptrdiff_t difference_type; typedef _Pointer_adapter pointer; typedef typename _Reference_type::reference reference; ! // Reminder: 'const' methods mean that the method is valid when the // pointer is immutable, and has nothing to do with whether the // 'pointee' is const. // Default Constructor (Convert from element_type*) ! _Pointer_adapter(element_type* __arg = NULL) { _Storage_policy::set(__arg); } ! // Copy constructor from _Pointer_adapter of same type. _Pointer_adapter(const _Pointer_adapter& __arg) { _Storage_policy::set(__arg.get()); } ! // Convert from _Up* if conversion to element_type* is valid. template ! _Pointer_adapter(_Up*__arg) ! { ! __glibcxx_function_requires(_ConvertibleConcept); ! _Storage_policy::set(__arg); ! } ! // Conversion from another _Pointer_adapter if _Up if static cast is // valid. template _Pointer_adapter(const _Pointer_adapter<_Up>& __arg) ! { ! __glibcxx_function_requires(_ConvertibleConcept::element_type*>); ! _Storage_policy::set(__arg.get()); ! } ! // Destructor ~_Pointer_adapter() { } --- 258,299 ---- * _Tp* const == const _Pointer_adapter<_Std_pointer_impl<_Tp> >; * const _Tp* const == const _Pointer_adapter<_Std_pointer_impl >; */ ! template class _Pointer_adapter : public _Storage_policy { public: typedef typename _Storage_policy::element_type element_type; ! // These are needed for iterator_traits typedef std::random_access_iterator_tag iterator_category; typedef typename _Unqualified_type::type value_type; ! typedef std::ptrdiff_t difference_type; typedef _Pointer_adapter pointer; typedef typename _Reference_type::reference reference; ! // Reminder: 'const' methods mean that the method is valid when the // pointer is immutable, and has nothing to do with whether the // 'pointee' is const. // Default Constructor (Convert from element_type*) ! _Pointer_adapter(element_type* __arg = 0) { _Storage_policy::set(__arg); } ! // Copy constructor from _Pointer_adapter of same type. _Pointer_adapter(const _Pointer_adapter& __arg) { _Storage_policy::set(__arg.get()); } ! // Convert from _Up* if conversion to element_type* is valid. template ! _Pointer_adapter(_Up* __arg) ! { _Storage_policy::set(__arg); } ! // Conversion from another _Pointer_adapter if _Up if static cast is // valid. template _Pointer_adapter(const _Pointer_adapter<_Up>& __arg) ! { _Storage_policy::set(__arg.get()); } ! // Destructor ~_Pointer_adapter() { } *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 344,350 **** _Storage_policy::set(__arg.get()); return *this; } ! template _Pointer_adapter& operator=(const _Pointer_adapter<_Up>& __arg) --- 304,310 ---- _Storage_policy::set(__arg.get()); return *this; } ! template _Pointer_adapter& operator=(const _Pointer_adapter<_Up>& __arg) *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 365,381 **** inline reference operator*() const { return *(_Storage_policy::get()); } ! // Operator->, returns element_type* inline element_type* operator->() const { return _Storage_policy::get(); } ! // Operator[], returns a element_type& to the item at that loc. ! inline reference ! operator[](int __index) const { return _Storage_policy::get()[__index]; } ! // To allow implicit conversion to "bool", for "if (ptr)..." private: typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const; --- 325,341 ---- inline reference operator*() const { return *(_Storage_policy::get()); } ! // Operator->, returns element_type* inline element_type* operator->() const { return _Storage_policy::get(); } ! // Operator[], returns a element_type& to the item at that loc. ! inline reference ! operator[](std::ptrdiff_t __index) const { return _Storage_policy::get()[__index]; } ! // To allow implicit conversion to "bool", for "if (ptr)..." private: typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const; *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 388,396 **** } // ! operator (for: if (!ptr)...) ! inline bool operator!() const ! { return (_Storage_policy::get()==NULL); } // Pointer differences inline friend std::ptrdiff_t --- 348,356 ---- } // ! operator (for: if (!ptr)...) ! inline bool operator!() const ! { return (_Storage_policy::get() == 0); } // Pointer differences inline friend std::ptrdiff_t *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 401,412 **** operator-(element_type* __lhs, const _Pointer_adapter& __rhs) { return (__lhs - __rhs.get()); } ! template inline friend std::ptrdiff_t operator-(const _Pointer_adapter& __lhs, _Up* __rhs) { return (__lhs.get() - __rhs); } ! template inline friend std::ptrdiff_t operator-(_Up* __lhs, const _Pointer_adapter& __rhs) { return (__lhs - __rhs.get()); } --- 361,372 ---- operator-(element_type* __lhs, const _Pointer_adapter& __rhs) { return (__lhs - __rhs.get()); } ! template inline friend std::ptrdiff_t operator-(const _Pointer_adapter& __lhs, _Up* __rhs) { return (__lhs.get() - __rhs); } ! template inline friend std::ptrdiff_t operator-(_Up* __lhs, const _Pointer_adapter& __rhs) { return (__lhs - __rhs.get()); } *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 483,489 **** } inline _Pointer_adapter ! operator--(int __unused) { _Pointer_adapter tmp(*this); _Storage_policy::set(_Storage_policy::get() - 1); --- 443,449 ---- } inline _Pointer_adapter ! operator--(int) { _Pointer_adapter tmp(*this); _Storage_policy::set(_Storage_policy::get() - 1); *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 520,526 **** _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>,); _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=,); - // These are here for expressions like "ptr == 0", "ptr != 0" template inline bool --- 480,485 ---- *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 551,592 **** operator==(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return __lhs._Tp::operator==(__rhs); } ! template inline bool operator<=(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); } ! template inline bool operator!=(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return !(__lhs._Tp::operator==(__rhs)); } ! template inline bool operator>(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); } ! template inline bool operator>=(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return !(__lhs._Tp::operator<(__rhs)); } ! ! ! template ! std::basic_ostream<_CharT, _Traits>& ! operator<<(std::basic_ostream<_CharT, _Traits> &os, const _Pointer_adapter<_StoreT>& __p) ! { ! os << __p.get(); ! return os; ! } - _GLIBCXX_END_NAMESPACE ! #endif /* _GCC_EXT_POINTER_ADAPTER */ --- 510,546 ---- operator==(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return __lhs._Tp::operator==(__rhs); } ! template inline bool operator<=(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); } ! template inline bool operator!=(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return !(__lhs._Tp::operator==(__rhs)); } ! template inline bool operator>(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); } ! template inline bool operator>=(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return !(__lhs._Tp::operator<(__rhs)); } ! ! template ! inline std::basic_ostream<_CharT, _Traits>& ! operator<<(std::basic_ostream<_CharT, _Traits>& __os, const _Pointer_adapter<_StoreT>& __p) ! { return (__os << __p.get()); } _GLIBCXX_END_NAMESPACE ! #endif // _POINTER_H Index: include/ext/extptr_allocator.h =================================================================== *** include/ext/extptr_allocator.h (revision 141739) --- include/ext/extptr_allocator.h (working copy) *************** *** 43,93 **** #include #include - using __gnu_cxx::_Pointer_adapter; - using __gnu_cxx::_Relative_pointer_impl; - _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) - // forward declaration - template - class _ExtPtr_allocator; - - // _ExtPtr_allocator specialization. - template<> - class _ExtPtr_allocator - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef void value_type; - - // Note the non-standard pointer types - typedef _Pointer_adapter<_Relative_pointer_impl > pointer; - typedef _Pointer_adapter<_Relative_pointer_impl > - const_pointer; - - template - struct rebind - { typedef _ExtPtr_allocator<_Up> other; }; - }; - /** * @brief An example allocator which uses a non-standard pointer type. * * This allocator specifies that containers use a 'relative pointer' as it's ! * pointer type. (See bits/pointer.h) Memory allocation in this example * is still performed using std::allocator. */ template class _ExtPtr_allocator { public: ! typedef size_t size_type; ! typedef ptrdiff_t difference_type; // Note the non-standard pointer types. typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer; ! typedef _Pointer_adapter<_Relative_pointer_impl > const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; --- 43,68 ---- #include #include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) /** * @brief An example allocator which uses a non-standard pointer type. * * This allocator specifies that containers use a 'relative pointer' as it's ! * pointer type. (See ext/pointer.h) Memory allocation in this example * is still performed using std::allocator. */ template class _ExtPtr_allocator { public: ! typedef std::size_t size_type; ! typedef std::ptrdiff_t difference_type; // Note the non-standard pointer types. typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer; ! typedef _Pointer_adapter<_Relative_pointer_impl > ! const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 103,109 **** _ExtPtr_allocator(const _ExtPtr_allocator &__rarg) throw() : _M_real_alloc(__rarg._M_real_alloc) { } ! template _ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg) throw() : _M_real_alloc(__rarg._M_getUnderlyingImp()) { } --- 78,84 ---- _ExtPtr_allocator(const _ExtPtr_allocator &__rarg) throw() : _M_real_alloc(__rarg._M_real_alloc) { } ! template _ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg) throw() : _M_real_alloc(__rarg._M_getUnderlyingImp()) { } *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 158,164 **** template inline friend void ! swap(_ExtPtr_allocator<_Up>& __larg, _ExtPtr_allocator<_Up>& __rarg); // A method specific to this implementation. const std::allocator<_Tp>& --- 133,139 ---- template inline friend void ! swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&); // A method specific to this implementation. const std::allocator<_Tp>& *************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) *** 166,182 **** { return _M_real_alloc; } private: - // simlated state data. std::allocator<_Tp> _M_real_alloc; }; template inline void swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg) { ! std::allocator<_Tp> temp( __rarg._M_real_alloc ); __rarg._M_real_alloc = __larg._M_real_alloc; ! __larg._M_real_alloc = temp; } _GLIBCXX_END_NAMESPACE --- 141,178 ---- { return _M_real_alloc; } private: std::allocator<_Tp> _M_real_alloc; }; + // _ExtPtr_allocator specialization. + template<> + class _ExtPtr_allocator + { + public: + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef void value_type; + + // Note the non-standard pointer types + typedef _Pointer_adapter<_Relative_pointer_impl > pointer; + typedef _Pointer_adapter<_Relative_pointer_impl > + const_pointer; + + template + struct rebind + { typedef _ExtPtr_allocator<_Up> other; }; + + private: + std::allocator _M_real_alloc; + }; + template inline void swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg) { ! std::allocator<_Tp> __tmp( __rarg._M_real_alloc ); __rarg._M_real_alloc = __larg._M_real_alloc; ! __larg._M_real_alloc = __tmp; } _GLIBCXX_END_NAMESPACE