1#ifndef ENTT_ENTITY_HANDLE_HPP
2#define ENTT_ENTITY_HANDLE_HPP
8#include "../config/config.h"
9#include "../core/iterator.hpp"
10#include "../core/type_traits.hpp"
20class handle_storage_iterator final {
21 template<
typename Other>
22 friend class handle_storage_iterator;
24 using underlying_type = std::remove_reference_t<typename It::value_type::second_type>;
25 using entity_type =
typename underlying_type::entity_type;
28 using value_type =
typename std::iterator_traits<It>::value_type;
29 using pointer = input_iterator_pointer<value_type>;
30 using reference = value_type;
31 using difference_type = std::ptrdiff_t;
32 using iterator_category = std::input_iterator_tag;
33 using iterator_concept = std::forward_iterator_tag;
35 constexpr handle_storage_iterator() noexcept
40 constexpr handle_storage_iterator(entity_type value, It from, It to) noexcept
44 while(it != last && !it->second.contains(entt)) {
49 constexpr handle_storage_iterator &operator++() noexcept {
50 for(++it; it != last && !it->second.contains(entt); ++it) {}
54 constexpr handle_storage_iterator operator++(
int)
noexcept {
55 const handle_storage_iterator orig = *
this;
56 return ++(*this), orig;
59 [[nodiscard]]
constexpr reference operator*() const noexcept {
63 [[nodiscard]]
constexpr pointer operator->() const noexcept {
67 template<
typename ILhs,
typename IRhs>
68 friend constexpr bool operator==(
const handle_storage_iterator<ILhs> &,
const handle_storage_iterator<IRhs> &)
noexcept;
76template<
typename ILhs,
typename IRhs>
77[[nodiscard]]
constexpr bool operator==(
const handle_storage_iterator<ILhs> &lhs,
const handle_storage_iterator<IRhs> &rhs)
noexcept {
78 return lhs.it == rhs.it;
81template<
typename ILhs,
typename IRhs>
82[[nodiscard]]
constexpr bool operator!=(
const handle_storage_iterator<ILhs> &lhs,
const handle_storage_iterator<IRhs> &rhs)
noexcept {
97template<
typename Registry,
typename... Scope>
101 [[nodiscard]]
auto &owner_or_assert()
const noexcept {
102 ENTT_ASSERT(owner !=
nullptr,
"Invalid pointer to registry");
103 return static_cast<Registry &
>(*owner);
143 auto underlying = owner_or_assert().storage();
144 return iterable{{
entt, underlying.begin(), underlying.end()}, {
entt, underlying.end(), underlying.end()}};
148 [[nodiscard]]
explicit operator bool() const noexcept {
149 return owner && owner->valid(
entt);
158 return static_cast<bool>(*this);
184 owner_or_assert().destroy(std::exchange(
entt,
null));
192 owner_or_assert().destroy(std::exchange(
entt,
null), version);
202 template<
typename Type,
typename... Args>
204 decltype(
auto)
emplace(Args &&...args)
const {
205 static_assert(((
sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>),
"Invalid type");
206 return owner_or_assert().template
emplace<Type>(
entt, std::forward<Args>(args)...);
216 template<
typename Type,
typename... Args>
218 static_assert(((
sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>),
"Invalid type");
229 template<
typename Type,
typename... Func>
230 decltype(
auto)
patch(Func &&...func)
const {
231 static_assert(((
sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>),
"Invalid type");
232 return owner_or_assert().template
patch<Type>(
entt, std::forward<Func>(func)...);
242 template<
typename Type,
typename... Args>
243 decltype(
auto)
replace(Args &&...args)
const {
244 static_assert(((
sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>),
"Invalid type");
245 return owner_or_assert().template
replace<Type>(
entt, std::forward<Args>(args)...);
253 template<
typename... Type>
257 return owner_or_assert().template
remove<Type...>(
entt);
264 template<
typename... Type>
267 owner_or_assert().template
erase<Type...>(
entt);
275 template<
typename... Type>
276 [[nodiscard]]
decltype(
auto)
all_of()
const {
277 return owner_or_assert().template
all_of<Type...>(
entt);
286 template<
typename... Type>
287 [[nodiscard]]
decltype(
auto)
any_of()
const {
288 return owner_or_assert().template
any_of<Type...>(
entt);
296 template<
typename... Type>
297 [[nodiscard]]
decltype(
auto)
get()
const {
299 return owner_or_assert().template
get<Type...>(
entt);
309 template<
typename Type,
typename... Args>
311 static_assert(((
sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>),
"Invalid type");
320 template<
typename... Type>
323 return owner_or_assert().template
try_get<Type...>(
entt);
331 return owner_or_assert().orphan(
entt);
341 template<
typename Other,
typename... Args>
343 static_assert(std::is_same_v<Other, Registry> || std::is_same_v<std::remove_const_t<Other>, Registry>,
"Invalid conversion between different handles");
344 static_assert((
sizeof...(Scope) == 0 || ((
sizeof...(Args) != 0 &&
sizeof...(Args) <=
sizeof...(Scope)) && ... && (
type_list_contains_v<
type_list<Scope...>, Args>))),
"Invalid conversion between different handles");
362template<
typename... Args,
typename... Other>
364 return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity();
376template<
typename... Args,
typename... Other>
378 return !(lhs == rhs);
388template<
typename... Args>
390 return (lhs.entity() == rhs);
400template<
typename... Args>
412template<
typename... Args>
414 return (lhs.entity() != rhs);
424template<
typename... Args>
typename internal::entt_traits< Type >::value_type value_type
typename internal::entt_traits< Type >::version_type version_type
Non-owning handle to an entity.
void destroy()
Destroys the entity associated with a handle.
void erase() const
Erases the given elements from a handle.
decltype(auto) replace(Args &&...args) const
Replaces the given element for a handle.
decltype(auto) get() const
Returns references to the given elements for a handle.
decltype(auto) any_of() const
Checks if a handle has at least one of the given elements.
decltype(auto) all_of() const
Checks if a handle has all the given elements.
iterable storage() const noexcept
Returns an iterable object to use to visit a handle.
decltype(auto) patch(Func &&...func) const
Patches the given element for a handle.
decltype(auto) emplace(Args &&...args) const
Assigns the given element to a handle.
iterable_adaptor< internal::handle_storage_iterator< typename decltype(std::declval< registry_type >().storage())::iterator > > iterable
basic_handle() noexcept
Constructs an invalid handle.
basic_handle(registry_type &ref, entity_type value) noexcept
Constructs a handle from a given registry and entity.
void destroy(const version_type version)
Destroys the entity associated with a handle.
decltype(auto) emplace_or_replace(Args &&...args) const
Assigns or replaces the given element for a handle.
bool orphan() const
Checks if a handle has elements assigned.
auto try_get() const
Returns pointers to the given elements for a handle.
size_type remove() const
Removes the given elements from a handle.
typename traits_type::version_type version_type
decltype(auto) get_or_emplace(Args &&...args) const
Returns a reference to the given element for a handle.
bool valid() const
Checks if a handle refers to a valid registry and entity.
entity_type entity() const noexcept
Returns the entity associated with a handle.
registry_type * registry() const noexcept
Returns a pointer to the underlying registry, if any.
typename traits_type::value_type entity_type
constexpr null_t null
Compile-time constant for null entities.
constexpr bool type_list_contains_v
Helper variable template.
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
@ ref
Aliasing mode, the object points to a non-const element.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Utility class to create an iterable object from a pair of iterators.
Null object for all identifiers.
A class to use to push around lists of types, nothing more.