diff mbox

[v3] More noexcept -- 5th

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

Commit Message

Marc Glisse Sept. 20, 2013, 7:46 a.m. UTC
Hello,

for basic_string, I tried not to add lies about exceptions, but I didn't
remove existing ones.

I find it strange that operator== and others are duplicated for
_Deque_iterator, one for the homogeneous case and one for the general
case, when both do the same.

Note that all deque constructors call new at least twice, there is no
noexcept constructor.

With all the indirections (container, container_base, container_impl, 
etc), there is a bit of dead code, some constructors are never called (I 
had to fix one in _Deque_base which was broken but never called).

bootstrap+testsuite ok.

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

 	PR libstdc++/58338
 	* include/bits/allocator.h (__alloc_swap::_S_do_it,
 	__shrink_to_fit_aux::_S_do_it): Mark as noexcept.
 	* include/bits/basic_string.h (basic_string::_Rep) [_S_empty_rep,
 	_M_is_leaked, _M_is_shared, _M_set_leaked, _M_set_sharable,
 	_M_set_length_and_sharable, _M_dispose]: Likewise.
 	(basic_string::_Alloc_hider::_Alloc_hider): Likewise.
 	(basic_string) [_M_data, _M_rep, _M_ibegin, _M_iend, _M_limit,
 	_M_disjunct, _M_copy, _M_move, _M_assign, _S_copy_chars, _S_compare,
 	_S_empty_rep, shrink_to_fit, operator[] const, front const, back const]:
 	Likewise.
 	[clear]: Link to PR 56166.
 	[swap]: Link to PR 58265.
 	* include/bits/stl_deque.h (_Deque_iterator) [_S_buffer_size,
 	_Deque_iterator, _M_const_cast, operator*, operator->, operator++,
 	operator--, operator+=, operator+, operator-=, operator-, operator[],
 	_M_set_node]: Mark as noexcept.
 	(operator==(const _Deque_iterator&, const _Deque_iterator&),
 	operator!=(const _Deque_iterator&, const _Deque_iterator&),
 	operator<(const _Deque_iterator&, const _Deque_iterator&),
 	operator>(const _Deque_iterator&, const _Deque_iterator&),
 	operator<=(const _Deque_iterator&, const _Deque_iterator&),
 	operator>=(const _Deque_iterator&, const _Deque_iterator&),
 	operator-(const _Deque_iterator&, const _Deque_iterator&),
 	operator+(ptrdiff_t, const _Deque_iterator&)): Likewise.
 	(_Deque_base) [_Deque_base(const allocator_type&)]: Add missing call to
 	_M_initialize_map.
 	[~_Deque_base, _M_deallocate_node, _M_deallocate_map, _M_destroy_nodes]:
 	Mark as noexcept.
 	(_Deque_base::_Deque_impl) [_Deque_impl(const _Tp_alloc_type&),
 	_Deque_impl(_Tp_alloc_type&&)]: Likewise.
 	(deque) [_S_buffer_size, operator=(deque&&), shrink_to_fit, operator[],
 	front, back, pop_front, pop_back, swap]: Likewise.
 	[deque(), deque(const allocator_type&)]: Merge.
 	* include/debug/deque (deque) [operator=(deque&&), shrink_to_fit,
 	operator[], front, back, pop_front, pop_back, swap]: Mark as noexcept.
 	* include/profile/deque (deque) [operator=(deque&&), operator[], front,
 	back, pop_front, pop_back, swap]: Likewise.
 	* testsuite/23_containers/deque/requirements/dr438/assign_neg.cc:
 	Adjust line number.
 	* testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc:
 	Likewise.
 	* testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc:
 	Likewise.
 	* testsuite/23_containers/deque/requirements/dr438/insert_neg.cc:
 	Likewise.

Comments

Paolo Carlini Sept. 20, 2013, 12:10 p.m. UTC | #1
On 09/20/2013 09:46 AM, Marc Glisse wrote:
> Hello,
>
> for basic_string, I tried not to add lies about exceptions, but I didn't
> remove existing ones.
Of course we should not have lies, I thought we didn't, besides maybe 
special cases having to do with the FULLY_DYNAMIC string thing, really a 
C++98 legacy wa, which will not exist in the future. Can you please send 
an updated patch fixing those?

Thanks,
Paolo.
Paolo Carlini Sept. 20, 2013, 12:42 p.m. UTC | #2
.. first blush, I think we have to remove the noexcept from the 
non-const forms of begin and end and from clear. Because the string can 
be shared...

Thanks,
Paolo.
Marc Glisse Sept. 20, 2013, 2:09 p.m. UTC | #3
On Fri, 20 Sep 2013, Paolo Carlini wrote:

> On 09/20/2013 09:46 AM, Marc Glisse wrote:
>> Hello,
>> 
>> for basic_string, I tried not to add lies about exceptions, but I didn't
>> remove existing ones.
> Of course we should not have lies, I thought we didn't, besides maybe special 
> cases having to do with the FULLY_DYNAMIC string thing, really a C++98 legacy 
> wa, which will not exist in the future. Can you please send an updated patch 
> fixing those?

