BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
single_pass_input.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2022 deCODE Genetics
3// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
4// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
5// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
6// shipped with this file and also available at: https://github.com/biocpp/biocpp-core/blob/main/LICENSE.md
7// -----------------------------------------------------------------------------------------------------
8
14#pragma once
15
16#include <cassert>
17#include <concepts>
18#include <iterator>
19#include <memory>
20#include <ranges>
21
23
24//-----------------------------------------------------------------------------
25// Implementation of single pass input view.
26//-----------------------------------------------------------------------------
27
28namespace bio::ranges::detail
29{
30
32template <typename view_t>
33class basic_iterator;
34
41template <std::ranges::view urng_t>
42class single_pass_input_view : public std::ranges::view_interface<single_pass_input_view<urng_t>>
43{
45private:
47 using urng_iterator_type = std::ranges::iterator_t<urng_t>;
48
50 template <typename view_t>
51 friend class basic_iterator;
52
54 struct state
55 {
57 urng_t urng;
59 urng_iterator_type cached_urng_iter = std::ranges::begin(urng);
60 };
61
63 std::shared_ptr<state> state_ptr{};
64
69 using iterator = basic_iterator<single_pass_input_view>;
71 using sentinel = std::ranges::sentinel_t<urng_t>;
72 //\}
73
74public:
80 constexpr single_pass_input_view() = default;
82 constexpr single_pass_input_view(single_pass_input_view const &) = default;
84 constexpr single_pass_input_view(single_pass_input_view &&) noexcept = default;
86 constexpr single_pass_input_view & operator=(single_pass_input_view const &) = default;
88 constexpr single_pass_input_view & operator=(single_pass_input_view &&) noexcept = default;
90 ~single_pass_input_view() = default;
91
93 explicit single_pass_input_view(urng_t _urng) : state_ptr{new state{std::move(_urng)}} {}
94
96 template <meta::different_from<single_pass_input_view> other_urng_t>
97 requires(std::ranges::viewable_range<other_urng_t> &&
98 std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<other_urng_t>>>)
99 explicit single_pass_input_view(other_urng_t && _urng) : single_pass_input_view{std::views::all(_urng)}
100 {}
102
113 iterator begin() { return {*this}; }
114
116 iterator begin() const = delete;
117
119 sentinel end() { return {std::ranges::end(state_ptr->urng)}; }
120
122 sentinel end() const = delete;
124};
125
132template <std::ranges::viewable_range urng_t>
133single_pass_input_view(urng_t &&) -> single_pass_input_view<std::views::all_t<urng_t>>;
135} // namespace bio::ranges::detail
136
137//-----------------------------------------------------------------------------
138// Iterator for single pass input view.
139//-----------------------------------------------------------------------------
140
141namespace bio::ranges::detail
142{
150template <typename view_type>
151class basic_iterator<single_pass_input_view<view_type>>
152{
154 using base_iterator_type = typename single_pass_input_view<view_type>::urng_iterator_type;
156 using sentinel_type = typename single_pass_input_view<view_type>::sentinel;
157
159 single_pass_input_view<view_type> * view_ptr{};
160
162 template <typename input_view_type>
163 friend class basic_iterator;
164
166 static_assert(std::sentinel_for<sentinel_type, base_iterator_type>);
167
168public:
173 using difference_type = std::iter_difference_t<base_iterator_type>;
175 using value_type = std::iter_value_t<base_iterator_type>;
177 using pointer = detail::iter_pointer_t<base_iterator_type>;
181 using iterator_category = std::input_iterator_tag;
183
188 basic_iterator() noexcept = default;
190 constexpr basic_iterator(basic_iterator const & rhs) noexcept = default;
192 constexpr basic_iterator(basic_iterator && rhs) noexcept = default;
194 constexpr basic_iterator & operator=(basic_iterator const & rhs) noexcept = default;
196 constexpr basic_iterator & operator=(basic_iterator && rhs) noexcept = default;
198 ~basic_iterator() noexcept = default;
199
201 basic_iterator(single_pass_input_view<view_type> & view) noexcept : view_ptr{&view} {}
203
208 reference operator*() const noexcept { return *cached(); }
209
211 pointer operator->() const noexcept
212 requires(!std::is_void_v<pointer>)
213 {
214 return std::addressof(*cached());
215 }
217
222 basic_iterator & operator++() noexcept
223 {
224 ++cached();
225 return *this;
226 }
227
229 auto operator++(int) noexcept
230 {
231 if constexpr (std::output_iterator<base_iterator_type, reference> &&
232 std::copy_constructible<base_iterator_type>)
233 {
234 basic_iterator tmp{*this};
235 ++(*this);
236 return tmp;
237 }
238 else
239 {
240 ++(*this);
241 }
242 }
244
249 constexpr bool operator==(sentinel_type const & s) const noexcept { return cached() == s; }
250
252 friend constexpr bool operator==(sentinel_type const & s, basic_iterator const & rhs) noexcept { return rhs == s; }
254
255protected:
258 base_iterator_type & cached() const noexcept
259 {
260 assert(view_ptr != nullptr);
261 assert(view_ptr->state_ptr != nullptr);
262 return view_ptr->state_ptr->cached_urng_iter;
263 }
264};
265} // namespace bio::ranges::detail
266
267//-----------------------------------------------------------------------------
268// View shortcut for functor.
269//-----------------------------------------------------------------------------
270
272namespace bio::ranges::views
273{
325inline constexpr auto single_pass_input = detail::adaptor_for_view_without_args<detail::single_pass_input_view>{};
326
328} // namespace bio::ranges::views
T addressof(T... args)
T begin(T... args)
T end(T... args)
constexpr auto single_pass_input
A view adapter that decays most of the range properties and adds single pass behavior.
Definition: single_pass_input.hpp:325
The BioC++ namespace for views.
Auxiliary header for the views submodule .