Extract key to avoid preemptive mallocs in insert/emplace in associative containers

Summary: This patch applies Duncan's work on __hash_table to __tree.

Reviewers: mclow.lists, dexonsmith

Subscribers: dexonsmith, cfe-commits

Differential Revision: http://reviews.llvm.org/D18637

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@266491 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/__hash_table b/include/__hash_table
index 16a0f5e..2ea1a30 100644
--- a/include/__hash_table
+++ b/include/__hash_table
@@ -100,22 +100,6 @@
     return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1));
 }
 
-#ifndef _LIBCPP_CXX03_LANG
-struct __extract_key_fail_tag {};
-struct __extract_key_self_tag {};
-struct __extract_key_first_tag {};
-
-template <class _ValTy, class _Key,
-          class _RawValTy = typename __unconstref<_ValTy>::type>
-struct __can_extract_key
-    : conditional<is_same<_RawValTy, _Key>::value, __extract_key_self_tag,
-                  __extract_key_fail_tag>::type {};
-
-template <class _Pair, class _Key, class _First, class _Second>
-struct __can_extract_key<_Pair, _Key, pair<_First, _Second>>
-    : conditional<is_same<typename remove_const<_First>::type, _Key>::value,
-                  __extract_key_first_tag, __extract_key_fail_tag>::type {};
-#endif
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
 
diff --git a/include/__tree b/include/__tree
index 314d5eb..eb6ff05 100644
--- a/include/__tree
+++ b/include/__tree
@@ -1064,16 +1064,85 @@
     __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...);
 
     template <class... _Args>
-    pair<iterator, bool> __emplace_unique(_Args&&... __args);
+    pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
 
     template <class... _Args>
-    iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args);
+    iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args);
 
     template <class... _Args>
     iterator __emplace_multi(_Args&&... __args);
 
     template <class... _Args>
     iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> __emplace_unique(_Pp&& __x) {
+        return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
+                                            __can_extract_key<_Pp, key_type>());
+    }
+
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> __emplace_unique(_Args&&... __args) {
+        return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
+    }
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool>
+    __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
+      return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
+    }
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool>
+    __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
+      return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
+    }
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool>
+    __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
+      return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
+    }
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
+        return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x),
+                                            __can_extract_key<_Pp, key_type>());
+    }
+
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
+        return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...);
+    }
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator
+    __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
+      return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
+    }
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator
+    __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) {
+      return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x));
+    }
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    iterator
+    __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) {
+      return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x));
+    }
+
 #else
     template <class _Key, class _Args>
     _LIBCPP_INLINE_VISIBILITY
@@ -1989,7 +2058,7 @@
 template <class _Tp, class _Compare, class _Allocator>
 template <class... _Args>
 pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
-__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args)
+__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     __node_base_pointer __parent;
@@ -2008,7 +2077,7 @@
 template <class _Tp, class _Compare, class _Allocator>
 template <class... _Args>
 typename __tree<_Tp, _Compare, _Allocator>::iterator
-__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args)
+__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     __node_base_pointer __parent;
diff --git a/include/__tuple b/include/__tuple
index 8c31759..09c6839 100644
--- a/include/__tuple
+++ b/include/__tuple
@@ -95,8 +95,6 @@
 
 // pair specializations
 
-template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
-
 template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
 
 template <size_t _Ip, class _T1, class _T2>
diff --git a/include/type_traits b/include/type_traits
index 6840ee2..12e24b7 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -368,6 +368,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
+
 template <class>
 struct __void_t { typedef void type; };
 
@@ -4434,6 +4436,24 @@
 # endif // _LIBCPP_HAS_NO_VARIADICS
 #endif  // _LIBCPP_STD_VER > 14
 
