diff mbox

[v3] More noexcept -- 4th

Message ID alpine.DEB.2.02.1309190439570.19561@stedding.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse Sept. 19, 2013, 3:46 a.m. UTC
Hello,

I did not touch the regular basic_string because Paulo usually says not to 
touch it, but I could do it as well if wanted. I didn't add noexcept to 
the debug string swap (and move assignments) because the regular 
basic_string swap can currently throw if the allocators are distinct.

bootstrap+testsuite ok.

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

 	PR libstdc++/58338
 	* include/bits/stl_tree.h (_Rb_tree_node_base) [_S_minimum, _S_maximum]:
 	Mark as noexcept.
 	(_Rb_tree_iterator) [_Rb_tree_iterator, operator*, operator->,
 	operator++, operator--, operator==, operator!=]: Likewise.
 	(_Rb_tree_const_iterator) [_Rb_tree_const_iterator, _M_const_cast,
 	operator*, operator->, operator++, operator--, operator==, operator!=]:
 	Likewise.
 	(operator==(const _Rb_tree_iterator&, const _Rb_tree_const_iterator&),
 	operator!=(const _Rb_tree_iterator&, const _Rb_tree_const_iterator&)):
 	Likewise.
 	(_Rb_tree) [_M_put_node, _M_destroy_node, _M_root, _M_leftmost,
 	_M_rightmost, _M_begin, _M_end, _S_left, _S_right, _S_minimum,
 	_S_maximum]: Likewise.
 	* include/debug/string (basic_string) [basic_string(const _Allocator&),
 	shrink_to_fit, operator[], pop_back]: Likewise.
 	* include/ext/vstring.h (__versa_string) [_M_limit, _M_disjunct,
 	_M_ibegin, _M_iend, __versa_string(const _Alloc&),
 	operator=(__versa_string&&), shrink_to_fit, operator[], front,
 	back, assign(__versa_string&&), swap]: Likewise.
 	(__versa_string) [__versa_string(), __versa_string(const _Alloc&)]:
 	Merge.

Comments

Paolo Carlini Sept. 19, 2013, 8:50 a.m. UTC | #1
Hi,

On 09/19/2013 05:46 AM, Marc Glisse wrote:
> Hello,
>
> I did not touch the regular basic_string because Paulo usually says 
> not to touch it, but I could do it as well if wanted.
If you like, please go ahead, there are no ABI issues in this case. 
Indeed, in the current implementation the move constructor isn't 
unconditionally noexcept due to the allocators. We have got a bug report 
about that, a very recent one. You could add the decorations to the 
current basic_string too and put a comment right before the constructor 
mentioning the bug # and the fact that things have to be reworked anyway 
in the C++11 conforming implementation.

The patch is otherwise Ok with me, thanks again!
Paolo.
Paolo Carlini Sept. 19, 2013, 8:57 a.m. UTC | #2
On 09/19/2013 10:50 AM, Paolo Carlini wrote:
> Hi,
>
> On 09/19/2013 05:46 AM, Marc Glisse wrote:
>> Hello,
>>
>> I did not touch the regular basic_string because Paulo usually says 
>> not to touch it, but I could do it as well if wanted.
> If you like, please go ahead, there are no ABI issues in this case. 
> Indeed, in the current implementation the move constructor
Read this *assignment* of course, sorry about the confusion. But the 
issue is very clear.

Paolo.
diff mbox

Patch

Index: include/bits/stl_tree.h
===================================================================
--- include/bits/stl_tree.h	(revision 202722)
+++ include/bits/stl_tree.h	(working copy)
@@ -92,42 +92,42 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
     typedef _Rb_tree_node_base* _Base_ptr;
     typedef const _Rb_tree_node_base* _Const_Base_ptr;
 
     _Rb_tree_color	_M_color;
     _Base_ptr		_M_parent;
     _Base_ptr		_M_left;
     _Base_ptr		_M_right;
 
     static _Base_ptr
-    _S_minimum(_Base_ptr __x)
+    _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     {
       while (__x->_M_left != 0) __x = __x->_M_left;
       return __x;
     }
 
     static _Const_Base_ptr
-    _S_minimum(_Const_Base_ptr __x)
+    _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
     {
       while (__x->_M_left != 0) __x = __x->_M_left;
       return __x;
     }
 
     static _Base_ptr
