SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
policy_search_result_builder.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
19 
20 namespace seqan3::detail
21 {
22 
25 template <typename search_configuration_t>
26 #if !SEQAN3_WORKAROUND_GCC_93467
27  requires is_type_specialisation_of_v<search_configuration_t, configuration>
30 #endif // !SEQAN3_WORKAROUND_GCC_93467
31 struct policy_search_result_builder
32 {
33 protected:
35  using search_traits_type = detail::search_traits<search_configuration_t>;
37  using search_result_type = typename search_traits_type::search_result_type;
38 
39  static_assert(!std::same_as<search_result_type, typename search_traits_type::empty_search_result_type>,
40  "The search result type was not configured properly.");
41 
45  policy_search_result_builder() = default;
46  policy_search_result_builder(policy_search_result_builder &&) = default;
47  policy_search_result_builder(policy_search_result_builder const &) = default;
48  policy_search_result_builder & operator=(policy_search_result_builder &&) = default;
49  policy_search_result_builder & operator=(policy_search_result_builder const &) = default;
50  ~policy_search_result_builder() = default;
51 
53  explicit policy_search_result_builder(search_configuration_t const &)
54  {}
56 
71  template <typename index_cursor_t, typename query_index_t, typename callback_t>
72  void make_results(std::vector<index_cursor_t> internal_hits, query_index_t idx, callback_t && callback)
73  {
74  return make_results_impl(std::move(internal_hits), idx, std::forward<callback_t>(callback));
75  }
76 
93  template <typename index_cursor_t, typename query_index_t, typename callback_t>
95  requires search_traits_type::output_requires_locate_call &&
96  (!search_traits_type::search_single_best_hit)
98  void make_results(std::vector<index_cursor_t> internal_hits, query_index_t idx, callback_t && callback)
99  {
101  results.reserve(internal_hits.size()); // expect at least as many text positions as cursors, possibly more
102 
103  make_results_impl(std::move(internal_hits), idx, [&results] (auto && search_result)
104  {
105  results.push_back(std::move(search_result));
106  });
107 
108  // sort by reference id or by reference position if both have the same reference id.
109  std::sort(results.begin(), results.end(), [] (auto const & r1, auto const & r2)
110  {
111  return (r1.reference_id() == r2.reference_id()) ? (r1.reference_begin_position() <
112  r2.reference_begin_position())
113  : (r1.reference_id() < r2.reference_id());
114  });
115 
116  results.erase(std::unique(results.begin(), results.end()), results.end());
117 
118  for (auto && search_result : results)
119  callback(std::move(search_result));
120  }
121 
122 private:
140  template <typename index_cursor_t, typename query_index_t, typename callback_t>
141  void make_results_impl(std::vector<index_cursor_t> internal_hits,
142  [[maybe_unused]] query_index_t idx,
143  callback_t && callback)
144  {
145  auto maybe_locate = [] (auto const & cursor)
146  {
147  if constexpr (search_traits_type::output_requires_locate_call)
148  return cursor.lazy_locate();
149  else
150  return std::views::single(std::tuple{0, 0});
151  };
152 
153  for (auto const & cursor : internal_hits)
154  {
155  for (auto && [ref_id, ref_pos] : maybe_locate(cursor))
156  {
157  search_result_type result{};
158 
159  if constexpr (search_traits_type::output_query_id)
160  result.query_id_ = std::move(idx);
161  if constexpr (search_traits_type::output_index_cursor)
162  result.cursor_ = cursor;
163  if constexpr (search_traits_type::output_reference_id)
164  result.reference_id_ = std::move(ref_id);
165  if constexpr (search_traits_type::output_reference_begin_position)
166  result.reference_begin_position_ = std::move(ref_pos);
167 
168  callback(result);
169 
170  if constexpr (search_traits_type::search_single_best_hit)
171  return;
172  }
173  }
174  }
175 };
176 
177 } // namespace seqan3::detail
seqan3::single
@ single
The text is a single range.
Definition: concept.hpp:84
std::vector::reserve
T reserve(T... args)
std::vector
std::vector::size
T size(T... args)
template_inspection.hpp
Provides seqan3::type_list and auxiliary type traits.
std::tuple
std::sort
T sort(T... args)
search_result.hpp
Provides seqan3::search_result.
seqan3::views::move
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
concept.hpp
Provides the concepts for seqan3::fm_index and seqan3::bi_fm_index and its traits and cursors.
std::unique
T unique(T... args)
search_traits.hpp
Provides seqan3::detail::search_traits.