SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
dynamic_bitset.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2021, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <seqan3/std/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_}, mask{1ULL<<pos}
104  {}
105 
107  constexpr operator bool() const noexcept
108  {
109  return static_cast<bool>(internal.bits & mask);
110  }
111 
113  constexpr bool operator~() const noexcept
114  {
115  return !static_cast<bool>(internal.bits & mask);
116  }
117 
119  constexpr reference_proxy_type & operator|=(bool const value)
120  {
121  if (value)
122  set();
123 
124  return *this;
125  }
126 
128  constexpr reference_proxy_type & operator&=(bool const value)
129  {
130  if (!value)
131  reset();
132 
133  return *this;
134  }
135 
137  constexpr reference_proxy_type & operator^=(bool const value)
138  {
139  operator bool() && value ? reset() : set();
140  return *this;
141  }
142 
143  private:
145  bitfield & internal;
147  uint64_t mask;
148 
150  constexpr void set() noexcept
151  {
152  internal.bits |= mask;
153  }
154 
156  constexpr void reset() noexcept
157  {
158  internal.bits &= ~mask;
159  }
160  };
161 
162 public:
163  static_assert(bit_capacity <= 58, "The capacity of the dynamic_bitset exceeds the limit of 58.");
164 
172  using value_type = bool;
173 
178  using reference = reference_proxy_type;
179 
184  using const_reference = bool;
185 
190  using iterator = detail::random_access_iterator<dynamic_bitset>;
191 
196  using const_iterator = detail::random_access_iterator<dynamic_bitset const>;
197 
202  using difference_type = ptrdiff_t;
203 
210 
212  // this signals to range-v3 that something is a container :|
213  using allocator_type = void;
215 
219  constexpr dynamic_bitset() noexcept = default;
220  constexpr dynamic_bitset(dynamic_bitset const &) noexcept = default;
221  constexpr dynamic_bitset(dynamic_bitset &&) noexcept = default;
222  constexpr dynamic_bitset & operator=(dynamic_bitset const &) noexcept = default;
223  constexpr dynamic_bitset & operator=(dynamic_bitset &&) noexcept = default;
224  ~dynamic_bitset() noexcept = default;
225 
246  constexpr dynamic_bitset(uint64_t const value)
247  {
248  if (std::popcount(value >> 58u) != 0u)
249  throw std::invalid_argument{"The dynamic_bitset can be at most 58 long."};
250  data.bits |= value;
251  data.size |= std::bit_width(value);
252  }
253 
273  template <std::forward_iterator begin_it_type, typename end_it_type>
275  requires std::sentinel_for<end_it_type, begin_it_type> &&
276  std::constructible_from<value_type, std::iter_reference_t<begin_it_type>>
278  constexpr dynamic_bitset(begin_it_type begin_it, end_it_type end_it) noexcept:
280  {
281  assign(begin_it, end_it);
282  }
283 
301  template <std::ranges::input_range other_range_t>
303  requires (!std::same_as<std::remove_cvref_t<other_range_t>, dynamic_bitset>)
305  explicit constexpr dynamic_bitset(other_range_t && range) noexcept :
306  dynamic_bitset{std::ranges::begin(range), std::ranges::end(range)}
307  {}
308 
325  constexpr dynamic_bitset(size_type const n, value_type const value) noexcept :
327  {
328  assign(n, value);
329  }
330 
347  {
348  assign(std::ranges::begin(ilist), std::ranges::end(ilist));
349  return *this;
350  }
351 
375  template <size_t N>
376  constexpr dynamic_bitset(char const (&lit)[N]) : dynamic_bitset{}
377  {
378  static_assert(N <= bit_capacity + 1, "Length of string literal exceeds capacity of dynamic_bitset.");
379  assign(lit);
380  }
381 
401  template <size_t N>
402  constexpr dynamic_bitset & operator=(char const (&lit)[N])
403  {
404  static_assert(N <= bit_capacity + 1, "Length of string literal exceeds capacity of dynamic_bitset.");
405  assign(lit);
406  return *this;
407  }
408 
428  template <size_t N>
429  constexpr void assign(char const (&lit)[N])
430  {
431  static_assert(N <= bit_capacity + 1, "Length of string literal exceeds capacity of dynamic_bitset.");
432  assert(lit[N - 1] == '\0');
433  uint64_t value{};
434 
435  for (size_t i = 0; i != N - 1; ++i)
436  {
437  if (lit[i] == '0')
438  {
439  value <<= 1;
440  }
441  else if (lit[i] == '1')
442  {
443  value <<= 1;
444  value |= 1u;
445  }
446  else
447  {
448  throw std::invalid_argument{"The string to construct a dynamic_bitset from may only contain 0 and 1."};
449  }
450  }
451 
452  *this = value;
453  resize(N - 1);
454  }
455 
471  constexpr void assign(std::initializer_list<value_type> const ilist) noexcept
472  {
473  assign(std::ranges::begin(ilist), std::ranges::end(ilist));
474  }
475 
492  constexpr void assign(size_type const count, value_type const value) noexcept
493  {
494  clear();
495  auto tmp = views::repeat_n(value, count);
496  assign(std::ranges::begin(tmp), std::ranges::end(tmp));
497  }
498 
516  template <std::ranges::input_range other_range_t>
518  requires std::constructible_from<value_type, std::ranges::range_reference_t<other_range_t>>
520  constexpr void assign(other_range_t && range) noexcept
521  {
522  assign(std::ranges::begin(range), std::ranges::end(range));
523  }
524 
544  template <std::forward_iterator begin_it_type, typename end_it_type>
546  requires std::sentinel_for<end_it_type, begin_it_type> &&
547  std::constructible_from<value_type, std::iter_reference_t<begin_it_type>>
549  constexpr void assign(begin_it_type begin_it, end_it_type end_it) noexcept
550  {
551  clear();
552  insert(cbegin(), begin_it, end_it);
553  }
555 
569  constexpr iterator begin() noexcept
570  {
571  return iterator{*this};
572  }
573 
575  constexpr const_iterator begin() const noexcept
576  {
577  return const_iterator{*this};
578  }
579 
581  constexpr const_iterator cbegin() const noexcept
582  {
583  return begin();
584  }
585 
596  constexpr iterator end() noexcept
597  {
598  return iterator{*this, size()};
599  }
600 
602  constexpr const_iterator end() const noexcept
603  {
604  return const_iterator{*this, size()};
605  }
606 
608  constexpr const_iterator cend() const noexcept
609  {
610  return end();
611  }
613 
640  constexpr dynamic_bitset & operator&=(dynamic_bitset const & rhs) noexcept
641  {
642  assert(size() == rhs.size());
643  data.bits &= rhs.data.bits;
644  return *this;
645  }
646 
670  constexpr dynamic_bitset & operator|=(dynamic_bitset const & rhs) noexcept
671  {
672  assert(size() == rhs.size());
673  data.bits |= rhs.data.bits;
674  return *this;
675  }
676 
700  constexpr dynamic_bitset & operator^=(dynamic_bitset const & rhs) noexcept
701  {
702  assert(size() == rhs.size());
703  data.bits ^= rhs.data.bits;
704  return *this;
705  }
706 
730  constexpr dynamic_bitset operator~() const noexcept
731  {
732  dynamic_bitset tmp{*this};
733  tmp.flip();
734  return tmp;
735  }
736 
757  constexpr dynamic_bitset & operator<<=(size_t const count) noexcept
758  {
759  assert(count > 0);
760  assert(count < size());
761  data.bits <<= count;
762  data.bits &= (1ULL << size()) - 1ULL;
763  return *this;
764  }
765 
786  constexpr dynamic_bitset & operator>>=(size_t const count) noexcept
787  {
788  assert(count > 0);
789  assert(count < size());
790  data.bits >>= count;
791  return *this;
792  }
793 
814  constexpr dynamic_bitset operator>>(size_t const count) const noexcept
815  {
816  assert(count > 0);
817  assert(count < size());
818  dynamic_bitset tmp{*this};
819  tmp >>= count;
820  return tmp;
821  }
822 
843  constexpr dynamic_bitset operator<<(size_t const count) const noexcept
844  {
845  assert(count > 0);
846  assert(count < size());
847  dynamic_bitset tmp{*this};
848  tmp <<= count;
849  return tmp;
850  }
851 
871  constexpr dynamic_bitset & set() noexcept
872  {
873  data.bits |= (1ULL << size()) - 1ULL;
874  return *this;
875  }
876 
899  constexpr dynamic_bitset & set(size_t const i, bool const value = true)
900  {
901  at(i) = value;
902  return *this;
903  }
904 
927  constexpr dynamic_bitset & reset() noexcept
928  {
929  data.bits = 0u;
930  return *this;
931  }
932 
954  constexpr dynamic_bitset & reset(size_t const i)
955  {
956  set(i, false);
957  return *this;
958  }
959 
979  constexpr dynamic_bitset & flip() noexcept
980  {
981  data.bits = ~data.bits;
982  data.bits &= (1ULL << size()) - 1ULL;
983  return *this;
984  }
985 
1007  constexpr dynamic_bitset & flip(size_t const i)
1008  {
1009  at(i) ? reset(i) : set(i);
1010  return *this;
1011  }
1013 
1022  constexpr bool all() const noexcept
1023  {
1024  return count() == size();
1025  }
1026 
1032  constexpr bool any() const noexcept
1033  {
1034  return count() != 0;
1035  }
1036 
1042  constexpr bool none() const noexcept
1043  {
1044  return count() == 0;
1045  }
1046 
1051  constexpr size_type count() const noexcept
1052  {
1053  return std::popcount(data.bits);
1054  }
1055 
1073  constexpr reference at(size_t const i)
1074  {
1075  if (i >= size()) // [[unlikely]]
1076  throw std::out_of_range{"Trying to access position " + std::to_string(i) +
1077  " in a seqan3::dynamic_bitset of size " + std::to_string(size()) + "."};
1078  return (*this)[i];
1079  }
1080 
1082  constexpr const_reference at(size_t const i) const
1083  {
1084  if (i >= size()) // [[unlikely]]
1085  throw std::out_of_range{"Trying to access position " + std::to_string(i) +
1086  " in a seqan3::dynamic_bitset of size " + std::to_string(size()) + "."};
1087  return (*this)[i];
1088  }
1089 
1091  constexpr const_reference test(size_t const i) const
1092  {
1093  return at(i);
1094  }
1095 
1119  constexpr reference operator[](size_t const i) noexcept
1120  {
1121  assert(i < size());
1122  return {data, i};
1123  }
1124 
1126  constexpr const_reference operator[](size_t const i) const noexcept
1127  {
1128  assert(i < size());
1129  return data.bits & 1ULL << i;
1130  }
1131 
1150  constexpr reference front() noexcept
1151  {
1152  assert(size() > 0);
1153  return (*this)[0];
1154  }
1155 
1157  constexpr const_reference front() const noexcept
1158  {
1159  assert(size() > 0);
1160  return (*this)[0];
1161  }
1162 
1180  constexpr reference back() noexcept
1181  {
1182  assert(size() > 0);
1183  return (*this)[size() - 1];
1184  }
1185 
1187  constexpr const_reference back() const noexcept
1188  {
1189  assert(size() > 0);
1190  return (*this)[size() - 1];
1191  }
1192 
1197  constexpr bitfield * raw_data() noexcept
1198  {
1199  return &data;
1200  }
1201 
1203  constexpr bitfield const * raw_data() const noexcept
1204  {
1205  return &data;
1206  }
1208 
1227  constexpr bool empty() const noexcept
1228  {
1229  return size() == 0;
1230  }
1231 
1247  constexpr size_type size() const noexcept
1248  {
1249  return data.size;
1250  }
1251 
1272  constexpr size_type max_size() const noexcept
1273  {
1274  return capacity();
1275  }
1276 
1292  constexpr size_type capacity() const noexcept
1293  {
1294  return bit_capacity;
1295  }
1296 
1301  constexpr void reserve(size_t) const noexcept
1302  {
1303  // no-op
1304  }
1305 
1310  constexpr void shrink_to_fit() const noexcept
1311  {
1312  // no-op
1313  }
1315 
1336  constexpr void clear() noexcept
1337  {
1338  data.size &= 0ULL;
1339  data.bits &= 0ULL;
1340  }
1341 
1361  constexpr iterator insert(const_iterator pos, value_type const value) noexcept
1362  {
1363  return insert(pos, 1, value);
1364  }
1365 
1386  constexpr iterator insert(const_iterator pos, size_type const count, value_type const value) noexcept
1387  {
1388  auto tmp = views::repeat_n(value, count);
1389  return insert(pos, std::ranges::begin(tmp), std::ranges::end(tmp));
1390  }
1391 
1416  template <std::forward_iterator begin_it_type, typename end_it_type>
1418  requires std::sentinel_for<end_it_type, begin_it_type> &&
1419  std::constructible_from<value_type, std::iter_reference_t<begin_it_type>>
1421  constexpr iterator insert(const_iterator pos, begin_it_type begin_it, end_it_type end_it) noexcept
1422  {
1423  auto const pos_as_num = std::ranges::distance(cbegin(), pos);
1424  auto const length = std::ranges::distance(begin_it, end_it);
1425 
1426  if (length == 0)
1427  return begin(); // nothing to insert
1428 
1429  size_type const tmp_size{size()};
1430  resize(tmp_size + length);
1431 
1432  for (size_type i = tmp_size + length - 1; i > pos_as_num + length - 1; --i)
1433  (*this)[i] = (*this)[i - length];
1434 
1435  // std::ranges::copy(begin_it, end_it, (*this)[pos_as_num]);
1436  for (auto i = pos_as_num; begin_it != end_it; ++i, ++begin_it)
1437  (*this)[i] = *begin_it;
1438 
1439  return begin() + pos_as_num;
1440  }
1441 
1461  constexpr iterator insert(const_iterator pos, std::initializer_list<value_type> const & ilist) noexcept
1462  {
1463  return insert(pos, ilist.begin(), ilist.end());
1464  }
1465 
1489  constexpr iterator erase(const_iterator begin_it, const_iterator end_it) noexcept
1490  {
1491  if (begin_it >= end_it) // [[unlikely]]
1492  return begin() + std::ranges::distance(cbegin(), end_it);
1493 
1494  auto const length = std::ranges::distance(begin_it, end_it);
1495  auto out_it = begin() + std::ranges::distance(cbegin(), begin_it);
1496 
1497  while (end_it != cend())
1498  *(out_it++) = *(end_it++);
1499 
1500  resize(size() - length);
1501  return begin() + std::ranges::distance(cbegin(), begin_it);
1502  }
1503 
1526  constexpr iterator erase(const_iterator pos) noexcept
1527  {
1528  return erase(pos, pos + 1);
1529  }
1530 
1548  constexpr void push_back(value_type const value) noexcept
1549  {
1550  assert(size() < bit_capacity);
1551  resize(size() + 1);
1552  (*this)[size() - 1] = value;
1553  }
1554 
1573  constexpr void pop_back() noexcept
1574  {
1575  assert(size() > 0);
1576  resize(size() - 1);
1577  }
1578 
1605  constexpr void resize(size_type const count, value_type const value = false) noexcept
1606  {
1607  assert(count <= bit_capacity);
1608  // Enlarging.
1609  data.bits |= value && count > size() ? ((1ULL << (count - size())) - 1) << size() : 0ULL;
1610  // Set size bits.
1611  data.size = count;
1612  // Shrinking.
1613  data.bits &= (1ULL << size()) - 1ULL;
1614  }
1615 
1631  constexpr void swap(dynamic_bitset & rhs) noexcept
1632  {
1633  bitfield tmp = std::move(data);
1634  data = std::move(rhs.data);
1635  rhs.data = std::move(tmp);
1636  }
1637 
1639  constexpr void swap(dynamic_bitset && rhs) noexcept
1640  {
1641  data = std::move(rhs.data);
1642  }
1643 
1645 
1662  friend constexpr void swap(dynamic_bitset & lhs, dynamic_bitset & rhs) noexcept
1663  {
1664  lhs.swap(rhs);
1665  }
1666 
1680  template <size_t cap>
1682  requires (cap <= bit_capacity)
1684  friend constexpr dynamic_bitset operator&(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1685  {
1686  assert(lhs.size() == rhs.size());
1687  dynamic_bitset tmp{lhs};
1688  tmp &= rhs;
1689  return tmp;
1690  }
1691 
1702  template <size_t cap>
1704  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  }
1713 
1724  template <size_t cap>
1726  requires (cap <= bit_capacity)
1728  friend constexpr dynamic_bitset operator|(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1729  {
1730  assert(lhs.size() == rhs.size());
1731  dynamic_bitset tmp{lhs};
1732  tmp |= rhs;
1733  return tmp;
1734  }
1736 
1744  template <size_t cap>
1745  friend constexpr bool operator==(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1746  {
1747  return lhs.data.size == rhs.raw_data()->size && lhs.data.bits == rhs.raw_data()->bits;
1748  }
1749 
1754  template <size_t cap>
1755  friend constexpr bool operator!=(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1756  {
1757  return !(lhs == rhs);
1758  }
1759 
1764  template <size_t cap>
1765  friend constexpr bool operator<(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1766  {
1767  return lhs.data.bits < rhs.raw_data()->bits;
1768  }
1769 
1774  template <size_t cap>
1775  friend constexpr bool operator>(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1776  {
1777  return lhs.data.bits > rhs.raw_data()->bits;
1778  }
1779 
1784  template <size_t cap>
1785  friend constexpr bool operator<=(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1786  {
1787  return !(lhs > rhs);
1788  }
1789 
1794  template <size_t cap>
1795  friend constexpr bool operator>=(dynamic_bitset const & lhs, dynamic_bitset<cap> const & rhs) noexcept
1796  {
1797  return !(lhs < rhs);
1798  }
1800 
1826  template <typename char_t = char>
1827  std::string to_string(char_t zero = char_t{'0'}, char_t one = char_t{'1'}) const
1828  {
1829  std::string str{};
1830  str.reserve(size());
1831  for (bool const bit : std::views::reverse(*this))
1832  bit ? str.push_back(one) : str.push_back(zero);
1833 
1834  return str;
1835  }
1836 
1853  inline constexpr unsigned long to_ulong() const
1854  {
1856  {
1857  if (data.bits > std::numeric_limits<unsigned long>::max())
1858  throw std::overflow_error{"seqan3::dynamic_bitset cannot be represented as unsigned long."};
1859  }
1860 
1861  return static_cast<unsigned long>(data.bits);
1862  }
1863 
1880  inline constexpr unsigned long long to_ullong() const
1881  {
1883  {
1885  throw std::overflow_error{"seqan3::dynamic_bitset cannot be represented as unsigned long long."};
1886  }
1887 
1888  return static_cast<unsigned long long>(data.bits);
1889  }
1891 
1907  {
1908  os << arg.to_string();
1909  return os;
1910  }
1911 
1926  {
1927  // Check if stream is ok and skip leading whitespaces.
1928  std::istream::sentry s(is);
1929  if (s)
1930  {
1931  arg.clear(); // clear the bitset
1932  std::streamsize num_char = (is.width() > 0)
1933  ? std::min<std::streamsize>(is.width(), arg.max_size())
1934  : arg.max_size();
1935  assert(num_char > 0);
1936  std::vector<bool> tmp{};
1937  tmp.reserve(num_char);
1938  for (std::streamsize n = num_char; n > 0 && (is.peek() == is.widen('0') || is.peek() == is.widen('1')); --n)
1939  {
1940  char c = is.get();
1941  c == is.widen('0') ? tmp.push_back(false) : tmp.push_back(true);
1942  }
1943 
1944  arg.assign(std::views::reverse(tmp));
1945 
1946  if (arg.size() == 0) // nothing extracted so we set the fail bit.
1947  is.setstate(std::ios_base::failbit); // LCOV_EXCL_LINE
1948 
1949  is.width(0); // cancel the effects of std::setw, if any.
1950  }
1951  return is;
1952  }
1953 
1965  template <typename char_t>
1967  {
1968  s << (std::string_view{arg.to_string()} | views::interleave(4, std::string_view{"'"}) | views::to<std::string>);
1969  return s;
1970  }
1972 
1974 
1985  template <cereal_archive archive_t>
1986  void CEREAL_SERIALIZE_FUNCTION_NAME(archive_t & archive)
1987  {
1988  uint64_t size = data.size;
1989  archive(size);
1990  data.size = size;
1991  uint64_t bits = data.bits;
1992  archive(bits);
1993  data.bits = bits;
1994  }
1996 };
1997 
1998 } // namespace seqan3
1999 
2000 namespace std
2001 {
2002 
2009 template <size_t cap>
2010 struct hash<seqan3::dynamic_bitset<cap>>
2011 {
2019  size_t operator()(seqan3::dynamic_bitset<cap> const arg) const noexcept
2020  {
2021  return static_cast<size_t>(arg.to_ullong());
2022  }
2023 };
2024 
2025 } //namespace std
Provides the C++20 <bit> header if it is not already available.
Adaptions of concepts from the Cereal library.
A "pretty printer" for most SeqAn data structures and related types.
Definition: debug_stream_type.hpp:76
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:402
constexpr dynamic_bitset operator<<(size_t const count) const noexcept
Performs binary shift left.
Definition: dynamic_bitset.hpp:843
friend class dynamic_bitset
Befriend other template instantiations of dynamic_bitset.
Definition: dynamic_bitset.hpp:58
constexpr iterator insert(const_iterator pos, value_type const value) noexcept
Inserts value before pos in the container.
Definition: dynamic_bitset.hpp:1361
constexpr size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition: dynamic_bitset.hpp:1247
constexpr dynamic_bitset & flip(size_t const i)
Flips the i'th bit (binary NOT).
Definition: dynamic_bitset.hpp:1007
constexpr dynamic_bitset & reset(size_t const i)
Sets the i'th bit to false.
Definition: dynamic_bitset.hpp:954
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:1461
constexpr bool any() const noexcept
Checks if any bit is set.
Definition: dynamic_bitset.hpp:1032
constexpr void resize(size_type const count, value_type const value=false) noexcept
Resizes the container to contain count elements.
Definition: dynamic_bitset.hpp:1605
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:1966
constexpr const_reference test(size_t const i) const
Returns the i-th element.
Definition: dynamic_bitset.hpp:1091
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:1421
constexpr reference back() noexcept
Returns the last element.
Definition: dynamic_bitset.hpp:1180
constexpr void clear() noexcept
Removes all elements from the container.
Definition: dynamic_bitset.hpp:1336
constexpr size_type count() const noexcept
Returns the number of set bits.
Definition: dynamic_bitset.hpp:1051
constexpr reference front() noexcept
Returns the first element.
Definition: dynamic_bitset.hpp:1150
constexpr bool empty() const noexcept
Checks whether the container is empty.
Definition: dynamic_bitset.hpp:1227
constexpr friend bool operator>=(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1795
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:1272
constexpr friend bool operator<=(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1785
constexpr void shrink_to_fit() const noexcept
Since the capacity is fixed on compile time, this is a no-op.
Definition: dynamic_bitset.hpp:1310
constexpr bool all() const noexcept
Checks if all bit are set.
Definition: dynamic_bitset.hpp:1022
reference_proxy_type reference
A proxy type that enables assignment.
Definition: dynamic_bitset.hpp:178
constexpr void assign(char const (&lit)[N])
Assign from literal.
Definition: dynamic_bitset.hpp:429
constexpr const_iterator begin() const noexcept
Returns the begin to the dynamic_bitset.
Definition: dynamic_bitset.hpp:575
constexpr unsigned long to_ulong() const
Converts the dynamic_bitset to an unsigned long integer.
Definition: dynamic_bitset.hpp:1853
constexpr void swap(dynamic_bitset &rhs) noexcept
Swap contents with another instance.
Definition: dynamic_bitset.hpp:1631
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:1639
constexpr dynamic_bitset(char const (&lit)[N])
Construction from literal.
Definition: dynamic_bitset.hpp:376
constexpr reference at(size_t const i)
Returns the i-th element.
Definition: dynamic_bitset.hpp:1073
constexpr friend bool operator!=(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1755
constexpr iterator erase(const_iterator pos) noexcept
Removes specified elements from the container.
Definition: dynamic_bitset.hpp:1526
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:1292
constexpr void push_back(value_type const value) noexcept
Appends the given element value to the end of the container.
Definition: dynamic_bitset.hpp:1548
constexpr friend bool operator<(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1765
constexpr const_iterator cbegin() const noexcept
Returns the begin to the dynamic_bitset.
Definition: dynamic_bitset.hpp:581
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:700
constexpr dynamic_bitset operator>>(size_t const count) const noexcept
Performs binary shift right.
Definition: dynamic_bitset.hpp:814
constexpr const_reference operator[](size_t const i) const noexcept
Returns the i-th element.
Definition: dynamic_bitset.hpp:1126
constexpr unsigned long long to_ullong() const
Converts the dynamic_bitset to an unsigned long long integer.
Definition: dynamic_bitset.hpp:1880
constexpr const_reference back() const noexcept
Returns the last element.
Definition: dynamic_bitset.hpp:1187
constexpr friend void swap(dynamic_bitset &lhs, dynamic_bitset &rhs) noexcept
Swap contents with another instance.
Definition: dynamic_bitset.hpp:1662
constexpr iterator end() noexcept
Returns iterator past the end of the dynamic_bitset.
Definition: dynamic_bitset.hpp:596
constexpr void pop_back() noexcept
Removes the last element of the container.
Definition: dynamic_bitset.hpp:1573
constexpr const_reference at(size_t const i) const
Returns the i-th element.
Definition: dynamic_bitset.hpp:1082
constexpr bitfield const * raw_data() const noexcept
Direct access to the underlying bit field.
Definition: dynamic_bitset.hpp:1203
constexpr dynamic_bitset & operator=(std::initializer_list< value_type > const ilist) noexcept
Assign from std::initializer_list.
Definition: dynamic_bitset.hpp:346
constexpr dynamic_bitset(begin_it_type begin_it, end_it_type end_it) noexcept
Construct from two iterators.
Definition: dynamic_bitset.hpp:278
constexpr dynamic_bitset & set(size_t const i, bool const value=true)
Sets the i'th bit to value.
Definition: dynamic_bitset.hpp:899
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:670
constexpr iterator begin() noexcept
Returns the begin to the dynamic_bitset.
Definition: dynamic_bitset.hpp:569
friend std::istream & operator>>(std::istream &is, dynamic_bitset &arg)
Formatted input for the seqan3::dynamic_bitset.
Definition: dynamic_bitset.hpp:1925
constexpr void assign(std::initializer_list< value_type > const ilist) noexcept
Assign from std::initializer_list.
Definition: dynamic_bitset.hpp:471
friend std::ostream & operator<<(std::ostream &os, dynamic_bitset const &arg)
Formatted output for the seqan3::dynamic_bitset.
Definition: dynamic_bitset.hpp:1906
constexpr const_iterator cend() const noexcept
Returns iterator past the end of the dynamic_bitset.
Definition: dynamic_bitset.hpp:608
constexpr dynamic_bitset & flip() noexcept
Flips all bits (binary NOT).
Definition: dynamic_bitset.hpp:979
constexpr bool none() const noexcept
Checks if no bit is set.
Definition: dynamic_bitset.hpp:1042
constexpr dynamic_bitset operator~() const noexcept
Returns a temporary copy of *this with all bits flipped (binary NOT).
Definition: dynamic_bitset.hpp:730
bool const_reference
Equals the value_type.
Definition: dynamic_bitset.hpp:184
constexpr const_iterator end() const noexcept
Returns iterator past the end of the dynamic_bitset.
Definition: dynamic_bitset.hpp:602
constexpr void assign(other_range_t &&range) noexcept
Assign from a different range.
Definition: dynamic_bitset.hpp:520
constexpr friend bool operator==(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1745
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:640
constexpr dynamic_bitset & operator=(dynamic_bitset const &) noexcept=default
Defaulted.
constexpr dynamic_bitset & reset() noexcept
Sets all bits to 0.
Definition: dynamic_bitset.hpp:927
constexpr void assign(size_type const count, value_type const value) noexcept
Assign with count times value.
Definition: dynamic_bitset.hpp:492
ptrdiff_t difference_type
A std::ptrdiff_t.
Definition: dynamic_bitset.hpp:202
constexpr dynamic_bitset() noexcept=default
Defaulted.
constexpr const_reference front() const noexcept
Returns the first element.
Definition: dynamic_bitset.hpp:1157
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:1827
constexpr iterator erase(const_iterator begin_it, const_iterator end_it) noexcept
Removes specified elements from the container.
Definition: dynamic_bitset.hpp:1489
constexpr dynamic_bitset & operator>>=(size_t const count) noexcept
Performs binary shift right on the current object.
Definition: dynamic_bitset.hpp:786
constexpr dynamic_bitset & operator<<=(size_t const count) noexcept
Performs binary shift left on the current object.
Definition: dynamic_bitset.hpp:757
constexpr dynamic_bitset & set() noexcept
Sets all bits to 1.
Definition: dynamic_bitset.hpp:871
constexpr void assign(begin_it_type begin_it, end_it_type end_it) noexcept
Assign from pair of iterators.
Definition: dynamic_bitset.hpp:549
constexpr void reserve(size_t) const noexcept
Since the capacity is fixed on compile time, this is a no-op.
Definition: dynamic_bitset.hpp:1301
detail::random_access_iterator< dynamic_bitset > iterator
The iterator type of this container (a random access iterator).
Definition: dynamic_bitset.hpp:190
constexpr dynamic_bitset(size_type const n, value_type const value) noexcept
Construct with n times value.
Definition: dynamic_bitset.hpp:325
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:1386
bool value_type
Equals bool.
Definition: dynamic_bitset.hpp:172
detail::random_access_iterator< dynamic_bitset const > const_iterator
The const_iterator type of this container (a random access iterator).
Definition: dynamic_bitset.hpp:196
constexpr reference operator[](size_t const i) noexcept
Returns the i-th element.
Definition: dynamic_bitset.hpp:1119
constexpr bitfield * raw_data() noexcept
Direct access to the underlying bit field.
Definition: dynamic_bitset.hpp:1197
constexpr friend bool operator>(dynamic_bitset const &lhs, dynamic_bitset< cap > const &rhs) noexcept
Performs element-wise comparison.
Definition: dynamic_bitset.hpp:1775
Provides seqan3::debug_stream and related types.
T get(T... args)
constexpr int popcount(T x) noexcept
Returns the number of 1 bits in the value of x.
Definition: bit:216
constexpr T bit_width(T x) noexcept
If x is not zero, calculates the number of bits needed to store the value x, that is,...
Definition: bit:154
constexpr auto repeat_n
A view factory that repeats a given value n times.
Definition: repeat_n.hpp:95
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:74
constexpr auto interleave
A view that interleaves a given range into another range at regular intervals.
Definition: interleave.hpp:384
Provides metaprogramming utilities for integer types.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
SeqAn specific customisations in the standard namespace.
T peek(T... args)
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:2019
T to_string(T... args)
Provides seqan3::views::interleave.
Provides seqan3::views::repeat_n.
Provides seqan3::views::to.
T widen(T... args)
T width(T... args)