Commit 4b17db44 authored by Nathan Bronson's avatar Nathan Bronson Committed by Facebook Github Bot

add missing operator=(initializer_list) overloads

Summary:
F14 maps and sets were missing the operator= overload that takes
an initializer list, resulting in map = {} having reset behavior rather
than clear behavior.  Without the overload an empty map is constructed and
then moved onto the lhs, freeing all memory.  With the overload we call
clear(), which retains the existing allocation when it is not too large.
This diff also cleans up the default constructor definitions, adding
noexcept for F14FastMap and F14FastSet and making the others more concise.

Reviewed By: shixiao

Differential Revision: D9661526

fbshipit-source-id: 101d66623bc4d50e7935fa9a73405a825648e6a5
parent 46bb4594
...@@ -275,6 +275,12 @@ class F14BasicMap { ...@@ -275,6 +275,12 @@ class F14BasicMap {
F14BasicMap& operator=(F14BasicMap&&) = default; F14BasicMap& operator=(F14BasicMap&&) = default;
F14BasicMap& operator=(std::initializer_list<value_type> ilist) {
clear();
bulkInsert(ilist.begin(), ilist.end(), false);
return *this;
}
allocator_type get_allocator() const noexcept { allocator_type get_allocator() const noexcept {
return table_.alloc(); return table_.alloc();
} }
...@@ -916,10 +922,17 @@ class F14ValueMap ...@@ -916,10 +922,17 @@ class F14ValueMap
using Super = f14::detail::F14BasicMap<Policy>; using Super = f14::detail::F14BasicMap<Policy>;
public: public:
F14ValueMap() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {} using typename Super::value_type;
F14ValueMap() = default;
using Super::Super; using Super::Super;
F14ValueMap& operator=(std::initializer_list<value_type> ilist) {
Super::operator=(ilist);
return *this;
}
void swap(F14ValueMap& rhs) noexcept(Policy::kSwapIsNoexcept) { void swap(F14ValueMap& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_); this->table_.swap(rhs.table_);
} }
...@@ -970,10 +983,15 @@ class F14NodeMap ...@@ -970,10 +983,15 @@ class F14NodeMap
public: public:
using typename Super::value_type; using typename Super::value_type;
F14NodeMap() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {} F14NodeMap() = default;
using Super::Super; using Super::Super;
F14NodeMap& operator=(std::initializer_list<value_type> ilist) {
Super::operator=(ilist);
return *this;
}
void swap(F14NodeMap& rhs) noexcept(Policy::kSwapIsNoexcept) { void swap(F14NodeMap& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_); this->table_.swap(rhs.table_);
} }
...@@ -1049,11 +1067,16 @@ class F14VectorMap ...@@ -1049,11 +1067,16 @@ class F14VectorMap
using reverse_iterator = typename Policy::ReverseIter; using reverse_iterator = typename Policy::ReverseIter;
using const_reverse_iterator = typename Policy::ConstReverseIter; using const_reverse_iterator = typename Policy::ConstReverseIter;
F14VectorMap() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {} F14VectorMap() = default;
// inherit constructors // inherit constructors
using Super::Super; using Super::Super;
F14VectorMap& operator=(std::initializer_list<value_type> ilist) {
Super::operator=(ilist);
return *this;
}
void swap(F14VectorMap& rhs) noexcept(Policy::kSwapIsNoexcept) { void swap(F14VectorMap& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_); this->table_.swap(rhs.table_);
} }
...@@ -1252,8 +1275,16 @@ class F14FastMap : public std::conditional_t< ...@@ -1252,8 +1275,16 @@ class F14FastMap : public std::conditional_t<
F14VectorMap<Key, Mapped, Hasher, KeyEqual, Alloc>>; F14VectorMap<Key, Mapped, Hasher, KeyEqual, Alloc>>;
public: public:
using typename Super::value_type;
F14FastMap() = default;
using Super::Super; using Super::Super;
F14FastMap() : Super() {}
F14FastMap& operator=(std::initializer_list<value_type> ilist) {
Super::operator=(ilist);
return *this;
}
}; };
template <typename K, typename M, typename H, typename E, typename A> template <typename K, typename M, typename H, typename E, typename A>
......
...@@ -271,6 +271,12 @@ class F14BasicSet { ...@@ -271,6 +271,12 @@ class F14BasicSet {
F14BasicSet& operator=(F14BasicSet&&) = default; F14BasicSet& operator=(F14BasicSet&&) = default;
F14BasicSet& operator=(std::initializer_list<value_type> ilist) {
clear();
bulkInsert(ilist.begin(), ilist.end(), false);
return *this;
}
allocator_type get_allocator() const noexcept { allocator_type get_allocator() const noexcept {
return table_.alloc(); return table_.alloc();
} }
...@@ -699,10 +705,17 @@ class F14ValueSet ...@@ -699,10 +705,17 @@ class F14ValueSet
using Super = f14::detail::F14BasicSet<Policy>; using Super = f14::detail::F14BasicSet<Policy>;
public: public:
F14ValueSet() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {} using typename Super::value_type;
F14ValueSet() = default;
using Super::Super; using Super::Super;
F14ValueSet& operator=(std::initializer_list<value_type> ilist) {
Super::operator=(ilist);
return *this;
}
void swap(F14ValueSet& rhs) noexcept(Policy::kSwapIsNoexcept) { void swap(F14ValueSet& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_); this->table_.swap(rhs.table_);
} }
...@@ -746,10 +759,15 @@ class F14NodeSet ...@@ -746,10 +759,15 @@ class F14NodeSet
public: public:
using typename Super::value_type; using typename Super::value_type;
F14NodeSet() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {} F14NodeSet() = default;
using Super::Super; using Super::Super;
F14NodeSet& operator=(std::initializer_list<value_type> ilist) {
Super::operator=(ilist);
return *this;
}
void swap(F14NodeSet& rhs) noexcept(Policy::kSwapIsNoexcept) { void swap(F14NodeSet& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_); this->table_.swap(rhs.table_);
} }
...@@ -812,11 +830,15 @@ class F14VectorSet ...@@ -812,11 +830,15 @@ class F14VectorSet
using reverse_iterator = typename Policy::ReverseIter; using reverse_iterator = typename Policy::ReverseIter;
using const_reverse_iterator = reverse_iterator; using const_reverse_iterator = reverse_iterator;
F14VectorSet() noexcept(Policy::kDefaultConstructIsNoexcept) : Super{} {} F14VectorSet() = default;
// inherit constructors
using Super::Super; using Super::Super;
F14VectorSet& operator=(std::initializer_list<value_type> ilist) {
Super::operator=(ilist);
return *this;
}
void swap(F14VectorSet& rhs) noexcept(Policy::kSwapIsNoexcept) { void swap(F14VectorSet& rhs) noexcept(Policy::kSwapIsNoexcept) {
this->table_.swap(rhs.table_); this->table_.swap(rhs.table_);
} }
...@@ -1026,8 +1048,16 @@ class F14FastSet : public std::conditional_t< ...@@ -1026,8 +1048,16 @@ class F14FastSet : public std::conditional_t<
F14VectorSet<Key, Hasher, KeyEqual, Alloc>>; F14VectorSet<Key, Hasher, KeyEqual, Alloc>>;
public: public:
using typename Super::value_type;
F14FastSet() = default;
using Super::Super; using Super::Super;
F14FastSet() : Super() {}
F14FastSet& operator=(std::initializer_list<value_type> ilist) {
Super::operator=(ilist);
return *this;
}
}; };
template <typename K, typename H, typename E, typename A> template <typename K, typename H, typename E, typename A>
......
...@@ -273,6 +273,20 @@ void runSimple() { ...@@ -273,6 +273,20 @@ void runSimple() {
EXPECT_EQ(h3.at(s("ghi")), s("GHI")); EXPECT_EQ(h3.at(s("ghi")), s("GHI"));
EXPECT_THROW(h3.at(s("abc")), std::out_of_range); EXPECT_THROW(h3.at(s("abc")), std::out_of_range);
h8.clear();
h8.emplace(s("abc"), s("ABC"));
EXPECT_GE(h8.bucket_count(), 1);
h8 = {};
EXPECT_GE(h8.bucket_count(), 1);
h9 = {{s("abc"), s("ABD")}, {s("def"), s("DEF")}};
EXPECT_TRUE(h8.empty());
EXPECT_EQ(h9.size(), 2);
auto expectH8 = [&](T& ref) { EXPECT_EQ(&ref, &h8); };
expectH8((h8 = h2));
expectH8((h8 = std::move(h2)));
expectH8((h8 = {}));
F14TableStats::compute(h); F14TableStats::compute(h);
F14TableStats::compute(h2); F14TableStats::compute(h2);
F14TableStats::compute(h3); F14TableStats::compute(h3);
......
...@@ -263,6 +263,20 @@ void runSimple() { ...@@ -263,6 +263,20 @@ void runSimple() {
EXPECT_EQ(h8.count(k), 1); EXPECT_EQ(h8.count(k), 1);
} }
h8.clear();
h8.emplace(s("abc"));
EXPECT_GT(h8.bucket_count(), 1);
h8 = {};
EXPECT_GT(h8.bucket_count(), 1);
h9 = {s("abc"), s("def")};
EXPECT_TRUE(h8.empty());
EXPECT_EQ(h9.size(), 2);
auto expectH8 = [&](T& ref) { EXPECT_EQ(&ref, &h8); };
expectH8((h8 = h2));
expectH8((h8 = std::move(h2)));
expectH8((h8 = {}));
F14TableStats::compute(h); F14TableStats::compute(h);
F14TableStats::compute(h2); F14TableStats::compute(h2);
F14TableStats::compute(h3); F14TableStats::compute(h3);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment