2#ifndef LIBSBX_ECS_DETAIL_VIEW_ITERATOR_HPP_
3#define LIBSBX_ECS_DETAIL_VIEW_ITERATOR_HPP_
5#include <libsbx/utility/assert.hpp>
6#include <libsbx/utility/type_list.hpp>
8#include <libsbx/memory/iterable_adaptor.hpp>
11#include <libsbx/ecs/entity.hpp>
13namespace sbx::ecs::detail {
15template<
typename... Type>
16static constexpr bool tombstone_check_v = ((
sizeof...(Type) == 1u) && ... && (Type::storage_policy == deletion_policy::in_place));
25template<std::forward_iterator Iterator,
typename Entity>
26[[nodiscard]]
auto all_of(Iterator first,
const Iterator last,
const Entity entity)
noexcept ->
bool {
27 for (; (first != last) && (*first)->contains(entity); ++first) { }
31template<std::forward_iterator Iterator,
typename Entity>
32[[nodiscard]]
auto none_of(Iterator first,
const Iterator last,
const Entity entity)
noexcept ->
bool {
33 for (; (first != last) && !(*first)->contains(entity); ++first) { }
43template<
typename Result,
typename View,
typename Other, std::size_t... GetLhs, std::size_t... GetRhs>
44[[nodiscard]]
auto view_pack(
const View& view,
const Other& other, std::index_sequence<GetLhs...>, std::index_sequence<GetRhs...>) -> Result{
45 auto element = Result{};
47 element.pools = {view.template storage<GetLhs>()..., other.template storage<GetRhs>()...};
57template<
typename Type,
bool IsChecked, std::
size_t Get, std::
size_t Exclude>
60 template<
typename,
typename...>
63 template<
typename LhsType,
auto... LhsArgs,
typename RhsType,
auto... RhsArgs>
66 using iterator_type =
typename Type::const_iterator;
67 using iterator_traits = std::iterator_traits<iterator_type>;
71 using common_type = Type;
72 using value_type =
typename iterator_traits::value_type;
73 using pointer =
typename iterator_traits::pointer;
74 using reference =
typename iterator_traits::reference;
75 using difference_type =
typename iterator_traits::difference_type;
76 using iterator_category = std::forward_iterator_tag;
83 view_iterator(iterator_type first, std::array<const common_type*, Get> value, std::array<const common_type*, Exclude> filter,
const std::size_t _index) noexcept
87 _index{
static_cast<difference_type
>(_index)} {
88 utility::assert_that((Get != 1u) || (Exclude != 0u) || _pools[0u]->policy() == deletion_policy::in_place,
"Non in-place storage view iterator");
99 const auto original = *
this;
104 [[nodiscard]]
auto operator->()
const noexcept -> pointer {
108 [[nodiscard]]
auto operator*()
const noexcept -> reference {
109 return *operator->();
114 [[nodiscard]]
auto _is_valid(
const value_type entity)
const noexcept ->
bool {
115 return (!IsChecked || (entity != tombstone_entity))
116 && ((Get == 1u) || (detail::all_of(_pools.begin(), _pools.begin() + _index, entity) && detail::all_of(_pools.begin() + _index + 1, _pools.end(), entity)))
117 && ((Exclude == 0u) || detail::none_of(_filter.begin(), _filter.end(), entity));
120 auto _seek_next() ->
void {
121 for (
constexpr auto sentinel = iterator_type{}; _iterator != sentinel && !_is_valid(*_iterator); ++_iterator) { }
124 iterator_type _iterator;
125 std::array<const common_type*, Get> _pools;
126 std::array<const common_type*, Exclude> _filter;
127 difference_type _index;
131template<
typename LhsType,
auto... LhsArgs,
typename RhsType,
auto... RhsArgs>
133 return lhs._iterator == rhs._iterator;
136template<
typename Iterator,
typename... Get>
139 template<
typename... Lhs,
typename... Rhs>
144 using iterator_type = Iterator;
145 using value_type =
decltype(std::tuple_cat(std::make_tuple(*std::declval<Iterator>()), std::declval<Get>().get_as_tuple(std::declval<typename Get::entity_type>())...));
147 using reference = value_type;
148 using difference_type = std::ptrdiff_t;
149 using iterator_category = std::input_iterator_tag;
150 using iterator_concept = std::forward_iterator_tag;
156 : _iterator{from} { }
159 return ++_iterator, *
this;
163 const auto original = *
this;
168 [[nodiscard]]
auto operator*()
const noexcept -> reference{
169 return _dereference(std::index_sequence_for<Get...>{});
172 [[nodiscard]]
auto operator->()
const noexcept ->
pointer {
176 [[nodiscard]]
constexpr auto base()
const noexcept -> iterator_type {
182 template<std::size_t... Index>
183 [[nodiscard]]
auto _dereference(std::index_sequence<Index...>)
const noexcept {
184 return std::tuple_cat(std::make_tuple(*_iterator),
static_cast<Get*
>(
const_cast<utility::constness_as_t<typename Get::base_type, Get>*
>(std::get<Index>(_iterator._pools)))->get_as_tuple(*_iterator)...);
191template<
typename... Lhs,
typename... Rhs>
193 return lhs._iterator == rhs._iterator;
Definition: view_iterator.hpp:137
Definition: view_iterator.hpp:58
Sparse set container for ECS entity storage.