This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] More noexcept for vectors


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.glisse@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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]