Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-iterator.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
45#ifndef AH_ITERATOR_H
46#define AH_ITERATOR_H
47
48#include <compare>
49#include <iterator>
50#include <concepts>
51#include <type_traits>
52#include <utility>
53
54namespace Aleph
55{
56 // Forward declaration only: extract_from_stl_container() below names
57 // Aleph::DynList in a non-dependent qualified-id, which needs the
58 // namespace and template to be visible even though the function body
59 // is not instantiated until htlist.H's full definition is in scope.
60 template <typename T> class DynList;
61}
62
72template <class I>
73concept AlephRandomAccessItor = requires { typename I::aleph_random_access_iterator; } and
74 std::same_as<typename I::aleph_random_access_iterator, I> and
75 requires(I &it, const I &cit, long n) {
76 { cit.get_pos() } -> std::convertible_to<long>;
77 it.set_pos(n);
78 it.prev();
79 };
80
97template <class SetType>
98struct StlIterator : public SetType::Iterator
99{
100 using T = typename SetType::Item_Type;
101 using Itor = typename SetType::Iterator;
102
107 std::conditional_t<AlephRandomAccessItor<Itor>, std::random_access_iterator_tag, std::forward_iterator_tag>;
109
110 using difference_type = std::ptrdiff_t;
111
112 using reference = decltype(std::declval<const Itor &>().get_curr());
113
114 using pointer = std::add_pointer_t<std::remove_reference_t<reference>>;
115
116 using value_type = T;
117
119 StlIterator() noexcept = default;
120
121 using Itor::Itor;
122
124 StlIterator &operator ++ ()
125 {
126 this->next();
127 return *this;
128 }
129
132 {
133 StlIterator ret_val = *this;
134 this->next();
135 return ret_val;
136 }
137
140 bool operator == (const StlIterator &it) const
141 {
142 if constexpr (requires(const Itor &a, const Itor &b) {
143 { a == b } -> std::convertible_to<bool>;
144 })
145 return static_cast<const Itor &>(*this) == static_cast<const Itor &>(it);
146
147 if (this->has_curr() and it.has_curr())
148 return this->get_pos() == it.get_pos();
149 // return this->get_curr() == it.get_curr();
150
151 if (not this->has_curr() and not it.has_curr())
152 return true;
153
154 return false;
155 }
156
158 bool operator != (const StlIterator &it) const
159 {
160 return not (*this == it);
161 }
162
163 // Note: operator* must be const to satisfy std::indirectly_readable.
164 // Constness of the iterator object does not imply constness of the element.
167 {
168 return this->get_curr();
169 }
170
173 {
174 return &this->get_curr();
175 }
176
177 // Random-access operations. These overloads exist only when the underlying
178 // Aleph iterator opts in via the `aleph_random_access_iterator` marker
179 // (e.g. DynArray, Array). They operate on the logical position exposed by
180 // get_pos()/set_pos(), so any physical/circular index mapping stays internal.
181
185 {
186 this->prev();
187 return *this;
188 }
189
193 {
194 StlIterator ret_val = *this;
195 this->prev();
196 return ret_val;
197 }
198
202 {
203 this->set_pos(this->get_pos() + n);
204 return *this;
205 }
206
210 {
211 this->set_pos(this->get_pos() - n);
212 return *this;
213 }
214
218 {
219 StlIterator ret_val = *this;
220 ret_val += n;
221 return ret_val;
222 }
223
227 {
228 return it + n;
229 }
230
234 {
235 StlIterator ret_val = *this;
236 ret_val -= n;
237 return ret_val;
238 }
239
243 {
244 return static_cast<difference_type>(this->get_pos() - it.get_pos());
245 }
246
250 {
251 StlIterator tmp = *this;
252 tmp += n;
253 return *tmp;
254 }
255
257 std::strong_ordering operator <=> (const StlIterator &it) const
259 {
260 return this->get_pos() <=> it.get_pos();
261 }
262
264 static StlIterator begin(SetType &s)
265 {
266 return StlIterator(s);
267 }
268
270 static StlIterator end(SetType &s)
271 {
272 StlIterator it(s);
273 it.Itor::end();
274 return it;
275 }
276};
277
284template <class SetType>
285struct StlConstIterator : public SetType::Iterator
286{
287 using T = typename SetType::Item_Type;
288 using Itor = typename SetType::Iterator;
289
294 std::conditional_t<AlephRandomAccessItor<Itor>, std::random_access_iterator_tag, std::forward_iterator_tag>;
296
297 using difference_type = std::ptrdiff_t;
298
299 using pointer = const T *;
300
301 using reference = const T &;
302
303 using value_type = T;
304
306 StlConstIterator() noexcept = default;
307
308 using Itor::Itor;
309
311 StlConstIterator &operator ++ ()
312 {
313 this->next();
314 return *this;
315 }
316
319 {
320 StlConstIterator ret_val = *this;
321 this->next();
322 return ret_val;
323 }
324
327 bool operator == (const StlConstIterator &it) const
328 {
329 if constexpr (requires(const Itor &a, const Itor &b) {
330 { a == b } -> std::convertible_to<bool>;
331 })
332 return static_cast<const Itor &>(*this) == static_cast<const Itor &>(it);
333
334 if (this->has_curr() and it.has_curr())
335 return this->get_pos() == it.get_pos();
336
337 if (not this->has_curr() and not it.has_curr())
338 return true;
339
340 return false;
341 }
342
344 bool operator != (const StlConstIterator &it) const
345 {
346 return not (*this == it);
347 }
348
350 const T &operator * () const
351 {
352 return this->get_curr();
353 }
354
356 const T *operator ->() const
357 {
358 return &this->get_curr();
359 }
360
361 // Random-access operations, mirroring StlIterator. These overloads exist
362 // only when the underlying Aleph iterator opts in via the
363 // `aleph_random_access_iterator` marker (e.g. DynArray, Array). They operate
364 // on the logical position exposed by get_pos()/set_pos(), so any
365 // physical/circular index mapping stays internal.
366
370 {
371 this->prev();
372 return *this;
373 }
374
378 {
379 StlConstIterator ret_val = *this;
380 this->prev();
381 return ret_val;
382 }
383
387 {
388 this->set_pos(this->get_pos() + n);
389 return *this;
390 }
391
395 {
396 this->set_pos(this->get_pos() - n);
397 return *this;
398 }
399
403 {
404 StlConstIterator ret_val = *this;
405 ret_val += n;
406 return ret_val;
407 }
408
412 {
413 return it + n;
414 }
415
419 {
420 StlConstIterator ret_val = *this;
421 ret_val -= n;
422 return ret_val;
423 }
424
428 {
429 return static_cast<difference_type>(this->get_pos() - it.get_pos());
430 }
431
435 {
436 StlConstIterator tmp = *this;
437 tmp += n;
438 return *tmp;
439 }
440
442 std::strong_ordering operator <=> (const StlConstIterator &it) const
444 {
445 return this->get_pos() <=> it.get_pos();
446 }
447
449 static StlConstIterator cbegin(const SetType &s)
450 {
451 return StlConstIterator(s);
452 }
453
455 static StlConstIterator cend(const SetType &s)
456 {
457 StlConstIterator it(s);
458 it.Itor::end();
459 return it;
460 }
461};
462
470template <class SetName>
472{
473 SetName *me()
474 {
475 return static_cast<SetName *>(this);
476 }
477
478 const SetName *const_me() const
479 {
480 return static_cast<const SetName *>(this);
481 }
482
483public:
485
487
489 iterator begin() noexcept
490 {
491 return iterator::begin(*me());
492 }
493
495 iterator end() noexcept
496 {
497 return iterator::end(*me());
498 }
499
501 const_iterator begin() const noexcept
502 {
504 }
505
507 const_iterator end() const noexcept
508 {
510 }
511
513 const_iterator cbegin() const noexcept
514 {
516 }
517
519 const_iterator cend() const noexcept
520 {
522 }
523
524 friend const_iterator cbegin(const SetName &s) noexcept
525 {
526 return s.begin();
527 }
528
529 friend const_iterator cend(const SetName &s) noexcept
530 {
531 return s.end();
532 }
533
534 friend const_iterator begin(const SetName &s) noexcept
535 {
536 return s.begin();
537 }
538
539 friend const_iterator end(const SetName &s) noexcept
540 {
541 return s.end();
542 }
543
544 friend iterator begin(SetName &s) noexcept
545 {
546 return s.begin();
547 }
548
549 friend iterator end(SetName &s) noexcept
550 {
551 return s.end();
552 }
553};
554
563template <class Container>
565{
567 for (const auto &i : c)
568 ret.append(i);
569 return ret;
570}
571
572#endif // AH_ITERATOR_H
Aleph::DynList< typename Container::value_type > extract_from_stl_container(const Container &c)
Extract all items from an STL container into an Aleph DynList.
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
Mixin that adds STL begin()/end() and cbegin()/cend() to Aleph containers.
friend const_iterator end(const SetName &s) noexcept
const_iterator begin() const noexcept
Return a const iterator to the first element.
friend const_iterator cbegin(const SetName &s) noexcept
friend const_iterator cend(const SetName &s) noexcept
SetName * me()
const_iterator cbegin() const noexcept
Return a const iterator to the first element.
const_iterator cend() const noexcept
Return a const end iterator.
friend iterator end(SetName &s) noexcept
const SetName * const_me() const
friend iterator begin(SetName &s) noexcept
iterator end() noexcept
Return an STL-compatible end iterator.
const_iterator end() const noexcept
Return a const end iterator.
friend const_iterator begin(const SetName &s) noexcept
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
Detects Aleph iterators that opted in to random-access promotion.
Definition ah-iterator.H:73
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
STL-compatible const iterator adapter for Aleph containers.
const T & operator*() const
Dereference: return the current element.
StlConstIterator() noexcept=default
Default constructor creates an "end" iterator (no current element).
typename SetType::Iterator Itor
typename SetType::Item_Type T
static StlConstIterator cbegin(const SetType &s)
Create a const iterator positioned at the first element of the container.
friend StlConstIterator operator+(difference_type n, const StlConstIterator &it)
Return an iterator advanced n positions (symmetric form).
const T * operator->() const
Member access to the current element.
const T * pointer
bool operator==(const StlConstIterator &it) const
Equality compares positions when both iterators are valid; otherwise both must be in the end state.
std::strong_ordering operator<=>(const StlConstIterator &it) const
Order two iterators by their logical position.
std::ptrdiff_t difference_type
std::conditional_t< AlephRandomAccessItor< Itor >, std::random_access_iterator_tag, std::forward_iterator_tag > iterator_category
Category is promoted to random-access when the underlying Aleph iterator opts in (see AlephRandomAcce...
bool operator!=(const StlConstIterator &it) const
Inequality.
StlConstIterator & operator++()
Pre-increment: advance to the next element.
static StlConstIterator cend(const SetType &s)
Create a const end iterator for the container.
iterator_category iterator_concept
const T & reference
StlConstIterator operator-(difference_type n) const
Return an iterator moved back n positions.
StlConstIterator & operator--()
Pre-decrement: move to the previous element.
reference operator[](difference_type n) const
Access the element n positions away from the current one.
StlConstIterator & operator+=(difference_type n)
Advance the iterator n positions (n may be negative).
StlConstIterator & operator-=(difference_type n)
Move the iterator back n positions (n may be negative).
STL-compatible mutable iterator adapter for Aleph containers.
Definition ah-iterator.H:99
std::add_pointer_t< std::remove_reference_t< reference > > pointer
std::strong_ordering operator<=>(const StlIterator &it) const
Order two iterators by their logical position.
bool operator!=(const StlIterator &it) const
Inequality.
friend StlIterator operator+(difference_type n, const StlIterator &it)
Return an iterator advanced n positions (symmetric form).
decltype(std::declval< const Itor & >().get_curr()) reference
typename SetType::Iterator Itor
std::ptrdiff_t difference_type
static StlIterator begin(SetType &s)
Create an iterator positioned at the first element of the container.
StlIterator & operator-=(difference_type n)
Move the iterator back n positions (n may be negative).
StlIterator operator-(difference_type n) const
Return an iterator moved back n positions.
std::conditional_t< AlephRandomAccessItor< Itor >, std::random_access_iterator_tag, std::forward_iterator_tag > iterator_category
Category is promoted to random-access when the underlying Aleph iterator opts in (see AlephRandomAcce...
StlIterator & operator+=(difference_type n)
Advance the iterator n positions (n may be negative).
static StlIterator end(SetType &s)
Create an end iterator for the container.
StlIterator() noexcept=default
Default constructor creates an "end" iterator (no current element).
pointer operator->() const
Member access to the current element.
StlIterator & operator++()
Pre-increment: advance to the next element.
bool operator==(const StlIterator &it) const
Equality compares positions when both iterators are valid; otherwise both must be in the end state.
iterator_category iterator_concept
reference operator*() const
Dereference: return the current element.
typename SetType::Item_Type T
reference operator[](difference_type n) const
Access the element n positions away from the current one.
StlIterator & operator--()
Pre-decrement: move to the previous element.