Would you mind if we did that as a separate follow-up patch, unless there 
are other problems with the patch? One is adding noexcept for 
optimization, the other one would be removing some (no intersection) for 
correctness. I'll do it this WE. I'll also need to remove the 
corresponding noexcept from debug/profile mode...
Paolo Carlini Sept. 20, 2013, 2:16 p.m. UTC | #4
On 09/20/2013 04:09 PM, Marc Glisse wrote:
> On Fri, 20 Sep 2013, Paolo Carlini wrote:
>
>> On 09/20/2013 09:46 AM, Marc Glisse wrote:
>>> Hello,
>>>
>>> for basic_string, I tried not to add lies about exceptions, but I 
>>> didn't
>>> remove existing ones.
>> Of course we should not have lies, I thought we didn't, besides maybe 
>> special cases having to do with the FULLY_DYNAMIC string thing, 
>> really a C++98 legacy wa, which will not exist in the future. Can you 
>> please send an updated patch fixing those?
>
> Would you mind if we did that as a separate follow-up patch, unless 
> there are other problems with the patch? One is adding noexcept for 
> optimization, the other one would be removing some (no intersection) 
> for correctness. I'll do it this WE. I'll also need to remove the 
> corresponding noexcept from debug/profile mode...
Ok It's fine like that, and thank you for doing the work, please also 
add a one-line comment before the noexcept you remove explaining that we 
are non-conforming in not having those decorations but that's life until 
we get rid of the reference-counted implementation. Thanks again!

By the way, I would be curious at some point to actually see with my 
eyes the effect of those optimizations in the assembly: is it easy to 
produce examples? Even at say -O2?

Thanks,
Paolo.
Marc Glisse Sept. 20, 2013, 2:32 p.m. UTC | #5
On Fri, 20 Sep 2013, Paolo Carlini wrote:

> By the way, I would be curious at some point to actually see with my eyes the 
> effect of those optimizations in the assembly: is it easy to produce 
> examples? Even at say -O2?

If you use "if(noexcept(container.shrink_to_fit()))", you can easily cause 
different code to be used. Now whether for regular code it somehow 
produces fewer implicit try-catch or some optimization like that, I have 
no idea. If it ever makes code worse, please beat the core- people who 
required std::terminate with a screen showing the benchmarks (I keep 
wanting to introduce -fno-abort -fno-terminate flags to turn those 2 calls 
into __builtin_unreachable).

Note that I am still a proponent of noexcept(auto), if it can't be the 
default. If someone feels like implementing it as an extension, we could 
use it in the library.
diff mbox

Patch

Index: include/bits/allocator.h
===================================================================
--- include/bits/allocator.h	(revision 202764)
+++ include/bits/allocator.h	(working copy)
@@ -151,27 +151,27 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern template class allocator<char>;
   extern template class allocator<wchar_t>;
 #endif
 
   // Undefine.
 #undef __allocator_base
 
   // To implement Option 3 of DR 431.
   template<typename _Alloc, bool = __is_empty(_Alloc)>
     struct __alloc_swap
-    { static void _S_do_it(_Alloc&, _Alloc&) { } };
+    { static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
 
   template<typename _Alloc>
     struct __alloc_swap<_Alloc, false>
     {
       static void
-      _S_do_it(_Alloc& __one, _Alloc& __two)
+      _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
       {
 	// Precondition: swappable allocators.
 	if (__one != __two)
 	  swap(__one, __two);
       }
     };
 
   // Optimize for stateless allocators.
   template<typename _Alloc, bool = __is_empty(_Alloc)>
     struct __alloc_neq
@@ -187,27 +187,27 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static bool
       _S_do_it(const _Alloc& __one, const _Alloc& __two)
       { return __one != __two; }
     };
 
 #if __cplusplus >= 201103L
   template<typename _Tp, bool
     = __or_<is_copy_constructible<typename _Tp::value_type>,
             is_nothrow_move_constructible<typename _Tp::value_type>>::value>
     struct __shrink_to_fit_aux
