entt  2.0.1
sparse_set.hpp
1 #ifndef ENTT_ENTITY_SPARSE_SET_HPP
2 #define ENTT_ENTITY_SPARSE_SET_HPP
3 
4 
5 #include <algorithm>
6 #include <utility>
7 #include <vector>
8 #include <cstddef>
9 #include <cassert>
10 #include "traits.hpp"
11 
12 
13 namespace entt {
14 
15 
22 template<typename...>
23 class SparseSet;
24 
25 
53 template<typename Entity>
56 
57  struct Iterator {
58  using value_type = Entity;
59 
60  Iterator(const std::vector<Entity> *direct, std::size_t pos)
61  : direct{direct}, pos{pos}
62  {}
63 
64  Iterator & operator++() noexcept {
65  return --pos, *this;
66  }
67 
68  Iterator operator++(int) noexcept {
69  Iterator orig = *this;
70  return ++(*this), orig;
71  }
72 
73  bool operator==(const Iterator &other) const noexcept {
74  return other.pos == pos && other.direct == direct;
75  }
76 
77  bool operator!=(const Iterator &other) const noexcept {
78  return !(*this == other);
79  }
80 
81  value_type operator*() const noexcept {
82  return (*direct)[pos-1];
83  }
84 
85  private:
86  const std::vector<Entity> *direct;
87  std::size_t pos;
88  };
89 
90 public:
92  using entity_type = Entity;
96  using size_type = std::size_t;
98  using iterator_type = Iterator;
99 
101  explicit SparseSet() noexcept = default;
102 
104  SparseSet(const SparseSet &) = delete;
106  SparseSet(SparseSet &&) = default;
107 
109  virtual ~SparseSet() noexcept = default;
110 
112  SparseSet & operator=(const SparseSet &) = delete;
114  SparseSet & operator=(SparseSet &&) = default;
115 
126  size_type size() const noexcept {
127  return direct.size();
128  }
129 
134  bool empty() const noexcept {
135  return direct.empty();
136  }
137 
153  const entity_type * data() const noexcept {
154  return direct.data();
155  }
156 
169  iterator_type begin() const noexcept {
170  return Iterator{&direct, direct.size()};
171  }
172 
186  iterator_type end() const noexcept {
187  return Iterator{&direct, 0};
188  }
189 
195  bool has(entity_type entity) const noexcept {
196  const auto entt = entity & traits_type::entity_mask;
197  return entt < reverse.size() && reverse[entt] < direct.size() && direct[reverse[entt]] == entity;
198  }
199 
212  pos_type get(entity_type entity) const noexcept {
213  assert(has(entity));
214  return reverse[entity & traits_type::entity_mask];
215  }
216 
230  assert(!has(entity));
231  const auto entt = entity & traits_type::entity_mask;
232 
233  if(!(entt < reverse.size())) {
234  reverse.resize(entt+1);
235  }
236 
237  const auto pos = pos_type(direct.size());
238  reverse[entt] = pos;
239  direct.emplace_back(entity);
240 
241  return pos;
242  }
243 
255  virtual void destroy(entity_type entity) {
256  assert(has(entity));
257  const auto entt = entity & traits_type::entity_mask;
258  const auto back = direct.back() & traits_type::entity_mask;
259  const auto pos = reverse[entt];
260  reverse[back] = pos;
261  direct[pos] = direct.back();
262  direct.pop_back();
263  }
264 
280  virtual void swap(entity_type lhs, entity_type rhs) {
281  assert(has(lhs));
282  assert(has(rhs));
283  const auto le = lhs & traits_type::entity_mask;
284  const auto re = rhs & traits_type::entity_mask;
285  std::swap(direct[reverse[le]], direct[reverse[re]]);
286  std::swap(reverse[le], reverse[re]);
287  }
288 
304  template<typename Compare>
305  void sort(Compare compare) {
306  std::vector<pos_type> copy{direct.cbegin(), direct.cend()};
307  std::sort(copy.begin(), copy.end(), [compare = std::move(compare)](auto... args) {
308  return !compare(args...);
309  });
310 
311  for(pos_type i = 0; i < copy.size(); ++i) {
312  if(direct[i] != copy[i]) {
313  swap(direct[i], copy[i]);
314  }
315  }
316  }
317 
337  void respect(const SparseSet<Entity> &other) {
338  struct Bool { bool value{false}; };
339  std::vector<Bool> check(std::max(other.reverse.size(), reverse.size()));
340 
341  for(auto entity: other.direct) {
342  check[entity & traits_type::entity_mask].value = true;
343  }
344 
345  sort([this, &other, &check](auto lhs, auto rhs) {
346  const auto le = lhs & traits_type::entity_mask;
347  const auto re = rhs & traits_type::entity_mask;
348 
349  const bool bLhs = check[le].value;
350  const bool bRhs = check[re].value;
351  bool compare = false;
352 
353  if(bLhs && bRhs) {
354  compare = other.get(rhs) < other.get(lhs);
355  } else if(!bLhs && !bRhs) {
356  compare = re < le;
357  } else {
358  compare = bLhs;
359  }
360 
361  return compare;
362  });
363  }
364 
368  virtual void reset() {
369  reverse.clear();
370  direct.clear();
371  }
372 
373 private:
374  std::vector<entity_type> reverse;
375  std::vector<entity_type> direct;
376 };
377 
378 
401 template<typename Entity, typename Type>
404 
405 public:
407  using type = Type;
416 
418  explicit SparseSet() noexcept = default;
419 
421  SparseSet(const SparseSet &) = delete;
423  SparseSet(SparseSet &&) = default;
424 
426  SparseSet & operator=(const SparseSet &) = delete;
428  SparseSet & operator=(SparseSet &&) = default;
429 
445  const type * raw() const noexcept {
446  return instances.data();
447  }
448 
464  type * raw() noexcept {
465  return instances.data();
466  }
467 
480  const type & get(entity_type entity) const noexcept {
481  return instances[underlying_type::get(entity)];
482  }
483 
496  type & get(entity_type entity) noexcept {
497  return const_cast<type &>(const_cast<const SparseSet *>(this)->get(entity));
498  }
499 
514  template<typename... Args>
515  type & construct(entity_type entity, Args&&... args) {
516  underlying_type::construct(entity);
517  instances.push_back({ std::forward<Args>(args)... });
518  return instances.back();
519  }
520 
532  void destroy(entity_type entity) override {
533  instances[underlying_type::get(entity)] = std::move(instances.back());
534  instances.pop_back();
535  underlying_type::destroy(entity);
536  }
537 
554  void swap(entity_type lhs, entity_type rhs) override {
555  std::swap(instances[underlying_type::get(lhs)], instances[underlying_type::get(rhs)]);
556  underlying_type::swap(lhs, rhs);
557  }
558 
562  void reset() override {
563  underlying_type::reset();
564  instances.clear();
565  }
566 
567 private:
568  std::vector<type> instances;
569 };
570 
571 
572 }
573 
574 
575 #endif // ENTT_ENTITY_SPARSE_SET_HPP
void swap(entity_type lhs, entity_type rhs) override
Swaps the two entities and their objects.
Definition: sparse_set.hpp:554
void sort(Compare compare)
Sort entities according to the given comparison function.
Definition: sparse_set.hpp:305
Type type
Type of the objects associated to the entities.
Definition: sparse_set.hpp:407
virtual void reset()
Resets the sparse set.
Definition: sparse_set.hpp:368
EnTT default namespace.
Definition: family.hpp:10
void reset() override
Resets the sparse set.
Definition: sparse_set.hpp:562
bool empty() const noexcept
Checks whether the sparse set is empty.
Definition: sparse_set.hpp:134
virtual void swap(entity_type lhs, entity_type rhs)
Swaps the position of the entities in the internal packed array.
Definition: sparse_set.hpp:280
type & construct(entity_type entity, Args &&... args)
Assigns an entity to the sparse set and constructs its object.
Definition: sparse_set.hpp:515
Sparse set.
Definition: sparse_set.hpp:23
std::size_t size_type
Unsigned integer type.
Definition: sparse_set.hpp:96
void respect(const SparseSet< Entity > &other)
Sort entities according to their order in the given sparse set.
Definition: sparse_set.hpp:337
Extended sparse set implementation.
Definition: sparse_set.hpp:402
void destroy(entity_type entity) override
Removes an entity from the sparse set and destroies its object.
Definition: sparse_set.hpp:532
Entity entity_type
Underlying entity identifier.
Definition: sparse_set.hpp:92
Iterator iterator_type
Input iterator type.
Definition: sparse_set.hpp:98
Basic sparse set implementation.
Definition: sparse_set.hpp:54
type * raw() noexcept
Direct access to the array of objects.
Definition: sparse_set.hpp:464
bool has(entity_type entity) const noexcept
Checks if the sparse set contains the given entity.
Definition: sparse_set.hpp:195
entity_type pos_type
Entity dependent position type.
Definition: sparse_set.hpp:94
const entity_type * data() const noexcept
Direct access to the internal packed array.
Definition: sparse_set.hpp:153
iterator_type end() const noexcept
Returns an iterator to the end.
Definition: sparse_set.hpp:186
virtual void destroy(entity_type entity)
Removes the given entity from the sparse set.
Definition: sparse_set.hpp:255
bool operator!=(const SigH< Ret(Args...)> &lhs, const SigH< Ret(Args...)> &rhs) noexcept
Checks if the contents of the two signals are different.
Definition: sigh.hpp:329
iterator_type begin() const noexcept
Returns an iterator to the beginning.
Definition: sparse_set.hpp:169
pos_type construct(entity_type entity)
Assigns an entity to the sparse set.
Definition: sparse_set.hpp:229
pos_type get(entity_type entity) const noexcept
Returns the position of the entity in the sparse set.
Definition: sparse_set.hpp:212
Entity traits.
Definition: traits.hpp:18