21 #include <type_traits>
77 template <std::ranges::viewable_range inner_type>
78 requires std::ranges::random_access_range<inner_type> && std::ranges::sized_range<inner_type>
79 && (std::is_const_v<std::remove_reference_t<inner_type>> || std::ranges::view<inner_type>)
84 template <
bool = true>
88 using iterator = basic_iterator<true>;
91 using const_iterator = iterator;
94 using ungapped_view_type = decltype(
views::type_reduce(std::declval<inner_type &&>()));
123 using size_type = std::ranges::range_size_t<inner_type>;
159 template <
typename other_range_t>
160 requires (!std::same_as<other_range_t, gap_decorator>)
161 && std::same_as<std::remove_cvref_t<other_range_t>, std::remove_cvref_t<inner_type>>
162 && std::ranges::viewable_range<other_range_t>
181 size_type
size()
const
184 return anchors.rbegin()->second + ungapped_view.size();
186 return ungapped_view.size();
204 iterator insert_gap(const_iterator
const it, size_type
const count = 1)
209 size_type
const pos = it - begin();
210 assert(pos <=
size());
212 set_iterator_type it_set = anchors.upper_bound(anchor_gap_t{pos, bound_dummy});
214 if (it_set == anchors.begin())
216 anchors.emplace_hint(anchors.begin(), anchor_gap_t{pos, count});
221 auto gap_len{it_set->second};
222 if (it_set != anchors.begin())
223 gap_len -= (*(
std::prev(it_set))).second;
225 if (it_set->first + gap_len >= pos)
227 anchor_gap_t gap{it_set->first, it_set->second +
count};
228 it_set = anchors.erase(it_set);
229 anchors.insert(it_set, gap);
233 anchor_gap_t gap{pos, it_set->second +
count};
235 anchors.insert(it_set, gap);
241 return iterator{*
this, pos};
257 iterator erase_gap(const_iterator
const it)
261 throw gap_erase_failure(
"The range to be erased does not correspond to a consecutive gap.");
281 iterator erase_gap(const_iterator
const first, const_iterator
const last)
283 size_type
const pos1 = first -
begin();
284 size_type
const pos2 = last -
begin();
285 set_iterator_type it = anchors.upper_bound(anchor_gap_t{pos1, bound_dummy});
287 if (it == anchors.begin())
288 throw gap_erase_failure{
"There is no gap to erase in range [" +
std::to_string(pos1) +
","
292 size_type
const gap_len = gap_length(it);
295 if ((it->first + gap_len) < pos2)
297 throw gap_erase_failure{
"The range to be erased does not correspond to a consecutive gap."};
300 else if (gap_len == pos2 - pos1)
302 it = anchors.erase(it);
307 anchor_gap_t gap{it->first, it->second - pos2 + pos1};
308 it = anchors.erase(it);
309 it = anchors.insert(it, gap);
314 update(it, pos2 - pos1);
316 return iterator{*
this, pos1};
326 template <
typename unaligned_sequence_t>
327 requires std::assignable_from<gap_decorator &, unaligned_sequence_t>
328 friend void assign_unaligned(
gap_decorator & dec, unaligned_sequence_t && unaligned)
352 const_iterator begin() const noexcept
354 return iterator{*
this};
358 const_iterator
cbegin() const noexcept
360 return const_iterator{*
this};
378 const_iterator
end() const noexcept
380 return iterator{*
this,
size()};
384 const_iterator
cend() const noexcept
386 return const_iterator{*
this,
size()};
407 reference at(size_type
const i)
410 throw std::out_of_range{
"Trying to access element behind the last in gap_decorator."};
415 const_reference at(size_type
const i)
const
418 throw std::out_of_range{
"Trying to access element behind the last in gap_decorator."};
434 reference operator[](size_type
const i)
const
436 return *iterator{*
this, i};
465 if (lhs.size() == rhs.size() && lhs.anchors == rhs.anchors
466 && std::ranges::equal(lhs.ungapped_view, rhs.ungapped_view))
480 return !(lhs == rhs);
489 auto lit = lhs.begin();
490 auto rit = rhs.begin();
492 while (lit != lhs.end() && rit != rhs.end() && *lit == *rit)
495 if (rit == rhs.end())
497 else if (lit == lhs.end())
509 auto lit = lhs.begin();
510 auto rit = rhs.begin();
512 while (lit != lhs.end() && rit != rhs.end() && *lit == *rit)
515 if (lit == lhs.end())
517 else if (rit == rhs.end())
529 return !(lhs <= rhs);
550 using set_iterator_type =
typename anchor_set_type::iterator;
567 size_type gap_length(set_iterator_type it)
const
569 return (it == anchors.begin()) ? it->second : it->second - (*
std::prev(it)).second;
584 void rupdate(size_type
const pos, size_type
const offset)
586 for (
auto it =
std::prev(anchors.end(), 1); it->first > pos;)
588 anchors.emplace_hint(it, anchor_gap_t{it->first +
offset, it->second +
offset});
589 anchors.erase(*it--);
605 void update(set_iterator_type it, size_type
const offset)
607 while (it != anchors.end())
609 anchor_gap_t gap{it->first -
offset, it->second -
offset};
610 it = anchors.erase(it);
611 it = anchors.insert(it, gap);
617 ungapped_view_type ungapped_view{};
620 anchor_set_type anchors{};
630 template <std::ranges::viewable_range urng_t>
638 template <
std::ranges::view urng_t>
658 template <
std::ranges::viewable_range inner_type>
659 requires std::ranges::random_access_range<inner_type> &&
std::ranges::sized_range<inner_type>
660 && (
std::is_const_v<
std::remove_reference_t<inner_type>> ||
std::ranges::view<inner_type>)
670 int64_t ungapped_view_pos{0};
676 typename gap_decorator::set_iterator_type anchor_set_it{};
678 bool is_at_gap{
true};
683 assert(new_pos <= host->
size());
686 anchor_set_it = host->anchors.upper_bound(anchor_gap_t{pos, host->bound_dummy});
687 ungapped_view_pos = pos;
689 if (anchor_set_it != host->anchors.begin())
691 typename gap_decorator::set_iterator_type prev{
std::prev(anchor_set_it)};
692 size_type gap_len{prev->second};
694 if (prev != host->anchors.begin())
697 ungapped_view_pos -= prev->second;
698 left_gap_end = prev->first + gap_len;
701 if (ungapped_view_pos !=
static_cast<int64_t
>(host->ungapped_view.size()) && pos >= left_gap_end
702 && (anchor_set_it == host->anchors.end() || pos < anchor_set_it->first))
719 using pointer = value_type *;
727 basic_iterator() =
default;
728 basic_iterator(basic_iterator
const &) =
default;
729 basic_iterator & operator=(basic_iterator
const &) =
default;
730 basic_iterator(basic_iterator &&) =
default;
731 basic_iterator & operator=(basic_iterator &&) =
default;
732 ~basic_iterator() =
default;
735 explicit basic_iterator(
gap_decorator const & host_) : host(&host_), anchor_set_it{host_.anchors.
begin()}
737 if (host_.anchors.
size() && (*host_.anchors.
begin()).first == 0)
740 left_gap_end = anchor_set_it->second;
760 basic_iterator & operator++()
765 if (pos < left_gap_end)
768 if (anchor_set_it == host->anchors.end() || pos < anchor_set_it->first)
771 if (ungapped_view_pos !=
static_cast<int64_t
>(host->ungapped_view.size()))
776 left_gap_end = anchor_set_it->first + anchor_set_it->second
777 - ((anchor_set_it != host->anchors.begin()) ? (
std::prev(anchor_set_it))->second : 0);
781 if (left_gap_end == host->size())
789 basic_iterator operator++(
int)
791 basic_iterator cpy{*
this};
797 basic_iterator & operator+=(difference_type
const skip)
799 this->jump(this->pos + skip);
804 basic_iterator operator+(difference_type
const skip)
const
806 return basic_iterator{*(this->host), this->pos + skip};
810 friend basic_iterator operator+(difference_type
const skip, basic_iterator
const & it)
816 basic_iterator & operator--()
821 if (pos < left_gap_end)
823 (anchor_set_it != host->anchors.begin()) ? --anchor_set_it : anchor_set_it;
825 if (anchor_set_it != host->anchors.begin())
829 prev->first + prev->second - ((prev != host->anchors.begin()) ?
std::prev(prev)->second : 0);
837 else if (anchor_set_it == host->anchors.end() || pos < anchor_set_it->first)
848 basic_iterator operator--(
int)
850 basic_iterator cpy{*
this};
856 basic_iterator & operator-=(difference_type
const skip)
858 this->jump(this->pos - skip);
863 basic_iterator operator-(difference_type
const skip)
const
865 return basic_iterator{*(this->host), this->pos - skip};
869 friend basic_iterator operator-(difference_type
const skip, basic_iterator
const & it)
875 difference_type operator-(basic_iterator
const lhs)
const noexcept
877 return static_cast<difference_type
>(this->pos - lhs.pos);
885 reference operator*()
const
887 return (is_at_gap) ? reference{
gap{}} : reference{host->ungapped_view[ungapped_view_pos]};
891 reference operator[](difference_type
const n)
const
903 friend bool operator==(basic_iterator
const & lhs, basic_iterator
const & rhs) noexcept
905 return lhs.pos == rhs.pos;
909 friend bool operator!=(basic_iterator
const & lhs, basic_iterator
const & rhs) noexcept
911 return lhs.pos != rhs.pos;
915 friend bool operator<(basic_iterator
const & lhs, basic_iterator
const & rhs) noexcept
917 return lhs.pos < rhs.pos;
921 friend bool operator>(basic_iterator
const & lhs, basic_iterator
const & rhs) noexcept
923 return lhs.pos > rhs.pos;
927 friend bool operator<=(basic_iterator
const & lhs, basic_iterator
const & rhs) noexcept
929 return lhs.pos <= rhs.pos;
933 friend bool operator>=(basic_iterator
const & lhs, basic_iterator
const & rhs) noexcept
935 return lhs.pos >= rhs.pos;
Includes customized exception types for the alignment module .
Core alphabet concept and free function/type trait wrappers.
A gap decorator allows the annotation of sequences with gap symbols while leaving the underlying sequ...
Definition: gap_decorator.hpp:81
gap_decorator & operator=(gap_decorator &&rhs)=default
Defaulted.
gap_decorator(gap_decorator &&rhs)=default
Defaulted.
std::ranges::range_difference_t< inner_type > difference_type
The difference type of the underlying sequence.
Definition: gap_decorator.hpp:129
inner_type unaligned_sequence_type
The underlying ungapped range type.
Definition: gap_decorator.hpp:136
~gap_decorator()=default
Defaulted.
gap_decorator(gap_decorator const &)=default
Defaulted.
reference const_reference
const_reference type equals reference type equals value type because the underlying sequence must not...
Definition: gap_decorator.hpp:117
gap_decorator & operator=(gap_decorator const &)=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:104
value_type reference
Use the value type as reference type because the underlying sequence must not be modified.
Definition: gap_decorator.hpp:110
gap_decorator()=default
Default constructor.
std::ranges::range_size_t< inner_type > size_type
The size_type of the underlying sequence.
Definition: gap_decorator.hpp:123
requires(!std::same_as< other_range_t, gap_decorator >) &&std
Construct with the ungapped range type.
Definition: gap_decorator.hpp:160
The alphabet of a gap character '-'.
Definition: gap.hpp:39
alphabet_variant< alphabet_t, gap > gapped
Extends a given alphabet with a gap character.
Definition: gapped.hpp:41
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
@ 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: type_pack/traits.hpp:164
constexpr size_t size
The size of a type pack.
Definition: type_pack/traits.hpp:146
constexpr auto type_reduce
A view adaptor that behaves like std::views::all, but type erases certain ranges.
Definition: type_reduce.hpp:150
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
gap_decorator(urng_t range) -> gap_decorator< urng_t >
Views always deduce to their respective type because they are copied.
SeqAn specific customisations in the standard namespace.
The <ranges> header from C++20's standard library.
Provides seqan3::views::type_reduce.