SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
alignment_matrix_column_major_range_base.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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 <cassert>
16#include <iterator>
17#include <ranges>
18#include <span>
19
22
23namespace seqan3::detail
24{
25
61template <typename derived_t>
62class alignment_matrix_column_major_range_base
63{
64private:
66 friend derived_t;
67
77 class alignment_column_type : public std::ranges::view_interface<alignment_column_type>
78 {
79 private:
81 using view_type = typename deferred_type<typename derived_t::column_data_view_type>::type;
82
83 static_assert(std::ranges::random_access_range<view_type>, "Column view must support random access.");
84 static_assert(std::ranges::sized_range<view_type>, "Column view must be a sized range.");
85 static_assert(std::ranges::view<view_type>, "Column view must be a view.");
86
88 using sentinel = std::ranges::sentinel_t<view_type>;
89
99 class iterator_type
100 {
101 public:
106 using value_type = typename deferred_type<typename derived_t::value_type>::type;
108 using reference = typename deferred_type<typename derived_t::reference>::type;
110 using pointer = void;
112 using difference_type = std::ranges::range_difference_t<view_type>;
114 using iterator_category = std::forward_iterator_tag;
116
120 constexpr iterator_type() = default;
121 constexpr iterator_type(iterator_type const &) = default;
122 constexpr iterator_type(iterator_type &&) = default;
123 constexpr iterator_type & operator=(iterator_type const &) = default;
124 constexpr iterator_type & operator=(iterator_type &&) = default;
125 ~iterator_type() = default;
126
130 explicit constexpr iterator_type(alignment_column_type & host) :
131 host_ptr{&host},
132 host_iter{host.ref.begin()}
133 {
134 host_ptr->me_ptr->on_column_iterator_creation(host_iter);
135 }
137
142 constexpr reference operator*() const noexcept
143 {
144 static_assert(std::convertible_to<decltype(host_ptr->me_ptr->make_proxy(host_iter)), reference>,
145 "The returned type of make_proxy must be convertible to the reference type.");
146 assert(host_ptr != nullptr);
147 return host_ptr->me_ptr->make_proxy(host_iter);
148 }
150
155 constexpr iterator_type & operator++() noexcept
156 {
157 assert(host_ptr != nullptr);
158 assert(host_ptr->me_ptr != nullptr);
159
160 host_ptr->me_ptr->before_column_iterator_increment(host_iter);
161 ++host_iter;
162 host_ptr->me_ptr->after_column_iterator_increment(host_iter);
163 return *this;
164 }
165
167 constexpr iterator_type operator++(int) noexcept
168 {
169 iterator_type tmp{*this};
170 ++(*this);
171 return tmp;
172 }
174
179 constexpr bool operator==(sentinel const & rhs) const noexcept
180 {
181 return host_iter == rhs;
182 }
183
185 friend constexpr bool operator==(sentinel const & lhs, iterator_type const & rhs) noexcept
186 {
187 return rhs == lhs;
188 }
189
191 constexpr bool operator==(iterator_type const & rhs) const noexcept
192 {
193 return (host_ptr == rhs.host_ptr) && (host_iter == rhs.host_iter);
194 }
195
197 constexpr bool operator!=(sentinel const & rhs) const noexcept
198 {
199 return !(*this == rhs);
200 }
201
203 friend constexpr bool operator!=(sentinel const & lhs, iterator_type const & rhs) noexcept
204 {
205 return rhs != lhs;
206 }
207
209 constexpr bool operator!=(iterator_type const & rhs) const noexcept
210 {
211 return !(*this == rhs);
212 }
214
215 private:
217 alignment_column_type * host_ptr{nullptr};
219 std::ranges::iterator_t<view_type> host_iter{};
220 }; // class iterator_type
221
222 public:
226 constexpr alignment_column_type() = default;
227 constexpr alignment_column_type(alignment_column_type const &) = default;
228 constexpr alignment_column_type(alignment_column_type &&) = default;
229 constexpr alignment_column_type & operator=(alignment_column_type const &) = default;
230 constexpr alignment_column_type & operator=(alignment_column_type &&) = default;
231 ~alignment_column_type() = default;
232
241 constexpr alignment_column_type(derived_t & me, view_type ref) : ref{std::move(ref)}, me_ptr{&me}
242 {}
244
250 constexpr iterator_type begin() noexcept
251 {
252 assert(me_ptr != nullptr);
253 return iterator_type{*this};
254 }
255
257 constexpr auto begin() const noexcept = delete; // Not needed by the alignment algorithm
258
260 constexpr sentinel end() noexcept
261 {
262 return ref.end();
263 }
264
266 constexpr sentinel end() const noexcept = delete; // Not needed by the alignment algorithm
268
270 constexpr size_t size() const noexcept
271 {
272 return std::ranges::size(ref);
273 }
274
275 private:
277 view_type ref{};
279 derived_t * me_ptr{};
280 }; // class alignment_column_type
281
294 class iterator_type
295 {
296 public:
301 using value_type = alignment_column_type;
303 using reference = value_type;
305 using pointer = void;
307 using difference_type = std::ranges::range_difference_t<alignment_column_type>;
309 using iterator_category = std::input_iterator_tag;
311
315 constexpr iterator_type() = default;
316 constexpr iterator_type(iterator_type const &) = default;
317 constexpr iterator_type(iterator_type &&) = default;
318 constexpr iterator_type & operator=(iterator_type const &) = default;
319 constexpr iterator_type & operator=(iterator_type &&) = default;
320 ~iterator_type() = default;
321
325 explicit constexpr iterator_type(derived_t & me) : me_ptr{&me}, column_index{0}
326 {}
328
333 constexpr reference operator*() const noexcept
334 {
335 static_assert(std::convertible_to<decltype(me_ptr->initialise_column(column_index)), reference>,
336 "The returned type of initialise_column must be convertible to the reference type.");
337 return me_ptr->initialise_column(column_index);
338 }
340
345 constexpr iterator_type & operator++() noexcept
346 {
347 ++column_index;
348 return *this;
349 }
350
352 constexpr void operator++(int) noexcept
353 {
354 ++(*this);
355 }
357
362 constexpr bool operator==(std::default_sentinel_t const &) const noexcept
363 {
364 return column_index == me_ptr->num_cols;
365 }
366
368 friend constexpr bool operator==(std::default_sentinel_t const & lhs, iterator_type const & rhs) noexcept
369 {
370 return rhs == lhs;
371 }
372
374 constexpr bool operator!=(std::default_sentinel_t const & rhs) const noexcept
375 {
376 return !(*this == rhs);
377 }
378
380 friend constexpr bool operator!=(std::default_sentinel_t const & lhs, iterator_type const & rhs) noexcept
381 {
382 return rhs != lhs;
383 }
385
386 private:
388 derived_t * me_ptr;
390 size_t column_index{};
391 }; // class iterator_type
392
397 constexpr alignment_matrix_column_major_range_base() = default;
399 constexpr alignment_matrix_column_major_range_base(alignment_matrix_column_major_range_base const &) = default;
401 constexpr alignment_matrix_column_major_range_base(alignment_matrix_column_major_range_base &&) = default;
403 constexpr alignment_matrix_column_major_range_base &
404 operator=(alignment_matrix_column_major_range_base const &) = default;
406 constexpr alignment_matrix_column_major_range_base &
407 operator=(alignment_matrix_column_major_range_base &&) = default;
409 ~alignment_matrix_column_major_range_base() = default;
411
419 SEQAN3_DOXYGEN_ONLY(typedef /*IMPLEMENTATION_DEFINED*/ value_type;)
420
424 SEQAN3_DOXYGEN_ONLY(typedef /*IMPLEMENTATION_DEFINED*/ column_data_view_type;)
426
436 SEQAN3_DOXYGEN_ONLY(value_type make_proxy(iter_t host_iter) noexcept {})
437
450 SEQAN3_DOXYGEN_ONLY(alignment_column_type initialise_column(size_t column_index){})
451
456 template <typename iter_t>
457 constexpr void on_column_iterator_creation(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
458 {}
459
464 template <typename iter_t>
465 constexpr void before_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
466 {}
467
472 template <typename iter_t>
473 constexpr void after_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
474 {}
476
478 using iterator = iterator_type;
480 using sentinel = std::default_sentinel_t;
481
482public:
488 constexpr iterator begin() noexcept
489 {
490 return iterator{static_cast<derived_t &>(*this)};
491 }
492
494 constexpr iterator begin() const noexcept = delete; // not needed for the alignment algorithm
495
497 constexpr sentinel end() noexcept
498 {
499 return std::default_sentinel;
500 }
501
503 constexpr sentinel end() const noexcept = delete; // not needed for the alignment algorithm
505};
506} // namespace seqan3::detail
Provides various type traits on generic types.
T begin(T... args)
Provides various transformation traits used by the range module.
T end(T... args)
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:146
T move(T... args)
SeqAn specific customisations in the standard namespace.
T operator!=(T... args)
T ref(T... args)