+// These traits are used in __tree and __hash_table
+#ifndef _LIBCPP_CXX03_LANG
+struct __extract_key_fail_tag {};
+struct __extract_key_self_tag {};
+struct __extract_key_first_tag {};
+
+template <class _ValTy, class _Key,
+          class _RawValTy = typename __unconstref<_ValTy>::type>
+struct __can_extract_key
+    : conditional<is_same<_RawValTy, _Key>::value, __extract_key_self_tag,
+                  __extract_key_fail_tag>::type {};
+
+template <class _Pair, class _Key, class _First, class _Second>
+struct __can_extract_key<_Pair, _Key, pair<_First, _Second>>
+    : conditional<is_same<typename remove_const<_First>::type, _Key>::value,
+                  __extract_key_first_tag, __extract_key_fail_tag>::type {};
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_TYPE_TRAITS
diff --git a/test/std/containers/associative/map/map.modifiers/insert_allocator_requirements.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_allocator_requirements.pass.cpp
deleted file mode 100644
index adc5b31..0000000
--- a/test/std/containers/associative/map/map.modifiers/insert_allocator_requirements.pass.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// <map>
-
-// class map
-
-// insert(...);
-
-// UNSUPPORTED: c++98, c++03
-
-#include <map>
-#include <iostream>
-#include <cassert>
-
-#include "test_macros.h"
-#include "count_new.hpp"
-#include "container_test_types.h"
-
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-{
-  std::cout << "In " << __FILE__ << ":" << line << ":\n    " << arg << "\n" << std::endl;
-}
-#define PRINT(msg) PrintInfo(__LINE__, msg)
-
-template <class Container>
-void testContainerInsert()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef Container C;
-  typedef std::pair<typename C::iterator, bool> R;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::insert(const value_type&)");
-    Container c;
-    const ValueTp v(42, 1);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42, 1);
-      assert(c.insert(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(value_type&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42, 1);
-      assert(c.insert(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(value_type&&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<ValueTp&&>();
-    assert(c.insert(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42, 1);
-      assert(c.insert(std::move(v2)).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(std::initializer_list<ValueTp>)");
-    Container c;
-    std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) };
-    cc->expect<ValueTp const&>(2);
-    c.insert(il);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(il);
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
-    Container c;
-    const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(std::begin(ValueList), std::end(ValueList));
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-    cc->expect<ValueTp&&>(3);
-    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
-             std::move_iterator<ValueTp*>(std::end(ValueList)));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-      c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)),
-               std::move_iterator<ValueTp*>(std::end(ValueList2)));
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(std::begin(ValueList), std::end(ValueList));
-    }
-  }
-}
-
-
-int main()
-{
-  testContainerInsert<TCT::map<> >();
-}
diff --git a/test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp
new file mode 100644
index 0000000..9eae628
--- /dev/null
+++ b/test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// insert(...);
+// emplace(...);
+// emplace_hint(...);
+
+// UNSUPPORTED: c++98, c++03
+
+#include <map>
+
+#include "container_test_types.h"
+#include "../../../map_allocator_requirement_test_templates.h"
+
+int main()
+{
+  testMapInsert<TCT::map<> >();
+  testMapEmplace<TCT::map<> >();
+  testMapEmplaceHint<TCT::map<> >();
+}
diff --git a/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp
index 8e3677d..d421de3 100644
--- a/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp
@@ -16,88 +16,12 @@
 // UNSUPPORTED: c++98, c++03
 
 #include <map>
-#include <iostream>
-#include <cassert>
 
-#include "test_macros.h"
-#include "count_new.hpp"
 #include "container_test_types.h"
-
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-{
-  std::cout << "In " << __FILE__ << ":" << line << ":\n    " << arg << "\n" << std::endl;
-}
-#define PRINT(msg) PrintInfo(__LINE__, msg)
-
-template <class Container>
-void testContainerInsert()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef Container C;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::insert(const value_type&)");
-    Container c;
-    const ValueTp v(42, 1);
-    cc->expect<const ValueTp&>();
-    c.insert(v);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(value_type&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<ValueTp&>();
-    c.insert(v);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(value_type&&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<ValueTp&&>();
-    c.insert(std::move(v));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(std::initializer_list<ValueTp>)");
-    Container c;
-    std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) };
-    cc->expect<ValueTp const&>(2);
-    c.insert(il);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
-    Container c;
-    const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-    cc->expect<ValueTp&&>(3);
-    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
-             std::move_iterator<ValueTp*>(std::end(ValueList)));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-    cc->expect<ValueTp&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-  }
-}
+#include "../../../map_allocator_requirement_test_templates.h"
 
 
 int main()
 {
-  testContainerInsert<TCT::multimap<> >();
+  testMultimapInsert<TCT::multimap<> >();
 }
diff --git a/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp b/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp
index a85c776..a280d10 100644
--- a/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp
+++ b/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp
@@ -16,87 +16,11 @@
 // UNSUPPORTED: c++98, c++03
 
 #include <set>
-#include <iostream>
-#include <cassert>
 
-#include "test_macros.h"
-#include "count_new.hpp"
 #include "container_test_types.h"
-
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-{
-  std::cout << "In " << __FILE__ << ":" << line << ":\n    " << arg << "\n" << std::endl;
-}
-#define PRINT(...) PrintInfo(__LINE__, __VA_ARGS__)
-
-template <class Container>
-void testContainerInsert()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef Container C;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::insert(const value_type&)");
-    Container c;
-    const ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    c.insert(v);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(value_type&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    c.insert(v);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(value_type&&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<ValueTp&&>();
-    c.insert(std::move(v));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(std::initializer_list<ValueTp>)");
-    Container c;
-    std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) };
-    cc->expect<ValueTp const&>(2);
-    c.insert(il);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
-    Container c;
-    const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-    cc->expect<ValueTp&&>(3);
-    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
-             std::move_iterator<ValueTp*>(std::end(ValueList)));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-    cc->expect<ValueTp&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-  }
-}
+#include "../../set_allocator_requirement_test_templates.h"
 
 int main()
 {
-  testContainerInsert<TCT::multiset<> >();
+  testMultisetInsert<TCT::multiset<> >();
 }
