OpenTTD Source 20250613-master-ga1786fa1f4
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 <http://www.gnu.org/licenses/>.
6 */
7
13#ifndef BASE_BITSET_TYPE_HPP
14#define BASE_BITSET_TYPE_HPP
15
16#include "bitmath_func.hpp"
17
24template <typename Timpl, typename Tvalue_type, typename Tstorage, Tstorage Tmask = std::numeric_limits<Tstorage>::max()>
26public:
27 using ValueType = Tvalue_type;
28 using BaseType = Tstorage;
29 static constexpr Tstorage MASK = Tmask;
30
31 constexpr BaseBitSet() : data(0) {}
32 explicit constexpr BaseBitSet(Tstorage data) : data(data & Tmask) {}
33
34 constexpr auto operator <=>(const BaseBitSet &) const noexcept = default;
35
40 inline constexpr Timpl &Set()
41 {
42 this->data = Tmask;
43 return static_cast<Timpl&>(*this);
44 }
45
51 inline constexpr Timpl &Set(Tvalue_type value)
52 {
53 this->data |= (1ULL << Timpl::DecayValueType(value));
54 return static_cast<Timpl&>(*this);
55 }
56
62 inline constexpr Timpl &Set(const Timpl &other)
63 {
64 this->data |= other.data;
65 return static_cast<Timpl&>(*this);
66 }
67
74 inline constexpr Timpl &Set(Tvalue_type value, bool set)
75 {
76 return set ? this->Set(value) : this->Reset(value);
77 }
78
83 inline constexpr Timpl &Reset()
84 {
85 this->data = 0;
86 return static_cast<Timpl &>(*this);
87 }
88
94 inline constexpr Timpl &Reset(Tvalue_type value)
95 {
96 this->data &= ~(1ULL << Timpl::DecayValueType(value));
97 return static_cast<Timpl&>(*this);
98 }
99
105 inline constexpr Timpl &Reset(const Timpl &other)
106 {
107 this->data &= ~other.data;
108 return static_cast<Timpl&>(*this);
109 }
110
116 inline constexpr Timpl &Flip(Tvalue_type value)
117 {
118 if (this->Test(value)) {
119 return this->Reset(value);
120 } else {
121 return this->Set(value);
122 }
123 }
124
130 inline constexpr Timpl &Flip(const Timpl &other)
131 {
132 this->data ^= other.data;
133 return static_cast<Timpl&>(*this);
134 }
135
141 inline constexpr bool Test(Tvalue_type value) const
142 {
143 return (this->data & (1ULL << Timpl::DecayValueType(value))) != 0;
144 }
145
151 inline constexpr bool All(const Timpl &other) const
152 {
153 return (this->data & other.data) == other.data;
154 }
155
160 inline constexpr bool All() const
161 {
162 return this->data == Tmask;
163 }
164
170 inline constexpr bool Any(const Timpl &other) const
171 {
172 return (this->data & other.data) != 0;
173 }
174
179 inline constexpr bool Any() const
180 {
181 return this->data != 0;
182 }
183
188 inline constexpr bool None() const
189 {
190 return this->data == 0;
191 }
192
193 inline constexpr Timpl &operator|=(const Timpl &other)
194 {
195 this->data |= other.data;
196 return static_cast<Timpl &>(*this);
197 }
198
199 inline constexpr Timpl operator|(const Timpl &other) const
200 {
201 return Timpl{static_cast<Tstorage>(this->data | other.data)};
202 }
203
204 inline constexpr Timpl &operator&=(const Timpl &other)
205 {
206 this->data &= other.data;
207 return static_cast<Timpl &>(*this);
208 }
209
210 inline constexpr Timpl operator&(const Timpl &other) const
211 {
212 return Timpl{static_cast<Tstorage>(this->data & other.data)};
213 }
214
219 inline constexpr Tstorage base() const noexcept
220 {
221 return this->data;
222 }
223
228 inline constexpr bool IsValid() const
229 {
230 return (this->base() & Tmask) == this->base();
231 }
232
237 inline uint Count() const
238 {
239 return CountBits(this->base());
240 }
241
247 std::optional<Tvalue_type> GetNthSetBit(uint n) const
248 {
249 for (auto i : *this) {
250 if (n == 0) return i;
251 --n;
252 }
253
254 return std::nullopt;
255 }
256
257 auto begin() const { return SetBitIterator<Tvalue_type>(this->data).begin(); }
258 auto end() const { return SetBitIterator<Tvalue_type>(this->data).end(); }
259
260private:
261 Tstorage data;
262};
263
264#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.