This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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]

Re: debug container patch


On 27/04/2014 15:39, Jonathan Wakely wrote:
On 17/04/14 22:43 +0200, François Dumont wrote:
Hi

   Here is a patch to globally enhance debug containers implementation.

François, sorry for the delay, this is a large patch and I wanted to
give it the time it deserves to review properly.

No problem, I see that there are a lot of proposals lately.


I understand why this is needed, but it changes the layout of the
classes in very significant ways, meaning the debug containers will
not be compatible across GCC releases. I'm OK with that now, but from
the next major GCC release I'd like to avoid that in future.

I remember Paolo saying that there is no abi guaranty for debug mode this is why I didn't hesitate in making this proposal. Will there be one in the future ? I plan also breaking changes for profile mode to fix its very bad performance.


I noticed also that in std/c++11/debug.cc we have some methods qualified with noexcept while in a C++03 user code those methods will have a throw() qualification. Is that fine ?

As I said in my last mail, yes, those specifications are compatible.
But I don't think your changes are doing what you think they are doing
in all cases. Using _GLIBCXX_NOEXCEPT does not expand to throw() in
C++03 mode, it expands to nothing.

Yes, I discover this difference in one of your recent mail.


   * include/debug/safe_unordered_container.tcc

N.B. This file has no changes listed in the changelog entry.

I reviewed the ChangeLog and limit modifications like in this file. Note however that patch have been generated with '-x -b' option to hide white space modifications. I clean usage of white chars in impacted files, replaced some white spaces with tabs and remove useless white spaces.


@@ -69,8 +75,26 @@

      // 23.2.1.1 construct/copy/destroy:

-      deque() : _Base() { }
+#if __cplusplus < 201103L
+      deque()
+      : _Base() { }

+      deque(const deque& __x)
+      : _Base(__x) { }
+
+      ~deque() _GLIBCXX_NOEXCEPT { }

In C++03 mode the _GLIBCXX_NOEXCEPT macro expands to an empty string,
so it is useless in this chunk of code, which is only compiled for
C++03 mode. It should probably just be removed here (and in all the
other debug containers which use it in C++03-only code).

Ok, I cleaned those. Did you mean removing the whole explicit destructor ? Is it a coding Standard to always explicitly implement the destructor or just a way to have Doxygen generate ?

+ * before-begin ownership.*/
+   template<typename _SafeSequence>
+    void
+    _Safe_forward_list<_SafeSequence>::
+    _M_swap(_Safe_sequence_base& __other) noexcept
+    {
+      __gnu_cxx::__scoped_lock sentry(_M_this()._M_get_mutex());

Shouldn't we be locking both containers' mutexes here?
As we do in src/c++11/debug.cc

Good point, not a regression but nice to fix in this patch.


+      forward_list(forward_list&& __list, const allocator_type& __al)
+    : _Safe(std::move(__list), __al),
+      _Base(std::move(__list), __al)
+      { }

This makes me feel uneasy, seeing a moved-from object being used
again, but I don't think changing it to use static_casts to the two
base classes would look better, so let's leave it like that.

That indeed looks scary, we replaced with:

      forward_list(forward_list&& __list, const allocator_type& __al)
    : _Safe(std::move(__list._M_safe()), __al),
      _Base(std::move(__list._M_base()), __al)
      { }

it makes clearer the fact that we move each part.


Index: include/debug/safe_base.h
===================================================================
--- include/debug/safe_base.h    (revision 209446)
+++ include/debug/safe_base.h    (working copy)
@@ -188,22 +188,18 @@

  protected:
    // Initialize with a version number of 1 and no iterators
-    _Safe_sequence_base()
+    _Safe_sequence_base() _GLIBCXX_NOEXCEPT

This use of _GLIBCXX_NOEXCEPT are correct, if the intention is to be
noexcept in C++11 and have no exception specification in C++98/C++03.

Yes, I preferred to use default implementation for special function in C++11 so I qualified as many things as possible noexcept so that resulting noexcept qualification depends only on the normal mode noexcept qualification.


    : _M_iterators(0), _M_const_iterators(0), _M_version(1)
    { }

#if __cplusplus >= 201103L
    _Safe_sequence_base(const _Safe_sequence_base&) noexcept
      : _Safe_sequence_base() { }
-
-    _Safe_sequence_base(_Safe_sequence_base&& __x) noexcept
-      : _Safe_sequence_base()
-    { _M_swap(__x); }
#endif

    /** Notify all iterators that reference this sequence that the
    sequence is being destroyed. */
-    ~_Safe_sequence_base()
+    ~_Safe_sequence_base() _GLIBCXX_NOEXCEPT

This is redundant. In C++03 the macro expands to nothing, and in C++11
destructors are noexcept by default anyway, so the macro adds nothing.

Ok, I didn't knew, I cleaned those then.


    { this->_M_detach_all(); }

    /** Detach all iterators, leaving them singular. */
@@ -231,7 +227,7 @@
     *  one container now reference the other container.
     */
    void
-    _M_swap(_Safe_sequence_base& __x);
+    _M_swap(_Safe_sequence_base& __x) _GLIBCXX_NOEXCEPT;

This is OK, if the intention is to only have an exc eption spec in
C++11.

This is used in noexcept constructors so I prefer to make it noexcept too.

I replaced this one with _GLIBCXX_USE_NOEXCEPT cause in src/c++11/debug.cc we always build it as noexcept, just in case it impacts the mangled name. I saw _GLIBCXX_NOTHROW in c++config but doesn't seem to be used.



+#if __cplusplus >= 201103L
+      _Safe_container&
+      operator=(_Safe_container&& __x) noexcept
+      {
+    __glibcxx_check_self_move_assign(__x);

N.B. I'm writing a paper for the next committee meeting to make it
clear that self-move-assignment is not undefined behaviour, so this
check will have to be removed in the future. At least your change
means there are fewer places to remove it from :-)
See http://gcc.gnu.org/PR59603 for some background.

I only looked over the testsuite changes quickly, but they look good.

The changes above are only minor, overall I like the proposal very
much. Thanks for working on this, one day our debug mode containers
will be perfect! :-)


Not yet, I will start submitting patches for the debug algos soon :-)

Here is the patch again with all your remarks. Ok to commit with the following ChangeLog ?

2014-04-29  François Dumont <fdumont@gcc.gnu.org>

    * include/debug/macros.h [__glibcxx_check_equal_allocs]: Add
    parameter to pass the 2 instances to check allocator equality.
    * include/debug/safe_container.h: New, define _Safe_container<>.
    * include/Makefile.am: Add previous.
    * include/debug/deque (std::__debug::deque<>): Inherit
    _Safe_container<>. Use default implementation for all special
    functions.
    * include/debug/forward_list (std::__debug::forward_list<>):
    Likewise.
    * include/debug/list (std::__debug::list<>): Likewise.
    * include/debug/map.h (std::__debug::map<>): Likewise.
    * include/debug/multimap.h (std::__debug::multimap<>): Likewise.
    * include/debug/set.h (std::__debug::set<>): Likewise.
    * include/debug/multiset.h (std::__debug::multiset<>): Likewise.
    * include/debug/string (std::__debug::basic_string<>): Likewise.
    * include/debug/unordered_map
    (std::__debug::unordered_map<>): Likewise.
    (std::__debug::unordered_multimap<>): Likewise.
    * include/debug/unordered_set
    (std::__debug::unordered_set<>): Likewise.
    (std::__debug::unordered_multiset<>): Likewise.
    * include/debug/vector (std::__debug::vector<>): Likewise.
    * include/debug/safe_base.h (_Safe_sequence_base()): Add
    noexcept.
    (_Safe_sequence_base(_Safe_sequence_base&&): Remove.
    (~_Safe_sequence_base()): Add noexcept.
    * include/debug/safe_sequence.h
    (std::__debug::_Safe_node_sequence<>): New.
    * include/debug/safe_unordered_base.h
    (_Safe_unordered_container_base()): Add noexcept.
    (~_Safe_unordered_container_base()): Likewise.
    (_M_swap(_Safe_unordered_container_base&)): Likewise.
    * include/debug/safe_unordered_container.h:
    (_Safe_unordered_container<>::_M_invalidate_locals()): New.
    (_Safe_unordered_container<>::_M_invalidate_all()): New.
    * src/c++11/debug.cc: Limit includes, adapt methods noexcept
    qualifications.
    * testsuite/util/debug/checks.h (check_construct1): Just implement
    an invalid constructor invocation  and no other operations
    potentially not supported by some types of container.
    (check_construct2): Likewise.
    (check_construct3): Likewise.
    * testsuite/23_containers/forward_list/allocator/move.cc: Add
    check on iterators to make sure they are correctly moved in debug
    mode.
    * testsuite/23_containers/forward_list/allocator/move_assign.cc:
    Likewise.
    * testsuite/23_containers/map/allocator/move.cc: Likewise.
    * testsuite/23_containers/map/allocator/move_assign.cc: Likewise.
    * testsuite/23_containers/multimap/allocator/move.cc: Likewise.
    * testsuite/23_containers/multimap/allocator/move_assign.cc:
    Likewise.
    * testsuite/23_containers/multiset/allocator/move.cc: Likewise.
    * testsuite/23_containers/multiset/allocator/move_assign.cc:
    Likewise.
    * testsuite/23_containers/set/allocator/move.cc: Likewise.
    * testsuite/23_containers/set/allocator/move_assign.cc: Likewise.
    * testsuite/23_containers/unordered_map/allocator/move.cc:
    Likewise.
    * testsuite/23_containers/unordered_map/allocator/move_assign.cc:
    Likewise.
    * testsuite/23_containers/unordered_multimap/allocator/move.cc:
    Likewise.
    * testsuite/23_containers/unordered_multimap/allocator/move_assign.cc:
    Likewise.
    * testsuite/23_containers/unordered_multiset/allocator/move.cc:
    Likewise.
    * testsuite/23_containers/unordered_multiset/allocator/move_assign.cc:
    Likewise.
    * testsuite/23_containers/unordered_set/allocator/move.cc:
    Likewise.
    * testsuite/23_containers/unordered_set/allocator/move_assign.cc:
    Likewise.
    * testsuite/23_containers/forward_list/debug/construct1_neg.cc:
    New.
    * testsuite/23_containers/forward_list/debug/construct2_neg.cc:
    New.
    * testsuite/23_containers/forward_list/debug/construct3_neg.cc:
    New.
    * testsuite/23_containers/forward_list/debug/construct4_neg.cc:
    New.
    * testsuite/23_containers/forward_list/debug/move_assign_neg.cc:
    New.
    * testsuite/23_containers/forward_list/debug/move_neg.cc: New.
    * testsuite/23_containers/map/debug/construct5_neg.cc: New.
    * testsuite/23_containers/map/debug/move_assign_neg.cc: New.
    * testsuite/23_containers/map/debug/move_neg.cc: New.
    * testsuite/23_containers/multimap/debug/construct5_neg.cc: New.
    * testsuite/23_containers/multimap/debug/move_assign_neg.cc: New.
    * testsuite/23_containers/multimap/debug/move_neg.cc: New.
    * testsuite/23_containers/multiset/debug/construct5_neg.cc: New.
    * testsuite/23_containers/multiset/debug/move_assign_neg.cc: New.
    * testsuite/23_containers/multiset/debug/move_neg.cc: New.
    * testsuite/23_containers/set/debug/construct5_neg.cc: New.
    * testsuite/23_containers/set/debug/move_assign_neg.cc: New.
    * testsuite/23_containers/set/debug/move_neg.cc: New.
    * testsuite/23_containers/unordered_map/debug/construct5_neg.cc:
    New.
    * testsuite/23_containers/unordered_map/debug/move_assign_neg.cc:
    New.
    * testsuite/23_containers/unordered_map/debug/move_neg.cc: New.
    * testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc:
    New.
    * testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc:
    New.
    * testsuite/23_containers/unordered_multimap/debug/move_neg.cc:
    New.
    * testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc:
    New.
    * testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc:
    New.
    * testsuite/23_containers/unordered_multiset/debug/move_neg.cc:
    New.
    * testsuite/23_containers/unordered_set/debug/construct5_neg.cc:
    New.
    * testsuite/23_containers/unordered_set/debug/move_assign_neg.cc:
    New.
    * testsuite/23_containers/unordered_set/debug/move_neg.cc: New.
    * testsuite/23_containers/vector/debug/move_neg.cc: New.


François

Index: include/Makefile.am
===================================================================
--- include/Makefile.am	(revision 209879)
+++ include/Makefile.am	(working copy)
@@ -733,6 +733,7 @@
 	${debug_srcdir}/multimap.h \
 	${debug_srcdir}/multiset.h \
 	${debug_srcdir}/safe_base.h \
+	${debug_srcdir}/safe_container.h \
 	${debug_srcdir}/safe_iterator.h \
 	${debug_srcdir}/safe_iterator.tcc \
 	${debug_srcdir}/safe_local_iterator.h \
Index: include/debug/deque
===================================================================
--- include/debug/deque	(revision 209879)
+++ include/debug/deque	(working copy)
@@ -31,6 +31,7 @@
 
 #include <deque>
 #include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -40,21 +41,26 @@
   /// Class std::deque with safety/checking/debug instrumentation.
   template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
     class deque
-    : public _GLIBCXX_STD_C::deque<_Tp, _Allocator>,
-      public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
+    : public __gnu_debug::_Safe_container<
+	deque<_Tp, _Allocator>, _Allocator,
+	__gnu_debug::_Safe_sequence, false>,
+      public _GLIBCXX_STD_C::deque<_Tp, _Allocator>
     {
       typedef  _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_container<
+	deque, _Allocator, __gnu_debug::_Safe_sequence, false>	_Safe;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
+
     public:
       typedef typename _Base::reference             reference;
       typedef typename _Base::const_reference       const_reference;
 
-      typedef __gnu_debug::_Safe_iterator<_Base_iterator,deque>
+      typedef __gnu_debug::_Safe_iterator<_Base_iterator, deque>
 						    iterator;
-      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,deque>
+      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, deque>
 						    const_iterator;
 
       typedef typename _Base::size_type             size_type;
@@ -69,8 +75,26 @@
 
       // 23.2.1.1 construct/copy/destroy:
 
-      deque() : _Base() { }
+#if __cplusplus < 201103L
+      deque()
+      : _Base() { }
 
+      deque(const deque& __x)
+      : _Base(__x) { }
+
+      ~deque() { }
+#else
+      deque() = default;
+      deque(const deque&) = default;
+      deque(deque&&) = default;
+
+      deque(initializer_list<value_type> __l,
+	    const allocator_type& __a = allocator_type())
+      : _Base(__l, __a) { }
+
+      ~deque() = default;
+#endif
+
       explicit
       deque(const _Allocator& __a)
       : _Base(__a) { }
@@ -103,48 +127,28 @@
 		__gnu_debug::__base(__last), __a)
         { }
 
-      deque(const deque& __x)
-      : _Base(__x) { }
-
       deque(const _Base& __x)
       : _Base(__x) { }
 
-#if __cplusplus >= 201103L
-      deque(deque&& __x)
-      : _Base(std::move(__x))
-      { this->_M_swap(__x); }
-
-      deque(initializer_list<value_type> __l,
-	    const allocator_type& __a = allocator_type())
-      : _Base(__l, __a) { }
-#endif
-
-      ~deque() _GLIBCXX_NOEXCEPT { }
-
+#if __cplusplus < 201103L
       deque&
       operator=(const deque& __x)
       {
-	*static_cast<_Base*>(this) = __x;
-	this->_M_invalidate_all();
+	this->_M_safe() = __x;
+	_M_base() = __x;
 	return *this;
       }
+#else
+      deque&
+      operator=(const deque&) = default;
 
-#if __cplusplus >= 201103L
       deque&
-      operator=(deque&& __x) noexcept
-      {
-	// NB: DR 1204.
-	// NB: DR 675.
-	__glibcxx_check_self_move_assign(__x);
-	clear();
-	swap(__x);
-	return *this;
-      }
+      operator=(deque&&) = default;
 
       deque&
       operator=(initializer_list<value_type> __l)
       {
-	*static_cast<_Base*>(this) = __l;
+	_M_base() = __l;
 	this->_M_invalidate_all();
 	return *this;
       }
@@ -241,7 +245,7 @@
 	typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
 	this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
       }
-      
+
     public:
       // 23.2.1.2 capacity:
       using _Base::size;
@@ -559,10 +563,13 @@
       }
 
       void
-      swap(deque& __x) _GLIBCXX_NOEXCEPT
+      swap(deque& __x)
+#if __cplusplus >= 201103L
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
+#endif
       {
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	this->_M_swap(__x);
       }
 
       void
Index: include/debug/forward_list
===================================================================
--- include/debug/forward_list	(revision 209879)
+++ include/debug/forward_list	(working copy)
@@ -33,8 +33,138 @@
 
 #include <forward_list>
 #include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 