diff --git a/test/std/containers/associative/set/insert_allocator_requirements.pass.cpp b/test/std/containers/associative/set/insert_allocator_requirements.pass.cpp
deleted file mode 100644
index f083669..0000000
--- a/test/std/containers/associative/set/insert_allocator_requirements.pass.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// <set>
-
-// class set
-
-// insert(...)
-
-// UNSUPPORTED: c++98, c++03
-
-#include <set>
-#include <iostream>
-#include <cassert>
-
-#include "test_macros.h"
-#include "count_new.hpp"
-#include "container_test_types.h"
-
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-{
-  std::cout << "In " << __FILE__ << ":" << line << ":\n    " << arg << "\n" << std::endl;
-}
-#define PRINT(msg) PrintInfo(__LINE__, msg)
-
-template <class Container>
-void testContainerInsert()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef Container C;
-  typedef std::pair<typename C::iterator, bool> R;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::insert(const value_type&)");
-    Container c;
-    const ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42);
-      assert(c.insert(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(value_type&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42);
-      assert(c.insert(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(value_type&&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<ValueTp&&>();
-    assert(c.insert(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42);
-      assert(c.insert(std::move(v2)).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(std::initializer_list<ValueTp>)");
-    Container c;
-    std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) };
-    cc->expect<ValueTp const&>(2);
-    c.insert(il);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(il);
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
-    Container c;
-    const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(std::begin(ValueList), std::end(ValueList));
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-    cc->expect<ValueTp&&>(3);
-    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
-             std::move_iterator<ValueTp*>(std::end(ValueList)));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp ValueList2[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-      c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)),
-               std::move_iterator<ValueTp*>(std::end(ValueList2)));
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(std::begin(ValueList), std::end(ValueList));
-    }
-  }
-}
-
-
-int main()
-{
-  testContainerInsert<TCT::set<> >();
-}
diff --git a/test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.cpp b/test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.cpp
new file mode 100644
index 0000000..b14340b
--- /dev/null
+++ b/test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <set>
+
+// class set
+
+// insert(...)
+// emplace(...)
+// emplace_hint(...)
+
+// UNSUPPORTED: c++98, c++03
+
+#include <set>
+#include "container_test_types.h"
+#include "../../set_allocator_requirement_test_templates.h"
+
+int main()
+{
+  testSetInsert<TCT::set<> >();
+  testSetEmplace<TCT::set<> >();
+  testSetEmplaceHint<TCT::set<> >();
+}
diff --git a/test/std/containers/map_allocator_requirement_test_templates.h b/test/std/containers/map_allocator_requirement_test_templates.h
new file mode 100644
index 0000000..b5958f7
--- /dev/null
+++ b/test/std/containers/map_allocator_requirement_test_templates.h
@@ -0,0 +1,419 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MAP_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H
+#define MAP_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H
+
+// <map>
+// <unordered_map>
+
+// class map
+// class unordered_map
+
+// insert(...);
+// emplace(...);
+// emplace_hint(...);
+
+// UNSUPPORTED: c++98, c++03
+
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+#include "container_test_types.h"
+#include "assert_checkpoint.h"
+
+
+template <class Container>
+void testMapInsert()
+{
+  typedef typename Container::value_type ValueTp;
+  typedef Container C;
+  typedef std::pair<typename C::iterator, bool> R;
+  ConstructController* cc = getConstructController();
+  cc->reset();
+  {
+    CHECKPOINT("Testing C::insert(const value_type&)");
+    Container c;
+    const ValueTp v(42, 1);
+    cc->expect<const ValueTp&>();
+    assert(c.insert(v).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42, 1);
+      assert(c.insert(v2).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(value_type&)");
+    Container c;
+    ValueTp v(42, 1);
+    cc->expect<const ValueTp&>();
+    assert(c.insert(v).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42, 1);
+      assert(c.insert(v2).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(value_type&&)");
+    Container c;
+    ValueTp v(42, 1);
+    cc->expect<ValueTp&&>();
+    assert(c.insert(std::move(v)).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42, 1);
+      assert(c.insert(std::move(v2)).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(const value_type&&)");
+    Container c;
+    const ValueTp v(42, 1);
+    cc->expect<const ValueTp&>();
+    assert(c.insert(std::move(v)).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42, 1);
+      assert(c.insert(std::move(v2)).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)");
+    Container c;
+    std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) };
+    cc->expect<ValueTp const&>(2);
+    c.insert(il);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      c.insert(il);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
+    Container c;
+    const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) };
+    cc->expect<ValueTp const&>(3);
+    c.insert(std::begin(ValueList), std::end(ValueList));
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      c.insert(std::begin(ValueList), std::end(ValueList));
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
+    Container c;
+    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
+    cc->expect<ValueTp&&>(3);
+    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
+             std::move_iterator<ValueTp*>(std::end(ValueList)));
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
+      c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)),
+               std::move_iterator<ValueTp*>(std::end(ValueList2)));
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
+    Container c;
+    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
+    cc->expect<ValueTp const&>(3);
+    c.insert(std::begin(ValueList), std::end(ValueList));
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      c.insert(std::begin(ValueList), std::end(ValueList));
+    }
+  }
+}
+
+template <class Container>
+void testMapEmplace()
+{
+  typedef typename Container::value_type ValueTp;
+  typedef typename Container::key_type Key;
+  typedef typename Container::mapped_type Mapped;
+  typedef typename std::pair<Key, Mapped> NonConstKeyPair;
+  typedef Container C;
+  typedef std::pair<typename C::iterator, bool> R;
+  ConstructController* cc = getConstructController();
+  cc->reset();
+  {
+    CHECKPOINT("Testing C::emplace(const value_type&)");
+    Container c;
+    const ValueTp v(42, 1);
+    cc->expect<const ValueTp&>();
+    assert(c.emplace(v).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42, 1);
+      assert(c.emplace(v2).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace(value_type&)");
+    Container c;
+    ValueTp v(42, 1);
+    cc->expect<ValueTp&>();
+    assert(c.emplace(v).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42, 1);
+      assert(c.emplace(v2).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace(value_type&&)");
+    Container c;
+    ValueTp v(42, 1);
+    cc->expect<ValueTp&&>();
+    assert(c.emplace(std::move(v)).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42, 1);
+      assert(c.emplace(std::move(v2)).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace(const value_type&&)");
+    Container c;
+    const ValueTp v(42, 1);
+    cc->expect<const ValueTp&&>();
+    assert(c.emplace(std::move(v)).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42, 1);
+      assert(c.emplace(std::move(v2)).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace(pair<Key, Mapped> const&)");
+    Container c;
+    const NonConstKeyPair v(42, 1);
+    cc->expect<const NonConstKeyPair&>();
+    assert(c.emplace(v).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const NonConstKeyPair v2(42, 1);
+      assert(c.emplace(v2).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace(pair<Key, Mapped> &&)");
+    Container c;
+    NonConstKeyPair v(42, 1);
+    cc->expect<NonConstKeyPair&&>();
+    assert(c.emplace(std::move(v)).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      NonConstKeyPair v2(42, 1);
+      assert(c.emplace(std::move(v2)).second == false);
+    }
+  }
+}
+
+
+template <class Container>
+void testMapEmplaceHint()
+{
+  typedef typename Container::value_type ValueTp;
+  typedef typename Container::key_type Key;
+  typedef typename Container::mapped_type Mapped;
+  typedef typename std::pair<Key, Mapped> NonConstKeyPair;
+  typedef Container C;
+  typedef typename C::iterator It;
+  ConstructController* cc = getConstructController();
+  cc->reset();
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, const value_type&)");
+    Container c;
+    const ValueTp v(42, 1);
+    cc->expect<const ValueTp&>();
+    It ret = c.emplace_hint(c.end(), v);
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42, 1);
+      It ret2 = c.emplace_hint(c.begin(), v2);
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, value_type&)");
+    Container c;
+    ValueTp v(42, 1);
+    cc->expect<ValueTp&>();
+    It ret = c.emplace_hint(c.end(), v);
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42, 1);
+      It ret2 = c.emplace_hint(c.begin(), v2);
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, value_type&&)");
+    Container c;
+    ValueTp v(42, 1);
+    cc->expect<ValueTp&&>();
+    It ret = c.emplace_hint(c.end(), std::move(v));
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42, 1);
+      It ret2 = c.emplace_hint(c.begin(), std::move(v2));
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, const value_type&&)");
+    Container c;
+    const ValueTp v(42, 1);
+    cc->expect<const ValueTp&&>();
+    It ret = c.emplace_hint(c.end(), std::move(v));
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42, 1);
+      It ret2 = c.emplace_hint(c.begin(), std::move(v2));
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, pair<Key, Mapped> const&)");
+    Container c;
+    const NonConstKeyPair v(42, 1);
+    cc->expect<const NonConstKeyPair&>();
+    It ret = c.emplace_hint(c.end(), v);
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const NonConstKeyPair v2(42, 1);
+      It ret2 = c.emplace_hint(c.begin(), v2);
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, pair<Key, Mapped>&&)");
+    Container c;
+    NonConstKeyPair v(42, 1);
+    cc->expect<NonConstKeyPair&&>();
+    It ret = c.emplace_hint(c.end(), std::move(v));
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      NonConstKeyPair v2(42, 1);
+      It ret2 = c.emplace_hint(c.begin(), std::move(v2));
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+}
+
+
+template <class Container>
+void testMultimapInsert()
+{
+  typedef typename Container::value_type ValueTp;
+  typedef Container C;
+  ConstructController* cc = getConstructController();
+  cc->reset();
+  {
+    CHECKPOINT("Testing C::insert(const value_type&)");
+    Container c;
+    const ValueTp v(42, 1);
+    cc->expect<const ValueTp&>();
+    c.insert(v);
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(value_type&)");
+    Container c;
+    ValueTp v(42, 1);
+    cc->expect<ValueTp&>();
+    c.insert(v);
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(value_type&&)");
+    Container c;
+    ValueTp v(42, 1);
+    cc->expect<ValueTp&&>();
+    c.insert(std::move(v));
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)");
+    Container c;
+    std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) };
+    cc->expect<ValueTp const&>(2);
+    c.insert(il);
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
+    Container c;
+    const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) };
+    cc->expect<ValueTp const&>(3);
+    c.insert(std::begin(ValueList), std::end(ValueList));
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
+    Container c;
+    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
+    cc->expect<ValueTp&&>(3);
+    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
+             std::move_iterator<ValueTp*>(std::end(ValueList)));
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
+    Container c;
+    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
+    cc->expect<ValueTp&>(3);
+    c.insert(std::begin(ValueList), std::end(ValueList));
+    assert(!cc->unchecked());
+  }
+}
+
+#endif
\ No newline at end of file
diff --git a/test/std/containers/set_allocator_requirement_test_templates.h b/test/std/containers/set_allocator_requirement_test_templates.h
new file mode 100644
index 0000000..fe72bf8
--- /dev/null
+++ b/test/std/containers/set_allocator_requirement_test_templates.h
@@ -0,0 +1,356 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef SET_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H
+#define SET_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H
+
+// <set>
+// <unordered_set>
+
+// class set
+// class unordered_set
+
+// insert(...);
+// emplace(...);
+// emplace_hint(...);
+
+
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+#include "container_test_types.h"
+#include "assert_checkpoint.h"
+
+
+template <class Container>
+void testSetInsert()
+{
+  typedef typename Container::value_type ValueTp;
+  typedef Container C;
+  typedef std::pair<typename C::iterator, bool> R;
+  ConstructController* cc = getConstructController();
+  cc->reset();
+  {
+    CHECKPOINT("Testing C::insert(const value_type&)");
+    Container c;
+    const ValueTp v(42);
+    cc->expect<const ValueTp&>();
+    assert(c.insert(v).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42);
+      assert(c.insert(v2).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(value_type&)");
+    Container c;
+    ValueTp v(42);
+    cc->expect<const ValueTp&>();
+    assert(c.insert(v).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42);
+      assert(c.insert(v2).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(value_type&&)");
+    Container c;
+    ValueTp v(42);
+    cc->expect<ValueTp&&>();
+    assert(c.insert(std::move(v)).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42);
+      assert(c.insert(std::move(v2)).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(const value_type&&)");
+    Container c;
+    const ValueTp v(42);
+    cc->expect<const ValueTp&>();
+    assert(c.insert(std::move(v)).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42);
+      assert(c.insert(std::move(v2)).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)");
+    Container c;
+    std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) };
+    cc->expect<ValueTp const&>(2);
+    c.insert(il);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      c.insert(il);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
+    Container c;
+    const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) };
+    cc->expect<ValueTp const&>(3);
+    c.insert(std::begin(ValueList), std::end(ValueList));
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      c.insert(std::begin(ValueList), std::end(ValueList));
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
+    Container c;
+    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
+    cc->expect<ValueTp&&>(3);
+    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
+             std::move_iterator<ValueTp*>(std::end(ValueList)));
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp ValueList2[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
+      c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)),
+               std::move_iterator<ValueTp*>(std::end(ValueList2)));
+    }
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
+    Container c;
+    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
+    cc->expect<ValueTp const&>(3);
+    c.insert(std::begin(ValueList), std::end(ValueList));
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      c.insert(std::begin(ValueList), std::end(ValueList));
+    }
+  }
+}
+
+
+template <class Container>
+void testSetEmplace()
+{
+  typedef typename Container::value_type ValueTp;
+  typedef Container C;
+  typedef std::pair<typename C::iterator, bool> R;
+  ConstructController* cc = getConstructController();
+  cc->reset();
+  {
+    CHECKPOINT("Testing C::emplace(const value_type&)");
+    Container c;
+    const ValueTp v(42);
+    cc->expect<const ValueTp&>();
+    assert(c.emplace(v).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42);
+      assert(c.emplace(v2).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace(value_type&)");
+    Container c;
+    ValueTp v(42);
+    cc->expect<ValueTp&>();
+    assert(c.emplace(v).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42);
+      assert(c.emplace(v2).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace(value_type&&)");
+    Container c;
+    ValueTp v(42);
+    cc->expect<ValueTp&&>();
+    assert(c.emplace(std::move(v)).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42);
+      assert(c.emplace(std::move(v2)).second == false);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace(const value_type&&)");
+    Container c;
+    const ValueTp v(42);
+    cc->expect<const ValueTp&&>();
+    assert(c.emplace(std::move(v)).second);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42);
+      assert(c.emplace(std::move(v2)).second == false);
+    }
+  }
+}
+
+
+template <class Container>
+void testSetEmplaceHint()
+{
+  typedef typename Container::value_type ValueTp;
+
+  typedef Container C;
+  typedef typename C::iterator It;
+  ConstructController* cc = getConstructController();
+  cc->reset();
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, const value_type&)");
+    Container c;
+    const ValueTp v(42);
+    cc->expect<const ValueTp&>();
+    It ret = c.emplace_hint(c.end(), v);
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42);
+      It ret2 = c.emplace_hint(c.begin(), v2);
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, value_type&)");
+    Container c;
+    ValueTp v(42);
+    cc->expect<ValueTp&>();
+    It ret = c.emplace_hint(c.end(), v);
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42);
+      It ret2 = c.emplace_hint(c.begin(), v2);
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, value_type&&)");
+    Container c;
+    ValueTp v(42);
+    cc->expect<ValueTp&&>();
+    It ret = c.emplace_hint(c.end(), std::move(v));
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      ValueTp v2(42);
+      It ret2 = c.emplace_hint(c.begin(), std::move(v2));
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+  {
+    CHECKPOINT("Testing C::emplace_hint(p, const value_type&&)");
+    Container c;
+    const ValueTp v(42);
+    cc->expect<const ValueTp&&>();
+    It ret = c.emplace_hint(c.end(), std::move(v));
+    assert(ret != c.end());
+    assert(c.size() == 1);
+    assert(!cc->unchecked());
+    {
+      DisableAllocationGuard g;
+      const ValueTp v2(42);
+      It ret2 = c.emplace_hint(c.begin(), std::move(v2));
+      assert(&(*ret2) == &(*ret));
+      assert(c.size() == 1);
+    }
+  }
+}
+
+
+template <class Container>
+void testMultisetInsert()
+{
+  typedef typename Container::value_type ValueTp;
+  typedef Container C;
+  ConstructController* cc = getConstructController();
+  cc->reset();
+  {
+    CHECKPOINT("Testing C::insert(const value_type&)");
+    Container c;
+    const ValueTp v(42);
+    cc->expect<const ValueTp&>();
+    c.insert(v);
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(value_type&)");
+    Container c;
+    ValueTp v(42);
+    cc->expect<const ValueTp&>();
+    c.insert(v);
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(value_type&&)");
+    Container c;
+    ValueTp v(42);
+    cc->expect<ValueTp&&>();
+    c.insert(std::move(v));
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)");
+    Container c;
+    std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) };
+    cc->expect<ValueTp const&>(2);
+    c.insert(il);
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
+    Container c;
+    const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) };
+    cc->expect<ValueTp const&>(3);
+    c.insert(std::begin(ValueList), std::end(ValueList));
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
+    Container c;
+    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
+    cc->expect<ValueTp&&>(3);
+    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
+             std::move_iterator<ValueTp*>(std::end(ValueList)));
+    assert(!cc->unchecked());
+  }
+  {
+    CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
+    Container c;
+    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
+    cc->expect<ValueTp&>(3);
+    c.insert(std::begin(ValueList), std::end(ValueList));
+    assert(!cc->unchecked());
+  }
+}
+
+
+
+#endif
\ No newline at end of file
diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp
index 1268051..5ee206a 100644
--- a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp
@@ -12,233 +12,18 @@
 // class unordered_map
 
 // insert(...);
