SeqAn3 3.2.0-rc.1
The Modern C++ library for sequence analysis.
gap_decorator.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
14#pragma once
15
16#include <algorithm>
17#include <limits>
18#include <seqan3/std/ranges>
19#include <set>
20#include <tuple>
21#include <type_traits>
22
28
29namespace seqan3
30{
31
77template <std::ranges::viewable_range inner_type>
79 requires std::ranges::random_access_range<inner_type> && std::ranges::sized_range<inner_type> &&
80 (std::is_const_v<std::remove_reference_t<inner_type>> || std::ranges::view<inner_type>)
83{
84private:
85 // Declaration of class's iterator types; for the definition see below.
86 template <bool = true>
87 class basic_iterator;
88
94
96 using ungapped_view_type = decltype(views::type_reduce(std::declval<inner_type &&>()));
97
98public:
107
113
120
125 using size_type = std::ranges::range_size_t<inner_type>;
126
131 using difference_type = std::ranges::range_difference_t<inner_type>;
133
138 using unaligned_sequence_type = inner_type;
139
150 gap_decorator() = default;
151 gap_decorator(gap_decorator const &) = default;
152 gap_decorator & operator=(gap_decorator const &) = default;
153 gap_decorator(gap_decorator && rhs) = default;
155 ~gap_decorator() = default;
156
161 template <typename other_range_t>
163 requires (!std::same_as<other_range_t, gap_decorator>) &&
165 std::ranges::viewable_range<other_range_t> // at end, otherwise it competes with the move ctor
167 gap_decorator(other_range_t && range) : ungapped_view{views::type_reduce(std::forward<inner_type>(range))}
168 {} // TODO (@smehringer) only works for copyable views. Has to be changed once views are not required to be copyable anymore.
169 // !\}
170
185 {
186 if (anchors.size())
187 return anchors.rbegin()->second + ungapped_view.size();
188
189 return ungapped_view.size();
190 }
191
208 {
209 if (!count) // [[unlikely]]
210 return it;
211
212 size_type const pos = it - begin();
213 assert(pos <= size());
214
215 set_iterator_type it_set = anchors.upper_bound(anchor_gap_t{pos, bound_dummy});
216
217 if (it_set == anchors.begin()) // will also catch if anchors is empty since begin() == end()
218 {
219 anchors.emplace_hint(anchors.begin(), anchor_gap_t{pos, count});
220 }
221 else // there are gaps before pos
222 {
223 --it_set;
224 auto gap_len{it_set->second};
225 if (it_set != anchors.begin())
226 gap_len -= (*(std::prev(it_set))).second;
227
228 if (it_set->first + gap_len >= pos) // extend existing gap
229 {
230 anchor_gap_t gap{it_set->first, it_set->second + count};
231 it_set = anchors.erase(it_set);
232 anchors.insert(it_set, gap);
233 }
234 else // insert new gap
235 {
236 anchor_gap_t gap{pos, it_set->second + count};
237 ++it_set;
238 anchors.insert(it_set, gap);
239 }
240 }
241
242 // post-processing: reverse update of succeeding gaps
243 rupdate(pos, count);
244 return iterator{*this, pos};
245 }
246
261 {
262 // check if [it, it+gap_len[ covers [first, last[
263 if ((*it) != gap{}) // [[unlikely]]
264 throw gap_erase_failure("The range to be erased does not correspond to a consecutive gap.");
265
266 return erase_gap(it, std::next(it));
267 }
268
285 {
286 size_type const pos1 = first - begin();
287 size_type const pos2 = last - begin();
288 set_iterator_type it = anchors.upper_bound(anchor_gap_t{pos1, bound_dummy}); // first element greater than pos1
289
290 if (it == anchors.begin())
291 throw gap_erase_failure{"There is no gap to erase in range [" + std::to_string(pos1) + "," +
292 std::to_string(pos2) + "]."};
293
294 --it;
295 size_type const gap_len = gap_length(it);
296
297 // check if [it, it+gap_len[ covers [first, last[
298 if ((it->first + gap_len) < pos2) // [[unlikely]]
299 {
300 throw gap_erase_failure{"The range to be erased does not correspond to a consecutive gap."};
301 }
302 // case 1: complete gap is deleted
303 else if (gap_len == pos2 - pos1)
304 {
305 it = anchors.erase(it);
306 }
307 // case 2: gap to be deleted in tail or larger than 1 (equiv. to shift tail left, i.e. pos remains unchanged)
308 else
309 {
310 anchor_gap_t gap{it->first, it->second - pos2 + pos1};
311 it = anchors.erase(it);
312 it = anchors.insert(it, gap); // amortized constant because of hint
313 ++it; // update node after the current
314 }
315
316 // post-processing: forward update of succeeding gaps
317 update(it, pos2 - pos1);
318
319 return iterator{*this, pos1};
320 }
321
329 template <typename unaligned_sequence_t> // generic template to use forwarding reference
331 requires std::assignable_from<gap_decorator &, unaligned_sequence_t>
333 friend void assign_unaligned(gap_decorator & dec, unaligned_sequence_t && unaligned)
334 {
335 dec = unaligned;
336 }
338
357 const_iterator begin() const noexcept
358 {
359 return iterator{*this};
360 }
361
363 const_iterator cbegin() const noexcept
364 {
365 return const_iterator{*this};
366 }
367
383 const_iterator end() const noexcept
384 {
385 return iterator{*this, size()};
386 }
387
389 const_iterator cend() const noexcept
390 {
391 return const_iterator{*this, size()};
392 }
394
413 {
414 if (i >= size()) // [[unlikely]]
415 throw std::out_of_range{"Trying to access element behind the last in gap_decorator."};
416 return (*this)[i];
417 }
418
421 {
422 if (i >= size()) // [[unlikely]]
423 throw std::out_of_range{"Trying to access element behind the last in gap_decorator."};
424 return (*this)[i];
425 }
426
440 {
441 return *iterator{*this, i};
442 }
444
468 friend bool operator==(gap_decorator const & lhs, gap_decorator const & rhs)
469 {
470 if (lhs.size() == rhs.size() &&
471 lhs.anchors == rhs.anchors &&
472 std::ranges::equal(lhs.ungapped_view, rhs.ungapped_view))
473 {
474 return true;
475 }
476
477 return false;
478 }
479
484 friend bool operator!=(gap_decorator const & lhs, gap_decorator const & rhs)
485 {
486 return !(lhs == rhs);
487 }
488
493 friend bool operator<(gap_decorator const & lhs, gap_decorator const & rhs)
494 {
495 auto lit = lhs.begin();
496 auto rit = rhs.begin();
497
498 while (lit != lhs.end() && rit != rhs.end() && *lit == *rit)
499 ++lit, ++rit;
500
501 if (rit == rhs.end())
502 return false; // lhs == rhs, or rhs prefix of lhs
503 else if (lit == lhs.end())
504 return true; // lhs prefix of rhs
505
506 return *lit < *rit;
507 }
508
513 friend bool operator<=(gap_decorator const & lhs, gap_decorator const & rhs)
514 {
515 auto lit = lhs.begin();
516 auto rit = rhs.begin();
517
518 while (lit != lhs.end() && rit != rhs.end() && *lit == *rit)
519 ++lit, ++rit;
520
521 if (lit == lhs.end())
522 return true; // lhs == rhs, or lhs prefix of rhs
523 else if (rit == rhs.end())
524 return false; // rhs prefix of lhs
525
526 return *lit < *rit;
527 }
528
533 friend bool operator>(gap_decorator const & lhs, gap_decorator const & rhs)
534 {
535 return !(lhs <= rhs);
536 }
537
542 friend bool operator>=(gap_decorator const & lhs, gap_decorator const & rhs)
543 {
544 return !(lhs < rhs);
545 }
547
548private:
551
554
556 using set_iterator_type = typename anchor_set_type::iterator;
557
559 constexpr static size_t bound_dummy{std::numeric_limits<size_t>::max()};
560
574 {
575 return (it == anchors.begin()) ? it->second : it->second - (*std::prev(it)).second;
576 }
577
590 void rupdate(size_type const pos, size_type const offset)
591 {
592 for (auto it = std::prev(anchors.end(), 1); it->first > pos;)
593 {
594 anchors.emplace_hint(it, anchor_gap_t{it->first + offset, it->second + offset});
595 anchors.erase(*it--);
596 }
597 }
598
611 void update(set_iterator_type it, size_type const offset)
612 {
613 while (it != anchors.end())
614 {
615 anchor_gap_t gap{it->first - offset, it->second - offset};
616 it = anchors.erase(it);
617 it = anchors.insert(it, gap);
618 ++it;
619 }
620 }
621
623 ungapped_view_type ungapped_view{};
624
627};
628
636template <std::ranges::viewable_range urng_t>
638 requires (!std::ranges::view<std::remove_reference_t<urng_t>>)
641
646template <std::ranges::view urng_t>
649
666template <std::ranges::viewable_range inner_type>
668 requires std::ranges::random_access_range<inner_type> && std::ranges::sized_range<inner_type> &&
669 (std::is_const_v<std::remove_reference_t<inner_type>> || std::ranges::view<inner_type>)
671template <bool>
673{
674protected:
678 typename gap_decorator::size_type pos{0u};
680 int64_t ungapped_view_pos{0}; // must be signed because we need this value to be -1 in case of leading gaps.
683 typename gap_decorator::size_type left_gap_end{0};
686 typename gap_decorator::set_iterator_type anchor_set_it{};
688 bool is_at_gap{true};
689
691 void jump(typename gap_decorator::size_type const new_pos)
692 {
693 assert(new_pos <= host->size());
694 pos = new_pos;
695
696 anchor_set_it = host->anchors.upper_bound(anchor_gap_t{pos, host->bound_dummy});
697 ungapped_view_pos = pos;
698
699 if (anchor_set_it != host->anchors.begin())
700 {
701 typename gap_decorator::set_iterator_type prev{std::prev(anchor_set_it)};
702 size_type gap_len{prev->second};
703
704 if (prev != host->anchors.begin())
705 gap_len -= std::prev(prev)->second;
706
707 ungapped_view_pos -= prev->second;
708 left_gap_end = prev->first + gap_len;
709 }
710
711 if (ungapped_view_pos != static_cast<int64_t>(host->ungapped_view.size()) &&
712 pos >= left_gap_end && (anchor_set_it == host->anchors.end() || pos < anchor_set_it->first))
713 is_at_gap = false;
714 else
715 is_at_gap = true;
716 }
717
718public:
733
737 basic_iterator() = default;
738 basic_iterator(basic_iterator const &) = default;
742 ~basic_iterator() = default;
743
745 explicit basic_iterator(gap_decorator const & host_) :
746 host(&host_), anchor_set_it{host_.anchors.begin()}
747 {
748 if (host_.anchors.size() && (*host_.anchors.begin()).first == 0) // there are gaps at the very front
749 {
750 --ungapped_view_pos; // set ungapped_view_pos to -1 so operator++ works without an extra if-branch.
751 left_gap_end = anchor_set_it->second;
752 ++anchor_set_it;
753 }
754 else
755 {
756 is_at_gap = false;
757 }
758 }
759
761 basic_iterator(gap_decorator const & host_, typename gap_decorator::size_type const pos_) : host(&host_)
762 {
763 jump(pos_); // random access to pos
764 }
766
772 {
773 assert(host); // host is set
774 ++pos;
775
776 if (pos < left_gap_end) // we stay within the preceding gap stretch
777 return *this;
778
779 if (anchor_set_it == host->anchors.end() || pos < anchor_set_it->first)
780 { // proceed within the view since we are right of the previous gap but didn't arrive at the right gap yet
781 ++ungapped_view_pos;
782 if (ungapped_view_pos != static_cast<int64_t>(host->ungapped_view.size()))
783 is_at_gap = false;
784 }
785 else
786 { // we arrived at the right gap and have to update the variables. ungapped_view_pos remains unchanged.
787 left_gap_end = anchor_set_it->first + anchor_set_it->second -
788 ((anchor_set_it != host->anchors.begin()) ? (std::prev(anchor_set_it))->second : 0);
789 ++anchor_set_it;
790 is_at_gap = true;
791
792 if (left_gap_end == host->size()) // very last gap
793 ++ungapped_view_pos;
794 }
795
796 return *this;
797 }
798
801 {
802 basic_iterator cpy{*this};
803 ++(*this);
804 return cpy;
805 }
806
809 {
810 this->jump(this->pos + skip);
811 return *this;
812 }
813
816 {
817 return basic_iterator{*(this->host), this->pos + skip};
818 }
819
822 {
823 return it + skip;
824 }
825
828 {
829 assert(host); // host is set
830 --pos;
831
832 if (pos < left_gap_end)
833 { // there was no gap before but we arrive at the left gap and have to update the variables.
834 (anchor_set_it != host->anchors.begin()) ? --anchor_set_it : anchor_set_it;
835
836 if (anchor_set_it != host->anchors.begin())
837 {
838 auto prev = std::prev(anchor_set_it);
839 left_gap_end = prev->first + prev->second -
840 ((prev != host->anchors.begin()) ? std::prev(prev)->second : 0);
841 }
842 else // [[unlikely]]
843 {
844 left_gap_end = 0;
845 }
846 is_at_gap = true;
847 }
848 else if (anchor_set_it == host->anchors.end() || pos < anchor_set_it->first)
849 { // we are neither at the left nor right gap
850 --ungapped_view_pos;
851 is_at_gap = false;
852 }
853 // else -> no op (we are still within the right gap stretch)
854
855 return *this;
856 }
857
860 {
861 basic_iterator cpy{*this};
862 --(*this);
863 return cpy;
864 }
865
868 {
869 this->jump(this->pos - skip);
870 return *this;
871 }
872
875 {
876 return basic_iterator{*(this->host), this->pos - skip};
877 }
878
881 {
882 return it - skip;
883 }
884
886 difference_type operator-(basic_iterator const lhs) const noexcept
887 {
888 return static_cast<difference_type>(this->pos - lhs.pos);
889 }
891
897 {
898 return (is_at_gap) ? reference{gap{}} : reference{host->ungapped_view[ungapped_view_pos]};
899 }
900
903 {
904 return *(*this + n);
905 }
907
914 friend bool operator==(basic_iterator const & lhs, basic_iterator const & rhs) noexcept
915 {
916 return lhs.pos == rhs.pos;
917 }
918
920 friend bool operator!=(basic_iterator const & lhs, basic_iterator const & rhs) noexcept
921 {
922 return lhs.pos != rhs.pos;
923 }
924
926 friend bool operator<(basic_iterator const & lhs, basic_iterator const & rhs) noexcept
927 {
928 return lhs.pos < rhs.pos;
929 }
930
932 friend bool operator>(basic_iterator const & lhs, basic_iterator const & rhs) noexcept
933 {
934 return lhs.pos > rhs.pos;
935 }
936
938 friend bool operator<=(basic_iterator const & lhs, basic_iterator const & rhs) noexcept
939 {
940 return lhs.pos <= rhs.pos;
941 }
942
944 friend bool operator>=(basic_iterator const & lhs, basic_iterator const & rhs) noexcept
945 {
946 return lhs.pos >= rhs.pos;
947 }
949};
950
951} // namespace seqan
Includes customized exception types for the alignment module .
Core alphabet concept and free function/type trait wrappers.
T begin(T... args)
A combined alphabet that can hold values of either of its alternatives..
Definition: alphabet_variant.hpp:120
The iterator type over a seqan3::gap_decorator.
Definition: gap_decorator.hpp:673
void jump(typename gap_decorator::size_type const new_pos)
A helper function that performs the random access into the anchor set, updating all member variables.
Definition: gap_decorator.hpp:691
friend bool operator<(basic_iterator const &lhs, basic_iterator const &rhs) noexcept
Checks whether *this is less than rhs.
Definition: gap_decorator.hpp:926
basic_iterator & operator++()
Increments iterator.
Definition: gap_decorator.hpp:771
typename gap_decorator::const_reference reference
The reference type.
Definition: gap_decorator.hpp:727
friend basic_iterator operator-(difference_type const skip, basic_iterator const &it)
Returns an iterator copy advanced by skip many positions.
Definition: gap_decorator.hpp:880
typename gap_decorator::value_type value_type
The value type.
Definition: gap_decorator.hpp:725
basic_iterator & operator=(basic_iterator const &)=default
Defaulted.
basic_iterator(gap_decorator const &host_, typename gap_decorator::size_type const pos_)
Construct from seqan3::gap_decorator and explicit position.
Definition: gap_decorator.hpp:761
basic_iterator operator--(int)
Returns a decremented iterator copy.
Definition: gap_decorator.hpp:859
basic_iterator(basic_iterator const &)=default
Defaulted.
friend bool operator>=(basic_iterator const &lhs, basic_iterator const &rhs) noexcept
Checks whether *this is greater than or equal to rhs.
Definition: gap_decorator.hpp:944
friend bool operator<=(basic_iterator const &lhs, basic_iterator const &rhs) noexcept
Checks whether *this is less than or equal to rhs.
Definition: gap_decorator.hpp:938
reference operator*() const
Dereference operator returns a copy of the element currently pointed at.
Definition: gap_decorator.hpp:896
reference operator[](difference_type const n) const
Return underlying container value currently pointed at.
Definition: gap_decorator.hpp:902
friend bool operator>(basic_iterator const &lhs, basic_iterator const &rhs) noexcept
Checks whether *this is greater than rhs.
Definition: gap_decorator.hpp:932
basic_iterator operator+(difference_type const skip) const
Returns an iterator copy advanced by skip many positions.
Definition: gap_decorator.hpp:815
basic_iterator operator++(int)
Returns an incremented iterator copy.
Definition: gap_decorator.hpp:800
basic_iterator operator-(difference_type const skip) const
Returns an iterator copy advanced by skip many positions.
Definition: gap_decorator.hpp:874
value_type * pointer
The pointer type.
Definition: gap_decorator.hpp:729
friend basic_iterator operator+(difference_type const skip, basic_iterator const &it)
Returns an iterator copy advanced by skip many positions.
Definition: gap_decorator.hpp:821
basic_iterator & operator=(basic_iterator &&)=default
Defaulted.
friend bool operator==(basic_iterator const &lhs, basic_iterator const &rhs) noexcept
Checks whether *this is equal to rhs.
Definition: gap_decorator.hpp:914
basic_iterator & operator+=(difference_type const skip)
Advances iterator by skip many positions.
Definition: gap_decorator.hpp:808
basic_iterator(gap_decorator const &host_)
Construct from seqan3::gap_decorator and initialising to first position.
Definition: gap_decorator.hpp:745
basic_iterator(basic_iterator &&)=default
Defaulted.
basic_iterator & operator--()
Decrements iterator.
Definition: gap_decorator.hpp:827
typename gap_decorator::difference_type difference_type
The difference type.
Definition: gap_decorator.hpp:723
basic_iterator & operator-=(difference_type const skip)
Advances iterator by skip many positions.
Definition: gap_decorator.hpp:867
difference_type operator-(basic_iterator const lhs) const noexcept
Returns the distance between two iterators.
Definition: gap_decorator.hpp:886
friend bool operator!=(basic_iterator const &lhs, basic_iterator const &rhs) noexcept
Checks whether *this is not equal to rhs.
Definition: gap_decorator.hpp:920
A gap decorator allows the annotation of sequences with gap symbols while leaving the underlying sequ...
Definition: gap_decorator.hpp:83
reference at(size_type const i)
Return the i-th element as a reference.
Definition: gap_decorator.hpp:412
friend bool operator==(gap_decorator const &lhs, gap_decorator const &rhs)
Checks whether lhs is equal to rhs.
Definition: gap_decorator.hpp:468
typename anchor_set_type::iterator set_iterator_type
The iterator type for an anchor set.
Definition: gap_decorator.hpp:556
gap_decorator & operator=(gap_decorator const &)=default
Defaulted.
gap_decorator(gap_decorator &&rhs)=default
Defaulted.
const_reference at(size_type const i) const
Return the i-th element as a reference.
Definition: gap_decorator.hpp:420
std::ranges::range_difference_t< inner_type > difference_type
The difference type of the underlying sequence.
Definition: gap_decorator.hpp:131
const_iterator cend() const noexcept
Returns an iterator pointing behind the last element of the decorator.
Definition: gap_decorator.hpp:389
const_iterator end() const noexcept
Returns an iterator pointing behind the last element of the decorator.
Definition: gap_decorator.hpp:383
typename std::pair< size_t, size_t > anchor_gap_t
The gap type as a tuple storing position and accumulated gap lengths.
Definition: gap_decorator.hpp:550
void rupdate(size_type const pos, size_type const offset)
Update all anchor gaps after the indicated position by adding an offset.
Definition: gap_decorator.hpp:590
inner_type unaligned_sequence_type
The underlying ungapped range type.
Definition: gap_decorator.hpp:138
gap_decorator(other_range_t &&range)
Construct with the ungapped range type.
Definition: gap_decorator.hpp:167
reference operator[](size_type const i) const
Return the i-th element as a reference.
Definition: gap_decorator.hpp:439
friend bool operator!=(gap_decorator const &lhs, gap_decorator const &rhs)
Checks whether lhs is not equal to rhs.
Definition: gap_decorator.hpp:484
iterator erase_gap(const_iterator const it)
Erase one gap symbol at the indicated iterator postion.
Definition: gap_decorator.hpp:260
const_iterator begin() const noexcept
Returns an iterator to the first element of the container.
Definition: gap_decorator.hpp:357
iterator insert_gap(const_iterator const it, size_type const count=1)
Insert a gap of length count at the aligned sequence iterator position.
Definition: gap_decorator.hpp:207
~gap_decorator()=default
Defaulted.
iterator erase_gap(const_iterator const first, const_iterator const last)
Erase gap symbols at the iterator postions [first, last[.
Definition: gap_decorator.hpp:284
gap_decorator(gap_decorator const &)=default
Defaulted.
friend bool operator<=(gap_decorator const &lhs, gap_decorator const &rhs)
Checks whether lhs is less than or equal to rhs.
Definition: gap_decorator.hpp:513
size_type size() const
Returns the total length of the aligned sequence.
Definition: gap_decorator.hpp:184
size_type gap_length(set_iterator_type it) const
Helper function to compute the length of the gap indicated by the input iterator.
Definition: gap_decorator.hpp:573
reference const_reference
const_reference type equals reference type equals value type because the underlying sequence must not...
Definition: gap_decorator.hpp:119
void update(set_iterator_type it, size_type const offset)
Update all anchor gaps after indicated position by substracting an offset.
Definition: gap_decorator.hpp:611
gap_decorator & operator=(gap_decorator &&rhs)=default
Defaulted.
gapped< std::ranges::range_value_t< inner_type > > value_type
The variant type of the alphabet type and gap symbol type (see seqan3::gapped).
Definition: gap_decorator.hpp:106
friend bool operator>(gap_decorator const &lhs, gap_decorator const &rhs)
Checks whether lhs is greater than rhs.
Definition: gap_decorator.hpp:533
friend bool operator>=(gap_decorator const &lhs, gap_decorator const &rhs)
Checks whether lhs is greater than or equal to rhs.
Definition: gap_decorator.hpp:542
gap_decorator()=default
Default constructor.
decltype(views::type_reduce(std::declval< inner_type && >())) ungapped_view_type
The type of the underlying view wrapped in seqan3::views::type_reduce.
Definition: gap_decorator.hpp:96
friend bool operator<(gap_decorator const &lhs, gap_decorator const &rhs)
Checks whether lhs is less than rhs.
Definition: gap_decorator.hpp:493
anchor_set_type anchors
Set storing the anchor gaps.
Definition: gap_decorator.hpp:626
std::ranges::range_size_t< inner_type > size_type
The size_type of the underlying sequence.
Definition: gap_decorator.hpp:125
friend void assign_unaligned(gap_decorator &dec, unaligned_sequence_t &&unaligned)
Assigns a new sequence of type seqan3::gap_decorator::unaligned_sequence_type to the decorator.
Definition: gap_decorator.hpp:333
ungapped_view_type ungapped_view
Stores a (copy of a) view to the ungapped, underlying sequence.
Definition: gap_decorator.hpp:623
const_iterator cbegin() const noexcept
Returns an iterator to the first element of the container.
Definition: gap_decorator.hpp:363
Thrown in function seqan3::erase_gap, if a position does not contain a gap.
Definition: exception.hpp:24
The alphabet of a gap character '-'.
Definition: gap.hpp:39
Provides seqan3::gap.
Provides seqan3::gapped.
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:169
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:151
constexpr auto type_reduce
A view adaptor that behaves like std::views::all, but type erases certain ranges.
Definition: type_reduce.hpp:153
T max(T... args)
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
gap_decorator(urng_t &&range) -> gap_decorator< std::remove_reference_t< urng_t > const & >
Ranges (not views!) always deduce to const & range_type since they are access-only anyway.
T next(T... args)
T prev(T... args)
The <ranges> header from C++20's standard library.
T size(T... args)
T to_string(T... args)
Provides seqan3::views::type_reduce.