+namespace __gnu_debug
+{
+  /// Special iterators swap and invalidation for forward_list because of the
+  /// before_begin iterator.
+  template<typename _SafeSequence>
+    class _Safe_forward_list
+    : public _Safe_sequence<_SafeSequence>
+    {
+      _SafeSequence&
+      _M_this() noexcept
+      { return *static_cast<_SafeSequence*>(this); }
+
+      static void
+      _M_swap_aux(_Safe_sequence_base& __lhs,
+		  _Safe_iterator_base*& __lhs_iterators,
+		  _Safe_sequence_base& __rhs,
+		  _Safe_iterator_base*& __rhs_iterators);
+
+      void _M_swap_single(_Safe_sequence_base&) noexcept;
+
+    protected:
+      void
+      _M_invalidate_all()
+      {
+	using _Base_const_iterator = __decltype(_M_this()._M_base().cend());
+	this->_M_invalidate_if([this](_Base_const_iterator __it)
+	{
+	  return __it != _M_this()._M_base().cbefore_begin()
+	    && __it != _M_this()._M_base().cend(); });
+      }
+
+      void _M_swap(_Safe_sequence_base&) noexcept;
+    };
+
+   template<typename _SafeSequence>
+    void
+    _Safe_forward_list<_SafeSequence>::
+    _M_swap_aux(_Safe_sequence_base& __lhs,
+		_Safe_iterator_base*& __lhs_iterators,
+		_Safe_sequence_base& __rhs,
+		_Safe_iterator_base*& __rhs_iterators)
+    {
+      using const_iterator = typename _SafeSequence::const_iterator;
+      _Safe_iterator_base* __bbegin_its = 0;
+      _Safe_iterator_base* __last_bbegin = 0;
+      _SafeSequence& __rseq = static_cast<_SafeSequence&>(__rhs);
+
+      for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;)
+	{
+	  // Even iterator is cast to const_iterator, not a problem.
+	  const_iterator* __victim = static_cast<const_iterator*>(__iter);
+	  __iter = __iter->_M_next;
+	  if (__victim->base() == __rseq._M_base().cbefore_begin())
+	    {
+	      __victim->_M_unlink();
+	      if (__lhs_iterators == __victim)
+		__lhs_iterators = __victim->_M_next;
+	      if (__bbegin_its)
+		{
+		  __victim->_M_next = __bbegin_its;
+		  __bbegin_its->_M_prior = __victim;
+		}
+	      else
+		__last_bbegin = __victim;
+	      __bbegin_its = __victim;
+	    }
+	  else
+	    __victim->_M_sequence = &__lhs;
+	}
+
+      if (__bbegin_its)
+	{
+	  if (__rhs_iterators)
+	    {
+	      __rhs_iterators->_M_prior = __last_bbegin;
+	      __last_bbegin->_M_next = __rhs_iterators;
+	    }
+	  __rhs_iterators = __bbegin_its;
+	}
+    }
+
+   template<typename _SafeSequence>
+    void
+    _Safe_forward_list<_SafeSequence>::
+    _M_swap_single(_Safe_sequence_base& __other) noexcept
+    {
+      std::swap(_M_this()._M_iterators, __other._M_iterators);
+      std::swap(_M_this()._M_const_iterators, __other._M_const_iterators);
+      // Useless, always 1 on forward_list
+      //std::swap(_M_this()_M_version, __other._M_version);
+      _Safe_iterator_base* __this_its = _M_this()._M_iterators;
+      _M_swap_aux(__other, __other._M_iterators,
+		  _M_this(), _M_this()._M_iterators);
+      _Safe_iterator_base* __this_const_its = _M_this()._M_const_iterators;
+      _M_swap_aux(__other, __other._M_const_iterators,
+		  _M_this(), _M_this()._M_const_iterators);
+      _M_swap_aux(_M_this(), __this_its,
+		  __other, __other._M_iterators);
+      _M_swap_aux(_M_this(), __this_const_its,
+		  __other, __other._M_const_iterators);
+    }
+
+  /* Special forward_list _M_swap version that does not swap the
+   * before-begin ownership.*/
+   template<typename _SafeSequence>
+    void
+    _Safe_forward_list<_SafeSequence>::
+    _M_swap(_Safe_sequence_base& __other) noexcept
+    {
+      // We need to lock both sequences to swap
+      using namespace __gnu_cxx;
+      __mutex *__this_mutex = &_M_this()._M_get_mutex();
+      __mutex *__other_mutex = &__other._M_get_mutex();
+      if (__this_mutex == __other_mutex)
+	{
+	  __scoped_lock __lock(*__this_mutex);
+	  _M_swap_single(__other);
+	}
+      else
+	{
+	  __scoped_lock __l1(__this_mutex < __other_mutex
+			     ? *__this_mutex : *__other_mutex);
+	  __scoped_lock __l2(__this_mutex < __other_mutex
+			     ? *__other_mutex : *__this_mutex);
+	  _M_swap_single(__other);
+	}
+    }
+}
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 namespace __debug
@@ -42,119 +172,88 @@
   /// Class std::forward_list with safety/checking/debug instrumentation.
   template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
     class forward_list
-    : public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>,
-      public __gnu_debug::_Safe_sequence<forward_list<_Tp, _Alloc> >
+    : public __gnu_debug::_Safe_container<
+	forward_list<_Tp, _Alloc>, _Alloc, __gnu_debug::_Safe_forward_list>,
+      public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>
     {
       typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base;
+      typedef __gnu_debug::_Safe_container<
+	forward_list, _Alloc, __gnu_debug::_Safe_forward_list>	_Safe;
 
       typedef typename _Base::iterator       _Base_iterator;
       typedef typename _Base::const_iterator _Base_const_iterator;
 
-      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
-        rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type;
-
-      typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
-
     public:
       typedef typename _Base::reference             reference;
       typedef typename _Base::const_reference       const_reference;
 
-      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
-					  forward_list> iterator;
-      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
-					  forward_list> const_iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_iterator, forward_list>		iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_const_iterator, forward_list>	const_iterator;
 
       typedef typename _Base::size_type             size_type;
       typedef typename _Base::difference_type       difference_type;
 
       typedef _Tp                                   value_type;
-      typedef _Alloc                                allocator_type;
+      typedef typename _Base::allocator_type	allocator_type;
       typedef typename _Base::pointer               pointer;
       typedef typename _Base::const_pointer         const_pointer;
 
       // 23.2.3.1 construct/copy/destroy:
       explicit
-      forward_list(const _Alloc& __al = _Alloc())
+      forward_list(const allocator_type& __al = allocator_type())
       : _Base(__al) { }
 
-      forward_list(const forward_list& __list, const _Alloc& __al)
+      forward_list(const forward_list& __list, const allocator_type& __al)
       : _Base(__list, __al)
       { }
 
-      forward_list(forward_list&& __list, const _Alloc& __al)
-      : _Base(std::move(__list._M_base()), __al)
-      {
-	if (__list.get_allocator() == __al)
-	  this->_M_swap(__list);
-	else
-	  __list._M_invalidate_all();
-      }
+      forward_list(forward_list&& __list, const allocator_type& __al)
+	: _Safe(std::move(__list._M_safe()), __al),
+	  _Base(std::move(__list._M_base()), __al)
+      { }
 
       explicit
-      forward_list(size_type __n, const _Alloc& __al = _Alloc())
+      forward_list(size_type __n, const allocator_type& __al = allocator_type())
       : _Base(__n, __al)
       { }
 
       forward_list(size_type __n, const _Tp& __value,
-                   const _Alloc& __al = _Alloc())
+		   const allocator_type& __al = allocator_type())
       : _Base(__n, __value, __al)
       { }
 
       template<typename _InputIterator,
 	       typename = std::_RequireInputIter<_InputIterator>>
 	forward_list(_InputIterator __first, _InputIterator __last,
-                     const _Alloc& __al = _Alloc())
+		     const allocator_type& __al = allocator_type())
         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
 		__gnu_debug::__base(__last), __al)
         { }
 
-      forward_list(const forward_list& __list)
-      : _Base(__list)
-      { }
+      forward_list(const forward_list&) = default;
 
-      forward_list(forward_list&& __list) noexcept
-      : _Base(std::move(__list._M_base()))
-      {
-	this->_M_swap(__list);
-      }
+      forward_list(forward_list&&) = default;
 
       forward_list(std::initializer_list<_Tp> __il,
-                   const _Alloc& __al = _Alloc())
+		   const allocator_type& __al = allocator_type())
       : _Base(__il, __al)
       { }
 
-      ~forward_list() noexcept
-      { }
+      ~forward_list() = default;
 
       forward_list&
-      operator=(const forward_list& __list)
-      {
-	static_cast<_Base&>(*this) = __list;
-	this->_M_invalidate_all();
-	return *this;
-      }
+      operator=(const forward_list&) = default;
 
       forward_list&
-      operator=(forward_list&& __list)
-      noexcept(_Node_alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__list);
-	bool __xfer_memory = _Node_alloc_traits::_S_propagate_on_move_assign()
-	    || __list.get_allocator() == this->get_allocator();
-	static_cast<_Base&>(*this) = std::move(__list);
-	if (__xfer_memory)
-	  this->_M_swap(__list);
-	else
-	  this->_M_invalidate_all();
-	__list._M_invalidate_all();
-	return *this;
-      }
+      operator=(forward_list&&) = default;
 
       forward_list&
       operator=(std::initializer_list<_Tp> __il)
       {
-	static_cast<_Base&>(*this) = __il;
+	_M_base() = __il;
 	this->_M_invalidate_all();
         return *this;
       }
@@ -347,12 +446,10 @@
 
       void
       swap(forward_list& __list)
-      noexcept(_Node_alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__list)) )
       {
-	if (!_Node_alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__list);
+	_Safe::_M_swap(__list);
 	_Base::swap(__list);
-	this->_M_swap(__list);
       }
 
       void
@@ -644,93 +741,9 @@
 
       const _Base&
       _M_base() const noexcept { return *this; }
-
-    private:
-      void
-      _M_invalidate_all()
-      {
-	this->_M_invalidate_if([this](_Base_const_iterator __it)
-	  {
-	    return __it != this->_M_base().cbefore_begin()
-		   && __it != this->_M_base().cend();
-	  });
-      }
-      typedef __gnu_debug::_Safe_iterator_base _Safe_iterator_base;
-      static void
-      _M_swap_aux(forward_list& __lhs,
-		  _Safe_iterator_base*& __lhs_iterators,
-		  forward_list& __rhs,
-		  _Safe_iterator_base*& __rhs_iterators);
-      void _M_swap(forward_list& __list);
     };
 
    template<typename _Tp, typename _Alloc>
-    void
-    forward_list<_Tp, _Alloc>::
-    _M_swap_aux(forward_list<_Tp, _Alloc>& __lhs,
-		__gnu_debug::_Safe_iterator_base*& __lhs_iterators,
-		forward_list<_Tp, _Alloc>& __rhs,
-		__gnu_debug::_Safe_iterator_base*& __rhs_iterators)
-    {
-      using __gnu_debug::_Safe_iterator_base;
-      _Safe_iterator_base* __bbegin_its = 0;
-      _Safe_iterator_base* __last_bbegin = 0;
-      for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;)
-	{
-	  // Even iterator are casted to const_iterator, not a problem.
-	  const_iterator* __victim = static_cast<const_iterator*>(__iter);
-	  __iter = __iter->_M_next;
-	  if (__victim->base() == __rhs._M_base().cbefore_begin())
-	    {
-	      __victim->_M_unlink();
-	      if (__lhs_iterators == __victim)
-		__lhs_iterators = __victim->_M_next;
-	      if (__bbegin_its)
-		{
-		  __victim->_M_next = __bbegin_its;
-		  __bbegin_its->_M_prior = __victim;
-		}
-	      else
-		__last_bbegin = __victim;
-	      __bbegin_its = __victim;
-	    }
-	  else
-	    __victim->_M_sequence = &__lhs;
-	}
-
-      if (__bbegin_its)
-	{
-	  if (__rhs_iterators)
-	    {
-	      __rhs_iterators->_M_prior = __last_bbegin;
-	      __last_bbegin->_M_next = __rhs_iterators;
-	    }
-	  __rhs_iterators = __bbegin_its;
-	}
-    }
-
-  /* Special forward_list _M_swap version that do not swap the
-   * before-begin ownership.*/
-  template<typename _Tp, typename _Alloc>
-    void
-    forward_list<_Tp, _Alloc>::
-    _M_swap(forward_list<_Tp, _Alloc>& __list)
-    {
-      __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
-      std::swap(this->_M_iterators, __list._M_iterators);
-      std::swap(this->_M_const_iterators, __list._M_const_iterators);
-      // Useless, always 1 on forward_list
-      //std::swap(this->_M_version, __list._M_version);
-      _Safe_iterator_base* __this_its = this->_M_iterators;
-      _M_swap_aux(__list, __list._M_iterators, *this, this->_M_iterators);
-      _Safe_iterator_base* __this_const_its = this->_M_const_iterators;
-      _M_swap_aux(__list, __list._M_const_iterators, *this,
-		  this->_M_const_iterators);
-      _M_swap_aux(*this, __this_its, __list, __list._M_iterators);
-      _M_swap_aux(*this, __this_const_its, __list, __list._M_const_iterators);
-    }
-
-  template<typename _Tp, typename _Alloc>
     bool
     operator==(const forward_list<_Tp, _Alloc>& __lx,
                const forward_list<_Tp, _Alloc>& __ly)
Index: include/debug/list
===================================================================
--- include/debug/list	(revision 209879)
+++ include/debug/list	(working copy)
@@ -31,6 +31,7 @@
 
 #include <list>
 #include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -40,15 +41,20 @@
   /// Class std::list with safety/checking/debug instrumentation.
   template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
     class list
-    : public _GLIBCXX_STD_C::list<_Tp, _Allocator>,
-      public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
+    : public __gnu_debug::_Safe_container<
+	list<_Tp, _Allocator>, _Allocator,
+	__gnu_debug::_Safe_node_sequence, false>,
+      public _GLIBCXX_STD_C::list<_Tp, _Allocator>
     {
       typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_container<
+	list, _Allocator, __gnu_debug::_Safe_node_sequence, false>	_Safe;
 
       typedef typename _Base::iterator       _Base_iterator;
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+
     public:
       typedef typename _Base::reference             reference;
       typedef typename _Base::const_reference       const_reference;
@@ -70,9 +76,26 @@
 
       // 23.2.2.1 construct/copy/destroy:
 
-      list() _GLIBCXX_NOEXCEPT
+#if __cplusplus < 201103L
+      list()
       : _Base() { }
 
+      list(const list& __x)
+      : _Base(__x) { }
+
+      ~list() { }
+#else
+      list() = default;
+      list(const list&) = default;
+      list(list&&) = default;
+
+      list(initializer_list<value_type> __l,
+	   const allocator_type& __a = allocator_type())
+      : _Base(__l, __a) { }
+
+      ~list() = default;
+#endif
+
       explicit
       list(const _Allocator& __a) _GLIBCXX_NOEXCEPT
       : _Base(__a) { }
@@ -105,49 +128,29 @@
 		__gnu_debug::__base(__last), __a)
         { }
 
-      list(const list& __x)
-      : _Base(__x) { }
-
       list(const _Base& __x)
       : _Base(__x) { }
 
-#if __cplusplus >= 201103L
-      list(list&& __x) noexcept
-      : _Base(std::move(__x))
-      { this->_M_swap(__x); }
-
-      list(initializer_list<value_type> __l,
-           const allocator_type& __a = allocator_type())
-        : _Base(__l, __a) { }
-#endif
-
-      ~list() _GLIBCXX_NOEXCEPT { }
-
+#if __cplusplus < 201103L
       list&
       operator=(const list& __x)
       {
-	static_cast<_Base&>(*this) = __x;
-	this->_M_invalidate_all();
+	this->_M_safe() = __x;
+	_M_base() = __x;
 	return *this;
       }
+#else
+      list&
+      operator=(const list&) = default;
 
-#if __cplusplus >= 201103L
       list&
-      operator=(list&& __x)
-      {
-	// NB: DR 1204.
-	// NB: DR 675.
-	__glibcxx_check_self_move_assign(__x);
-	clear();
-	swap(__x);
-      	return *this;
-      }
+      operator=(list&&) = default;
 
       list&
       operator=(initializer_list<value_type> __l)
       {
-	static_cast<_Base&>(*this) = __l;
 	this->_M_invalidate_all();
+	_M_base() = __l;
 	return *this;
       }
 
