tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
bitset.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2020 Tobias Hienzsch
3
4#ifndef TETL_BITSET_BITSET_HPP
5#define TETL_BITSET_BITSET_HPP
6
7#include <etl/_algorithm/min.hpp>
8#include <etl/_bit/bit_cast.hpp>
9#include <etl/_bit/byteswap.hpp>
10#include <etl/_bit/endian.hpp>
11#include <etl/_bit/set_bit.hpp>
12#include <etl/_bitset/basic_bitset.hpp>
13#include <etl/_contracts/check.hpp>
14#include <etl/_cstddef/size_t.hpp>
15#include <etl/_limits/numeric_limits.hpp>
16#include <etl/_string/basic_inplace_string.hpp>
17#include <etl/_string_view/basic_string_view.hpp>
18
19namespace etl {
20
21/// The class template bitset represents a fixed-size sequence of Bits bits.
22/// Bitsets can be manipulated by standard logic operators.
23/// \headerfile etl/bitset.hpp
24/// \ingroup bitset
25template <etl::size_t Bits>
26struct bitset {
27 using reference = basic_bitset<Bits, etl::size_t>::reference;
28
29 /// Constructs a bitset with all bits set to zero.
30 constexpr bitset() noexcept = default;
31
32 /// Constructs a bitset, initializing the first (rightmost, least
33 /// significant) M bit positions to the corresponding bit values of val,
34 /// where M is the smaller of the number of bits in an unsigned long long
35 /// and the number of bits Bits in the bitset being constructed. If M is less
36 /// than Bits (the bitset is longer than 64 bits, for typical implementations
37 /// of unsigned long long), the remaining bit positions are initialized to
38 /// zeroes.
39 constexpr bitset(unsigned long long val) noexcept
40 : _bits(val)
41 {
42 }
43
44 /// Constructs a bitset using the characters in the
45 /// etl::basic_string_view str.
46 ///
47 /// \details An optional starting position pos and length n can be provided,
48 /// as well as characters denoting alternate values for set (one) and unset
49 /// (zero) bits. Traits::eq() is used to compare the character values. The
50 /// effective length of the initializing string is min(n, str.size() - pos).
51 ///
52 /// \param str string used to initialize the bitset
53 /// \param pos a starting offset into str
54 /// \param n number of characters to use from str
55 /// \param zero alternate character for set bits in str
56 /// \param one alternate character for unset bits in str
57 template <typename CharT, typename Traits>
58 explicit constexpr bitset(
59 basic_string_view<CharT, Traits> const& str,
60 typename basic_string_view<CharT, Traits>::size_type pos = 0,
61 typename basic_string_view<CharT, Traits>::size_type n = basic_string_view<CharT, Traits>::npos,
62 CharT zero = CharT('0'),
63 CharT one = CharT('1')
64 )
65 : bitset()
66 {
67 using size_type = decltype(pos);
68
69 auto const len = etl::min<size_type>(n, str.size() - pos);
70 auto const substr = str.substr(pos, len);
71 TETL_PRECONDITION(len >= 0);
72 TETL_PRECONDITION(len <= size());
73
74 for (size_type i{0}; i < len; ++i) {
75 if (Traits::eq(substr[len - i - 1], one)) {
76 set(i, true);
77 }
78 if (Traits::eq(substr[len - i - 1], zero)) {
79 set(i, false);
80 }
81 }
82 }
83
84 /// Constructs a bitset using the characters in the char const* str.
85 ///
86 /// \param str string used to initialize the bitset
87 /// \param n number of characters to use from str
88 /// \param zero alternate character for set bits in str
89 /// \param one alternate character for unset bits in str
90 template <typename CharT>
91 explicit constexpr bitset(
92 CharT const* str,
93 typename basic_string_view<CharT>::size_type n = basic_string_view<CharT>::npos,
94 CharT zero = CharT('0'),
95 CharT one = CharT('1')
96 )
97 : bitset(
98 n == basic_string_view<CharT>::npos ? basic_string_view<CharT>(str) : basic_string_view<CharT>(str, n),
99 0,
100 n,
101 zero,
102 one
103 )
104 {
105 }
106
107 /// Sets all bits to true.
108 constexpr auto set() noexcept -> bitset&
109 {
110 _bits.set();
111 return *this;
112 }
113
114 /// Sets the bit at the given position to the given value.
115 ///
116 /// \param pos Index of the bit to be modified.
117 /// \param value The new value for the bit.
118 /// \returns *this
119 constexpr auto set(etl::size_t pos, bool value = true) -> bitset&
120 {
121 TETL_PRECONDITION(pos < size());
122 _bits.unchecked_set(pos, value);
123 return *this;
124 }
125
126 /// Sets all bits to false.
127 constexpr auto reset() noexcept -> bitset&
128 {
129 _bits.reset();
130 return *this;
131 }
132
133 /// Sets the bit at position pos to false.
134 ///
135 /// \param pos Index of the bit to be reset.
136 /// \returns *this
137 constexpr auto reset(size_t pos) noexcept -> bitset&
138 {
139 TETL_PRECONDITION(pos < size());
140 _bits.unchecked_reset(pos);
141 return *this;
142 }
143
144 /// Flips all bits (like operator~, but in-place).
145 constexpr auto flip() noexcept -> bitset&
146 {
147 _bits.flip();
148 return *this;
149 }
150
151 /// Flips the bit at the position pos.
152 ///
153 /// \param pos Index of the bit to be reset.
154 /// \returns *this
155 constexpr auto flip(size_t pos) noexcept -> bitset&
156 {
157 TETL_PRECONDITION(pos < size());
158 _bits.unchecked_flip(pos);
159 return *this;
160 }
161
162 /// Returns a reference like proxy to the bit at the position pos.
163 /// Perfoms no bounds checking.
164 ///
165 /// \param pos Index of the bit.
166 [[nodiscard]] constexpr auto operator[](size_t const pos) -> reference
167 {
168 TETL_PRECONDITION(pos < size());
169 return _bits.unchecked_at(pos);
170 }
171
172 /// Returns the value of the bit at the position pos. Perfoms no
173 /// bounds checking.
174 ///
175 /// \param pos Index of the bit.
176 [[nodiscard]] constexpr auto operator[](size_t const pos) const -> bool
177 {
178 TETL_PRECONDITION(pos < size());
179 return _bits.unchecked_at(pos);
180 }
181
182 /// Returns the value of the bit at the position pos. Perfoms no
183 /// bounds checking.
184 ///
185 /// \param pos Index of the bit.
186 [[nodiscard]] constexpr auto test(size_t const pos) const -> bool
187 {
188 TETL_PRECONDITION(pos < size());
189 return _bits.unchecked_test(pos);
190 }
191
192 /// Checks if all bits are set to true.
193 [[nodiscard]] constexpr auto all() const noexcept -> bool
194 {
195 return _bits.all();
196 }
197
198 /// Checks if any bits are set to true.
199 [[nodiscard]] constexpr auto any() const noexcept -> bool
200 {
201 return _bits.any();
202 }
203
204 /// Checks if none bits are set to true.
205 [[nodiscard]] constexpr auto none() const noexcept -> bool
206 {
207 return _bits.none();
208 }
209
210 /// Returns the number of bits that are set to true.
211 [[nodiscard]] constexpr auto count() const noexcept -> size_t
212 {
213 return _bits.count();
214 }
215
216 /// Returns the number of bits that the bitset holds.
217 [[nodiscard]] constexpr auto size() const noexcept -> size_t
218 {
219 return _bits.size();
220 }
221
222 /// Returns true if all of the bits in *this and rhs are equal.
223 [[nodiscard]] constexpr auto operator==(bitset const& rhs) const noexcept -> bool
224 {
225 return _bits == rhs._bits;
226 }
227
228 /// Sets the bits to the result of binary AND on corresponding pairs
229 /// of bits of *this and other.
230 constexpr auto operator&=(bitset const& other) noexcept -> bitset&
231 {
232 _bits &= other._bits;
233 return *this;
234 }
235
236 /// Sets the bits to the result of binary OR on corresponding pairs
237 /// of bits of *this and other.
238 constexpr auto operator|=(bitset const& other) noexcept -> bitset&
239 {
240 _bits |= other._bits;
241 return *this;
242 }
243
244 /// Sets the bits to the result of binary XOR on corresponding pairs
245 /// of bits of *this and other.
246 constexpr auto operator^=(bitset const& other) noexcept -> bitset&
247 {
248 _bits ^= other._bits;
249 return *this;
250 }
251
252 /// Returns a temporary copy of *this with all bits flipped (binary NOT).
253 constexpr auto operator~() const noexcept -> bitset
254 {
255 return bitset(*this).flip();
256 }
257
258 /// Converts the contents of the bitset to a string. Uses zero to
259 /// represent bits with value of false and one to represent bits with value
260 /// of true. The resulting string contains Bits characters with the first
261 /// character corresponds to the last (Bits-1th) bit and the last character
262 /// corresponding to the first bit.
263 /// \todo Currently truncates the low bits, if the string is large enough.
264 template <size_t Capacity, typename CharT = char, typename Traits = char_traits<CharT>>
265 requires(Capacity >= Bits)
266 [[nodiscard]] constexpr auto to_string(CharT zero = CharT('0'), CharT one = CharT('1')) const
267 -> basic_inplace_string<CharT, Capacity, Traits>
268 {
269 auto str = basic_inplace_string<CharT, Capacity, Traits>{};
270 for (auto i{size() - 1U}; i != 0; --i) {
271 str.push_back(test(i) ? one : zero);
272 }
273 str.push_back(test(0) ? one : zero);
274 return str;
275 }
276
277 /// Converts the contents of the bitset to an unsigned long integer.
278 /// The first bit corresponds to the least significant digit of the number
279 /// and the last bit corresponds to the most significant digit.
280 [[nodiscard]] constexpr auto to_ulong() const noexcept -> unsigned long
281 requires(etl::numeric_limits<unsigned long>::digits >= Bits)
282 {
283 return to_unsigned_type<unsigned long>();
284 }
285
286 /// Converts the contents of the bitset to an unsigned long long
287 /// integer. The first bit corresponds to the least significant digit of the
288 /// number and the last bit corresponds to the most significant digit.
289 [[nodiscard]] constexpr auto to_ullong() const noexcept -> unsigned long long
290 requires(etl::numeric_limits<unsigned long long>::digits >= Bits)
291 {
292 return to_unsigned_type<unsigned long long>();
293 }
294
295 /// Performs binary AND between two bitsets, lhs and rhs.
296 friend constexpr auto operator&(bitset const& lhs, bitset const& rhs) noexcept -> bitset
297 {
298 return bitset(lhs) &= rhs;
299 }
300
301 /// Performs binary OR between two bitsets, lhs and rhs.
302 friend constexpr auto operator|(bitset const& lhs, bitset const& rhs) noexcept -> bitset
303 {
304 return bitset(lhs) |= rhs;
305 }
306
307 /// Performs binary XOR between two bitsets, lhs and rhs.
308 friend constexpr auto operator^(bitset const& lhs, bitset const& rhs) noexcept -> bitset
309 {
310 return bitset(lhs) ^= rhs;
311 }
312
313private:
314 template <typename UInt>
315 [[nodiscard]] constexpr auto to_unsigned_type() const noexcept -> UInt
316 {
317 if constexpr (sizeof(UInt) == sizeof(_bits)) {
318 if constexpr (etl::endian::native == etl::endian::little) {
319 return etl::bit_cast<UInt>(_bits);
320 } else {
321 return etl::byteswap(etl::bit_cast<UInt>(_bits));
322 }
323 } else {
324 constexpr auto digits = static_cast<UInt>(etl::numeric_limits<UInt>::digits);
325 auto const idx = etl::min<UInt>(static_cast<UInt>(size()), digits);
326 UInt result{};
327 for (UInt i{0}; i != idx; ++i) {
328 if (test(static_cast<etl::size_t>(i))) {
329 result = etl::set_bit(result, i);
330 }
331 }
332 return result;
333 }
334 }
335
336 basic_bitset<Bits, etl::size_t> _bits;
337};
338
339} // namespace etl
340
341#endif // TETL_BITSET_BITSET_HPP
endian
Indicates the endianness of all scalar types. If all scalar types are little-endian,...
Definition endian.hpp:16
Definition adjacent_find.hpp:9
Definition basic_bitset.hpp:32
basic_inplace_string class with fixed size capacity.
Definition basic_inplace_string.hpp:42
The class template basic_string_view describes an object that can refer to a constant contiguous sequ...
Definition basic_string_view.hpp:35
The class template bitset represents a fixed-size sequence of Bits bits. Bitsets can be manipulated b...
Definition bitset.hpp:26
constexpr auto none() const noexcept -> bool
Checks if none bits are set to true.
Definition bitset.hpp:205
constexpr bitset(unsigned long long val) noexcept
Constructs a bitset, initializing the first (rightmost, least significant) M bit positions to the cor...
Definition bitset.hpp:39
constexpr auto operator==(bitset const &rhs) const noexcept -> bool
Returns true if all of the bits in *this and rhs are equal.
Definition bitset.hpp:223
constexpr auto operator^=(bitset const &other) noexcept -> bitset &
Sets the bits to the result of binary XOR on corresponding pairs of bits of *this and other.
Definition bitset.hpp:246
constexpr auto any() const noexcept -> bool
Checks if any bits are set to true.
Definition bitset.hpp:199
constexpr auto operator[](size_t const pos) const -> bool
Returns the value of the bit at the position pos. Perfoms no bounds checking.
Definition bitset.hpp:176
friend constexpr auto operator^(bitset const &lhs, bitset const &rhs) noexcept -> bitset
Performs binary XOR between two bitsets, lhs and rhs.
Definition bitset.hpp:308
constexpr auto size() const noexcept -> size_t
Returns the number of bits that the bitset holds.
Definition bitset.hpp:217
constexpr auto count() const noexcept -> size_t
Returns the number of bits that are set to true.
Definition bitset.hpp:211
constexpr auto operator&=(bitset const &other) noexcept -> bitset &
Sets the bits to the result of binary AND on corresponding pairs of bits of *this and other.
Definition bitset.hpp:230
constexpr auto flip(size_t pos) noexcept -> bitset &
Flips the bit at the position pos.
Definition bitset.hpp:155
constexpr auto operator~() const noexcept -> bitset
Returns a temporary copy of *this with all bits flipped (binary NOT).
Definition bitset.hpp:253
constexpr auto all() const noexcept -> bool
Checks if all bits are set to true.
Definition bitset.hpp:193
constexpr auto reset() noexcept -> bitset &
Sets all bits to false.
Definition bitset.hpp:127
friend constexpr auto operator&(bitset const &lhs, bitset const &rhs) noexcept -> bitset
Performs binary AND between two bitsets, lhs and rhs.
Definition bitset.hpp:296
constexpr auto operator[](size_t const pos) -> reference
Returns a reference like proxy to the bit at the position pos. Perfoms no bounds checking.
Definition bitset.hpp:166
friend constexpr auto operator|(bitset const &lhs, bitset const &rhs) noexcept -> bitset
Performs binary OR between two bitsets, lhs and rhs.
Definition bitset.hpp:302
constexpr auto set(etl::size_t pos, bool value=true) -> bitset &
Sets the bit at the given position to the given value.
Definition bitset.hpp:119
constexpr auto flip() noexcept -> bitset &
Flips all bits (like operator~, but in-place).
Definition bitset.hpp:145
constexpr auto reset(size_t pos) noexcept -> bitset &
Sets the bit at position pos to false.
Definition bitset.hpp:137
constexpr auto to_string(CharT zero=CharT('0'), CharT one=CharT('1')) const -> basic_inplace_string< CharT, Capacity, Traits >
Converts the contents of the bitset to a string. Uses zero to represent bits with value of false and ...
Definition bitset.hpp:266
constexpr auto set() noexcept -> bitset &
Sets all bits to true.
Definition bitset.hpp:108
constexpr bitset() noexcept=default
Constructs a bitset with all bits set to zero.
constexpr auto operator|=(bitset const &other) noexcept -> bitset &
Sets the bits to the result of binary OR on corresponding pairs of bits of *this and other.
Definition bitset.hpp:238
constexpr bitset(CharT const *str, typename basic_string_view< CharT >::size_type n=basic_string_view< CharT >::npos, CharT zero=CharT('0'), CharT one=CharT('1'))
Constructs a bitset using the characters in the char const* str.
Definition bitset.hpp:91
constexpr bitset(basic_string_view< CharT, Traits > const &str, typename basic_string_view< CharT, Traits >::size_type pos=0, typename basic_string_view< CharT, Traits >::size_type n=basic_string_view< CharT, Traits >::npos, CharT zero=CharT('0'), CharT one=CharT('1'))
Constructs a bitset using the characters in the etl::basic_string_view str.
Definition bitset.hpp:58
constexpr auto test(size_t const pos) const -> bool
Returns the value of the bit at the position pos. Perfoms no bounds checking.
Definition bitset.hpp:186
static constexpr int digits
Definition numeric_limits.hpp:829
static constexpr int digits
Definition numeric_limits.hpp:982
Definition numeric_limits.hpp:18