SPH
FlatMap.h
Go to the documentation of this file.
1 #pragma once
2 
7 
10 #include <algorithm>
11 
13 
18 template <typename TKey, typename TValue, typename TLess = std::less<TKey>>
19 class FlatMap : TLess, Noncopyable {
20 public:
22  struct Element {
25  TKey key;
26  TValue value;
27  };
28 
29 private:
30  Array<Element> data;
31 
32 public:
33  FlatMap() = default;
34 
39  FlatMap(std::initializer_list<Element> list)
40  : data(list) {
41  std::sort(data.begin(), data.end(), [this](const Element& e1, const Element& e2) {
42  return less(e1.key, e2.key);
43  });
44  }
45 
49  INLINE TValue& operator[](const TKey& key) {
50  Element* element = this->find(key);
51  SPH_ASSERT(element);
52  return element->value;
53  }
54 
58  INLINE const TValue& operator[](const TKey& key) const {
59  const Element* element = this->find(key);
60  SPH_ASSERT(element);
61  return element->value;
62  }
63 
65  INLINE TValue& insert(const TKey& key, const TValue& value) {
66  Element* element = this->find(key);
67  if (!element) {
68  return this->add(key, value);
69  } else {
70  element->value = value;
71  return element->value;
72  }
73  }
74 
76  INLINE TValue& insert(const TKey& key, TValue&& value) {
77  Element* element = this->find(key);
78  if (!element) {
79  return this->add(key, std::move(value));
80  } else {
81  element->value = std::move(value);
82  return element->value;
83  }
84  }
85 
89  INLINE void remove(const TKey& key) {
90  Element* element = this->find(key);
91  SPH_ASSERT(element);
92  const Size index = element - &data[0];
93  data.remove(index);
94  }
95 
99  INLINE bool tryRemove(const TKey& key) {
100  Element* element = this->find(key);
101  if (!element) {
102  return false;
103  } else {
104  const Size index = element - &data[0];
105  data.remove(index);
106  return true;
107  }
108  }
109 
111  INLINE void clear() {
112  data.clear();
113  }
114 
118  INLINE Optional<TValue&> tryGet(const TKey& key) {
119  Element* element = this->find(key);
120  if (!element) {
121  return NOTHING;
122  } else {
123  return element->value;
124  }
125  }
126 
128  INLINE Optional<const TValue&> tryGet(const TKey& key) const {
129  const Element* element = this->find(key);
130  if (!element) {
131  return NOTHING;
132  } else {
133  return element->value;
134  }
135  }
136 
140  INLINE bool contains(const TKey& key) const {
141  return this->find(key) != nullptr;
142  }
143 
145  INLINE Size size() const {
146  return data.size();
147  }
148 
150  INLINE Size empty() const {
151  return data.empty();
152  }
153 
156  return data.begin();
157  }
158 
161  return data.begin();
162  }
163 
166  return data.end();
167  }
168 
171  return data.end();
172  }
173 
175  return data;
176  }
177 
178  INLINE operator ArrayView<const Element>() const {
179  return data;
180  }
181 
182  FlatMap clone() const {
183  FlatMap cloned;
184  cloned.data = data.clone();
185  return cloned;
186  }
187 
188 private:
189  INLINE bool less(const TKey& key1, const TKey& key2) const {
190  return TLess::operator()(key1, key2);
191  }
192 
194  INLINE Element* find(const TKey& key) {
195  auto compare = [this](const Element& element, const TKey& key) { return less(element.key, key); };
196  auto iter = std::lower_bound(data.begin(), data.end(), key, compare);
197  if (iter != data.end() && iter->key == key) {
198  return &*iter;
199  } else {
200  return nullptr;
201  }
202  }
203 
204  INLINE const Element* find(const TKey& key) const {
205  return const_cast<FlatMap*>(this)->find(key);
206  }
207 
209  template <typename T>
210  INLINE TValue& add(const TKey& key, T&& value) {
211  Size from = 0;
212  Size to = data.size();
213  Size mid = Size(-1);
214 
215  while (from < to && from != mid) {
216  mid = (from + to) / 2;
217  SPH_ASSERT(less(data[mid].key, key) || less(key, data[mid].key));
218  if (less(data[mid].key, key)) {
219  from = mid + 1;
220  } else {
221  to = mid;
222  }
223  }
224  data.insert(from, Element{ key, std::forward<T>(value) });
225  return data[from].value;
226  }
227 };
228 
229 
Generic dynamically allocated resizable storage.
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
Wrapper of type value of which may or may not be present.
const NothingType NOTHING
Definition: Optional.h:16
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
INLINE Iterator< StorageType > end() noexcept
Definition: Array.h:462
void remove(const TCounter idx)
Removes an element with given index from the array.
Definition: Array.h:383
void insert(const TCounter position, U &&value)
Inserts a new element to given position in the array.
Definition: Array.h:345
void clear()
Removes all elements from the array, but does NOT release the memory.
Definition: Array.h:434
INLINE TCounter size() const noexcept
Definition: Array.h:193
INLINE bool empty() const noexcept
Definition: Array.h:201
INLINE Iterator< StorageType > begin() noexcept
Definition: Array.h:450
Array clone() const
Performs a deep copy of all elements of the array.
Definition: Array.h:147
Container of key-value pairs.
Definition: FlatMap.h:19
FlatMap clone() const
Definition: FlatMap.h:182
INLINE Optional< const TValue & > tryGet(const TKey &key) const
Returns a reference to the value matching the given key, or NOTHING if no such value exists.
Definition: FlatMap.h:128
INLINE Iterator< Element > end()
Returns the iterator pointing to the one-past-last element.
Definition: FlatMap.h:165
FlatMap()=default
INLINE Iterator< const Element > end() const
Returns the iterator pointing to the one-past-last element.
Definition: FlatMap.h:170
INLINE Size empty() const
Returns true if the map contains no elements, false otherwise.
Definition: FlatMap.h:150
INLINE bool tryRemove(const TKey &key)
Removes element with given key if present, otherwise it does nothing.
Definition: FlatMap.h:99
INLINE TValue & insert(const TKey &key, TValue &&value)
Adds a new element into the map or sets new value of element with the same key.
Definition: FlatMap.h:76
INLINE bool contains(const TKey &key) const
Returns true if the map contains element of given key.
Definition: FlatMap.h:140
INLINE void remove(const TKey &key)
Removes element with given key from the map.
Definition: FlatMap.h:89
INLINE TValue & insert(const TKey &key, const TValue &value)
Adds a new element into the map or sets new value of element with the same key.
Definition: FlatMap.h:65
INLINE TValue & operator[](const TKey &key)
Returns a reference to the element, given its key.
Definition: FlatMap.h:49
FlatMap(std::initializer_list< Element > list)
Constructs the map fromm initializer list of elements.
Definition: FlatMap.h:39
INLINE Iterator< Element > begin()
Returns the iterator pointing to the first element.
Definition: FlatMap.h:155
INLINE void clear()
Removes all elements from the map.
Definition: FlatMap.h:111
INLINE Optional< TValue & > tryGet(const TKey &key)
Returns a reference to the value matching the given key, or NOTHING if no such value exists.
Definition: FlatMap.h:118
INLINE const TValue & operator[](const TKey &key) const
Returns a reference to the element, given its key.
Definition: FlatMap.h:58
INLINE Size size() const
Returns the number of elements in the map.
Definition: FlatMap.h:145
INLINE Iterator< const Element > begin() const
Returns the iterator pointing to the first element.
Definition: FlatMap.h:160
Simple (forward) iterator over continuous array of objects of type T.
Definition: Iterator.h:18
Wrapper of type value of which may or may not be present.
Definition: Optional.h:23
Element of the container.
Definition: FlatMap.h:22
TValue value
Definition: FlatMap.h:26
Object with deleted copy constructor and copy operator.
Definition: Object.h:54