@@ -245,16 +248,14 @@
       {
 	this->_M_detach_singular();
 
-	// if __sz < size(), invalidate all iterators in [begin+__sz, end())
+	// if __sz < size(), invalidate all iterators in [begin + __sz, end())
 	_Base_iterator __victim = _Base::begin();
 	_Base_iterator __end = _Base::end();
 	for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
 	  ++__victim;
 
 	for (; __victim != __end; ++__victim)
-	  {
 	    this->_M_invalidate_if(_Equal(__victim));
-	  }
 
 	__try
 	  {
@@ -272,16 +273,14 @@
       {
 	this->_M_detach_singular();
 
-	// if __sz < size(), invalidate all iterators in [begin+__sz, end())
+	// if __sz < size(), invalidate all iterators in [begin + __sz, end())
 	_Base_iterator __victim = _Base::begin();
 	_Base_iterator __end = _Base::end();
 	for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
 	  ++__victim;
 
 	for (; __victim != __end; ++__victim)
-	  {
 	    this->_M_invalidate_if(_Equal(__victim));
-	  }
 
 	__try
 	  {
@@ -299,16 +298,14 @@
       {
 	this->_M_detach_singular();
 
-	// if __sz < size(), invalidate all iterators in [begin+__sz, end())
+	// if __sz < size(), invalidate all iterators in [begin + __sz, end())
 	_Base_iterator __victim = _Base::begin();
 	_Base_iterator __end = _Base::end();
 	for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
 	  ++__victim;
 
 	for (; __victim != __end; ++__victim)
-	  {
 	    this->_M_invalidate_if(_Equal(__victim));
-	  }
 
 	__try
 	  {
@@ -504,9 +501,12 @@
 
       void
       swap(list& __x)
+#if __cplusplus >= 201103L
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
+#endif
       {
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	this->_M_swap(__x);
       }
 
       void
@@ -742,13 +742,6 @@
 
       const _Base&
       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
-
-    private:
-      void
-      _M_invalidate_all()
-      {
-	this->_M_invalidate_if(_Not_equal(_Base::end()));
-      }
     };
 
   template<typename _Tp, typename _Alloc>
Index: include/debug/macros.h
===================================================================
--- include/debug/macros.h	(revision 209879)
+++ include/debug/macros.h	(working copy)
@@ -347,10 +347,10 @@
 		      _M_message(__gnu_debug::__msg_valid_load_factor)	\
                       ._M_sequence(*this, "this"))
 
-#define __glibcxx_check_equal_allocs(_Other)				\
-_GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(),	\
+#define __glibcxx_check_equal_allocs(_This, _Other)			\
+_GLIBCXX_DEBUG_VERIFY(_This.get_allocator() == _Other.get_allocator(),	\
 		      _M_message(__gnu_debug::__msg_equal_allocs)	\
-		      ._M_sequence(*this, "this"))
+		      ._M_sequence(_This, "this"))
 
 #ifdef _GLIBCXX_DEBUG_PEDANTIC
 #  define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
Index: include/debug/map.h
===================================================================
--- include/debug/map.h	(revision 209879)
+++ include/debug/map.h	(working copy)
@@ -30,6 +30,7 @@
 #define _GLIBCXX_DEBUG_MAP_H 1
 
 #include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 #include <utility>
 
@@ -41,19 +42,20 @@
   template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
 	   typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
     class map
-    : public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>,
-      public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> >
+    : public __gnu_debug::_Safe_container<
+	map<_Key, _Tp, _Compare, _Allocator>, _Allocator,
+	__gnu_debug::_Safe_node_sequence>,
+      public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>
     {
-      typedef _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator> _Base;
+      typedef _GLIBCXX_STD_C::map<
+	_Key, _Tp, _Compare, _Allocator>			_Base;
+      typedef __gnu_debug::_Safe_container<
+	map, _Allocator, __gnu_debug::_Safe_node_sequence>	_Safe;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
 
-#if __cplusplus >= 201103L
-      typedef __gnu_cxx::__alloc_traits<typename
-					_Base::allocator_type> _Alloc_traits;
-#endif
     public:
       // types:
       typedef _Key                                  key_type;
@@ -78,33 +80,18 @@
 
       // 23.3.1.1 construct/copy/destroy:
 
+#if __cplusplus < 201103L
       map() : _Base() { }
 
-      explicit map(const _Compare& __comp,
-		   const _Allocator& __a = _Allocator())
-      : _Base(__comp, __a) { }
-
-      template<typename _InputIterator>
-        map(_InputIterator __first, _InputIterator __last,
-	    const _Compare& __comp = _Compare(),
-	    const _Allocator& __a = _Allocator())
-	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
-								     __last)),
-		__gnu_debug::__base(__last),
-		__comp, __a) { }
-
       map(const map& __x)
       : _Base(__x) { }
 
-      map(const _Base& __x)
-      : _Base(__x) { }
+      ~map() { }
+#else
+      map() = default;
+      map(const map&) = default;
+      map(map&&) = default;
 
-#if __cplusplus >= 201103L
-      map(map&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x))
-      { this->_M_swap(__x); }
-
       map(initializer_list<value_type> __l,
 	  const _Compare& __c = _Compare(),
 	  const allocator_type& __a = allocator_type())
@@ -118,7 +105,8 @@
       : _Base(__m, __a) { }
 
       map(map&& __m, const allocator_type& __a)
-      : _Base(std::move(__m._M_base()), __a) { }
+      : _Safe(std::move(__m._M_safe()), __a),
+	_Base(std::move(__m._M_base()), __a) { }
 
       map(initializer_list<value_type> __l, const allocator_type& __a)
       : _Base(__l, __a) { }
@@ -130,34 +118,40 @@
 								       __last)),
 		  __gnu_debug::__base(__last), __a)
 	{ }
+
+      ~map() = default;
 #endif
 
-      ~map() _GLIBCXX_NOEXCEPT { }
+      map(const _Base& __x)
+      : _Base(__x) { }
 
+      explicit map(const _Compare& __comp,
+		   const _Allocator& __a = _Allocator())
+      : _Base(__comp, __a) { }
+
+      template<typename _InputIterator>
+	map(_InputIterator __first, _InputIterator __last,
+	    const _Compare& __comp = _Compare(),
+	    const _Allocator& __a = _Allocator())
+	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
+								     __last)),
+		__gnu_debug::__base(__last),
+		__comp, __a) { }
+
+#if __cplusplus < 201103L
       map&
       operator=(const map& __x)
       {
+	this->_M_safe() = __x;
 	_M_base() = __x;
-	this->_M_invalidate_all();
 	return *this;
       }
+#else
+      map&
+      operator=(const map&) = default;
 
-#if __cplusplus >= 201103L
       map&
-      operator=(map&& __x)
-      noexcept(_Alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__x);
-	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
-	    || __x.get_allocator() == this->get_allocator();
-	_M_base() = std::move(__x._M_base());
-	if (__xfer_memory)
-	  this->_M_swap(__x);
-	else
-	  this->_M_invalidate_all();
-	__x._M_invalidate_all();
-	return *this;
-      }
+      operator=(map&&) = default;
 
       map&
       operator=(initializer_list<value_type> __l)
@@ -173,7 +167,7 @@
       using _Base::get_allocator;
 
       // iterators:
-      iterator 
+      iterator
       begin() _GLIBCXX_NOEXCEPT
       { return iterator(_Base::begin(), this); }
 
@@ -395,15 +389,11 @@
       void
       swap(map& __x)
 #if __cplusplus >= 201103L
-      noexcept(_Alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
 #endif
       {
-#if __cplusplus >= 201103L
-	if (!_Alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__x);
-#endif
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	this->_M_swap(__x);
       }
 
       void
@@ -467,14 +457,6 @@
 
       const _Base&
       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
-
-    private:
-      void
-      _M_invalidate_all()
-      {
-	typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
-	this->_M_invalidate_if(_Not_equal(_M_base().end()));
-      }
     };
 
   template<typename _Key, typename _Tp,
Index: include/debug/multimap.h
===================================================================
--- include/debug/multimap.h	(revision 209879)
+++ include/debug/multimap.h	(working copy)
@@ -30,6 +30,7 @@
 #define _GLIBCXX_DEBUG_MULTIMAP_H 1
 
 #include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 #include <utility>
 
@@ -41,20 +42,20 @@
   template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
 	   typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
     class multimap
-    : public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>,
-      public __gnu_debug::_Safe_sequence<multimap<_Key, _Tp,
-						  _Compare, _Allocator> >
+      : public __gnu_debug::_Safe_container<
+	multimap<_Key, _Tp, _Compare, _Allocator>, _Allocator,
+	__gnu_debug::_Safe_node_sequence>,
+	public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>
     {
-      typedef _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
+      typedef _GLIBCXX_STD_C::multimap<
+	_Key, _Tp, _Compare, _Allocator>			_Base;
+      typedef __gnu_debug::_Safe_container<
+	multimap, _Allocator, __gnu_debug::_Safe_node_sequence>	_Safe;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
 
-#if __cplusplus >= 201103L
-      typedef __gnu_cxx::__alloc_traits<typename
-					_Base::allocator_type> _Alloc_traits;
-#endif
     public:
       // types:
       typedef _Key				     key_type;
@@ -79,33 +80,18 @@
 
       // 23.3.1.1 construct/copy/destroy:
 
+#if __cplusplus < 201103L
       multimap() : _Base() { }
 
-      explicit multimap(const _Compare& __comp,
-			const _Allocator& __a = _Allocator())
-      : _Base(__comp, __a) { }
-
-      template<typename _InputIterator>
-      multimap(_InputIterator __first, _InputIterator __last,
-	       const _Compare& __comp = _Compare(),
-	       const _Allocator& __a = _Allocator())
-	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
-								     __last)),
-		__gnu_debug::__base(__last),
-	      __comp, __a) { }
-
       multimap(const multimap& __x)
       : _Base(__x) { }
 
-      multimap(const _Base& __x)
-      : _Base(__x) { }
+      ~multimap() { }
+#else
+      multimap() = default;
+      multimap(const multimap&) = default;
+      multimap(multimap&&) = default;
 
-#if __cplusplus >= 201103L
-      multimap(multimap&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x))
-      { this->_M_swap(__x); }
-
       multimap(initializer_list<value_type> __l,
 	       const _Compare& __c = _Compare(),
 	       const allocator_type& __a = allocator_type())
@@ -119,47 +105,52 @@
       : _Base(__m, __a) { }
 
       multimap(multimap&& __m, const allocator_type& __a)
-      : _Base(std::move(__m._M_base()), __a) { }
+      : _Safe(std::move(__m._M_safe()), __a),
+	_Base(std::move(__m._M_base()), __a) { }
 
       multimap(initializer_list<value_type> __l, const allocator_type& __a)
-      : _Base(__l, __a)
-      { }
+      : _Base(__l, __a) { }
 
       template<typename _InputIterator>
         multimap(_InputIterator __first, _InputIterator __last,
 		 const allocator_type& __a)
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
-		__gnu_debug::__base(__last), __a)
-      { }
+		__gnu_debug::__base(__last), __a) { }
+
+      ~multimap() = default;
 #endif
 
-      ~multimap() _GLIBCXX_NOEXCEPT { }
+      explicit multimap(const _Compare& __comp,
+			const _Allocator& __a = _Allocator())
+      : _Base(__comp, __a) { }
 
+      template<typename _InputIterator>
+      multimap(_InputIterator __first, _InputIterator __last,
+	       const _Compare& __comp = _Compare(),
+	       const _Allocator& __a = _Allocator())
+	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
+								     __last)),
+		__gnu_debug::__base(__last),
+	      __comp, __a) { }
+
+      multimap(const _Base& __x)
+      : _Base(__x) { }
+
+#if __cplusplus < 201103L
       multimap&
       operator=(const multimap& __x)
       {
+	this->_M_safe() = __x;
 	_M_base() = __x;
-	this->_M_invalidate_all();
 	return *this;
       }
+#else
+      multimap&
+      operator=(const multimap&) = default;
 
-#if __cplusplus >= 201103L
       multimap&
-      operator=(multimap&& __x)
-      noexcept(_Alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__x);
-	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
-	    || __x.get_allocator() == this->get_allocator();
-	_M_base() = std::move(__x._M_base());
-	if (__xfer_memory)
-	  this->_M_swap(__x);
-	else
-	  this->_M_invalidate_all();
-	__x._M_invalidate_all();
-	return *this;
-      }
+      operator=(multimap&&) = default;
 
       multimap&
       operator=(initializer_list<value_type> __l)
@@ -247,7 +238,7 @@
 			  this);
 	}
 #endif
-      
+
       iterator
       insert(const value_type& __x)
       { return iterator(_Base::insert(__x), this); }
@@ -379,15 +370,11 @@
       void
       swap(multimap& __x)
 #if __cplusplus >= 201103L
-      noexcept(_Alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
 #endif
       {
-#if __cplusplus >= 201103L
-	if (!_Alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__x);
-#endif
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	this->_M_swap(__x);
       }
 
       void
@@ -451,14 +438,6 @@
 
       const _Base&
       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
-
-    private:
-      void
-      _M_invalidate_all()
-      {
-	typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
-	this->_M_invalidate_if(_Not_equal(_Base::end()));
-      }
     };
 
   template<typename _Key, typename _Tp,
Index: include/debug/multiset.h
===================================================================
--- include/debug/multiset.h	(revision 209879)
+++ include/debug/multiset.h	(working copy)
@@ -30,6 +30,7 @@
 #define _GLIBCXX_DEBUG_MULTISET_H 1
 
 #include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 #include <utility>
 
@@ -41,19 +42,19 @@
   template<typename _Key, typename _Compare = std::less<_Key>,
 	   typename _Allocator = std::allocator<_Key> >
     class multiset
-    : public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>,
-      public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> >
+    : public __gnu_debug::_Safe_container<
+	multiset<_Key, _Compare, _Allocator>, _Allocator,
+	__gnu_debug::_Safe_node_sequence>,
+      public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>
     {
       typedef _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_container<
+	multiset, _Allocator, __gnu_debug::_Safe_node_sequence>		_Safe;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
 
-#if __cplusplus >= 201103L
-      typedef __gnu_cxx::__alloc_traits<typename
-					_Base::allocator_type> _Alloc_traits;
-#endif
     public:
       // types:
       typedef _Key				     key_type;
@@ -78,33 +79,18 @@
 
       // 23.3.3.1 construct/copy/destroy:
 
+#if __cplusplus < 201103L
       multiset() : _Base() { }
 
-      explicit multiset(const _Compare& __comp,
-			const _Allocator& __a = _Allocator())
-      : _Base(__comp, __a) { }
-
-      template<typename _InputIterator>
-        multiset(_InputIterator __first, _InputIterator __last,
-		 const _Compare& __comp = _Compare(),
-		 const _Allocator& __a = _Allocator())
-	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
-								     __last)),
-		__gnu_debug::__base(__last),
-		__comp, __a) { }
-
       multiset(const multiset& __x)
       : _Base(__x) { }
 
-      multiset(const _Base& __x)
-      : _Base(__x) { }
+      ~multiset() { }
+#else
+      multiset() = default;
+      multiset(const multiset&) = default;
+      multiset(multiset&&) = default;
 
-#if __cplusplus >= 201103L
-      multiset(multiset&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x))
-      { this->_M_swap(__x); }
-
       multiset(initializer_list<value_type> __l,
 	       const _Compare& __comp = _Compare(),
 	       const allocator_type& __a = allocator_type())
@@ -118,7 +104,8 @@
       : _Base(__m, __a) { }
 
       multiset(multiset&& __m, const allocator_type& __a)
-      : _Base(std::move(__m._M_base()), __a) { }
+      : _Safe(std::move(__m._M_safe()), __a),
+	_Base(std::move(__m._M_base()), __a) { }
 
       multiset(initializer_list<value_type> __l, const allocator_type& __a)
 	: _Base(__l, __a)
@@ -129,36 +116,41 @@
 		 const allocator_type& __a)
 	  : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								       __last)),
-		  __gnu_debug::__base(__last), __a)
-        { }
+		__gnu_debug::__base(__last), __a) { }
+
+      ~multiset() = default;
 #endif
 
-      ~multiset() _GLIBCXX_NOEXCEPT { }
+      explicit multiset(const _Compare& __comp,
+			const _Allocator& __a = _Allocator())
+      : _Base(__comp, __a) { }
 
+      template<typename _InputIterator>
+	multiset(_InputIterator __first, _InputIterator __last,
+		 const _Compare& __comp = _Compare(),
+		 const _Allocator& __a = _Allocator())
+	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
+								     __last)),
+		__gnu_debug::__base(__last),
+		__comp, __a) { }
+
+      multiset(const _Base& __x)
+      : _Base(__x) { }
+
+#if __cplusplus < 201103L
       multiset&
       operator=(const multiset& __x)
       {
+	this->_M_safe() = __x;
 	_M_base() = __x;
-	this->_M_invalidate_all();
 	return *this;
       }
+#else
+      multiset&
+      operator=(const multiset&) = default;
 
-#if __cplusplus >= 201103L
       multiset&
-      operator=(multiset&& __x)
-      noexcept(_Alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__x);
-	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
-	    || __x.get_allocator() == this->get_allocator();
-	_M_base() = std::move(__x._M_base());
-	if (__xfer_memory)
-	  this->_M_swap(__x);
-	else
-	  this->_M_invalidate_all();
-	__x._M_invalidate_all();
-	return *this;
-      }
+      operator=(multiset&&) = default;
 
       multiset&
       operator=(initializer_list<value_type> __l)
@@ -233,7 +225,8 @@
 	iterator
 	emplace(_Args&&... __args)
 	{
-	  return iterator(_Base::emplace(std::forward<_Args>(__args)...), this);
+	  return iterator(_Base::emplace(std::forward<_Args>(__args)...),
+			  this);
 	}
 
       template<typename... _Args>
@@ -364,15 +357,11 @@
       void
       swap(multiset& __x)
 #if __cplusplus >= 201103L
-      noexcept(_Alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
 #endif
       {
-#if __cplusplus >= 201103L
-	if (!_Alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__x);
-#endif
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	this->_M_swap(__x);
       }
 
       void
@@ -444,14 +433,6 @@
 
       const _Base&
       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
-
-    private:
-      void
-      _M_invalidate_all()
-      {
-	typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
-	this->_M_invalidate_if(_Not_equal(_Base::end()));
-      }
     };
 
   template<typename _Key, typename _Compare, typename _Allocator>
Index: include/debug/safe_base.h
===================================================================
--- include/debug/safe_base.h	(revision 209879)
+++ include/debug/safe_base.h	(working copy)
@@ -104,7 +104,8 @@
     ~_Safe_iterator_base() { this->_M_detach(); }
 
     /** For use in _Safe_iterator. */
