SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
iota_simd.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, 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 <seqan3/std/ranges>
16
21
22namespace seqan3::detail
23{
24
36template <simd_concept index_simd_t>
37class counted_simd_iterator
38{
39private:
41 index_simd_t count_simd{};
42
43public:
48 using value_type = index_simd_t;
50 using reference = value_type;
52 using pointer = void;
54 using difference_type = std::ptrdiff_t;
56 using iterator_category = std::forward_iterator_tag;
58
62 counted_simd_iterator() = default;
63 counted_simd_iterator(counted_simd_iterator const &) = default;
64 counted_simd_iterator(counted_simd_iterator &&) = default;
65 counted_simd_iterator & operator=(counted_simd_iterator const &) = default;
66 counted_simd_iterator & operator=(counted_simd_iterator &&) = default;
67 ~counted_simd_iterator() = default;
68
75 template <arithmetic index_scalar_t>
76 explicit counted_simd_iterator(index_scalar_t const scalar_index) noexcept :
77 count_simd{simd::fill<index_simd_t>(scalar_index)}
78 {}
80
86 reference operator*() const
87 {
88 return count_simd;
89 }
91
97 counted_simd_iterator & operator++()
98 {
99 count_simd += seqan3::simd::fill<index_simd_t>(1);
100 return *this;
101 }
102
104 counted_simd_iterator operator++(int)
105 {
106 counted_simd_iterator tmp{*this};
107 ++(*this);
108 return tmp;
109 }
110
112 difference_type operator-(counted_simd_iterator const & rhs) const
113 {
114 return count_simd[0] - rhs.count_simd[0];
115 }
117
123 friend bool operator==(counted_simd_iterator const & lhs, counted_simd_iterator const & rhs) noexcept
124 {
125 return lhs.count_simd[0] == rhs.count_simd[0];
126 }
127
129 friend bool operator!=(counted_simd_iterator const & lhs, counted_simd_iterator const & rhs) noexcept
130 {
131 return !(lhs == rhs);
132 }
134};
135
140template <simd_concept index_simd_t>
141class iota_simd_view : public std::ranges::view_interface<iota_simd_view<index_simd_t>>
142{
143private:
145 using index_scalar_type = typename simd_traits<index_simd_t>::scalar_type;
147 using iterator_type = seqan3::detail::counted_simd_iterator<index_simd_t>;
148
150 index_scalar_type begin_index{};
152 index_scalar_type end_index{};
153
154public:
158 iota_simd_view() = default;
159 iota_simd_view(iota_simd_view const &) noexcept = default;
160 iota_simd_view(iota_simd_view &&) = default;
161 iota_simd_view & operator=(iota_simd_view const &) = default;
162 iota_simd_view & operator=(iota_simd_view &&) = default;
163 ~iota_simd_view() = default;
164
170 iota_simd_view(index_scalar_type const begin_index, index_scalar_type const end_index) :
171 begin_index{begin_index},
172 end_index{end_index}
173 {}
175
180 iterator_type begin() const noexcept
181 {
182 return iterator_type{begin_index};
183 }
184
186 iterator_type end() const noexcept
187 {
188 return iterator_type{end_index};
189 }
191};
192
197template <simd_concept index_simd_t>
198struct iota_simd_view_fn
199{
201 using index_scalar_type = typename simd_traits<index_simd_t>::scalar_type;
202
210 constexpr auto operator()(index_scalar_type const begin_index, index_scalar_type const end_index) const
211 {
212 return iota_simd_view<index_simd_t>{begin_index, end_index};
213 }
214};
215} // namespace seqan3::detail
216
217namespace seqan3::views
218{
219
273template <simd_concept index_simd_t>
274inline constexpr detail::iota_simd_view_fn<index_simd_t> iota_simd{};
275
276} // namespace seqan3::views
277
278namespace ranges
279{
281template <seqan3::simd_concept index_simd_t>
282inline constexpr bool enable_borrowed_range<seqan3::detail::iota_simd_view<index_simd_t>> = true;
284} // namespace ranges
285
286#ifdef __cpp_lib_ranges
287namespace std::ranges
288{
290template <seqan3::simd_concept index_simd_t>
291inline constexpr bool enable_borrowed_range<seqan3::detail::iota_simd_view<index_simd_t>> = true;
293} // namespace std::ranges
294#endif // __cpp_lib_ranges
Provides algorithms to modify seqan3::simd::simd_type.
T begin(T... args)
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
T end(T... args)
The SeqAn namespace for views.
Definition: char_to.hpp:22
constexpr detail::iota_simd_view_fn< index_simd_t > iota_simd
An iota view over a simd vector.
Definition: iota_simd.hpp:274
T operator!=(T... args)
The <ranges> header from C++20's standard library.
Provides seqan3::simd::simd_traits.
Provides seqan3::simd::simd_concept.