19 using parent_iterator = ParentIt;
20 using child_iterator = std::conditional_t<
21 std::is_const_v<std::remove_reference_t<typename std::iterator_traits<ParentIt>::reference>>,
40 recursive_iterator(parent_iterator parent_it, parent_iterator parent_it_end, child_iterator child_it) noexcept :
41 _parent_it(parent_it), _parent_it_end(parent_it_end), _child_it(child_it)
48 _parent_it(parent_it),
49 _parent_it_end(parent_it_end),
50 _child_it(parent_it != parent_it_end ?
std::begin(*parent_it) : child_iterator{})
57 _parent_it(parent_it_end), _parent_it_end(parent_it_end), _child_it()
63 [[nodiscard]] parent_iterator
parent() const noexcept
71 [[nodiscard]] child_iterator
child() const noexcept
84 [[nodiscard]]
bool at_end() const noexcept
86 return _parent_it == _parent_it_end;
89 [[nodiscard]]
reference operator*() const noexcept
94 [[nodiscard]] pointer operator->() const noexcept
99 [[nodiscard]] reference operator[](
std::size_t i)
const noexcept
104 recursive_iterator &operator++() noexcept
107 if (_child_it ==
std::end(*_parent_it)) {
110 _child_it = _parent_it->begin();
116 recursive_iterator &operator--() noexcept
126 recursive_iterator operator++(
int)
noexcept
132 recursive_iterator operator--(
int)
noexcept
139 recursive_iterator &operator+=(difference_type rhs)
noexcept
142 return (*
this) -= -rhs;
148 if (left_in_child <= rhs) {
153 rhs -= left_in_child;
165 recursive_iterator &operator-=(difference_type rhs)
noexcept
168 return (*
this) += -rhs;
174 if (left_in_child < rhs) {
176 _child_it =
std::end(*_parent_it) - 1;
177 rhs -= (left_in_child + 1);
189 [[nodiscard]]
friend bool operator==(recursive_iterator
const &lhs, recursive_iterator
const &rhs)
noexcept
191 if (lhs._parent_it != rhs._parent_it) {
193 }
else if (lhs.at_end()) {
194 hi_axiom(rhs.at_end());
197 return lhs._child_it == rhs._child_it;
201 [[nodiscard]]
friend std::strong_ordering operator<=>(recursive_iterator
const &lhs, recursive_iterator
const &rhs)
noexcept
203 if (lhs._parent_it != rhs._parent_it) {
204 return (lhs._parent_it - rhs._parent_it) <=> 0;
205 }
else if (lhs.at_end()) {
206 hi_axiom(rhs.at_end());
207 return std::strong_ordering::equal;
209 return (lhs._child_it - rhs._child_it) <=> 0;
213 [[nodiscard]]
friend recursive_iterator operator+(recursive_iterator lhs, difference_type rhs)
noexcept
217 [[nodiscard]]
friend recursive_iterator operator-(recursive_iterator lhs, difference_type rhs)
noexcept
221 [[nodiscard]]
friend recursive_iterator operator+(difference_type lhs, recursive_iterator rhs)
noexcept
226 [[nodiscard]]
friend difference_type operator-(recursive_iterator
const &lhs, recursive_iterator
const &rhs)
noexcept
232 difference_type
count = 0;
233 while (lhs_._parent_it < rhs._parent_it) {
236 lhs_._child_it =
begin(*lhs_._parent_it);
243 parent_iterator _parent_it;
244 parent_iterator _parent_it_end;
245 child_iterator _child_it;
recursive_iterator(parent_iterator parent_it, parent_iterator parent_it_end) noexcept
Create a begin iterator at the first child's first element.
Definition recursive_iterator.hpp:47
recursive_iterator(parent_iterator parent_it, parent_iterator parent_it_end, child_iterator child_it) noexcept
Create an iterator at an element inside a child container.
Definition recursive_iterator.hpp:40