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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits