22namespace seqan3::detail
62template <
typename derived_t, two_dimensional_matrix_iterator matrix_iter_t>
63class trace_iterator_base
66 static_assert(std::same_as<std::iter_value_t<matrix_iter_t>, trace_directions>,
67 "Value type of the underlying iterator must be seqan3::detail::trace_directions.");
70 template <
typename other_derived_t, two_dimensional_matrix_iterator other_matrix_iter_t>
71 friend class trace_iterator_base;
79 constexpr trace_iterator_base() =
default;
80 constexpr trace_iterator_base(trace_iterator_base
const &) =
default;
81 constexpr trace_iterator_base(trace_iterator_base &&) =
default;
82 constexpr trace_iterator_base & operator=(trace_iterator_base
const &) =
default;
83 constexpr trace_iterator_base & operator=(trace_iterator_base &&) =
default;
84 ~trace_iterator_base() =
default;
89 constexpr trace_iterator_base(matrix_iter_t
const matrix_iter) noexcept : matrix_iter{matrix_iter}
91 set_trace_direction(*matrix_iter);
104 template <
typename other_derived_t, two_dimensional_matrix_iterator other_matrix_iter_t>
105 requires std::constructible_from<matrix_iter_t, other_matrix_iter_t>
106 constexpr trace_iterator_base(trace_iterator_base<other_derived_t, other_matrix_iter_t>
const & other) noexcept :
107 trace_iterator_base{other.matrix_iter}
117 using value_type = trace_directions;
118 using reference = trace_directions
const &;
119 using pointer = value_type
const *;
128 reference operator*() const noexcept
130 return current_direction;
134 pointer operator->() const noexcept
136 return ¤t_direction;
140 [[nodiscard]]
constexpr matrix_coordinate coordinate() const noexcept
142 return matrix_iter.coordinate();
150 constexpr derived_t & operator++() noexcept
152 trace_directions old_dir = *matrix_iter;
154 assert(old_dir != trace_directions::none);
156 if (current_direction == trace_directions::up)
158 derived().go_up(matrix_iter);
160 if (
static_cast<bool>(old_dir & trace_directions::carry_up_open))
161 set_trace_direction(*matrix_iter);
163 else if (current_direction == trace_directions::left)
165 derived().go_left(matrix_iter);
167 if (
static_cast<bool>(old_dir & trace_directions::carry_left_open))
168 set_trace_direction(*matrix_iter);
172 assert(current_direction == trace_directions::diagonal);
174 derived().go_diagonal(matrix_iter);
175 set_trace_direction(*matrix_iter);
181 constexpr derived_t operator++(
int)
noexcept
183 derived_t tmp{derived()};
193 constexpr friend bool operator==(derived_t
const & lhs, derived_t
const & rhs)
noexcept
195 return lhs.matrix_iter == rhs.matrix_iter;
199 constexpr friend bool operator==(derived_t
const & lhs, std::default_sentinel_t
const &)
noexcept
201 return *lhs.matrix_iter == trace_directions::none;
205 constexpr friend bool operator==(std::default_sentinel_t
const &, derived_t
const & rhs)
noexcept
207 return rhs == std::default_sentinel;
211 constexpr friend bool operator!=(derived_t
const & lhs, derived_t
const & rhs)
noexcept
213 return !(lhs == rhs);
217 constexpr friend bool operator!=(derived_t
const & lhs, std::default_sentinel_t
const &)
noexcept
219 return !(lhs == std::default_sentinel);
223 constexpr friend bool operator!=(std::default_sentinel_t
const &, derived_t
const & rhs)
noexcept
225 return !(rhs == std::default_sentinel);
235 constexpr void go_left(matrix_iter_t & iter)
const noexcept
237 iter -= matrix_offset{row_index_type{0}, column_index_type{1}};
241 constexpr void go_up(matrix_iter_t & iter)
const noexcept
243 iter -= matrix_offset{row_index_type{1}, column_index_type{0}};
247 constexpr void go_diagonal(matrix_iter_t & iter)
const noexcept
249 iter -= matrix_offset{row_index_type{1}, column_index_type{1}};
254 void set_trace_direction(trace_directions
const dir)
noexcept
256 if (
static_cast<bool>(dir & trace_directions::diagonal))
258 current_direction = trace_directions::diagonal;
260 else if (
static_cast<bool>(dir & trace_directions::up))
262 current_direction = trace_directions::up;
264 else if (
static_cast<bool>(dir & trace_directions::left))
266 current_direction = trace_directions::left;
270 current_direction = trace_directions::none;
275 constexpr derived_t & derived() noexcept
277 return static_cast<derived_t &
>(*this);
281 constexpr derived_t
const & derived() const noexcept
283 return static_cast<derived_t
const &
>(*this);
286 matrix_iter_t matrix_iter{};
287 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.