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;
208 async_input_buffer_iterator() noexcept = default;
210 async_input_buffer_iterator(async_input_buffer_iterator const & rhs) noexcept = default;
211 async_input_buffer_iterator(async_input_buffer_iterator && rhs) noexcept = default;
213 async_input_buffer_iterator & operator=(async_input_buffer_iterator const & rhs) noexcept = default;
214 async_input_buffer_iterator & operator=(async_input_buffer_iterator && rhs) noexcept = default;
215 ~async_input_buffer_iterator() noexcept = default;
218 async_input_buffer_iterator(contrib::fixed_buffer_queue<
value_type_t<urng_t>> & buffer) noexcept :
228 reference operator*() const noexcept
235 pointer operator->() const noexcept
244 async_input_buffer_iterator & operator++() noexcept
250 assert(buffer_ptr !=
nullptr);
252 if (buffer_ptr->wait_pop(cached_value) == contrib::queue_op_status::closed)
259 void operator++(
int) noexcept
268 friend constexpr
bool operator==(async_input_buffer_iterator
const & lhs,
270 std::ranges::default_sentinel_t
const &) noexcept
276 friend constexpr
bool operator==(std::ranges::default_sentinel_t
const &,
277 async_input_buffer_iterator
const & rhs) noexcept
279 return rhs == std::ranges::default_sentinel_t{};
283 friend constexpr
bool operator!=(async_input_buffer_iterator
const & lhs,
284 std::ranges::default_sentinel_t
const &) noexcept
286 return !(lhs == std::ranges::default_sentinel_t{});
290 friend constexpr
bool operator!=(std::ranges::default_sentinel_t
const &,
291 async_input_buffer_iterator
const & rhs) noexcept
293 return rhs != std::ranges::default_sentinel_t{};
303 template <std::ranges::viewable_range urng_t>
305 async_input_buffer_view(urng_t &&,
size_t const buffer_size) -> async_input_buffer_view<std::ranges::all_view<urng_t>>;
313 struct async_input_buffer_fn
316 constexpr
auto operator()(
size_t const buffer_size)
const
318 return detail::adaptor_from_functor{*
this, buffer_size};
326 template <std::ranges::range urng_t>
327 constexpr
auto operator()(urng_t && urange,
size_t const buffer_size)
const
329 static_assert(std::ranges::input_range<urng_t>,
330 "The range parameter to views::async_input_buffer must be at least an std::ranges::InputRange.");
331 static_assert(std::ranges::viewable_range<urng_t>,
332 "The range parameter to views::async_input_buffer cannot be a temporary of a non-view range.");
334 "The range parameter to views::async_input_buffer must have a value_type that is std::Movable.");
336 "The range parameter to views::async_input_buffer must have a value_type that is constructible by a moved "
337 "value of its reference type.");
339 if (buffer_size == 0)
342 return detail::async_input_buffer_view{std::forward<urng_t>(urange), buffer_size};