-    { static bool _S_do_it(_Tp&) { return false; } };
+    { static bool _S_do_it(_Tp&) noexcept { return false; } };
 
   template<typename _Tp>
     struct __shrink_to_fit_aux<_Tp, true>
     {
       static bool
-      _S_do_it(_Tp& __c)
+      _S_do_it(_Tp& __c) noexcept
       {
 	__try
 	  {
 	    _Tp(__make_move_if_noexcept_iterator(__c.begin()),
 		__make_move_if_noexcept_iterator(__c.end()),
 		__c.get_allocator()).swap(__c);
 	    return true;
 	  }
 	__catch(...)
 	  { return false; }
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h	(revision 202764)
+++ include/bits/basic_string.h	(working copy)
@@ -171,47 +171,47 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	// m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
 	// In addition, this implementation quarters this amount.
 	static const size_type	_S_max_size;
 	static const _CharT	_S_terminal;
 
 	// The following storage is init'd to 0 by the linker, resulting
         // (carefully) in an empty string with one reference.
         static size_type _S_empty_rep_storage[];
 
         static _Rep&
-        _S_empty_rep()
+        _S_empty_rep() _GLIBCXX_NOEXCEPT
         { 
 	  // NB: Mild hack to avoid strict-aliasing warnings.  Note that
 	  // _S_empty_rep_storage is never modified and the punning should
 	  // be reasonably safe in this case.
 	  void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
 	  return *reinterpret_cast<_Rep*>(__p);
 	}
 
         bool
-	_M_is_leaked() const
+	_M_is_leaked() const _GLIBCXX_NOEXCEPT
         { return this->_M_refcount < 0; }
 
         bool
-	_M_is_shared() const
+	_M_is_shared() const _GLIBCXX_NOEXCEPT
         { return this->_M_refcount > 0; }
 
         void
-	_M_set_leaked()
+	_M_set_leaked() _GLIBCXX_NOEXCEPT
         { this->_M_refcount = -1; }
 
         void
-	_M_set_sharable()
+	_M_set_sharable() _GLIBCXX_NOEXCEPT
         { this->_M_refcount = 0; }
 
 	void
-	_M_set_length_and_sharable(size_type __n)
+	_M_set_length_and_sharable(size_type __n) _GLIBCXX_NOEXCEPT
 	{
 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
 	  if (__builtin_expect(this != &_S_empty_rep(), false))
 #endif
 	    {
 	      this->_M_set_sharable();  // One reference.
 	      this->_M_length = __n;
 	      traits_type::assign(this->_M_refdata()[__n], _S_terminal);
 	      // grrr. (per 21.3.4)
 	      // You cannot leave those LWG people alone for a second.
@@ -227,21 +227,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{
 	  return (!_M_is_leaked() && __alloc1 == __alloc2)
 	          ? _M_refcopy() : _M_clone(__alloc1);
 	}
 
 	// Create & Destroy
 	static _Rep*
 	_S_create(size_type, size_type, const _Alloc&);
 
 	void
-	_M_dispose(const _Alloc& __a)
+	_M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT
 	{
 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
 	  if (__builtin_expect(this != &_S_empty_rep(), false))
 #endif
 	    {
 	      // Be race-detector-friendly.  For more info see bits/c++config.
 	      _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount);
 	      if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
 							 -1) <= 0)
 		{
@@ -264,57 +264,57 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return _M_refdata();
 	}  // XXX MT
 
 	_CharT*
 	_M_clone(const _Alloc&, size_type __res = 0);
       };
 
       // Use empty-base optimization: http://www.cantrip.org/emptyopt.html
       struct _Alloc_hider : _Alloc
       {
-	_Alloc_hider(_CharT* __dat, const _Alloc& __a)
+	_Alloc_hider(_CharT* __dat, const _Alloc& __a) _GLIBCXX_NOEXCEPT
 	: _Alloc(__a), _M_p(__dat) { }
 
 	_CharT* _M_p; // The actual data.
       };
 
     public:
       // Data Members (public):
       // NB: This is an unsigned type, and thus represents the maximum
       // size that the allocator can hold.
       ///  Value returned by various member functions when they fail.
       static const size_type	npos = static_cast<size_type>(-1);
 
     private:
       // Data Members (private):
       mutable _Alloc_hider	_M_dataplus;
 
       _CharT*
-      _M_data() const
+      _M_data() const _GLIBCXX_NOEXCEPT
       { return  _M_dataplus._M_p; }
 
       _CharT*
-      _M_data(_CharT* __p)
+      _M_data(_CharT* __p) _GLIBCXX_NOEXCEPT
       { return (_M_dataplus._M_p = __p); }
 
       _Rep*
-      _M_rep() const
+      _M_rep() const _GLIBCXX_NOEXCEPT
       { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
 
       // 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(_M_data()); }
 
       iterator
-      _M_iend() const
+      _M_iend() const _GLIBCXX_NOEXCEPT
       { return iterator(_M_data() + this->size()); }
 
       void
       _M_leak()    // for use in begin() & non-const op[]
       {
 	if (!_M_rep()->_M_is_leaked())
 	  _M_leak_hard();
       }
 
       size_type
@@ -327,110 +327,113 @@  _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)
 	  __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 (less<const _CharT*>()(__s, _M_data())
 		|| less<const _CharT*>()(_M_data() + this->size(), __s));
       }
 
       // When __n = 1 way faster than the general multichar
       // traits_type::copy/move/assign.
       static void
-      _M_copy(_CharT* __d, const _CharT* __s, size_type __n)
+      _M_copy(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT
       {
 	if (__n == 1)
 	  traits_type::assign(*__d, *__s);
 	else
 	  traits_type::copy(__d, __s, __n);
       }
 
       static void
-      _M_move(_CharT* __d, const _CharT* __s, size_type __n)
+      _M_move(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT
       {
 	if (__n == 1)
 	  traits_type::assign(*__d, *__s);
 	else
 	  traits_type::move(__d, __s, __n);	  
       }
 
       static void
-      _M_assign(_CharT* __d, size_type __n, _CharT __c)
+      _M_assign(_CharT* __d, size_type __n, _CharT __c) _GLIBCXX_NOEXCEPT
       {
 	if (__n == 1)
 	  traits_type::assign(*__d, __c);
 	else
 	  traits_type::assign(__d, __n, __c);	  
       }
 
       // _S_copy_chars is a separate template to permit specialization
       // to optimize for the common case of pointers as iterators.
       template<class _Iterator>
         static void
         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
+	_GLIBCXX_NOEXCEPT
         {
 	  for (; __k1 != __k2; ++__k1, ++__p)
 	    traits_type::assign(*__p, *__k1); // These types are off.
 	}
 
       static void
-      _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2)
+      _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT
       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
 
       static void
       _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
+      _GLIBCXX_NOEXCEPT
       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
 
       static void
-      _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
+      _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT
       { _M_copy(__p, __k1, __k2 - __k1); }
 
       static void
       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
+      _GLIBCXX_NOEXCEPT
       { _M_copy(__p, __k1, __k2 - __k1); }
 
       static int
-      _S_compare(size_type __n1, size_type __n2)
+      _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT
       {
 	const difference_type __d = difference_type(__n1 - __n2);
 
 	if (__d > __gnu_cxx::__numeric_traits<int>::__max)
 	  return __gnu_cxx::__numeric_traits<int>::__max;
 	else if (__d < __gnu_cxx::__numeric_traits<int>::__min)
 	  return __gnu_cxx::__numeric_traits<int>::__min;
 	else
 	  return int(__d);
       }
 
       void
       _M_mutate(size_type __pos, size_type __len1, size_type __len2);
 
       void
       _M_leak_hard();
 
       static _Rep&
-      _S_empty_rep()
+      _S_empty_rep() _GLIBCXX_NOEXCEPT
       { return _Rep::_S_empty_rep(); }
 
     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.
        */
@@ -749,21 +752,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *  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() _GLIBCXX_NOEXCEPT
       {
 	if (capacity() > size())
 	  {
 	    __try
 	      { reserve(0); }
 	    __catch(...)
 	      { }
 	  }
       }
 #endif
@@ -792,20 +795,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *  required, the user can reserve the memory in %advance, and thus
        *  prevent a possible reallocation of memory and copying of %string
        *  data.
        */
       void
       reserve(size_type __res_arg = 0);
 
       /**
        *  Erases the string, making it empty.
        */
+      // PR 56166: this should not throw.
       void
       clear() _GLIBCXX_NOEXCEPT
       { _M_mutate(0, this->size(), 0); }
 
       /**
        *  Returns true if the %string is empty.  Equivalent to 
        *  <code>*this == ""</code>.
        */
       bool
       empty() const _GLIBCXX_NOEXCEPT
@@ -816,21 +820,21 @@  _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 <= size());
 	return _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.
        *
@@ -896,37 +900,37 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        */
       reference
       front()
       { 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()
       { 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.
        */
       basic_string&
@@ -1780,20 +1784,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       size_type
       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.
       */
+      // PR 58265, this should be noexcept.
       void
       swap(basic_string& __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.
       */
Index: include/bits/stl_deque.h
===================================================================
--- include/bits/stl_deque.h	(revision 202764)
+++ include/bits/stl_deque.h	(working copy)
@@ -101,268 +101,269 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
    *  operator overloading in this class.
    *
    *  All the functions are op overloads except for _M_set_node.
   */
   template<typename _Tp, typename _Ref, typename _Ptr>
     struct _Deque_iterator
     {
       typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
       typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
 
-      static size_t _S_buffer_size()
+      static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT
       { return __deque_buf_size(sizeof(_Tp)); }
 
       typedef std::random_access_iterator_tag iterator_category;
       typedef _Tp                             value_type;
       typedef _Ptr                            pointer;
       typedef _Ref                            reference;
       typedef size_t                          size_type;
       typedef ptrdiff_t                       difference_type;
       typedef _Tp**                           _Map_pointer;
       typedef _Deque_iterator                 _Self;
 
       _Tp* _M_cur;
       _Tp* _M_first;
       _Tp* _M_last;
       _Map_pointer _M_node;
 
-      _Deque_iterator(_Tp* __x, _Map_pointer __y)
+      _Deque_iterator(_Tp* __x, _Map_pointer __y) _GLIBCXX_NOEXCEPT
       : _M_cur(__x), _M_first(*__y),
         _M_last(*__y + _S_buffer_size()), _M_node(__y) { }
 
-      _Deque_iterator()
+      _Deque_iterator() _GLIBCXX_NOEXCEPT
       : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) { }
 
-      _Deque_iterator(const iterator& __x)
+      _Deque_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT
       : _M_cur(__x._M_cur), _M_first(__x._M_first),
         _M_last(__x._M_last), _M_node(__x._M_node) { }
 
       iterator
-      _M_const_cast() const
+      _M_const_cast() const _GLIBCXX_NOEXCEPT
       { return iterator(_M_cur, _M_node); }
 
       reference
-      operator*() const
+      operator*() const _GLIBCXX_NOEXCEPT
       { return *_M_cur; }
 
       pointer
-      operator->() const
+      operator->() const _GLIBCXX_NOEXCEPT
       { return _M_cur; }
 
       _Self&
-      operator++()
+      operator++() _GLIBCXX_NOEXCEPT
       {
 	++_M_cur;
 	if (_M_cur == _M_last)
 	  {
 	    _M_set_node(_M_node + 1);
 	    _M_cur = _M_first;
 	  }
 	return *this;
       }
 
       _Self
-      operator++(int)
+      operator++(int) _GLIBCXX_NOEXCEPT
       {
 	_Self __tmp = *this;
 	++*this;
 	return __tmp;
       }
 
       _Self&
-      operator--()
+      operator--() _GLIBCXX_NOEXCEPT
       {
 	if (_M_cur == _M_first)
 	  {
 	    _M_set_node(_M_node - 1);
 	    _M_cur = _M_last;
 	  }
 	--_M_cur;
 	return *this;
       }
 
       _Self
-      operator--(int)
+      operator--(int) _GLIBCXX_NOEXCEPT
       {
 	_Self __tmp = *this;
 	--*this;
 	return __tmp;
       }
 
       _Self&
-      operator+=(difference_type __n)
+      operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
       {
 	const difference_type __offset = __n + (_M_cur - _M_first);
 	if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
 	  _M_cur += __n;
 	else
 	  {
 	    const difference_type __node_offset =
 	      __offset > 0 ? __offset / difference_type(_S_buffer_size())
 	                   : -difference_type((-__offset - 1)
 					      / _S_buffer_size()) - 1;
 	    _M_set_node(_M_node + __node_offset);
 	    _M_cur = _M_first + (__offset - __node_offset
 				 * difference_type(_S_buffer_size()));
 	  }
 	return *this;
       }
 
       _Self
-      operator+(difference_type __n) const
+      operator+(difference_type __n) const _GLIBCXX_NOEXCEPT
       {
 	_Self __tmp = *this;
 	return __tmp += __n;
       }
 
       _Self&
-      operator-=(difference_type __n)
+      operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
       { return *this += -__n; }
 
       _Self
-      operator-(difference_type __n) const
+      operator-(difference_type __n) const _GLIBCXX_NOEXCEPT
       {
 	_Self __tmp = *this;
 	return __tmp -= __n;
       }
 
       reference
-      operator[](difference_type __n) const
+      operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
       { return *(*this + __n); }
 
       /** 
        *  Prepares to traverse new_node.  Sets everything except
        *  _M_cur, which should therefore be set by the caller
        *  immediately afterwards, based on _M_first and _M_last.
        */
       void
-      _M_set_node(_Map_pointer __new_node)
+      _M_set_node(_Map_pointer __new_node) _GLIBCXX_NOEXCEPT
       {
 	_M_node = __new_node;
 	_M_first = *__new_node;
 	_M_last = _M_first + difference_type(_S_buffer_size());
       }
     };
 
   // Note: we also provide overloads whose operands are of the same type in
   // order to avoid ambiguous overload resolution when std::rel_ops operators
   // are in scope (for additional details, see libstdc++/3628)
   template<typename _Tp, typename _Ref, typename _Ptr>
     inline bool
     operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
     { return __x._M_cur == __y._M_cur; }
 
   template<typename _Tp, typename _RefL, typename _PtrL,
 	   typename _RefR, typename _PtrR>
     inline bool
     operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
     { return __x._M_cur == __y._M_cur; }
 
   template<typename _Tp, typename _Ref, typename _Ptr>
     inline bool
     operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
     { return !(__x == __y); }
 
   template<typename _Tp, typename _RefL, typename _PtrL,
 	   typename _RefR, typename _PtrR>
     inline bool
     operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
     { return !(__x == __y); }
 
   template<typename _Tp, typename _Ref, typename _Ptr>
     inline bool
     operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
     { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
                                           : (__x._M_node < __y._M_node); }
 
   template<typename _Tp, typename _RefL, typename _PtrL,
 	   typename _RefR, typename _PtrR>
     inline bool
     operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
     { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
 	                                  : (__x._M_node < __y._M_node); }
 
   template<typename _Tp, typename _Ref, typename _Ptr>
     inline bool
     operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
     { return __y < __x; }
 
   template<typename _Tp, typename _RefL, typename _PtrL,
 	   typename _RefR, typename _PtrR>
     inline bool
     operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
     { return __y < __x; }
 
   template<typename _Tp, typename _Ref, typename _Ptr>
     inline bool
     operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
     { return !(__y < __x); }
 
   template<typename _Tp, typename _RefL, typename _PtrL,
 	   typename _RefR, typename _PtrR>
     inline bool
     operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
     { return !(__y < __x); }
 
   template<typename _Tp, typename _Ref, typename _Ptr>
     inline bool
     operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
     { return !(__x < __y); }
 
   template<typename _Tp, typename _RefL, typename _PtrL,
 	   typename _RefR, typename _PtrR>
     inline bool
     operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
     { return !(__x < __y); }
 
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // According to the resolution of DR179 not only the various comparison
   // operators but also operator- must accept mixed iterator/const_iterator
   // parameters.
   template<typename _Tp, typename _Ref, typename _Ptr>
     inline typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type
     operator-(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
+	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
     {
       return typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type
 	(_Deque_iterator<_Tp, _Ref, _Ptr>::_S_buffer_size())
 	* (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first)
 	+ (__y._M_last - __y._M_cur);
     }
 
   template<typename _Tp, typename _RefL, typename _PtrL,
 	   typename _RefR, typename _PtrR>
     inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
     operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
     {
       return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
 	(_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size())
 	* (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first)
 	+ (__y._M_last - __y._M_cur);
     }
 
   template<typename _Tp, typename _Ref, typename _Ptr>
     inline _Deque_iterator<_Tp, _Ref, _Ptr>
     operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
+    _GLIBCXX_NOEXCEPT
     { return __x + __n; }
 
   template<typename _Tp>
     void
     fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>&,
 	 const _Deque_iterator<_Tp, _Tp&, _Tp*>&, const _Tp&);
 
   template<typename _Tp>
     _Deque_iterator<_Tp, _Tp&, _Tp*>
     copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>,
@@ -459,38 +460,38 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _Deque_base(size_t __num_elements)
       : _M_impl()
       { _M_initialize_map(__num_elements); }
 
       _Deque_base(const allocator_type& __a, size_t __num_elements)
       : _M_impl(__a)
       { _M_initialize_map(__num_elements); }
 
       _Deque_base(const allocator_type& __a)
       : _M_impl(__a)
-      { }
+      { _M_initialize_map(0); }
 
 #if __cplusplus >= 201103L
       _Deque_base(_Deque_base&& __x)
       : _M_impl(std::move(__x._M_get_Tp_allocator()))
       {
 	_M_initialize_map(0);
 	if (__x._M_impl._M_map)
 	  {
 	    std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
 	    std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
 	    std::swap(this->_M_impl._M_map, __x._M_impl._M_map);
 	    std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size);
 	  }
       }
 #endif
 
-      ~_Deque_base();
+      ~_Deque_base() _GLIBCXX_NOEXCEPT;
 
     protected:
       //This struct encapsulates the implementation of the std::deque
       //standard container and at the same time makes use of the EBO
       //for empty allocators.
       typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
 
       typedef typename _Alloc::template rebind<_Tp>::other  _Tp_alloc_type;
 
       struct _Deque_impl
@@ -499,27 +500,27 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	_Tp** _M_map;
 	size_t _M_map_size;
 	iterator _M_start;
 	iterator _M_finish;
 
 	_Deque_impl()
 	: _Tp_alloc_type(), _M_map(0), _M_map_size(0),
 	  _M_start(), _M_finish()
 	{ }
 
-	_Deque_impl(const _Tp_alloc_type& __a)
+	_Deque_impl(const _Tp_alloc_type& __a) _GLIBCXX_NOEXCEPT
 	: _Tp_alloc_type(__a), _M_map(0), _M_map_size(0),
 	  _M_start(), _M_finish()
 	{ }
 
 #if __cplusplus >= 201103L
-	_Deque_impl(_Tp_alloc_type&& __a)
+	_Deque_impl(_Tp_alloc_type&& __a) _GLIBCXX_NOEXCEPT
 	: _Tp_alloc_type(std::move(__a)), _M_map(0), _M_map_size(0),
 	  _M_start(), _M_finish()
 	{ }
 #endif
       };
 
       _Tp_alloc_type&
       _M_get_Tp_allocator() _GLIBCXX_NOEXCEPT
       { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); }
 
