dexonsmith updated this revision to Diff 50883.
dexonsmith added a comment.

Eric sent me his preferred tests, which look fine to me.  I've applied them to 
this patch.


http://reviews.llvm.org/D16360

Files:
  include/__hash_table
  test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp
  
test/std/containers/unord/unord.map/unord.map.modifiers/insert_allocator_requirements.pass.cpp
  
test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp
  test/std/containers/unord/unord.set/insert_allocator_requirements.pass.cpp
  
test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp

Index: test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp
===================================================================
--- /dev/null
+++ test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp
@@ -0,0 +1,220 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// class unordered_set
+
+// insert(...)
+// emplace(...)
+
+// 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"
+
+#if TEST_STD_VER >= 11
+template <class Arg>
+void PrintInfo(int line, Arg&& arg)
+#else
+template <class Arg>
+void PrintInfo(int line, Arg arg)
+#endif
+{
+  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;
+  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);
+    }
+  }
+}
+
+
+int main()
+{
+  testContainerInsert<TCT::unordered_set<> >();
+  testContainerEmplace<TCT::unordered_set<> >();
+}
Index: test/std/containers/unord/unord.set/insert_allocator_requirements.pass.cpp
===================================================================
--- test/std/containers/unord/unord.set/insert_allocator_requirements.pass.cpp
+++ /dev/null
@@ -1,142 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// <unordered_set>
-
-// class unordered_set
-
-// insert(...)
-
-// 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"
-
-#if TEST_STD_VER >= 11
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-#else
-template <class Arg>
-void PrintInfo(int line, Arg arg)
-#endif
-{
-  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;
-  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::unordered_set<> >();
-}
Index: test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp
===================================================================
--- /dev/null
+++ test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp
@@ -0,0 +1,249 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// class unordered_map
+
+// insert(...);
+
+// 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"
+
+#if TEST_STD_VER >= 11
+template <class Arg>
+void PrintInfo(int line, Arg&& arg)
+#else
+template <class Arg>
+void PrintInfo(int line, Arg arg)
+#endif
+{
+  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;
+  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);
+    }
+  }
+}
+
+
+int main()
+{
+  testContainerInsert<TCT::unordered_map<> >();
+  testContainerEmplace<TCT::unordered_map<> >();
+}
Index: test/std/containers/unord/unord.map/unord.map.modifiers/insert_allocator_requirements.pass.cpp
===================================================================
--- test/std/containers/unord/unord.map/unord.map.modifiers/insert_allocator_requirements.pass.cpp
+++ /dev/null
@@ -1,143 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// <unordered_map>
-
-// class unordered_map
-
-// insert(...);
-
-// 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"
-
-#if TEST_STD_VER >= 11
-template <class Arg>
-void PrintInfo(int line, Arg&& arg)
-#else
-template <class Arg>
-void PrintInfo(int line, Arg arg)
-#endif
-{
-  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;
-  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::unordered_map<> >();
-}
Index: test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp
===================================================================
--- test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp
+++ /dev/null
@@ -1,48 +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.
-//
-//===----------------------------------------------------------------------===//
-
-// Check that we don't allocate when trying to insert a duplicate value into a
-// unordered_set. See PR12999 http://llvm.org/bugs/show_bug.cgi?id=12999
-
-#include <cassert>
-#include <unordered_set>
-#include "count_new.hpp"
-#include "MoveOnly.h"
-
-int main()
-{
-    {
-    std::unordered_set<int> s;
-    assert(globalMemCounter.checkNewCalledEq(0));
-
-    for(int i=0; i < 100; ++i)
-        s.insert(3);
-
-    assert(s.size() == 1);
-    assert(s.count(3) == 1);
-    assert(globalMemCounter.checkNewCalledEq(2));
-    }
-    assert(globalMemCounter.checkOutstandingNewEq(0));
-    globalMemCounter.reset();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    {
-    std::unordered_set<MoveOnly> s;
-    assert(globalMemCounter.checkNewCalledEq(0));
-
-    for(int i=0; i<100; i++)
-        s.insert(MoveOnly(3));
-
-    assert(s.size() == 1);
-    assert(s.count(MoveOnly(3)) == 1);
-    assert(globalMemCounter.checkNewCalledEq(2));
-    }
-    assert(globalMemCounter.checkOutstandingNewEq(0));
-    globalMemCounter.reset();
-#endif
-}
Index: include/__hash_table
===================================================================
--- include/__hash_table
+++ include/__hash_table
@@ -100,6 +100,21 @@
     return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1));
 }
 
+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 {};
+
 template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
 
 template <class _NodePtr>      class _LIBCPP_TYPE_VIS_ONLY __hash_iterator;
@@ -903,6 +918,7 @@
 
     typedef typename _NodeTypes::__node_value_type           __node_value_type;
     typedef typename _NodeTypes::__container_value_type      __container_value_type;
+    typedef typename _NodeTypes::key_type                    key_type;
     typedef value_type&                              reference;
     typedef const value_type&                        const_reference;
     typedef typename __alloc_traits::pointer         pointer;
@@ -1041,13 +1057,49 @@
 
 #ifndef _LIBCPP_CXX03_LANG
     template <class _Key, class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
     pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
 
     template <class... _Args>
-    pair<iterator, bool> __emplace_unique(_Args&&... __args);
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> __emplace_unique_impl(_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... _Args>
+    _LIBCPP_INLINE_VISIBILITY
     iterator __emplace_multi(_Args&&... __args);
     template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY
     iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
 
 
@@ -1989,7 +2041,7 @@
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 template <class... _Args>
 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique(_Args&&... __args)
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args)
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     pair<iterator, bool> __r = __node_insert_unique(__h.get());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to