Skip to content

Commit

Permalink
Implement copy assignment operator for hvec_map (#4388)
Browse files Browse the repository at this point in the history
Implement copy constructor for hvec_map. We cannot use a default one since it would involved copying of std::pair<const KEY, VAL> that had its copy ctor explicitly disabled.

Instead, go the standard "way" for maps via clear() and reinsert().

Fixes #4331
  • Loading branch information
asl committed Feb 8, 2024
1 parent 6bf96d8 commit 40fc6bb
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
19 changes: 18 additions & 1 deletion lib/hvec_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
#ifndef LIB_HVEC_MAP_H_
#define LIB_HVEC_MAP_H_

#include <initializer_list>
#include <tuple>
#include <vector>

Expand Down Expand Up @@ -52,7 +53,18 @@ class hvec_map : hash_vector_base {
}
hvec_map(const hvec_map &) = default;
hvec_map(hvec_map &&) = default;
hvec_map &operator=(const hvec_map &) = default;
hvec_map &operator=(const hvec_map &that) {
if (this != std::addressof(that)) {
clear();
hf = that.hf;
eql = that.eql;

data.reserve(that.size());
insert(that.begin(), that.end());
}

return *this;
}
hvec_map &operator=(hvec_map &&) = default;
~hvec_map() = default;
template <class ITER>
Expand Down Expand Up @@ -247,6 +259,11 @@ class hvec_map : hash_vector_base {
}
return std::make_pair(iterator(*this, idx), new_key);
}
template <typename InputIterator>
void insert(InputIterator first, InputIterator last) {
for (; first != last; ++first) insert(*first);
}
void insert(std::initializer_list<value_type> vl) { return insert(vl.begin(), vl.end()); }
template <class HVM, class VT>
_iter<HVM, VT> erase(_iter<HVM, VT> it) {
BUG_CHECK(this == it.self, "incorrect iterator for hvec_map::erase");
Expand Down
18 changes: 11 additions & 7 deletions test/gtest/hvec_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,20 +150,24 @@ TEST(hvec_map, insert_emplace_erase) {
}

TEST(hvec_map, string_map) {
hvec_map<std::string, std::string> m;
hvec_map<std::string, std::string> m, m1;

for (int i = 1; i <= 100; ++i) {
m[std::to_string(i)] = "test";
m[std::to_string(i)] += std::to_string(i);
}
EXPECT_EQ(m.size(), 100);
for (int i = 1; i <= 100; i += 2) m.erase(std::to_string(i));
EXPECT_EQ(m.size(), 50);
for (int i = 102; i <= 200; i += 2) m[std::to_string(i)] = "foobar";
EXPECT_EQ(m.size(), 100);
m1 = m;

hvec_map<std::string, std::string> m2(m);

EXPECT_EQ(m1.size(), 100);
for (int i = 1; i <= 100; i += 2) m1.erase(std::to_string(i));
EXPECT_EQ(m1.size(), 50);
for (int i = 102; i <= 200; i += 2) m1[std::to_string(i)] = "foobar";
EXPECT_EQ(m1.size(), 100);

int idx = 2;
for (auto &el : m) {
for (auto &el : m1) {
EXPECT_TRUE(el.first == std::to_string(idx));
if (idx <= 100)
EXPECT_TRUE(el.second.c_str() + 4 == std::to_string(idx));
Expand Down

0 comments on commit 40fc6bb

Please sign in to comment.