58 static_assert(0 < N && 64 >= N,
"BitSet is defined for [1..64] bits");
61 using T = std::conditional_t<
63 std::conditional_t<16 >= N, std::uint16_t,
64 std::conditional_t<32 >= N, std::uint32_t, std::uint64_t>>>;
69 static constexpr T
const ALL_SET = []() {
70 if constexpr (std::numeric_limits<T>::digits == N) {
71 return static_cast<T
>(~T(0));
73 return static_cast<T
>(~(
static_cast<T
>(~T(0)) << N));
82 constexpr Reference& operator=(
bool v)
noexcept
85 T
const y =
static_cast<T
>(~bit_);
86 T
const z =
static_cast<T
>(v) << pos_;
94 constexpr operator bool()
const noexcept {
return !!(set_ & bit_); }
96 constexpr bool operator~()
const noexcept {
return !(set_ & bit_); }
105 constexpr Reference(T& set, std::size_t pos) noexcept
106 : set_(set), pos_(pos), bit_(
static_cast<T
>(T(1) << pos))
116 constexpr BitSet() noexcept = default;
118 constexpr
BitSet(T val) noexcept : set_(val & ALL_SET) {}
120 template <
class CharT,
class Traits,
class Alloc>
121 explicit BitSet(std::basic_string<CharT, Traits, Alloc>
const& str,
122 typename std::basic_string<CharT, Traits, Alloc>::size_type pos = 0,
123 typename std::basic_string<CharT, Traits, Alloc>::size_type n =
124 std::basic_string<CharT, Traits, Alloc>::npos,
125 CharT zero = CharT(
'0'), CharT one = CharT(
'1'))
130 template <
class CharT>
133 typename std::basic_string<CharT>::size_type n = std::basic_string<CharT>::npos,
134 CharT zero = CharT(
'0'), CharT one = CharT(
'1'))
139 constexpr bool operator==(BitSet rhs)
const noexcept {
return set_ == rhs.set_; }
141 constexpr bool operator!=(BitSet rhs)
const noexcept {
return !(*
this == rhs); }
143 [[nodiscard]]
constexpr bool operator[](std::size_t pos)
const
146 return (set_ >> pos) & T(1);
149 [[nodiscard]]
constexpr Reference operator[](std::size_t pos)
152 return Reference(set_, pos);
155 [[nodiscard]]
bool test(std::size_t pos)
const
158 std::out_of_range(
"position (which is " + std::to_string(pos) +
159 ") >= size (which is " + std::to_string(size()) +
")");
161 return operator[](pos);
164 [[nodiscard]]
constexpr bool all() const noexcept {
return ALL_SET == set_; }
166 [[nodiscard]]
constexpr bool any() const noexcept {
return !none(); }
168 [[nodiscard]]
constexpr bool none() const noexcept {
return T(0) == set_; }
170 [[nodiscard]]
constexpr bool some() const noexcept {
return !all() && !none(); }
172 [[nodiscard]]
constexpr std::size_t count() const noexcept
174 return std::popcount(set_);
177 [[nodiscard]]
static constexpr std::size_t size() noexcept {
return N; }
179 constexpr BitSet& operator&=(BitSet
const other)
noexcept
185 constexpr BitSet& operator|=(BitSet
const& other)
noexcept
191 constexpr BitSet& operator^=(BitSet
const& other)
noexcept
197 constexpr BitSet operator~() const noexcept {
return BitSet(
static_cast<T
>(~set_)); }
199 constexpr void set() noexcept { set_ = ALL_SET; }
201 constexpr void set(std::size_t pos,
bool value)
206 T
const y =
static_cast<T
>(~(T(1) << pos));
207 T
const z =
static_cast<T
>(value) << pos;
212 constexpr void set(std::size_t pos)
218 constexpr void reset() noexcept { set_ = 0; }
220 constexpr void reset(std::size_t pos)
223 set_ &=
static_cast<T
>(~(T(1) << pos));
226 constexpr void flip() noexcept { set_ =
static_cast<T
>(~set_); }
228 constexpr void flip(std::size_t pos)
231 set_ ^=
static_cast<T
>(T(1) << pos);
234 [[nodiscard]]
constexpr value_type data()
const {
return set_; }
259std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
266std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is,
constexpr Vec< Dim, T > operator^(Vec< Dim, T > lhs, Vec< Dim, T > const &rhs) noexcept
Component-wise bitwise XOR of two integral vectors.