SeqAn3
alignment_executor_two_way.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (c) 2016-2018, Knut Reinert & MPI Molekulare Genetik
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
25 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 //
33 // ============================================================================
34 
40 #pragma once
41 
42 #include <functional>
43 #include <optional>
44 #include <type_traits>
45 
50 #include <seqan3/std/ranges>
51 
52 namespace seqan3::detail
53 {
54 
61 template <std::ranges::ViewableRange align_instance_rng_t,
62  typename alignment_selector_t,
63  typename execution_handler_t = execution_handler_sequential>
64 class alignment_executor_two_way
65 {
67  using this_t = alignment_executor_two_way<align_instance_rng_t, alignment_selector_t, execution_handler_t>;
68 
70  template <typename executor_t>
71  friend class seqan3::alignment_range;
72 
76  using resource_type = std::remove_reference_t<align_instance_rng_t>;
79  using resource_iterator = std::ranges::iterator_t<resource_type>;
81  using resource_sentinel = std::ranges::sentinel_t<resource_type>;
83  using resource_value_type = std::remove_reference_t<decltype(*std::declval<resource_iterator>())>;
85 
89  using buffer_value_type = typename std::remove_reference_t<alignment_selector_t>::result_type;
92  using buffer_type = std::vector<buffer_value_type>;
94  using buffer_pointer = std::ranges::iterator_t<buffer_type>;
96 public:
98  using value_type = buffer_value_type;
100  using reference = std::add_lvalue_reference_t<value_type>;
102  using difference_type = typename buffer_type::difference_type;
103 
107  alignment_executor_two_way() = default;
108  alignment_executor_two_way(alignment_executor_two_way const &) = default;
109  alignment_executor_two_way(alignment_executor_two_way &&) = default;
110  alignment_executor_two_way & operator=(alignment_executor_two_way const &) = default;
111  alignment_executor_two_way & operator=(alignment_executor_two_way &&) = default;
112  ~alignment_executor_two_way() = default;
113 
115  alignment_executor_two_way(align_instance_rng_t _resource,
116  alignment_selector_t _selector) :
117  resource{std::forward<align_instance_rng_t>(_resource)},
118  selector{std::forward<alignment_selector_t>(_selector)},
119  resource_iter{begin(resource)},
120  resource_end{end(resource)}
121  {
122  buffer.resize(1);
123  setg(end(buffer), end(buffer));
124  }
126 
128  alignment_range<this_t> range()
129  {
130  return alignment_range<this_t>{*this};
131  }
132 
133 protected:
134 
138  constexpr size_t in_avail() const noexcept
140  {
141  return egptr - gptr;
142  }
143 
145  std::optional<std::reference_wrapper<value_type>> bump()
146  {
147  if (gptr == buffer_pointer{} || gptr >= egptr)
148  {
149  if (underflow() == eof)
150  {
151  return {};
152  }
153  }
154  return {std::ref(*gptr++)};
155  }
156 
157  //\brief Sets the buffer pointer.
158  void setg(buffer_pointer beg, buffer_pointer end)
159  {
160  gptr = beg;
161  egptr = end;
162  }
163 
165  size_t underflow()
166  {
167  if (gptr < egptr) // Case: buffer not completely consumed
168  return in_avail();
169 
170  if (is_eof()) // Case: reached end of resource.
171  return eof;
172 
173  // Reset the get pointer.
174  setg(begin(buffer), begin(buffer) +
175  std::min(static_cast<size_t>(resource_end - resource_iter), buffer.size()));
176 
177  // Apply the alignment execution.
178  // TODO: Adapt for async behavior for parallel execution handler.
179  std::transform(resource_iter, resource_iter + in_avail(), gptr,
180  [this](auto && align_instance){
181  // value_type tmp;
182  auto f = selector.select(std::forward<decltype(align_instance)>(align_instance));
183  value_type tmp;
184  exec_handler.execute(std::move(f), tmp, [&tmp](auto && res){ tmp = std::move(res); });
185  return tmp;
186  });
187  // Advance the resource.
188  std::advance(resource_iter, in_avail());
189  return in_avail();
190  }
192 
196  bool is_eof() const noexcept
198  {
199  return resource_iter == resource_end;
200  }
202 
203 private:
204 
206  static constexpr size_t eof{-1};
207 
209  execution_handler_t exec_handler{};
210 
212  align_instance_rng_t resource; // view or lvalue ref
214  alignment_selector_t selector;
215 
217  resource_iterator resource_iter{};
219  resource_sentinel resource_end{};
220 
222  buffer_type buffer;
224  buffer_pointer gptr;
226  buffer_pointer egptr;
227 };
228 
233 template <std::ranges::ViewableRange resource_rng_t, typename selector_t>
234 alignment_executor_two_way(resource_rng_t && , selector_t &&) ->
235  alignment_executor_two_way<resource_rng_t, selector_t, execution_handler_sequential>;
236 
238 } // namespace seqan3::detail
constexpr auto transform
A range adaptor that takes a invocable and returns a view of the elements with the invocable applied...
Definition: transform.hpp:95
Contains various shortcuts for common std::ranges functions.
typename range_buffer_t::value_type value_type
The alignment result type.
Definition: alignment_range.hpp:167
::ranges::iterator_t iterator_t
Alias for ranges::iterator_t. Obtains the iterator type of a range.
Definition: ranges:225
Adaptations of concepts from the Ranges TS.
::ranges::sentinel_t sentinel_t
Alias for ranges::sentinel_t. Obtains the sentinel type of a range.
Definition: ranges:220
::ranges::begin begin
Alias for ranges::begin. Returns an iterator to the beginning of a range.
Definition: ranges:185
Provides seqan3::detail::alignment_range.
Specifies the requirements of a Range type that is either a std::ranges::View or an lvalue-reference...
constexpr bool eof() const noexcept
Returns whether the executor buffer reached is end.
Definition: alignment_range.hpp:244
auto constexpr is_eof
Checks whether a given letter is equal to the EOF constant defined in <cstdio>.
Definition: parse_condition.hpp:120
Definition: aligned_sequence_concept.hpp:288
Provides C++20 additions to the type_traits header.
typename range_buffer_t::difference_type difference_type
The offset type.
Definition: alignment_range.hpp:165
Provides various metafunctions used by the range module.
::ranges::end end
Alias for ranges::end. Returns an iterator to the end of a range.
Definition: ranges:190
The alignment.
Definition: alignment_range.hpp:60
Provides seqan3::detail::execution_handler_sequential.
typename range_buffer_t::reference reference
The reference type.
Definition: alignment_range.hpp:169