Skip to content

Commit b8daa75

Browse files
committed
enable byte indexing for msg::located at
1 parent 924cab6 commit b8daa75

File tree

3 files changed

+89
-6
lines changed

3 files changed

+89
-6
lines changed

include/msg/field.hpp

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ struct field_spec_t {
8383
constexpr static auto size = BitSize;
8484
};
8585

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>
8787
struct bits_locator_t {
8888
constexpr static auto size = BitSize;
8989

@@ -112,7 +112,7 @@ struct bits_locator_t {
112112
constexpr auto Msb = Lsb + BitSize - 1u;
113113

114114
constexpr auto BaseIndex =
115-
DWordIndex * sizeof(std::uint32_t) / sizeof(elem_t);
115+
Index * sizeof(std::uint32_t) / sizeof(elem_t);
116116

117117
constexpr auto elem_size = stdx::bit_size<elem_t>();
118118
constexpr auto max_idx = BaseIndex + Msb / elem_size;
@@ -158,7 +158,7 @@ struct bits_locator_t {
158158
constexpr auto Msb = Lsb + BitSize - 1u;
159159

160160
constexpr auto BaseIndex =
161-
DWordIndex * sizeof(std::uint32_t) / sizeof(elem_t);
161+
Index * sizeof(std::uint32_t) / sizeof(elem_t);
162162

163163
constexpr auto elem_size = stdx::bit_size<elem_t>();
164164
[[maybe_unused]] constexpr auto min_idx = BaseIndex + Lsb / elem_size;
@@ -209,13 +209,13 @@ struct bits_locator_t {
209209
template <std::uint32_t NumBits>
210210
constexpr static auto fits_inside() -> bool {
211211
constexpr auto Msb = Lsb + BitSize - 1;
212-
return DWordIndex * 32 + Msb <= NumBits;
212+
return Index * 32 + Msb <= NumBits;
213213
}
214214

215215
template <typename T> constexpr static auto extent_in() -> std::size_t {
216216
constexpr auto msb = Lsb + BitSize - 1;
217217
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);
219219
constexpr auto extent = base_extent + msb_extent;
220220
return (extent + sizeof(T) - 1) / sizeof(T);
221221
}
@@ -277,12 +277,19 @@ template <bits_locator... BLs> struct field_locator_t {
277277
};
278278
} // namespace detail
279279

280+
enum struct byte_index_t : std::uint32_t {};
280281
enum struct dword_index_t : std::uint32_t {};
281282
enum struct msb_t : std::uint32_t {};
282283
enum struct lsb_t : std::uint32_t {};
283284

284285
inline namespace literals {
285286
// NOLINTNEXTLINE(google-runtime-int)
287+
CONSTEVAL auto operator""_bi(unsigned long long int v) -> byte_index_t {
288+
return static_cast<byte_index_t>(v);
289+
}
290+
CONSTEVAL auto operator""_dwi(unsigned long long int v) -> dword_index_t {
291+
return static_cast<dword_index_t>(v);
292+
}
286293
CONSTEVAL auto operator""_dw(unsigned long long int v) -> dword_index_t {
287294
return static_cast<dword_index_t>(v);
288295
}
@@ -323,6 +330,32 @@ template <> struct at<dword_index_t, msb_t, lsb_t> {
323330
}
324331
};
325332

333+
template <> struct at<byte_index_t, msb_t, lsb_t> {
334+
byte_index_t index_{};
335+
msb_t msb_{};
336+
lsb_t lsb_{};
337+
338+
[[nodiscard]] constexpr auto
339+
index() const -> std::underlying_type_t<byte_index_t> {
340+
return stdx::to_underlying(index_) / 4;
341+
}
342+
[[nodiscard]] constexpr auto lsb() const -> std::underlying_type_t<lsb_t> {
343+
return (stdx::to_underlying(index_) * 8) % 32 +
344+
stdx::to_underlying(lsb_);
345+
}
346+
[[nodiscard]] constexpr auto size() const -> std::underlying_type_t<lsb_t> {
347+
return stdx::to_underlying(msb_) - stdx::to_underlying(lsb_) + 1;
348+
}
349+
[[nodiscard]] constexpr auto valid() const -> bool {
350+
return size() <= 8 and
351+
stdx::to_underlying(msb_) >= stdx::to_underlying(lsb_);
352+
}
353+
[[nodiscard]] constexpr auto
354+
sort_key() const -> std::underlying_type_t<lsb_t> {
355+
return index() * 32u + stdx::to_underlying(lsb_);
356+
}
357+
};
358+
326359
template <> struct at<msb_t, lsb_t> {
327360
msb_t msb_{};
328361
lsb_t lsb_{};

test/msg/field_extract.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,34 @@ TEST_CASE("across multiple storage elements", "[field extract]") {
6161
CHECK(0b11'1010'1010'1010'11u == F::extract(data));
6262
}
6363

64+
TEST_CASE("with byte index", "[field extract]") {
65+
using F = field<"", std::uint32_t>::located<
66+
at{0_bi, 7_msb, 2_lsb}, at{1_bi, 7_msb, 0_lsb}, at{2_bi, 1_msb, 0_lsb}>;
67+
std::array<std::uint8_t, 3> data{
68+
0b1010'1110u,
69+
0b1010'1010u,
70+
0b0000'0111u,
71+
};
72+
CHECK(0b1010'11'1010'1010'11u == F::extract(data));
73+
}
74+
75+
TEST_CASE("with byte index, at order", "[field extract]") {
76+
using F = field<"", std::uint32_t>::located<
77+
at{2_bi, 1_msb, 0_lsb}, at{1_bi, 7_msb, 0_lsb}, at{0_bi, 7_msb, 2_lsb}>;
78+
std::array<std::uint8_t, 3> data{
79+
0b1010'1110u,
80+
0b1010'1010u,
81+
0b0000'0111u,
82+
};
83+
CHECK(0b11'1010'1010'1010'11u == F::extract(data));
84+
}
85+
6486
TEST_CASE("without dword index", "[field extract]") {
6587
using F = field<"", std::uint32_t>::located<at{17_msb, 2_lsb}>;
6688
std::array<std::uint8_t, 3> data{
6789
0b1010'1110u,
6890
0b1010'1010u,
69-
0b111u,
91+
0b0000'0111u,
7092
};
7193
CHECK(0b11'1010'1010'1010'11u == F::extract(data));
7294
}

test/msg/field_insert.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,34 @@ TEST_CASE("across multiple storage elements", "[field insert]") {
7070
CHECK(0b111u == data[2]);
7171
}
7272

73+
TEST_CASE("with byte index", "[field insert]") {
74+
using F = field<"", std::uint32_t>::located<
75+
at{0_bi, 7_msb, 2_lsb}, at{1_bi, 7_msb, 0_lsb}, at{2_bi, 1_msb, 0_lsb}>;
76+
std::array<std::uint8_t, 3> data{
77+
0b0000'0010u,
78+
0b0000'0000u,
79+
0b0000'0100u,
80+
};
81+
F::insert(data, 0b11'1010'1010'1010'11u);
82+
CHECK(0b1110'1010u == data[0]);
83+
CHECK(0b1010'1010u == data[1]);
84+
CHECK(0b0000'0111u == data[2]);
85+
}
86+
87+
TEST_CASE("with byte index, at order", "[field insert]") {
88+
using F = field<"", std::uint32_t>::located<
89+
at{2_bi, 1_msb, 0_lsb}, at{1_bi, 7_msb, 0_lsb}, at{0_bi, 7_msb, 2_lsb}>;
90+
std::array<std::uint8_t, 3> data{
91+
0b0000'0010u,
92+
0b0000'0000u,
93+
0b0000'0100u,
94+
};
95+
F::insert(data, 0b11'1010'1010'1010'11u);
96+
CHECK(0b1010'1110u == data[0]);
97+
CHECK(0b1010'1010u == data[1]);
98+
CHECK(0b0000'0111u == data[2]);
99+
}
100+
73101
TEST_CASE("without dword index", "[field insert]") {
74102
using F = field<"", std::uint32_t>::located<at{17_msb, 2_lsb}>;
75103
std::array<std::uint8_t, 3> data{

0 commit comments

Comments
 (0)