SeqAn3  3.2.0-rc.1
The Modern C++ library for sequence analysis.
dynamic_bitset.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 <bit>
16 
23 
24 namespace seqan3
25 {
26 
52 template <size_t bit_capacity = 58>
54 {
55 private:
57  template <size_t>
58  friend class dynamic_bitset;
59 
61  struct bitfield
62  {
64  uint64_t size : 6u;
66  uint64_t bits : 58u;
67  };
68 
70  bitfield data{0u, 0u}; // Specifying values prevents ICE on gcc < 9 when comparing to default constructed bitset
71 
73  class reference_proxy_type
74  {
75  public:
79  constexpr reference_proxy_type() noexcept = default;
80  constexpr reference_proxy_type(reference_proxy_type const &) noexcept = default;
81  constexpr reference_proxy_type(reference_proxy_type &&) noexcept = default;
82 
84  constexpr reference_proxy_type & operator=(reference_proxy_type const rhs) noexcept
85  {
86  rhs ? set() : reset();
87  return *this;
88  }
89 
91  constexpr reference_proxy_type & operator=(bool const value) noexcept
92  {
93  value ? set() : reset();
94  return *this;
95  }
96 
97  ~reference_proxy_type() noexcept = default;
98 
100 
102  constexpr reference_proxy_type(bitfield & internal_, size_t const pos) noexcept :
103  internal{internal_},
104  mask{1ULL << pos}
105  {}
106 
108  constexpr operator bool() const noexcept
109  {
110  return static_cast<bool>(internal.bits & mask);
111  }
112 
114  constexpr bool operator~() const noexcept
115  {
116  return !static_cast<bool>(internal.bits & mask);
117  }
118 
120  constexpr reference_proxy_type & operator|=(bool const value)
121  {
122  if (value)
123  set();
124 
125  return *this;
126  }
127 
129  constexpr reference_proxy_type & operator&=(bool const value)
130  {
131  if (!value)
132  reset();
133 
134  return *this;
135  }
136 
138  constexpr reference_proxy_type & operator^=(bool const value)
139  {
140  operator bool() && value ? reset() : set();
141  return *this;
142  }
143 
144  private:
146  bitfield & internal;
148  uint64_t mask;
149 
151  constexpr void set() noexcept
152  {
153  internal.bits |= mask;
154  }
155 
157  constexpr void reset() noexcept
158  {
159  internal.bits &= ~mask;
160  }
161  };
162 
163 public:
164  static_assert(bit_capacity <= 58, "The capacity of the dynamic_bitset exceeds the limit of 58.");
165 
173  using value_type = bool;
174 
179  using reference = reference_proxy_type;
180 
185  using const_reference = bool;
186 
191  using iterator = detail::random_access_iterator<dynamic_bitset>;
192 
197  using const_iterator = detail::random_access_iterator<dynamic_bitset const>;
198 
203  using difference_type = ptrdiff_t;
204 
211 
215  constexpr dynamic_bitset() noexcept = default;
216  constexpr dynamic_bitset(dynamic_bitset const &) noexcept = default;
217  constexpr dynamic_bitset(dynamic_bitset &&) noexcept = default;
218  constexpr dynamic_bitset & operator=(dynamic_bitset const &) noexcept = default;
219  constexpr dynamic_bitset & operator=(dynamic_bitset &&) noexcept = default;
220  ~dynamic_bitset() noexcept = default;
221 
242  constexpr dynamic_bitset(uint64_t const value)
243  {
244  if (std::popcount(value >> 58u) != 0u)
245  throw std::invalid_argument{"The dynamic_bitset can be at most 58 long."};
246  data.bits |= value;
247  data.size |= std::bit_width(value);
248  }
249 
269  template <std::forward_iterator begin_it_type, typename end_it_type>
270  requires std::sentinel_for<end_it_type, begin_it_type>
271  && std::constructible_from<value_type, std::iter_reference_t<begin_it_type>>
272  constexpr dynamic_bitset(begin_it_type begin_it, end_it_type end_it) noexcept : dynamic_bitset{}
273  {
274  assign(begin_it, end_it);
275  }
276 
294  template <std::ranges::input_range other_range_t>
295  requires (!std::same_as<std::remove_cvref_t<other_range_t>, dynamic_bitset>)
296  explicit constexpr dynamic_bitset(other_range_t && range) noexcept :
297  dynamic_bitset{std::ranges::begin(range), std::ranges::end(range)}
298  {}
299 
316  constexpr dynamic_bitset(size_type const n, value_type const value) noexcept : dynamic_bitset{}
317  {
318  assign(n, value);
319  }
320 
337  {
338  assign(std::ranges::begin(ilist), std::ranges::end(ilist));
339  return *this;
340  }
341 
365  template <size_t N>
366  constexpr dynamic_bitset(char const (&lit)[N]) : dynamic_bitset{}
367  {
368  static_assert(N <= bit_capacity + 1, "Length of string literal exceeds capacity of dynamic_bitset.");
369  assign(lit);
370  }
371 
391  template <size_t N>
392  constexpr dynamic_bitset & operator=(char const (&lit)[N])
393  {
394  static_assert(N <= bit_capacity + 1, "Length of string literal exceeds capacity of dynamic_bitset.");
395  assign(lit);
396  return *this;
397  }
398 
418  template <size_t N>
419  constexpr void assign(char const (&lit)[N])
420  {
421  static_assert(N <= bit_capacity + 1, "Length of string literal exceeds capacity of dynamic_bitset.");
422  assert(lit[N - 1] == '\0');
423  uint64_t value{};
424 
425  for (size_t i = 0; i != N - 1; ++i)
426  {
427  if (lit[i] == '0')
428  {
429  value <<= 1;
430  }
431  else if (lit[i] == '1')
432  {
433  value <<= 1;
434  value |= 1u;
435  }
436  else
437  {
438  throw std::invalid_argument{"The string to construct a dynamic_bitset from may only contain 0 and 1."};
439  }
440  }
441 
442  *this = value;
443  resize(N - 1);
444  }
445 
462  {
463  assign(std::ranges::begin(ilist), std::ranges::end(ilist));
464  }
465 
482  constexpr void assign(size_type const count, value_type const value) noexcept
483  {
484  clear();
485  auto tmp = views::repeat_n(value, count);
486  assign(std::ranges::begin(tmp), std::ranges::end(tmp));
487  }
488 
506  template <std::ranges::input_range other_range_t>
507  requires std::constructible_from<value_type, std::ranges::range_reference_t<other_range_t>>
508  constexpr void assign(other_range_t && range) noexcept
509  {
510  assign(std::ranges::begin(range), std::ranges::end(range));
511  }
512 
532  template <std::forward_iterator begin_it_type, typename end_it_type>
533  requires std::sentinel_for<end_it_type, begin_it_type>
534  && std::constructible_from<value_type, std::iter_reference_t<begin_it_type>>
535  constexpr void assign(begin_it_type begin_it, end_it_type end_it) noexcept
536  {
537  clear();
538  insert(cbegin(), begin_it, end_it);
539  }
541 
555  constexpr iterator begin() noexcept
556  {
557  return iterator{*this};
558  }
559 
561  constexpr const_iterator begin() const noexcept
562  {
563  return const_iterator{*this};
564  }
565 
567  constexpr const_iterator cbegin() const noexcept
568  {
569  return begin();
570  }
571 
582  constexpr iterator end() noexcept
583  {
584  return iterator{*this, size()};
585  }
586 
588  constexpr const_iterator end() const noexcept
589  {
590  return const_iterator{*this, size()};
591  }
592 
594  constexpr const_iterator cend() const noexcept
595  {
596  return end();
597  }
599 
627  {
628  assert(size() == rhs.size());
629  data.bits &= rhs.data.bits;
630  return *this;
631  }
632 
657  {
658  assert(size() == rhs.size());
659  data.bits |= rhs.data.bits;
660  return *this;
661  }
662 
687  {
688  assert(size() == rhs.size());
689  data.bits ^= rhs.data.bits;
690  return *this;
691  }
692 
717  {
718  dynamic_bitset tmp{*this};
719  tmp.flip();
720  return tmp;
721  }
722 
743  constexpr dynamic_bitset & operator<<=(size_t const count) noexcept
744  {
745  assert(count > 0);
746  assert(count < size());
747  data.bits <<= count;
748  data.bits &= (1ULL << size()) - 1ULL;
749  return *this;
750  }
751 
772  constexpr dynamic_bitset & operator>>=(size_t const count) noexcept
773  {
774  assert(count > 0);
775  assert(count < size());
776  data.bits >>= count;
777  return *this;
778  }
779 
800  constexpr dynamic_bitset operator>>(size_t const count) const noexcept
801  {
802  assert(count > 0);
803  assert(count < size());
804  dynamic_bitset tmp{*this};
805  tmp >>= count;
806  return tmp;
807  }
808 
829  constexpr dynamic_bitset operator<<(size_t const count) const noexcept
830  {
831  assert(count > 0);
832  assert(count < size());
833  dynamic_bitset tmp{*this};
834  tmp <<= count;
835  return tmp;
836  }
837 
858  {
859  data.bits |= (1ULL << size()) - 1ULL;
860  return *this;
861  }
862 
885  constexpr dynamic_bitset & set(size_t const i, bool const value = true)
886  {
887  at(i) = value;
888  return *this;
889  }
890 
914  {
915  data.bits = 0u;
916  return *this;
917  }
918 
940  constexpr dynamic_bitset & reset(size_t const i)
941  {
942  set(i, false);
943  return *this;
944  }
945 
966  {
967  data.bits = ~data.bits;
968  data.bits &= (1ULL << size()) - 1ULL;
969  return *this;
970  }
971 
993  constexpr dynamic_bitset & flip(size_t const i)
994  {
995  at(i) ? reset(i) : set(i);
996  return *this;
997  }
999 
1008  constexpr bool all() const noexcept
1009  {
1010  return count() == size();
1011  }
1012 
1018  constexpr bool any() const noexcept
1019  {
1020  return count() != 0;
1021  }
1022 
1028  constexpr bool none() const noexcept
1029  {
1030  return count() == 0;
1031  }
1032 
1037  constexpr size_type count() const noexcept
1038  {
1039  return std::popcount(data.bits);
1040  }
1041 
1059  constexpr reference at(size_t const i)
1060  {
1061  if (i >= size()) // [[unlikely]]
1062  throw std::out_of_range{"Trying to access position " + std::to_string(i)
1063  + " in a seqan3::dynamic_bitset of size " + std::to_string(size()) + "."};
1064  return (*this)[i];
1065  }
1066 
1068  constexpr const_reference at(size_t const i) const
1069  {
1070  if (i >= size()) // [[unlikely]]
1071  throw std::out_of_range{"Trying to access position " + std::to_string(i)
1072  + " in a seqan3::dynamic_bitset of size " + std::to_string(size()) + "."};
1073  return (*this)[i];
1074  }
1075 
1077  constexpr const_reference test(size_t const i) const
1078  {
1079  return at(i);
1080  }
1081 
1105  constexpr reference operator[](size_t const i) noexcept
1106  {
1107  assert(i < size());
1108  return {data, i};
1109  }
1110 
1112  constexpr const_reference operator[](size_t const i) const noexcept
1113  {
1114  assert(i < size());
1115  return data.bits & 1ULL << i;
1116  }
1117 
1137  {
1138  assert(size() > 0);
1139  return (*this)[0];
1140  }
1141 
1143  constexpr const_reference front() const noexcept
1144  {
1145  assert(size() > 0);
1146  return (*this)[0];
1147  }
1148 
1167  {
1168  assert(size() > 0);
1169  return (*this)[size() - 1];
1170  }
1171 
1173  constexpr const_reference back() const noexcept
1174  {
1175  assert(size() > 0);
1176  return (*this)[size() - 1];
1177  }
1178 
1183  constexpr bitfield * raw_data() noexcept
1184  {
1185  return &data;
1186  }
1187 
1189  constexpr bitfield const * raw_data() const noexcept
1190  {
1191  return &data;
1192  }
1194 
1213  constexpr bool empty() const noexcept
1214  {
1215  return size() == 0;
1216  }
1217 
1233  constexpr size_type size() const noexcept
1234  {
1235  return data.size;
1236  }
1237 
1258  constexpr size_type max_size() const noexcept
1259  {
1260  return capacity();
1261  }
1262 
1278  constexpr size_type capacity() const noexcept
1279  {
1280  return bit_capacity;
1281  }
1282 
1287  constexpr void reserve(size_t) const noexcept
1288  {
1289  // no-op
1290  }
1291 
1296  constexpr void shrink_to_fit() const noexcept
1297  {
1298  // no-op
1299  }
1301 
1322  constexpr void clear() noexcept
1323  {
1324  data.size &= 0ULL;
1325  data.bits &= 0ULL;
1326  }
1327 
1347  constexpr iterator insert(const_iterator pos, value_type const value) noexcept
1348  {
1349  return insert(pos, 1, value);
1350  }
1351 
1372  constexpr iterator insert(const_iterator pos, size_type const count, value_type const value) noexcept
1373  {
1374  auto tmp = views::repeat_n(value, count);
1375  return insert(pos, std::ranges::begin(tmp), std::ranges::end(tmp));
1376  }
1377 
1402  template <std::forward_iterator begin_it_type, typename end_it_type>
1403  requires std::sentinel_for<end_it_type, begin_it_type>
1404  && std::constructible_from<value_type, std::iter_reference_t<begin_it_type>>
1405  constexpr iterator insert(const_iterator pos, begin_it_type begin_it, end_it_type end_it) noexcept
1406  {
1407  auto const pos_as_num = std::ranges::distance(cbegin(), pos);
1408  auto const length = std::ranges::distance(begin_it, end_it);
1409 
1410  if (length == 0)
1411  return begin(); // nothing to insert
1412 
1413  size_type const tmp_size{size()};
1414  resize(tmp_size + length);
1415 
1416  for (size_type i = tmp_size + length - 1; i > pos_as_num + length - 1; --i)
1417  (*this)[i] = (*this)[i - length];
1418 
1419  // std::ranges::copy(begin_it, end_it, (*this)[pos_as_num]);
1420  for (auto i = pos_as_num; begin_it != end_it; ++i, ++begin_it)
1421  (*this)[i] = *begin_it;
1422 
1423  return begin() + pos_as_num;
1424  }
1425 
1446  {
1447  return insert(pos, ilist.begin(), ilist.end());
1448  }
1449 
1474  {
1475  if (begin_it >= end_it) // [[unlikely]]
1476  return begin() + std::ranges::distance(cbegin(), end_it);
1477 
1478  auto const length = std::ranges::distance(begin_it, end_it);
1479  auto out_it = begin() + std::ranges::distance(cbegin(), begin_it);
1480 
1481  while (end_it != cend())
1482  *(out_it++) = *(end_it++);
1483 
1484  resize(size() - length);
1485  return begin() + std::ranges::distance(cbegin(), begin_it);
1486  }
1487 
1511  {
1512  return erase(pos, pos + 1);
1513  }
1514 
1532  constexpr void push_back(value_type const value) noexcept
1533  {
1534  assert(size() < bit_capacity);
1535  resize(size() + 1);
1536  (*this)[size() - 1] = value;
1537  }
1538 
1557  constexpr void pop_back() noexcept
1558  {
1559  assert(size() > 0);
1560  resize(size() - 1);
1561  }
1562 
1589  constexpr void resize(size_type const count, value_type const value = false) noexcept
1590  {
1591  assert(count <= bit_capacity);
1592  // Enlarging.
1593  data.bits |= value && count > size() ? ((1ULL << (count - size())) - 1) << size() : 0ULL;
1594  // Set size bits.
1595  data.size = count;
1596  // Shrinking.
1597  data.bits &= (1ULL << size()) - 1ULL;
1598  }
1599 
1615  constexpr void swap(dynamic_bitset & rhs) noexcept
1616  {
1617  bitfield tmp = std::move(data);
1618  data = std::move(rhs.data);
1619  rhs.data = std::move(tmp);
1620  }
1621 
1623  constexpr void swap(dynamic_bitset && rhs) noexcept
1624  {
1625  data = std::move(rhs.data);
1626  }
1627 
1629 
1646  friend constexpr void swap(dynamic_bitset & lhs, dynamic_bitset & rhs) noexcept
1647  {
1648  lhs.swap(rhs);
1649  }
1650 
1664  template <size_t cap>
1665  requires (cap <= bit_capacity)
1666  friend constexpr dynamic_bitset operator&(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1667  {
1668  assert(lhs.size() == rhs.size());
1670  tmp &= rhs;
1671  return tmp;
1672  }
1673 
1684  template <size_t cap>
1685  requires (cap <= bit_capacity)
1686  friend constexpr dynamic_bitset operator^(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1687  {
1688  assert(lhs.size() == rhs.size());
1689  dynamic_bitset tmp{lhs};
1690  tmp ^= rhs;
1691  return tmp;
1692  }
1693 
1704  template <size_t cap>
1705  requires (cap <= bit_capacity)
1706  friend constexpr dynamic_bitset operator|(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1707  {
1708  assert(lhs.size() == rhs.size());
1709  dynamic_bitset tmp{lhs};
1710  tmp |= rhs;
1711  return tmp;
1712  }
1714 
1722  template <size_t cap>
1723  friend constexpr bool operator==(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1724  {
1725  return lhs.data.size == rhs.raw_data()->size && lhs.data.bits == rhs.raw_data()->bits;
1726  }
1727 
1732  template <size_t cap>
1733  friend constexpr bool operator!=(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1734  {
1735  return !(lhs == rhs);
1736  }
1737 
1742  template <size_t cap>
1743  friend constexpr bool operator<(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1744  {
1745  return lhs.data.bits < rhs.raw_data()->bits;
1746  }
1747 
1752  template <size_t cap>
1753  friend constexpr bool operator>(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1754  {
1755  return lhs.data.bits > rhs.raw_data()->bits;
1756  }
1757 
1762  template <size_t cap>
1763  friend constexpr bool operator<=(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1764  {
1765  return !(lhs > rhs);
1766  }
1767 
1772  template <size_t cap>
1773  friend constexpr bool operator>=(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1774  {
1775  return !(lhs < rhs);
1776  }
1778 
1804  template <typename char_t = char>
1805  std::string to_string(char_t zero = char_t{'0'}, char_t one = char_t{'1'}) const
1806  {
1807  std::string str{};
1808  str.reserve(size());
1809  for (bool const bit : std::views::reverse(*this))
1810  bit ? str.push_back(one) : str.push_back(zero);
1811 
1812  return str;
1813  }
1814 
1831  inline constexpr unsigned long to_ulong() const
1832  {
1834  {
1835  if (data.bits > std::numeric_limits<unsigned long>::max())
1836  throw std::overflow_error{"seqan3::dynamic_bitset cannot be represented as unsigned long."};
1837  }
1838 
1839  return static_cast<unsigned long>(data.bits);
1840  }
1841 
1858  inline constexpr unsigned long long to_ullong() const
1859  {
1861  {
1863  throw std::overflow_error{"seqan3::dynamic_bitset cannot be represented as unsigned long long."};
1864  }
1865 
1866  return static_cast<unsigned long long>(data.bits);
1867  }
1869 
1885  {
1886  os << arg.to_string();
1887  return os;
1888  }
1889 
1904  {
1905  // Check if stream is ok and skip leading whitespaces.
1906  std::istream::sentry s(is);
1907  if (s)
1908  {
1909  arg.clear(); // clear the bitset
1910  std::streamsize num_char =
1911  (is.width() > 0) ? std::min<std::streamsize>(is.width(), arg.max_size()) : arg.max_size();
1912  assert(num_char > 0);
1914  tmp.reserve(num_char);
1915  for (std::streamsize n = num_char; n > 0 && (is.peek() == is.widen('0') || is.peek() == is.widen('1')); --n)
1916  {
1917  char c = is.get();
1918  c == is.widen('0') ? tmp.push_back(false) : tmp.push_back(true);
1919  }
1920 
1921  arg.assign(std::views::reverse(tmp));
1922 
1923  if (arg.size() == 0) // nothing extracted so we set the fail bit.
1924  is.setstate(std::ios_base::failbit); // LCOV_EXCL_LINE
1925 
1926  is.width(0); // cancel the effects of std::setw, if any.
1927  }
1928  return is;
1929  }
1930 
1942  template <typename char_t>
1944  {
1946  | ranges::to<std::string>());
1947  return s;
1948  }
1950 
1952 
1963  template <cereal_archive archive_t>
1964  void CEREAL_SERIALIZE_FUNCTION_NAME(archive_t & archive)
1965  {
1966  uint64_t size = data.size;
1967  archive(size);
1968  data.size = size;
1969  uint64_t bits = data.bits;
1970  archive(bits);
1971  data.bits = bits;
1972  }
1974 };
1975 
1976 } // namespace seqan3
1977 
1978 namespace std
1979 {
1980 
1987 template <size_t cap>
1988 struct hash<seqan3::dynamic_bitset<cap>>
1989 {
1997  size_t operator()(seqan3::dynamic_bitset<cap> const arg) const noexcept
1998  {
1999  return static_cast<size_t>(arg.to_ullong());
2000  }
2001 };
2002 
2003 } //namespace std
The <bit> header from C++20's standard library.
Adaptions of concepts from the Cereal library.
A "pretty printer" for most SeqAn data structures and related types.
Definition: debug_stream_type.hpp:78
A constexpr bitset implementation with dynamic size at compile time.
Definition: dynamic_bitset.hpp:54
constexpr dynamic_bitset & operator=(char const (&lit)[N])
Assign from literal.
Definition: dynamic_bitset.hpp:392
constexpr dynamic_bitset operator<<(size_t const count) const noexcept
Performs binary shift left.
Definition: dynamic_bitset.hpp:829
constexpr iterator insert(const_iterator pos, value_type const value) noexcept
Inserts value before pos in the container.
Definition: dynamic_bitset.hpp:1347
constexpr size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition: dynamic_bitset.hpp:1233
constexpr dynamic_bitset & flip(size_t const i)
Flips the i'th bit (binary NOT).
Definition: dynamic_bitset.hpp:993
constexpr dynamic_bitset & reset(size_t const i)
Sets the i'th bit to false.
Definition: dynamic_bitset.hpp:940
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:1445
constexpr bool any() const noexcept
Checks if any bit is set.
Definition: dynamic_bitset.hpp:1018
requires std::sentinel_for< end_it_type, begin_it_type > &&constexpr std::constructible_from< value_type, std::iter_reference_t< begin_it_type > > void assign(begin_it_type begin_it, end_it_type end_it) noexcept
Assign from pair of iterators.
Definition: dynamic_bitset.hpp:535
constexpr void resize(size_type const count, value_type const value=false) noexcept
Resizes the container to contain count elements.
Definition: dynamic_bitset.hpp:1589
friend debug_stream_type< char_t > & operator<<(debug_stream_type< char_t > &s, dynamic_bitset arg)
Formatted debug output for the seqan3::dynamic_bitset.
Definition: dynamic_bitset.hpp:1943
constexpr const_reference test(size_t const i) const
Returns the i-th element.
Definition: dynamic_bitset.hpp:1077
constexpr reference back() noexcept
Returns the last element.
Definition: dynamic_bitset.hpp:1166
constexpr void clear() noexcept
Removes all elements from the container.
Definition: dynamic_bitset.hpp:1322
constexpr size_type count() const noexcept
Returns the number of set bits.
Definition: dynamic_bitset.hpp:1037
constexpr reference front() noexcept
Returns the first element.
Definition: dynamic_bitset.hpp:1136
dynamic_bitset tmp
Returns dynamic_bitset containing the result of binary AND on corresponding pairs of bits of lhs and ...
Definition: dynamic_bitset.hpp:1669
constexpr bool empty() const noexcept
Checks whether the container is empty.
Definition: dynamic_bitset.hpp:1213
constexpr friend bool operator>=(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1773
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:1258
constexpr friend bool operator<=(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1763
constexpr void shrink_to_fit() const noexcept
Since the capacity is fixed on compile time, this is a no-op.
Definition: dynamic_bitset.hpp:1296
constexpr bool all() const noexcept
Checks if all bit are set.
Definition: dynamic_bitset.hpp:1008
reference_proxy_type reference
A proxy type that enables assignment.
Definition: dynamic_bitset.hpp:179
constexpr void assign(char const (&lit)[N])
Assign from literal.
Definition: dynamic_bitset.hpp:419
dynamic_bitset< cap > const &rhs noexcept
Returns dynamic_bitset containing the result of binary AND on corresponding pairs of bits of lhs and ...
Definition: dynamic_bitset.hpp:1667
constexpr const_iterator begin() const noexcept
Returns the begin to the dynamic_bitset.
Definition: dynamic_bitset.hpp:561
constexpr unsigned long to_ulong() const
Converts the dynamic_bitset to an unsigned long integer.
Definition: dynamic_bitset.hpp:1831
constexpr void swap(dynamic_bitset &rhs) noexcept
Swap contents with another instance.
Definition: dynamic_bitset.hpp:1615
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:1623
constexpr dynamic_bitset(char const (&lit)[N])
Construction from literal.
Definition: dynamic_bitset.hpp:366
constexpr reference at(size_t const i)
Returns the i-th element.
Definition: dynamic_bitset.hpp:1059
constexpr friend bool operator!=(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1733
requires(cap<=bit_capacity) friend const expr dynamic_bitset operator|(dynamic_bitset const &lhs
Returns dynamic_bitset containing the result of binary OR on corresponding pairs of bits of lhs and r...
constexpr iterator erase(const_iterator pos) noexcept
Removes specified elements from the container.
Definition: dynamic_bitset.hpp:1510
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:1278
constexpr void push_back(value_type const value) noexcept
Appends the given element value to the end of the container.
Definition: dynamic_bitset.hpp:1532
constexpr friend bool operator<(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1743
constexpr const_iterator cbegin() const noexcept
Returns the begin to the dynamic_bitset.
Definition: dynamic_bitset.hpp:567
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:686
constexpr dynamic_bitset operator>>(size_t const count) const noexcept
Performs binary shift right.
Definition: dynamic_bitset.hpp:800
constexpr const_reference operator[](size_t const i) const noexcept
Returns the i-th element.
Definition: dynamic_bitset.hpp:1112
constexpr unsigned long long to_ullong() const
Converts the dynamic_bitset to an unsigned long long integer.
Definition: dynamic_bitset.hpp:1858
constexpr const_reference back() const noexcept
Returns the last element.
Definition: dynamic_bitset.hpp:1173
tmp &return tmp
Returns dynamic_bitset containing the result of binary AND on corresponding pairs of bits of lhs and ...
Definition: dynamic_bitset.hpp:1670
constexpr friend void swap(dynamic_bitset &lhs, dynamic_bitset &rhs) noexcept
Swap contents with another instance.
Definition: dynamic_bitset.hpp:1646
requires std::sentinel_for< end_it_type, begin_it_type > &&constexpr std::constructible_from< value_type, std::iter_reference_t< begin_it_type > > 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:1405
constexpr iterator end() noexcept
Returns iterator past the end of the dynamic_bitset.
Definition: dynamic_bitset.hpp:582
constexpr void pop_back() noexcept
Removes the last element of the container.
Definition: dynamic_bitset.hpp:1557
constexpr const_reference at(size_t const i) const
Returns the i-th element.
Definition: dynamic_bitset.hpp:1068
constexpr bitfield const * raw_data() const noexcept
Direct access to the underlying bit field.
Definition: dynamic_bitset.hpp:1189
constexpr dynamic_bitset & operator=(std::initializer_list< value_type > const ilist) noexcept
Assign from std::initializer_list.
Definition: dynamic_bitset.hpp:336
constexpr dynamic_bitset & set(size_t const i, bool const value=true)
Sets the i'th bit to value.
Definition: dynamic_bitset.hpp:885
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:656
requires(cap<=bit_capacity) friend const expr dynamic_bitset operator&(dynamic_bitset const &lhs
Returns dynamic_bitset containing the result of binary AND on corresponding pairs of bits of lhs and ...
constexpr iterator begin() noexcept
Returns the begin to the dynamic_bitset.
Definition: dynamic_bitset.hpp:555
friend std::istream & operator>>(std::istream &is, dynamic_bitset &arg)
Formatted input for the seqan3::dynamic_bitset.
Definition: dynamic_bitset.hpp:1903
constexpr void assign(std::initializer_list< value_type > const ilist) noexcept
Assign from std::initializer_list.
Definition: dynamic_bitset.hpp:461
friend std::ostream & operator<<(std::ostream &os, dynamic_bitset const &arg)
Formatted output for the seqan3::dynamic_bitset.
Definition: dynamic_bitset.hpp:1884
constexpr const_iterator cend() const noexcept
Returns iterator past the end of the dynamic_bitset.
Definition: dynamic_bitset.hpp:594
requires std::sentinel_for< end_it_type, begin_it_type > &&constexpr std::constructible_from< value_type, std::iter_reference_t< begin_it_type > > dynamic_bitset(begin_it_type begin_it, end_it_type end_it) noexcept
Construct from two iterators.
Definition: dynamic_bitset.hpp:272
constexpr dynamic_bitset & flip() noexcept
Flips all bits (binary NOT).
Definition: dynamic_bitset.hpp:965
constexpr bool none() const noexcept
Checks if no bit is set.
Definition: dynamic_bitset.hpp:1028
constexpr dynamic_bitset operator~() const noexcept
Returns a temporary copy of *this with all bits flipped (binary NOT).
Definition: dynamic_bitset.hpp:716
bool const_reference
Equals the value_type.
Definition: dynamic_bitset.hpp:185
requires(!std::same_as< std::remove_cvref_t< other_range_t >, dynamic_bitset >) explicit const expr dynamic_bitset(other_range_t &&range) noexcept
Construct from a different range.
Definition: dynamic_bitset.hpp:295
constexpr const_iterator end() const noexcept
Returns iterator past the end of the dynamic_bitset.
Definition: dynamic_bitset.hpp:588
constexpr friend bool operator==(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1723
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:626
constexpr dynamic_bitset & operator=(dynamic_bitset const &) noexcept=default
Defaulted.
constexpr dynamic_bitset & reset() noexcept
Sets all bits to 0.
Definition: dynamic_bitset.hpp:913
constexpr void assign(size_type const count, value_type const value) noexcept
Assign with count times value.
Definition: dynamic_bitset.hpp:482
ptrdiff_t difference_type
A std::ptrdiff_t.
Definition: dynamic_bitset.hpp:203
constexpr dynamic_bitset() noexcept=default
Defaulted.
constexpr const_reference front() const noexcept
Returns the first element.
Definition: dynamic_bitset.hpp:1143
std::string to_string(char_t zero=char_t{ '0'}, char_t one=char_t{ '1'}) const
Converts the dynamic_bitset to a std::string.
Definition: dynamic_bitset.hpp:1805
constexpr iterator erase(const_iterator begin_it, const_iterator end_it) noexcept
Removes specified elements from the container.
Definition: dynamic_bitset.hpp:1473
constexpr dynamic_bitset & operator>>=(size_t const count) noexcept
Performs binary shift right on the current object.
Definition: dynamic_bitset.hpp:772
constexpr dynamic_bitset & operator<<=(size_t const count) noexcept
Performs binary shift left on the current object.
Definition: dynamic_bitset.hpp:743
constexpr dynamic_bitset & set() noexcept
Sets all bits to 1.
Definition: dynamic_bitset.hpp:857
constexpr void reserve(size_t) const noexcept
Since the capacity is fixed on compile time, this is a no-op.
Definition: dynamic_bitset.hpp:1287
requires(cap<=bit_capacity) friend const expr dynamic_bitset operator^(dynamic_bitset const &lhs
Returns dynamic_bitset containing the result of binary XOR on corresponding pairs of bits of lhs and ...
detail::random_access_iterator< dynamic_bitset > iterator
The iterator type of this container (a random access iterator).
Definition: dynamic_bitset.hpp:191
constexpr dynamic_bitset(size_type const n, value_type const value) noexcept
Construct with n times value.
Definition: dynamic_bitset.hpp:316
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:1372
bool value_type
Equals bool.
Definition: dynamic_bitset.hpp:173
detail::random_access_iterator< dynamic_bitset const > const_iterator
The const_iterator type of this container (a random access iterator).
Definition: dynamic_bitset.hpp:197
constexpr reference operator[](size_t const i) noexcept
Returns the i-th element.
Definition: dynamic_bitset.hpp:1105
constexpr bitfield * raw_data() noexcept
Direct access to the underlying bit field.
Definition: dynamic_bitset.hpp:1183
constexpr friend bool operator>(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1753
requires constexpr std::constructible_from< value_type, std::ranges::range_reference_t< other_range_t > > void assign(other_range_t &&range) noexcept
Assign from a different range.
Definition: dynamic_bitset.hpp:508
Provides seqan3::debug_stream and related types.
T get(T... args)
requires std::common_with< typename std::remove_reference_t< validator1_type >::option_value_type, typename std::remove_reference_t< validator2_type >::option_value_type > auto operator|(validator1_type &&vali1, validator2_type &&vali2)
Enables the chaining of validators.
Definition: validators.hpp:1124
constexpr auto repeat_n
A view factory that repeats a given value n times.
Definition: repeat_n.hpp:91
constexpr auto interleave
A view that interleaves a given range into another range at regular intervals.
Definition: interleave.hpp:379
Provides metaprogramming utilities for integer types.
Provides seqan3::views::interleave.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
SeqAn specific customisations in the standard namespace.
T peek(T... args)
Provides seqan3::ranges::to.
Provides seqan3::views::repeat_n.
T reserve(T... args)
T setstate(T... args)
size_t operator()(seqan3::dynamic_bitset< cap > const arg) const noexcept
Compute the hash for a seqan3::dynamic_bitset.
Definition: dynamic_bitset.hpp:1997
T to_string(T... args)
T widen(T... args)
T width(T... args)