-    _S_maximum(_Base_ptr __x)
+    _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
     {
       while (__x->_M_right != 0) __x = __x->_M_right;
       return __x;
     }
 
     static _Const_Base_ptr
-    _S_maximum(_Const_Base_ptr __x)
+    _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
     {
       while (__x->_M_right != 0) __x = __x->_M_right;
       return __x;
     }
   };
 
   template<typename _Val>
     struct _Rb_tree_node : public _Rb_tree_node_base
     {
       typedef _Rb_tree_node<_Val>* _Link_type;
@@ -160,72 +160,72 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef _Tp& reference;
       typedef _Tp* pointer;
 
       typedef bidirectional_iterator_tag iterator_category;
       typedef ptrdiff_t                  difference_type;
 
       typedef _Rb_tree_iterator<_Tp>        _Self;
       typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
       typedef _Rb_tree_node<_Tp>*           _Link_type;
 
-      _Rb_tree_iterator()
+      _Rb_tree_iterator() _GLIBCXX_NOEXCEPT
       : _M_node() { }
 
       explicit
-      _Rb_tree_iterator(_Link_type __x)
+      _Rb_tree_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT
       : _M_node(__x) { }
 
       reference
-      operator*() const
+      operator*() const _GLIBCXX_NOEXCEPT
       { return static_cast<_Link_type>(_M_node)->_M_value_field; }
 
       pointer
-      operator->() const
+      operator->() const _GLIBCXX_NOEXCEPT
       { return std::__addressof(static_cast<_Link_type>
 				(_M_node)->_M_value_field); }
 
       _Self&
-      operator++()
+      operator++() _GLIBCXX_NOEXCEPT
       {
 	_M_node = _Rb_tree_increment(_M_node);
 	return *this;
       }
 
       _Self
-      operator++(int)
+      operator++(int) _GLIBCXX_NOEXCEPT
       {
 	_Self __tmp = *this;
 	_M_node = _Rb_tree_increment(_M_node);
 	return __tmp;
       }
 
       _Self&
-      operator--()
+      operator--() _GLIBCXX_NOEXCEPT
       {
 	_M_node = _Rb_tree_decrement(_M_node);
 	return *this;
       }
 
       _Self
-      operator--(int)
+      operator--(int) _GLIBCXX_NOEXCEPT
       {
 	_Self __tmp = *this;
 	_M_node = _Rb_tree_decrement(_M_node);
 	return __tmp;
       }
 
       bool
-      operator==(const _Self& __x) const
+      operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
       { return _M_node == __x._M_node; }
 
       bool
-      operator!=(const _Self& __x) const
+      operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
       { return _M_node != __x._M_node; }
 
       _Base_ptr _M_node;
   };
 
   template<typename _Tp>
     struct _Rb_tree_const_iterator
     {
       typedef _Tp        value_type;
       typedef const _Tp& reference;
@@ -233,95 +233,95 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       typedef _Rb_tree_iterator<_Tp> iterator;
 
       typedef bidirectional_iterator_tag iterator_category;
       typedef ptrdiff_t                  difference_type;
 
       typedef _Rb_tree_const_iterator<_Tp>        _Self;
       typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr;
       typedef const _Rb_tree_node<_Tp>*           _Link_type;
 
-      _Rb_tree_const_iterator()
+      _Rb_tree_const_iterator() _GLIBCXX_NOEXCEPT
       : _M_node() { }
 
       explicit
-      _Rb_tree_const_iterator(_Link_type __x)
+      _Rb_tree_const_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT
       : _M_node(__x) { }
 
-      _Rb_tree_const_iterator(const iterator& __it)
+      _Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPT
       : _M_node(__it._M_node) { }
 
       iterator
-      _M_const_cast() const
+      _M_const_cast() const _GLIBCXX_NOEXCEPT
       { return iterator(static_cast<typename iterator::_Link_type>
 			(const_cast<typename iterator::_Base_ptr>(_M_node))); }
 
       reference
-      operator*() const
+      operator*() const _GLIBCXX_NOEXCEPT
       { return static_cast<_Link_type>(_M_node)->_M_value_field; }
 
       pointer
-      operator->() const
+      operator->() const _GLIBCXX_NOEXCEPT
       { return std::__addressof(static_cast<_Link_type>
 				(_M_node)->_M_value_field); }
 
       _Self&
-      operator++()
+      operator++() _GLIBCXX_NOEXCEPT
       {
 	_M_node = _Rb_tree_increment(_M_node);
 	return *this;
       }
 
       _Self
-      operator++(int)
+      operator++(int) _GLIBCXX_NOEXCEPT
       {
 	_Self __tmp = *this;
 	_M_node = _Rb_tree_increment(_M_node);
 	return __tmp;
       }
 
       _Self&
-      operator--()
+      operator--() _GLIBCXX_NOEXCEPT
       {
 	_M_node = _Rb_tree_decrement(_M_node);
 	return *this;
       }
 
       _Self
-      operator--(int)
+      operator--(int) _GLIBCXX_NOEXCEPT
       {
 	_Self __tmp = *this;
 	_M_node = _Rb_tree_decrement(_M_node);
 	return __tmp;
       }
 
       bool
-      operator==(const _Self& __x) const
+      operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
       { return _M_node == __x._M_node; }
 
       bool
-      operator!=(const _Self& __x) const
+      operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
       { return _M_node != __x._M_node; }
 
       _Base_ptr _M_node;
     };
 
   template<typename _Val>
     inline bool
     operator==(const _Rb_tree_iterator<_Val>& __x,
-               const _Rb_tree_const_iterator<_Val>& __y)
+               const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
     { return __x._M_node == __y._M_node; }
 
   template<typename _Val>
     inline bool
     operator!=(const _Rb_tree_iterator<_Val>& __x,
-               const _Rb_tree_const_iterator<_Val>& __y)
+               const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
     { return __x._M_node != __y._M_node; }
 
   void
   _Rb_tree_insert_and_rebalance(const bool __insert_left,
                                 _Rb_tree_node_base* __x,
                                 _Rb_tree_node_base* __p,
                                 _Rb_tree_node_base& __header) throw ();
 
   _Rb_tree_node_base*
   _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
