BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
dynamic_bitset.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2022 deCODE Genetics
3// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
4// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
5// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
6// shipped with this file and also available at: https://github.com/biocpp/biocpp-core/blob/main/LICENSE.md
7// -----------------------------------------------------------------------------------------------------
8
14#pragma once
15
16#include <bit>
17
19#include <bio/ranges/to.hpp>
22
23namespace bio::ranges::detail
24{
25
27struct dynamic_bitset_bitfield
28{
30 uint64_t size : 6u;
32 uint64_t bits : 58u;
33};
34
36class dynamic_bitset_reference_proxy
37{
38public:
42 constexpr dynamic_bitset_reference_proxy() = delete;
43 constexpr dynamic_bitset_reference_proxy(dynamic_bitset_reference_proxy const &) noexcept = default;
44 constexpr dynamic_bitset_reference_proxy(dynamic_bitset_reference_proxy &&) noexcept = default;
45
47 constexpr dynamic_bitset_reference_proxy const & operator=(dynamic_bitset_reference_proxy const rhs) const noexcept
48 {
49 rhs ? set() : reset();
50 return *this;
51 }
52
54 constexpr dynamic_bitset_reference_proxy const & operator=(bool const value) const noexcept
55 {
56 value ? set() : reset();
57 return *this;
58 }
59
60 ~dynamic_bitset_reference_proxy() noexcept = default;
62
64 constexpr dynamic_bitset_reference_proxy(dynamic_bitset_bitfield & internal_, size_t const pos) noexcept :
65 internal{internal_}, mask{1ULL << pos}
66 {}
67
69 constexpr operator bool() const noexcept { return static_cast<bool>(internal.bits & mask); }
70
72 constexpr bool operator~() const noexcept { return !static_cast<bool>(internal.bits & mask); }
73
75 constexpr dynamic_bitset_reference_proxy const & operator|=(bool const value) const noexcept
76 {
77 if (value)
78 set();
79
80 return *this;
81 }
82
84 constexpr dynamic_bitset_reference_proxy const & operator&=(bool const value) const noexcept
85 {
86 if (!value)
87 reset();
88
89 return *this;
90 }
91
93 constexpr dynamic_bitset_reference_proxy const & operator^=(bool const value) const noexcept
94 {
95 operator bool() && value ? reset() : set();
96 return *this;
97 }
98
99private:
101 dynamic_bitset_bitfield & internal;
103 uint64_t mask;
104
106 constexpr void set() const noexcept { internal.bits |= mask; }
107
109 constexpr void reset() const noexcept { internal.bits &= ~mask; }
110};
111
112} // namespace bio::ranges::detail
113
114namespace bio::ranges
115{
116
140template <size_t bit_capacity = 58>
142{
143private:
145 template <size_t>
146 friend class dynamic_bitset;
147
149 detail::dynamic_bitset_bitfield data{
150 0u,
151 0u}; // Specifying values prevents ICE on gcc < 9 when comparing to default constructed bitset
152
153public:
154 static_assert(bit_capacity <= 58, "The capacity of the dynamic_bitset exceeds the limit of 58.");
155
160 using value_type = bool;
162 using reference = detail::dynamic_bitset_reference_proxy;
164 using const_reference = bool;
166 using iterator = detail::random_access_iterator<dynamic_bitset>;
168 using const_iterator = detail::random_access_iterator<dynamic_bitset const>;
170 using difference_type = ptrdiff_t;
174
176 // this signals to range-v3 that something is a container :|
177 using allocator_type = void;
179
183 constexpr dynamic_bitset() noexcept = default;
184 constexpr dynamic_bitset(dynamic_bitset const &) noexcept = default;
185 constexpr dynamic_bitset(dynamic_bitset &&) noexcept = default;
186 constexpr dynamic_bitset & operator=(dynamic_bitset const &) noexcept = default;
187 constexpr dynamic_bitset & operator=(dynamic_bitset &&) noexcept = default;
188 ~dynamic_bitset() noexcept = default;
189
208 constexpr dynamic_bitset(uint64_t const value)
209 {
210 if (std::popcount(value >> 58) != 0)
211 throw std::invalid_argument{"The dynamic_bitset can be at most 58 long."};
212 data.bits = value;
213 data.size = std::bit_width(value);
214 }
215
233 template <std::forward_iterator begin_it_type, typename end_it_type>
234 requires(std::sentinel_for<end_it_type, begin_it_type> &&
235 std::constructible_from<value_type, std::iter_reference_t<begin_it_type>>)
236 constexpr dynamic_bitset(begin_it_type begin_it, end_it_type end_it) noexcept : dynamic_bitset{}
237 {
238 assign(begin_it, end_it);
239 }
240
256 template <meta::different_from<dynamic_bitset> other_range_t>
257 requires std::ranges::input_range<other_range_t>
258 explicit constexpr dynamic_bitset(other_range_t && range) noexcept :
259 dynamic_bitset{std::ranges::begin(range), std::ranges::end(range)}
260 {}
261
276 constexpr dynamic_bitset(size_type const n, value_type const value) noexcept : dynamic_bitset{}
277 {
278 assign(n, value);
279 }
280
295 {
296 assign(std::ranges::begin(ilist), std::ranges::end(ilist));
297 return *this;
298 }
299
321 template <size_t N>
322 constexpr dynamic_bitset(char const (&lit)[N]) : dynamic_bitset{}
323 {
324 static_assert(N <= bit_capacity + 1, "Length of string literal exceeds capacity of dynamic_bitset.");
325 assign(lit);
326 }
327
345 template <size_t N>
346 constexpr dynamic_bitset & operator=(char const (&lit)[N])
347 {
348 static_assert(N <= bit_capacity + 1, "Length of string literal exceeds capacity of dynamic_bitset.");
349 assign(lit);
350 return *this;
351 }
352
370 template <size_t N>
371 constexpr void assign(char const (&lit)[N])
372 {
373 static_assert(N <= bit_capacity + 1, "Length of string literal exceeds capacity of dynamic_bitset.");
374 assert(lit[N - 1] == '\0');
375 uint64_t value{};
376
377 for (size_t i = 0; i != N - 1; ++i)
378 {
379 if (lit[i] == '0')
380 {
381 value <<= 1;
382 }
383 else if (lit[i] == '1')
384 {
385 value <<= 1;
386 value |= 1u;
387 }
388 else
389 {
390 throw std::invalid_argument{"The string to construct a dynamic_bitset from may only contain 0 and 1."};
391 }
392 }
393
394 *this = value;
395 resize(N - 1);
396 }
397
411 constexpr void assign(std::initializer_list<value_type> const ilist) noexcept
412 {
413 assign(std::ranges::begin(ilist), std::ranges::end(ilist));
414 }
415
430 constexpr void assign(size_type const count, value_type const value) noexcept
431 {
432 clear();
433 auto tmp = views::repeat_n(value, count);
434 assign(std::ranges::begin(tmp), std::ranges::end(tmp));
435 }
436
452 template <std::ranges::input_range other_range_t>
453 requires std::constructible_from<value_type, std::ranges::range_reference_t<other_range_t>>
454 constexpr void assign(other_range_t && range) noexcept
455 {
456 assign(std::ranges::begin(range), std::ranges::end(range));
457 }
458
476 template <std::forward_iterator begin_it_type, typename end_it_type>
477 requires(std::sentinel_for<end_it_type, begin_it_type> &&
478 std::constructible_from<value_type, std::iter_reference_t<begin_it_type>>)
479 constexpr void assign(begin_it_type begin_it, end_it_type end_it) noexcept
480 {
481 clear();
482 insert(cbegin(), begin_it, end_it);
483 }
485
497 constexpr iterator begin() noexcept { return iterator{*this}; }
498
500 constexpr const_iterator begin() const noexcept { return const_iterator{*this}; }
501
503 constexpr const_iterator cbegin() const noexcept { return begin(); }
504
513 constexpr iterator end() noexcept { return iterator{*this, size()}; }
514
516 constexpr const_iterator end() const noexcept { return const_iterator{*this, size()}; }
517
519 constexpr const_iterator cend() const noexcept { return end(); }
521
546 constexpr dynamic_bitset & operator&=(dynamic_bitset const & rhs) noexcept
547 {
548 assert(size() == rhs.size());
549 data.bits &= rhs.data.bits;
550 return *this;
551 }
552
574 constexpr dynamic_bitset & operator|=(dynamic_bitset const & rhs) noexcept
575 {
576 assert(size() == rhs.size());
577 data.bits |= rhs.data.bits;
578 return *this;
579 }
580
602 constexpr dynamic_bitset & operator^=(dynamic_bitset const & rhs) noexcept
603 {
604 assert(size() == rhs.size());
605 data.bits ^= rhs.data.bits;
606 return *this;
607 }
608
630 constexpr dynamic_bitset operator~() const noexcept
631 {
632 dynamic_bitset tmp{*this};
633 tmp.flip();
634 return tmp;
635 }
636
655 constexpr dynamic_bitset & operator<<=(size_t const count) noexcept
656 {
657 assert(count > 0);
658 assert(count < size());
659 data.bits <<= count;
660 data.bits &= (1ULL << size()) - 1ULL;
661 return *this;
662 }
663
682 constexpr dynamic_bitset & operator>>=(size_t const count) noexcept
683 {
684 assert(count > 0);
685 assert(count < size());
686 data.bits >>= count;
687 return *this;
688 }
689
708 constexpr dynamic_bitset operator>>(size_t const count) const noexcept
709 {
710 assert(count > 0);
711 assert(count < size());
712 dynamic_bitset tmp{*this};
713 tmp >>= count;
714 return tmp;
715 }
716
735 constexpr dynamic_bitset operator<<(size_t const count) const noexcept
736 {
737 assert(count > 0);
738 assert(count < size());
739 dynamic_bitset tmp{*this};
740 tmp <<= count;
741 return tmp;
742 }
743
761 constexpr dynamic_bitset & set() noexcept
762 {
763 data.bits |= (1ULL << size()) - 1ULL;
764 return *this;
765 }
766
787 constexpr dynamic_bitset & set(size_t const i, bool const value = true)
788 {
789 at(i) = value;
790 return *this;
791 }
792
813 constexpr dynamic_bitset & reset() noexcept
814 {
815 data.bits = 0u;
816 return *this;
817 }
818
838 constexpr dynamic_bitset & reset(size_t const i)
839 {
840 set(i, false);
841 return *this;
842 }
843
861 constexpr dynamic_bitset & flip() noexcept
862 {
863 data.bits = ~data.bits;
864 data.bits &= (1ULL << size()) - 1ULL;
865 return *this;
866 }
867
887 constexpr dynamic_bitset & flip(size_t const i)
888 {
889 at(i) ? reset(i) : set(i);
890 return *this;
891 }
893
900 constexpr bool all() const noexcept { return count() == size(); }
901
905 constexpr bool any() const noexcept { return count() != 0; }
906
910 constexpr bool none() const noexcept { return count() == 0; }
911
913 constexpr size_type count() const noexcept { return std::popcount(data.bits); }
914
930 constexpr reference at(size_t const i)
931 {
932 if (i >= size()) // [[unlikely]]
933 throw std::out_of_range{"Trying to access position " + std::to_string(i) +
934 " in a bio::ranges::dynamic_bitset of size " + std::to_string(size()) + "."};
935 return (*this)[i];
936 }
937
939 constexpr const_reference at(size_t const i) const
940 {
941 if (i >= size()) // [[unlikely]]
942 throw std::out_of_range{"Trying to access position " + std::to_string(i) +
943 " in a bio::ranges::dynamic_bitset of size " + std::to_string(size()) + "."};
944 return (*this)[i];
945 }
946
948 constexpr const_reference test(size_t const i) const { return at(i); }
949
971 constexpr reference operator[](size_t const i) noexcept
972 {
973 assert(i < size());
974 return {data, i};
975 }
976
978 constexpr const_reference operator[](size_t const i) const noexcept
979 {
980 assert(i < size());
981 return data.bits & 1ULL << i;
982 }
983
1000 constexpr reference front() noexcept
1001 {
1002 assert(size() > 0);
1003 return (*this)[0];
1004 }
1005
1007 constexpr const_reference front() const noexcept
1008 {
1009 assert(size() > 0);
1010 return (*this)[0];
1011 }
1012
1028 constexpr reference back() noexcept
1029 {
1030 assert(size() > 0);
1031 return (*this)[size() - 1];
1032 }
1033
1035 constexpr const_reference back() const noexcept
1036 {
1037 assert(size() > 0);
1038 return (*this)[size() - 1];
1039 }
1040
1042 constexpr detail::dynamic_bitset_bitfield * raw_data() noexcept { return &data; }
1043
1045 constexpr detail::dynamic_bitset_bitfield const * raw_data() const noexcept { return &data; }
1047
1064 constexpr bool empty() const noexcept { return size() == 0; }
1065
1079 constexpr size_type size() const noexcept { return data.size; }
1080
1099 constexpr size_type max_size() const noexcept { return capacity(); }
1100
1114 constexpr size_type capacity() const noexcept { return bit_capacity; }
1115
1117 constexpr void reserve(size_t) const noexcept
1118 {
1119 // no-op
1120 }
1121
1123 constexpr void shrink_to_fit() const noexcept
1124 {
1125 // no-op
1126 }
1128
1147 constexpr void clear() noexcept
1148 {
1149 data.size &= 0ULL;
1150 data.bits &= 0ULL;
1151 }
1152
1170 constexpr iterator insert(const_iterator pos, value_type const value) noexcept { return insert(pos, 1, value); }
1171
1190 constexpr iterator insert(const_iterator pos, size_type const count, value_type const value) noexcept
1191 {
1192 auto tmp = views::repeat_n(value, count);
1193 return insert(pos, std::ranges::begin(tmp), std::ranges::end(tmp));
1194 }
1195
1218 template <std::forward_iterator begin_it_type, typename end_it_type>
1219 requires(std::sentinel_for<end_it_type, begin_it_type> &&
1220 std::constructible_from<value_type, std::iter_reference_t<begin_it_type>>)
1221 constexpr iterator insert(const_iterator pos, begin_it_type begin_it, end_it_type end_it) noexcept
1222 {
1223 auto const pos_as_num = std::ranges::distance(cbegin(), pos);
1224 auto const length = std::ranges::distance(begin_it, end_it);
1225
1226 if (length == 0)
1227 return begin(); // nothing to insert
1228
1229 size_type const tmp_size{size()};
1230 resize(tmp_size + length);
1231
1232 for (size_type i = tmp_size + length - 1; i > pos_as_num + length - 1; --i)
1233 (*this)[i] = (*this)[i - length];
1234
1235 // std::ranges::copy(begin_it, end_it, (*this)[pos_as_num]);
1236 for (auto i = pos_as_num; begin_it != end_it; ++i, ++begin_it)
1237 (*this)[i] = *begin_it;
1238
1239 return begin() + pos_as_num;
1240 }
1241
1260 {
1261 return insert(pos, ilist.begin(), ilist.end());
1262 }
1263
1285 constexpr iterator erase(const_iterator begin_it, const_iterator end_it) noexcept
1286 {
1287 if (begin_it >= end_it) // [[unlikely]]
1288 return begin() + std::ranges::distance(cbegin(), end_it);
1289
1290 auto const length = std::ranges::distance(begin_it, end_it);
1291 auto out_it = begin() + std::ranges::distance(cbegin(), begin_it);
1292
1293 while (end_it != cend())
1294 *(out_it++) = *(end_it++);
1295
1296 resize(size() - length);
1297 return begin() + std::ranges::distance(cbegin(), begin_it);
1298 }
1299
1320 constexpr iterator erase(const_iterator pos) noexcept { return erase(pos, pos + 1); }
1321
1337 constexpr void push_back(value_type const value) noexcept
1338 {
1339 assert(size() < bit_capacity);
1340 resize(size() + 1);
1341 (*this)[size() - 1] = value;
1342 }
1343
1360 constexpr void pop_back() noexcept
1361 {
1362 assert(size() > 0);
1363 resize(size() - 1);
1364 }
1365
1390 constexpr void resize(size_type const count, value_type const value = false) noexcept
1391 {
1392 assert(count <= bit_capacity);
1393 // Enlarging.
1394 data.bits |= value && count > size() ? ((1ULL << (count - size())) - 1) << size() : 0ULL;
1395 // Set size bits.
1396 data.size = count;
1397 // Shrinking.
1398 data.bits &= (1ULL << size()) - 1ULL;
1399 }
1400
1414 constexpr void swap(dynamic_bitset & rhs) noexcept
1415 {
1416 static_assert(meta::trivial<decltype(data)>); // if type is no longer trivially copyable, do actual moves:
1417 detail::dynamic_bitset_bitfield tmp = data;
1418 data = rhs.data;
1419 rhs.data = tmp;
1420 }
1421
1423 constexpr void swap(dynamic_bitset && rhs) noexcept { data = std::move(rhs.data); }
1424
1426
1441 friend constexpr void swap(dynamic_bitset & lhs, dynamic_bitset & rhs) noexcept { lhs.swap(rhs); }
1442
1454 template <size_t cap>
1455 requires(cap <= bit_capacity)
1456 friend constexpr dynamic_bitset operator&(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1457 {
1458 assert(lhs.size() == rhs.size());
1459 dynamic_bitset tmp{lhs};
1460 tmp &= rhs;
1461 return tmp;
1462 }
1463
1472 template <size_t cap>
1473 requires(cap <= bit_capacity)
1474 friend constexpr dynamic_bitset operator^(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1475 {
1476 assert(lhs.size() == rhs.size());
1477 dynamic_bitset tmp{lhs};
1478 tmp ^= rhs;
1479 return tmp;
1480 }
1481
1490 template <size_t cap>
1491 requires(cap <= bit_capacity)
1492 friend constexpr dynamic_bitset operator|(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1493 {
1494 assert(lhs.size() == rhs.size());
1495 dynamic_bitset tmp{lhs};
1496 tmp |= rhs;
1497 return tmp;
1498 }
1500
1505 template <size_t cap>
1506 friend constexpr bool operator==(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1507 {
1508 return lhs.data.size == rhs.raw_data()->size && lhs.data.bits == rhs.raw_data()->bits;
1509 }
1510
1512 template <size_t cap>
1513 friend constexpr auto operator<=>(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1514 {
1515 return lhs.data.bits <=> rhs.raw_data()->bits;
1516 }
1518
1536 inline constexpr unsigned long to_ulong() const
1537 {
1539 {
1541 throw std::overflow_error{"bio::ranges::dynamic_bitset cannot be represented as unsigned long."};
1542 }
1543
1544 return static_cast<unsigned long>(data.bits);
1545 }
1546
1561 inline constexpr unsigned long long to_ullong() const
1562 {
1564 {
1566 throw std::overflow_error{"bio::ranges::dynamic_bitset cannot be represented as unsigned long long."};
1567 }
1568
1569 return static_cast<unsigned long long>(data.bits);
1570 }
1572
1574
1583 template <typename archive_t>
1584 void serialize(archive_t & archive)
1585 {
1586 uint64_t size = data.size;
1587 archive(size);
1588 data.size = size;
1589 uint64_t bits = data.bits;
1590 archive(bits);
1591 data.bits = bits;
1592 }
1594};
1595
1596} // namespace bio::ranges
1597
1598namespace std
1599{
1600
1605template <size_t cap>
1606struct hash<bio::ranges::dynamic_bitset<cap>>
1607{
1613 size_t operator()(bio::ranges::dynamic_bitset<cap> const arg) const noexcept
1614 {
1615 return static_cast<size_t>(arg.to_ullong());
1616 }
1617};
1618
1619} //namespace std
1620
1621#if __has_include(<fmt/format.h>)
1622
1623# include <fmt/ranges.h>
1624
1625template <>
1626struct fmt::formatter<bio::ranges::detail::dynamic_bitset_reference_proxy> : fmt::formatter<bool>
1627{
1628 constexpr auto format(bio::ranges::detail::dynamic_bitset_reference_proxy const a, auto & ctx) const
1629 {
1630 return fmt::formatter<bool>::format(static_cast<bool>(a), ctx);
1631 }
1632};
1633
1634template <size_t bit_capacity>
1635struct fmt::is_range<bio::ranges::dynamic_bitset<bit_capacity>, char> : std::false_type
1636{};
1637
1638template <size_t bit_capacity>
1639struct fmt::formatter<bio::ranges::dynamic_bitset<bit_capacity>> : fmt::formatter<std::string>
1640{
1641 constexpr auto format(bio::ranges::dynamic_bitset<bit_capacity> const s, auto & ctx) const
1642 {
1643 std::string str{"0b"};
1644 str.reserve(2 + s.size() + s.size() / 4); // TODO fix me
1645 auto v = s | std::views::transform([](bool const bit) { return bit ? '1' : '0'; }) |
1646 bio::ranges::views::interleave(4, std::string_view{"'"}) | std::views::reverse;
1648 return fmt::formatter<std::string>::format(str, ctx);
1649 }
1650};
1651
1652#endif
T back_inserter(T... args)
T begin(T... args)
T bit_width(T... args)
A constexpr bitset implementation with dynamic size at compile time.
Definition: dynamic_bitset.hpp:142
ptrdiff_t difference_type
A std::ptrdiff_t.
Definition: dynamic_bitset.hpp:170
constexpr void assign(std::initializer_list< value_type > const ilist) noexcept
Assign from std::initializer_list.
Definition: dynamic_bitset.hpp:411
constexpr size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition: dynamic_bitset.hpp:1079
constexpr bool any() const noexcept
Checks if any bit is set.
Definition: dynamic_bitset.hpp:905
constexpr reference front() noexcept
Returns the first element.
Definition: dynamic_bitset.hpp:1000
constexpr dynamic_bitset(char const (&lit)[N])
Construction from literal.
Definition: dynamic_bitset.hpp:322
constexpr void assign(other_range_t &&range) noexcept
Assign from a different range.
Definition: dynamic_bitset.hpp:454
constexpr reference at(size_t const i)
Returns the i-th element.
Definition: dynamic_bitset.hpp:930
constexpr dynamic_bitset(size_type const n, value_type const value) noexcept
Construct with n times value.
Definition: dynamic_bitset.hpp:276
constexpr size_type max_size() const noexcept
Returns the maximum number of elements the container is able to hold and resolves to bit_capacity.
Definition: dynamic_bitset.hpp:1099
constexpr reference operator[](size_t const i) noexcept
Returns the i-th element.
Definition: dynamic_bitset.hpp:971
detail::dynamic_bitset_reference_proxy reference
A proxy type that enables assignment.
Definition: dynamic_bitset.hpp:162
constexpr void resize(size_type const count, value_type const value=false) noexcept
Resizes the container to contain count elements.
Definition: dynamic_bitset.hpp:1390
constexpr iterator end() noexcept
Returns iterator past the end of the dynamic_bitset.
Definition: dynamic_bitset.hpp:513
constexpr size_type capacity() const noexcept
Returns the number of elements that the container is able to hold and resolves to bit_capacity.
Definition: dynamic_bitset.hpp:1114
constexpr void swap(dynamic_bitset &rhs) noexcept
Swap contents with another instance.
Definition: dynamic_bitset.hpp:1414
friend constexpr bool operator==(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1506
constexpr const_iterator cend() const noexcept
Returns iterator past the end of the dynamic_bitset.
Definition: dynamic_bitset.hpp:519
constexpr dynamic_bitset & operator&=(dynamic_bitset const &rhs) noexcept
Sets the bits to the result of binary AND on corresponding pairs of bits of *this and rhs.
Definition: dynamic_bitset.hpp:546
constexpr const_iterator end() const noexcept
Returns iterator past the end of the dynamic_bitset.
Definition: dynamic_bitset.hpp:516
constexpr dynamic_bitset & flip() noexcept
Flips all bits (binary NOT).
Definition: dynamic_bitset.hpp:861
constexpr dynamic_bitset(other_range_t &&range) noexcept
Construct from a different range.
Definition: dynamic_bitset.hpp:258
constexpr dynamic_bitset & set(size_t const i, bool const value=true)
Sets the i'th bit to value.
Definition: dynamic_bitset.hpp:787
constexpr dynamic_bitset & operator=(std::initializer_list< value_type > const ilist) noexcept
Assign from std::initializer_list.
Definition: dynamic_bitset.hpp:294
constexpr dynamic_bitset & operator|=(dynamic_bitset const &rhs) noexcept
Sets the bits to the result of binary OR on corresponding pairs of bits of *this and rhs.
Definition: dynamic_bitset.hpp:574
constexpr dynamic_bitset operator~() const noexcept
Returns a temporary copy of *this with all bits flipped (binary NOT).
Definition: dynamic_bitset.hpp:630
constexpr void reserve(size_t) const noexcept
Since the capacity is fixed on compile time, this is a no-op.
Definition: dynamic_bitset.hpp:1117
constexpr dynamic_bitset & flip(size_t const i)
Flips the i'th bit (binary NOT).
Definition: dynamic_bitset.hpp:887
constexpr iterator insert(const_iterator pos, size_type const count, value_type const value) noexcept
Inserts count copies of value before position in the container.
Definition: dynamic_bitset.hpp:1190
constexpr unsigned long to_ulong() const
Converts the dynamic_bitset to an unsigned long integer.
Definition: dynamic_bitset.hpp:1536
constexpr dynamic_bitset & reset(size_t const i)
Sets the i'th bit to false.
Definition: dynamic_bitset.hpp:838
constexpr const_reference back() const noexcept
Returns the last element.
Definition: dynamic_bitset.hpp:1035
constexpr dynamic_bitset operator>>(size_t const count) const noexcept
Performs binary shift right.
Definition: dynamic_bitset.hpp:708
constexpr void push_back(value_type const value) noexcept
Appends the given element value to the end of the container.
Definition: dynamic_bitset.hpp:1337
constexpr const_reference front() const noexcept
Returns the first element.
Definition: dynamic_bitset.hpp:1007
constexpr dynamic_bitset & operator=(char const (&lit)[N])
Assign from literal.
Definition: dynamic_bitset.hpp:346
constexpr bool all() const noexcept
Checks if all bit are set.
Definition: dynamic_bitset.hpp:900
constexpr void pop_back() noexcept
Removes the last element of the container.
Definition: dynamic_bitset.hpp:1360
constexpr void assign(size_type const count, value_type const value) noexcept
Assign with count times value.
Definition: dynamic_bitset.hpp:430
constexpr void clear() noexcept
Removes all elements from the container.
Definition: dynamic_bitset.hpp:1147
constexpr iterator erase(const_iterator begin_it, const_iterator end_it) noexcept
Removes specified elements from the container.
Definition: dynamic_bitset.hpp:1285
constexpr const_reference at(size_t const i) const
Returns the i-th element.
Definition: dynamic_bitset.hpp:939
constexpr dynamic_bitset(begin_it_type begin_it, end_it_type end_it) noexcept
Construct from two iterators.
Definition: dynamic_bitset.hpp:236
constexpr dynamic_bitset & set() noexcept
Sets all bits to 1.
Definition: dynamic_bitset.hpp:761
constexpr void shrink_to_fit() const noexcept
Since the capacity is fixed on compile time, this is a no-op.
Definition: dynamic_bitset.hpp:1123
constexpr reference back() noexcept
Returns the last element.
Definition: dynamic_bitset.hpp:1028
constexpr iterator insert(const_iterator pos, std::initializer_list< value_type > const &ilist) noexcept
Inserts elements from initializer list before pos in the container.
Definition: dynamic_bitset.hpp:1259
constexpr void assign(char const (&lit)[N])
Assign from literal.
Definition: dynamic_bitset.hpp:371
constexpr iterator insert(const_iterator pos, value_type const value) noexcept
Inserts value before pos in the container.
Definition: dynamic_bitset.hpp:1170
constexpr void swap(dynamic_bitset &&rhs) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: dynamic_bitset.hpp:1423
constexpr detail::dynamic_bitset_bitfield * raw_data() noexcept
Direct access to the underlying bit field.
Definition: dynamic_bitset.hpp:1042
constexpr void assign(begin_it_type begin_it, end_it_type end_it) noexcept
Assign from pair of iterators.
Definition: dynamic_bitset.hpp:479
constexpr dynamic_bitset() noexcept=default
Defaulted.
constexpr dynamic_bitset & reset() noexcept
Sets all bits to 0.
Definition: dynamic_bitset.hpp:813
constexpr dynamic_bitset & operator<<=(size_t const count) noexcept
Performs binary shift left on the current object.
Definition: dynamic_bitset.hpp:655
constexpr iterator erase(const_iterator pos) noexcept
Removes specified elements from the container.
Definition: dynamic_bitset.hpp:1320
constexpr unsigned long long to_ullong() const
Converts the dynamic_bitset to an unsigned long long integer.
Definition: dynamic_bitset.hpp:1561
constexpr const_reference test(size_t const i) const
Returns the i-th element.
Definition: dynamic_bitset.hpp:948
constexpr const_reference operator[](size_t const i) const noexcept
Returns the i-th element.
Definition: dynamic_bitset.hpp:978
constexpr dynamic_bitset operator<<(size_t const count) const noexcept
Performs binary shift left.
Definition: dynamic_bitset.hpp:735
constexpr bool none() const noexcept
Checks if no bit is set.
Definition: dynamic_bitset.hpp:910
friend constexpr auto operator<=>(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1513
constexpr const_iterator begin() const noexcept
Returns the begin to the dynamic_bitset.
Definition: dynamic_bitset.hpp:500
friend constexpr void swap(dynamic_bitset &lhs, dynamic_bitset &rhs) noexcept
Swap contents with another instance.
Definition: dynamic_bitset.hpp:1441
bool value_type
Equals bool.
Definition: dynamic_bitset.hpp:160
constexpr iterator insert(const_iterator pos, begin_it_type begin_it, end_it_type end_it) noexcept
Inserts elements from range [begin_it, end_it) before pos in the container.
Definition: dynamic_bitset.hpp:1221
detail::random_access_iterator< dynamic_bitset > iterator
The iterator type of this container (a random access iterator).
Definition: dynamic_bitset.hpp:166
constexpr const_iterator cbegin() const noexcept
Returns the begin to the dynamic_bitset.
Definition: dynamic_bitset.hpp:503
bool const_reference
Equals the value_type.
Definition: dynamic_bitset.hpp:164
constexpr bool empty() const noexcept
Checks whether the container is empty.
Definition: dynamic_bitset.hpp:1064
detail::random_access_iterator< dynamic_bitset const > const_iterator
The const_iterator type of this container (a random access iterator).
Definition: dynamic_bitset.hpp:168
constexpr dynamic_bitset & operator>>=(size_t const count) noexcept
Performs binary shift right on the current object.
Definition: dynamic_bitset.hpp:682
constexpr iterator begin() noexcept
Returns the begin to the dynamic_bitset.
Definition: dynamic_bitset.hpp:497
constexpr size_type count() const noexcept
Returns the number of set bits.
Definition: dynamic_bitset.hpp:913
constexpr dynamic_bitset & operator^=(dynamic_bitset const &rhs) noexcept
Sets the bits to the result of binary XOR on corresponding pairs of bits of *this and rhs.
Definition: dynamic_bitset.hpp:602
constexpr detail::dynamic_bitset_bitfield const * raw_data() const noexcept
Direct access to the underlying bit field.
Definition: dynamic_bitset.hpp:1045
A type that satisfies bio::meta::trivially_copyable and bio::meta::trivially_destructible.
Definition: core_language.hpp:111
T copy(T... args)
T format(T... args)
constexpr auto size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:517
constexpr auto repeat_n
A view factory that repeats a given value n times.
Definition: repeat_n.hpp:98
constexpr auto interleave
A view that interleaves a given range into another range at regular intervals.
Definition: interleave.hpp:164
Provides metaprogramming utilities for integer types.
Provides bio::views::interleave.
T internal(T... args)
T max(T... args)
constexpr translation_frames & operator^=(translation_frames &lhs, translation_frames rhs) noexcept
Binary operators for bio::alphabet::translation_frames.
Definition: translation.hpp:141
constexpr translation_frames & operator&=(translation_frames &lhs, translation_frames rhs) noexcept
Binary operators for bio::alphabet::translation_frames.
Definition: translation.hpp:129
constexpr translation_frames operator~(translation_frames lhs) noexcept
Binary operators for bio::alphabet::translation_frames.
Definition: translation.hpp:123
constexpr translation_frames & operator|=(translation_frames &lhs, translation_frames rhs) noexcept
Binary operators for bio::alphabet::translation_frames.
Definition: translation.hpp:135
The ranges module's namespace.
The main BioC++ namespace.
Definition: aa10li.hpp:23
T popcount(T... args)
Provides bio::views::repeat_n.
T reserve(T... args)
size_t operator()(bio::ranges::dynamic_bitset< cap > const arg) const noexcept
Compute the hash for a bio::ranges::dynamic_bitset.
Definition: dynamic_bitset.hpp:1613
An implementation of C++23's std::ranges::to.
T to_string(T... args)