diff options
author | Tor Egge <Tor.Egge@broadpark.no> | 2018-05-26 12:30:21 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@broadpark.no> | 2018-05-27 17:26:01 +0200 |
commit | 8db8e842c9653a0ce9c98e6bd055ead125517b93 (patch) | |
tree | f8a4898b86bc7e96f3499fccdb6e53af6b7ad7cd | |
parent | 2b33daa972f399b7734215ac03d8102cb68d7c1b (diff) |
Handle insertion of non-copyable keys and values in hash map.
Handle insertion of non-copyable keys in hash set.
-rw-r--r-- | vespalib/src/tests/stllike/hash_test.cpp | 39 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/hash_map.h | 1 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/hash_set.h | 1 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/hash_set.hpp | 6 |
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) \ |