@@ -363,21 +363,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       allocator_type
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return allocator_type(_M_get_Node_allocator()); }
 
     protected:
       _Link_type
       _M_get_node()
       { return _M_impl._Node_allocator::allocate(1); }
 
       void
-      _M_put_node(_Link_type __p)
+      _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT
       { _M_impl._Node_allocator::deallocate(__p, 1); }
 
 #if __cplusplus < 201103L
       _Link_type
       _M_create_node(const value_type& __x)
       {
 	_Link_type __tmp = _M_get_node();
 	__try
 	  { get_allocator().construct
 	      (std::__addressof(__tmp->_M_value_field), __x); }
@@ -409,21 +409,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    }
 	  __catch(...)
 	    {
 	      _M_put_node(__tmp);
 	      __throw_exception_again;
 	    }
 	  return __tmp;
 	}
 
       void
-      _M_destroy_node(_Link_type __p)
+      _M_destroy_node(_Link_type __p) noexcept
       {
 	_M_get_Node_allocator().destroy(__p);
 	_M_put_node(__p);
       }
 #endif
 
       _Link_type
       _M_clone_node(_Const_Link_type __x)
       {
 	_Link_type __tmp = _M_create_node(__x->_M_value_field);
@@ -467,108 +467,108 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    this->_M_header._M_parent = 0;
 	    this->_M_header._M_left = &this->_M_header;
 	    this->_M_header._M_right = &this->_M_header;
 	  }	    
 	};
 
       _Rb_tree_impl<_Compare> _M_impl;
 
     protected:
       _Base_ptr&
-      _M_root()
+      _M_root() _GLIBCXX_NOEXCEPT
       { return this->_M_impl._M_header._M_parent; }
 
       _Const_Base_ptr
-      _M_root() const
+      _M_root() const _GLIBCXX_NOEXCEPT
       { return this->_M_impl._M_header._M_parent; }
 
       _Base_ptr&
-      _M_leftmost()
+      _M_leftmost() _GLIBCXX_NOEXCEPT
       { return this->_M_impl._M_header._M_left; }
 
       _Const_Base_ptr
-      _M_leftmost() const
+      _M_leftmost() const _GLIBCXX_NOEXCEPT
       { return this->_M_impl._M_header._M_left; }
 
       _Base_ptr&
-      _M_rightmost()
+      _M_rightmost() _GLIBCXX_NOEXCEPT
       { return this->_M_impl._M_header._M_right; }
 
       _Const_Base_ptr
-      _M_rightmost() const
+      _M_rightmost() const _GLIBCXX_NOEXCEPT
       { return this->_M_impl._M_header._M_right; }
 
       _Link_type
