Patchwork [v3] More noexcept for vectors

login
register
mail settings
Submitter Marc Glisse
Date Sept. 16, 2013, 5:32 p.m.
Message ID <alpine.DEB.2.02.1309161917530.1285@stedding.saclay.inria.fr>
Download mbox | patch
Permalink /patch/275259/
State New
Headers show

Comments

Marc Glisse - Sept. 16, 2013, 5:32 p.m.
New version that passed testing.

2013-09-16  Marc Glisse  <marc.glisse@inria.fr>

 	PR libstdc++/58338
 	* include/bits/stl_vector.h (vector::vector(),
 	vector::vector(const allocator_type&)): Merge.
 	(_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_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.
 	* include/debug/vector (vector::vector(const _Allocator&),
 	vector::operator[], vector::operator[] const, vector::front,
 	vector::front const, vector::back, vector::back const, vector::pop_back,
 	_M_requires_reallocation, _M_update_guaranteed_capacity,
 	_M_invalidate_after_nth): Mark as noexcept.
 	* include/profile/vector (vector::vector(const _Allocator&),
 	vector::operator[], vector::operator[] const, vector::front,
 	vector::front const, vector::back, vector::back const): Mark as
 	noexcept.
 	(vector::vector(vector&&, const _Allocator&)): Remove wrong noexcept.
 	* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
 	Adjust line number.
 	* testsuite/23_containers/vector/requirements/dr438/
 	constructor_1_neg.cc: Likewise.
 	* testsuite/23_containers/vector/requirements/dr438/
 	constructor_2_neg.cc: Likewise.
 	* testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
 	Likewise.
Paolo Carlini - Sept. 17, 2013, 12:05 a.m.
On 09/16/2013 07:32 PM, Marc Glisse wrote:
> New version that passed testing.
Looks good to me, thanks!

Paolo.

Patch

Index: include/bits/stl_vector.h

===================================================================
--- include/bits/stl_vector.h	(revision 202625)

+++ 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,53 +117,53 @@  _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
 	  {
 	    size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start;
 	    _M_create_storage(__n);
 	  }
       }
 #endif
 
-      ~_Vector_base()

+      ~_Vector_base() _GLIBCXX_NOEXCEPT

       { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage
 		      - this->_M_impl._M_start); }
 
     public:
       _Vector_impl _M_impl;
 
       pointer
       _M_allocate(size_t __n)
       { return __n != 0 ? _M_impl.allocate(__n) : 0; }
 
