@@ -66,6 +66,7 @@ concept field_locator_for =
66
66
67
67
template <typename T>
68
68
concept field_location = requires (T const &t) {
69
+ { t.indexed_bit_size () } -> std::same_as<std::uint32_t >;
69
70
{ t.index () } -> std::same_as<std::uint32_t >;
70
71
{ t.lsb () } -> std::same_as<std::uint32_t >;
71
72
{ t.size () } -> std::same_as<std::uint32_t >;
@@ -83,9 +84,10 @@ struct field_spec_t {
83
84
constexpr static auto size = BitSize;
84
85
};
85
86
86
- template <std::uint32_t DWordIndex , std::uint32_t BitSize, std::uint32_t Lsb>
87
+ template <std::uint32_t Index, std:: uint32_t IndexedBitSize , std::uint32_t BitSize, std::uint32_t Lsb>
87
88
struct bits_locator_t {
88
89
constexpr static auto size = BitSize;
90
+ constexpr static auto indexed_byte_size = std::size_t {IndexedBitSize/8 };
89
91
90
92
template <std::unsigned_integral T>
91
93
[[nodiscard]] constexpr static auto fold (T value) -> T {
@@ -112,7 +114,7 @@ struct bits_locator_t {
112
114
constexpr auto Msb = Lsb + BitSize - 1u ;
113
115
114
116
constexpr auto BaseIndex =
115
- DWordIndex * sizeof (std:: uint32_t ) / sizeof (elem_t );
117
+ Index * indexed_byte_size / sizeof (elem_t );
116
118
117
119
constexpr auto elem_size = stdx::bit_size<elem_t >();
118
120
constexpr auto max_idx = BaseIndex + Msb / elem_size;
@@ -158,7 +160,7 @@ struct bits_locator_t {
158
160
constexpr auto Msb = Lsb + BitSize - 1u ;
159
161
160
162
constexpr auto BaseIndex =
161
- DWordIndex * sizeof (std:: uint32_t ) / sizeof (elem_t );
163
+ Index * indexed_byte_size / sizeof (elem_t );
162
164
163
165
constexpr auto elem_size = stdx::bit_size<elem_t >();
164
166
[[maybe_unused]] constexpr auto min_idx = BaseIndex + Lsb / elem_size;
@@ -209,13 +211,13 @@ struct bits_locator_t {
209
211
template <std::uint32_t NumBits>
210
212
constexpr static auto fits_inside () -> bool {
211
213
constexpr auto Msb = Lsb + BitSize - 1 ;
212
- return DWordIndex * 32 + Msb <= NumBits;
214
+ return Index * IndexedBitSize + Msb <= NumBits;
213
215
}
214
216
215
217
template <typename T> constexpr static auto extent_in () -> std::size_t {
216
218
constexpr auto msb = Lsb + BitSize - 1 ;
217
219
constexpr auto msb_extent = (msb + CHAR_BIT - 1 ) / CHAR_BIT;
218
- constexpr auto base_extent = DWordIndex * sizeof (std:: uint32_t ) ;
220
+ constexpr auto base_extent = Index * indexed_byte_size ;
219
221
constexpr auto extent = base_extent + msb_extent;
220
222
return (extent + sizeof (T) - 1 ) / sizeof (T);
221
223
}
@@ -277,12 +279,16 @@ template <bits_locator... BLs> struct field_locator_t {
277
279
};
278
280
} // namespace detail
279
281
282
+ enum struct byte_index_t : std::uint32_t {};
280
283
enum struct dword_index_t : std::uint32_t {};
281
284
enum struct msb_t : std::uint32_t {};
282
285
enum struct lsb_t : std::uint32_t {};
283
286
284
287
inline namespace literals {
285
288
// NOLINTNEXTLINE(google-runtime-int)
289
+ CONSTEVAL auto operator " " _bi(unsigned long long int v) -> byte_index_t {
290
+ return static_cast <byte_index_t >(v);
291
+ }
286
292
CONSTEVAL auto operator " " _dw(unsigned long long int v) -> dword_index_t {
287
293
return static_cast <dword_index_t >(v);
288
294
}
@@ -307,6 +313,9 @@ template <> struct at<dword_index_t, msb_t, lsb_t> {
307
313
index () const -> std::underlying_type_t <dword_index_t > {
308
314
return stdx::to_underlying (index_);
309
315
}
316
+ [[nodiscard]] constexpr auto indexed_bit_size () const -> std::uint32_t {
317
+ return 32 ;
318
+ }
310
319
[[nodiscard]] constexpr auto lsb () const -> std::underlying_type_t<lsb_t> {
311
320
return stdx::to_underlying (lsb_);
312
321
}
@@ -323,6 +332,34 @@ template <> struct at<dword_index_t, msb_t, lsb_t> {
323
332
}
324
333
};
325
334
335
+ template <> struct at <byte_index_t , msb_t , lsb_t > {
336
+ byte_index_t index_{};
337
+ msb_t msb_{};
338
+ lsb_t lsb_{};
339
+
340
+ [[nodiscard]] constexpr auto
341
+ index () const -> std::underlying_type_t <byte_index_t > {
342
+ return stdx::to_underlying (index_);
343
+ }
344
+ [[nodiscard]] constexpr auto indexed_bit_size () const -> std::uint32_t {
345
+ return 8 ;
346
+ }
347
+ [[nodiscard]] constexpr auto lsb () const -> std::underlying_type_t<lsb_t> {
348
+ return stdx::to_underlying (lsb_);
349
+ }
350
+ [[nodiscard]] constexpr auto size () const -> std::underlying_type_t<lsb_t> {
351
+ return stdx::to_underlying (msb_) - lsb () + 1 ;
352
+ }
353
+ [[nodiscard]] constexpr auto valid () const -> bool {
354
+ return size () <= 64 and
355
+ stdx::to_underlying (msb_) >= stdx::to_underlying (lsb_);
356
+ }
357
+ [[nodiscard]] constexpr auto
358
+ sort_key () const -> std::underlying_type_t <lsb_t > {
359
+ return index () * 8u + stdx::to_underlying (lsb_);
360
+ }
361
+ };
362
+
326
363
template <> struct at <msb_t , lsb_t > {
327
364
msb_t msb_{};
328
365
lsb_t lsb_{};
@@ -331,6 +368,9 @@ template <> struct at<msb_t, lsb_t> {
331
368
index () const -> std::underlying_type_t <lsb_t > {
332
369
return stdx::to_underlying (lsb_) / 32u ;
333
370
}
371
+ [[nodiscard]] constexpr auto indexed_bit_size () const -> std::uint32_t {
372
+ return 32 ;
373
+ }
334
374
[[nodiscard]] constexpr auto lsb () const -> std::underlying_type_t<lsb_t> {
335
375
return stdx::to_underlying (lsb_) % 32u ;
336
376
}
@@ -353,7 +393,7 @@ namespace detail {
353
393
template <auto ... Ats>
354
394
requires (... and field_location<decltype (Ats)>)
355
395
using locator_for =
356
- field_locator_t <bits_locator_t <Ats.index(), Ats.size(), Ats.lsb()>...>;
396
+ field_locator_t <bits_locator_t <Ats.index(), Ats.indexed_bit_size(), Ats. size(), Ats.lsb()>...>;
357
397
358
398
template <at... Ats> constexpr inline auto field_size = (0u + ... + Ats.size());
359
399
0 commit comments