sandbox
Loading...
Searching...
No Matches
view_iterator.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_ECS_DETAIL_VIEW_ITERATOR_HPP_
3#define LIBSBX_ECS_DETAIL_VIEW_ITERATOR_HPP_
4
5#include <libsbx/utility/assert.hpp>
6#include <libsbx/utility/type_list.hpp>
7
8#include <libsbx/memory/iterable_adaptor.hpp>
9
11#include <libsbx/ecs/entity.hpp>
12
13namespace sbx::ecs::detail {
14
15template<typename... Type>
16static constexpr bool tombstone_check_v = ((sizeof...(Type) == 1u) && ... && (Type::storage_policy == deletion_policy::in_place));
17
18// template<typename Type>
19// requires (std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>)
20// auto view_placeholder() -> const Type* {
21// static const auto placeholder = Type{};
22// return &placeholder;
23// }
24
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) { }
28 return first == last;
29}
30
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) { }
34 return first == last;
35}
36
37// template<typename Iterator>
38// [[nodiscard]] auto is_fully_initialized(Iterator first, const Iterator last, const std::remove_pointer_t<typename std::iterator_traits<Iterator>::value_type>* placeholder) noexcept -> bool {
39// for (; (first != last) && *first != placeholder; ++first) { }
40// return first == last;
41// }
42
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{};
46
47 element.pools = {view.template storage<GetLhs>()..., other.template storage<GetRhs>()...};
48
49 // auto filter_or_placeholder = [placeholder = element.placeholder](auto* value) { return (value == nullptr) ? placeholder : value; };
50
51 // element.filter = {filter_or_placeholder(view.template storage<sizeof...(GLhs)>())..., filter_or_placeholder(other.template storage<sizeof...(GRhs)>())...};
52 element.refresh();
53
54 return element;
55}
56
57template<typename Type, bool IsChecked, std::size_t Get, std::size_t Exclude>
58class view_iterator final {
59
60 template<typename, typename...>
61 friend class extended_view_iterator;
62
63 template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
64 friend constexpr bool operator==(const view_iterator<LhsType, LhsArgs...>&, const view_iterator<RhsType, RhsArgs...>&) noexcept;
65
66 using iterator_type = typename Type::const_iterator;
67 using iterator_traits = std::iterator_traits<iterator_type>;
68
69public:
70
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;
77
78 constexpr view_iterator() noexcept
79 : _iterator{},
80 _pools{},
81 _index{} { }
82
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
84 : _iterator{first},
85 _pools{value},
86 _filter{filter},
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");
89 _seek_next();
90 }
91
92 auto operator++() noexcept -> view_iterator& {
93 ++_iterator;
94 _seek_next();
95 return *this;
96 }
97
98 auto operator++(int) noexcept -> view_iterator {
99 const auto original = *this;
100 ++(*this);
101 return original;
102 }
103
104 [[nodiscard]] auto operator->() const noexcept -> pointer {
105 return &*_iterator;
106 }
107
108 [[nodiscard]] auto operator*() const noexcept -> reference {
109 return *operator->();
110 }
111
112private:
113
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));
118 }
119
120 auto _seek_next() -> void {
121 for (constexpr auto sentinel = iterator_type{}; _iterator != sentinel && !_is_valid(*_iterator); ++_iterator) { }
122 }
123
124 iterator_type _iterator;
125 std::array<const common_type*, Get> _pools;
126 std::array<const common_type*, Exclude> _filter;
127 difference_type _index;
128
129}; // class view_iterator
130
131template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
132[[nodiscard]] constexpr auto operator==(const view_iterator<LhsType, LhsArgs...>& lhs, const view_iterator<RhsType, RhsArgs...>& rhs) noexcept -> bool {
133 return lhs._iterator == rhs._iterator;
134}
135
136template<typename Iterator, typename... Get>
138
139 template<typename... Lhs, typename... Rhs>
140 friend auto constexpr operator==(const extended_view_iterator<Lhs...>&, const extended_view_iterator<Rhs...>&) noexcept -> bool;
141
142public:
143
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;
151
152 constexpr extended_view_iterator()
153 : _iterator{} { }
154
155 extended_view_iterator(iterator_type from)
156 : _iterator{from} { }
157
158 auto operator++() noexcept -> extended_view_iterator& {
159 return ++_iterator, *this;
160 }
161
162 auto operator++(int) noexcept -> extended_view_iterator {
163 const auto original = *this;
164 ++(*this);
165 return original;
166 }
167
168 [[nodiscard]] auto operator*() const noexcept -> reference{
169 return _dereference(std::index_sequence_for<Get...>{});
170 }
171
172 [[nodiscard]] auto operator->() const noexcept -> pointer {
173 return operator*();
174 }
175
176 [[nodiscard]] constexpr auto base() const noexcept -> iterator_type {
177 return _iterator;
178 }
179
180private:
181
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)...);
185 }
186
187 Iterator _iterator;
188
189}; // class extended_view_iterator
190
191template<typename... Lhs, typename... Rhs>
192[[nodiscard]] constexpr auto operator==(const extended_view_iterator<Lhs...>& lhs, const extended_view_iterator<Rhs...>& rhs) noexcept -> bool {
193 return lhs._iterator == rhs._iterator;
194}
195
196} // namespace sbx::ecs::detail
197
198#endif // LIBSBX_ECS_DETAIL_VIEW_ITERATOR_HPP_
Definition: view_iterator.hpp:137
Definition: view_iterator.hpp:58
Definition: iterable_adaptor.hpp:51
Sparse set container for ECS entity storage.