20 using parent_iterator = ParentIt;
21 using child_iterator = std::conditional_t<
22 std::is_const_v<std::remove_reference_t<typename std::iterator_traits<ParentIt>::reference>>,
41 constexpr recursive_iterator(parent_iterator parent_it, parent_iterator parent_it_end, child_iterator child_it) noexcept :
42 _parent_it(parent_it), _parent_it_end(parent_it_end), _child_it(child_it)
48 constexpr recursive_iterator(parent_iterator parent_it, parent_iterator parent_it_end) noexcept :
49 _parent_it(parent_it),
50 _parent_it_end(parent_it_end),
51 _child_it(parent_it != parent_it_end ?
std::begin(*parent_it) : child_iterator{})
58 _parent_it(parent_it_end), _parent_it_end(parent_it_end), _child_it()
64 [[nodiscard]]
constexpr parent_iterator
parent() const noexcept
72 [[nodiscard]]
constexpr child_iterator
child() const noexcept
85 [[nodiscard]]
constexpr bool at_end() const noexcept
87 return _parent_it == _parent_it_end;
90 [[nodiscard]]
constexpr reference operator*() const noexcept
95 [[nodiscard]]
constexpr pointer operator->() const noexcept
100 [[nodiscard]]
constexpr reference operator[](
std::size_t i)
const noexcept
105 constexpr recursive_iterator& operator++() noexcept
108 if (_child_it ==
std::end(*_parent_it)) {
111 _child_it = _parent_it->begin();
117 constexpr recursive_iterator& operator--() noexcept
127 constexpr recursive_iterator operator++(
int)
noexcept
134 constexpr recursive_iterator operator--(
int)
noexcept
141 constexpr recursive_iterator& operator+=(difference_type rhs)
noexcept
144 return (*
this) -= -rhs;
150 if (left_in_child <= rhs) {
155 rhs -= left_in_child;
167 constexpr recursive_iterator& operator-=(difference_type rhs)
noexcept
170 return (*
this) += -rhs;
176 if (left_in_child < rhs) {
178 _child_it =
std::end(*_parent_it) - 1;
179 rhs -= (left_in_child + 1);
191 [[nodiscard]]
constexpr friend bool operator==(recursive_iterator
const& lhs, recursive_iterator
const& rhs)
noexcept
193 if (lhs._parent_it != rhs._parent_it) {
195 }
else if (lhs.at_end()) {
199 return lhs._child_it == rhs._child_it;
203 [[nodiscard]]
constexpr friend std::strong_ordering
204 operator<=>(recursive_iterator
const& lhs, recursive_iterator
const& rhs)
noexcept
206 if (lhs._parent_it != rhs._parent_it) {
207 return (lhs._parent_it - rhs._parent_it) <=> 0;
208 }
else if (lhs.at_end()) {
210 return std::strong_ordering::equal;
212 return (lhs._child_it - rhs._child_it) <=> 0;
216 [[nodiscard]]
constexpr friend recursive_iterator operator+(recursive_iterator lhs, difference_type rhs)
noexcept
220 [[nodiscard]]
constexpr friend recursive_iterator operator-(recursive_iterator lhs, difference_type rhs)
noexcept
224 [[nodiscard]]
constexpr friend recursive_iterator operator+(difference_type lhs, recursive_iterator rhs)
noexcept
229 [[nodiscard]]
constexpr friend difference_type
230 operator-(recursive_iterator
const& lhs, recursive_iterator
const& rhs)
noexcept
236 difference_type
count = 0;
237 while (lhs_._parent_it < rhs._parent_it) {
240 lhs_._child_it =
begin(*lhs_._parent_it);
247 parent_iterator _parent_it;
248 parent_iterator _parent_it_end;
249 child_iterator _child_it;
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
constexpr auto recursive_iterator_begin(Container &rhs) noexcept
Get a recursive iterator from the begin of a recursive container.
Definition recursive_iterator.hpp:255
constexpr auto recursive_iterator_end(Container &rhs) noexcept
Get a recursive iterator from one beyond the end of a recursive container.
Definition recursive_iterator.hpp:263
constexpr 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:41
constexpr 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:48