1#ifndef ENTT_ENTITY_VIEW_HPP
2#define ENTT_ENTITY_VIEW_HPP
10#include "../config/config.h"
11#include "../core/iterator.hpp"
12#include "../core/type_traits.hpp"
21template<
typename... Type>
23static constexpr bool tombstone_check_v = ((
sizeof...(Type) == 1u) && ... && (Type::storage_policy == deletion_policy::in_place));
25template<
typename Type>
26const Type *view_placeholder() {
27 static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>,
"Unexpected type");
28 static const Type placeholder{};
32template<
typename It,
typename Entity>
33[[nodiscard]]
bool all_of(It first,
const It last,
const Entity entt)
noexcept {
34 for(; (first != last) && (*first)->contains(entt); ++first) {}
38template<
typename It,
typename Entity>
39[[nodiscard]]
bool none_of(It first,
const It last,
const Entity entt)
noexcept {
40 for(; (first != last) && !(*first)->contains(entt); ++first) {}
45[[nodiscard]]
bool fully_initialized(It first,
const It last,
const std::remove_pointer_t<
typename std::iterator_traits<It>::value_type> *placeholder)
noexcept {
46 for(; (first != last) && *first != placeholder; ++first) {}
50template<
typename Result,
typename View,
typename Other, std::size_t... GLhs, std::size_t... ELhs, std::size_t... GRhs, std::size_t... ERhs>
51[[nodiscard]] Result view_pack(
const View &view,
const Other &other, std::index_sequence<GLhs...>, std::index_sequence<ELhs...>, std::index_sequence<GRhs...>, std::index_sequence<ERhs...>) {
54 elem.pools = {
view.template storage<GLhs>()..., other.template storage<GRhs>()...};
55 auto filter_or_placeholder = [placeholder = elem.placeholder](
auto *value) {
return (value ==
nullptr) ? placeholder : value; };
56 elem.filter = {filter_or_placeholder(
view.template storage<
sizeof...(GLhs) + ELhs>())..., filter_or_placeholder(other.template storage<
sizeof...(GRhs) + ERhs>())...};
61template<
typename Type,
bool Checked, std::
size_t Get, std::
size_t Exclude>
62class view_iterator final {
63 template<
typename,
typename...>
64 friend class extended_view_iterator;
66 using iterator_type =
typename Type::const_iterator;
67 using iterator_traits = std::iterator_traits<iterator_type>;
69 [[nodiscard]]
bool valid(
const typename iterator_traits::value_type entt)
const noexcept {
70 return (!Checked || (entt != tombstone))
71 && ((Get == 1u) || (internal::all_of(pools.begin(), pools.begin() + index, entt) && internal::all_of(pools.begin() + index + 1, pools.end(), entt)))
72 && ((Exclude == 0u) || internal::none_of(filter.begin(), filter.end(), entt));
76 for(
constexpr iterator_type sentinel{}; it != sentinel && !valid(*it); ++it) {}
80 using value_type =
typename iterator_traits::value_type;
81 using pointer =
typename iterator_traits::pointer;
82 using reference =
typename iterator_traits::reference;
83 using difference_type =
typename iterator_traits::difference_type;
84 using iterator_category = std::forward_iterator_tag;
86 constexpr view_iterator() noexcept
92 view_iterator(iterator_type first, std::array<const Type *, Get> value, std::array<const Type *, Exclude> excl,
const std::size_t idx) noexcept
96 index{
static_cast<difference_type
>(idx)} {
97 ENTT_ASSERT((Get != 1u) || (Exclude != 0u) || pools[0u]->policy() == deletion_policy::in_place,
"Non in-place storage view iterator");
101 view_iterator &operator++() noexcept {
107 view_iterator operator++(
int)
noexcept {
108 const view_iterator orig = *
this;
109 return ++(*this), orig;
112 [[nodiscard]] pointer operator->() const noexcept {
116 [[nodiscard]] reference operator*() const noexcept {
117 return *operator->();
120 template<
typename LhsType,
auto... LhsArgs,
typename RhsType,
auto... RhsArgs>
121 friend constexpr bool operator==(
const view_iterator<LhsType, LhsArgs...> &,
const view_iterator<RhsType, RhsArgs...> &)
noexcept;
125 std::array<const Type *, Get> pools;
126 std::array<const Type *, Exclude> filter;
127 difference_type index;
130template<
typename LhsType,
auto... LhsArgs,
typename RhsType,
auto... RhsArgs>
131[[nodiscard]]
constexpr bool operator==(
const view_iterator<LhsType, LhsArgs...> &lhs,
const view_iterator<RhsType, RhsArgs...> &rhs)
noexcept {
132 return lhs.it == rhs.it;
135template<
typename LhsType,
auto... LhsArgs,
typename RhsType,
auto... RhsArgs>
136[[nodiscard]]
constexpr bool operator!=(
const view_iterator<LhsType, LhsArgs...> &lhs,
const view_iterator<RhsType, RhsArgs...> &rhs)
noexcept {
137 return !(lhs == rhs);
140template<
typename It,
typename... Get>
141class extended_view_iterator final {
142 template<std::size_t... Index>
143 [[nodiscard]]
auto dereference(std::index_sequence<Index...>)
const noexcept {
144 return std::tuple_cat(std::make_tuple(*it),
static_cast<Get *
>(
const_cast<constness_as_t<typename Get::base_type, Get> *
>(std::get<Index>(it.pools)))->get_as_tuple(*it)...);
148 using iterator_type = It;
149 using value_type =
decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::declval<Get>().get_as_tuple({})...));
150 using pointer = input_iterator_pointer<value_type>;
151 using reference = value_type;
152 using difference_type = std::ptrdiff_t;
153 using iterator_category = std::input_iterator_tag;
154 using iterator_concept = std::forward_iterator_tag;
156 constexpr extended_view_iterator()
159 extended_view_iterator(iterator_type from)
162 extended_view_iterator &operator++() noexcept {
166 extended_view_iterator operator++(
int)
noexcept {
167 const extended_view_iterator orig = *
this;
168 return ++(*this), orig;
171 [[nodiscard]] reference operator*() const noexcept {
172 return dereference(std::index_sequence_for<Get...>{});
175 [[nodiscard]] pointer operator->() const noexcept {
179 [[nodiscard]]
constexpr iterator_type base() const noexcept {
183 template<
typename... Lhs,
typename... Rhs>
184 friend bool constexpr operator==(
const extended_view_iterator<Lhs...> &,
const extended_view_iterator<Rhs...> &)
noexcept;
190template<
typename... Lhs,
typename... Rhs>
191[[nodiscard]]
constexpr bool operator==(
const extended_view_iterator<Lhs...> &lhs,
const extended_view_iterator<Rhs...> &rhs)
noexcept {
192 return lhs.it == rhs.it;
195template<
typename... Lhs,
typename... Rhs>
196[[nodiscard]]
constexpr bool operator!=(
const extended_view_iterator<Lhs...> &lhs,
const extended_view_iterator<Rhs...> &rhs)
noexcept {
197 return !(lhs == rhs);
221template<
typename,
typename,
typename>
232template<
typename Type,
bool Checked, std::
size_t Get, std::
size_t Exclude>
234 static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>,
"Unexpected type");
236 template<
typename Return,
typename View,
typename Other, std::size_t... GLhs, std::size_t... ELhs, std::size_t... GRhs, std::size_t... ERhs>
237 friend Return internal::view_pack(
const View &,
const Other &, std::index_sequence<GLhs...>, std::index_sequence<ELhs...>, std::index_sequence<GRhs...>, std::index_sequence<ERhs...>);
239 [[nodiscard]]
auto offset()
const noexcept {
240 ENTT_ASSERT(index != Get,
"Invalid view");
244 void unchecked_refresh()
noexcept {
247 if constexpr(Get > 1u) {
248 for(
size_type pos{1u}; pos < Get; ++pos) {
249 if(pools[pos]->size() < pools[index]->size()) {
259 for(
size_type pos{}, last = filter.size(); pos < last; ++pos) {
260 filter[pos] = placeholder;
264 basic_common_view(std::array<const Type *, Get> value, std::array<const Type *, Exclude> excl) noexcept
271 [[nodiscard]]
const Type *pool_at(
const std::size_t pos)
const noexcept {
275 void pool_at(
const std::size_t pos,
const Type *elem)
noexcept {
276 ENTT_ASSERT(elem !=
nullptr,
"Unexpected element");
281 [[nodiscard]]
const Type *filter_at(
const std::size_t pos)
const noexcept {
282 return (filter[pos] == placeholder) ? nullptr : filter[pos];
285 void filter_at(
const std::size_t pos,
const Type *elem)
noexcept {
286 ENTT_ASSERT(elem !=
nullptr,
"Unexpected element");
290 [[nodiscard]]
bool none_of(
const typename Type::entity_type
entt)
const noexcept {
291 return internal::none_of(filter.begin(), filter.end(),
entt);
294 void use(
const std::size_t pos)
noexcept {
295 index = (index != Get) ? pos : Get;
309 using iterator = internal::view_iterator<common_type, Checked, Get, Exclude>;
314 for(; pos < Get && pools[pos] !=
nullptr; ++pos) {}
326 return (index != Get) ? pools[index] :
nullptr;
334 return (index != Get) ? offset() :
size_type{};
353 return (index != Get) ?
iterator{pools[index]->end(), pools, filter, index} :
iterator{};
362 const auto it =
begin();
363 return it !=
end() ? *it :
null;
373 auto it = pools[index]->rbegin();
375 for(
const auto idx =
static_cast<difference_type>(index); it != last && !(internal::all_of(pools.begin(), pools.begin() + idx, *it) && internal::all_of(pools.begin() + idx + 1, pools.end(), *it) && internal::none_of(filter.begin(), filter.end(), *it)); ++it) {}
376 return it == last ?
null : *it;
396 [[nodiscard]]
explicit operator bool() const noexcept {
397 return (index != Get) && internal::fully_initialized(filter.begin(), filter.end(), placeholder);
406 return (index != Get)
407 && internal::all_of(pools.begin(), pools.end(),
entt)
408 && internal::none_of(filter.begin(), filter.end(),
entt)
409 && pools[index]->index(
entt) < offset();
413 std::array<const common_type *, Get> pools{};
414 std::array<const common_type *, Exclude> filter{};
415 const common_type *placeholder{internal::view_placeholder<common_type>()};
431template<
typename... Get,
typename... Exclude>
433 :
public basic_common_view<std::common_type_t<typename Get::base_type...>, internal::tombstone_check_v<Get...>, sizeof...(Get), sizeof...(Exclude)> {
434 using base_type =
basic_common_view<std::common_type_t<
typename Get::base_type...>, internal::tombstone_check_v<Get...>,
sizeof...(Get),
sizeof...(Exclude)>;
436 template<std::
size_t Index>
439 template<
typename Type>
442 template<std::size_t... Index>
447 template<std::size_t Curr, std::size_t Other,
typename... Args>
448 [[nodiscard]]
auto dispatch_get(
const std::tuple<typename base_type::entity_type, Args...> &curr)
const {
449 if constexpr(Curr == Other) {
450 return std::forward_as_tuple(std::get<Args>(curr)...);
456 template<std::size_t Curr,
typename Func, std::size_t... Index>
457 void each(Func &func, std::index_sequence<Index...>)
const {
459 if(
const auto entt = std::get<0>(curr); (!internal::tombstone_check_v<Get...> || (
entt !=
tombstone)) && ((Curr == Index || base_type::pool_at(Index)->contains(
entt)) && ...) && base_type::none_of(
entt)) {
460 if constexpr(
is_applicable_v<Func,
decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_view>().get({})))>) {
461 std::apply(func, std::tuple_cat(std::make_tuple(
entt), dispatch_get<Curr, Index>(curr)...));
463 std::apply(func, std::tuple_cat(dispatch_get<Curr, Index>(curr)...));
469 template<
typename Func, std::size_t... Index>
470 void pick_and_each(Func &func, std::index_sequence<Index...> seq)
const {
472 ((
view == base_type::pool_at(Index) ? each<Index>(func, seq) : void()), ...);
500 : base_type{{&value...}, {&excl...}} {
508 basic_view(std::tuple<Get &...> value, std::tuple<Exclude &...> excl = {})
noexcept
515 template<
typename Type>
524 template<std::
size_t Index>
526 base_type::use(Index);
534 template<
typename Type>
535 [[nodiscard]]
auto *
storage() const noexcept {
544 template<std::
size_t Index>
545 [[nodiscard]]
auto *
storage() const noexcept {
546 if constexpr(Index <
sizeof...(Get)) {
558 template<
typename Type>
569 template<std::
size_t Index,
typename Type>
571 static_assert(std::is_convertible_v<Type &, element_at<Index> &>,
"Unexpected type");
573 if constexpr(Index <
sizeof...(Get)) {
574 base_type::pool_at(Index, &elem);
576 base_type::filter_at(Index -
sizeof...(Get), &elem);
596 template<
typename Type,
typename... Other>
598 return get<index_of<Type>, index_of<Other>...>(
entt);
607 template<std::size_t... Index>
609 if constexpr(
sizeof...(Index) == 0) {
610 return get(
entt, std::index_sequence_for<Get...>{});
611 }
else if constexpr(
sizeof...(Index) == 1) {
633 template<
typename Func>
635 pick_and_each(func, std::index_sequence_for<Get...>{});
657 template<
typename OGet>
669 template<
typename... OGet,
typename... OExclude>
672 *
this, other, std::index_sequence_for<Get...>{}, std::index_sequence_for<Exclude...>{}, std::index_sequence_for<OGet...>{}, std::index_sequence_for<OExclude...>{});
682template<
typename Type, deletion_policy Policy>
684 static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>,
"Unexpected type");
692 ENTT_ASSERT(leading->policy() == Policy,
"Unexpected storage policy");
706 using iterator = std::conditional_t<Policy == deletion_policy::in_place, internal::view_iterator<common_type, true, 1u, 0u>,
typename common_type::iterator>;
708 using reverse_iterator = std::conditional_t<Policy == deletion_policy::in_place, void, typename common_type::reverse_iterator>;
724 [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, size_type>
size() const noexcept {
726 return leading ? leading->size() :
size_type{};
729 return leading ? leading->free_list() :
size_type{};
739 [[nodiscard]] std::enable_if_t<Pol == deletion_policy::in_place, size_type>
size_hint() const noexcept {
740 return leading ? leading->size() :
size_type{};
749 [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, bool>
empty() const noexcept {
751 return !leading || leading->empty();
754 return !leading || (leading->free_list() == 0u);
767 return leading ? leading->begin() :
iterator{};
772 return leading ?
iterator{leading->begin(), {leading}, {}, 0u} :
iterator{};
782 return leading ? leading->end() :
iterator{};
798 [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, reverse_iterator>
rbegin() const noexcept {
810 [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, reverse_iterator>
rend() const noexcept {
826 return empty() ?
null : *leading->begin();
831 const auto it =
begin();
832 return (it ==
end()) ?
null : *it;
843 return empty() ?
null : *leading->rbegin();
848 auto it = leading->rbegin();
849 const auto last = leading->rend();
850 for(; (it != last) && (*it ==
tombstone); ++it) {}
851 return it == last ?
null : *it;
868 const auto it = leading ? leading->find(
entt) :
iterator{};
869 return leading && (
static_cast<size_type>(it.index()) < leading->free_list()) ? it :
iterator{};
879 [[nodiscard]]
explicit operator bool() const noexcept {
880 return (leading !=
nullptr);
890 return leading && leading->contains(
entt);
893 return leading && leading->contains(
entt) && (leading->index(
entt) < leading->free_list());
911template<
typename Get>
930 using iterable = std::conditional_t<Get::storage_policy == deletion_policy::in_place, iterable_adaptor<internal::extended_view_iterator<iterator, Get>>,
decltype(std::declval<Get>().each())>;
941 : base_type{&value} {
948 basic_view(std::tuple<Get &> value, std::tuple<> = {})
noexcept
956 template<
typename Type =
typename Get::element_type>
957 [[nodiscard]]
auto *
storage() const noexcept {
958 static_assert(std::is_same_v<std::remove_const_t<Type>,
typename Get::element_type>,
"Invalid element type");
967 template<std::
size_t Index>
968 [[nodiscard]]
auto *
storage() const noexcept {
969 static_assert(Index == 0u,
"Index out of bounds");
986 template<std::
size_t Index>
988 static_assert(Index == 0u,
"Index out of bounds");
1015 template<
typename Elem>
1017 static_assert(std::is_same_v<std::remove_const_t<Elem>,
typename Get::element_type>,
"Invalid element type");
1027 template<std::size_t... Index>
1029 if constexpr(
sizeof...(Index) == 0) {
1051 template<
typename Func>
1053 if constexpr(
is_applicable_v<Func,
decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_view>().get({})))>) {
1054 for(
const auto pack:
each()) {
1055 std::apply(func, pack);
1058 if constexpr(std::is_void_v<typename Get::value_type>) {
1064 for(
auto last =
storage()->
end(), first = last - len; first != last; ++first) {
1072 for(
const auto pack:
each()) {
1073 std::apply([&func](
const auto,
auto &&...elem) { func(std::forward<
decltype(elem)>(elem)...); }, pack);
1102 template<
typename OGet>
1114 template<
typename... OGet,
typename... OExclude>
1117 *
this, other, std::index_sequence_for<Get>{}, std::index_sequence_for<>{}, std::index_sequence_for<OGet...>{}, std::index_sequence_for<OExclude...>{});
1126template<
typename... Type>
1134template<
typename... Get,
typename... Exclude>
1135basic_view(std::tuple<Get &...>, std::tuple<Exclude &...> = {}) ->
basic_view<get_t<Get...>, exclude_t<Exclude...>>;
Basic storage view implementation.
iterator begin() const noexcept
Returns an iterator to the first entity of the view.
iterator find(const entity_type entt) const noexcept
Finds an entity.
typename Type::entity_type entity_type
Underlying entity identifier.
const common_type * handle() const noexcept
Returns the leading storage of a view, if any.
size_type size_hint() const noexcept
Estimates the number of entities iterated by the view.
bool contains(const entity_type entt) const noexcept
Checks if a view contains an entity.
entity_type back() const noexcept
Returns the last entity of the view, if any.
void refresh() noexcept
Updates the internal leading view if required.
std::ptrdiff_t difference_type
Signed integer type.
entity_type front() const noexcept
Returns the first entity of the view, if any.
internal::view_iterator< common_type, Checked, Get, Exclude > iterator
Forward iterator type.
iterator end() const noexcept
Returns an iterator that is past the last entity of the view.
Type common_type
Common type among all storage types.
std::size_t size_type
Unsigned integer type.
Basic storage view implementation.
entity_type front() const noexcept
Returns the first entity of the view, if any.
std::enable_if_t< Pol !=deletion_policy::in_place, bool > empty() const noexcept
Checks whether a view is empty.
std::conditional_t< Policy==deletion_policy::in_place, void, typename common_type::reverse_iterator > reverse_iterator
Reverse iterator type.
std::ptrdiff_t difference_type
Signed integer type.
entity_type back() const noexcept
Returns the last entity of the view, if any.
bool contains(const entity_type entt) const noexcept
Checks if a view contains an entity.
std::enable_if_t< Pol !=deletion_policy::in_place, reverse_iterator > rend() const noexcept
Returns an iterator that is past the last entity of the reversed view.
iterator end() const noexcept
Returns an iterator that is past the last entity of the view.
std::enable_if_t< Pol==deletion_policy::in_place, size_type > size_hint() const noexcept
Estimates the number of entities iterated by the view.
std::conditional_t< Policy==deletion_policy::in_place, internal::view_iterator< common_type, true, 1u, 0u >, typename common_type::iterator > iterator
Random access iterator type.
std::enable_if_t< Pol !=deletion_policy::in_place, reverse_iterator > rbegin() const noexcept
Returns an iterator to the first entity of the reversed view.
std::enable_if_t< Pol !=deletion_policy::in_place, size_type > size() const noexcept
Returns the number of entities that have the given element.
std::size_t size_type
Unsigned integer type.
typename common_type::entity_type entity_type
Underlying entity identifier.
iterator begin() const noexcept
Returns an iterator to the first entity of the view.
const common_type * handle() const noexcept
Returns the leading storage of a view, if any.
Type common_type
Common type among all storage types.
iterator find(const entity_type entt) const noexcept
Finds an entity.
const value_type & get(const entity_type entt) const noexcept
Returns the object assigned to an entity.
iterable each() noexcept
Returns an iterable object to use to visit a storage.
std::tuple< const value_type & > get_as_tuple(const entity_type entt) const noexcept
Returns the object assigned to an entity as a tuple.
basic_view(std::tuple< Get & > value, std::tuple<>={}) noexcept
Constructs a view from a storage class.
typename base_type::entity_type entity_type
Underlying entity identifier.
auto operator|(const basic_view< get_t< OGet... >, exclude_t< OExclude... > > &other) const noexcept
Combines two views in a more specific one.
basic_view(Get &value) noexcept
Constructs a view from a storage class.
std::ptrdiff_t difference_type
Signed integer type.
void storage(Get &elem) noexcept
Assigns a storage to a view.
Get * operator->() const noexcept
Returns a pointer to the underlying storage.
typename base_type::common_type common_type
Common type among all storage types.
typename base_type::reverse_iterator reverse_iterator
Reverse iterator type.
typename base_type::iterator iterator
Random access iterator type.
auto * storage() const noexcept
Returns the storage for a given element type, if any.
basic_view() noexcept
Default constructor to use to create empty, invalid views.
std::enable_if_t< std::is_base_of_v< common_type, OGet >, basic_view< get_t< Get, OGet >, exclude_t<> > > operator|(OGet &other) const noexcept
Combines a view and a storage in more specific view.
void each(Func func) const
Iterates entities and elements and applies the given function object to them.
iterable each() const noexcept
Returns an iterable object to use to visit a view.
void storage(Get &elem) noexcept
Assigns a storage to a view.
typename base_type::size_type size_type
Unsigned integer type.
std::conditional_t< Get::storage_policy==deletion_policy::in_place, iterable_adaptor< internal::extended_view_iterator< iterator, Get > >, decltype(std::declval< Get >().each())> iterable
Iterable view type.
decltype(auto) get(const entity_type entt) const
Returns the element assigned to the given entity.
typename base_type::entity_type entity_type
Underlying entity identifier.
typename base_type::common_type common_type
Common type among all storage types.
basic_view() noexcept
Default constructor to use to create empty, invalid views.
void each(Func func) const
Iterates entities and elements and applies the given function object to them.
decltype(auto) get(const entity_type entt) const
Returns the elements assigned to the given entity.
void storage(Type &elem) noexcept
Assigns a storage to a view.
void storage(Type &elem) noexcept
Assigns a storage to a view.
std::enable_if_t< std::is_base_of_v< common_type, OGet >, basic_view< get_t< Get..., OGet >, exclude_t< Exclude... > > > operator|(OGet &other) const noexcept
Combines a view and a storage in more specific view.
auto operator|(const basic_view< get_t< OGet... >, exclude_t< OExclude... > > &other) const noexcept
Combines two views in a more specific one.
typename base_type::iterator iterator
Forward iterator type.
std::ptrdiff_t difference_type
Signed integer type.
iterable each() const noexcept
Returns an iterable object to use to visit a view.
decltype(auto) get(const entity_type entt) const
Returns the elements assigned to the given entity.
iterable_adaptor< internal::extended_view_iterator< iterator, Get... > > iterable
Iterable view type.
void use() noexcept
Forces a view to use a given element to drive iterations.
basic_view(std::tuple< Get &... > value, std::tuple< Exclude &... > excl={}) noexcept
Constructs a view from a set of storage classes.
basic_view(Get &...value, Exclude &...excl) noexcept
Constructs a view from a set of storage classes.
auto * storage() const noexcept
Returns the storage for a given element type, if any.
typename base_type::size_type size_type
Unsigned integer type.
basic_view(Type &...storage) -> basic_view< get_t< Type... >, exclude_t<> >
Deduction guide.
typename constness_as< To, From >::type constness_as_t
Alias template to facilitate the transcription of the constness.
constexpr null_t null
Compile-time constant for null entities.
constexpr std::size_t type_list_index_v
Helper variable template.
basic_view< type_list_transform_t< Get, storage_for >, type_list_transform_t< Exclude, storage_for > > view
Alias declaration for the most common use case.
constexpr bool is_applicable_v
Helper variable template.
constexpr tombstone_t tombstone
Compile-time constant for tombstone entities.
constexpr get_t< Type... > get
Variable template for lists of observed elements.
typename type_list_element< Index, List >::type type_list_element_t
Helper type.
deletion_policy
Storage deletion policy.
@ swap_only
Swap-only deletion policy.
@ swap_and_pop
Swap-and-pop deletion policy.
@ in_place
In-place deletion policy.
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
basic_storage< Type > storage
Alias declaration for the most common use case.
Alias for exclusion lists.
Alias for lists of observed elements.
Utility class to create an iterable object from a pair of iterators.
A class to use to push around lists of types, nothing more.