@@ -531,45 +532,45 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _M_get_map_allocator() const _GLIBCXX_NOEXCEPT
       { return _Map_alloc_type(_M_get_Tp_allocator()); }
 
       _Tp*
       _M_allocate_node()
       { 
 	return _M_impl._Tp_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
       }
 
       void
-      _M_deallocate_node(_Tp* __p)
+      _M_deallocate_node(_Tp* __p) _GLIBCXX_NOEXCEPT
       {
 	_M_impl._Tp_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
       }
 
       _Tp**
       _M_allocate_map(size_t __n)
       { return _M_get_map_allocator().allocate(__n); }
 
       void
-      _M_deallocate_map(_Tp** __p, size_t __n)
+      _M_deallocate_map(_Tp** __p, size_t __n) _GLIBCXX_NOEXCEPT
       { _M_get_map_allocator().deallocate(__p, __n); }
 
     protected:
       void _M_initialize_map(size_t);
       void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
-      void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
+      void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) _GLIBCXX_NOEXCEPT;
       enum { _S_initial_map_size = 8 };
 
       _Deque_impl _M_impl;
     };
 
   template<typename _Tp, typename _Alloc>
     _Deque_base<_Tp, _Alloc>::
-    ~_Deque_base()
+    ~_Deque_base() _GLIBCXX_NOEXCEPT
     {
       if (this->_M_impl._M_map)
 	{
 	  _M_destroy_nodes(this->_M_impl._M_start._M_node,
 			   this->_M_impl._M_finish._M_node + 1);
 	  _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
 	}
     }
 
   /**
@@ -633,21 +634,21 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       __catch(...)
 	{
 	  _M_destroy_nodes(__nstart, __cur);
 	  __throw_exception_again;
 	}
     }
 
   template<typename _Tp, typename _Alloc>
     void
     _Deque_base<_Tp, _Alloc>::
-    _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
+    _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) _GLIBCXX_NOEXCEPT
     {
       for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
 	_M_deallocate_node(*__n);
     }
 
   /**
    *  @brief  A standard container using fixed-size memory allocation and
    *  constant-time manipulation of elements at either end.
    *
    *  @ingroup sequences
@@ -751,21 +752,21 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       typedef typename _Base::const_iterator             const_iterator;
       typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
       typedef std::reverse_iterator<iterator>            reverse_iterator;
       typedef size_t                             size_type;
       typedef ptrdiff_t                          difference_type;
       typedef _Alloc                             allocator_type;
 
     protected:
       typedef pointer*                           _Map_pointer;
 
-      static size_t _S_buffer_size()
+      static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT
       { return __deque_buf_size(sizeof(_Tp)); }
 
       // Functions controlling memory layout, and nothing else.
       using _Base::_M_initialize_map;
       using _Base::_M_create_nodes;
       using _Base::_M_destroy_nodes;
       using _Base::_M_allocate_node;
       using _Base::_M_deallocate_node;
       using _Base::_M_allocate_map;
       using _Base::_M_deallocate_map;
@@ -774,32 +775,26 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /** 
        *  A total of four data members accumulated down the hierarchy.
        *  May be accessed via _M_impl.*
        */
       using _Base::_M_impl;
 
     public:
       // [23.2.1.1] construct/copy/destroy
       // (assign() and get_allocator() are also listed in this section)
       /**
-       *  @brief  Default constructor creates no elements.
-       */
-      deque()
-      : _Base() { }
-
-      /**
        *  @brief  Creates a %deque with no elements.
        *  @param  __a  An allocator object.
        */
       explicit
