1 #ifndef ENTT_ENTITY_SPARSE_SET_HPP 2 #define ENTT_ENTITY_SPARSE_SET_HPP 11 #include <type_traits> 55 template<
typename Entity>
60 using value_type = Entity;
62 Iterator(
const std::vector<Entity> *direct, std::size_t pos)
63 : direct{direct}, pos{pos}
66 Iterator & operator++() noexcept {
70 Iterator operator++(
int) noexcept {
71 Iterator orig = *
this;
72 return ++(*this), orig;
75 bool operator==(
const Iterator &other)
const noexcept {
76 return other.pos == pos && other.direct == direct;
79 bool operator!=(
const Iterator &other)
const noexcept {
80 return !(*
this == other);
83 value_type operator*()
const noexcept {
84 return (*direct)[pos-1];
88 const std::vector<Entity> *direct;
92 static constexpr Entity in_use = (Entity{1} << traits_type::entity_shift);
131 return direct.size();
139 return direct.empty();
158 return direct.data();
174 return Iterator{&direct, direct.size()};
191 return Iterator{&direct, 0};
202 const auto entt = promotion_type{entity} & traits_type::entity_mask;
204 return (
entt < reverse.size()) && (reverse[
entt] & in_use);
221 const auto entt = entity & traits_type::entity_mask;
223 return reverse[
entt] & ~in_use;
238 assert(!has(entity));
241 const auto entt = promotion_type{entity} & traits_type::entity_mask;
243 if(!(
entt < reverse.size())) {
250 direct.emplace_back(entity);
266 const auto entt = entity & traits_type::entity_mask;
267 const auto back = direct.back() & traits_type::entity_mask;
268 const auto pos = reverse[
entt] & ~in_use;
271 reverse[back] = pos | in_use;
274 direct[pos] = direct.back();
294 assert(lhs < direct.size());
295 assert(rhs < direct.size());
296 std::swap(reverse[direct[lhs]], reverse[direct[rhs]]);
297 std::swap(direct[lhs], direct[rhs]);
320 auto from = other.begin();
321 auto to = other.end();
325 while(pos > 0 && from != to) {
327 if(*from != direct[pos]) {
328 swap(pos,
get(*from));
347 std::vector<pos_type> reverse;
348 std::vector<entity_type> direct;
374 template<
typename Entity,
typename Type>
419 return instances.data();
438 return instances.data();
454 return instances[underlying_type::get(entity)];
487 template<
typename... Args>
489 underlying_type::construct(entity);
491 instances.push_back({ std::forward<Args>(args)... });
492 return instances.back();
508 instances[underlying_type::get(entity)] = std::move(instances.back());
509 instances.pop_back();
510 underlying_type::destroy(entity);
535 template<
typename Compare>
537 std::vector<pos_type> copy(instances.size());
538 std::iota(copy.begin(), copy.end(), 0);
540 std::sort(copy.begin(), copy.end(), [
this, compare = std::move(compare)](
auto lhs,
auto rhs) {
541 return compare(const_cast<const object_type &>(instances[rhs]), const_cast<const object_type &>(instances[lhs]));
544 for(
pos_type i = 0; i < copy.size(); ++i) {
546 auto next = copy[curr];
548 while(curr != next) {
549 auto lhs = copy[curr];
550 auto rhs = copy[next];
551 std::swap(instances[lhs], instances[rhs]);
552 underlying_type::swap(lhs, rhs);
583 auto from = other.begin();
584 auto to = other.end();
586 pos_type pos = underlying_type::size() - 1;
587 const auto *direct = underlying_type::data();
589 while(pos > 0 && from != to) {
590 if(underlying_type::has(*from)) {
591 if(*from != *(direct + pos)) {
592 auto candidate = underlying_type::get(*from);
593 std::swap(instances[pos], instances[candidate]);
594 underlying_type::swap(pos, candidate);
608 underlying_type::reset();
613 std::vector<object_type> instances;
620 #endif // ENTT_ENTITY_SPARSE_SET_HPP void sort(Compare compare)
Sort components according to the given comparison function.
virtual void reset()
Resets a sparse set.
void reset() override
Resets a sparse set.
bool empty() const noexcept
Checks whether a sparse set is empty.
void respect(const SparseSet< Entity > &other) noexcept override
Sort components according to the order of the entities in another sparse set.
std::size_t size_type
Unsigned integer type.
Extended sparse set implementation.
void destroy(entity_type entity) override
Removes an entity from a sparse set and destroies its object.
Entity entity_type
Underlying entity identifier.
Iterator iterator_type
Input iterator type.
Basic sparse set implementation.
bool has(entity_type entity) const noexcept
Checks if a sparse set contains an entity.
entity_type pos_type
Entity dependent position type.
Type object_type
Type of the objects associated to the entities.
const entity_type * data() const noexcept
Direct access to the internal packed array.
iterator_type end() const noexcept
Returns an iterator to the end.
virtual void destroy(entity_type entity)
Removes an entity from a sparse set.
iterator_type begin() const noexcept
Returns an iterator to the beginning.
void construct(entity_type entity)
Assigns an entity to a sparse set.
object_type & construct(entity_type entity, Args &&... args)
Assigns an entity to a sparse set and constructs its object.
constexpr bool operator!=(const HashedString &lhs, const HashedString &rhs) noexcept
Compares two hashed strings.
virtual void respect(const SparseSet< Entity > &other) noexcept
Sort entities according to their order in another sparse set.
object_type * raw() noexcept
Direct access to the array of objects.
void swap(pos_type lhs, pos_type rhs) noexcept
Swaps the position of two entities in the internal packed array.