SeqAn3  3.0.3
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 
22 namespace seqan3::detail
23 {
24 
36 template <simd_concept index_simd_t>
37 class counted_simd_iterator
38 {
39 private:
41  index_simd_t count_simd{};
42 
43 public:
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 
140 template <simd_concept index_simd_t>
141 class iota_simd_view : public std::ranges::view_interface<iota_simd_view<index_simd_t>>
142 {
143 private:
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 
154 public:
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 
197 template <simd_concept index_simd_t>
198 struct 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 
217 namespace seqan3::views
218 {
219 
273 template <simd_concept index_simd_t>
274 inline constexpr detail::iota_simd_view_fn<index_simd_t> iota_simd{};
275 
276 } // namespace seqan3::views
277 
278 namespace ranges
279 {
281 template <seqan3::simd_concept index_simd_t>
282 inline constexpr bool enable_borrowed_range<seqan3::detail::iota_simd_view<index_simd_t>> = true;
284 } // namespace ranges
285 
286 #ifdef __cpp_lib_ranges
287 namespace std::ranges
288 {
290 template <seqan3::simd_concept index_simd_t>
291 inline 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)
T end(T... args)
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
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)
Adaptations of concepts from the Ranges TS.
Provides seqan3::simd::simd_concept.
Provides seqan3::simd::simd_traits.