-      deque(const allocator_type& __a)
-      : _Base(__a, 0) { }
+      deque(const allocator_type& __a = allocator_type())
+      : _Base(__a) { }
 
 #if __cplusplus >= 201103L
       /**
        *  @brief  Creates a %deque with default constructed elements.
        *  @param  __n  The number of elements to initially create.
        *
        *  This constructor fills the %deque with @a n default
        *  constructed elements.
        */
       explicit
@@ -933,21 +928,21 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
 #if __cplusplus >= 201103L
       /**
        *  @brief  %Deque move assignment operator.
        *  @param  __x  A %deque of identical element and allocator types.
        *
        *  The contents of @a __x are moved into this deque (without copying).
        *  @a __x is a valid, but unspecified %deque.
        */
       deque&
-      operator=(deque&& __x)
+      operator=(deque&& __x) noexcept
       {
 	// NB: DR 1204.
 	// NB: DR 675.
 	this->clear();
 	this->swap(__x);
 	return *this;
       }
 
       /**
        *  @brief  Assigns an initializer list to a %deque.
@@ -1213,21 +1208,21 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  insert(this->_M_impl._M_finish, __new_size - __len, __x);
 	else if (__new_size < __len)
 	  _M_erase_at_end(this->_M_impl._M_start
 			  + difference_type(__new_size));
       }
 #endif
 
 #if __cplusplus >= 201103L
       /**  A non-binding request to reduce memory use.  */
       void
