@@ -83,7 +83,7 @@ struct field_spec_t {
83
83
constexpr static auto size = BitSize;
84
84
};
85
85
86
- template <std::uint32_t DWordIndex , std::uint32_t BitSize, std::uint32_t Lsb>
86
+ template <std::uint32_t Index , std::uint32_t BitSize, std::uint32_t Lsb>
87
87
struct bits_locator_t {
88
88
constexpr static auto size = BitSize;
89
89
@@ -112,7 +112,7 @@ struct bits_locator_t {
112
112
constexpr auto Msb = Lsb + BitSize - 1u ;
113
113
114
114
constexpr auto BaseIndex =
115
- DWordIndex * sizeof (std::uint32_t ) / sizeof (elem_t );
115
+ Index * sizeof (std::uint32_t ) / sizeof (elem_t );
116
116
117
117
constexpr auto elem_size = stdx::bit_size<elem_t >();
118
118
constexpr auto max_idx = BaseIndex + Msb / elem_size;
@@ -158,7 +158,7 @@ struct bits_locator_t {
158
158
constexpr auto Msb = Lsb + BitSize - 1u ;
159
159
160
160
constexpr auto BaseIndex =
161
- DWordIndex * sizeof (std::uint32_t ) / sizeof (elem_t );
161
+ Index * sizeof (std::uint32_t ) / sizeof (elem_t );
162
162
163
163
constexpr auto elem_size = stdx::bit_size<elem_t >();
164
164
[[maybe_unused]] constexpr auto min_idx = BaseIndex + Lsb / elem_size;
@@ -209,13 +209,13 @@ struct bits_locator_t {
209
209
template <std::uint32_t NumBits>
210
210
constexpr static auto fits_inside () -> bool {
211
211
constexpr auto Msb = Lsb + BitSize - 1 ;
212
- return DWordIndex * 32 + Msb <= NumBits;
212
+ return Index * 32 + Msb <= NumBits;
213
213
}
214
214
215
215
template <typename T> constexpr static auto extent_in () -> std::size_t {
216
216
constexpr auto msb = Lsb + BitSize - 1 ;
217
217
constexpr auto msb_extent = (msb + CHAR_BIT - 1 ) / CHAR_BIT;
218
- constexpr auto base_extent = DWordIndex * sizeof (std::uint32_t );
218
+ constexpr auto base_extent = Index * sizeof (std::uint32_t );
219
219
constexpr auto extent = base_extent + msb_extent;
220
220
return (extent + sizeof (T) - 1 ) / sizeof (T);
221
221
}
@@ -279,12 +279,19 @@ template <bits_locator... BLs> struct field_locator_t {
279
279
};
280
280
} // namespace detail
281
281
282
+ enum struct byte_index_t : std::uint32_t {};
282
283
enum struct dword_index_t : std::uint32_t {};
283
284
enum struct msb_t : std::uint32_t {};
284
285
enum struct lsb_t : std::uint32_t {};
285
286
286
287
inline namespace literals {
287
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
+ }
292
+ CONSTEVAL auto operator " " _dwi(unsigned long long int v) -> dword_index_t {
293
+ return static_cast <dword_index_t >(v);
294
+ }
288
295
CONSTEVAL auto operator " " _dw(unsigned long long int v) -> dword_index_t {
289
296
return static_cast <dword_index_t >(v);
290
297
}
@@ -325,6 +332,32 @@ template <> struct at<dword_index_t, msb_t, lsb_t> {
325
332
}
326
333
};
327
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_) / 4 ;
343
+ }
344
+ [[nodiscard]] constexpr auto lsb () const -> std::underlying_type_t<lsb_t> {
345
+ return (stdx::to_underlying (index_) * 8 ) % 32 +
346
+ stdx::to_underlying (lsb_);
347
+ }
348
+ [[nodiscard]] constexpr auto size () const -> std::underlying_type_t<lsb_t> {
349
+ return stdx::to_underlying (msb_) - stdx::to_underlying (lsb_) + 1 ;
350
+ }
351
+ [[nodiscard]] constexpr auto valid () const -> bool {
352
+ return size () <= 8 and
353
+ stdx::to_underlying (msb_) >= stdx::to_underlying (lsb_);
354
+ }
355
+ [[nodiscard]] constexpr auto
356
+ sort_key () const -> std::underlying_type_t <lsb_t > {
357
+ return index () * 32u + stdx::to_underlying (lsb_);
358
+ }
359
+ };
360
+
328
361
template <> struct at <msb_t , lsb_t > {
329
362
msb_t msb_{};
330
363
lsb_t lsb_{};
0 commit comments