17template<concepts::View View>
20template<concepts::View View>
28 class InnerIterator :
public IteratorBase<InnerIterator, InputIteratorTag, meta::ContainerValue<View>, SSizeType> {
32 constexpr explicit InnerIterator(
ChunkView& parent) : m_parent(util::addressof(parent)) {}
35 InnerIterator(InnerIterator&&) =
default;
36 auto operator=(InnerIterator&&) -> InnerIterator& =
default;
38 constexpr auto base()
const& -> Iter
const& {
return *m_parent->m_current; }
40 constexpr auto operator*()
const ->
decltype(
auto) {
return **m_parent->m_current; }
42 constexpr void advance_one() {
43 ++*m_parent->m_current;
45 m_parent->m_remainder = 0;
47 --m_parent->m_remainder;
52 constexpr auto at_end()
const ->
bool {
return m_parent->m_remainder == 0; }
54 constexpr auto distance()
const -> SSizeType {
78 constexpr explicit ValueType(
ChunkView& parent) : m_parent(util::addressof(parent)) {}
81 constexpr auto begin()
const {
return InnerIterator(*m_parent); }
85 constexpr auto size()
const
95 class OuterIterator :
public IteratorBase<OuterIterator, InputIteratorTag, ValueType, SSizeType> {
99 constexpr explicit OuterIterator(
ChunkView& parent) : m_parent(util::addressof(parent)) {}
102 OuterIterator(OuterIterator&&) =
default;
103 auto operator=(OuterIterator&&) -> OuterIterator& =
default;
105 constexpr auto operator*()
const -> ValueType {
return ValueType(*m_parent); }
107 constexpr void advance_one() {
109 m_parent->m_remainder = m_parent->m_chunk_size;
113 constexpr auto at_end()
const ->
bool {
114 return *m_parent->m_current ==
container::end(m_parent->m_base) && m_parent->m_remainder != 0;
117 constexpr auto distance()
const -> SSizeType {
120 if (distance < m_parent->m_remainder) {
157 constexpr auto base() && ->
View {
return util::move(m_base); }
163 m_remainder = m_chunk_size;
164 return OuterIterator(*
this);
183 SSizeType m_chunk_size { 0 };
184 SSizeType m_remainder { 0 };
185 util::NonPropagatingCache<Iter> m_current;
188template<concepts::View View>
189requires(concepts::ForwardContainer<View>)
194 template<
bool is_const>
197 template<
bool is_const>
200 template<
bool is_const>
203 template<
bool is_const>
206 template<
bool is_const>
212 template<
bool is_const>
215 meta::Conditional<concepts::RandomAccessIterator<Iter<is_const>>, RandomAccessIteratorTag,
216 meta::Conditional<concepts::BidirectionalIterator<Iter<is_const>>,
217 BidirectionalIteratorTag, ForwardIteratorTag>>,
218 ValueType<is_const>, SSizeType<is_const>> {
222 constexpr Iterator(meta::MaybeConst<is_const, ChunkView>* parent, Iter<is_const> base,
223 SSizeType<is_const> missing = 0)
224 : m_base(util::
move(base))
225 , m_end(container::
end(parent->m_base))
226 , m_chunk_size(parent->chunk_size())
227 , m_missing(missing) {}
230 Iterator() =
default;
232 constexpr Iterator(Iterator<!is_const> other)
233 requires(is_const && concepts::ConvertibleTo<Iter<false>, Iter<true>> &&
234 concepts::ConvertibleTo<Sent<false>, Sent<true>>)
235 : m_base(util::
move(other.m_base))
236 , m_end(util::
move(other.m_end))
237 , m_chunk_size(other.m_chunk_size)
238 , m_missing(other.m_missing) {}
240 constexpr auto base() -> Iter<is_const> {
return m_base; }
242 constexpr auto operator*() const -> decltype(auto) {
243 return view::take(
reconstruct(in_place_type<Base<is_const>>, m_base, m_end), m_chunk_size);
246 constexpr void advance_one() { m_missing = container::advance(m_base, m_chunk_size, m_end); }
248 constexpr void back_one()
249 requires(concepts::BidirectionalIterator<Iter<is_const>>)
251 container::advance(m_base, m_missing - m_chunk_size);
255 constexpr void advance_n(SSizeType<is_const> n)
256 requires(concepts::RandomAccessIterator<Iter<is_const>>)
259 m_missing = container::advance(m_base, m_chunk_size * n, m_end);
261 container::advance(m_base, m_chunk_size * n + m_missing);
268 friend class Iterator;
270 constexpr friend auto operator==(Iterator
const& self, DefaultSentinel) ->
bool {
271 return self.m_base == self.m_end;
273 constexpr friend auto operator==(Iterator
const& a, Iterator
const& b) ->
bool {
return a.m_base == b.m_base; }
275 constexpr friend auto operator<=>(Iterator
const& a, Iterator
const& b)
276 requires(concepts::RandomAccessIterator<Iter<is_const>>)
278 return a.m_base <=> b.m_base;
281 constexpr friend auto operator-(Iterator
const& a, Iterator
const& b) -> SSizeType<is_const>
282 requires(concepts::SizedSentinelFor<Iter<is_const>, Iter<is_const>>)
284 auto n = a.m_base - b.m_base;
285 return (n + a.m_missing - b.m_missing) / a.m_chunk_size;
288 constexpr friend auto operator-(DefaultSentinel, Iterator
const& b) -> SSizeType<is_const> {
289 return math::divide_round_up(b.m_base - b.m_current, b.m_chunk_size);
291 constexpr friend auto operator-(Iterator
const& a, DefaultSentinel) -> SSizeType<is_const> {
295 Iter<is_const> m_base {};
296 Sent<is_const> m_end {};
297 SSizeType<is_const> m_chunk_size { 0 };
298 SSizeType<is_const> m_missing { 0 };
316 constexpr auto base() && ->
View {
return util::move(m_base); }
345 constexpr auto end() const
372 SSizeType<false> m_chunk_size;
375template<
typename Con>
#define DI_ASSERT(...)
Definition assert_bool.h:7
constexpr auto begin()
Definition chunk_view.h:161
constexpr auto base() const &-> View requires(concepts::CopyConstructible< View >)
Definition chunk_view.h:152
constexpr ChunkView(View base, SSizeType< false > chunk_size)
Definition chunk_view.h:306
constexpr auto begin() const
Definition chunk_view.h:326
constexpr auto size()
Definition chunk_view.h:169
constexpr auto begin()
Definition chunk_view.h:320
constexpr ChunkView(View base, SSizeType chunk_size)
Definition chunk_view.h:148
constexpr auto end() const
Definition chunk_view.h:345
constexpr auto size() const
Definition chunk_view.h:175
constexpr auto base() &&-> View
Definition chunk_view.h:157
constexpr auto chunk_size() const
Definition chunk_view.h:159
constexpr auto end()
Definition chunk_view.h:332
constexpr auto end() const
Definition chunk_view.h:167
Definition chunk_view.h:18
Definition view_interface.h:26
Definition bidirectional_container.h:8
Definition common_container.h:10
Definition operations.h:27
Definition forward_container.h:8
Definition simple_view.h:11
Definition sized_container.h:8
Definition sized_sentinel_for.h:9
constexpr auto operator-(Duration< Rep1, Period1 > const &a, Duration< Rep2, Period2 > const &b)
Definition duration.h:65
constexpr auto operator==(Duration< Rep1, Period1 > const &a, Duration< Rep2, Period2 > const &b) -> bool
Definition duration.h:108
constexpr auto operator<=>(Duration< Rep1, Period1 > const &a, Duration< Rep2, Period2 > const &b)
Definition duration.h:115
constexpr auto operator*(Duration< Rep, Period > const &a, Value const &b)
Definition duration.h:71
Definition any_storable.h:9
constexpr auto take
Definition take.h:35
constexpr auto min
Definition min.h:49
constexpr auto operator-(MoveIterator< Iter > const &a, MoveIterator< U > const &b) -> decltype(a.base() - b.base())
Definition move_iterator.h:95
constexpr auto reconstruct
Definition reconstruct.h:75
ChunkView(Con &&, meta::ContainerSSizeType< Con >) -> ChunkView< meta::AsView< Con > >
constexpr auto move
Definition move.h:38
constexpr auto operator==(MoveIterator< Iter > const &a, MoveIterator< U > const &b) -> bool
Definition move_iterator.h:85
constexpr auto distance
Definition distance.h:44
constexpr auto default_sentinel
Definition default_sentinel.h:6
constexpr auto end
Definition end.h:55
constexpr auto advance
Definition advance.h:62
constexpr auto begin
Definition begin.h:52
constexpr auto to_unsigned
Definition to_unsigned.h:16
constexpr auto divide_round_up
Definition divide_round_up.h:17
auto declval() -> meta::AddRValueReference< T >
Definition declval.h:8
constexpr auto in_place_type
Definition in_place_type.h:12
Definition default_sentinel.h:4
Definition enable_borrowed_container.h:9
Definition iterator_base.h:14