-      shrink_to_fit()
+      shrink_to_fit() noexcept
       { _M_shrink_to_fit(); }
 #endif
 
       /**
        *  Returns true if the %deque is empty.  (Thus begin() would
        *  equal end().)
        */
       bool
       empty() const _GLIBCXX_NOEXCEPT
       { return this->_M_impl._M_finish == this->_M_impl._M_start; }
@@ -1238,36 +1233,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[difference_type(__n)]; }
 
       /**
        *  @brief Subscript access to the data contained in the %deque.
        *  @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[difference_type(__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("deque::_M_range_check"));
       }
@@ -1307,49 +1302,49 @@  _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 %deque.
        */
       reference
-      front()
+      front() _GLIBCXX_NOEXCEPT
       { return *begin(); }
 
       /**
        *  Returns a read-only (constant) reference to the data at the first
        *  element of the %deque.
        */
       const_reference
-      front() const
+      front() const _GLIBCXX_NOEXCEPT
       { return *begin(); }
 
       /**
        *  Returns a read/write reference to the data at the last element of the
        *  %deque.
        */
       reference
-      back()
+      back() _GLIBCXX_NOEXCEPT
       {
 	iterator __tmp = end();
 	--__tmp;
 	return *__tmp;
       }
 
       /**
        *  Returns a read-only (constant) reference to the data at the last
        *  element of the %deque.
        */
       const_reference
