@@ -17,6 +17,12 @@ namespace stdx {
17
17
inline namespace v1 {
18
18
struct place_bits_t {};
19
19
constexpr inline auto place_bits = place_bits_t {};
20
+ struct all_bits_t {};
21
+ constexpr inline auto all_bits = all_bits_t {};
22
+
23
+ enum struct lsb_t : std::size_t {};
24
+ enum struct msb_t : std::size_t {};
25
+ enum struct length_t : std::size_t {};
20
26
21
27
namespace detail {
22
28
template <std::size_t N, typename StorageElem> class bitset {
@@ -128,6 +134,12 @@ template <std::size_t N, typename StorageElem> class bitset {
128
134
(set (static_cast <std::size_t >(bs)), ...);
129
135
}
130
136
137
+ constexpr explicit bitset (all_bits_t ) {
138
+ for (auto &elem : storage) {
139
+ elem = allbits;
140
+ }
141
+ }
142
+
131
143
constexpr explicit bitset (std::string_view str, std::size_t pos = 0 ,
132
144
std::size_t n = std::string_view::npos,
133
145
char one = ' 1' ) {
@@ -173,6 +185,37 @@ template <std::size_t N, typename StorageElem> class bitset {
173
185
return *this ;
174
186
}
175
187
188
+ constexpr auto set (lsb_t lsb, msb_t msb, bool value = true ) -> bitset & {
189
+ auto const l = to_underlying (lsb);
190
+ auto const m = to_underlying (msb);
191
+ auto [l_index, l_offset] = indices (l);
192
+ auto const [m_index, m_offset] = indices (m);
193
+
194
+ auto l_mask = std::numeric_limits<StorageElem>::max () << l_offset;
195
+ while (l_index != m_index) {
196
+ if (value) {
197
+ storage[l_index++] |= static_cast <StorageElem>(l_mask);
198
+ } else {
199
+ storage[l_index++] &= static_cast <StorageElem>(~(l_mask));
200
+ }
201
+ l_mask = std::numeric_limits<StorageElem>::max ();
202
+ }
203
+ auto const m_mask = std::numeric_limits<StorageElem>::max () >>
204
+ (storage_elem_size - m_offset - 1 );
205
+ if (value) {
206
+ storage[l_index] |= static_cast <StorageElem>(l_mask & m_mask);
207
+ } else {
208
+ storage[l_index] &= static_cast <StorageElem>(~(l_mask & m_mask));
209
+ }
210
+ return *this ;
211
+ }
212
+
213
+ constexpr auto set (lsb_t lsb, length_t len, bool value = true ) -> bitset & {
214
+ auto const l = to_underlying (lsb);
215
+ auto const length = to_underlying (len);
216
+ return set (lsb, static_cast <msb_t >(l + length - 1 ), value);
217
+ }
218
+
176
219
constexpr auto set () -> bitset & {
177
220
for (auto &elem : storage) {
178
221
elem = allbits;
@@ -193,6 +236,14 @@ template <std::size_t N, typename StorageElem> class bitset {
193
236
return *this ;
194
237
}
195
238
239
+ constexpr auto reset (lsb_t lsb, msb_t msb) -> bitset & {
240
+ return set (lsb, msb, false );
241
+ }
242
+
243
+ constexpr auto reset (lsb_t lsb, length_t len) -> bitset & {
244
+ return set (lsb, len, false );
245
+ }
246
+
196
247
constexpr auto flip (std::size_t pos) -> bitset & {
197
248
auto const [index , offset] = indices (pos);
198
249
storage[index ] ^= static_cast <StorageElem>(bit << offset);
@@ -345,5 +396,18 @@ template <std::size_t N, typename StorageElem = void>
345
396
using bitset =
346
397
detail::bitset<N, decltype(detail::select_storage<N, StorageElem>())>;
347
398
399
+ namespace literals {
400
+ // NOLINTBEGIN(google-runtime-int)
401
+ CONSTEVAL auto operator " " _lsb(unsigned long long int n) -> lsb_t {
402
+ return static_cast <lsb_t >(n);
403
+ }
404
+ CONSTEVAL auto operator " " _msb(unsigned long long int n) -> msb_t {
405
+ return static_cast <msb_t >(n);
406
+ }
407
+ CONSTEVAL auto operator " " _len(unsigned long long int n) -> length_t {
408
+ return static_cast <length_t >(n);
409
+ }
410
+ // NOLINTEND(google-runtime-int)
411
+ } // namespace literals
348
412
} // namespace v1
349
413
} // namespace stdx
0 commit comments