vecs
Fast, flexible ecs in C++ with ergonomic API
Loading...
Searching...
No Matches
dense_map.h
1#ifndef __VECS_STORAGE_DENSE_MAP_H__
2#define __VECS_STORAGE_DENSE_MAP_H__
3
4#include <algorithm>
5#include <vector>
6
7namespace vecs::storage {
8
17template<
18 typename Key,
19 typename Value,
20 typename = std::enable_if_t<std::is_integral_v<Key>>>
21class dense_map {
22 public:
23 using pair_type = std::pair<Key, Value>;
24 using iterator = typename std::vector<pair_type>::iterator;
25 using const_iterator = typename std::vector<pair_type>::const_iterator;
26
27 void insert(const Key& key, const Value& value) {
28 auto it = std::lower_bound(
29 m_data.begin(),
30 m_data.end(),
31 key,
32 [](const pair_type& lhs, const Key& rhs) { return lhs.first < rhs; }
33 );
34 if (it != m_data.end() && it->first == key) {
35 // Key already exists; update the value
36 it->second = value;
37 } else {
38 // Insert the new key and value at the correct position
39 m_data.insert(it, pair_type {key, value});
40 }
41 }
42
43 iterator find(const Key& key) {
44 auto it = std::lower_bound(
45 m_data.begin(),
46 m_data.end(),
47 key,
48 [](const pair_type& lhs, const Key& rhs) { return lhs.first < rhs; }
49 );
50 if (it != m_data.end() && it->first == key) {
51 return it;
52 }
53 return m_data.end();
54 }
55
56 const_iterator find(const Key& key) const {
57 auto it = std::lower_bound(
58 m_data.begin(),
59 m_data.end(),
60 key,
61 [](const pair_type& lhs, const Key& rhs) { return lhs.first < rhs; }
62 );
63 if (it != m_data.end() && it->first == key) {
64 return it;
65 }
66 return m_data.end();
67 }
68
69 Value& operator[](const Key& key) {
70 auto it = std::lower_bound(
71 m_data.begin(),
72 m_data.end(),
73 key,
74 [](const pair_type& lhs, const Key& rhs) { return lhs.first < rhs; }
75 );
76 if (it != m_data.end() && it->first == key) {
77 return it->second;
78 } else {
79 // Key does not exist; insert default value
80 return m_data.insert(it, pair_type {key, Value {}})->second;
81 }
82 }
83
84 void clear() {
85 m_data.clear();
86 }
87
88 void erase(const Key& key) {
89 auto it = std::lower_bound(
90 m_data.begin(),
91 m_data.end(),
92 key,
93 [](const pair_type& lhs, const Key& rhs) { return lhs.first < rhs; }
94 );
95 if (it != m_data.end() && it->first == key) {
96 m_data.erase(it);
97 }
98 }
99
100 iterator erase(iterator it) {
101 return m_data.erase(it);
102 }
103
104 size_t size() const {
105 return m_data.size();
106 }
107
108 bool empty() const {
109 return m_data.empty();
110 }
111
112 iterator begin() {
113 return m_data.begin();
114 }
115
116 const_iterator begin() const {
117 return m_data.begin();
118 }
119
120 iterator end() {
121 return m_data.end();
122 }
123
124 const_iterator end() const {
125 return m_data.end();
126 }
127
128 private:
129 std::vector<pair_type>
130 m_data; // Stores pairs of keys and values in sorted order
131};
132
133} // namespace vecs::storage
134
135#endif
A dense map optimized for integral keys.
Definition dense_map.h:21