33 namespace seqan3::detail
41 template <std::ranges::range urng_t>
42 class async_input_buffer_view :
public std::ranges::view_interface<async_input_buffer_view<urng_t>>
45 static_assert(std::ranges::input_range<urng_t>,
46 "The range parameter to async_input_buffer_view must be at least an std::ranges::InputRange.");
47 static_assert(std::ranges::view<urng_t>,
48 "The range parameter to async_input_buffer_view must model std::ranges::View.");
50 "The range parameter to async_input_buffer_view must have a value_type that is std::Movable.");
52 "The range parameter to async_input_buffer_view must have a value_type that is constructible by a moved "
53 "value of its reference type.");
56 using urng_iterator_type = std::ranges::iterator_t<urng_t>;
65 contrib::fixed_buffer_queue<value_type_t<urng_t>> buffer;
75 class async_input_buffer_iterator;
81 async_input_buffer_view() =
default;
82 async_input_buffer_view(async_input_buffer_view
const &) =
default;
83 async_input_buffer_view(async_input_buffer_view &&) =
default;
84 async_input_buffer_view & operator=(async_input_buffer_view
const &) =
default;
85 async_input_buffer_view & operator=(async_input_buffer_view &&) =
default;
86 ~async_input_buffer_view() =
default;
89 async_input_buffer_view(urng_t _urng,
size_t const buffer_size)
91 auto deleter = [] (state * p)
102 contrib::fixed_buffer_queue<value_type_t<urng_t>>{buffer_size},
106 auto runner = [&state = *state_ptr] ()
108 for (
auto && val : state.urange)
109 if (state.buffer.wait_push(
std::move(val)) == contrib::queue_op_status::closed)
112 state.buffer.close();
119 template <
typename other_urng_t>
122 std::ranges::viewable_range<other_urng_t> &&
125 async_input_buffer_view(other_urng_t && _urng,
size_t const buffer_size) :
144 async_input_buffer_iterator
begin()
146 assert(state_ptr !=
nullptr);
147 return {state_ptr->buffer};
151 async_input_buffer_iterator
begin()
const =
delete;
154 async_input_buffer_iterator
cbegin()
const =
delete;
157 std::ranges::default_sentinel_t
end()
159 return std::ranges::default_sentinel;
163 std::ranges::default_sentinel_t
end()
const =
delete;
166 std::ranges::default_sentinel_t
cend()
const =
delete;
171 template <
typename urng_t>
172 class async_input_buffer_view<urng_t>::async_input_buffer_iterator
175 using sentinel_type = std::ranges::default_sentinel_t;
178 contrib::fixed_buffer_queue<value_type_t<urng_t>> * buffer_ptr =
nullptr;
181 mutable value_type_t<urng_t> cached_value;
191 using difference_type = difference_type_t<urng_iterator_type>;
194 using value_type = value_type_t<urng_iterator_type>;
196 using pointer = value_type *;
198 using reference = value_type &;
200 using iterator_category = void;
209 async_input_buffer_iterator() =
default;
211 async_input_buffer_iterator(async_input_buffer_iterator
const & rhs) =
default;
212 async_input_buffer_iterator(async_input_buffer_iterator && rhs) =
default;
214 async_input_buffer_iterator & operator=(async_input_buffer_iterator
const & rhs) =
default;
215 async_input_buffer_iterator & operator=(async_input_buffer_iterator && rhs) =
default;
216 ~async_input_buffer_iterator() noexcept = default;
219 async_input_buffer_iterator(contrib::fixed_buffer_queue<
value_type_t<urng_t>> & buffer) noexcept :
229 reference operator*() const noexcept
236 pointer operator->() const noexcept
245 async_input_buffer_iterator & operator++() noexcept
251 assert(buffer_ptr !=
nullptr);
253 if (buffer_ptr->wait_pop(cached_value) == contrib::queue_op_status::closed)
260 void operator++(
int) noexcept
269 friend constexpr
bool operator==(async_input_buffer_iterator
const & lhs,
271 std::ranges::default_sentinel_t
const &) noexcept
277 friend constexpr
bool operator==(std::ranges::default_sentinel_t
const &,
278 async_input_buffer_iterator
const & rhs) noexcept
280 return rhs == std::ranges::default_sentinel_t{};
284 friend constexpr
bool operator!=(async_input_buffer_iterator
const & lhs,
285 std::ranges::default_sentinel_t
const &) noexcept
287 return !(lhs == std::ranges::default_sentinel_t{});
291 friend constexpr
bool operator!=(std::ranges::default_sentinel_t
const &,
292 async_input_buffer_iterator
const & rhs) noexcept
294 return rhs != std::ranges::default_sentinel_t{};
304 template <std::ranges::viewable_range urng_t>
306 async_input_buffer_view(urng_t &&,
size_t const buffer_size) -> async_input_buffer_view<std::ranges::all_view<urng_t>>;
314 struct async_input_buffer_fn
317 constexpr
auto operator()(
size_t const buffer_size)
const
319 return detail::adaptor_from_functor{*
this, buffer_size};
327 template <std::ranges::range urng_t>
328 constexpr
auto operator()(urng_t && urange,
size_t const buffer_size)
const
330 static_assert(std::ranges::input_range<urng_t>,
331 "The range parameter to views::async_input_buffer must be at least an std::ranges::InputRange.");
332 static_assert(std::ranges::viewable_range<urng_t>,
333 "The range parameter to views::async_input_buffer cannot be a temporary of a non-view range.");
335 "The range parameter to views::async_input_buffer must have a value_type that is std::Movable.");
337 "The range parameter to views::async_input_buffer must have a value_type that is constructible by a moved "
338 "value of its reference type.");
340 if (buffer_size == 0)
343 return detail::async_input_buffer_view{std::forward<urng_t>(urange), buffer_size};