diff options
| author | Eric Fiselier <eric@efcs.ca> | 2015-06-13 07:18:32 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2015-06-13 07:18:32 +0000 |
| commit | de3f2b396c229399c00e3013aa060be3f0d336c1 (patch) | |
| tree | 4e294b6a3845c3989b7b2b388dbbb2c4e753756e /libcxx/test | |
| parent | 098e6de9aa41dec16c09dfab456b83bf8a2946cb (diff) | |
| download | bcm5719-llvm-de3f2b396c229399c00e3013aa060be3f0d336c1.tar.gz bcm5719-llvm-de3f2b396c229399c00e3013aa060be3f0d336c1.zip | |
Fix PR12999 - unordered_set::insert calls operator new when no insert occurs
Summary:
when `unordered_set::insert(value_type&&)` was called it would be treated like `unordered_set::emplace(Args&&)` and it would allocate and construct a node before trying to insert it.
This caused unnecessary allocations when the value was already in the set. This patch adds an overload to `__hash_table::__insert_unique` that specifically handles `value_type&&` more link `value_type const &`.
This patch also adds a single unified insert function for values into `__hash_table` called `__insert_unique_value` that handles the cases for `__insert_unique(value_type&&)` and `__insert_unique(value_type const &)`.
This patch fixes PR12999: http://llvm.org/bugs/show_bug.cgi?id=12999.
Reviewers: mclow.lists, titus, danalbert
Reviewed By: danalbert
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D7570
llvm-svn: 239666
Diffstat (limited to 'libcxx/test')
| -rw-r--r-- | libcxx/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/libcxx/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp new file mode 100644 index 00000000000..76ceafed220 --- /dev/null +++ b/libcxx/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// 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 +} |

