SeqAn3 3.4.0-rc.4
The Modern C++ library for sequence analysis.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
bitpacked_sequence.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <concepts>
13#include <iterator>
14#include <ranges>
15#include <type_traits>
16
20#include <seqan3/contrib/sdsl-lite.hpp>
25
26namespace seqan3
27{
28
59template <writable_semialphabet alphabet_type>
60 requires std::regular<alphabet_type>
62{
63private:
65 static constexpr size_t bits_per_letter = detail::ceil_log2(alphabet_size<alphabet_type>);
66
67 static_assert(bits_per_letter <= 64, "alphabet must be representable in at most 64bit.");
68
70 using data_type = seqan3::contrib::sdsl::int_vector<bits_per_letter>;
71
73 data_type data;
74
76 class reference_proxy_type : public alphabet_proxy<reference_proxy_type, alphabet_type>
77 {
78 private:
82 friend base_t;
83
85 std::ranges::range_reference_t<data_type> internal_proxy;
86
88 constexpr void on_update() noexcept
89 {
90 internal_proxy = base_t::to_rank();
91 }
92
93 public:
94 // Import from base:
95 using base_t::operator=;
96
101 reference_proxy_type() = delete;
102 constexpr reference_proxy_type(reference_proxy_type const &) noexcept = default;
103 constexpr reference_proxy_type(reference_proxy_type &&) noexcept = default;
104 constexpr reference_proxy_type & operator=(reference_proxy_type const &) noexcept = default;
105 constexpr reference_proxy_type & operator=(reference_proxy_type &&) noexcept = default;
106 ~reference_proxy_type() noexcept = default;
107
109 reference_proxy_type(std::ranges::range_reference_t<data_type> const internal) noexcept :
110 internal_proxy{internal}
111 {
112 // Call alphabet_base's assign_rank to prevent calling on_update() during construction
113 // which is not necessary, because internal_proxy is already correctly initialised!
115 }
117 };
118
121 //NOTE(h-2): it is entirely unclear to me why we need this
122 template <typename t>
123 requires std::is_same_v<std::ranges::range_value_t<std::remove_cvref_t<t>>, alphabet_type>
124 static constexpr bool has_same_value_type_v = true;
126
127public:
135 using value_type = alphabet_type;
141 using reference = reference_proxy_type;
146 using const_reference = alphabet_type;
151 using iterator = detail::random_access_iterator<bitpacked_sequence>;
156 using const_iterator = detail::random_access_iterator<bitpacked_sequence const>;
161 using difference_type = std::ranges::range_difference_t<data_type>;
166 using size_type = std::ranges::range_size_t<data_type>;
168
172 bitpacked_sequence() = default;
173 constexpr bitpacked_sequence(bitpacked_sequence const &) = default;
174 constexpr bitpacked_sequence(bitpacked_sequence &&) = default;
175 constexpr bitpacked_sequence & operator=(bitpacked_sequence const &) = default;
178
194 template <typename other_range_t>
195 requires (!std::same_as<bitpacked_sequence, std::remove_cvref_t<other_range_t>>)
196 && std::ranges::input_range<other_range_t> && has_same_value_type_v<other_range_t>
200
215 bitpacked_sequence(size_type const count, value_type const value) : data(count, to_rank(value))
216 {}
217
235 template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
237 requires std::sentinel_for<end_iterator_type, begin_iterator_type>
238 && std::common_reference_with<std::iter_value_t<begin_iterator_type>, value_type>
239 {
240 insert(cend(), begin_it, end_it);
241 }
242
258
277
293 template <std::ranges::input_range other_range_t>
295 requires std::common_reference_with<std::ranges::range_value_t<other_range_t>, value_type>
296 {
297 bitpacked_sequence rhs{std::forward<other_range_t>(range)};
298 swap(rhs);
299 }
300
315 void assign(size_type const count, value_type const value)
316 {
317 bitpacked_sequence rhs{count, value};
318 swap(rhs);
319 }
320
338 template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
340 requires std::sentinel_for<end_iterator_type, begin_iterator_type>
341 && std::common_reference_with<std::iter_value_t<begin_iterator_type>, value_type>
342 {
343 bitpacked_sequence rhs{begin_it, end_it};
344 swap(rhs);
345 }
346
364
366
386 {
387 return iterator{*this};
388 }
389
392 {
393 return const_iterator{*this};
394 }
395
398 {
399 return const_iterator{*this};
400 }
401
418 {
419 return iterator{*this, size()};
420 }
421
424 {
425 return const_iterator{*this, size()};
426 }
427
430 {
431 return const_iterator{*this, size()};
432 }
434
454 {
455 if (i >= size()) // [[unlikely]]
456 {
457 throw std::out_of_range{"Trying to access element behind the last in bitpacked_sequence."};
458 }
459 return (*this)[i];
460 }
461
464 {
465 if (i >= size()) // [[unlikely]]
466 {
467 throw std::out_of_range{"Trying to access element behind the last in bitpacked_sequence."};
468 }
469 return (*this)[i];
470 }
471
490 {
491 assert(i < size());
492 return data[i];
493 }
494
496 const_reference operator[](size_type const i) const noexcept
497 {
498 assert(i < size());
499 return assign_rank_to(data[i], const_reference{});
500 }
501
518 {
519 assert(size() > 0);
520 return (*this)[0];
521 }
522
525 {
526 assert(size() > 0);
527 return (*this)[0];
528 }
529
546 {
547 assert(size() > 0);
548 return (*this)[size() - 1];
549 }
550
553 {
554 assert(size() > 0);
555 return (*this)[size() - 1];
556 }
557
567 constexpr data_type & raw_data() noexcept
568 {
569 return data;
570 }
571
573 constexpr data_type const & raw_data() const noexcept
574 {
575 return data;
576 }
578
596 {
597 return size() == 0;
598 }
599
614 {
615 return data.size();
616 }
617
635 {
636 return data.max_size();
637 }
638
653 {
654 return data.capacity();
655 }
656
678 {
679 data.reserve(new_cap);
680 }
681
700 {
701 data.shrink_to_fit();
702 }
704
721 {
722 data.clear();
723 }
724
746 {
747 return insert(pos, 1, value);
748 }
749
771 iterator insert(const_iterator pos, size_type const count, value_type const value)
772 {
773 auto const pos_as_num = std::distance(cbegin(), pos); // we want to insert BEFORE this position
774
775 data.insert(data.begin() + pos_as_num, count, to_rank(value));
776
777 return begin() + pos_as_num;
778 }
779
806 template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
808 requires std::sentinel_for<end_iterator_type, begin_iterator_type>
809 && std::common_reference_with<std::iter_value_t<begin_iterator_type>, value_type>
810 {
811 auto const pos_as_num = std::distance(cbegin(), pos);
812
813 auto v = std::ranges::subrange<begin_iterator_type, end_iterator_type>{begin_it, end_it}
814 | views::convert<value_type> | views::to_rank;
815 data.insert(data.begin() + pos_as_num, std::ranges::begin(v), std::ranges::end(v));
816
817 return begin() + pos_as_num;
818 }
819
841 {
842 return insert(pos, ilist.begin(), ilist.end());
843 }
844
867 {
868 if (begin_it >= end_it) // [[unlikely]]
869 return begin() + std::distance(cbegin(), end_it);
870
871 auto const begin_it_pos = std::distance(cbegin(), begin_it);
872 auto const end_it_pos = std::distance(cbegin(), end_it);
873
874 data.erase(data.cbegin() + begin_it_pos, data.cbegin() + end_it_pos);
875
876 return begin() + begin_it_pos;
877 }
878
901 {
902 return erase(pos, pos + 1);
903 }
904
922 void push_back(value_type const value)
923 {
924 data.push_back(to_rank(value));
925 }
926
945 void pop_back()
946 {
947 assert(size() > 0);
948 data.pop_back();
949 }
950
979 void resize(size_type const count)
980 {
981 assert(count < max_size());
982 data.resize(count);
983 }
984
989 void resize(size_type const count, value_type const value)
990 {
991 assert(count < max_size());
992 data.resize(count, to_rank(value));
993 }
994
1008 constexpr void swap(bitpacked_sequence & rhs) noexcept
1009 {
1010 std::swap(data, rhs.data);
1011 }
1012
1014 constexpr void swap(bitpacked_sequence && rhs) noexcept
1015 {
1016 std::swap(data, rhs.data);
1017 }
1018
1033 friend constexpr void swap(bitpacked_sequence & lhs, bitpacked_sequence & rhs) noexcept
1034 {
1035 std::swap(lhs, rhs);
1036 }
1037
1039 friend constexpr void swap(bitpacked_sequence && lhs, bitpacked_sequence && rhs) noexcept
1040 {
1041 std::swap(lhs, rhs);
1042 }
1044
1053 constexpr bool operator==(bitpacked_sequence const & rhs) const noexcept
1054 {
1055 return data == rhs.data;
1056 }
1057
1062 constexpr bool operator!=(bitpacked_sequence const & rhs) const noexcept
1063 {
1064 return data != rhs.data;
1065 }
1066
1071 constexpr bool operator<(bitpacked_sequence const & rhs) const noexcept
1072 {
1073 return data < rhs.data;
1074 }
1075
1080 constexpr bool operator>(bitpacked_sequence const & rhs) const noexcept
1081 {
1082 return data > rhs.data;
1083 }
1084
1089 constexpr bool operator<=(bitpacked_sequence const & rhs) const noexcept
1090 {
1091 return data <= rhs.data;
1092 }
1093
1098 constexpr bool operator>=(bitpacked_sequence const & rhs) const noexcept
1099 {
1100 return data >= rhs.data;
1101 }
1103
1111 template <cereal_archive archive_t>
1113 {
1114 archive(data);
1115 }
1117};
1118
1119} // namespace seqan3
Provides seqan3::alphabet_proxy.
T begin(T... args)
Adaptions of concepts from the Cereal library.
A CRTP-base that eases the definition of proxy types returned in place of regular alphabets.
Definition alphabet_proxy.hpp:62
constexpr reference_proxy_type & assign_rank(alphabet_rank_t< alphabet_type > const r) noexcept
Assigns a rank.
Definition alphabet_proxy.hpp:142
constexpr auto to_rank() const noexcept
Returns the rank.
Definition alphabet_proxy.hpp:204
A space-optimised version of std::vector that compresses multiple letters into a single byte.
Definition bitpacked_sequence.hpp:62
void assign(size_type const count, value_type const value)
Assign with count times value.
Definition bitpacked_sequence.hpp:315
alphabet_type value_type
Equals the alphabet_type.
Definition bitpacked_sequence.hpp:135
std::ranges::range_difference_t< data_type > difference_type
A signed integer type (usually std::ptrdiff_t)
Definition bitpacked_sequence.hpp:161
iterator insert(const_iterator pos, begin_iterator_type begin_it, end_iterator_type end_it)
Inserts elements from range [begin_it, end_it) before position in the container.
Definition bitpacked_sequence.hpp:807
constexpr bitpacked_sequence(bitpacked_sequence &&)=default
Defaulted.
iterator erase(const_iterator pos)
Removes specified elements from the container.
Definition bitpacked_sequence.hpp:900
reference_proxy_type reference
A proxy type (models seqan3::writable_semialphabet) that enables assignment, think of it as value_typ...
Definition bitpacked_sequence.hpp:141
constexpr bool operator>(bitpacked_sequence const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition bitpacked_sequence.hpp:1080
size_type max_size() const noexcept
Returns the maximum number of elements the container is able to hold due to system or library impleme...
Definition bitpacked_sequence.hpp:634
bool empty() const noexcept
Checks whether the container is empty.
Definition bitpacked_sequence.hpp:595
reference operator[](size_type const i) noexcept
Return the i-th element.
Definition bitpacked_sequence.hpp:489
const_reference back() const noexcept
Return the last element.
Definition bitpacked_sequence.hpp:552
const_iterator cbegin() const noexcept
Returns an iterator to the first element of the container.
Definition bitpacked_sequence.hpp:397
iterator erase(const_iterator begin_it, const_iterator end_it)
Removes specified elements from the container.
Definition bitpacked_sequence.hpp:866
iterator insert(const_iterator pos, value_type const value)
Inserts value before position in the container.
Definition bitpacked_sequence.hpp:745
~bitpacked_sequence()=default
Defaulted.
void resize(size_type const count, value_type const value)
Resizes the container to contain count elements.
Definition bitpacked_sequence.hpp:989
void clear() noexcept
Removes all elements from the container.
Definition bitpacked_sequence.hpp:720
constexpr bool operator<=(bitpacked_sequence const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition bitpacked_sequence.hpp:1089
const_iterator end() const noexcept
Returns an iterator to the element following the last element of the container.
Definition bitpacked_sequence.hpp:423
constexpr bool operator>=(bitpacked_sequence const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition bitpacked_sequence.hpp:1098
constexpr bitpacked_sequence(bitpacked_sequence const &)=default
Defaulted.
void push_back(value_type const value)
Appends the given element value to the end of the container.
Definition bitpacked_sequence.hpp:922
const_reference at(size_type const i) const
Return the i-th element.
Definition bitpacked_sequence.hpp:463
constexpr bool operator!=(bitpacked_sequence const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition bitpacked_sequence.hpp:1062
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition bitpacked_sequence.hpp:417
void assign(std::initializer_list< value_type > ilist)
Assign from std::initializer_list.
Definition bitpacked_sequence.hpp:360
void reserve(size_type const new_cap)
Increase the capacity to a value that's greater or equal to new_cap.
Definition bitpacked_sequence.hpp:677
const_iterator begin() const noexcept
Returns an iterator to the first element of the container.
Definition bitpacked_sequence.hpp:391
detail::random_access_iterator< bitpacked_sequence const > const_iterator
The const_iterator type of this container (a random access iterator).
Definition bitpacked_sequence.hpp:156
bitpacked_sequence(std::initializer_list< value_type > ilist)
Construct from std::initializer_list.
Definition bitpacked_sequence.hpp:256
void shrink_to_fit()
Requests the removal of unused capacity.
Definition bitpacked_sequence.hpp:699
const_reference operator[](size_type const i) const noexcept
Return the i-th element.
Definition bitpacked_sequence.hpp:496
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition bitpacked_sequence.hpp:385
std::ranges::range_size_t< data_type > size_type
An unsigned integer type (usually std::size_t)
Definition bitpacked_sequence.hpp:166
size_type capacity() const noexcept
Returns the number of elements that the container has currently allocated space for.
Definition bitpacked_sequence.hpp:652
void assign(other_range_t &&range)
Assign from a different range.
Definition bitpacked_sequence.hpp:294
detail::random_access_iterator< bitpacked_sequence > iterator
The iterator type of this container (a random access iterator).
Definition bitpacked_sequence.hpp:151
alphabet_type const_reference
Equals the alphabet_type / value_type.
Definition bitpacked_sequence.hpp:146
iterator insert(const_iterator pos, std::initializer_list< value_type > const &ilist)
Inserts elements from initializer list before position in the container.
Definition bitpacked_sequence.hpp:840
reference at(size_type const i)
Return the i-th element.
Definition bitpacked_sequence.hpp:453
bitpacked_sequence(begin_iterator_type begin_it, end_iterator_type end_it)
Construct from pair of iterators.
Definition bitpacked_sequence.hpp:236
friend constexpr void swap(bitpacked_sequence &lhs, bitpacked_sequence &rhs) noexcept
Swap contents with another instance.
Definition bitpacked_sequence.hpp:1033
const_reference front() const noexcept
Return the first element. Calling front on an empty container is undefined.
Definition bitpacked_sequence.hpp:524
constexpr bitpacked_sequence & operator=(bitpacked_sequence const &)=default
Defaulted.
constexpr data_type const & raw_data() const noexcept
Provides direct, unsafe access to underlying data structures.
Definition bitpacked_sequence.hpp:573
constexpr bool operator==(bitpacked_sequence const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition bitpacked_sequence.hpp:1053
friend constexpr void swap(bitpacked_sequence &&lhs, bitpacked_sequence &&rhs) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition bitpacked_sequence.hpp:1039
const_iterator cend() const noexcept
Returns an iterator to the element following the last element of the container.
Definition bitpacked_sequence.hpp:429
bitpacked_sequence(size_type const count, value_type const value)
Construct with count times value.
Definition bitpacked_sequence.hpp:215
bitpacked_sequence & operator=(std::initializer_list< value_type > ilist)
Assign from std::initializer_list.
Definition bitpacked_sequence.hpp:272
void resize(size_type const count)
Resizes the container to contain count elements.
Definition bitpacked_sequence.hpp:979
void pop_back()
Removes the last element of the container.
Definition bitpacked_sequence.hpp:945
reference back() noexcept
Return the last element.
Definition bitpacked_sequence.hpp:545
iterator insert(const_iterator pos, size_type const count, value_type const value)
Inserts count copies of value before position in the container.
Definition bitpacked_sequence.hpp:771
bitpacked_sequence()=default
Defaulted.
constexpr void swap(bitpacked_sequence &&rhs) noexcept
Swap contents with another instance.
Definition bitpacked_sequence.hpp:1014
bitpacked_sequence(other_range_t &&range)
Construct from a different range.
Definition bitpacked_sequence.hpp:197
constexpr data_type & raw_data() noexcept
Provides direct, unsafe access to underlying data structures.
Definition bitpacked_sequence.hpp:567
constexpr bool operator<(bitpacked_sequence const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition bitpacked_sequence.hpp:1071
constexpr void swap(bitpacked_sequence &rhs) noexcept
Swap contents with another instance.
Definition bitpacked_sequence.hpp:1008
size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition bitpacked_sequence.hpp:613
reference front() noexcept
Return the first element. Calling front on an empty container is undefined.
Definition bitpacked_sequence.hpp:517
constexpr bitpacked_sequence & operator=(bitpacked_sequence &&)=default
Defaulted.
void assign(begin_iterator_type begin_it, end_iterator_type end_it)
Assign from pair of iterators.
Definition bitpacked_sequence.hpp:339
A "pretty printer" for most SeqAn data structures and related types.
Definition debug_stream_type.hpp:79
T distance(T... args)
T end(T... args)
auto const to_rank
A view that calls seqan3::to_rank() on each element in the input range.
Definition to_rank.hpp:63
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition alphabet/concept.hpp:288
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition alphabet/concept.hpp:152
Provides math related functionality.
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
SeqAn specific customisations in the standard namespace.
Provides the seqan3::detail::random_access_iterator class.
T swap(T... args)
Provides seqan3::views::to_char.
Provides seqan3::views::to_rank.
Provides seqan3::views::convert.
Hide me