-    __gnu_cxx::__mutex& _M_get_mutex() throw ();
+    __gnu_cxx::__mutex&
+    _M_get_mutex() throw ();
 
   public:
     /** Attaches this iterator to the given sequence, detaching it
@@ -112,30 +113,37 @@
      *	new sequence is the NULL pointer, the iterator is left
      *	unattached.
      */
-    void _M_attach(_Safe_sequence_base* __seq, bool __constant);
+    void
+    _M_attach(_Safe_sequence_base* __seq, bool __constant);
 
     /** Likewise, but not thread-safe. */
-    void _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ();
+    void
+    _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ();
 
     /** Detach the iterator for whatever sequence it is attached to,
      *	if any.
     */
-    void _M_detach();
+    void
+    _M_detach();
 
     /** Likewise, but not thread-safe. */
-    void _M_detach_single() throw ();
+    void
+    _M_detach_single() throw ();
 
     /** Determines if we are attached to the given sequence. */
-    bool _M_attached_to(const _Safe_sequence_base* __seq) const
+    bool
+    _M_attached_to(const _Safe_sequence_base* __seq) const
     { return _M_sequence == __seq; }
 
     /** Is this iterator singular? */
-    _GLIBCXX_PURE bool _M_singular() const throw ();
+    _GLIBCXX_PURE bool
+    _M_singular() const throw ();
 
     /** Can we compare this iterator to the given iterator @p __x?
 	Returns true if both iterators are nonsingular and reference
 	the same sequence. */
-    _GLIBCXX_PURE bool _M_can_compare(const _Safe_iterator_base& __x) const throw ();
+    _GLIBCXX_PURE bool
+    _M_can_compare(const _Safe_iterator_base& __x) const throw ();
 
     /** Invalidate the iterator, making it singular. */
     void
@@ -188,17 +196,13 @@
 
   protected:
     // Initialize with a version number of 1 and no iterators
-    _Safe_sequence_base()
+    _Safe_sequence_base() _GLIBCXX_NOEXCEPT
     : _M_iterators(0), _M_const_iterators(0), _M_version(1)
     { }
 
 #if __cplusplus >= 201103L
     _Safe_sequence_base(const _Safe_sequence_base&) noexcept
       : _Safe_sequence_base() { }
-
-    _Safe_sequence_base(_Safe_sequence_base&& __x) noexcept
-      : _Safe_sequence_base()
-    { _M_swap(__x); }
 #endif
 
     /** Notify all iterators that reference this sequence that the
@@ -231,10 +235,11 @@
      *  one container now reference the other container.
      */
     void
-    _M_swap(_Safe_sequence_base& __x);
+    _M_swap(_Safe_sequence_base& __x) _GLIBCXX_USE_NOEXCEPT;
 
     /** For use in _Safe_sequence. */
-    __gnu_cxx::__mutex& _M_get_mutex() throw ();
+    __gnu_cxx::__mutex&
+    _M_get_mutex() throw ();
 
   public:
     /** Invalidates all iterators. */
Index: include/debug/safe_container.h
===================================================================
--- include/debug/safe_container.h	(revision 0)
+++ include/debug/safe_container.h	(working copy)
@@ -0,0 +1,125 @@
+// Safe container implementation  -*- C++ -*-
+
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file debug/safe_container.h
+ *  This file is a GNU debug extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_DEBUG_SAFE_CONTAINER_H
+#define _GLIBCXX_DEBUG_SAFE_CONTAINER_H 1
+
+#include <ext/alloc_traits.h>
+
+namespace __gnu_debug
+{
+  /// Safe class dealing with some allocator dependent operations.
+  template<typename _SafeContainer,
+	   typename _Alloc,
+	   template<typename> class _SafeBase,
+	   bool _IsCxx11AllocatorAware = true>
+    class _Safe_container
+    : public _SafeBase<_SafeContainer>
+    {
+      typedef _SafeBase<_SafeContainer> _Base;
+
+      _SafeContainer&
+      _M_cont() _GLIBCXX_NOEXCEPT
+      { return *static_cast<_SafeContainer*>(this); }
+
+    protected:
+      _Safe_container&
+      _M_safe() _GLIBCXX_NOEXCEPT
+      { return *this; }
+
+#if __cplusplus >= 201103L
+      _Safe_container() = default;
+      _Safe_container(const _Safe_container&) = default;
+      _Safe_container(_Safe_container&& __x) noexcept
+      : _Safe_container()
+      { _Base::_M_swap(__x); }
+
+      _Safe_container(_Safe_container&& __x,
+		      const _Alloc& __a)
+      : _Safe_container()
+      {
+	if (__x._M_cont().get_allocator() == __a)
+	  _Base::_M_swap(__x);
+	else
+	  __x._M_invalidate_all();
+      }
+#endif
+
+    public:
+      // Copy assignment invalidate all iterators.
+      _Safe_container&
+      operator=(const _Safe_container&) _GLIBCXX_NOEXCEPT
+      {
+	this->_M_invalidate_all();
+	return *this;
+      }
+
+#if __cplusplus >= 201103L
+      _Safe_container&
+      operator=(_Safe_container&& __x) noexcept
+      {
+	__glibcxx_check_self_move_assign(__x);
+
+	if (_IsCxx11AllocatorAware)
+	  {
+	    typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits;
+
+	    bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
+	      || _M_cont().get_allocator() == __x._M_cont().get_allocator();
+	    if (__xfer_memory)
+	      _Base::_M_swap(__x);
+	    else
+	      this->_M_invalidate_all();
+	  }
+	else
+	  _Base::_M_swap(__x);
+
+	__x._M_invalidate_all();
+	return *this;
+      }
+
+      void
+      _M_swap(_Safe_container& __x) noexcept
+      {
+	if (_IsCxx11AllocatorAware)
+	  {
+	    typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits;
+
+	    if (!_Alloc_traits::_S_propagate_on_swap())
+	      __glibcxx_check_equal_allocs(this->_M_cont()._M_base(),
+					   __x._M_cont()._M_base());
+	  }
+
+	_Base::_M_swap(__x);
+      }
+#endif
+    };
+
+} // namespace __gnu_debug
+
+#endif
Index: include/debug/safe_iterator.h
===================================================================
--- include/debug/safe_iterator.h	(revision 209879)
+++ include/debug/safe_iterator.h	(working copy)
@@ -58,7 +58,7 @@
   /** Iterators that derive from _Safe_iterator_base can be determined singular
    *  or non-singular.
    **/
-  inline bool 
+  inline bool
   __check_singular_aux(const _Safe_iterator_base* __x)
   { return __x->_M_singular(); }
 
Index: include/debug/safe_sequence.h
===================================================================
--- include/debug/safe_sequence.h	(revision 209879)
+++ include/debug/safe_sequence.h	(working copy)
@@ -127,6 +127,25 @@
         void
         _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred);
     };
+
+  /// Like _Safe_sequence but with a special _M_invalidate_all implementation
+  /// not invalidating past-the-end iterators. Used by node based sequence.
+  template<typename _Sequence>
+    class _Safe_node_sequence
+    : public _Safe_sequence<_Sequence>
+    {
+    protected:
+      void
+      _M_invalidate_all()
+      {
+	typedef typename _Sequence::const_iterator _Const_iterator;
+	typedef typename _Const_iterator::iterator_type _Base_const_iterator;
+	typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+	const _Sequence& __seq = *static_cast<_Sequence*>(this);
+	this->_M_invalidate_if(_Not_equal(__seq._M_base().end()));
+      }
+    };
+
 } // namespace __gnu_debug
 
 #include <debug/safe_sequence.tcc>
Index: include/debug/safe_unordered_base.h
===================================================================
--- include/debug/safe_unordered_base.h	(revision 209879)
+++ include/debug/safe_unordered_base.h	(working copy)
@@ -80,7 +80,7 @@
     ~_Safe_local_iterator_base() { this->_M_detach(); }
 
     _Safe_unordered_container_base*
-    _M_get_container() const _GLIBCXX_NOEXCEPT;
+    _M_get_container() const noexcept;
 
   public:
     /** Attaches this iterator to the given container, detaching it
@@ -132,15 +132,16 @@
 
   protected:
     // Initialize with a version number of 1 and no iterators
-    _Safe_unordered_container_base()
+    _Safe_unordered_container_base() noexcept
     : _M_local_iterators(nullptr), _M_const_local_iterators(nullptr)
     { }
 
-    // Initialize with a version number of 1 and no iterators
+    // Copy constructor does not copy iterators.
     _Safe_unordered_container_base(const _Safe_unordered_container_base&)
     noexcept
     : _Safe_unordered_container_base() { }
 
+    // When moved unordered containers iterators are swapped.
     _Safe_unordered_container_base(_Safe_unordered_container_base&& __x)
     noexcept
     : _Safe_unordered_container_base()
@@ -148,7 +149,7 @@
 
     /** Notify all iterators that reference this container that the
 	container is being destroyed. */
-    ~_Safe_unordered_container_base()
+    ~_Safe_unordered_container_base() noexcept
     { this->_M_detach_all(); }
 
     /** Detach all iterators, leaving them singular. */
@@ -161,7 +162,7 @@
      *  one container now reference the other container.
      */
     void
-    _M_swap(_Safe_unordered_container_base& __x);
+    _M_swap(_Safe_unordered_container_base& __x) noexcept;
 
   public:
     /** Attach an iterator to this container. */