-      back() const
+      back() const _GLIBCXX_NOEXCEPT
       {
 	const_iterator __tmp = end();
 	--__tmp;
 	return *__tmp;
       }
 
       // [23.2.1.2] modifiers
       /**
        *  @brief  Add data to the front of the %deque.
        *  @param  __x  Data to be added.
@@ -1415,42 +1410,42 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       /**
        *  @brief  Removes first element.
        *
        *  This is a typical stack operation.  It shrinks the %deque by one.
        *
        *  Note that no data is returned, and if the first element's data is
        *  needed, it should be retrieved before pop_front() is called.
        */
       void
-      pop_front()
+      pop_front() _GLIBCXX_NOEXCEPT
       {
 	if (this->_M_impl._M_start._M_cur
 	    != this->_M_impl._M_start._M_last - 1)
 	  {
 	    this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
 	    ++this->_M_impl._M_start._M_cur;
 	  }
 	else
 	  _M_pop_front_aux();
       }
 
       /**
        *  @brief  Removes last element.
        *
        *  This is a typical stack operation.  It shrinks the %deque 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
       {
 	if (this->_M_impl._M_finish._M_cur
 	    != this->_M_impl._M_finish._M_first)
 	  {
 	    --this->_M_impl._M_finish._M_cur;
 	    this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
 	  }
 	else
 	  _M_pop_back_aux();
       }
@@ -1648,21 +1643,21 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /**
        *  @brief  Swaps data with another %deque.
        *  @param  __x  A %deque of the same element and allocator types.
        *
        *  This exchanges the elements between two deques in constant time.
        *  (Four pointers, so it should be quite fast.)
        *  Note that the global std::swap() function is specialized such that
        *  std::swap(d1,d2) will feed to this function.
        */
       void
-      swap(deque& __x)
+      swap(deque& __x) _GLIBCXX_NOEXCEPT
       {
 	std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
 	std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
 	std::swap(this->_M_impl._M_map, __x._M_impl._M_map);
 	std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size);
 
 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
 	// 431. Swapping containers with unequal allocators.
 	std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(),
 						    __x._M_get_Tp_allocator());
Index: include/debug/deque
===================================================================
--- include/debug/deque	(revision 202764)
+++ include/debug/deque	(working copy)
@@ -121,21 +121,21 @@  namespace __debug
       deque&
       operator=(const deque& __x)
       {
 	*static_cast<_Base*>(this) = __x;
 	this->_M_invalidate_all();
 	return *this;
       }
 
 #if __cplusplus >= 201103L
       deque&
-      operator=(deque&& __x)
+      operator=(deque&& __x) noexcept
       {
 	// NB: DR 1204.
 	// NB: DR 675.
 	__glibcxx_check_self_move_assign(__x);
 	clear();
 	swap(__x);
 	return *this;
       }
 
       deque&
@@ -280,69 +280,69 @@  namespace __debug
 
 	_Base::resize(__sz, __c);
 
 	if (__invalidate_all)
 	  this->_M_invalidate_all();
       }
 #endif
 
 #if __cplusplus >= 201103L
       void
