21 namespace seqan3::detail
61 template <
typename derived_t, two_dimensional_matrix_iterator matrix_iter_t>
62 class trace_iterator_base
66 "Value type of the underlying iterator must be seqan3::detail::trace_directions.");
69 template <
typename other_derived_t, two_dimensional_matrix_iterator other_matrix_iter_t>
71 requires std::constructible_from<derived_t, other_derived_t> &&
72 std::constructible_from<matrix_iter_t, other_matrix_iter_t>
74 friend class trace_iterator_base;
82 constexpr trace_iterator_base() =
default;
83 constexpr trace_iterator_base(trace_iterator_base
const &) =
default;
84 constexpr trace_iterator_base(trace_iterator_base &&) =
default;
85 constexpr trace_iterator_base & operator=(trace_iterator_base
const &) =
default;
86 constexpr trace_iterator_base & operator=(trace_iterator_base &&) =
default;
87 ~trace_iterator_base() =
default;
92 constexpr trace_iterator_base(matrix_iter_t
const matrix_iter) noexcept : matrix_iter{matrix_iter}
94 set_trace_direction(*matrix_iter);
107 template <
typename other_derived_t, two_dimensional_matrix_iterator other_matrix_iter_t>
109 requires std::constructible_from<matrix_iter_t, other_matrix_iter_t>
111 constexpr trace_iterator_base(trace_iterator_base<other_derived_t, other_matrix_iter_t>
const & other) noexcept :
112 trace_iterator_base{other.matrix_iter}
120 using value_type = trace_directions;
121 using reference = trace_directions
const &;
122 using pointer = value_type *;
130 reference operator*() const noexcept
133 return current_direction;
137 pointer operator->() const noexcept
139 return ¤t_direction;
143 [[nodiscard]] constexpr matrix_coordinate coordinate() const noexcept
145 return matrix_iter.coordinate();
152 constexpr derived_t & operator++() noexcept
155 trace_directions old_dir = *matrix_iter;
159 if (current_direction == trace_directions::up)
161 derived().go_up(matrix_iter);
163 if (
static_cast<bool>(old_dir & trace_directions::up_open))
164 set_trace_direction(*matrix_iter);
166 else if (current_direction == trace_directions::left)
168 derived().go_left(matrix_iter);
170 if (
static_cast<bool>(old_dir & trace_directions::left_open))
171 set_trace_direction(*matrix_iter);
175 assert(current_direction == trace_directions::diagonal);
177 derived().go_diagonal(matrix_iter);
178 set_trace_direction(*matrix_iter);
184 constexpr derived_t operator++(
int) noexcept
186 derived_t tmp{derived()};
195 constexpr
friend bool operator==(derived_t
const & lhs, derived_t
const & rhs) noexcept
198 return lhs.matrix_iter == rhs.matrix_iter;
202 constexpr
friend bool operator==(derived_t
const & lhs, std::default_sentinel_t
const &) noexcept
208 constexpr
friend bool operator==(std::default_sentinel_t
const &, derived_t
const & rhs) noexcept
210 return rhs == std::default_sentinel;
214 constexpr
friend bool operator!=(derived_t
const & lhs, derived_t
const & rhs) noexcept
216 return !(lhs == rhs);
220 constexpr
friend bool operator!=(derived_t
const & lhs, std::default_sentinel_t
const &) noexcept
222 return !(lhs == std::default_sentinel);
226 constexpr
friend bool operator!=(std::default_sentinel_t
const &, derived_t
const & rhs) noexcept
228 return !(rhs == std::default_sentinel);
237 constexpr
void go_left(matrix_iter_t & iter)
const noexcept
240 iter -= matrix_offset{row_index_type{0}, column_index_type{1}};
244 constexpr
void go_up(matrix_iter_t & iter)
const noexcept
246 iter -= matrix_offset{row_index_type{1}, column_index_type{0}};
250 constexpr
void go_diagonal(matrix_iter_t & iter)
const noexcept
252 iter -= matrix_offset{row_index_type{1}, column_index_type{1}};
257 void set_trace_direction(trace_directions
const dir) noexcept
259 if (
static_cast<bool>(dir & trace_directions::diagonal))
261 current_direction = trace_directions::diagonal;
263 else if (
static_cast<bool>(dir & trace_directions::up) ||
264 static_cast<bool>(dir & trace_directions::up_open))
266 current_direction = trace_directions::up;
268 else if (
static_cast<bool>(dir & trace_directions::left) ||
269 static_cast<bool>(dir & trace_directions::left_open))
271 current_direction = trace_directions::left;
280 constexpr derived_t & derived() noexcept
282 return static_cast<derived_t &
>(*this);
286 constexpr derived_t
const & derived() const noexcept
288 return static_cast<derived_t
const &
>(*this);
291 matrix_iter_t matrix_iter{};
292 trace_directions current_direction{};