lxgui
utils_sorted_vector.hpp
1 #ifndef LXGUI_SORTED_VECTOR_HPP
2 #define LXGUI_SORTED_VECTOR_HPP
3 
4 #include "lxgui/lxgui.hpp"
5 
6 #include <algorithm>
7 #include <functional>
8 #include <memory>
9 #include <vector>
10 
11 namespace lxgui::utils {
12 
68 template<typename T, typename Cmp = std::less<T>>
69 class sorted_vector : private std::vector<T> {
70  using base = std::vector<T>;
71  Cmp compare;
72 
73 public:
74  using iterator = typename base::iterator;
75  using const_iterator = typename base::const_iterator;
76  using reverse_iterator = typename base::reverse_iterator;
77  using const_reverse_iterator = typename base::const_reverse_iterator;
78 
83  sorted_vector() = default;
84 
86  sorted_vector(const sorted_vector& s) = default;
87 
93  sorted_vector(sorted_vector&& s) = default;
94 
96  sorted_vector& operator=(const sorted_vector& s) = default;
97 
104 
109  explicit sorted_vector(const base& s) : base(s) {}
110 
117  explicit sorted_vector(base&& s) : base(std::move(s)) {}
118 
123  explicit sorted_vector(const Cmp& c) : compare(c) {}
124 
129  sorted_vector(std::initializer_list<T> l) {
130  for (auto& e : l) {
131  insert(e);
132  }
133  }
134 
136  Cmp& comparator() {
137  return compare;
138  }
139 
141  const Cmp& comparator() const {
142  return compare;
143  }
144 
151  template<typename U>
152  std::pair<iterator, bool> insert(U&& t) {
153  if (empty()) {
154  base::push_back(std::forward<U>(t));
155  return {base::begin(), true};
156  } else {
157  auto iter = std::lower_bound(base::begin(), base::end(), t, compare);
158  if (iter != base::end() && !compare(t, *iter)) {
159  return {iter, false};
160  } else {
161  return {base::insert(iter, std::forward<U>(t)), true};
162  }
163  }
164  }
165 
170  template<typename U>
172  auto [iter, inserted] = insert(std::forward<U>(t));
173  if (!inserted)
174  *iter = std::forward<U>(t);
175  return iter;
176  }
177 
180  return base::erase(iter);
181  }
182 
185  return base::erase(first, last);
186  }
187 
194  template<typename Key>
195  iterator erase(const Key& k) {
196  auto iter = find(k);
197  if (iter != end()) {
198  return base::erase(iter);
199  } else {
200  return end();
201  }
202  }
203 
209  template<typename Key>
210  iterator find(const Key& k) {
211  if (!empty()) {
212  auto iter = std::lower_bound(begin(), end(), k, compare);
213  if (iter != end() && !compare(k, *iter)) {
214  return iter;
215  }
216  }
217  return end();
218  }
219 
225  template<typename Key>
226  const_iterator find(const Key& k) const {
227  if (!empty()) {
228  auto iter = std::lower_bound(begin(), end(), k, compare);
229  if (iter != end() && !compare(k, *iter)) {
230  return iter;
231  }
232  }
233  return end();
234  }
235 
236  using base::back;
237  using base::capacity;
238  using base::clear;
239  using base::empty;
240  using base::front;
241  using base::max_size;
242  using base::pop_back;
243  using base::reserve;
244  using base::size;
245 
246  using base::begin;
247  using base::end;
248  using base::rbegin;
249  using base::rend;
250 };
251 
252 } // namespace lxgui::utils
253 
254 #endif
Sorted std::vector wrapper. This class is a light alternative to std::set. Inspired from: [1] www....
sorted_vector(const Cmp &c)
Default constructor, with comparator. Creates an empty vector and sets the comparator function.
sorted_vector & operator=(sorted_vector &&s)=default
Move another vector into this one. The other vector is left empty in the process, and all its content...
const_iterator find(const Key &k) const
Find an object in this vector by its key. The key can be a copy of the element itself,...
typename base::const_reverse_iterator const_reverse_iterator
sorted_vector()=default
Default constructor. Creates an empty vector.
iterator find(const Key &k)
Find an object in this vector by its key. The key can be a copy of the element itself,...
typename base::reverse_iterator reverse_iterator
std::pair< iterator, bool > insert(U &&t)
Insert the provided object in the vector, only if no object exists with the same key.
iterator erase(const Key &k)
Erase an element from this vector by its key. The key can be a copy of the element itself,...
iterator erase(iterator first, iterator last)
Erase a range from this vector.
sorted_vector(sorted_vector &&s)=default
Move another sorted_vector into this one. The other vector is left empty in the process,...
typename base::const_iterator const_iterator
iterator erase(iterator iter)
Erase an element from this vector.
typename base::iterator iterator
Cmp & comparator()
Return the comparator object.
sorted_vector & operator=(const sorted_vector &s)=default
Copy another sorted_vector into this one.
sorted_vector(const base &s)
Copy a pre-built vector into this one. The provided vector must be sorted, and shall not contain any ...
iterator insert_or_assign(U &&t)
Insert the provided object in the vector.
const Cmp & comparator() const
Return the comparator object.
sorted_vector(base &&s)
Move a pre-built vector into this one. The provided vector must be sorted, and shall not contain any ...
sorted_vector(std::initializer_list< T > l)
Write an initializer list into this vector. The list need not be sorted.
sorted_vector(const sorted_vector &s)=default
Copy another vector into this one.
Empty type, used in the implementation of utils::variant.