-      _M_begin()
+      _M_begin() _GLIBCXX_NOEXCEPT
       { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
 
       _Const_Link_type
-      _M_begin() const
+      _M_begin() const _GLIBCXX_NOEXCEPT
       {
 	return static_cast<_Const_Link_type>
 	  (this->_M_impl._M_header._M_parent);
       }
 
       _Link_type
-      _M_end()
+      _M_end() _GLIBCXX_NOEXCEPT
       { return static_cast<_Link_type>(&this->_M_impl._M_header); }
 
       _Const_Link_type
-      _M_end() const
+      _M_end() const _GLIBCXX_NOEXCEPT
       { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); }
 
       static const_reference
       _S_value(_Const_Link_type __x)
       { return __x->_M_value_field; }
 
       static const _Key&
       _S_key(_Const_Link_type __x)
       { return _KeyOfValue()(_S_value(__x)); }
 
       static _Link_type
-      _S_left(_Base_ptr __x)
+      _S_left(_Base_ptr __x) _GLIBCXX_NOEXCEPT
       { return static_cast<_Link_type>(__x->_M_left); }
 
       static _Const_Link_type
-      _S_left(_Const_Base_ptr __x)
+      _S_left(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
       { return static_cast<_Const_Link_type>(__x->_M_left); }
 
       static _Link_type
-      _S_right(_Base_ptr __x)
+      _S_right(_Base_ptr __x) _GLIBCXX_NOEXCEPT
       { return static_cast<_Link_type>(__x->_M_right); }
 
       static _Const_Link_type
-      _S_right(_Const_Base_ptr __x)
+      _S_right(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
       { return static_cast<_Const_Link_type>(__x->_M_right); }
 
       static const_reference
       _S_value(_Const_Base_ptr __x)
       { return static_cast<_Const_Link_type>(__x)->_M_value_field; }
 
       static const _Key&
       _S_key(_Const_Base_ptr __x)
       { return _KeyOfValue()(_S_value(__x)); }
 
       static _Base_ptr
-      _S_minimum(_Base_ptr __x)
+      _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
       { return _Rb_tree_node_base::_S_minimum(__x); }
 
       static _Const_Base_ptr
-      _S_minimum(_Const_Base_ptr __x)
+      _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
       { return _Rb_tree_node_base::_S_minimum(__x); }
 
       static _Base_ptr
-      _S_maximum(_Base_ptr __x)
+      _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
       { return _Rb_tree_node_base::_S_maximum(__x); }
 
       static _Const_Base_ptr
-      _S_maximum(_Const_Base_ptr __x)
+      _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT
       { return _Rb_tree_node_base::_S_maximum(__x); }
 
     public:
       typedef _Rb_tree_iterator<value_type>       iterator;
       typedef _Rb_tree_const_iterator<value_type> const_iterator;
 
       typedef std::reverse_iterator<iterator>       reverse_iterator;
       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
     private:
Index: include/debug/string
===================================================================
--- include/debug/string	(revision 202722)
+++ include/debug/string	(working copy)
@@ -63,20 +63,21 @@  namespace __gnu_debug
     typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
                                          basic_string> const_iterator;
 
     typedef std::reverse_iterator<iterator>            reverse_iterator;
     typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
 
     using _Base::npos;
 
     // 21.3.1 construct/copy/destroy:
     explicit basic_string(const _Allocator& __a = _Allocator())
+    _GLIBCXX_NOEXCEPT
     : _Base(__a)
     { }
 
     // Provides conversion from a release-mode string to a debug-mode string
     basic_string(const _Base& __base) : _Base(__base) { }
 
     // _GLIBCXX_RESOLVE_LIB_DEFECTS
     // 42. string ctors specify wrong default allocator
     basic_string(const basic_string& __str)
     : _Base(__str, 0, _Base::npos, __str.get_allocator())
@@ -231,21 +232,21 @@  namespace __gnu_debug
       _Base::resize(__n, __c);
       this->_M_invalidate_all();
     }
 
     void
     resize(size_type __n)
     { this->resize(__n, _CharT()); }
 
 #if __cplusplus >= 201103L
     void
-    shrink_to_fit()
+    shrink_to_fit() noexcept
     {
       if (capacity() > size())
 	{
 	  __try
 	    {
 	      reserve(0);
 	      this->_M_invalidate_all();
 	    }
 	  __catch(...)
 	    { }
@@ -260,32 +261,32 @@  namespace __gnu_debug
     clear() _GLIBCXX_NOEXCEPT
     {
       _Base::clear();
       this->_M_invalidate_all();
     }
 
     using _Base::empty;
 
     // 21.3.4 element access:
     const_reference
-    operator[](size_type __pos) const
+    operator[](size_type __pos) const _GLIBCXX_NOEXCEPT
     {
       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
 			    _M_message(__gnu_debug::__msg_subscript_oob)
 			    ._M_sequence(*this, "this")
 			    ._M_integer(__pos, "__pos")
 			    ._M_integer(this->size(), "size"));
       return _M_base()[__pos];
     }
 
     reference
-    operator[](size_type __pos)
+    operator[](size_type __pos) _GLIBCXX_NOEXCEPT
     {
 #ifdef _GLIBCXX_DEBUG_PEDANTIC
       __glibcxx_check_subscript(__pos);
 #else
       // as an extension v3 allows s[s.size()] when s is non-const.
       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
 			    _M_message(__gnu_debug::__msg_subscript_oob)
 			    ._M_sequence(*this, "this")
 			    ._M_integer(__pos, "__pos")
 			    ._M_integer(this->size(), "size"));
@@ -575,21 +576,21 @@  namespace __gnu_debug
       // 151. can't currently clear() empty container
       __glibcxx_check_erase_range(__first, __last);
       typename _Base::iterator __res = _Base::erase(__first.base(),
 						       __last.base());
       this->_M_invalidate_all();
       return iterator(__res, this);
     }
 
 #if __cplusplus >= 201103L
     void
-    pop_back()
+    pop_back() noexcept
     {
       __glibcxx_check_nonempty();
       _Base::pop_back();
       this->_M_invalidate_all();
     }
 #endif // C++11
 
     basic_string&
     replace(size_type __pos1, size_type __n1, const basic_string& __str)
     {
Index: include/ext/vstring.h
===================================================================
--- include/ext/vstring.h	(revision 202722)
+++ include/ext/vstring.h	(working copy)
@@ -91,61 +91,55 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       void
       _M_check_length(size_type __n1, size_type __n2, const char* __s) const
       {
 	if (this->max_size() - (this->size() - __n1) < __n2)
 	  std::__throw_length_error(__N(__s));
       }
 
       // NB: _M_limit doesn't check for a bad __pos value.
       size_type
-      _M_limit(size_type __pos, size_type __off) const
+      _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT
       {
 	const bool __testoff =  __off < this->size() - __pos;
 	return __testoff ? __off : this->size() - __pos;
       }
 
       // True if _Rep and source do not overlap.
       bool
-      _M_disjunct(const _CharT* __s) const
+      _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT
       {
 	return (std::less<const _CharT*>()(__s, this->_M_data())
 		|| std::less<const _CharT*>()(this->_M_data()
 					      + this->size(), __s));
       }
 
       // For the internal use we have functions similar to `begin'/`end'
       // but they do not call _M_leak.
       iterator
-      _M_ibegin() const
+      _M_ibegin() const _GLIBCXX_NOEXCEPT
       { return iterator(this->_M_data()); }
 
       iterator
-      _M_iend() const
+      _M_iend() const _GLIBCXX_NOEXCEPT
       { return iterator(this->_M_data() + this->_M_length()); }
 
     public:
       // Construct/copy/destroy:
       // NB: We overload ctors in some cases instead of using default
       // arguments, per 17.4.4.4 para. 2 item 2.
 
       /**
-       *  @brief  Default constructor creates an empty string.
-       */
-      __versa_string()
-      : __vstring_base() { }
-      
-      /**
        *  @brief  Construct an empty string using allocator @a a.
        */
       explicit
-      __versa_string(const _Alloc& __a)
+      __versa_string(const _Alloc& __a = _Alloc()) _GLIBCXX_NOEXCEPT
       : __vstring_base(__a) { }
 
       // NB: per LWG issue 42, semantics different from IS:
       /**
        *  @brief  Construct string with copy of value of @a __str.
        *  @param  __str  Source string.
        */
       __versa_string(const __versa_string& __str)
       : __vstring_base(__str) { }
 
@@ -262,21 +256,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cplusplus >= 201103L
       /**
        *  @brief  String move assignment operator.
        *  @param  __str  Source string.
        *
        *  The contents of @a __str are moved into this string (without
        *  copying).  @a __str is a valid, but unspecified string.
        */
       __versa_string&
-      operator=(__versa_string&& __str)
+      operator=(__versa_string&& __str) noexcept
       {
 	// NB: DR 1204.
 	this->swap(__str);
 	return *this;
       }
 
       /**
        *  @brief  Set value to string constructed from initializer list.
        *  @param  __l  std::initializer_list.
        */
@@ -463,21 +457,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *  is extended and new characters are default-constructed.  For
        *  basic types such as char, this means setting them to 0.
        */
       void
       resize(size_type __n)
       { this->resize(__n, _CharT()); }
 
 #if __cplusplus >= 201103L
       /// A non-binding request to reduce capacity() to size().
       void
-      shrink_to_fit()
+      shrink_to_fit() noexcept
       {
 	if (capacity() > size())
 	  {
 	    __try
 	      { this->reserve(0); }
 	    __catch(...)
 	      { }
 	  }
       }
 #endif
@@ -531,38 +525,38 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *  @brief  Subscript access to the data contained in the %string.
        *  @param  __pos  The index of the character to access.
        *  @return  Read-only (constant) reference to the character.
        *
        *  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 __pos) const
+      operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT
       {
 	_GLIBCXX_DEBUG_ASSERT(__pos <= this->size());
 	return this->_M_data()[__pos];
       }
 
       /**
        *  @brief  Subscript access to the data contained in the %string.
        *  @param  __pos  The index of the character to access.
        *  @return  Read/write reference to the character.
        *
        *  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().)  Unshares the string.
        */
       reference
-      operator[](size_type __pos)
+      operator[](size_type __pos) _GLIBCXX_NOEXCEPT
       {
         // Allow pos == size() both in C++98 mode, as v3 extension,
 	// and in C++11 mode.
 	_GLIBCXX_DEBUG_ASSERT(__pos <= this->size());
         // In pedantic mode be strict in C++98 mode.
 	_GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L
 				 || __pos < this->size());
 	this->_M_leak();
 	return this->_M_data()[__pos];
       }
