FlatHashMap: support initializer_list
This commit is contained in:
parent
d5db554b70
commit
d5e163cd9d
@ -72,7 +72,10 @@ class fixed_vector {
|
|||||||
|
|
||||||
template <class KeyT, class ValueT, class HashT = std::hash<KeyT>>
|
template <class KeyT, class ValueT, class HashT = std::hash<KeyT>>
|
||||||
class FlatHashMapImpl {
|
class FlatHashMapImpl {
|
||||||
|
public:
|
||||||
struct Node {
|
struct Node {
|
||||||
|
using first_type = KeyT;
|
||||||
|
using second_type = ValueT;
|
||||||
KeyT first{};
|
KeyT first{};
|
||||||
union {
|
union {
|
||||||
ValueT second;
|
ValueT second;
|
||||||
@ -86,6 +89,10 @@ class FlatHashMapImpl {
|
|||||||
|
|
||||||
Node() {
|
Node() {
|
||||||
}
|
}
|
||||||
|
Node(KeyT key, ValueT value) : first(std::move(key)) {
|
||||||
|
new (&second) ValueT(std::move(value));
|
||||||
|
CHECK(!empty());
|
||||||
|
}
|
||||||
~Node() {
|
~Node() {
|
||||||
if (!empty()) {
|
if (!empty()) {
|
||||||
second.~ValueT();
|
second.~ValueT();
|
||||||
@ -127,10 +134,9 @@ class FlatHashMapImpl {
|
|||||||
using NodeIterator = typename fixed_vector<Node>::iterator;
|
using NodeIterator = typename fixed_vector<Node>::iterator;
|
||||||
using ConstNodeIterator = typename fixed_vector<Node>::const_iterator;
|
using ConstNodeIterator = typename fixed_vector<Node>::const_iterator;
|
||||||
|
|
||||||
public:
|
|
||||||
// define key_type and value_type for benchmarks
|
// define key_type and value_type for benchmarks
|
||||||
using key_type = KeyT;
|
using key_type = KeyT;
|
||||||
using value_type = std::pair<const KeyT, ValueT>;
|
using value_type = Node;
|
||||||
|
|
||||||
struct Iterator {
|
struct Iterator {
|
||||||
using iterator_category = std::bidirectional_iterator_tag;
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
@ -218,6 +224,18 @@ class FlatHashMapImpl {
|
|||||||
assign(other.begin(), other.end());
|
assign(other.begin(), other.end());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlatHashMapImpl(std::initializer_list<Node> nodes) {
|
||||||
|
reserve(nodes.size());
|
||||||
|
for (auto &node : nodes) {
|
||||||
|
size_t bucket = calc_bucket(node.key());
|
||||||
|
while (!nodes_[bucket].empty()) {
|
||||||
|
next_bucket(bucket);
|
||||||
|
}
|
||||||
|
nodes_[bucket].emplace(node.first, node.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FlatHashMapImpl(FlatHashMapImpl &&other) noexcept : nodes_(std::move(other.nodes_)), used_nodes_(other.used_nodes_) {
|
FlatHashMapImpl(FlatHashMapImpl &&other) noexcept : nodes_(std::move(other.nodes_)), used_nodes_(other.used_nodes_) {
|
||||||
other.used_nodes_ = 0;
|
other.used_nodes_ = 0;
|
||||||
}
|
}
|
||||||
|
@ -11,22 +11,29 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
TEST(FlatHashMap, basic) {
|
TEST(FlatHashMap, basic) {
|
||||||
td::FlatHashMap<int, int> map;
|
{
|
||||||
map[1] = 2;
|
td::FlatHashMap<int, int> map;
|
||||||
ASSERT_EQ(2, map[1]);
|
map[1] = 2;
|
||||||
ASSERT_EQ(1, map.find(1)->first);
|
ASSERT_EQ(2, map[1]);
|
||||||
ASSERT_EQ(2, map.find(1)->second);
|
ASSERT_EQ(1, map.find(1)->first);
|
||||||
// ASSERT_EQ(1, map.find(1)->key());
|
ASSERT_EQ(2, map.find(1)->second);
|
||||||
// ASSERT_EQ(2, map.find(1)->value());
|
// ASSERT_EQ(1, map.find(1)->key());
|
||||||
for (auto &kv : map) {
|
// ASSERT_EQ(2, map.find(1)->value());
|
||||||
ASSERT_EQ(1, kv.first);
|
for (auto &kv : map) {
|
||||||
ASSERT_EQ(2, kv.second);
|
ASSERT_EQ(1, kv.first);
|
||||||
|
ASSERT_EQ(2, kv.second);
|
||||||
|
}
|
||||||
|
map.erase(map.find(1));
|
||||||
|
auto map_copy = map;
|
||||||
}
|
}
|
||||||
map.erase(map.find(1));
|
|
||||||
auto map_copy = map;
|
|
||||||
|
|
||||||
td::FlatHashMap<int, std::array<td::unique_ptr<td::string>, 20>> x;
|
td::FlatHashMap<int, std::array<td::unique_ptr<td::string>, 20>> x;
|
||||||
auto y = std::move(x);
|
auto y = std::move(x);
|
||||||
x[12];
|
x[12];
|
||||||
x.erase(x.find(12));
|
x.erase(x.find(12));
|
||||||
|
|
||||||
|
{
|
||||||
|
td::FlatHashMap<int, std::string> map = {{1, "hello"}, {2, "world"}};
|
||||||
|
ASSERT_EQ("hello", map[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user