SeqAn3  3.2.0
The Modern C++ library for sequence analysis.
algorithm_result_generator_range.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, 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 
15 #include <cassert>
16 #include <concepts>
17 #include <memory>
18 #include <ranges>
19 
20 #include <seqan3/core/platform.hpp>
21 
22 namespace seqan3
23 {
24 
46 template <typename algorithm_executor_type>
48 {
49  static_assert(!std::is_const_v<algorithm_executor_type>, "Cannot create an algorithm stream over a const buffer.");
50 
52  using optional_type = decltype(std::declval<algorithm_executor_type>().next_result());
54  using algorithm_result_type = typename optional_type::value_type;
55 
57 
60 
61 public:
72 
74  explicit algorithm_result_generator_range(algorithm_executor_type const & algorithm_executor) = delete;
75 
84  explicit algorithm_result_generator_range(algorithm_executor_type && algorithm_executor) :
85  algorithm_executor_ptr{std::make_unique<algorithm_executor_type>(std::move(algorithm_executor))}
86  {}
88 
101  {
102  return algorithm_range_iterator{*this};
103  }
104 
106  algorithm_range_iterator begin() const = delete;
107 
116  constexpr std::default_sentinel_t end() noexcept
117  {
118  return std::default_sentinel;
119  }
120 
122  constexpr std::default_sentinel_t end() const = delete;
124 
125 protected:
134  bool next()
135  {
136  if (!algorithm_executor_ptr)
137  throw std::runtime_error{"No algorithm execution buffer available."};
138 
139  if (auto opt = algorithm_executor_ptr->next_result(); opt.has_value())
140  {
141  cache = std::move(*opt);
142  return true;
143  }
144 
145  return false;
146  }
147 
148 private:
150  std::unique_ptr<algorithm_executor_type> algorithm_executor_ptr{};
152  algorithm_result_type cache{};
153 };
154 
161 template <typename algorithm_executor_type>
162 algorithm_result_generator_range(algorithm_executor_type &&)
165 
169 template <typename algorithm_executor_type>
171 {
172 public:
179  using value_type = algorithm_result_type;
187 
191  constexpr algorithm_range_iterator() noexcept = default;
192  constexpr algorithm_range_iterator(algorithm_range_iterator const &) noexcept = default;
193  constexpr algorithm_range_iterator(algorithm_range_iterator &&) noexcept = default;
194  constexpr algorithm_range_iterator & operator=(algorithm_range_iterator const &) noexcept = default;
195  constexpr algorithm_range_iterator & operator=(algorithm_range_iterator &&) noexcept = default;
197 
200  range_ptr(std::addressof(range))
201  {
202  ++(*this); // Fetch the next element.
203  }
205 
214  reference operator*() const noexcept
215  {
216  return range_ptr->cache;
217  }
218 
220  pointer operator->() const noexcept
221  {
222  return &range_ptr->cache;
223  }
225 
231  {
232  assert(range_ptr != nullptr);
233 
234  at_end = !range_ptr->next();
235  return *this;
236  }
237 
239  void operator++(int /*post*/)
240  {
241  ++(*this);
242  }
244 
249  friend constexpr bool operator==(algorithm_range_iterator const & lhs, std::default_sentinel_t const &) noexcept
250  {
251  return lhs.at_end;
252  }
253 
255  friend constexpr bool operator==(std::default_sentinel_t const & lhs, algorithm_range_iterator const & rhs) noexcept
256  {
257  return rhs == lhs;
258  }
259 
261  friend constexpr bool operator!=(algorithm_range_iterator const & lhs, std::default_sentinel_t const & rhs) noexcept
262  {
263  return !(lhs == rhs);
264  }
265 
267  friend constexpr bool operator!=(std::default_sentinel_t const & lhs, algorithm_range_iterator const & rhs) noexcept
268  {
269  return rhs != lhs;
270  }
272 
273 private:
275  algorithm_result_generator_range * range_ptr{};
277  bool at_end{true};
278 };
279 
280 } // namespace seqan3
The iterator of seqan3::detail::algorithm_result_generator_range.
Definition: algorithm_result_generator_range.hpp:171
constexpr algorithm_range_iterator() noexcept=default
Defaulted.
void operator++(int)
Returns an iterator incremented by one.
Definition: algorithm_result_generator_range.hpp:239
algorithm_range_iterator & operator++()
Increments the iterator by one.
Definition: algorithm_result_generator_range.hpp:230
reference operator*() const noexcept
Access the pointed-to element.
Definition: algorithm_result_generator_range.hpp:214
constexpr friend bool operator==(algorithm_range_iterator const &lhs, std::default_sentinel_t const &) noexcept
Checks whether lhs is equal to the sentinel.
Definition: algorithm_result_generator_range.hpp:249
constexpr friend bool operator!=(algorithm_range_iterator const &lhs, std::default_sentinel_t const &rhs) noexcept
Checks whether *this is not equal to the sentinel.
Definition: algorithm_result_generator_range.hpp:261
algorithm_result_type value_type
Value type of container elements.
Definition: algorithm_result_generator_range.hpp:179
constexpr friend bool operator==(std::default_sentinel_t const &lhs, algorithm_range_iterator const &rhs) noexcept
Checks whether lhs is equal to rhs.
Definition: algorithm_result_generator_range.hpp:255
constexpr friend bool operator!=(std::default_sentinel_t const &lhs, algorithm_range_iterator const &rhs) noexcept
Checks whether lhs is not equal to rhs.
Definition: algorithm_result_generator_range.hpp:267
pointer operator->() const noexcept
Returns a pointer to the current algorithm result.
Definition: algorithm_result_generator_range.hpp:220
An input range over the algorithm results generated by the underlying algorithm executor.
Definition: algorithm_result_generator_range.hpp:48
constexpr std::default_sentinel_t end() noexcept
Returns a sentinel signaling the end of the algorithm range.
Definition: algorithm_result_generator_range.hpp:116
constexpr std::default_sentinel_t end() const =delete
This range is not const-iterable.
algorithm_result_generator_range(algorithm_executor_type const &algorithm_executor)=delete
Explicit deletion to forbid copy construction of the underlying executor.
algorithm_result_generator_range(algorithm_result_generator_range &&)=default
Defaulted.
algorithm_result_generator_range & operator=(algorithm_result_generator_range const &)=delete
This is a move-only type.
algorithm_result_generator_range(algorithm_result_generator_range const &)=delete
This is a move-only type.
bool next()
Receives the next algorithm result from the executor buffer.
Definition: algorithm_result_generator_range.hpp:134
algorithm_range_iterator begin() const =delete
This range is not const-iterable.
algorithm_result_generator_range()=default
Defaulted.
constexpr algorithm_range_iterator begin()
Returns an iterator to the first element of the algorithm range.
Definition: algorithm_result_generator_range.hpp:100
algorithm_result_generator_range(algorithm_executor_type &&) -> algorithm_result_generator_range< std::remove_reference_t< algorithm_executor_type >>
Deduces from the passed algorithm_executor_type.
algorithm_result_generator_range(algorithm_executor_type &&algorithm_executor)
Constructs a new algorithm range by taking ownership over the passed algorithm buffer.
Definition: algorithm_result_generator_range.hpp:84
algorithm_result_generator_range & operator=(algorithm_result_generator_range &&)=default
Defaulted.
~algorithm_result_generator_range()=default
Defaulted.
The <concepts> header from C++20's standard library.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
SeqAn specific customisations in the standard namespace.
Provides platform and dependency checks.
The <ranges> header from C++20's standard library.