Hello,this patch passes bootstrap+testsuite. The guarantees given by the standard on allocators are a bit weird, but I see there is already DR2016 taking care of it.
2013-09-14 Marc Glisse <marc.gli...@inria.fr> PR libstdc++/58338 * include/bits/stl_vector.h (_Vector_impl::_Vector_impl(_Tp_alloc_type const&), _Vector_impl::_Vector_impl(_Tp_alloc_type&&), _Vector_impl::_M_swap_data, _Vector_base::_Vector_base(const allocator_type&), _Vector_base::_Vector_base(allocator_type&&), _Vector_base::_Vector_base(_Vector_base&&), vector::vector(const allocator_type&), vector::operator[], vector::operator[] const, vector::front, vector::front const, vector::back, vector::back const, vector::pop_back, vector::_M_erase_at_end): Mark as noexcept. (vector::~vector): Remove useless noexcept. -- Marc Glisse
Index: include/bits/stl_vector.h =================================================================== --- include/bits/stl_vector.h (revision 202588) +++ include/bits/stl_vector.h (working copy) @@ -80,32 +80,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : public _Tp_alloc_type { pointer _M_start; pointer _M_finish; pointer _M_end_of_storage; _Vector_impl() : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } - _Vector_impl(_Tp_alloc_type const& __a) + _Vector_impl(_Tp_alloc_type const& __a) _GLIBCXX_NOEXCEPT : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } #if __cplusplus >= 201103L - _Vector_impl(_Tp_alloc_type&& __a) + _Vector_impl(_Tp_alloc_type&& __a) noexcept : _Tp_alloc_type(std::move(__a)), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } #endif - void _M_swap_data(_Vector_impl& __x) + void _M_swap_data(_Vector_impl& __x) _GLIBCXX_NOEXCEPT { std::swap(_M_start, __x._M_start); std::swap(_M_finish, __x._M_finish); std::swap(_M_end_of_storage, __x._M_end_of_storage); } }; public: typedef _Alloc allocator_type; @@ -117,36 +117,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); } allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_get_Tp_allocator()); } _Vector_base() : _M_impl() { } - _Vector_base(const allocator_type& __a) + _Vector_base(const allocator_type& __a) _GLIBCXX_NOEXCEPT : _M_impl(__a) { } _Vector_base(size_t __n) : _M_impl() { _M_create_storage(__n); } _Vector_base(size_t __n, const allocator_type& __a) : _M_impl(__a) { _M_create_storage(__n); } #if __cplusplus >= 201103L - _Vector_base(_Tp_alloc_type&& __a) + _Vector_base(_Tp_alloc_type&& __a) noexcept : _M_impl(std::move(__a)) { } - _Vector_base(_Vector_base&& __x) + _Vector_base(_Vector_base&& __x) noexcept : _M_impl(std::move(__x._M_get_Tp_allocator())) { this->_M_impl._M_swap_data(__x._M_impl); } _Vector_base(_Vector_base&& __x, const allocator_type& __a) : _M_impl(__a) { if (__x.get_allocator() == __a) this->_M_impl._M_swap_data(__x._M_impl); else { @@ -246,21 +246,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @brief Default constructor creates no elements. */ vector() : _Base() { } /** * @brief Creates a %vector with no elements. * @param __a An allocator object. */ explicit - vector(const allocator_type& __a) + vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT : _Base(__a) { } #if __cplusplus >= 201103L /** * @brief Creates a %vector with default constructed elements. * @param __n The number of elements to initially create. * @param __a An allocator. * * This constructor fills the %vector with @a __n default * constructed elements. @@ -404,21 +404,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_initialize_dispatch(__first, __last, _Integral()); } #endif /** * The dtor only erases the elements, and note that if the * elements themselves are pointers, the pointed-to memory is * not touched in any way. Managing the pointer is the user's * responsibility. */ - ~vector() _GLIBCXX_NOEXCEPT + ~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); } /** * @brief %Vector assignment operator. * @param __x A %vector of identical element and allocator types. * * All the elements of @a __x are copied, but any extra memory in * @a __x (for fast expansion) will not be copied. Unlike the * copy constructor, the allocator object is not copied. @@ -760,36 +760,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @param __n The index of the element for which data should be * accessed. * @return Read/write reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ reference - operator[](size_type __n) + operator[](size_type __n) _GLIBCXX_NOEXCEPT { return *(this->_M_impl._M_start + __n); } /** * @brief Subscript access to the data contained in the %vector. * @param __n The index of the element for which data should be * accessed. * @return Read-only (constant) reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ const_reference - operator[](size_type __n) const + operator[](size_type __n) const _GLIBCXX_NOEXCEPT { return *(this->_M_impl._M_start + __n); } protected: /// Safety check used only from at(). void _M_range_check(size_type __n) const { if (__n >= this->size()) __throw_out_of_range(__N("vector::_M_range_check")); } @@ -829,45 +829,45 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { _M_range_check(__n); return (*this)[__n]; } /** * Returns a read/write reference to the data at the first * element of the %vector. */ reference - front() + front() _GLIBCXX_NOEXCEPT { return *begin(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %vector. */ const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { return *begin(); } /** * Returns a read/write reference to the data at the last * element of the %vector. */ reference - back() + back() _GLIBCXX_NOEXCEPT { return *(end() - 1); } /** * Returns a read-only (constant) reference to the data at the * last element of the %vector. */ const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { return *(end() - 1); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 464. Suggestion for new member functions in standard containers. // data access /** * Returns a pointer such that [data(), data() + size()) is a valid * range. For a non-empty %vector, data() == &front(). */ #if __cplusplus >= 201103L @@ -927,21 +927,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * @brief Removes last element. * * This is a typical stack operation. It shrinks the %vector by one. * * Note that no data is returned, and if the last element's * data is needed, it should be retrieved before pop_back() is * called. */ void - pop_back() + pop_back() _GLIBCXX_NOEXCEPT { --this->_M_impl._M_finish; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); } #if __cplusplus >= 201103L /** * @brief Inserts an object in %vector before specified iterator. * @param __position A const_iterator into the %vector. * @param __args Arguments. @@ -1408,21 +1408,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const size_type __len = size() + std::max(size(), __n); return (__len < size() || __len > max_size()) ? max_size() : __len; } // Internal erase functions follow. // Called by erase(q1,q2), clear(), resize(), _M_fill_assign, // _M_assign_aux. void - _M_erase_at_end(pointer __pos) + _M_erase_at_end(pointer __pos) _GLIBCXX_NOEXCEPT { std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __pos; } iterator _M_erase(iterator __position); iterator _M_erase(iterator __first, iterator __last);