-      shrink_to_fit()
+      shrink_to_fit() noexcept
       {
 	if (_Base::_M_shrink_to_fit())
 	  this->_M_invalidate_all();
       }
 #endif
 
       using _Base::empty;
 
       // 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();
       }
 
       // 23.2.1.3 modifiers:
       void
       push_front(const _Tp& __x)
       {
 	_Base::push_front(__x);
@@ -461,29 +461,29 @@  namespace __debug
 	       _InputIterator __first, _InputIterator __last)
         {
 	  __glibcxx_check_insert_range(__position, __first, __last);
 	  _Base::insert(__position.base(), __gnu_debug::__base(__first),
 					   __gnu_debug::__base(__last));
 	  this->_M_invalidate_all();
 	}
 #endif
 
       void
-      pop_front()
+      pop_front() _GLIBCXX_NOEXCEPT
       {
 	__glibcxx_check_nonempty();
 	this->_M_invalidate_if(_Equal(_Base::begin()));
 	_Base::pop_front();
       }
 
       void
-      pop_back()
+      pop_back() _GLIBCXX_NOEXCEPT
       {
 	__glibcxx_check_nonempty();
 	this->_M_invalidate_if(_Equal(--_Base::end()));
 	_Base::pop_back();
       }
 
       iterator
 #if __cplusplus >= 201103L
       erase(const_iterator __position)
 #else
@@ -549,21 +549,21 @@  namespace __debug
 	else
 	  {
 	    _Base_iterator __res = _Base::erase(__first.base(),
 						__last.base());
 	    this->_M_invalidate_all();
 	    return iterator(__res, this);
 	  }
       }
 
       void
-      swap(deque& __x)
+      swap(deque& __x) _GLIBCXX_NOEXCEPT
       {
 	_Base::swap(__x);
 	this->_M_swap(__x);
       }
 
       void
       clear() _GLIBCXX_NOEXCEPT
       {
 	_Base::clear();
 	this->_M_invalidate_all();
Index: include/profile/deque
===================================================================
--- include/profile/deque	(revision 202764)
+++ include/profile/deque	(working copy)
@@ -110,21 +110,21 @@  namespace __profile
 
       deque&
       operator=(const deque& __x)
       {
 	*static_cast<_Base*>(this) = __x;
 	return *this;
       }
 
 #if __cplusplus >= 201103L
       deque&
-      operator=(deque&& __x)
+      operator=(deque&& __x) noexcept
       {
 	// NB: DR 1204.
 	// NB: DR 675.
 	this->clear();
 	this->swap(__x);
 	return *this;
       }
 
       deque&
       operator=(initializer_list<value_type> __l)
@@ -238,53 +238,53 @@  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
       {
 	return _M_base()[__n];
       }
 
       const_reference
-      operator[](size_type __n) const
+      operator[](size_type __n) const _GLIBCXX_NOEXCEPT
       {
 	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();
       }
 
       // 23.2.1.3 modifiers:
       void
       push_front(const _Tp& __x)
       {
 	_Base::push_front(__x);
       }
@@ -368,27 +368,27 @@  namespace __profile
         { return _Base::insert(__position, __first, __last); }
 #else
       template<typename _InputIterator>
         void
         insert(iterator __position,
 	       _InputIterator __first, _InputIterator __last)
         { _Base::insert(__position, __first, __last); }
 #endif
 
       void
-      pop_front()
+      pop_front() _GLIBCXX_NOEXCEPT
       {
 	_Base::pop_front();
       }
 
       void
-      pop_back()
+      pop_back() _GLIBCXX_NOEXCEPT
       {
 	_Base::pop_back();
       }
 
       iterator
 #if __cplusplus >= 201103L
       erase(const_iterator __position)
 #else
       erase(iterator __position)	
 #endif
@@ -402,21 +402,21 @@  namespace __profile
 #else
       erase(iterator __first, iterator __last)
 #endif
       {
 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
 	// 151. can't currently clear() empty container
         return _Base::erase(__first, __last);
       }
 
       void
-      swap(deque& __x)
+      swap(deque& __x) _GLIBCXX_NOEXCEPT
       {
 	_Base::swap(__x);
       }
 
       void
       clear() _GLIBCXX_NOEXCEPT
       {
 	_Base::clear();
       }
 
Index: testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
===================================================================
--- testsuite/23_containers/deque/requirements/dr438/assign_neg.cc	(revision 202764)
+++ testsuite/23_containers/deque/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 *-*-* } 1760 }
+// { dg-error "no matching" "" { target *-*-* } 1755 }
 
 #include <deque>
 
 struct A
 {
   explicit A(int) { }
 };
 
 void f()
 {
Index: testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
===================================================================
--- testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc	(revision 202764)
+++ testsuite/23_containers/deque/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 *-*-* } 1693 }
+// { dg-error "no matching" "" { target *-*-* } 1688 }
 
 #include <deque>
 
 void f()
 {
   std::deque<std::deque<int> > d(10, 1);
 }
Index: testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
===================================================================
--- testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc	(revision 202764)
+++ testsuite/23_containers/deque/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 *-*-* } 1693 }
+// { dg-error "no matching" "" { target *-*-* } 1688 }
 
 #include <deque>
 #include <utility>
 
 void f()
 {
   std::deque<std::deque<std::pair<char, char> > > d('a', 'b');
 }
Index: testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
===================================================================
--- testsuite/23_containers/deque/requirements/dr438/insert_neg.cc	(revision 202764)
+++ testsuite/23_containers/deque/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 *-*-* } 1844 }
+// { dg-error "no matching" "" { target *-*-* } 1839 }
 
 #include <deque>
 
 struct A
 {
   explicit A(int) { }
 };
 
 void f()
 {