19namespace seqan3::detail
59template <
typename derived_t, two_dimensional_matrix_iterator matrix_iter_t>
60class trace_iterator_base
63 static_assert(std::same_as<std::iter_value_t<matrix_iter_t>, trace_directions>,
64 "Value type of the underlying iterator must be seqan3::detail::trace_directions.");
67 template <
typename other_derived_t, two_dimensional_matrix_iterator other_matrix_iter_t>
68 friend class trace_iterator_base;
76 constexpr trace_iterator_base() =
default;
77 constexpr trace_iterator_base(trace_iterator_base
const &) =
default;
78 constexpr trace_iterator_base(trace_iterator_base &&) =
default;
79 constexpr trace_iterator_base & operator=(trace_iterator_base
const &) =
default;
80 constexpr trace_iterator_base & operator=(trace_iterator_base &&) =
default;
81 ~trace_iterator_base() =
default;
86 constexpr trace_iterator_base(matrix_iter_t
const matrix_iter) noexcept : matrix_iter{matrix_iter}
88 set_trace_direction(*matrix_iter);
101 template <
typename other_derived_t, two_dimensional_matrix_iterator other_matrix_iter_t>
102 requires std::constructible_from<matrix_iter_t, other_matrix_iter_t>
103 constexpr trace_iterator_base(trace_iterator_base<other_derived_t, other_matrix_iter_t>
const & other) noexcept :
104 trace_iterator_base{other.matrix_iter}
114 using value_type = trace_directions;
115 using reference = trace_directions
const &;
116 using pointer = value_type
const *;
125 reference operator*() const noexcept
127 return current_direction;
131 pointer operator->() const noexcept
133 return ¤t_direction;
137 [[nodiscard]]
constexpr matrix_coordinate coordinate() const noexcept
139 return matrix_iter.coordinate();
147 constexpr derived_t & operator++() noexcept
149 trace_directions old_dir = *matrix_iter;
151 assert(old_dir != trace_directions::none);
153 if (current_direction == trace_directions::up)
155 derived().go_up(matrix_iter);
157 if (
static_cast<bool>(old_dir & trace_directions::carry_up_open))
158 set_trace_direction(*matrix_iter);
160 else if (current_direction == trace_directions::left)
162 derived().go_left(matrix_iter);
164 if (
static_cast<bool>(old_dir & trace_directions::carry_left_open))
165 set_trace_direction(*matrix_iter);
169 assert(current_direction == trace_directions::diagonal);
171 derived().go_diagonal(matrix_iter);
172 set_trace_direction(*matrix_iter);
178 constexpr derived_t operator++(
int)
noexcept
180 derived_t tmp{derived()};
190 constexpr friend bool operator==(derived_t
const & lhs, derived_t
const & rhs)
noexcept
192 return lhs.matrix_iter == rhs.matrix_iter;
196 constexpr friend bool operator==(derived_t
const & lhs, std::default_sentinel_t
const &)
noexcept
198 return *lhs.matrix_iter == trace_directions::none;
202 constexpr friend bool operator==(std::default_sentinel_t
const &, derived_t
const & rhs)
noexcept
204 return rhs == std::default_sentinel;
208 constexpr friend bool operator!=(derived_t
const & lhs, derived_t
const & rhs)
noexcept
210 return !(lhs == rhs);
214 constexpr friend bool operator!=(derived_t
const & lhs, std::default_sentinel_t
const &)
noexcept
216 return !(lhs == std::default_sentinel);
220 constexpr friend bool operator!=(std::default_sentinel_t
const &, derived_t
const & rhs)
noexcept
222 return !(rhs == std::default_sentinel);
232 constexpr void go_left(matrix_iter_t & iter)
const noexcept
234 iter -= matrix_offset{row_index_type{0}, column_index_type{1}};
238 constexpr void go_up(matrix_iter_t & iter)
const noexcept
240 iter -= matrix_offset{row_index_type{1}, column_index_type{0}};
244 constexpr void go_diagonal(matrix_iter_t & iter)
const noexcept
246 iter -= matrix_offset{row_index_type{1}, column_index_type{1}};
251 void set_trace_direction(trace_directions
const dir)
noexcept
253 if (
static_cast<bool>(dir & trace_directions::diagonal))
255 current_direction = trace_directions::diagonal;
257 else if (
static_cast<bool>(dir & trace_directions::up))
259 current_direction = trace_directions::up;
261 else if (
static_cast<bool>(dir & trace_directions::left))
263 current_direction = trace_directions::left;
267 current_direction = trace_directions::none;
272 constexpr derived_t & derived() noexcept
274 return static_cast<derived_t &
>(*this);
278 constexpr derived_t
const & derived() const noexcept
280 return static_cast<derived_t
const &
>(*this);
283 matrix_iter_t matrix_iter{};
284 trace_directions current_direction{};
Provides the declaration of seqan3::detail::trace_directions.
Provides seqan3::detail::two_dimensional_matrix_iterator_base.
Provides seqan3::detail::two_dimensional_matrix_iterator.