UFO 1.0.0
An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown
Loading...
Searching...
No Matches
bit_set.hpp
1
41#ifndef UFO_UTILITY_BIT_SET_HPP
42#define UFO_UTILITY_BIT_SET_HPP
43
44// STL
45#include <bit>
46#include <cassert>
47#include <cstdint>
48#include <limits>
49#include <stdexcept>
50#include <type_traits>
51
52namespace ufo
53{
54
55template <std::size_t N>
56class BitSet
57{
58 static_assert(0 < N && 64 >= N, "BitSet is defined for [1..64] bits");
59
60 public:
61 using T = std::conditional_t<
62 8 >= N, std::uint8_t,
63 std::conditional_t<16 >= N, std::uint16_t,
64 std::conditional_t<32 >= N, std::uint32_t, std::uint64_t>>>;
65
66 using value_type = T;
67
68 private:
69 static constexpr T const ALL_SET = []() {
70 if constexpr (std::numeric_limits<T>::digits == N) {
71 return static_cast<T>(~T(0));
72 } else {
73 return static_cast<T>(~(static_cast<T>(~T(0)) << N));
74 }
75 }();
76
77 public:
78 struct Reference {
79 friend class BitSet<N>;
80
81 public:
82 constexpr Reference& operator=(bool v) noexcept
83 {
84 T const x = set_;
85 T const y = static_cast<T>(~bit_);
86 T const z = static_cast<T>(v) << pos_;
87
88 set_ = (x & y) | z;
89 return *this;
90 }
91
92 constexpr Reference& operator=(Reference const& v) noexcept { return operator=(!!v); }
93
94 constexpr operator bool() const noexcept { return !!(set_ & bit_); }
95
96 constexpr bool operator~() const noexcept { return !(set_ & bit_); }
97
98 constexpr Reference& flip() noexcept
99 {
100 set_ ^= bit_;
101 return *this;
102 }
103
104 private:
105 constexpr Reference(T& set, std::size_t pos) noexcept
106 : set_(set), pos_(pos), bit_(static_cast<T>(T(1) << pos))
107 {
108 }
109
110 private:
111 T& set_;
112 T pos_;
113 T bit_;
114 };
115
116 constexpr BitSet() noexcept = default;
117
118 constexpr BitSet(T val) noexcept : set_(val & ALL_SET) {}
119
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'))
126 {
127 // TODO: Implement
128 }
129
130 template <class CharT>
131 explicit BitSet(
132 CharT const* str,
133 typename std::basic_string<CharT>::size_type n = std::basic_string<CharT>::npos,
134 CharT zero = CharT('0'), CharT one = CharT('1'))
135 {
136 // TODO: Implement
137 }
138
139 constexpr bool operator==(BitSet rhs) const noexcept { return set_ == rhs.set_; }
140
141 constexpr bool operator!=(BitSet rhs) const noexcept { return !(*this == rhs); }
142
143 [[nodiscard]] constexpr bool operator[](std::size_t pos) const
144 {
145 assert(N > pos);
146 return (set_ >> pos) & T(1);
147 }
148
149 [[nodiscard]] constexpr Reference operator[](std::size_t pos)
150 {
151 assert(N > pos);
152 return Reference(set_, pos);
153 }
154
155 [[nodiscard]] bool test(std::size_t pos) const
156 {
157 if (size() <= pos) {
158 std::out_of_range("position (which is " + std::to_string(pos) +
159 ") >= size (which is " + std::to_string(size()) + ")");
160 }
161 return operator[](pos);
162 }
163
164 [[nodiscard]] constexpr bool all() const noexcept { return ALL_SET == set_; }
165
166 [[nodiscard]] constexpr bool any() const noexcept { return !none(); }
167
168 [[nodiscard]] constexpr bool none() const noexcept { return T(0) == set_; }
169
170 [[nodiscard]] constexpr bool some() const noexcept { return !all() && !none(); }
171
172 [[nodiscard]] constexpr std::size_t count() const noexcept
173 {
174 return std::popcount(set_);
175 }
176
177 [[nodiscard]] static constexpr std::size_t size() noexcept { return N; }
178
179 constexpr BitSet& operator&=(BitSet const other) noexcept
180 {
181 set_ &= other.set_;
182 return *this;
183 }
184
185 constexpr BitSet& operator|=(BitSet const& other) noexcept
186 {
187 set_ |= other.set_;
188 return *this;
189 }
190
191 constexpr BitSet& operator^=(BitSet const& other) noexcept
192 {
193 set_ ^= other.set_;
194 return *this;
195 }
196
197 constexpr BitSet operator~() const noexcept { return BitSet(static_cast<T>(~set_)); }
198
199 constexpr void set() noexcept { set_ = ALL_SET; }
200
201 constexpr void set(std::size_t pos, bool value)
202 {
203 assert(N > pos);
204
205 T const x = set_;
206 T const y = static_cast<T>(~(T(1) << pos));
207 T const z = static_cast<T>(value) << pos;
208
209 set_ = (x & y) | z;
210 }
211
212 constexpr void set(std::size_t pos)
213 {
214 assert(N > pos);
215 set_ |= T(1) << pos;
216 }
217
218 constexpr void reset() noexcept { set_ = 0; }
219
220 constexpr void reset(std::size_t pos)
221 {
222 assert(N > pos);
223 set_ &= static_cast<T>(~(T(1) << pos));
224 }
225
226 constexpr void flip() noexcept { set_ = static_cast<T>(~set_); }
227
228 constexpr void flip(std::size_t pos)
229 {
230 assert(N > pos);
231 set_ ^= static_cast<T>(T(1) << pos);
232 }
233
234 [[nodiscard]] constexpr value_type data() const { return set_; }
235
236 private:
237 T set_{};
238};
239
240template <std::size_t N>
241constexpr BitSet<N> operator&(BitSet<N> lhs, BitSet<N> rhs) noexcept
242{
243 return BitSet<N>(lhs.data() & rhs.data());
244}
245
246template <std::size_t N>
247constexpr BitSet<N> operator|(BitSet<N> lhs, BitSet<N> rhs) noexcept
248{
249 return BitSet<N>(lhs.data() | rhs.data());
250}
251
252template <std::size_t N>
253constexpr BitSet<N> operator^(BitSet<N> lhs, BitSet<N> rhs) noexcept
254{
255 return BitSet<N>(lhs.data() ^ rhs.data());
256}
257
258template <class CharT, class Traits, std::size_t N>
259std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
260 BitSet<N> x)
261{
262 return os << +x.data();
263}
264
265template <class CharT, class Traits, std::size_t N>
266std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is,
267 BitSet<N>& x)
268{
269 typename BitSet<N>::value_type data;
270 is >> data;
271 x = BitSet<N>(data);
272 return is;
273}
274} // namespace ufo
275
276namespace std
277{
278template <std::size_t N>
279struct hash<ufo::BitSet<N>> {
280 std::size_t operator()(ufo::BitSet<N> x) const { return x.data(); }
281};
282} // namespace std
283
284#endif // UFO_UTILITY_BIT_SET_HPP
STL namespace.
All vision-related classes and functions.
Definition cloud.hpp:49
constexpr Vec< Dim, T > operator^(Vec< Dim, T > lhs, Vec< Dim, T > const &rhs) noexcept
Component-wise bitwise XOR of two integral vectors.
Definition vec.hpp:650