+// emplace(...);
 
 // UNSUPPORTED: c++98, c++03
 
 
 #include <unordered_map>
-#include <iostream>
-#include <cassert>
 
-#include "test_macros.h"
-#include "count_new.hpp"
 #include "container_test_types.h"
-
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-{
-  std::cout << "In " << __FILE__ << ":" << line << ":\n    " << arg << "\n" << std::endl;
-}
-#define PRINT(msg) PrintInfo(__LINE__, msg)
-
-template <class Container>
-void testContainerInsert()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef Container C;
-  typedef std::pair<typename C::iterator, bool> R;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::insert(const value_type&)");
-    Container c;
-    const ValueTp v(42, 1);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42, 1);
-      assert(c.insert(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(value_type&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42, 1);
-      assert(c.insert(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(value_type&&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<ValueTp&&>();
-    assert(c.insert(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42, 1);
-      assert(c.insert(std::move(v2)).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(const value_type&&)");
-    Container c;
-    const ValueTp v(42, 1);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42, 1);
-      assert(c.insert(std::move(v2)).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(std::initializer_list<ValueTp>)");
-    Container c;
-    std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) };
-    cc->expect<ValueTp const&>(2);
-    c.insert(il);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(il);
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
-    Container c;
-    const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(std::begin(ValueList), std::end(ValueList));
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-    cc->expect<ValueTp&&>(3);
-    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
-             std::move_iterator<ValueTp*>(std::end(ValueList)));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-      c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)),
-               std::move_iterator<ValueTp*>(std::end(ValueList2)));
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(std::begin(ValueList), std::end(ValueList));
-    }
-  }
-}
-
-
-template <class Container>
-void testContainerEmplace()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef typename Container::key_type Key;
-  typedef typename Container::mapped_type Mapped;
-  typedef typename std::pair<Key, Mapped> NonConstKeyPair;
-  typedef Container C;
-  typedef std::pair<typename C::iterator, bool> R;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::emplace(const value_type&)");
-    Container c;
-    const ValueTp v(42, 1);
-    cc->expect<const ValueTp&>();
-    assert(c.emplace(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42, 1);
-      assert(c.emplace(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::emplace(value_type&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<ValueTp&>();
-    assert(c.emplace(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42, 1);
-      assert(c.emplace(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::emplace(value_type&&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<ValueTp&&>();
-    assert(c.emplace(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42, 1);
-      assert(c.emplace(std::move(v2)).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::emplace(const value_type&&)");
-    Container c;
-    const ValueTp v(42, 1);
-    cc->expect<const ValueTp&&>();
-    assert(c.emplace(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42, 1);
-      assert(c.emplace(std::move(v2)).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::emplace(pair<Key, Mapped> const&)");
-    Container c;
-    const NonConstKeyPair v(42, 1);
-    cc->expect<const NonConstKeyPair&>();
-    assert(c.emplace(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const NonConstKeyPair v2(42, 1);
-      assert(c.emplace(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::emplace(pair<Key, Mapped> &&)");
-    Container c;
-    NonConstKeyPair v(42, 1);
-    cc->expect<NonConstKeyPair&&>();
-    assert(c.emplace(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      NonConstKeyPair v2(42, 1);
-      assert(c.emplace(std::move(v2)).second == false);
-    }
-  }
-}
-
+#include "../../../map_allocator_requirement_test_templates.h"
 
 int main()
 {
-  testContainerInsert<TCT::unordered_map<> >();
-  testContainerEmplace<TCT::unordered_map<> >();
+  testMapInsert<TCT::unordered_map<> >();
+  testMapEmplace<TCT::unordered_map<> >();
 }
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp
index 793419a..1145eb9 100644
--- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp
@@ -16,88 +16,11 @@
 // UNSUPPORTED: c++98, c++03
 
 #include <unordered_map>
-#include <iostream>
-#include <cassert>
 
-#include "test_macros.h"
-#include "count_new.hpp"
 #include "container_test_types.h"
-
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-{
-  std::cout << "In " << __FILE__ << ":" << line << ":\n    " << arg << "\n" << std::endl;
-}
-#define PRINT(msg) PrintInfo(__LINE__, msg)
-
-template <class Container>
-void testContainerInsert()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef Container C;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::insert(const value_type&)");
-    Container c;
-    const ValueTp v(42, 1);
-    cc->expect<const ValueTp&>();
-    c.insert(v);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(value_type&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<ValueTp&>();
-    c.insert(v);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(value_type&&)");
-    Container c;
-    ValueTp v(42, 1);
-    cc->expect<ValueTp&&>();
-    c.insert(std::move(v));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(std::initializer_list<ValueTp>)");
-    Container c;
-    std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) };
-    cc->expect<ValueTp const&>(2);
-    c.insert(il);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
-    Container c;
-    const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-    cc->expect<ValueTp&&>(3);
-    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
-             std::move_iterator<ValueTp*>(std::end(ValueList)));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) };
-    cc->expect<ValueTp&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-  }
-}
-
+#include "../../../map_allocator_requirement_test_templates.h"
 
 int main()
 {
-  testContainerInsert<TCT::unordered_multimap<> >();
+  testMultimapInsert<TCT::unordered_multimap<> >();
 }
diff --git a/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp b/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp
index 791d7dd..ad7bc04 100644
--- a/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp
@@ -16,87 +16,10 @@
 // UNSUPPORTED: c++98, c++03
 
 #include <unordered_set>
-#include <iostream>
-#include <cassert>
-
-#include "test_macros.h"
-#include "count_new.hpp"
 #include "container_test_types.h"
-
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-{
-  std::cout << "In " << __FILE__ << ":" << line << ":\n    " << arg << "\n" << std::endl;
-}
-#define PRINT(msg) PrintInfo(__LINE__, msg)
-
-template <class Container>
-void testContainerInsert()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef Container C;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::insert(const value_type&)");
-    Container c;
-    const ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    c.insert(v);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(value_type&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    c.insert(v);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(value_type&&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<ValueTp&&>();
-    c.insert(std::move(v));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(std::initializer_list<ValueTp>)");
-    Container c;
-    std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) };
-    cc->expect<ValueTp const&>(2);
-    c.insert(il);
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
-    Container c;
-    const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-    cc->expect<ValueTp&&>(3);
-    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
-             std::move_iterator<ValueTp*>(std::end(ValueList)));
-    assert(!cc->unchecked());
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-    cc->expect<ValueTp&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-  }
-}
+#include "../../set_allocator_requirement_test_templates.h"
 
 int main()
 {
-  testContainerInsert<TCT::unordered_multiset<> >();
+  testMultisetInsert<TCT::unordered_multiset<> >();
 }
diff --git a/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp b/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp
index 05c2d0a..e85e945 100644
--- a/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp
+++ b/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp
@@ -17,199 +17,13 @@
 // UNSUPPORTED: c++98, c++03
 
 #include <unordered_set>
-#include <iostream>
-#include <cassert>
 
-#include "test_macros.h"
-#include "count_new.hpp"
 #include "container_test_types.h"
-
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-{
-  std::cout << "In " << __FILE__ << ":" << line << ":\n    " << arg << "\n" << std::endl;
-}
-#define PRINT(msg) PrintInfo(__LINE__, msg)
-
-template <class Container>
-void testContainerInsert()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef Container C;
-  typedef std::pair<typename C::iterator, bool> R;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::insert(const value_type&)");
-    Container c;
-    const ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42);
-      assert(c.insert(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(value_type&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42);
-      assert(c.insert(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(value_type&&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<ValueTp&&>();
-    assert(c.insert(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42);
-      assert(c.insert(std::move(v2)).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(const value_type&&)");
-    Container c;
-    const ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    assert(c.insert(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42);
-      assert(c.insert(std::move(v2)).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::insert(std::initializer_list<ValueTp>)");
-    Container c;
-    std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) };
-    cc->expect<ValueTp const&>(2);
-    c.insert(il);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(il);
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&");
-    Container c;
-    const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(std::begin(ValueList), std::end(ValueList));
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-    cc->expect<ValueTp&&>(3);
-    c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)),
-             std::move_iterator<ValueTp*>(std::end(ValueList)));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp ValueList2[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-      c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)),
-               std::move_iterator<ValueTp*>(std::end(ValueList2)));
-    }
-  }
-  {
-    PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&");
-    Container c;
-    ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) };
-    cc->expect<ValueTp const&>(3);
-    c.insert(std::begin(ValueList), std::end(ValueList));
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      c.insert(std::begin(ValueList), std::end(ValueList));
-    }
-  }
-}
-
-
-template <class Container>
-void testContainerEmplace()
-{
-  typedef typename Container::value_type ValueTp;
-  typedef Container C;
-  typedef std::pair<typename C::iterator, bool> R;
-  ConstructController* cc = getConstructController();
-  cc->reset();
-  {
-    PRINT("Testing C::emplace(const value_type&)");
-    Container c;
-    const ValueTp v(42);
-    cc->expect<const ValueTp&>();
-    assert(c.emplace(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42);
-      assert(c.emplace(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::emplace(value_type&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<ValueTp&>();
-    assert(c.emplace(v).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42);
-      assert(c.emplace(v2).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::emplace(value_type&&)");
-    Container c;
-    ValueTp v(42);
-    cc->expect<ValueTp&&>();
-    assert(c.emplace(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      ValueTp v2(42);
-      assert(c.emplace(std::move(v2)).second == false);
-    }
-  }
-  {
-    PRINT("Testing C::emplace(const value_type&&)");
-    Container c;
-    const ValueTp v(42);
-    cc->expect<const ValueTp&&>();
-    assert(c.emplace(std::move(v)).second);
-    assert(!cc->unchecked());
-    {
-      DisableAllocationGuard g;
-      const ValueTp v2(42);
-      assert(c.emplace(std::move(v2)).second == false);
-    }
-  }
-}
+#include "../../set_allocator_requirement_test_templates.h"
 
 
 int main()
 {
-  testContainerInsert<TCT::unordered_set<> >();
-  testContainerEmplace<TCT::unordered_set<> >();
+  testSetInsert<TCT::unordered_set<> >();
+  testSetEmplace<TCT::unordered_set<> >();
 }
diff --git a/test/support/assert_checkpoint.h b/test/support/assert_checkpoint.h
new file mode 100644
index 0000000..eea78ef
--- /dev/null
+++ b/test/support/assert_checkpoint.h
@@ -0,0 +1,62 @@
+#ifndef SUPPORT_ASSERT_CHECKPOINT_H
+#define SUPPORT_ASSERT_CHECKPOINT_H
+
+#include <csignal>
+#include <iostream>
+#include <cstdlib>
+
+struct Checkpoint {
+  const char* file;
+  const char* func;
+  int line;
+  const char* msg;
+
+  template <class Stream>
+  void print(Stream& s) const {
+      if (!file) {
+          s << "NO CHECKPOINT\n";
+          return;
+      }
+      s << file << ":" << line << " " << func << ": Checkpoint";
+      if (msg)
+        s << " '" << msg << "'";
+      s << std::endl;
+  }
+};
+
+inline Checkpoint& globalCheckpoint() {
+    static Checkpoint C;
+    return C;
+}
+
+inline void clearCheckpoint() {
+    globalCheckpoint() = Checkpoint{0};
+}
+
+#define CHECKPOINT(msg) globalCheckpoint() = Checkpoint{__FILE__, __PRETTY_FUNCTION__, __LINE__, msg}
+
+inline void checkpointSignalHandler(int signal) {
+    if (signal == SIGABRT) {
+        globalCheckpoint().print(std::cerr);
+    } else {
+        std::cerr << "Unexpected signal " << signal << " received\n";
+    }
+    std::_Exit(EXIT_FAILURE);
+}
+
+inline bool initCheckpointHandler() {
+    typedef void(*HandlerT)(int);
+    static bool isInit = false;
+    if (isInit) return true;
+    HandlerT prev_h = std::signal(SIGABRT, checkpointSignalHandler);
+    if (prev_h == SIG_ERR) {
+        std::cerr << "Setup failed.\n";
+        std::_Exit(EXIT_FAILURE);
+    }
+    isInit = true;
+    return false;
+}
+
+static bool initDummy = initCheckpointHandler();
+
+#endif