15 #include <type_traits>
33 namespace seqan3::detail
53 template <std::ranges::viewable_range range_t>
54 struct make_aligned_sequence_type
61 using type = lazy_conditional_t<is_class_template_declarable_with_v<
gap_decorator,
62 decltype(std::declval<range_t>()
64 lazy<gap_decorator, decltype(std::declval<range_t>() |
views::slice(0, 1))>,
88 template <std::ranges::viewable_range fst_sequence_t, std::ranges::viewable_range sec_sequence_t>
89 class aligned_sequence_builder
93 using fst_aligned_t =
typename make_aligned_sequence_type<fst_sequence_t>::type;
95 using sec_aligned_t =
typename make_aligned_sequence_type<sec_sequence_t>::type;
98 "fst_aligned_t is required to model seqan3::aligned_sequence!");
100 "sec_aligned_t is required to model seqan3::aligned_sequence!");
105 struct [[nodiscard]] result_type
119 constexpr aligned_sequence_builder() =
default;
120 constexpr aligned_sequence_builder(aligned_sequence_builder
const &) =
default;
121 constexpr aligned_sequence_builder(aligned_sequence_builder &&) =
default;
122 constexpr aligned_sequence_builder & operator=(aligned_sequence_builder
const &) =
default;
123 constexpr aligned_sequence_builder & operator=(aligned_sequence_builder &&) =
default;
124 ~aligned_sequence_builder() =
default;
130 constexpr aligned_sequence_builder(fst_sequence_t fst_rng, sec_sequence_t sec_rng) :
150 template <std::ranges::input_range trace_path_t>
151 result_type operator()(trace_path_t && trace_path)
153 static_assert(
std::same_as<value_type_t<trace_path_t>, trace_directions>,
154 "The value type of the trace path must be seqan3::detail::trace_directions");
158 std::tie(res.first_sequence_slice_positions.second, res.second_sequence_slice_positions.second) =
163 while (trace_it != std::ranges::end(trace_path))
165 trace_directions last_dir = *trace_it;
167 for (; trace_it != std::ranges::end(trace_path) && *trace_it == last_dir; ++trace_it, ++span)
173 std::tie(res.first_sequence_slice_positions.first, res.second_sequence_slice_positions.first) =
177 res.first_sequence_slice_positions.second));
179 res.second_sequence_slice_positions.second));
182 fill_aligned_sequence(trace_segments | std::views::reverse, res.alignment.first, res.alignment.second);
195 template <
typename reverse_traces_t,
typename fst_aligned_t,
typename sec_aligned_t>
196 void fill_aligned_sequence(reverse_traces_t && rev_traces,
197 fst_aligned_t & fst_aligned,
198 sec_aligned_t & sec_aligned)
const
200 if (std::ranges::empty(rev_traces))
206 for (
auto const & [dir, span] : rev_traces)
208 if (dir == trace_directions::up)
209 fst_it =
insert_gap(fst_aligned, fst_it, span);
211 if (dir == trace_directions::left)
212 sec_it =
insert_gap(sec_aligned, sec_it, span);
219 type_reduce_view<fst_sequence_t> fst_rng;
220 type_reduce_view<sec_sequence_t> sec_rng;
227 template <std::ranges::viewable_range fst_sequence_t, std::ranges::viewable_range sec_sequence_t>
229 aligned_sequence_builder(fst_sequence_t &&, sec_sequence_t &&) ->
230 aligned_sequence_builder<fst_sequence_t, sec_sequence_t>;