@@ -236,31 +236,25 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER

     protected:
       using _Base::_M_allocate;
       using _Base::_M_deallocate;
       using _Base::_M_impl;
       using _Base::_M_get_Tp_allocator;
 
     public:
       // [23.2.4.1] construct/copy/destroy
       // (assign() and get_allocator() are also listed in this section)
       /**
-       *  @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 = allocator_type()) _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.
@@ -760,36 +754,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 +823,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 +921,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 +1402,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);
Index: include/debug/vector

===================================================================
--- include/debug/vector	(revision 202625)

+++ include/debug/vector	(working copy)

@@ -69,21 +69,21 @@  namespace __debug

 
       typedef _Tp				    value_type;
       typedef _Allocator			    allocator_type;
       typedef typename _Base::pointer               pointer;
       typedef typename _Base::const_pointer         const_pointer;
       typedef std::reverse_iterator<iterator>       reverse_iterator;
       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
       // 23.2.4.1 construct/copy/destroy:
       explicit
-      vector(const _Allocator& __a = _Allocator())

+      vector(const _Allocator& __a = _Allocator()) _GLIBCXX_NOEXCEPT

       : _Base(__a), _M_guaranteed_capacity(0) { }
 
 #if __cplusplus >= 201103L
       explicit
       vector(size_type __n, const _Allocator& __a = _Allocator())
       : _Base(__n, __a), _M_guaranteed_capacity(__n) { }
 
       vector(size_type __n, const _Tp& __value,
 	     const _Allocator& __a = _Allocator())
       : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
@@ -334,58 +334,58 @@  namespace __debug

 	bool __realloc = _M_requires_reallocation(__n);
 	_Base::reserve(__n);
 	if (__n > _M_guaranteed_capacity)
 	  _M_guaranteed_capacity = __n;
 	if (__realloc)
 	  this->_M_invalidate_all();
       }
 
       // element access:
       reference
-      operator[](size_type __n)

+      operator[](size_type __n) _GLIBCXX_NOEXCEPT

       {
 	__glibcxx_check_subscript(__n);
 	return _M_base()[__n];
       }
 
       const_reference
-      operator[](size_type __n) const

+      operator[](size_type __n) const _GLIBCXX_NOEXCEPT

       {
 	__glibcxx_check_subscript(__n);
 	return _M_base()[__n];
       }
 
       using _Base::at;
 
       reference
-      front()

+      front() _GLIBCXX_NOEXCEPT

       {
 	__glibcxx_check_nonempty();
 	return _Base::front();
       }
 
       const_reference
-      front() const

+      front() const _GLIBCXX_NOEXCEPT

       {
 	__glibcxx_check_nonempty();
 	return _Base::front();
       }
 
       reference
-      back()

+      back() _GLIBCXX_NOEXCEPT

       {
 	__glibcxx_check_nonempty();
 	return _Base::back();
       }
 
       const_reference
-      back() const

+      back() const _GLIBCXX_NOEXCEPT

       {
 	__glibcxx_check_nonempty();
 	return _Base::back();
       }
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR 464. Suggestion for new member functions in standard containers.
       using _Base::data;
 
       // 23.2.4.3 modifiers:
@@ -412,21 +412,21 @@  namespace __debug

 	{
 	  bool __realloc = _M_requires_reallocation(this->size() + 1);
 	  _Base::emplace_back(std::forward<_Args>(__args)...);
 	  if (__realloc)
 	    this->_M_invalidate_all();
 	  _M_update_guaranteed_capacity();
 	}
 #endif
 
       void
-      pop_back()

+      pop_back() _GLIBCXX_NOEXCEPT

       {
 	__glibcxx_check_nonempty();
 	this->_M_invalidate_if(_Equal(--_Base::end()));
 	_Base::pop_back();
       }
 
 #if __cplusplus >= 201103L
       template<typename... _Args>
         iterator
         emplace(const_iterator __position, _Args&&... __args)
@@ -623,32 +623,32 @@  namespace __debug

       _Base&
       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
 
       const _Base&
       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
 
     private:
       size_type _M_guaranteed_capacity;
 
       bool
-      _M_requires_reallocation(size_type __elements)

+      _M_requires_reallocation(size_type __elements) _GLIBCXX_NOEXCEPT

       { return __elements > this->capacity(); }
 
       void
-      _M_update_guaranteed_capacity()

+      _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT

       {
 	if (this->size() > _M_guaranteed_capacity)
 	  _M_guaranteed_capacity = this->size();
       }
 
       void
-      _M_invalidate_after_nth(difference_type __n)

+      _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT

       {
 	typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
 	this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
       }
     };
 
   template<typename _Tp, typename _Alloc>
     inline bool
     operator==(const vector<_Tp, _Alloc>& __lhs,
 	       const vector<_Tp, _Alloc>& __rhs)
Index: include/profile/vector

===================================================================
--- include/profile/vector	(revision 202625)

+++ include/profile/vector	(working copy)

@@ -71,21 +71,21 @@  namespace __profile

       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
       
       _Base&
       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
 
       const _Base&
       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
 
       // 23.2.4.1 construct/copy/destroy:
       explicit
-      vector(const _Allocator& __a = _Allocator())

+      vector(const _Allocator& __a = _Allocator()) _GLIBCXX_NOEXCEPT

       : _Base(__a)
       {
         __profcxx_vector_construct(this, this->capacity());
         __profcxx_vector_construct2(this);
       }
 
 #if __cplusplus >= 201103L
       explicit
       vector(size_type __n, const _Allocator& __a = _Allocator())
       : _Base(__n, __a)
@@ -149,21 +149,21 @@  namespace __profile

         __profcxx_vector_construct2(this);
       }
 
       vector(const _Base& __x, const _Allocator& __a)
       : _Base(__x, __a)
       { 
         __profcxx_vector_construct(this, this->capacity());
         __profcxx_vector_construct2(this);
       }
 
-      vector(vector&& __x, const _Allocator& __a) noexcept

+      vector(vector&& __x, const _Allocator& __a)

       : _Base(std::move(__x), __a)
       {
         __profcxx_vector_construct(this, this->capacity());
         __profcxx_vector_construct2(this);
       }
 
       vector(initializer_list<value_type> __l,
 	     const allocator_type& __a = allocator_type())
       : _Base(__l, __a) { }
 #endif
@@ -285,54 +285,54 @@  namespace __profile

 #endif
 
 #if __cplusplus >= 201103L
       using _Base::shrink_to_fit;
 #endif
 
       using _Base::empty;
 
       // element access:
       reference
-      operator[](size_type __n)

+      operator[](size_type __n) _GLIBCXX_NOEXCEPT

       {
         __profcxx_vector_invalid_operator(this);
         return _M_base()[__n];
       }
       const_reference
-      operator[](size_type __n) const

+      operator[](size_type __n) const _GLIBCXX_NOEXCEPT

       {
         __profcxx_vector_invalid_operator(this);
         return _M_base()[__n];
       }
 
       using _Base::at;
 
       reference
-      front()

+      front() _GLIBCXX_NOEXCEPT

       { 
         return _Base::front();
       }
 
       const_reference
-      front() const

+      front() const _GLIBCXX_NOEXCEPT

       {
 	return _Base::front();
       }
 
       reference
-      back()

+      back() _GLIBCXX_NOEXCEPT

       {
 	return _Base::back();
       }
 
       const_reference
-      back() const

+      back() const _GLIBCXX_NOEXCEPT

       {
 	return _Base::back();
       }
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR 464. Suggestion for new member functions in standard containers.
       using _Base::data;
 
       // 23.2.4.3 modifiers:
       void
Index: testsuite/23_containers/vector/requirements/dr438/assign_neg.cc

===================================================================
--- testsuite/23_containers/vector/requirements/dr438/assign_neg.cc	(revision 202625)

+++ testsuite/23_containers/vector/requirements/dr438/assign_neg.cc	(working copy)

@@ -11,21 +11,21 @@ 

 // 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 COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1308 }

+// { dg-error "no matching" "" { target *-*-* } 1302 }

 
 #include <vector>
 
 struct A
 {
   explicit A(int) { }
 };
 
 void f()
 {
Index: testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc

===================================================================
--- testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc	(revision 202625)

+++ testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc	(working copy)

@@ -11,18 +11,18 @@ 

 // 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 COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1234 }

+// { dg-error "no matching" "" { target *-*-* } 1228 }

 
 #include <vector>
 
 void f()
 {
   std::vector<std::vector<int> > v(10, 1);
 }
Index: testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc

===================================================================
--- testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc	(revision 202625)

+++ testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc	(working copy)

@@ -11,19 +11,19 @@ 

 // 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 COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1234 }

+// { dg-error "no matching" "" { target *-*-* } 1228 }

 
 #include <vector>
 #include <utility>
 
 void f()
 {
   std::vector<std::vector<std::pair<char, char> > > v('a', 'b');
 }
Index: testsuite/23_containers/vector/requirements/dr438/insert_neg.cc

===================================================================
--- testsuite/23_containers/vector/requirements/dr438/insert_neg.cc	(revision 202625)

+++ testsuite/23_containers/vector/requirements/dr438/insert_neg.cc	(working copy)

@@ -11,21 +11,21 @@ 

 // 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 COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1349 }

+// { dg-error "no matching" "" { target *-*-* } 1343 }

 
 #include <vector>
 
 struct A
 {
   explicit A(int) { }
 };
 
 void f()
 {