OpenTTD Source 20260108-master-g8ba1860eaa
base_bitset_type.hpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#ifndef BASE_BITSET_TYPE_HPP
11#define BASE_BITSET_TYPE_HPP
12
13#include "bitmath_func.hpp"
14
21template <typename Timpl, typename Tvalue_type, typename Tstorage, Tstorage Tmask = std::numeric_limits<Tstorage>::max()>
23public:
24 using ValueType = Tvalue_type;
25 using BaseType = Tstorage;
26 static constexpr Tstorage MASK = Tmask;
27
28 constexpr BaseBitSet() : data(0) {}
29 explicit constexpr BaseBitSet(Tstorage data) : data(data & Tmask) {}
30
31 constexpr auto operator <=>(const BaseBitSet &) const noexcept = default;
32
37 inline constexpr Timpl &Set()
38 {
39 this->data = Tmask;
40 return static_cast<Timpl&>(*this);
41 }
42
48 inline constexpr Timpl &Set(Tvalue_type value)
49 {
50 this->data |= (1ULL << Timpl::DecayValueType(value));
51 return static_cast<Timpl&>(*this);
52 }
53
59 inline constexpr Timpl &Set(const Timpl &other)
60 {
61 this->data |= other.data;
62 return static_cast<Timpl&>(*this);
63 }
64
71 inline constexpr Timpl &Set(Tvalue_type value, bool set)
72 {
73 return set ? this->Set(value) : this->Reset(value);
74 }
75
80 inline constexpr Timpl &Reset()
81 {
82 this->data = 0;
83 return static_cast<Timpl &>(*this);
84 }
85
91 inline constexpr Timpl &Reset(Tvalue_type value)
92 {
93 this->data &= ~(1ULL << Timpl::DecayValueType(value));
94 return static_cast<Timpl&>(*this);
95 }
96
102 inline constexpr Timpl &Reset(const Timpl &other)
103 {
104 this->data &= ~other.data;
105 return static_cast<Timpl&>(*this);
106 }
107
113 inline constexpr Timpl &Flip(Tvalue_type value)
114 {
115 if (this->Test(value)) {
116 return this->Reset(value);
117 } else {
118 return this->Set(value);
119 }
120 }
121
127 inline constexpr Timpl &Flip(const Timpl &other)
128 {
129 this->data ^= other.data;
130 return static_cast<Timpl&>(*this);
131 }
132
138 inline constexpr bool Test(Tvalue_type value) const
139 {
140 return (this->data & (1ULL << Timpl::DecayValueType(value))) != 0;
141 }
142
148 inline constexpr bool All(const Timpl &other) const
149 {
150 return (this->data & other.data) == other.data;
151 }
152
157 inline constexpr bool All() const
158 {
159 return this->data == Tmask;
160 }
161
167 inline constexpr bool Any(const Timpl &other) const
168 {
169 return (this->data & other.data) != 0;
170 }
171
176 inline constexpr bool Any() const
177 {
178 return this->data != 0;
179 }
180
185 inline constexpr bool None() const
186 {
187 return this->data == 0;
188 }
189
190 inline constexpr Timpl &operator|=(const Timpl &other)
191 {
192 this->data |= other.data;
193 return static_cast<Timpl &>(*this);
194 }
195
196 inline constexpr Timpl operator|(const Timpl &other) const
197 {
198 return Timpl{static_cast<Tstorage>(this->data | other.data)};
199 }
200
201 inline constexpr Timpl &operator&=(const Timpl &other)
202 {
203 this->data &= other.data;
204 return static_cast<Timpl &>(*this);
205 }
206
207 inline constexpr Timpl operator&(const Timpl &other) const
208 {
209 return Timpl{static_cast<Tstorage>(this->data & other.data)};
210 }
211
216 inline constexpr Tstorage base() const noexcept
217 {
218 return this->data;
219 }
220
225 inline constexpr bool IsValid() const
226 {
227 return (this->base() & Tmask) == this->base();
228 }
229
234 inline uint Count() const
235 {
236 return CountBits(this->base());
237 }
238
244 std::optional<Tvalue_type> GetNthSetBit(uint n) const
245 {
246 for (auto i : *this) {
247 if (n == 0) return i;
248 --n;
249 }
250
251 return std::nullopt;
252 }
253
254 auto begin() const { return SetBitIterator<Tvalue_type, Tstorage>(this->data).begin(); }
255 auto end() const { return SetBitIterator<Tvalue_type, Tstorage>(this->data).end(); }
256
257private:
258 Tstorage data;
259};
260
261#endif /* BASE_BITSET_TYPE_HPP */
Functions related to bit mathematics.
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
Base for bit set wrapper.
uint Count() const
Count the number of set bits.
constexpr Timpl & Set(Tvalue_type value, bool set)
Assign the value-th bit.
constexpr bool All(const Timpl &other) const
Test if all of the values are set.
constexpr Timpl & Flip(const Timpl &other)
Flip values from another bitset.
Tstorage data
Bitmask of values.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Tstorage base() const noexcept
Retrieve the raw value behind this bit set.
constexpr bool None() const
Test if none of the values are set.
constexpr Timpl & Reset()
Reset all bits.
constexpr bool Any() const
Test if any of the values are set.
constexpr Timpl & Set(const Timpl &other)
Set values from another bitset.
constexpr bool IsValid() const
Test that the raw value of this bit set is valid.
constexpr Timpl & Reset(const Timpl &other)
Reset values from another bitset.
constexpr Timpl & Flip(Tvalue_type value)
Flip the value-th bit.
Tvalue_type ValueType
Value type of this BaseBitSet.
constexpr Timpl & Set()
Set all bits.
Tstorage BaseType
Storage type of this BaseBitSet, be ConvertibleThroughBase.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
constexpr Timpl & Set(Tvalue_type value)
Set the value-th bit.
constexpr bool All() const
Test if all of the values are set.
constexpr Timpl & Reset(Tvalue_type value)
Reset the value-th bit.
std::optional< Tvalue_type > GetNthSetBit(uint n) const
Get the value of the Nth set bit.
Iterable ensemble of each set bit in a value.