Index: libstdc++-v3/include/Makefile.in =================================================================== --- libstdc++-v3/include/Makefile.in (revision 141290) +++ libstdc++-v3/include/Makefile.in (working copy) @@ -748,10 +748,12 @@ ${ext_srcdir}/atomicity.h \ ${ext_srcdir}/array_allocator.h \ ${ext_srcdir}/bitmap_allocator.h \ + ${ext_srcdir}/cast.h \ ${ext_srcdir}/codecvt_specializations.h \ ${ext_srcdir}/concurrence.h \ ${ext_srcdir}/debug_allocator.h \ ${ext_srcdir}/enc_filebuf.h \ + ${ext_srcdir}/extptr_allocator.h \ ${ext_srcdir}/stdio_filebuf.h \ ${ext_srcdir}/stdio_sync_filebuf.h \ ${ext_srcdir}/functional \ @@ -763,6 +765,7 @@ ${ext_srcdir}/numeric \ ${ext_srcdir}/numeric_traits.h \ ${ext_srcdir}/pod_char_traits.h \ + ${ext_srcdir}/pointer.h \ ${ext_srcdir}/pool_allocator.h \ ${ext_srcdir}/rb_tree \ ${ext_srcdir}/rope \ Index: libstdc++-v3/include/ext/cast.h =================================================================== --- libstdc++-v3/include/ext/cast.h (revision 0) +++ libstdc++-v3/include/ext/cast.h (revision 0) @@ -0,0 +1,69 @@ +// -*- C++ -*- + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GCC_EXT_CAST_ +#define _GCC_EXT_CAST_ + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx); + + /** + * These functions are here to allow containers to support non standard + * pointer types. For normal pointers, these resolve to the use of the + * standard cast operation. Specific pointer classes can overload these + * functions to provide any needed customization on how casts are done, + * and to support explicit casting to normal pointer types. + */ + + template + _ToType + __static_pointer_cast(_FromType * const arg) + { return static_cast<_ToType>(arg); } + + + template + _ToType + __dynamic_pointer_cast(_FromType * const arg) + { return dynamic_cast<_ToType>(arg); } + + + template + _ToType + __const_pointer_cast(_FromType * const arg) + { return const_cast<_ToType>(arg); } + + + template + _ToType + __reinterpret_pointer_cast(_FromType * const arg) + { return reinterpret_cast<_ToType>(arg); } + + +_GLIBCXX_END_NAMESPACE + +#endif Index: libstdc++-v3/include/ext/pointer.h =================================================================== --- libstdc++-v3/include/ext/pointer.h (revision 0) +++ libstdc++-v3/include/ext/pointer.h (revision 0) @@ -0,0 +1,603 @@ +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** + * @file ext/pointer.h + * @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 _GCC_EXT_POINTER_ADAPTER +#define _GCC_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) + + /** + * @brief A storage policy for use with _Pointer_adapter<> which yields a + * standard pointer. + * + * A _Storage_policy is required to provide 4 things: + * 1) A get() API for returning the stored pointer value. + * 2) An set() API for storing a pointer value. + * 3) An element_type typedef to define the type this points to. + * 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; } + + // A method to set the pointer value, from a standard T* value; + inline void + set(_Type* __arg) + { _M_value = __arg; } + + // Comparison of pointers + inline bool + operator<(const _Std_pointer_impl &rarg) const + { return (_M_value < rarg._M_value); } + + inline bool + operator==(const _Std_pointer_impl &rarg) const + { return (_M_value == rarg._M_value); } + + private: + _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 + * its own address. + * + * This is intended for pointers + * within shared memory regions which might be mapped at different + * addresses by different processes. For null pointers, a value of 1 is + * used. (0 is legitimate sometimes for nodes in circularly linked lists) + * This value was chosen as the least likely to generate an incorrect null, + * 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) + - reinterpret_cast(this); + } + + // Comparison of pointers + inline bool + operator<(const _Relative_pointer_impl &rarg) const + { return (this->get() < rarg.get()); } + + inline bool + operator==(const _Relative_pointer_impl &rarg) const + { 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) + - reinterpret_cast(this); + } + + // Comparison of pointers + inline bool + operator<(const _Relative_pointer_impl &rarg) const + { return (this->get() < rarg.get()); } + + inline bool + operator==(const _Relative_pointer_impl &rarg) const + { 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 + * for cases of void*, const void*, and so on. + */ + struct _Invalid_type { }; + + 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<> + * is normally specialized for const T*, so that value_type is still T. + */ + template + struct _Unqualified_type + { + typedef T type; + }; + + template + struct _Unqualified_type + { + typedef T type; + }; + + template + struct _Unqualified_type + { + typedef volatile T type; + }; + + template + struct _Unqualified_type + { + typedef volatile T 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 + * raising compile-time ambiguities. Because creating a working pointer can + * be challenging, this pointer template was designed to wrapper an + * easier storage policy type, so that it becomes reusable for creating + * other pointer types. + * + * A key point of this class is also that it allows container writers to + * 'assume' Alocator::pointer is a typedef for a normal pointer. This class + * supports most of the conventions of a true pointer, and can, for instance + * handle implicit conversion to const and base class pointer types. The + * only impositions on container writers to support extended pointers are: + * 1) use the Allocator::pointer typedef appropriately for pointer types. + * 2) if you need pointer casting, use the __pointer_cast<> functions + * from ext/cast.h. This allows pointer cast operations to be overloaded + * is necessary by custom pointers. + * + * Note: The const qualifier works with this pointer adapter as follows: + * + * T* == _Pointer_adapter<_Std_pointer_impl >; + * const T* == _Pointer_adapter<_Std_pointer_impl >; + * T* const == const _Pointer_adapter<_Std_pointer_impl >; + * const T* const == const _Pointer_adapter<_Std_pointer_impl >; + */ + + template + class _Pointer_adapter : public _Storage_policy + { + public: + typedef typename _Storage_policy::element_type element_type; // shorthand + + // 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 _U* if conversion to element_type* is valid. + template + _Pointer_adapter(_U *__arg) + { + __glibcxx_function_requires(_ConvertibleConcept); + _Storage_policy::set(__arg); + } + + // Conversion from another _Pointer_adapter if _U if static cast is valid. + template + _Pointer_adapter(const _Pointer_adapter<_U>& __arg) + { + __glibcxx_function_requires(_ConvertibleConcept::element_type*>); + _Storage_policy::set(__arg.get()); + } + + // Destructor + ~_Pointer_adapter() { } + + // Assignment operator + _Pointer_adapter& + operator=(const _Pointer_adapter& __arg) + { + _Storage_policy::set(__arg.get()); + return *this; + } + + template + _Pointer_adapter& + operator=(const _Pointer_adapter<_U>& __arg) + { + _Storage_policy::set(__arg.get()); + return *this; + } + + template + _Pointer_adapter& + operator=(_U* __arg) + { + _Storage_policy::set(__arg); + return *this; + } + + // Operator*, returns element_type& + 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; + + public: + operator __unspecified_bool_type() const // never throws + { return _Storage_policy::get() == 0 ? 0 : &_Pointer_adapter::operator->; } + + // ! operator (for: if (!ptr)...) + inline bool + operator!() const + { return (_Storage_policy::get()==NULL); } + + // Pointer differences + inline friend std::ptrdiff_t + operator-(const _Pointer_adapter& __lhs, element_type* __rhs) + { return (__lhs.get() - __rhs); } + + inline friend std::ptrdiff_t + operator-(element_type* __lhs, const _Pointer_adapter& __rhs) + { return (__lhs - __rhs.get()); } + + template + inline friend std::ptrdiff_t + operator-(const _Pointer_adapter& __lhs, _U* __rhs) + { return (__lhs.get() - __rhs); } + + template + inline friend std::ptrdiff_t + operator-(_U* __lhs, const _Pointer_adapter& __rhs) + { return (__lhs - __rhs.get()); } + + template + inline std::ptrdiff_t + operator-(const _Pointer_adapter<_U>& __rhs) const + { return (_Storage_policy::get() - __rhs.get()); } + + // Pointer math + // Note: There is a reason for all this overloading based on different + // integer types. In some libstdc++-v3 test cases, a templated + // operator+ is declared which can match any types. This templated operator + // tends to "steal" the recognition of _Pointer_adapter's own operator+ + // unless the integer type matches perfectly. + + #define _GCC_CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE) \ + inline friend _Pointer_adapter \ + operator+ (const _Pointer_adapter& __lhs, INT_TYPE __offset) \ + { return _Pointer_adapter(__lhs.get() + __offset); } \ + \ + inline friend _Pointer_adapter \ + operator+ (INT_TYPE __offset, const _Pointer_adapter& __rhs) \ + { return _Pointer_adapter(__rhs.get() + __offset); } \ + \ + inline friend _Pointer_adapter \ + operator- (const _Pointer_adapter& __lhs, INT_TYPE __offset) \ + { return _Pointer_adapter(__lhs.get() - __offset); } \ + \ + inline _Pointer_adapter& \ + operator+= (INT_TYPE __offset) \ + { \ + _Storage_policy::set(_Storage_policy::get() + __offset); \ + return *this; \ + } \ + \ + inline _Pointer_adapter& \ + operator-= (INT_TYPE __offset) \ + { \ + _Storage_policy::set(_Storage_policy::get() - __offset); \ + return *this; \ + } + // END of _GCC_CXX_POINTER_ARITH_OPERATOR_SET macro + + // Expand into the various pointer arithmatic operators needed. + _GCC_CXX_POINTER_ARITH_OPERATOR_SET(int); + _GCC_CXX_POINTER_ARITH_OPERATOR_SET(unsigned int); + _GCC_CXX_POINTER_ARITH_OPERATOR_SET(long); + _GCC_CXX_POINTER_ARITH_OPERATOR_SET(unsigned long); + + // Mathematical Manipulators + inline _Pointer_adapter& + operator++ () + { + _Storage_policy::set(_Storage_policy::get() + 1); + return *this; + } + + inline _Pointer_adapter + operator++ (int unused) + { + _Pointer_adapter tmp(*this); + _Storage_policy::set(_Storage_policy::get() + 1); + return tmp; + } + + inline _Pointer_adapter& + operator-- () + { + _Storage_policy::set(_Storage_policy::get() - 1); + return *this; + } + + inline _Pointer_adapter + operator-- (int unused) + { + _Pointer_adapter tmp(*this); + _Storage_policy::set(_Storage_policy::get() - 1); + return tmp; + } + + }; // class _Pointer_adapter + + +#define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR,BLANK) \ + template \ + inline bool \ + operator OPERATOR##BLANK (const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \ + { return __lhs.get() OPERATOR##BLANK __rhs; } \ +\ + template \ + inline bool \ + operator OPERATOR##BLANK (_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \ + { return __lhs OPERATOR##BLANK __rhs.get(); } \ +\ + template \ + inline bool \ + operator OPERATOR##BLANK (const _Pointer_adapter<_Tp1>& __lhs, \ + const _Pointer_adapter<_Tp2>& __rhs) \ + { return __lhs.get() OPERATOR##BLANK __rhs.get(); } \ +\ +// End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro + + // Expand into the various comparison operators needed. + _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==,); + _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=,); + _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<,); + _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=,); + _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>,); + _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=,); + + /** + * Comparison operators for _Pointer_adapter defer to the base class'es + * comparison operators, when possible. + */ + 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 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<_E, _T>& + operator<<(std::basic_ostream<_E, _T> &os, _Pointer_adapter<_Y> const& p) + { + os << p.get(); + return os; + } + + + /** + * This type supports the semantics of the pointer cast operators (below.) + */ + template + struct caster { + typedef typename _ToType::element_type* type; + }; + template + struct caster<_ToType*> { + typedef _ToType* type; + }; + + /** + * _Pointer_adapter overloads the pointer_cast() functions of cast.h to + * provide casting between _Pointer_adapter types. These functions support + * the casting of a _Pointer_adapter to another type of _Pointer_adapter + * or to a type of raw pointer, as long as the equivalent raw pointer cast + * would be valid. + */ + template + inline _ToType + __static_pointer_cast(const _Pointer_adapter<_FromType>& arg) + { return _ToType(static_cast::type>(arg.get())); } + + template + inline _ToType + __dynamic_pointer_cast(const _Pointer_adapter<_FromType>& arg) + { return _ToType(dynamic_cast::type>(arg.get())); } + + template + inline _ToType + __const_pointer_cast(const _Pointer_adapter<_FromType>& arg) + { return _ToType(const_cast::type>(arg.get())); } + + template + inline _ToType + __reinterpret_pointer_cast(const _Pointer_adapter<_FromType>& arg) + { return _ToType(reinterpret_cast::type>(arg.get())); } + + +_GLIBCXX_END_NAMESPACE + +#endif /* _GCC_EXT_POINTER_ADAPTER */ Index: libstdc++-v3/include/ext/extptr_allocator.h =================================================================== --- libstdc++-v3/include/ext/extptr_allocator.h (revision 0) +++ libstdc++-v3/include/ext/extptr_allocator.h (revision 0) @@ -0,0 +1,184 @@ +// -*- C++ -*- + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** + * @file ext/extptr_allocator.h + * @author Bob Walters + * + * An example allocator which uses an alternative pointer type from + * bits/pointer.h. Supports test cases which confirm container support + * for alternative pointers. + */ + +#ifndef _EXTPTR_ALLOCATOR_H_ +#define _EXTPTR_ALLOCATOR_H_ + +#include +#include +#include + +using __gnu_cxx::_Pointer_adapter; +using __gnu_cxx::_Relative_pointer_impl; +using __gnu_cxx::__static_pointer_cast; +using __gnu_cxx::__const_pointer_cast; + + +_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<_Tp2> 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; + typedef _Tp value_type; + + template + struct rebind + { typedef _ExtPtr_allocator<_Tp2> other; }; + + _ExtPtr_allocator() throw() + : _m_real_alloc() { } + + _ExtPtr_allocator(const _ExtPtr_allocator &__rarg) throw() + : _m_real_alloc(__rarg._m_real_alloc) { } + + template + _ExtPtr_allocator(const _ExtPtr_allocator<_Tp2>& __rarg) throw() + : _m_real_alloc(__rarg._M_getUnderlyingImp()) { } + + ~_ExtPtr_allocator() throw() + { } + + pointer address(reference __x) const + { return &__x; } + + const_pointer address(const_reference __x) const + { return &__x; } + + pointer allocate(size_type __n, void* __hint = 0) + { return _m_real_alloc.allocate(__n,__hint); } + + void deallocate(pointer __p, size_type __n) + { _m_real_alloc.deallocate(__static_pointer_cast<_Tp*>(__p), __n); } + + size_type max_size() const throw() + { return std::numeric_limits::max() / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) + { ::new(__static_pointer_cast(__p)) _Tp(__val); } + + void destroy(pointer __p) + { __p->~_Tp(); } + + template + inline bool + operator==(const _ExtPtr_allocator<_Tp2>& __rarg) + { return _m_real_alloc == __rarg._M_getUnderlyingImp(); } + + inline bool + operator==(const _ExtPtr_allocator& __rarg) + { return _m_real_alloc == __rarg._m_real_alloc; } + + template + inline bool + operator!=(const _ExtPtr_allocator<_Tp2>& __rarg) + { return _m_real_alloc != __rarg._M_getUnderlyingImp(); } + + inline bool + operator!=(const _ExtPtr_allocator& __rarg) + { return _m_real_alloc != __rarg._m_real_alloc; } + + template + inline friend void + swap(_ExtPtr_allocator<_Tp2>& __larg, _ExtPtr_allocator<_Tp2>& __rarg); + + // A method specific to this implementation. + const std::allocator<_Tp>& + _M_getUnderlyingImp() const + { 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 + +#endif /*_NONSTD_ALLOCATOR_H_*/ Index: libstdc++-v3/include/Makefile.am =================================================================== --- libstdc++-v3/include/Makefile.am (revision 141290) +++ libstdc++-v3/include/Makefile.am (working copy) @@ -484,10 +484,12 @@ ${ext_srcdir}/atomicity.h \ ${ext_srcdir}/array_allocator.h \ ${ext_srcdir}/bitmap_allocator.h \ + ${ext_srcdir}/cast.h \ ${ext_srcdir}/codecvt_specializations.h \ ${ext_srcdir}/concurrence.h \ ${ext_srcdir}/debug_allocator.h \ ${ext_srcdir}/enc_filebuf.h \ + ${ext_srcdir}/extptr_allocator.h \ ${ext_srcdir}/stdio_filebuf.h \ ${ext_srcdir}/stdio_sync_filebuf.h \ ${ext_srcdir}/functional \ @@ -499,6 +501,7 @@ ${ext_srcdir}/numeric \ ${ext_srcdir}/numeric_traits.h \ ${ext_srcdir}/pod_char_traits.h \ + ${ext_srcdir}/pointer.h \ ${ext_srcdir}/pool_allocator.h \ ${ext_srcdir}/rb_tree \ ${ext_srcdir}/rope \ Index: libstdc++-v3/testsuite/ext/nonstd_pointer/1.cc =================================================================== --- libstdc++-v3/testsuite/ext/nonstd_pointer/1.cc (revision 0) +++ libstdc++-v3/testsuite/ext/nonstd_pointer/1.cc (revision 0) @@ -0,0 +1,201 @@ +// Test for Container using non-standard pointer types. + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include +#include + +using __gnu_cxx::_Pointer_adapter; +using __gnu_cxx::_Relative_pointer_impl; +using __gnu_cxx::__static_pointer_cast; +using __gnu_cxx::__const_pointer_cast; + + +void +test01() { + + typedef _Pointer_adapter<_Relative_pointer_impl > pointer; + typedef _Pointer_adapter<_Relative_pointer_impl > const_pointer; + + int A[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + // basic pointer assignment/access tests. + pointer x = &A[0]; + VERIFY( *x == 0 ); + VERIFY( std::equal( x, x+10, A ) ); + pointer y ( &A[9] ); + VERIFY( *y == 9 ); + + // assignability + pointer z(x); + VERIFY(z==x); + VERIFY(*z == 0); + + z = y; + VERIFY(z==y); + VERIFY(z!=x); + VERIFY(z>x); + VERIFY(*z == 9); + + // pointer arithmetic + VERIFY( *++x == 1 ); + VERIFY( *--x == 0 ); + VERIFY( *(x++) == 0 ); + VERIFY( *(x--) == 1 ); + VERIFY( *(x+2) == 2 ); + VERIFY( *(2+x) == 2 ); + VERIFY( *(y-2) == 7 ); + VERIFY( y - x == 9 ); + VERIFY( &*y - x == 9 ); + VERIFY( y - &*x == 9 ); + + size_t s( y - x ); + VERIFY( s == 9 ); +} + + +struct A { + mutable int i; +}; +struct B : public A{ + mutable int j; +}; +typedef _Pointer_adapter<_Relative_pointer_impl > B_pointer; +typedef _Pointer_adapter<_Relative_pointer_impl > const_B_pointer; +typedef _Pointer_adapter<_Relative_pointer_impl > A_pointer; +typedef _Pointer_adapter<_Relative_pointer_impl > const_A_pointer; + + +// Test implicit conversion from B* to A* +void inc( _Pointer_adapter<_Relative_pointer_impl > a ) { + a->i++; +} +// Test implicit conversion from B* to const B* +void inc2( _Pointer_adapter<_Relative_pointer_impl > b ) { + b->i++; + b->j++; +} +// Test implicit conversion from B* to const A* +void inc3( _Pointer_adapter<_Relative_pointer_impl > a ) { + a->i++; +} + +void test02( ) { + B b; + b.i = 2; + b.j = 2; + + B_pointer Bptr( &b ); + VERIFY( Bptr->i == 2 ); + Bptr->i++; + VERIFY( b.i == 3 ); + + const_B_pointer cBptr( &b ); + b.i++; + VERIFY( cBptr->i == 4 ); + + A_pointer Aptr( &b ); + b.i++; + VERIFY(Aptr->i == 5); + Aptr->i++; + VERIFY( b.i == 6 ); + + const_A_pointer cAptr( &b ); + b.i++; + VERIFY( cAptr->i == 7 ); + + const_B_pointer cBptr2( Bptr ); + b.i++; + VERIFY( cBptr2->i == 8 ); + + A_pointer Aptr2( Bptr ); + b.i++; + VERIFY(Aptr2->i == 9); + Aptr2->i++; + VERIFY( b.i == 10 ); + + const_A_pointer cAptr2( Bptr ); + b.i++; + VERIFY( cAptr2->i == 11 ); + + // Implicit casting during invocation + inc( Bptr ); + VERIFY( Bptr->i == 12 ); + inc2( Bptr ); + VERIFY( Bptr->i == 13 ); + VERIFY( Bptr->j == 3 ); + inc3( Bptr ); + VERIFY( Bptr->i == 14 ); +} + +void test03( ) { + + B b; + B *Bptr = &b; + A *aPtr = static_cast( Bptr ); + const A *caPtr = static_cast( Bptr /*implicit cast to const B * ? */ ); + const B *cbPtr = static_cast( Bptr ); + + B_pointer Bptr2 = &b; + + const A* caPtr2 = __static_pointer_cast( Bptr2 ); + A * aPtr2 = __static_pointer_cast( Bptr2 ); + const B* cbPtr2 = __const_pointer_cast( Bptr2 ); + + const_A_pointer caPtr3 = __static_pointer_cast( Bptr2 ); + A_pointer aPtr3 = __static_pointer_cast( Bptr2 ); + const_B_pointer cbPtr3 = __const_pointer_cast( Bptr2 ); +} + +// Confirm the usability of the __static_pointer_cast<> template function +// to transform between _Pointer_adapter and standard versions. +void test04() { + B b; + B_pointer bPtr = &b; + + A_pointer aPtr = __static_pointer_cast( bPtr ); + VERIFY( aPtr == bPtr ); + B_pointer bPtr2 = __static_pointer_cast( aPtr ); + VERIFY( bPtr2 == aPtr ); + + A* aPtr3 = __static_pointer_cast( bPtr ); + VERIFY( aPtr3 == bPtr ); + B* bPtr3 = __static_pointer_cast( aPtr ); + VERIFY( bPtr3 == aPtr ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + return 0; +} Index: libstdc++-v3/testsuite/ext/nonstd_pointer/1_neg.cc =================================================================== --- libstdc++-v3/testsuite/ext/nonstd_pointer/1_neg.cc (revision 0) +++ libstdc++-v3/testsuite/ext/nonstd_pointer/1_neg.cc (revision 0) @@ -0,0 +1,110 @@ +// Bob Walters 10-2008 + +// Test for Container using non-standard pointer types. + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// { dg-do compile } + +#include +#include +#include + +using __gnu_cxx::_Pointer_adapter; +using __gnu_cxx::_Relative_pointer_impl; +using __gnu_cxx::__static_pointer_cast; +using __gnu_cxx::__const_pointer_cast; + + +struct A { + int i; +}; +struct B : public A{ + int j; +}; +typedef _Pointer_adapter<_Relative_pointer_impl > B_pointer; +typedef _Pointer_adapter<_Relative_pointer_impl > const_B_pointer; +typedef _Pointer_adapter<_Relative_pointer_impl > A_pointer; +typedef _Pointer_adapter<_Relative_pointer_impl > const_A_pointer; + + +void test01(void) { + A a; + B b; + + A_pointer aptr( &a ); + + // Can't implicitly cast from A* to B* + B_pointer bptr1(aptr); // { dg-error "instantiated from here" 31 } + B_pointer bptr2(&a); // { dg-error "instantiated from here" 32 } + + // but explicit cast/conversion is OK. + B_pointer bptr3(__static_pointer_cast(aptr)); // ok + B_pointer bptr4(__static_pointer_cast(&a)); // ok + + // Can't implicitly cast from A* to B* + bptr1 = aptr; // { dg-error "instantiated from here" 39 } + bptr1 = &a; // { dg-error "instantiated from here" 40 } + + // but explicit cast/conversion is OK. + bptr1 = __static_pointer_cast(aptr); // ok + bptr1 = __static_pointer_cast(&a); // ok + + // Similarly, can't shed constness via implicit cast + const_A_pointer captr(&a); + A_pointer aptr2(captr); // { dg-error "instantiated from here" 48 } + + // but explicit cast/conversion is OK. + A_pointer aptr3(__const_pointer_cast(captr)); // ok + + // Similarly, can't shed constness via implicit cast + aptr2 = captr; // { dg-error "instantiated from here" 54 } + + // but explicit cast/conversion is OK. + aptr3 = __const_pointer_cast(captr); // ok + + // Combine explicit const cast with implicit downcast. + const_B_pointer cbptr( &b ); + A_pointer aptr4( cbptr ); // { dg-error "instantiated from here" 61 } + aptr4 = cbptr; // { dg-error "instantiated from here" 62 } + + A_pointer aptr5(__const_pointer_cast(cbptr)); // ok + aptr5 = __const_pointer_cast(cbptr); // ok +} + +// { dg-error "invalid conversion " "" { target *-*-* } 333 } +// { dg-error "initializing argument 1 of" "" { target *-*-* } 333 } +// { dg-error "invalid conversion " "" { target *-*-* } 324 } +// { dg-error "initializing argument 1 of" "" { target *-*-* } 324 } +// { dg-error "invalid conversion " "" { target *-*-* } 351 } +// { dg-error "initializing argument 1 of" "" { target *-*-* } 351 } +// { dg-error "invalid conversion " "" { target *-*-* } 359 } +// { dg-error "initializing argument 1 of" "" { target *-*-* } 359 } +// { dg-excess-errors "In constructor" } + Index: libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/modifiers/erase.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/modifiers/erase.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/modifiers/erase.cc (revision 0) @@ -0,0 +1,153 @@ +// Bob Walters 10-2008 + +// Test for Container using non-standard pointer types. + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include +#include + +const int A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; +const int A1[] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; +const int A2[] = {0, 2, 3, 4, 10, 11, 12, 13, 14, 15}; +const int A3[] = {0, 2, 3, 4, 10, 11}; +const int A4[] = {4, 10, 11}; +const int A5[] = {4, 10}; +const unsigned int N = sizeof(A) / sizeof(int); +const unsigned int N1 = sizeof(A1) / sizeof(int); +const unsigned int N2 = sizeof(A2) / sizeof(int); +const unsigned int N3 = sizeof(A3) / sizeof(int); +const unsigned int N4 = sizeof(A4) / sizeof(int); +const unsigned int N5 = sizeof(A5) / sizeof(int); + +void +test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::vector > vec_type; + typedef vec_type::iterator iterator_type; + + vec_type v(A, A + N); + std::cout << v.size() << std::endl; + std::cout << v.capacity() << std::endl; + std::cout << v.max_size() << std::endl; + + iterator_type it1 = v.erase(v.begin() + 1); + VERIFY( it1 == v.begin() + 1 ); + std::cout << N << std::endl << v.size() << std::endl; + VERIFY( v.size() == N1 ); + VERIFY( std::equal(v.begin(), v.end(), A1) ); + + iterator_type it2 = v.erase(v.begin() + 4, v.begin() + 9); + VERIFY( it2 == v.begin() + 4 ); + VERIFY( v.size() == N2 ); + VERIFY( std::equal(v.begin(), v.end(), A2) ); + + iterator_type it3 = v.erase(v.begin() + 6, v.end()); + VERIFY( it3 == v.begin() + 6 ); + VERIFY( v.size() == N3 ); + VERIFY( std::equal(v.begin(), v.end(), A3) ); + + iterator_type it4 = v.erase(v.begin(), v.begin() + 3); + VERIFY( it4 == v.begin() ); + VERIFY( v.size() == N4 ); + VERIFY( std::equal(v.begin(), v.end(), A4) ); + + iterator_type it5 = v.erase(v.begin() + 2); + VERIFY( it5 == v.begin() + 2 ); + VERIFY( v.size() == N5 ); + VERIFY( std::equal(v.begin(), v.end(), A5) ); + + iterator_type it6 = v.erase(v.begin(), v.end()); + VERIFY( it6 == v.begin() ); + VERIFY( v.empty() ); +} + +void +test02() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_cxx::_ExtPtr_allocator int_alloc_type; + typedef __gnu_cxx::_ExtPtr_allocator< std::vector > vec_alloc_type; + typedef std::vector,vec_alloc_type> vec_type; + typedef vec_type::iterator iterator_type; + + vec_type v, v1, v2, v3, v4, v5; + for (unsigned int i = 0; i < N; ++i) + v.push_back(std::vector(1, A[i])); + for (unsigned int i = 0; i < N1; ++i) + v1.push_back(std::vector(1, A1[i])); + for (unsigned int i = 0; i < N2; ++i) + v2.push_back(std::vector(1, A2[i])); + for (unsigned int i = 0; i < N3; ++i) + v3.push_back(std::vector(1, A3[i])); + for (unsigned int i = 0; i < N4; ++i) + v4.push_back(std::vector(1, A4[i])); + for (unsigned int i = 0; i < N5; ++i) + v5.push_back(std::vector(1, A5[i])); + + iterator_type it1 = v.erase(v.begin() + 1); + VERIFY( it1 == v.begin() + 1 ); + VERIFY( v.size() == N1 ); + VERIFY( std::equal(v.begin(), v.end(), v1.begin()) ); + + iterator_type it2 = v.erase(v.begin() + 4, v.begin() + 9); + VERIFY( it2 == v.begin() + 4 ); + VERIFY( v.size() == N2 ); + VERIFY( std::equal(v.begin(), v.end(), v2.begin()) ); + + iterator_type it3 = v.erase(v.begin() + 6, v.end()); + VERIFY( it3 == v.begin() + 6 ); + VERIFY( v.size() == N3 ); + VERIFY( std::equal(v.begin(), v.end(), v3.begin()) ); + + iterator_type it4 = v.erase(v.begin(), v.begin() + 3); + VERIFY( it4 == v.begin() ); + VERIFY( v.size() == N4 ); + VERIFY( std::equal(v.begin(), v.end(), v4.begin()) ); + + iterator_type it5 = v.erase(v.begin() + 2); + VERIFY( it5 == v.begin() + 2 ); + VERIFY( v.size() == N5 ); + VERIFY( std::equal(v.begin(), v.end(), v5.begin()) ); + + iterator_type it6 = v.erase(v.begin(), v.end()); + VERIFY( it6 == v.begin() ); + VERIFY( v.empty() ); +} + +int main() +{ + test01(); + test02(); + return 0; +} Index: libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/modifiers/insert.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/modifiers/insert.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/modifiers/insert.cc (revision 0) @@ -0,0 +1,76 @@ +// Test for Container using non-standard pointer types. + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + __gnu_cxx::_ExtPtr_allocator alloc; + std::vector > iv(alloc); + VERIFY( iv.get_allocator() == alloc ); + VERIFY( iv.size() == 0 ); + + int A[] = { 0, 1, 2, 3, 4 }; + int B[] = { 5, 5, 5, 5, 5 }; + int C[] = { 6, 7 }; + iv.insert(iv.end(), A, A+5 ); + VERIFY( iv.size() == 5 ); + iv.insert(iv.begin(), 5, 5 ); + iv.insert(iv.begin()+5, 7); + iv.insert(iv.begin()+5, 6); + VERIFY( std::equal(iv.begin(), iv.begin()+5, B )); + VERIFY( std::equal(iv.begin()+5, iv.begin()+7, C)); + VERIFY( std::equal(iv.begin()+7, iv.end(), A)); + VERIFY( iv.size() == 12 ); + + try + { + iv.insert(iv.end(), iv.max_size() + 1, 1); + } + catch(std::length_error&) + { + VERIFY( true ); + } + catch(...) + { + VERIFY( false ); + } +} + +int main() +{ + test01(); + return 0; +} Index: libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/modifiers/element.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/modifiers/element.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/modifiers/element.cc (revision 0) @@ -0,0 +1,86 @@ +// Test for Container using non-standard pointer types. + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include +#include + +// General tests element access and manipulation +void test01() +{ + bool test __attribute__((unused)) = true; + + int A[] = { 0, 1, 2, 3, 4 }; + __gnu_cxx::_ExtPtr_allocator alloc; + std::vector > mv( A, A+5, alloc ); + + VERIFY( mv.size() == 5 ); + VERIFY( mv.front() == 0 ); + VERIFY( mv.back() == 4 ); + VERIFY( mv.at(2) == 2 ); + VERIFY( mv[3] == 3); + mv.front() = 5; + mv.back() = 6; + mv.at(2) = 7; + mv[3] = 8; + VERIFY( mv.size() == 5 ); + VERIFY( mv.front() == 5 ); + VERIFY( mv.back() == 6 ); + VERIFY( mv.at(2) == 7 ); + VERIFY( mv[3] == 8 ); + + try + { + mv.at(100) = 8; + } + catch(std::out_of_range&) + { + VERIFY( true ); + } + catch(...) + { + VERIFY( false ); + } + + const std::vector > cmv( mv ); + VERIFY( cmv.get_allocator() == mv.get_allocator() ); + VERIFY( mv.size() == 5 ); + VERIFY( mv.front() == 5 ); + VERIFY( mv.back() == 6 ); + VERIFY( mv.at(2) == 7 ); + VERIFY( mv[3] == 8 ); +} + + +int main() +{ + test01(); + return 0; +} Index: libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/citerators.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/citerators.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/citerators.cc (revision 0) @@ -0,0 +1,55 @@ +// { dg-options "-std=gnu++0x" } + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include +#include + +// Ensures equivalence of iterators based on low-level comparison +// between const / non-const Pointer types. +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::vector > v(7); + VERIFY( v.cbegin() == v.begin() ); + VERIFY( v.cend() == v.end() ); + VERIFY( v.crbegin() == v.rbegin() ); + VERIFY( v.crend() == v.rend() ); + VERIFY( v.cbegin() != v.cend() ); + VERIFY( v.crbegin() != v.crend() ); +} + +int main() +{ + test01(); + return 0; +} Index: libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/types/1.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/types/1.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/types/1.cc (revision 0) @@ -0,0 +1,70 @@ +// Test for Container using non-standard pointer types. + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// This is a copy of vector/types/1.cc with altered allocator. +// The operator+()s in this test initially failed the test - +// they stress the accurate recognition, by the compiler, +// of _Pointer_adapter's own pointer arithmetic functions, +// which have to match perfectly on the int type to get +// chosen by the compiler when it sees: _Pointer_adapter + int, etc. + +#include +#include + +namespace N +{ + struct X { }; + + template + X operator+(T, std::size_t) + { return X(); } + + template + X operator-(T, T) + { return X(); } +} + +int main() +{ + std::vector > v(5); + const std::vector > w(1); + + v[0]; + w[0]; + v.size(); + v.capacity(); + v.resize(1); + v.insert(v.begin(), N::X()); + v.insert(v.begin(), 1, N::X()); + v.insert(v.begin(), w.begin(), w.end()); + v = w; + + return 0; +} Index: libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/explicit_instantiation/1.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/explicit_instantiation/1.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/explicit_instantiation/1.cc (revision 0) @@ -0,0 +1,36 @@ +// Test for Container using non-standard pointer types. + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include + +// { dg-do compile } + +template class std::vector >; Index: libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/explicit_instantiation/3.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/explicit_instantiation/3.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/explicit_instantiation/3.cc (revision 0) @@ -0,0 +1,37 @@ +// Test for Container using non-standard pointer types. + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include + +// { dg-do compile } + +// libstdc++/21770 +template class std::vector >; Index: libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/resize.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/resize.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/resize.cc (revision 0) @@ -0,0 +1,74 @@ + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include +#include +#include +#include + + +void test01() +{ + // non POD types + bool test __attribute__((unused)) = true; + + std::vector > vec01; + typedef std::vector >::size_type size_type; + + VERIFY ( vec01.empty() ); + + const int A[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + // Test resize of the vector based on reserve + size_type sz01 = vec01.capacity(); + vec01.reserve(100); + size_type sz02 = vec01.capacity(); + VERIFY( sz02 >= sz01 ); + + // grow/shrink + vec01.assign( A, A+10 ); + sz01 = vec01.size() + 100; + vec01.resize(sz01); + sz02 = vec01.size(); + VERIFY( sz01 == sz02 ); + VERIFY(std::equal(vec01.begin(), vec01.begin()+10, A)); + + sz01 = vec01.size() - 100; + vec01.resize(sz01); + sz02 = vec01.size(); + VERIFY( sz01 == sz02 ); + VERIFY(std::equal(vec01.begin(), vec01.end(), A)); +} + +int main() +{ + test01(); + return 0; +} Index: libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/data_access.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/data_access.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/vector/nonstd_pointer/data_access.cc (revision 0) @@ -0,0 +1,62 @@ +// Test for Container using non-standard pointer types. + +// 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include +#include + +// libstdc++/23578 +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::vector > vector_type; + + { + const int A[] = { 0, 1, 2, 3, 4 }; + vector_type v(A, A + 5); + VERIFY( v.data() == &v.front() ); + int* pi = &* v.data(); + VERIFY( *pi == 0 ); + } + + { + const int A[] = { 4, 3, 2, 1, 0 }; + const vector_type cv(A, A + 5); + VERIFY( cv.data() == &cv.front() ); + const int* pci = &* cv.data(); + VERIFY( *pci == 4 ); + } +} + +int main() +{ + test01(); + return 0; +}