Index: include/debug/safe_unordered_container.h
===================================================================
--- include/debug/safe_unordered_container.h	(revision 209879)
+++ include/debug/safe_unordered_container.h	(working copy)
@@ -57,7 +57,31 @@
   template<typename _Container>
     class _Safe_unordered_container : public _Safe_unordered_container_base
     {
-    public:
+    private:
+      _Container&
+      _M_cont() noexcept
+      { return *static_cast<_Container*>(this); }
+
+    protected:
+      void
+      _M_invalidate_locals()
+      {
+	auto __local_end = _M_cont()._M_base().end(0);
+	this->_M_invalidate_local_if(
+		[__local_end](__decltype(_M_cont()._M_base().cend(0)) __it)
+		{ return __it != __local_end; });
+      }
+
+      void
+      _M_invalidate_all()
+      {
+	auto __end = _M_cont()._M_base().end();
+	this->_M_invalidate_if(
+		[__end](__decltype(_M_cont()._M_base().cend()) __it)
+		{ return __it != __end; });
+	_M_invalidate_locals();
+      }
+
       /** Invalidates all iterators @c x that reference this container,
 	  are not singular, and for which @c __pred(x) returns @c
 	  true. @c __pred will be invoked with the normal iterators nested
Index: include/debug/set.h
===================================================================
--- include/debug/set.h	(revision 209879)
+++ include/debug/set.h	(working copy)
@@ -30,10 +30,11 @@
 #define _GLIBCXX_DEBUG_SET_H 1
 
 #include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 #include <utility>
 
-namespace std _GLIBCXX_VISIBILITY(default) 
+namespace std _GLIBCXX_VISIBILITY(default)
 {
 namespace __debug
 {
@@ -41,18 +42,19 @@
   template<typename _Key, typename _Compare = std::less<_Key>,
 	   typename _Allocator = std::allocator<_Key> >
     class set
-    : public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>,
-      public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> >
+    : public __gnu_debug::_Safe_container<
+	set<_Key, _Compare, _Allocator>, _Allocator,
+	__gnu_debug::_Safe_node_sequence>,
+      public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>
     {
       typedef _GLIBCXX_STD_C::set<_Key, _Compare, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_container<
+	set, _Allocator, __gnu_debug::_Safe_node_sequence>	_Safe;
 
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
-#if __cplusplus >= 201103L
-      typedef __gnu_cxx::__alloc_traits<typename
-					_Base::allocator_type> _Alloc_traits;
-#endif
+
     public:
       // types:
       typedef _Key				    key_type;
@@ -77,33 +79,18 @@
 
       // 23.3.3.1 construct/copy/destroy:
 
+#if __cplusplus < 201103L
       set() : _Base() { }
 
-      explicit set(const _Compare& __comp,
-		   const _Allocator& __a = _Allocator())
-      : _Base(__comp, __a) { }
-
-      template<typename _InputIterator>
-        set(_InputIterator __first, _InputIterator __last,
-	    const _Compare& __comp = _Compare(),
-	    const _Allocator& __a = _Allocator())
-	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
-								     __last)),
-		__gnu_debug::__base(__last),
-		__comp, __a) { }
-
       set(const set& __x)
       : _Base(__x) { }
 
-      set(const _Base& __x)
-      : _Base(__x) { }
+      ~set() { }
+#else
+      set() = default;
+      set(const set&) = default;
+      set(set&&) = default;
 
-#if __cplusplus >= 201103L
-      set(set&& __x)
-      noexcept(is_nothrow_copy_constructible<_Compare>::value)
-      : _Base(std::move(__x))
-      { this->_M_swap(__x); }
-
       set(initializer_list<value_type> __l,
 	  const _Compare& __comp = _Compare(),
 	  const allocator_type& __a = allocator_type())
@@ -117,47 +104,52 @@
       : _Base(__x, __a) { }
 
       set(set&& __x, const allocator_type& __a)
-      : _Base(std::move(__x._M_base()), __a) { }
+      : _Safe(std::move(__x._M_safe()), __a),
+	_Base(std::move(__x._M_base()), __a) { }
 
       set(initializer_list<value_type> __l, const allocator_type& __a)
-	: _Base(__l, __a)
-      { }
+      : _Base(__l, __a) { }
 
       template<typename _InputIterator>
         set(_InputIterator __first, _InputIterator __last,
 	    const allocator_type& __a)
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
-		__gnu_debug::__base(__last), __a)
-        { }
+		__gnu_debug::__base(__last), __a) { }
+
+      ~set() = default;
 #endif
 
-      ~set() _GLIBCXX_NOEXCEPT { }
+      explicit set(const _Compare& __comp,
+		   const _Allocator& __a = _Allocator())
+      : _Base(__comp, __a) { }
 
+      template<typename _InputIterator>
+	set(_InputIterator __first, _InputIterator __last,
+	    const _Compare& __comp = _Compare(),
+	    const _Allocator& __a = _Allocator())
+	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
+								     __last)),
+		__gnu_debug::__base(__last),
+		__comp, __a) { }
+
+      set(const _Base& __x)
+      : _Base(__x) { }
+
+#if __cplusplus < 201103L
       set&
       operator=(const set& __x)
       {
+	this->_M_safe() = __x;
 	_M_base() = __x;
-	this->_M_invalidate_all();
 	return *this;
       }
+#else
+      set&
+      operator=(const set&) = default;
 
-#if __cplusplus >= 201103L
       set&
-      operator=(set&& __x)
-      noexcept(_Alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__x);
-	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
-	    || __x.get_allocator() == this->get_allocator();
-	_M_base() = std::move(__x._M_base());
-	if (__xfer_memory)
-	  this->_M_swap(__x);
-	else
-	  this->_M_invalidate_all();
-	__x._M_invalidate_all();
-	return *this;
-      }
+      operator=(set&&) = default;
 
       set&
       operator=(initializer_list<value_type> __l)
@@ -372,15 +364,11 @@
       void
       swap(set& __x)
 #if __cplusplus >= 201103L
-      noexcept(_Alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
 #endif
       {
-#if __cplusplus >= 201103L
-	if (!_Alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__x);
-#endif
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	this->_M_swap(__x);
       }
 
       void
@@ -452,14 +440,6 @@
 
       const _Base&
       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
-
-    private:
-      void
-      _M_invalidate_all()
-      {
-	typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
-	this->_M_invalidate_if(_Not_equal(_M_base().end()));
-      }
     };
 
   template<typename _Key, typename _Compare, typename _Allocator>
Index: include/debug/string
===================================================================
--- include/debug/string	(revision 209879)
+++ include/debug/string	(working copy)
@@ -31,6 +31,7 @@
 
 #include <string>
 #include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 
 namespace __gnu_debug
@@ -39,12 +40,14 @@
   template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
             typename _Allocator = std::allocator<_CharT> >
     class basic_string
+    : public __gnu_debug::_Safe_container<
+	basic_string<_CharT, _Traits, _Allocator>, _Allocator,
+	_Safe_sequence, false>
     : public std::basic_string<_CharT, _Traits, _Allocator>,
-      public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits,
-						      _Allocator> >
     {
       typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
-      typedef __gnu_debug::_Safe_sequence<basic_string>     _Safe_base;
+      typedef __gnu_debug::_Safe_container<
+	basic_string, _Allocator, _Safe_sequence, false>	_Safe;
 
   public:
     // types:
@@ -58,10 +61,10 @@
     typedef typename _Base::pointer                    pointer;
     typedef typename _Base::const_pointer              const_pointer;
 
-    typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string>
-                                                       iterator;
-    typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
-                                         basic_string> const_iterator;
+    typedef __gnu_debug::_Safe_iterator<
+      typename _Base::iterator, basic_string>		iterator;
+    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;
@@ -71,18 +74,29 @@
     // 21.3.1 construct/copy/destroy:
     explicit basic_string(const _Allocator& __a = _Allocator())
     // _GLIBCXX_NOEXCEPT
-    : _Base(__a)
-    { }
+    : _Base(__a) { }
 
-    // Provides conversion from a release-mode string to a debug-mode string
-    basic_string(const _Base& __base) : _Base(__base) { }
+#if __cplusplus < 201103L
+    basic_string(const basic_string& __str)
+    : _Base(__str) { }
 
-    // _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())
+    ~basic_string() { }
+#else
+    basic_string(const basic_string&) = default;
+    basic_string(basic_string&&) = default;
+
+    basic_string(std::initializer_list<_CharT> __l,
+		 const _Allocator& __a = _Allocator())
+    : _Base(__l, __a)
     { }
 
+    ~basic_string() = default;
+#endif // C++11
+
+    // Provides conversion from a normal-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, size_type __pos,
@@ -113,32 +127,27 @@
 	      __gnu_debug::__base(__end), __a)
       { }
 
-#if __cplusplus >= 201103L
-    basic_string(basic_string&& __str) // noexcept
-    : _Base(std::move(__str))
-    { }
-
-    basic_string(std::initializer_list<_CharT> __l,
-		 const _Allocator& __a = _Allocator())
-    : _Base(__l, __a)
-    { }
-#endif // C++11
-
-    ~basic_string() _GLIBCXX_NOEXCEPT { }
-
+#if __cplusplus < 201103L
     basic_string&
     operator=(const basic_string& __str)
     {
-      *static_cast<_Base*>(this) = __str;
-      this->_M_invalidate_all();
+      this->_M_safe() = __str;
+      _M_base() = __str;
       return *this;
     }
+#else
+    basic_string&
+    operator=(const basic_string&) = default;
 
     basic_string&
+    operator=(basic_string&&) = default;
+#endif
+
+    basic_string&
     operator=(const _CharT* __s)
     {
       __glibcxx_check_string(__s);
-      *static_cast<_Base*>(this) = __s;
+      _M_base() = __s;
       this->_M_invalidate_all();
       return *this;
     }
@@ -146,25 +155,16 @@
     basic_string&
     operator=(_CharT __c)
     {
-      *static_cast<_Base*>(this) = __c;
+      _M_base() = __c;
       this->_M_invalidate_all();
       return *this;
     }
 
 #if __cplusplus >= 201103L
     basic_string&
-    operator=(basic_string&& __str)
-    {
-      __glibcxx_check_self_move_assign(__str);
-      *static_cast<_Base*>(this) = std::move(__str);
-      this->_M_invalidate_all();
-      return *this;
-    }
-
-    basic_string&
     operator=(std::initializer_list<_CharT> __l)
     {
-      *static_cast<_Base*>(this) = __l;
+      _M_base() = __l;
       this->_M_invalidate_all();
       return *this;
     }
@@ -704,12 +704,13 @@
     }
 
     void
-    swap(basic_string<_CharT,_Traits,_Allocator>& __x)
+    swap(basic_string& __x)
+#if __cplusplus >= 201103L
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
+#endif
     {
+      _Safe::_M_swap(__x);
       _Base::swap(__x);
-      this->_M_swap(__x);
-      this->_M_invalidate_all();
-      __x._M_invalidate_all();
     }
 
     // 21.3.6 string operations:
@@ -801,7 +802,7 @@
     { return _Base::find_first_of(__c, __pos); }
 
     size_type
-    find_last_of(const basic_string& __str, 
+    find_last_of(const basic_string& __str,
 		 size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
     { return _Base::find_last_of(__str, __pos); }
 
@@ -922,7 +923,7 @@
     const _Base&
     _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
 
-    using _Safe_base::_M_invalidate_all;
+    using _Safe::_M_invalidate_all;
   };
 
   template<typename _CharT, typename _Traits, typename _Allocator>
Index: include/debug/unordered_map
===================================================================
--- include/debug/unordered_map	(revision 209879)
+++ include/debug/unordered_map	(working copy)
@@ -35,6 +35,7 @@
 # include <unordered_map>
 
 #include <debug/safe_unordered_container.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 #include <debug/safe_local_iterator.h>
 
@@ -48,21 +49,21 @@
 	   typename _Pred = std::equal_to<_Key>,
 	   typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
     class unordered_map
-    : public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
-      public __gnu_debug::_Safe_unordered_container<unordered_map<_Key, _Tp,
-							_Hash, _Pred, _Alloc> >
+    : public __gnu_debug::_Safe_container<
+	unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
+	__gnu_debug::_Safe_unordered_container>,
+      public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
     {
       typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
 					    _Pred, _Alloc> _Base;
-      typedef __gnu_debug::_Safe_unordered_container<unordered_map> _Safe_base;
+      typedef __gnu_debug::_Safe_container<unordered_map,
+		   _Alloc, __gnu_debug::_Safe_unordered_container>	_Safe;
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
-      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
+      typedef typename _Base::const_local_iterator
+						_Base_const_local_iterator;
       typedef typename _Base::local_iterator _Base_local_iterator;
 
-      typedef __gnu_cxx::__alloc_traits<typename
-					_Base::allocator_type> _Alloc_traits;
-
     public:
       typedef typename _Base::size_type       size_type;
       typedef typename _Base::hasher          hasher;
@@ -72,14 +73,14 @@
       typedef typename _Base::key_type        key_type;
       typedef typename _Base::value_type      value_type;
 
-      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
-					  unordered_map> iterator;
-      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
-					  unordered_map> const_iterator;
-      typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
-					  unordered_map> local_iterator;
-      typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
-					  unordered_map> const_local_iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_iterator, unordered_map>			iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_const_iterator, unordered_map>		const_iterator;
+      typedef __gnu_debug::_Safe_local_iterator<
+	_Base_local_iterator, unordered_map>		local_iterator;
+      typedef __gnu_debug::_Safe_local_iterator<
+	_Base_const_local_iterator, unordered_map>	const_local_iterator;
 
       explicit
       unordered_map(size_type __n = 10,
@@ -89,10 +90,10 @@
       : _Base(__n, __hf, __eql, __a) { }
 
       template<typename _InputIterator>
-	unordered_map(_InputIterator __first, _InputIterator __last, 
+	unordered_map(_InputIterator __first, _InputIterator __last,
 		      size_type __n = 0,
-		      const hasher& __hf = hasher(), 
-		      const key_equal& __eql = key_equal(), 
+		      const hasher& __hf = hasher(),
+		      const key_equal& __eql = key_equal(),
 		      const allocator_type& __a = allocator_type())
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
@@ -108,18 +109,16 @@
 
       explicit
       unordered_map(const allocator_type& __a)
-	: _Base(__a)
-      { }
+      : _Base(__a) { }
 
       unordered_map(const unordered_map& __umap,
 		    const allocator_type& __a)
-	: _Base(__umap._M_base(), __a)
-      { }
+      : _Base(__umap, __a) { }
 
       unordered_map(unordered_map&& __umap,
 		    const allocator_type& __a)
-	: _Base(std::move(__umap._M_base()), __a)
-      { }
+      : _Safe(std::move(__umap._M_safe()), __a),
+	_Base(std::move(__umap._M_base()), __a) { }
 
       unordered_map(initializer_list<value_type> __l,
 		    size_type __n = 0,
@@ -128,31 +127,13 @@
 		    const allocator_type& __a = allocator_type())
       : _Base(__l, __n, __hf, __eql, __a) { }
 
-      ~unordered_map() noexcept { }
+      ~unordered_map() = default;
 
       unordered_map&
-      operator=(const unordered_map& __x)
-      {
-	_M_base() = __x._M_base();
-	this->_M_invalidate_all();
-	return *this;
-      }
+      operator=(const unordered_map&) = default;
 
       unordered_map&
-      operator=(unordered_map&& __x)
-      noexcept(_Alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__x);
-	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
-	    || __x.get_allocator() == this->get_allocator();
-	_M_base() = std::move(__x._M_base());	
-	if (__xfer_memory)
-	  this->_M_swap(__x);
-	else
-	  this->_M_invalidate_all();
-	__x._M_invalidate_all();
-	return *this;
-      }
+      operator=(unordered_map&&) = default;
 
       unordered_map&
       operator=(initializer_list<value_type> __l)
@@ -164,12 +145,10 @@
 
       void
       swap(unordered_map& __x)
-      noexcept(_Alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
       {
-	if (!_Alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__x);
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	_Safe_base::_M_swap(__x);
       }
 
       void
@@ -179,7 +158,7 @@
 	this->_M_invalidate_all();
       }
 
-      iterator 
+      iterator
       begin() noexcept
       { return iterator(_Base::begin(), this); }
 
@@ -301,7 +280,7 @@
       {
 	__glibcxx_check_insert(__hint);
 	size_type __bucket_count = this->bucket_count();
-	_Base_iterator __it = _Base::insert(__hint.base(), __obj); 
+	_Base_iterator __it = _Base::insert(__hint.base(), __obj);
 	_M_check_rehashed(__bucket_count);
 	return iterator(__it, this);
       }
@@ -409,7 +388,7 @@
 			[__victim](_Base_const_local_iterator __it)
 			{ return __it._M_curr() == __victim._M_cur; });
 	size_type __bucket_count = this->bucket_count();
-	_Base_iterator __next = _Base::erase(__it.base()); 
+	_Base_iterator __next = _Base::erase(__it.base());
 	_M_check_rehashed(__bucket_count);
 	return iterator(__next, this);
       }
@@ -449,28 +428,10 @@
 
     private:
       void
-      _M_invalidate_locals()
-      {
-	_Base_local_iterator __local_end = _Base::end(0);
-	this->_M_invalidate_local_if(
-			[__local_end](_Base_const_local_iterator __it)
-			{ return __it != __local_end; });
-      }
-
-      void
-      _M_invalidate_all()
-      {
-	_Base_iterator __end = _Base::end();
-	this->_M_invalidate_if([__end](_Base_const_iterator __it)
-			{ return __it != __end; });
-	_M_invalidate_locals();
-      }
-
-      void
       _M_check_rehashed(size_type __prev_count)
       {
 	if (__prev_count != this->bucket_count())
-	  _M_invalidate_locals();
+	  this->_M_invalidate_locals();
       }
     };
 
@@ -502,23 +463,20 @@
 	   typename _Pred = std::equal_to<_Key>,
 	   typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
     class unordered_multimap
-    : public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
-						_Pred, _Alloc>,
-      public __gnu_debug::_Safe_unordered_container<unordered_multimap<_Key,
-						_Tp, _Hash, _Pred, _Alloc> >
+      : public __gnu_debug::_Safe_container<
+	unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
+	__gnu_debug::_Safe_unordered_container>,
+	public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
     {
       typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
 						 _Pred, _Alloc> _Base;
-      typedef __gnu_debug::_Safe_unordered_container<unordered_multimap>
-	_Safe_base;
+      typedef __gnu_debug::_Safe_container<unordered_multimap,
+	_Alloc, __gnu_debug::_Safe_unordered_container>			_Safe;
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
       typedef typename _Base::local_iterator _Base_local_iterator;
 
-      typedef __gnu_cxx::__alloc_traits<typename
-					_Base::allocator_type> _Alloc_traits;
-
     public:
       typedef typename _Base::size_type       size_type;
       typedef typename _Base::hasher          hasher;
@@ -528,10 +486,10 @@
       typedef typename _Base::key_type        key_type;
       typedef typename _Base::value_type      value_type;
 
-      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
-					  unordered_multimap> iterator;
-      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
-					  unordered_multimap> const_iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_iterator, unordered_multimap>		iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_const_iterator, unordered_multimap>	const_iterator;
       typedef __gnu_debug::_Safe_local_iterator<
 	_Base_local_iterator, unordered_multimap> local_iterator;
       typedef __gnu_debug::_Safe_local_iterator<
@@ -545,10 +503,10 @@
       : _Base(__n, __hf, __eql, __a) { }
 
       template<typename _InputIterator>
-	unordered_multimap(_InputIterator __first, _InputIterator __last, 
+	unordered_multimap(_InputIterator __first, _InputIterator __last,
 			   size_type __n = 0,
-			   const hasher& __hf = hasher(), 
-			   const key_equal& __eql = key_equal(), 
+			   const hasher& __hf = hasher(),
+			   const key_equal& __eql = key_equal(),
 			   const allocator_type& __a = allocator_type())
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
@@ -557,25 +515,23 @@
 
       unordered_multimap(const unordered_multimap&) = default;
 
-      unordered_multimap(const _Base& __x) 
+      unordered_multimap(const _Base& __x)
       : _Base(__x) { }
 
       unordered_multimap(unordered_multimap&&) = default;
 
       explicit
       unordered_multimap(const allocator_type& __a)
-	: _Base(__a)
-      { }
+      : _Base(__a) { }
 
       unordered_multimap(const unordered_multimap& __umap,
 			 const allocator_type& __a)
-	: _Base(__umap._M_base(), __a)
-      { }
+      : _Base(__umap, __a) { }
 
       unordered_multimap(unordered_multimap&& __umap,
 			 const allocator_type& __a)
-	: _Base(std::move(__umap._M_base()), __a)
-      { }
+      : _Safe(std::move(__umap._M_safe()), __a),
+	_Base(std::move(__umap._M_base()), __a) { }
 
       unordered_multimap(initializer_list<value_type> __l,
 			 size_type __n = 0,
@@ -584,48 +540,28 @@
 			 const allocator_type& __a = allocator_type())
       : _Base(__l, __n, __hf, __eql, __a) { }
 
-      ~unordered_multimap() noexcept { }
+      ~unordered_multimap() = default;
 
       unordered_multimap&
-      operator=(const unordered_multimap& __x)
-      {
-	_M_base() = __x._M_base();
-	this->_M_invalidate_all();
-	return *this;
-      }
+      operator=(const unordered_multimap&) = default;
 
       unordered_multimap&
-      operator=(unordered_multimap&& __x)
-      noexcept(_Alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__x);
-	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
-	    || __x.get_allocator() == this->get_allocator();
-	_M_base() = std::move(__x._M_base());
-	if (__xfer_memory)
-	  this->_M_swap(__x);
-	else
-	  this->_M_invalidate_all();
-	__x._M_invalidate_all();
-	return *this;
-      }
+      operator=(unordered_multimap&&) = default;
 
       unordered_multimap&
       operator=(initializer_list<value_type> __l)
       {
-	_M_base() = __l;
+	this->_M_base() = __l;
 	this->_M_invalidate_all();
 	return *this;
       }
 
       void
       swap(unordered_multimap& __x)
-      noexcept(_Alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
       {
-	if (!_Alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__x);
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	_Safe_base::_M_swap(__x);
       }
 
       void
@@ -635,7 +571,7 @@
 	this->_M_invalidate_all();
       }
 
-      iterator 
+      iterator
       begin() noexcept
       { return iterator(_Base::begin(), this); }
 
@@ -901,28 +837,10 @@
 
     private:
       void
-      _M_invalidate_locals()
-      {
-	_Base_local_iterator __local_end = _Base::end(0);
-	this->_M_invalidate_local_if(
-			[__local_end](_Base_const_local_iterator __it)
-			{ return __it != __local_end; });
-      }
-
-      void
-      _M_invalidate_all()
-      {
-	_Base_iterator __end = _Base::end();
-	this->_M_invalidate_if([__end](_Base_const_iterator __it)
-			{ return __it != __end; });
-	_M_invalidate_locals();
-      }
-
-      void
       _M_check_rehashed(size_type __prev_count)
       {
 	if (__prev_count != this->bucket_count())
-	  _M_invalidate_locals();
+	  this->_M_invalidate_locals();
       }
     };
 
Index: include/debug/unordered_set
===================================================================
--- include/debug/unordered_set	(revision 209879)
+++ include/debug/unordered_set	(working copy)
@@ -35,6 +35,7 @@
 # include <unordered_set>
 
 #include <debug/safe_unordered_container.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 #include <debug/safe_local_iterator.h>
 
@@ -48,20 +49,21 @@
 	   typename _Pred = std::equal_to<_Value>,
 	   typename _Alloc = std::allocator<_Value> >
     class unordered_set
-    : public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>,
-      public __gnu_debug::_Safe_unordered_container<unordered_set<_Value, _Hash,
-						       _Pred, _Alloc> >
+    : public __gnu_debug::_Safe_container<
+	unordered_set<_Value, _Hash, _Pred, _Alloc>, _Alloc,
+	__gnu_debug::_Safe_unordered_container>,
+      public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>
     {
-      typedef _GLIBCXX_STD_C::unordered_set<_Value, _Hash,
-					    _Pred, _Alloc> _Base;
-      typedef __gnu_debug::_Safe_unordered_container<unordered_set> _Safe_base;
+      typedef _GLIBCXX_STD_C::unordered_set<
+	_Value, _Hash, _Pred, _Alloc>					_Base;
+      typedef __gnu_debug::_Safe_container<
+	unordered_set, _Alloc, __gnu_debug::_Safe_unordered_container>	_Safe;
+
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
       typedef typename _Base::local_iterator _Base_local_iterator;
 
-      typedef __gnu_cxx::__alloc_traits<typename
-					_Base::allocator_type> _Alloc_traits;
     public:
       typedef typename _Base::size_type       size_type;
       typedef typename _Base::hasher          hasher;
@@ -71,14 +73,14 @@
       typedef typename _Base::key_type        key_type;
       typedef typename _Base::value_type      value_type;
 
-      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
-					  unordered_set> iterator;
-      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
-					  unordered_set> const_iterator;
-      typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
-					  unordered_set> local_iterator;
-      typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
-					  unordered_set> const_local_iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_iterator, unordered_set>			iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_const_iterator, unordered_set>		const_iterator;
+      typedef __gnu_debug::_Safe_local_iterator<
+	_Base_local_iterator, unordered_set>		local_iterator;
+      typedef __gnu_debug::_Safe_local_iterator<
+	_Base_const_local_iterator, unordered_set>	const_local_iterator;
 
       explicit
       unordered_set(size_type __n = 10,
@@ -88,10 +90,10 @@
       : _Base(__n, __hf, __eql, __a) { }
 
       template<typename _InputIterator>
-        unordered_set(_InputIterator __first, _InputIterator __last, 
+	unordered_set(_InputIterator __first, _InputIterator __last,
 		      size_type __n = 0,
-		      const hasher& __hf = hasher(), 
-		      const key_equal& __eql = key_equal(), 
+		      const hasher& __hf = hasher(),
+		      const key_equal& __eql = key_equal(),
 		      const allocator_type& __a = allocator_type())
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
@@ -107,18 +109,16 @@
 
       explicit
       unordered_set(const allocator_type& __a)
-	: _Base(__a)
-      { }
+      : _Base(__a) { }
 
       unordered_set(const unordered_set& __uset,
 		    const allocator_type& __a)
-	: _Base(__uset._M_base(), __a)
-      { }
+      : _Base(__uset, __a) { }
 
       unordered_set(unordered_set&& __uset,
 		    const allocator_type& __a)
-	: _Base(std::move(__uset._M_base()), __a)
-      { }
+      : _Safe(std::move(__uset._M_safe()), __a),
+	_Base(std::move(__uset._M_base()), __a) { }
 
       unordered_set(initializer_list<value_type> __l,
 		    size_type __n = 0,
@@ -127,31 +127,13 @@
 		    const allocator_type& __a = allocator_type())
       : _Base(__l, __n, __hf, __eql, __a) { }
 
-      ~unordered_set() noexcept { }
+      ~unordered_set() = default;
 
       unordered_set&
-      operator=(const unordered_set& __x)
-      {
-	_M_base() = __x._M_base();
-	this->_M_invalidate_all();
-	return *this;
-      }
+      operator=(const unordered_set&) = default;
 
       unordered_set&
-      operator=(unordered_set&& __x)
-      noexcept(_Alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__x);
-	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
-	    || __x.get_allocator() == this->get_allocator();
-	_M_base() = std::move(__x._M_base());
-	if (__xfer_memory)
-	  this->_M_swap(__x);
-	else
-	  this->_M_invalidate_all();
-	__x._M_invalidate_all();
-	return *this;
-      }
+      operator=(unordered_set&&) = default;
 
       unordered_set&
       operator=(initializer_list<value_type> __l)
@@ -163,12 +145,10 @@
 
       void
       swap(unordered_set& __x)
-      noexcept(_Alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
       {
-	if (!_Alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__x);
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	_Safe_base::_M_swap(__x);
       }
 
       void
@@ -178,7 +158,7 @@
 	this->_M_invalidate_all();
       }
 
-      iterator 
+      iterator
       begin() noexcept
       { return iterator(_Base::begin(), this); }
 
@@ -290,8 +270,8 @@
       insert(const value_type& __obj)
       {
 	size_type __bucket_count = this->bucket_count();
-	typedef std::pair<_Base_iterator, bool> __pair_type;
-	  __pair_type __res = _Base::insert(__obj);
+	std::pair<_Base_iterator, bool> __res
+	  = _Base::insert(__obj);
 	_M_check_rehashed(__bucket_count);
 	return std::make_pair(iterator(__res.first, this), __res.second);
       }
@@ -310,8 +290,8 @@
       insert(value_type&& __obj)
       {
 	size_type __bucket_count = this->bucket_count();
-	typedef std::pair<typename _Base::iterator, bool> __pair_type;
-	  __pair_type __res = _Base::insert(std::move(__obj));
+	std::pair<_Base_iterator, bool> __res
+	  = _Base::insert(std::move(__obj));
 	_M_check_rehashed(__bucket_count);
 	return std::make_pair(iterator(__res.first, this), __res.second);
       }
@@ -356,8 +336,8 @@
       std::pair<iterator, iterator>
       equal_range(const key_type& __key)
       {
-	typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
-	__pair_type __res = _Base::equal_range(__key);
+	std::pair<_Base_iterator, _Base_iterator> __res
+	  = _Base::equal_range(__key);
 	return std::make_pair(iterator(__res.first, this),
 			      iterator(__res.second, this));
       }
@@ -446,29 +426,10 @@
 
     private:
       void
-      _M_invalidate_locals()
-      {
-	_Base_local_iterator __local_end = _Base::end(0);
-	this->_M_invalidate_local_if(
-			[__local_end](_Base_const_local_iterator __it)
-			{ return __it != __local_end; });
-      }
-
-      void
-      _M_invalidate_all()
-      {
-	_Base_iterator __end = _Base::end();
-	this->_M_invalidate_if(
-			[__end](_Base_const_iterator __it)
-			{ return __it != __end; });
-	_M_invalidate_locals();
-      }
-
-      void
       _M_check_rehashed(size_type __prev_count)
       {
 	if (__prev_count != this->bucket_count())
-	  _M_invalidate_locals();
+	  this->_M_invalidate_locals();
       }
     };
 
@@ -497,22 +458,21 @@
 	   typename _Pred = std::equal_to<_Value>,
 	   typename _Alloc = std::allocator<_Value> >
     class unordered_multiset
-    : public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
-      public __gnu_debug::_Safe_unordered_container<
-		unordered_multiset<_Value, _Hash, _Pred, _Alloc> >
+    : public __gnu_debug::_Safe_container<
+	unordered_multiset<_Value, _Hash, _Pred, _Alloc>, _Alloc,
+	__gnu_debug::_Safe_unordered_container>,
+      public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>
     {
-      typedef _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash,
-						 _Pred, _Alloc> _Base;
-      typedef __gnu_debug::_Safe_unordered_container<unordered_multiset>
-		_Safe_base;
+      typedef _GLIBCXX_STD_C::unordered_multiset<
+	_Value, _Hash, _Pred, _Alloc>				_Base;
+      typedef __gnu_debug::_Safe_container<unordered_multiset,
+	_Alloc, __gnu_debug::_Safe_unordered_container>		_Safe;
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef typename _Base::iterator _Base_iterator;
-      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
+      typedef typename _Base::const_local_iterator
+						_Base_const_local_iterator;
       typedef typename _Base::local_iterator _Base_local_iterator;
 
-      typedef __gnu_cxx::__alloc_traits<typename
-					_Base::allocator_type> _Alloc_traits;
-
     public:
       typedef typename _Base::size_type       size_type;
       typedef typename _Base::hasher          hasher;
@@ -522,10 +482,10 @@
       typedef typename _Base::key_type        key_type;
       typedef typename _Base::value_type      value_type;
 
-      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
-					  unordered_multiset> iterator;
-      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
-					  unordered_multiset> const_iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_iterator, unordered_multiset>		iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_const_iterator, unordered_multiset>	const_iterator;
       typedef __gnu_debug::_Safe_local_iterator<
 	_Base_local_iterator, unordered_multiset> local_iterator;
       typedef __gnu_debug::_Safe_local_iterator<
@@ -539,10 +499,10 @@
       : _Base(__n, __hf, __eql, __a) { }
 
       template<typename _InputIterator>
-        unordered_multiset(_InputIterator __first, _InputIterator __last, 
+	unordered_multiset(_InputIterator __first, _InputIterator __last,
 			   size_type __n = 0,
-			   const hasher& __hf = hasher(), 
-			   const key_equal& __eql = key_equal(), 
+			   const hasher& __hf = hasher(),
+			   const key_equal& __eql = key_equal(),
 			   const allocator_type& __a = allocator_type())
 	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
@@ -551,25 +511,23 @@
 
       unordered_multiset(const unordered_multiset&) = default;
 
-      unordered_multiset(const _Base& __x) 
+      unordered_multiset(const _Base& __x)
       : _Base(__x) { }
 
       unordered_multiset(unordered_multiset&&) = default;
 
       explicit
       unordered_multiset(const allocator_type& __a)
-	: _Base(__a)
-      { }
+      : _Base(__a) { }
 
       unordered_multiset(const unordered_multiset& __uset,
 			 const allocator_type& __a)
-	: _Base(__uset._M_base(), __a)
-      { }
-      
+      : _Base(__uset, __a) { }
+
       unordered_multiset(unordered_multiset&& __uset,
 			 const allocator_type& __a)
-	: _Base(std::move(__uset._M_base()), __a)
-      { }
+      : _Safe(std::move(__uset._M_safe()), __a),
+	_Base(std::move(__uset._M_base()), __a) { }
 
       unordered_multiset(initializer_list<value_type> __l,
 			 size_type __n = 0,
@@ -578,48 +536,28 @@
 			 const allocator_type& __a = allocator_type())
       : _Base(__l, __n, __hf, __eql, __a) { }
 
-      ~unordered_multiset() noexcept { }
+      ~unordered_multiset() = default;
 
       unordered_multiset&
-      operator=(const unordered_multiset& __x)
-      {
-	_M_base() = __x._M_base();
-	this->_M_invalidate_all();
-	return *this;
-      }
+      operator=(const unordered_multiset&) = default;
 
       unordered_multiset&
-      operator=(unordered_multiset&& __x)
-      noexcept(_Alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__x);
-	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
-	    || __x.get_allocator() == this->get_allocator();
-	_M_base() = std::move(__x._M_base());
-	if (__xfer_memory)
-	  this->_M_swap(__x);
-	else
-	  this->_M_invalidate_all();
-	__x._M_invalidate_all();
-	return *this;
-      }
+      operator=(unordered_multiset&&) = default;
 
       unordered_multiset&
       operator=(initializer_list<value_type> __l)
       {
-	_M_base() = __l;
+	this->_M_base() = __l;
 	this->_M_invalidate_all();
 	return *this;
       }
 
       void
       swap(unordered_multiset& __x)
-      noexcept(_Alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
       {
-	if (!_Alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__x);
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	_Safe_base::_M_swap(__x);
       }
 
       void
@@ -751,7 +689,7 @@
       {
 	__glibcxx_check_insert(__hint);
 	size_type __bucket_count = this->bucket_count();
-	_Base_iterator __it = _Base::insert(__hint.base(), __obj); 
+	_Base_iterator __it = _Base::insert(__hint.base(), __obj);
 	_M_check_rehashed(__bucket_count);
 	return iterator(__it, this);
       }
@@ -760,7 +698,7 @@
       insert(value_type&& __obj)
       {
 	size_type __bucket_count = this->bucket_count();
-	_Base_iterator __it = _Base::insert(std::move(__obj)); 
+	_Base_iterator __it = _Base::insert(std::move(__obj));
 	_M_check_rehashed(__bucket_count);
 	return iterator(__it, this);
       }
@@ -770,7 +708,7 @@
       {
 	__glibcxx_check_insert(__hint);
 	size_type __bucket_count = this->bucket_count();
-	_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj)); 
+	_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
 	_M_check_rehashed(__bucket_count);
 	return iterator(__it, this);
       }
@@ -805,8 +743,8 @@
       std::pair<iterator, iterator>
       equal_range(const key_type& __key)
       {
-	typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
-	__pair_type __res = _Base::equal_range(__key);
+	std::pair<_Base_iterator, _Base_iterator> __res
+	  = _Base::equal_range(__key);
 	return std::make_pair(iterator(__res.first, this),
 			      iterator(__res.second, this));
       }
@@ -885,28 +823,10 @@
 
     private:
       void
-      _M_invalidate_locals()
-      {
-	_Base_local_iterator __local_end = _Base::end(0);
-	this->_M_invalidate_local_if(
-			[__local_end](_Base_const_local_iterator __it)
-			{ return __it != __local_end; });
-      }
-
-      void
-      _M_invalidate_all()
-      {
-	_Base_iterator __end = _Base::end();
-	this->_M_invalidate_if([__end](_Base_const_iterator __it)
-			{ return __it != __end; });
-	_M_invalidate_locals();
-      }
-
-      void
       _M_check_rehashed(size_type __prev_count)
       {
 	if (__prev_count != this->bucket_count())
-	  _M_invalidate_locals();
+	  this->_M_invalidate_locals();
       }
     };
 
Index: include/debug/vector
===================================================================
--- include/debug/vector	(revision 209879)
+++ include/debug/vector	(working copy)
@@ -32,8 +32,68 @@
 #include <vector>
 #include <utility>
 #include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
 #include <debug/safe_iterator.h>
 
+namespace __gnu_debug
+{
+  /// Special vector safe base class to add a guaranteed capacity information
+  /// useful to detect code relying on the libstdc++ reallocation management
+  /// implementation detail.
+  template<typename _SafeSequence,
+	   typename _BaseSequence>
+    class _Safe_vector
+    {
+      typedef typename _BaseSequence::size_type size_type;
+
+      const _SafeSequence&
+      _M_seq() const { return *static_cast<const _SafeSequence*>(this); }
+
+    protected:
+      _Safe_vector() _GLIBCXX_NOEXCEPT
+	: _M_guaranteed_capacity(0)
+      { _M_update_guaranteed_capacity(); }
+
+      _Safe_vector(const _Safe_vector&) _GLIBCXX_NOEXCEPT
+	: _M_guaranteed_capacity(0)
+      { _M_update_guaranteed_capacity(); }
+
+      _Safe_vector(size_type __n) _GLIBCXX_NOEXCEPT
+	: _M_guaranteed_capacity(__n)
+      { }
+
+#if __cplusplus >= 201103L
+      _Safe_vector(_Safe_vector&& __x) noexcept
+	: _Safe_vector()
+      { __x._M_guaranteed_capacity = 0; }
+
+      _Safe_vector&
+      operator=(const _Safe_vector&) noexcept
+      { _M_update_guaranteed_capacity(); }
+
+      _Safe_vector&
+      operator=(_Safe_vector&& __x) noexcept
+      {
+	_M_update_guaranteed_capacity();
+	__x._M_guaranteed_capacity = 0;
+      }
+#endif
+
+      size_type _M_guaranteed_capacity;
+
+      bool
+      _M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
+      { return __elements > _M_seq().capacity(); }
+
+      void
+      _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT
+      {
+	if (_M_seq().size() > _M_guaranteed_capacity)
+	  _M_guaranteed_capacity = _M_seq().size();
+      }
+    };
+}
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 namespace __debug
@@ -42,28 +102,30 @@
   template<typename _Tp,
 	   typename _Allocator = std::allocator<_Tp> >
     class vector
-    : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
-      public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
+    : public __gnu_debug::_Safe_container<
+	vector<_Tp, _Allocator>, _Allocator, __gnu_debug::_Safe_sequence>,
+      public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
+      public __gnu_debug::_Safe_vector<
+	vector<_Tp, _Allocator>,
+	_GLIBCXX_STD_C::vector<_Tp, _Allocator> >
     {
       typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_container<
+	vector, _Allocator, __gnu_debug::_Safe_sequence>	_Safe;
+      typedef __gnu_debug::_Safe_vector<vector, _Base>		_Safe_vector;
 
       typedef typename _Base::iterator _Base_iterator;
       typedef typename _Base::const_iterator _Base_const_iterator;
       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
 
-#if __cplusplus >= 201103L
-      typedef __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > _Safe_base;
-      typedef __gnu_cxx::__alloc_traits<_Allocator>  _Alloc_traits;
-#endif
-
     public:
       typedef typename _Base::reference             reference;
       typedef typename _Base::const_reference       const_reference;
 
-      typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector>
-      iterator;
-      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector>
-      const_iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_iterator, vector>				iterator;
+      typedef __gnu_debug::_Safe_iterator<
+	_Base_const_iterator, vector>			const_iterator;
 
       typedef typename _Base::size_type             size_type;
       typedef typename _Base::difference_type       difference_type;
@@ -77,26 +139,30 @@
 
       // 23.2.4.1 construct/copy/destroy:
 
+#if __cplusplus < 201103L
       vector() _GLIBCXX_NOEXCEPT
-      : _Base(), _M_guaranteed_capacity(0) { }
+      : _Base() { }
+#else
+      vector() = default;
+#endif
 
       explicit
       vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
-      : _Base(__a), _M_guaranteed_capacity(0) { }
+      : _Base(__a) { }
 
 #if __cplusplus >= 201103L
       explicit
       vector(size_type __n, const _Allocator& __a = _Allocator())
-      : _Base(__n, __a), _M_guaranteed_capacity(__n) { }
+      : _Base(__n, __a), _Safe_vector(__n) { }
 
       vector(size_type __n, const _Tp& __value,
 	     const _Allocator& __a = _Allocator())
-      : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
+      : _Base(__n, __value, __a) { }
 #else
       explicit
       vector(size_type __n, const _Tp& __value = _Tp(),
 	     const _Allocator& __a = _Allocator())
-      : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
+      : _Base(__n, __value, __a) { }
 #endif
 
 #if __cplusplus >= 201103L
@@ -109,79 +175,58 @@
 	       const _Allocator& __a = _Allocator())
         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 								     __last)),
-		__gnu_debug::__base(__last), __a),
-	  _M_guaranteed_capacity(0)
-        { _M_update_guaranteed_capacity(); }
+		__gnu_debug::__base(__last), __a) { }
 
+#if __cplusplus < 201103L
       vector(const vector& __x)
-      : _Base(__x), _M_guaranteed_capacity(__x.size()) { }
+      : _Base(__x) { }
 
-      /// Construction from a normal-mode vector
-      vector(const _Base& __x)
-      : _Base(__x), _M_guaranteed_capacity(__x.size()) { }
+      ~vector() _GLIBCXX_NOEXCEPT { }
+#else
+      vector(const vector&) = default;
+      vector(vector&&) = default;
 
-#if __cplusplus >= 201103L
-      vector(vector&& __x) noexcept
-      : _Base(std::move(__x)),
-	_Safe_base(std::move(__x)),
-	_M_guaranteed_capacity(this->size())
-      { __x._M_guaranteed_capacity = 0; }
-
       vector(const vector& __x, const allocator_type& __a)
-      : _Base(__x, __a), _M_guaranteed_capacity(__x.size()) { }
+      : _Base(__x, __a) { }
 
       vector(vector&& __x, const allocator_type& __a)
-      : _Base(std::move(__x), __a),
-        _M_guaranteed_capacity(this->size())
-      {
-	if (__x.get_allocator() == __a)
-	  this->_M_swap(__x);
-	else
-	  __x._M_invalidate_all();
-	__x._M_guaranteed_capacity = 0;
-      }
+      : _Safe(std::move(__x._M_safe()), __a),
+	_Base(std::move(__x._M_base()), __a),
+	_Safe_vector(std::move(__x)) { }
 
       vector(initializer_list<value_type> __l,
 	     const allocator_type& __a = allocator_type())
-      : _Base(__l, __a),
-	_M_guaranteed_capacity(__l.size()) { }
+      : _Base(__l, __a) { }
+
+      ~vector() = default;
 #endif
 
-      ~vector() _GLIBCXX_NOEXCEPT { }
+      /// Construction from a normal-mode vector
+      vector(const _Base& __x)
+      : _Base(__x) { }
 
+#if __cplusplus < 201103L
       vector&
       operator=(const vector& __x)
       {
+	this->_M_safe() = __x;
 	_M_base() = __x;
-	this->_M_invalidate_all();
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
 	return *this;
       }
+#else
+      vector&
+      operator=(const vector&) = default;
 
-#if __cplusplus >= 201103L
       vector&
-      operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
-      {
-	__glibcxx_check_self_move_assign(__x);
-	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
-	    || __x.get_allocator() == this->get_allocator();
-	_M_base() = std::move(__x._M_base());
-	if (__xfer_memory)
-	  this->_M_swap(__x);
-	else
-	  this->_M_invalidate_all();
-	_M_update_guaranteed_capacity();
-	__x._M_invalidate_all();
-	__x._M_guaranteed_capacity = 0;
-	return *this;
-      }
+      operator=(vector&&) = default;
 
       vector&
       operator=(initializer_list<value_type> __l)
       {
 	_M_base() = __l;
 	this->_M_invalidate_all();
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
 	return *this;
       }
 #endif
@@ -199,7 +244,7 @@
 	  _Base::assign(__gnu_debug::__base(__first),
 			__gnu_debug::__base(__last));
 	  this->_M_invalidate_all();
-	  _M_update_guaranteed_capacity();
+	  this->_M_update_guaranteed_capacity();
 	}
 
       void
@@ -207,7 +252,7 @@
       {
 	_Base::assign(__n, __u);
 	this->_M_invalidate_all();
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
       }
 
 #if __cplusplus >= 201103L
@@ -216,7 +261,7 @@
       {
 	_Base::assign(__l);
 	this->_M_invalidate_all();
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
       }
 #endif
 
@@ -281,37 +326,37 @@
       void
       resize(size_type __sz)
       {
-	bool __realloc = _M_requires_reallocation(__sz);
+	bool __realloc = this->_M_requires_reallocation(__sz);
 	if (__sz < this->size())
 	  this->_M_invalidate_after_nth(__sz);
 	_Base::resize(__sz);
 	if (__realloc)
 	  this->_M_invalidate_all();
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
       }
 
       void
       resize(size_type __sz, const _Tp& __c)
       {
-	bool __realloc = _M_requires_reallocation(__sz);
+	bool __realloc = this->_M_requires_reallocation(__sz);
 	if (__sz < this->size())
 	  this->_M_invalidate_after_nth(__sz);
 	_Base::resize(__sz, __c);
 	if (__realloc)
 	  this->_M_invalidate_all();
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
       }
 #else
       void
       resize(size_type __sz, _Tp __c = _Tp())
       {
-	bool __realloc = _M_requires_reallocation(__sz);
+	bool __realloc = this->_M_requires_reallocation(__sz);
 	if (__sz < this->size())
 	  this->_M_invalidate_after_nth(__sz);
 	_Base::resize(__sz, __c);
 	if (__realloc)
 	  this->_M_invalidate_all();
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
       }
 #endif
 
@@ -321,7 +366,7 @@
       {
 	if (_Base::_M_shrink_to_fit())
 	  {
-	    _M_guaranteed_capacity = _Base::capacity();
+	    this->_M_guaranteed_capacity = _Base::capacity();
 	    this->_M_invalidate_all();
 	  }
       }
@@ -331,7 +376,7 @@
       capacity() const _GLIBCXX_NOEXCEPT
       {
 #ifdef _GLIBCXX_DEBUG_PEDANTIC
-	return _M_guaranteed_capacity;
+	return this->_M_guaranteed_capacity;
 #else
 	return _Base::capacity();
 #endif
@@ -342,10 +387,10 @@
       void
       reserve(size_type __n)
       {
-	bool __realloc = _M_requires_reallocation(__n);
+	bool __realloc = this->_M_requires_reallocation(__n);
 	_Base::reserve(__n);
-	if (__n > _M_guaranteed_capacity)
-	  _M_guaranteed_capacity = __n;
+	if (__n > this->_M_guaranteed_capacity)
+	  this->_M_guaranteed_capacity = __n;
 	if (__realloc)
 	  this->_M_invalidate_all();
       }
@@ -403,11 +448,11 @@
       void
       push_back(const _Tp& __x)
       {
-	bool __realloc = _M_requires_reallocation(this->size() + 1);
+	bool __realloc = this->_M_requires_reallocation(this->size() + 1);
 	_Base::push_back(__x);
 	if (__realloc)
 	  this->_M_invalidate_all();
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
       }
 
 #if __cplusplus >= 201103L
@@ -421,11 +466,11 @@
         void
         emplace_back(_Args&&... __args)
 	{
-	  bool __realloc = _M_requires_reallocation(this->size() + 1);
+	  bool __realloc = this->_M_requires_reallocation(this->size() + 1);
 	  _Base::emplace_back(std::forward<_Args>(__args)...);
 	  if (__realloc)
 	    this->_M_invalidate_all();
-	  _M_update_guaranteed_capacity();
+	  this->_M_update_guaranteed_capacity();
 	}
 #endif
 
@@ -443,7 +488,7 @@
         emplace(const_iterator __position, _Args&&... __args)
 	{
 	  __glibcxx_check_insert(__position);
-	  bool __realloc = _M_requires_reallocation(this->size() + 1);
+	  bool __realloc = this->_M_requires_reallocation(this->size() + 1);
 	  difference_type __offset = __position.base() - _Base::begin();
 	  _Base_iterator __res = _Base::emplace(__position.base(),
 						std::forward<_Args>(__args)...);
@@ -451,7 +496,7 @@
 	    this->_M_invalidate_all();
 	  else
 	    this->_M_invalidate_after_nth(__offset);
-	  _M_update_guaranteed_capacity();
+	  this->_M_update_guaranteed_capacity();
 	  return iterator(__res, this);
 	}
 #endif
@@ -464,14 +509,14 @@
 #endif
       {
 	__glibcxx_check_insert(__position);
-	bool __realloc = _M_requires_reallocation(this->size() + 1);
+	bool __realloc = this->_M_requires_reallocation(this->size() + 1);
 	difference_type __offset = __position.base() - _Base::begin();
 	_Base_iterator __res = _Base::insert(__position.base(), __x);
 	if (__realloc)
 	  this->_M_invalidate_all();
 	else
 	  this->_M_invalidate_after_nth(__offset);
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
 	return iterator(__res, this);
       }
 
@@ -492,14 +537,14 @@
       insert(const_iterator __position, size_type __n, const _Tp& __x)
       {
 	__glibcxx_check_insert(__position);
-	bool __realloc = _M_requires_reallocation(this->size() + __n);
+	bool __realloc = this->_M_requires_reallocation(this->size() + __n);
 	difference_type __offset = __position.base() - _Base::cbegin();
 	_Base_iterator __res = _Base::insert(__position.base(), __n, __x);
 	if (__realloc)
 	  this->_M_invalidate_all();
 	else
 	  this->_M_invalidate_after_nth(__offset);
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
 	return iterator(__res, this);
       }
 #else
@@ -507,14 +552,14 @@
       insert(iterator __position, size_type __n, const _Tp& __x)
       {
 	__glibcxx_check_insert(__position);
-	bool __realloc = _M_requires_reallocation(this->size() + __n);
+	bool __realloc = this->_M_requires_reallocation(this->size() + __n);
 	difference_type __offset = __position.base() - _Base::begin();
 	_Base::insert(__position.base(), __n, __x);
 	if (__realloc)
 	  this->_M_invalidate_all();
 	else
 	  this->_M_invalidate_after_nth(__offset);
-	_M_update_guaranteed_capacity();
+	this->_M_update_guaranteed_capacity();
       }
 #endif
 
@@ -540,7 +585,7 @@
 	    this->_M_invalidate_all();
 	  else
 	    this->_M_invalidate_after_nth(__offset);
-	  _M_update_guaranteed_capacity();
+	  this->_M_update_guaranteed_capacity();
 	  return iterator(__res, this);
 	}
 #else
@@ -563,7 +608,7 @@
 	    this->_M_invalidate_all();
 	  else
 	    this->_M_invalidate_after_nth(__offset);
-	  _M_update_guaranteed_capacity();
+	  this->_M_update_guaranteed_capacity();
 	}
 #endif
 
@@ -611,16 +656,12 @@
       void
       swap(vector& __x)
 #if __cplusplus >= 201103L
-			noexcept(_Alloc_traits::_S_nothrow_swap())
+	noexcept( noexcept(declval<_Base>().swap(__x)) )
 #endif
       {
-#if __cplusplus >= 201103L
-	if (!_Alloc_traits::_S_propagate_on_swap())
-	  __glibcxx_check_equal_allocs(__x);
-#endif
+	_Safe::_M_swap(__x);
 	_Base::swap(__x);
-	this->_M_swap(__x);
-        std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
+	std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
       }
 
       void
@@ -628,7 +669,7 @@
       {
 	_Base::clear();
 	this->_M_invalidate_all();
-        _M_guaranteed_capacity = 0;
+	this->_M_guaranteed_capacity = 0;
       }
 
       _Base&
@@ -638,20 +679,7 @@
       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
 
     private:
-      size_type _M_guaranteed_capacity;
-
-      bool
-      _M_requires_reallocation(size_type __elements) _GLIBCXX_NOEXCEPT
-      { return __elements > this->capacity(); }
-
       void
-      _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) _GLIBCXX_NOEXCEPT
       {
 	typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
Index: src/c++11/debug.cc
===================================================================
--- src/c++11/debug.cc	(revision 209879)
+++ src/c++11/debug.cc	(working copy)
@@ -23,8 +23,8 @@
 // <http://www.gnu.org/licenses/>.
 
 #include <debug/debug.h>
-#include <debug/safe_sequence.h>
-#include <debug/safe_unordered_container.h>
+#include <debug/safe_base.h>
+#include <debug/safe_unordered_base.h>
 #include <debug/safe_iterator.h>
 #include <debug/safe_local_iterator.h>
 #include <algorithm>
@@ -235,7 +235,7 @@
 
   void
   _Safe_sequence_base::
-  _M_swap(_Safe_sequence_base& __x)
+  _M_swap(_Safe_sequence_base& __x) noexcept
   {
     // We need to lock both sequences to swap
     using namespace __gnu_cxx;
@@ -382,7 +382,7 @@
 
   _Safe_unordered_container_base*
   _Safe_local_iterator_base::
-  _M_get_container() const _GLIBCXX_NOEXCEPT
+  _M_get_container() const noexcept
   { return static_cast<_Safe_unordered_container_base*>(_M_sequence); }
 
   void
@@ -455,7 +455,7 @@
 
   void
   _Safe_unordered_container_base::
-  _M_swap(_Safe_unordered_container_base& __x)
+  _M_swap(_Safe_unordered_container_base& __x) noexcept
   {
     // We need to lock both containers to swap
     using namespace __gnu_cxx;
Index: testsuite/23_containers/forward_list/allocator/move.cc
===================================================================
--- testsuite/23_containers/forward_list/allocator/move.cc	(revision 209879)
+++ testsuite/23_containers/forward_list/allocator/move.cc	(working copy)
@@ -32,9 +32,11 @@
   typedef std::forward_list<T, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { T() };
+  auto it = v1.begin();
   test_type v2(std::move(v1));
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 void test02()
Index: testsuite/23_containers/forward_list/allocator/move_assign.cc
===================================================================
--- testsuite/23_containers/forward_list/allocator/move_assign.cc	(revision 209879)
+++ testsuite/23_containers/forward_list/allocator/move_assign.cc	(working copy)
@@ -46,11 +46,13 @@
   typedef std::forward_list<T, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1.push_front(T());
+  auto it = v1.begin();
   test_type v2(alloc_type(2));
   v2.push_front(T());
   v2 = std::move(v1);
   VERIFY(0 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 int main()
Index: testsuite/23_containers/forward_list/debug/construct1_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/debug/construct1_neg.cc	(revision 0)
+++ testsuite/23_containers/forward_list/debug/construct1_neg.cc	(working copy)
@@ -0,0 +1,34 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-require-debug-mode "" }
+// { dg-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <forward_list>
+#include <debug/checks.h>
+
+void test01()
+{
+  __gnu_test::check_construct1<std::forward_list<int> >();
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/forward_list/debug/construct2_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/debug/construct2_neg.cc	(revision 0)
+++ testsuite/23_containers/forward_list/debug/construct2_neg.cc	(working copy)
@@ -0,0 +1,34 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-require-debug-mode "" }
+// { dg-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <forward_list>
+#include <debug/checks.h>
+
+void test01()
+{
+  __gnu_test::check_construct2<std::forward_list<int> >();
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/forward_list/debug/construct3_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/debug/construct3_neg.cc	(revision 0)
+++ testsuite/23_containers/forward_list/debug/construct3_neg.cc	(working copy)
@@ -0,0 +1,34 @@
+// Copyright (C) 2010-2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-require-debug-mode "" }
+// { dg-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <forward_list>
+#include <debug/checks.h>
+
+void test01()
+{
+  __gnu_test::check_construct3<std::forward_list<int> >();
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/forward_list/debug/construct4_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/debug/construct4_neg.cc	(revision 0)
+++ testsuite/23_containers/forward_list/debug/construct4_neg.cc	(working copy)
@@ -0,0 +1,44 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/forward_list>
+
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::forward_list<int, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(0);
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it == v2.begin() ); // Error, it is singular
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/forward_list/debug/move_assign_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/debug/move_assign_neg.cc	(revision 0)
+++ testsuite/23_containers/forward_list/debug/move_assign_neg.cc	(working copy)
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/forward_list>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::forward_list<int, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.push_front(0);
+  auto it = v1.begin();
+
+  test_type v2(alloc_type(2));
+  v2.push_front(1);
+
+  v2 = std::move(v1);
+
+  VERIFY( *it == 0 ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/forward_list/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/forward_list/debug/move_neg.cc	(working copy)
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/forward_list>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::forward_list<int, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { 0 };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( *it == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/map/allocator/move.cc
===================================================================
--- testsuite/23_containers/map/allocator/move.cc	(revision 209879)
+++ testsuite/23_containers/map/allocator/move.cc	(working copy)
@@ -38,9 +38,13 @@
   typedef std::map<T, U, Cmp, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { test_type::value_type{} };
+  auto it = v1.begin();
+
   test_type v2(std::move(v1));
+
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 void test02()
Index: testsuite/23_containers/map/allocator/move_assign.cc
===================================================================
--- testsuite/23_containers/map/allocator/move_assign.cc	(revision 209879)
+++ testsuite/23_containers/map/allocator/move_assign.cc	(working copy)
@@ -38,9 +38,11 @@
   typedef std::map<T, U, Cmp, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { test_type::value_type{} };
+
   test_type v2(alloc_type(2));
   v2 = { test_type::value_type{} };
   v2 = std::move(v1);
+
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(2 == v2.get_allocator().get_personality());
 }
@@ -52,11 +54,15 @@
   typedef std::map<T, U, Cmp, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { test_type::value_type{} };
+  auto it = v1.begin();
+
   test_type v2(alloc_type(2));
   v2 = { test_type::value_type{} };
   v2 = std::move(v1);
+
   VERIFY(0 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 int main()
Index: testsuite/23_containers/map/debug/construct5_neg.cc
===================================================================
--- testsuite/23_containers/map/debug/construct5_neg.cc	(revision 0)
+++ testsuite/23_containers/map/debug/construct5_neg.cc	(working copy)
@@ -0,0 +1,45 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/map>
+
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
+  typedef __gnu_debug::map<int, int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(std::make_pair(0, 0));
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it->first == 0 ); // Error, it is singular
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/map/debug/move_assign_neg.cc
===================================================================
--- testsuite/23_containers/map/debug/move_assign_neg.cc	(revision 0)
+++ testsuite/23_containers/map/debug/move_assign_neg.cc	(working copy)
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/map>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
+  typedef __gnu_debug::map<int, int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(std::make_pair(0, 0));
+  auto it = v1.begin();
+
+  test_type v2(alloc_type(2));
+  v2.insert(std::make_pair(1, 1));
+
+  v2 = std::move(v1);
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/map/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/map/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/map/debug/move_neg.cc	(working copy)
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/map>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<std::pair<const int, int> > alloc_type;
+  typedef __gnu_debug::map<int, int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { { 0, 0 } };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it->first == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/multimap/allocator/move.cc
===================================================================
--- testsuite/23_containers/multimap/allocator/move.cc	(revision 209879)
+++ testsuite/23_containers/multimap/allocator/move.cc	(working copy)
@@ -38,9 +38,13 @@
   typedef std::multimap<T, U, Cmp, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { test_type::value_type{} };
+  auto it = v1.begin();
+
   test_type v2(std::move(v1));
+
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 void test02()
Index: testsuite/23_containers/multimap/allocator/move_assign.cc
===================================================================
--- testsuite/23_containers/multimap/allocator/move_assign.cc	(revision 209879)
+++ testsuite/23_containers/multimap/allocator/move_assign.cc	(working copy)
@@ -52,11 +52,13 @@
   typedef std::multimap<T, U, Cmp, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { test_type::value_type{} };
+  auto it = v1.begin();
   test_type v2(alloc_type(2));
   v2 = { test_type::value_type{} };
   v2 = std::move(v1);
   VERIFY(0 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin()  );
 }
 
 int main()
Index: testsuite/23_containers/multimap/debug/construct5_neg.cc
===================================================================
--- testsuite/23_containers/multimap/debug/construct5_neg.cc	(revision 0)
+++ testsuite/23_containers/multimap/debug/construct5_neg.cc	(working copy)
@@ -0,0 +1,45 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/map>
+
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
+  typedef __gnu_debug::multimap<int, int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(std::make_pair(0, 0));
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it->first == 0 ); // Error, it is singular
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/multimap/debug/move_assign_neg.cc
===================================================================
--- testsuite/23_containers/multimap/debug/move_assign_neg.cc	(revision 0)
+++ testsuite/23_containers/multimap/debug/move_assign_neg.cc	(working copy)
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/map>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
+  typedef __gnu_debug::multimap<int, int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(std::make_pair(0, 0));
+  auto it = v1.begin();
+
+  test_type v2(alloc_type(2));
+  v2.insert(std::make_pair(1, 1));
+
+  v2 = std::move(v1);
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/multimap/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/multimap/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/multimap/debug/move_neg.cc	(working copy)
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/map>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<std::pair<const int, int> > alloc_type;
+  typedef __gnu_debug::multimap<int, int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { { 0, 0 } };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it->first == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/multiset/allocator/move.cc
===================================================================
--- testsuite/23_containers/multiset/allocator/move.cc	(revision 209879)
+++ testsuite/23_containers/multiset/allocator/move.cc	(working copy)
@@ -36,9 +36,13 @@
   typedef std::multiset<T, Cmp, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { test_type::value_type{} };
+  auto it = v1.begin();
+
   test_type v2(std::move(v1));
+
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 void test02()
Index: testsuite/23_containers/multiset/allocator/move_assign.cc
===================================================================
--- testsuite/23_containers/multiset/allocator/move_assign.cc	(revision 209879)
+++ testsuite/23_containers/multiset/allocator/move_assign.cc	(working copy)
@@ -50,11 +50,13 @@
   typedef std::multiset<T, Cmp, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { test_type::value_type{} };
+  auto it = v1.begin();
   test_type v2(alloc_type(2));
   v2 = { test_type::value_type{} };
   v2 = std::move(v1);
   VERIFY(0 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 int main()
Index: testsuite/23_containers/multiset/debug/construct5_neg.cc
===================================================================
--- testsuite/23_containers/multiset/debug/construct5_neg.cc	(revision 0)
+++ testsuite/23_containers/multiset/debug/construct5_neg.cc	(working copy)
@@ -0,0 +1,45 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/set>
+
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::multiset<int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(0);
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( *it == 0 ); // Error, it is singular
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/multiset/debug/move_assign_neg.cc
===================================================================
--- testsuite/23_containers/multiset/debug/move_assign_neg.cc	(revision 0)
+++ testsuite/23_containers/multiset/debug/move_assign_neg.cc	(working copy)
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/set>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::multiset<int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(0);
+  auto it = v1.begin();
+
+  test_type v2(alloc_type(2));
+  v2.insert(1);
+
+  v2 = std::move(v1);
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/multiset/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/multiset/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/multiset/debug/move_neg.cc	(working copy)
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/set>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::multiset<int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { 0 };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( *it == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/set/allocator/move.cc
===================================================================
--- testsuite/23_containers/set/allocator/move.cc	(revision 209879)
+++ testsuite/23_containers/set/allocator/move.cc	(working copy)
@@ -38,9 +38,13 @@
   typedef std::set<T, Cmp, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { test_type::value_type{} };
+  auto it = v1.begin();
+
   test_type v2(std::move(v1));
+
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 void test02()
Index: testsuite/23_containers/set/allocator/move_assign.cc
===================================================================
--- testsuite/23_containers/set/allocator/move_assign.cc	(revision 209879)
+++ testsuite/23_containers/set/allocator/move_assign.cc	(working copy)
@@ -50,11 +50,13 @@
   typedef std::set<T, Cmp, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1 = { test_type::value_type{} };
+  auto it = v1.begin();
   test_type v2(alloc_type(2));
   v2 = { test_type::value_type{} };
   v2 = std::move(v1);
   VERIFY(0 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 int main()
Index: testsuite/23_containers/set/debug/construct5_neg.cc
===================================================================
--- testsuite/23_containers/set/debug/construct5_neg.cc	(revision 0)
+++ testsuite/23_containers/set/debug/construct5_neg.cc	(working copy)
@@ -0,0 +1,45 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/set>
+
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::set<int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(0);
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( *it == 0 ); // Error, it is singular
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/set/debug/move_assign_neg.cc
===================================================================
--- testsuite/23_containers/set/debug/move_assign_neg.cc	(revision 0)
+++ testsuite/23_containers/set/debug/move_assign_neg.cc	(working copy)
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/set>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::set<int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(0);
+  auto it = v1.begin();
+
+  test_type v2(alloc_type(2));
+  v2.insert(1);
+
+  v2 = std::move(v1);
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/set/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/set/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/set/debug/move_neg.cc	(working copy)
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/set>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::set<int, std::less<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { 0 };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( *it == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_map/allocator/move.cc
===================================================================
--- testsuite/23_containers/unordered_map/allocator/move.cc	(revision 209879)
+++ testsuite/23_containers/unordered_map/allocator/move.cc	(working copy)
@@ -45,9 +45,11 @@
   test_type v1(alloc_type(1));
   v1.emplace(std::piecewise_construct,
 	     std::make_tuple(T()), std::make_tuple(T()));
+  auto it = v1.begin();
   test_type v2(std::move(v1));
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 void test02()
Index: testsuite/23_containers/unordered_map/allocator/move_assign.cc
===================================================================
--- testsuite/23_containers/unordered_map/allocator/move_assign.cc	(revision 209879)
+++ testsuite/23_containers/unordered_map/allocator/move_assign.cc	(working copy)
@@ -66,6 +66,8 @@
   v1.emplace(std::piecewise_construct,
 	     std::make_tuple(1), std::make_tuple(1));
 
+  auto it = v1.begin();
+
   test_type v2(alloc_type(2));
   v2.emplace(std::piecewise_construct,
 	     std::make_tuple(2), std::make_tuple(2));
@@ -79,6 +81,8 @@
 
   VERIFY( counter_type::move_assign_count == 0 );
   VERIFY( counter_type::destructor_count == 2 );
+
+  VERIFY( it == v2.begin() );
 }
 
 int main()
Index: testsuite/23_containers/unordered_map/debug/construct5_neg.cc
===================================================================
--- testsuite/23_containers/unordered_map/debug/construct5_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_map/debug/construct5_neg.cc	(working copy)
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_map>
+
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<std::pair<const int, int>> alloc_type;
+  typedef __gnu_debug::unordered_map<int, int, std::hash<int>,
+				     std::equal_to<int>,
+				     alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(std::make_pair(0, 0));
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_map/debug/move_assign_neg.cc
===================================================================
--- testsuite/23_containers/unordered_map/debug/move_assign_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_map/debug/move_assign_neg.cc	(working copy)
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_map>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
+  typedef __gnu_debug::unordered_map<int, int,
+				     std::hash<int>, std::equal_to<int>,
+				     alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(std::make_pair(0, 0));
+  auto it = v1.begin();
+
+  test_type v2(alloc_type(2));
+
+  v2 = std::move(v1);
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_map/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/unordered_map/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_map/debug/move_neg.cc	(working copy)
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_map>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<std::pair<const int, int> > alloc_type;
+  typedef __gnu_debug::unordered_map<
+    int, int, std::hash<int>, std::equal_to<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { { 0, 0 } };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it->first == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_multimap/allocator/move.cc
===================================================================
--- testsuite/23_containers/unordered_multimap/allocator/move.cc	(revision 209879)
+++ testsuite/23_containers/unordered_multimap/allocator/move.cc	(working copy)
@@ -45,9 +45,11 @@
   test_type v1(alloc_type(1));
   v1.emplace(std::piecewise_construct,
 	     std::make_tuple(T()), std::make_tuple(T()));
+  auto it = v1.begin();
   test_type v2(std::move(v1));
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 void test02()
Index: testsuite/23_containers/unordered_multimap/allocator/move_assign.cc
===================================================================
--- testsuite/23_containers/unordered_multimap/allocator/move_assign.cc	(revision 209879)
+++ testsuite/23_containers/unordered_multimap/allocator/move_assign.cc	(working copy)
@@ -66,6 +66,8 @@
   v1.emplace(std::piecewise_construct,
 	     std::make_tuple(1), std::make_tuple(1));
 
+  auto it = v1.begin();
+
   test_type v2(alloc_type(2));
   v2.emplace(std::piecewise_construct,
 	     std::make_tuple(2), std::make_tuple(2));
@@ -79,6 +81,8 @@
 
   VERIFY( counter_type::move_assign_count == 0 );
   VERIFY( counter_type::destructor_count == 2 );
+
+  VERIFY( it == v2.begin() );
 }
 
 int main()
Index: testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc
===================================================================
--- testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc	(working copy)
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_map>
+
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<std::pair<const int, int>> alloc_type;
+  typedef __gnu_debug::unordered_multimap<int, int,
+					  std::hash<int>, std::equal_to<int>,
+					  alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(std::make_pair(0, 0));
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc
===================================================================
--- testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc	(working copy)
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_map>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<std::pair<const int, int>> alloc_type;
+  typedef __gnu_debug::unordered_multimap<int, int, std::hash<int>,
+					  std::equal_to<int>,
+					  alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(std::make_pair(0, 0));
+  auto it = v1.begin();
+
+  test_type v2(alloc_type(2));
+
+  v2 = std::move(v1);
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_multimap/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/unordered_multimap/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_multimap/debug/move_neg.cc	(working copy)
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_map>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<std::pair<const int, int> > alloc_type;
+  typedef __gnu_debug::unordered_multimap<
+    int, int, std::hash<int>, std::equal_to<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { { 0, 0 } };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it->first == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_multiset/allocator/move.cc
===================================================================
--- testsuite/23_containers/unordered_multiset/allocator/move.cc	(revision 209879)
+++ testsuite/23_containers/unordered_multiset/allocator/move.cc	(working copy)
@@ -44,9 +44,11 @@
   typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1.insert(T());
+  auto it = v1.begin();
   test_type v2(std::move(v1));
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 void test02()
Index: testsuite/23_containers/unordered_multiset/allocator/move_assign.cc
===================================================================
--- testsuite/23_containers/unordered_multiset/allocator/move_assign.cc	(revision 209879)
+++ testsuite/23_containers/unordered_multiset/allocator/move_assign.cc	(working copy)
@@ -63,6 +63,8 @@
   test_type v1(alloc_type(1));
   v1.emplace(0);
 
+  auto it = v1.begin();
+
   test_type v2(alloc_type(2));
   v2.emplace(0);
 
@@ -76,6 +78,8 @@
   VERIFY( counter_type::move_count == 0 );
   VERIFY( counter_type::copy_count == 0 );
   VERIFY( counter_type::destructor_count == 1 );
+
+  VERIFY( it == v2.begin() );
 }
 
 int main()
Index: testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc
===================================================================
--- testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc	(working copy)
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_set>
+
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::unordered_multiset<int, std::hash<int>,
+					  std::equal_to<int>,
+					  alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.insert(0);
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it == v2.begin() ); // Error, it is singular
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc
===================================================================
--- testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc	(working copy)
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_set>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::unordered_multiset<int, std::hash<int>,
+					  std::equal_to<int>,
+					  alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.emplace(0);
+  auto it = v1.begin();
+
+  test_type v2(alloc_type(2));
+  v2.emplace(1);
+
+  v2 = std::move(v1);
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_multiset/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/unordered_multiset/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_multiset/debug/move_neg.cc	(working copy)
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_set>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::unordered_multiset<
+    int, std::hash<int>, std::equal_to<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { 0 };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( *it == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_set/allocator/move.cc
===================================================================
--- testsuite/23_containers/unordered_set/allocator/move.cc	(revision 209879)
+++ testsuite/23_containers/unordered_set/allocator/move.cc	(working copy)
@@ -44,9 +44,11 @@
   typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
   test_type v1(alloc_type(1));
   v1.insert(T());
+  auto it = v1.begin();
   test_type v2(std::move(v1));
   VERIFY(1 == v1.get_allocator().get_personality());
   VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
 }
 
 void test02()
Index: testsuite/23_containers/unordered_set/allocator/move_assign.cc
===================================================================
--- testsuite/23_containers/unordered_set/allocator/move_assign.cc	(revision 209879)
+++ testsuite/23_containers/unordered_set/allocator/move_assign.cc	(working copy)
@@ -63,6 +63,8 @@
   test_type v1(alloc_type(1));
   v1.emplace(0);
 
+  auto it = v1.begin();
+
   test_type v2(alloc_type(2));
   v2.emplace(0);
 
@@ -76,6 +78,8 @@
   VERIFY( counter_type::move_count == 0 );
   VERIFY( counter_type::copy_count == 0 );
   VERIFY( counter_type::destructor_count == 1 );
+
+  VERIFY( it == v2.begin() );
 }
 
 int main()
Index: testsuite/23_containers/unordered_set/debug/construct5_neg.cc
===================================================================
--- testsuite/23_containers/unordered_set/debug/construct5_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_set/debug/construct5_neg.cc	(working copy)
@@ -0,0 +1,45 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_set>
+
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::unordered_set<int, std::hash<int>,
+				     std::equal_to<int>, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.insert(0);
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( it == v2.begin() ); // Error, it is singular
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_set/debug/move_assign_neg.cc
===================================================================
--- testsuite/23_containers/unordered_set/debug/move_assign_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_set/debug/move_assign_neg.cc	(working copy)
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_set>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef __gnu_test::uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::unordered_set<int, std::hash<int>,
+				     std::equal_to<int>,
+				     alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1.emplace(0);
+  auto it = v1.begin();
+
+  test_type v2(alloc_type(2));
+  v2.emplace(1);
+
+  v2 = std::move(v1);
+
+  VERIFY( it == v2.begin() ); // Error, it is singular.
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/unordered_set/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/unordered_set/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/unordered_set/debug/move_neg.cc	(working copy)
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/unordered_set>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::unordered_set<
+    int, std::hash<int>, std::equal_to<int>, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { 0 };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( *it == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/vector/debug/move_neg.cc
===================================================================
--- testsuite/23_containers/vector/debug/move_neg.cc	(revision 0)
+++ testsuite/23_containers/vector/debug/move_neg.cc	(working copy)
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/vector>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef uneq_allocator<int> alloc_type;
+  typedef __gnu_debug::vector<int, alloc_type> test_type;
+
+  test_type v1(alloc_type(1));
+  v1 = { 0 };
+  auto it = v1.begin();
+
+  test_type v2(std::move(v1), alloc_type(2));
+
+  VERIFY( *it == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/util/debug/checks.h
===================================================================
--- testsuite/util/debug/checks.h	(revision 209879)
+++ testsuite/util/debug/checks.h	(working copy)
@@ -179,10 +179,8 @@
 
       val_type *first = &v.front() + 1;
       val_type *last = first + 2;
-      cont_type c1(first, last);
-      VERIFY(c1.size() == 2);
 
-      cont_type c2(last, first); // Expected failure
+      cont_type c(last, first); // Expected failure
     } 
 
   // Check that invalid range of debug random iterators is detected
@@ -206,10 +204,8 @@
 
       typename vector_type::iterator first = v.begin() + 1;
       typename vector_type::iterator last = first + 2;
-      cont_type c1(first, last);
-      VERIFY(c1.size() == 2);
 
-      cont_type c2(last, first); // Expected failure
+      cont_type c(last, first); // Expected failure
     }
 
   // Check that invalid range of debug not random iterators is detected
@@ -233,10 +229,8 @@
 
       typename list_type::iterator first = l.begin(); ++first;
       typename list_type::iterator last = first; ++last; ++last;
-      cont_type c1(first, last);
-      VERIFY(c1.size() == 2);
 
-      cont_type c2(last, first); // Expected failure
+      cont_type c(last, first); // Expected failure
     }
 
   template <typename _Cont>

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