summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@broadpark.no>2018-05-26 12:30:21 +0200
committerTor Egge <Tor.Egge@broadpark.no>2018-05-27 17:26:01 +0200
commit8db8e842c9653a0ce9c98e6bd055ead125517b93 (patch)
treef8a4898b86bc7e96f3499fccdb6e53af6b7ad7cd /vespalib
parent2b33daa972f399b7734215ac03d8102cb68d7c1b (diff)
Handle insertion of non-copyable keys and values in hash map.
Handle insertion of non-copyable keys in hash set.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/stllike/hash_test.cpp39
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_map.h1
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_set.h1
-rw-r--r--vespalib/src/vespa/vespalib/stllike/hash_set.hpp6
4 files changed, 47 insertions, 0 deletions
diff --git a/vespalib/src/tests/stllike/hash_test.cpp b/vespalib/src/tests/stllike/hash_test.cpp
index 94e214e9fb9..366111cad0d 100644
--- a/vespalib/src/tests/stllike/hash_test.cpp
+++ b/vespalib/src/tests/stllike/hash_test.cpp
@@ -434,6 +434,45 @@ TEST("test that for_each member works as std::for_each") {
TEST_DO(verify_sum(m, expected_sum));
}
+namespace {
+
+class WrappedKey
+{
+ std::unique_ptr<const int> _key;
+public:
+ WrappedKey() : _key() { }
+ WrappedKey(int key) : _key(std::make_unique<const int>(key)) { }
+ size_t hash() const { return vespalib::hash<int>()(*_key); }
+ bool operator==(const WrappedKey &rhs) const { return *_key == *rhs._key; }
+};
+
+}
+
+TEST("test that hash map can have non-copyable key")
+{
+ hash_map<WrappedKey, int> m;
+ EXPECT_TRUE(m.insert(std::make_pair(WrappedKey(4), 5)).second);
+ WrappedKey testKey(4);
+ ASSERT_TRUE(m.find(testKey) != m.end());
+ EXPECT_EQUAL(5, m.find(testKey)->second);
+}
+
+TEST("test that hash map can have non-copyable value")
+{
+ hash_map<int, std::unique_ptr<int>> m;
+ EXPECT_TRUE(m.insert(std::make_pair(4, std::make_unique<int>(5))).second);
+ EXPECT_TRUE(m[4]);
+ EXPECT_EQUAL(5, *m[4]);
+}
+
+TEST("test that hash set can have non-copyable key")
+{
+ hash_set<WrappedKey> m;
+ EXPECT_TRUE(m.insert(WrappedKey(4)).second);
+ WrappedKey testKey(4);
+ ASSERT_TRUE(m.find(testKey) != m.end());
+}
+
using IntHashSet = hash_set<int>;
TEST("test hash set initializer list - empty")
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map.h b/vespalib/src/vespa/vespalib/stllike/hash_map.h
index f2431a73f28..6d6498f8e78 100644
--- a/vespalib/src/vespa/vespalib/stllike/hash_map.h
+++ b/vespalib/src/vespa/vespalib/stllike/hash_map.h
@@ -36,6 +36,7 @@ public:
size_t size() const { return _ht.size(); }
bool empty() const { return _ht.empty(); }
insert_result insert(const value_type & value) { return _ht.insert(value); }
+ insert_result insert(value_type &&value) { return _ht.insert(std::move(value)); }
template <typename InputIt>
void insert(InputIt first, InputIt last);
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.h b/vespalib/src/vespa/vespalib/stllike/hash_set.h
index bb16932a990..c4ccc662787 100644
--- a/vespalib/src/vespa/vespalib/stllike/hash_set.h
+++ b/vespalib/src/vespa/vespalib/stllike/hash_set.h
@@ -37,6 +37,7 @@ public:
size_t size() const { return _ht.size(); }
bool empty() const { return _ht.empty(); }
insert_result insert(const K & value);
+ insert_result insert(K &&value);
template<typename InputIt>
void insert(InputIt first, InputIt last);
void erase(const K & key);
diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.hpp b/vespalib/src/vespa/vespalib/stllike/hash_set.hpp
index bd323b2c860..cf6341218f1 100644
--- a/vespalib/src/vespa/vespalib/stllike/hash_set.hpp
+++ b/vespalib/src/vespa/vespalib/stllike/hash_set.hpp
@@ -74,6 +74,12 @@ hash_set<K, H, EQ, M>::insert(const K & value) {
return _ht.insert(value);
}
+template<typename K, typename H, typename EQ, typename M>
+typename hash_set<K, H, EQ, M>::insert_result
+hash_set<K, H, EQ, M>::insert(K &&value) {
+ return _ht.insert(std::move(value));
+}
+
}
#define VESPALIB_HASH_SET_INSTANTIATE(K) \