CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
FlatMap.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7#pragma once
8
9#include "Pair.hpp"
10#include "SmallVector.hpp"
11#include "StaticVector.hpp"
12#include "Vector.hpp"
13
15
16#include <algorithm>
17#include <cstring>
18#include <stdexcept>
19#include <type_traits>
20#include <vector>
21
22namespace CeresEngine {
23
53 template<typename Key, typename T, typename Compare = std::less<>, typename Container = Vector<Pair<Key, T>>> class FlatMap {
54 public:
55 using key_type = Key;
56 using mapped_type = T;
57 using value_type = std::pair<Key, T>;
58 using container_type = Container;
62 using allocator_type = typename container_type::allocator_type;
63 using pointer = typename std::allocator_traits<allocator_type>::pointer;
64 using const_pointer = typename std::allocator_traits<allocator_type>::pointer;
65 using iterator = typename container_type::iterator;
66 using const_iterator = typename container_type::const_iterator;
67 using reverse_iterator = typename container_type::reverse_iterator;
68 using const_reverse_iterator = typename container_type::const_reverse_iterator;
69 using difference_type = typename container_type::difference_type;
70 using size_type = typename container_type::size_type;
71
73
75
76 FlatMap(const FlatMap& x) = default;
77 FlatMap(FlatMap&& x) = default;
78
80 m_cmp = x.m_cmp;
82 return *this;
83 }
85 m_cmp = std::move(x.m_cmp);
86 m_container = std::move(x.m_container);
87 return *this;
88 }
89
90 iterator begin() noexcept { return m_container.begin(); }
92 iterator end() noexcept { return m_container.end(); }
100
101 [[nodiscard]] bool empty() const noexcept { return m_container.empty(); }
104
105 void reserve(size_type count) { return m_container.reserve(count); }
107
108 void clear() noexcept { m_container.clear(); }
109
110 template<typename K = key_type> iterator lower_bound(const K& k) { return std::lower_bound(m_container.begin(), m_container.end(), k, m_cmp); }
111
112 template<typename K = key_type> [[nodiscard]] const_iterator lower_bound(const K& k) const { return std::lower_bound(m_container.begin(), m_container.end(), k, m_cmp); }
113
114 template<typename K = key_type> iterator find(const K& k) {
115 auto i = lower_bound(k);
116 if(i != end() && !m_cmp(k, *i)) {
117 return i;
118 }
119
120 return end();
121 }
122
123 template<typename K = key_type> [[nodiscard]] const_iterator find(const K& k) const {
124 auto i = lower_bound(k);
125 if(i != end() && !m_cmp(k, *i)) {
126 return i;
127 }
128
129 return end();
130 }
131
132 template<typename K = key_type> [[nodiscard]] size_t count(const K& k) const { return find(k) == end() ? 0 : 1; }
133
134 template<typename P> std::pair<iterator, bool> insert(P&& val) {
135 auto i = lower_bound(val.first);
136 if(i != end() && !m_cmp(val.first, *i)) {
137 return {i, false};
138 }
139
140 return {m_container.emplace(i, std::forward<P>(val)), true};
141 }
142
143 std::pair<iterator, bool> insert(const value_type& val) {
144 auto i = lower_bound(val.first);
145 if(i != end() && !m_cmp(val.first, *i)) {
146 return {i, false};
147 }
148
149 return {m_container.emplace(i, val), true};
150 }
151
152 template<typename... Args> std::pair<iterator, bool> emplace(Args&&... args) {
153 value_type val(std::forward<Args>(args)...);
154 return insert(std::move(val));
155 }
156
159
160 template<typename K = key_type> size_type erase(const K& k) {
161 auto i = find(k);
162 if(i == end()) {
163 return 0;
164 }
165
166 erase(i);
167 return 1;
168 }
169
170 template<typename K = key_type> mapped_type& operator[](const K& k) {
171 auto i = lower_bound(k);
172 if(i != end() && !m_cmp(k, *i)) {
173 return i->second;
174 }
175
176 i = m_container.emplace(i, k, mapped_type());
177 return i->second;
178 }
179
180 template<typename K = key_type> mapped_type& operator[](K&& k) {
181 auto i = lower_bound(k);
182 if(i != end() && !m_cmp(k, *i)) {
183 return i->second;
184 }
185
186 i = m_container.emplace(i, std::forward<K>(k), mapped_type());
187 return i->second;
188 }
189
190 template<typename K = key_type> mapped_type& at(const K& k) {
191 auto i = lower_bound(k);
192 if(i == end() || m_cmp(*i, k)) {
193 throw std::out_of_range("FlatMap out of range");
194 }
195
196 return i->second;
197 }
198
199 template<typename K = key_type> [[nodiscard]] const mapped_type& at(const K& k) const {
200 auto i = lower_bound(k);
201 if(i == end() || m_cmp(*i, k)) {
202 throw std::out_of_range("FlatMap out of range");
203 }
204
205 return i->second;
206 }
207
208 void swap(FlatMap& x) {
209 std::swap(m_cmp, x.m_cmp);
210 m_container.swap(x.m_container);
211 }
212
214
215 // DANGER! If you're not careful with this function, you may irreversably break the map
217
218 private:
220 pair_compare() = default;
222
223 template<typename K = key_type> bool operator()(const value_type& a, const K& b) const { return kcmp(a.first, b); }
224 template<typename K = key_type> bool operator()(const K& a, const value_type& b) const { return kcmp(a, b.first); }
225
227 };
230 };
231
232 template<typename Key, typename T, typename Compare, typename Container>
236
237 template<typename Key, typename T, typename Compare, typename Container>
241
243 template<typename Key, typename T, size_t Capacity, typename Compare = std::less<>>
245
246} // namespace CeresEngine
FlatMap is an almsot drop-in replacement of Map.
Definition FlatMap.hpp:53
FlatMap & operator=(FlatMap &&x)
Definition FlatMap.hpp:84
typename container_type::allocator_type allocator_type
Definition FlatMap.hpp:62
FlatMap & operator=(const FlatMap &x)
Definition FlatMap.hpp:79
value_type & reference
Definition FlatMap.hpp:60
FlatMap()
Definition FlatMap.hpp:72
typename std::allocator_traits< allocator_type >::pointer const_pointer
Definition FlatMap.hpp:64
const_reverse_iterator rbegin() const noexcept
Definition FlatMap.hpp:95
Key key_type
Definition FlatMap.hpp:55
typename container_type::difference_type difference_type
Definition FlatMap.hpp:69
const value_type & const_reference
Definition FlatMap.hpp:61
size_type erase(const K &k)
Definition FlatMap.hpp:160
typename container_type::reverse_iterator reverse_iterator
Definition FlatMap.hpp:67
mapped_type & operator[](K &&k)
Definition FlatMap.hpp:180
iterator find(const K &k)
Definition FlatMap.hpp:114
iterator lower_bound(const K &k)
Definition FlatMap.hpp:110
std::pair< iterator, bool > insert(P &&val)
Definition FlatMap.hpp:134
mapped_type & at(const K &k)
Definition FlatMap.hpp:190
typename container_type::const_iterator const_iterator
Definition FlatMap.hpp:66
const_iterator end() const noexcept
Definition FlatMap.hpp:93
void swap(FlatMap &x)
Definition FlatMap.hpp:208
size_type max_size() const noexcept
Definition FlatMap.hpp:103
typename container_type::const_reverse_iterator const_reverse_iterator
Definition FlatMap.hpp:68
size_type size() const noexcept
Definition FlatMap.hpp:102
FlatMap(FlatMap &&x)=default
container_type & modify_container() noexcept
Definition FlatMap.hpp:216
reverse_iterator rbegin() noexcept
Definition FlatMap.hpp:94
const_iterator begin() const noexcept
Definition FlatMap.hpp:91
typename std::allocator_traits< allocator_type >::pointer pointer
Definition FlatMap.hpp:63
size_type capacity() const noexcept
Definition FlatMap.hpp:106
const_iterator find(const K &k) const
Definition FlatMap.hpp:123
typename container_type::iterator iterator
Definition FlatMap.hpp:65
std::pair< iterator, bool > emplace(Args &&... args)
Definition FlatMap.hpp:152
pair_compare m_cmp
Definition FlatMap.hpp:228
iterator erase(const_iterator pos)
Definition FlatMap.hpp:158
const_reverse_iterator rend() const noexcept
Definition FlatMap.hpp:97
container_type m_container
Definition FlatMap.hpp:229
FlatMap(const key_compare &comp, const allocator_type &alloc=allocator_type())
Definition FlatMap.hpp:74
typename container_type::size_type size_type
Definition FlatMap.hpp:70
const_iterator lower_bound(const K &k) const
Definition FlatMap.hpp:112
iterator begin() noexcept
Definition FlatMap.hpp:90
std::pair< iterator, bool > insert(const value_type &val)
Definition FlatMap.hpp:143
const_iterator cend() const noexcept
Definition FlatMap.hpp:99
size_t count(const K &k) const
Definition FlatMap.hpp:132
mapped_type & operator[](const K &k)
Definition FlatMap.hpp:170
const container_type & container() const noexcept
Definition FlatMap.hpp:213
void clear() noexcept
Definition FlatMap.hpp:108
FlatMap(const FlatMap &x)=default
void reserve(size_type count)
Definition FlatMap.hpp:105
iterator erase(iterator pos)
Definition FlatMap.hpp:157
reverse_iterator rend() noexcept
Definition FlatMap.hpp:96
bool empty() const noexcept
Definition FlatMap.hpp:101
iterator end() noexcept
Definition FlatMap.hpp:92
Compare key_compare
Definition FlatMap.hpp:59
const mapped_type & at(const K &k) const
Definition FlatMap.hpp:199
std::pair< Key, T > value_type
Definition FlatMap.hpp:57
Container container_type
Definition FlatMap.hpp:58
const_iterator cbegin() const noexcept
Definition FlatMap.hpp:98
T mapped_type
Definition FlatMap.hpp:56
Definition Application.hpp:19
bool operator!=(const ShortAllocator< T, N, A1 > &x, const ShortAllocator< U, M, A2 > &y) noexcept
Definition Allocator.hpp:416
bool operator==(const ShortAllocator< T, N, A1 > &x, const ShortAllocator< U, M, A2 > &y) noexcept
Definition Allocator.hpp:411
constexpr CountAlgorithmFunctor count
Returns the number of elements matching an element.
Definition Count.hpp:82
constexpr FindAlgorithmFunctor find
Finds the first element equal to another element.
Definition Find.hpp:70
@ Key
The event is of type KeyEvent.
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
Definition FlatMap.hpp:219
pair_compare(const key_compare &kc)
Definition FlatMap.hpp:221
bool operator()(const K &a, const value_type &b) const
Definition FlatMap.hpp:224
bool operator()(const value_type &a, const K &b) const
Definition FlatMap.hpp:223
key_compare kcmp
Definition FlatMap.hpp:226