@@ -604,45 +598,45 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	this->_M_leak();
 	return this->_M_data()[__n];
       }
 
 #if __cplusplus >= 201103L
       /**
        *  Returns a read/write reference to the data at the first
        *  element of the %string.
        */
       reference
-      front()
+      front() _GLIBCXX_NOEXCEPT
       { return operator[](0); }
 
       /**
        *  Returns a read-only (constant) reference to the data at the first
        *  element of the %string.
        */
       const_reference
-      front() const
+      front() const _GLIBCXX_NOEXCEPT
       { return operator[](0); }
 
       /**
        *  Returns a read/write reference to the data at the last
        *  element of the %string.
        */
       reference
-      back()
+      back() _GLIBCXX_NOEXCEPT
       { return operator[](this->size() - 1); }
 
       /**
        *  Returns a read-only (constant) reference to the data at the
        *  last element of the %string.
        */
       const_reference
-      back() const
+      back() const _GLIBCXX_NOEXCEPT
       { return operator[](this->size() - 1); }
 #endif
 
       // Modifiers:
       /**
        *  @brief  Append a string to this string.
        *  @param __str  The string to append.
        *  @return  Reference to this string.
        */
       __versa_string&
@@ -807,21 +801,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus >= 201103L
       /**
        *  @brief  Set value to contents of another string.
        *  @param  __str  Source string to use.
        *  @return  Reference to this string.
        *
        *  This function sets this string to the exact contents of @a __str.
        *  @a __str is a valid, but unspecified string.
        */
       __versa_string&
-      assign(__versa_string&& __str)
+      assign(__versa_string&& __str) noexcept
       {
 	this->swap(__str);
 	return *this;
       }
 #endif // C++11
 
       /**
        *  @brief  Set value to a substring of a string.
        *  @param __str  The string to use.
        *  @param __pos  Index of the first character of str.
@@ -1624,21 +1618,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
 
       /**
        *  @brief  Swap contents with another string.
        *  @param __s  String to swap with.
        *
        *  Exchanges the contents of this string with that of @a __s in
        *  constant time.
       */
       void
-      swap(__versa_string& __s)
+      swap(__versa_string& __s) _GLIBCXX_NOEXCEPT
       { this->_M_swap(__s); }
 
       // String operations:
       /**
        *  @brief  Return const pointer to null-terminated contents.
        *
        *  This is a handle to internal data.  Do not modify or dire things may
        *  happen.
       */
       const _CharT*