OpenTTD Source 20260208-master-g43af8e94d0
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
9
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()>
22class BaseBitSet {
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.
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 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.