Skip to content

Commit

Permalink
Merge pull request #320 from bdeane-intel/fix-message-base-size
Browse files Browse the repository at this point in the history
🐛 💥 Fix message_base size
  • Loading branch information
bdeane-intel authored Jul 12, 2023
2 parents 2af9c4b + 80290b3 commit bd34119
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 36 deletions.
28 changes: 14 additions & 14 deletions include/msg/field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace msg {
* @tparam MsbT most significant bit position for the field
* @tparam LsbT least significant bit position for the field
*/
template <typename NameTypeT, std::uint32_t DWordIndexT, std::uint32_t MsbT,
template <typename NameTypeT, std::uint32_t DWordIndex, std::uint32_t MsbT,
std::uint32_t LsbT, typename T = std::uint32_t, T DefaultValue = T{},
typename MatchRequirementsType = match::always_t<true>>
class field {
Expand All @@ -29,18 +29,18 @@ class field {
constexpr static size_t size = (MsbT - LsbT) + 1;
static_assert(size <= 64, "field must be 64 bits or smaller");

using FieldId = field<NameTypeT, DWordIndexT, MsbT, LsbT, T>;
using This = field<NameTypeT, DWordIndexT, MsbT, LsbT, T, DefaultValue,
using FieldId = field<NameTypeT, DWordIndex, MsbT, LsbT, T>;
using This = field<NameTypeT, DWordIndex, MsbT, LsbT, T, DefaultValue,
MatchRequirementsType>;
using ValueType = T;

using NameType = NameTypeT;
constexpr static auto MaxDWordExtent = DWordIndex + (MsbT / 32);

template <typename MsgType> constexpr static void fits_inside(MsgType) {
static_assert(DWordIndex < MsgType::NumDWords);
static_assert(MaxDWordExtent < MsgType::max_num_dwords);
}

using NameType = NameTypeT;
constexpr static auto DWordIndex = DWordIndexT;

constexpr static NameType name{};
constexpr static uint64_t bit_mask = [] {
if constexpr (size == 64) {
Expand Down Expand Up @@ -80,34 +80,34 @@ class field {

template <T NewGreaterValue>
using WithGreaterThan =
field<NameTypeT, DWordIndexT, MsbT, LsbT, T, NewGreaterValue,
field<NameTypeT, DWordIndex, MsbT, LsbT, T, NewGreaterValue,
msg::greater_than_t<This, T, NewGreaterValue>>;

template <T NewDefaultValue>
using WithDefault =
field<NameTypeT, DWordIndexT, MsbT, LsbT, T, NewDefaultValue>;
field<NameTypeT, DWordIndex, MsbT, LsbT, T, NewDefaultValue>;

template <T NewRequiredValue>
using WithRequired =
field<NameTypeT, DWordIndexT, MsbT, LsbT, T, NewRequiredValue,
field<NameTypeT, DWordIndex, MsbT, LsbT, T, NewRequiredValue,
msg::equal_to_t<This, T, NewRequiredValue>>;

template <T... PotentialValues>
using WithIn = field<NameTypeT, DWordIndexT, MsbT, LsbT, T, T{},
using WithIn = field<NameTypeT, DWordIndex, MsbT, LsbT, T, T{},
msg::in_t<This, T, PotentialValues...>>;

template <typename NewRequiredMatcher>
using WithMatch = field<NameTypeT, DWordIndexT, MsbT, LsbT, T, DefaultValue,
using WithMatch = field<NameTypeT, DWordIndex, MsbT, LsbT, T, DefaultValue,
NewRequiredMatcher>;

template <T NewGreaterValue>
using WithGreaterThanOrEqualTo =
field<NameTypeT, DWordIndexT, MsbT, LsbT, T, NewGreaterValue,
field<NameTypeT, DWordIndex, MsbT, LsbT, T, NewGreaterValue,
msg::greater_than_or_equal_to_t<This, T, NewGreaterValue>>;

template <T NewLesserValue>
using WithLessThanOrEqualTo =
field<NameTypeT, DWordIndexT, MsbT, LsbT, T, NewLesserValue,
field<NameTypeT, DWordIndex, MsbT, LsbT, T, NewLesserValue,
msg::less_than_or_equal_to_t<This, T, NewLesserValue>>;

constexpr explicit field(T const &new_value) : value{new_value} {}
Expand Down
28 changes: 15 additions & 13 deletions include/msg/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ template <typename MsgType, typename AdditionalMatcher>
return is_valid_msg_t<MsgType, AdditionalMatcher>{};
}

template <typename NameType, std::uint32_t MaxNumDWords,
std::uint32_t NumDWordsT, typename... FieldsT>
template <typename NameType, std::uint32_t MaxNumDWords, typename... FieldsT>
struct message_base : public message_data<MaxNumDWords> {
constexpr static NameType name{};
constexpr static auto NumDWords = NumDWordsT;
constexpr static auto max_num_dwords = MaxNumDWords;
static_assert((... and (FieldsT::MaxDWordExtent < MaxNumDWords)));
using FieldTupleType = cib::tuple<FieldsT...>;

template <typename additional_matcherType>
Expand Down Expand Up @@ -99,31 +99,33 @@ struct message_base : public message_data<MaxNumDWords> {

constexpr message_base() {
resize_and_overwrite(
*this, [](std::uint32_t *, std::size_t) { return NumDWordsT; });
*this, [](std::uint32_t *, std::size_t) { return MaxNumDWords; });
(set(FieldsT{}), ...);
}

template <detail::convertible_range_of<std::uint32_t> R>
explicit constexpr message_base(R const &r) {
resize_and_overwrite(*this, [&](std::uint32_t *dest,
std::size_t max_size) {
std::copy_n(std::begin(r), std::min(std::size(r), max_size), dest);
return NumDWordsT;
});
resize_and_overwrite(
*this, [&](std::uint32_t *dest, std::size_t max_size) {
auto const size = std::min(std::size(r), max_size);
std::copy_n(std::begin(r), size, dest);
return size;
});
}

template <typename... ArgFields>
explicit constexpr message_base(ArgFields... argFields) {
if constexpr ((std::is_integral_v<std::remove_cvref_t<ArgFields>> and
...)) {
static_assert(sizeof...(ArgFields) == NumDWordsT);
static_assert(sizeof...(ArgFields) <= MaxNumDWords);
resize_and_overwrite(*this, [&](std::uint32_t *dest, std::size_t) {
((*dest++ = static_cast<std::uint32_t>(argFields)), ...);
return NumDWordsT;
return sizeof...(ArgFields);
});
} else {
resize_and_overwrite(
*this, [](std::uint32_t *, std::size_t) { return NumDWordsT; });
resize_and_overwrite(*this, [](std::uint32_t *, std::size_t) {
return MaxNumDWords;
});
// TODO: ensure all required fields are set
// TODO: ensure fields aren't set more than once
(set(FieldsT{}), ...);
Expand Down
10 changes: 5 additions & 5 deletions test/msg/handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ using TestField2 = field<decltype("TestField2"_sc), 1, 23, 16, std::uint32_t>;

using TestField3 = field<decltype("TestField3"_sc), 1, 15, 0, std::uint32_t>;

using TestBaseMsg = message_data<4>;
using TestBaseMsg = message_data<2>;

using TestMsg =
message_base<decltype("TestMsg"_sc), 4, 2, TestIdField::WithRequired<0x80>,
message_base<decltype("TestMsg"_sc), 2, TestIdField::WithRequired<0x80>,
TestField1, TestField2, TestField3>;

using TestMsgMultiCb =
message_base<decltype("TestMsg"_sc), 4, 2, TestIdField::WithRequired<0x81>,
message_base<decltype("TestMsg"_sc), 2, TestIdField::WithRequired<0x81>,
TestField1, TestField2, TestField3>;

using TestMsgFieldRequired = message_base<decltype("TestMsgFieldRequired"_sc),
4, 2, TestIdField::WithRequired<0x44>,
2, TestIdField::WithRequired<0x44>,
TestField1, TestField2, TestField3>;

enum class Opcode { A = 0x8, B = 0x9, C = 0xA };

using TestOpField = field<decltype("TestOpField"_sc), 0, 27, 24, Opcode>;

using TestMsgOp = message_base<decltype("TestMsg"_sc), 4, 2,
using TestMsgOp = message_base<decltype("TestMsg"_sc), 2,
TestOpField::WithIn<Opcode::A, Opcode::B>,
TestField1, TestField2>;

Expand Down
6 changes: 3 additions & 3 deletions test/msg/handler_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ using test_field_2 =
using test_field_3 =
field<decltype("test_field_3"_sc), 1, 15, 0, std::uint32_t>;

using test_msg_t = message_base<decltype("test_msg"_sc), 4, 2,
test_id_field::WithRequired<0x80>, test_field_1,
test_field_2, test_field_3>;
using test_msg_t =
message_base<decltype("test_msg"_sc), 2, test_id_field::WithRequired<0x80>,
test_field_1, test_field_2, test_field_3>;

struct test_service : ::msg::service<test_msg_t> {};

Expand Down
2 changes: 1 addition & 1 deletion test/msg/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ using TestField2 = field<decltype("TestField2"_sc), 1, 23, 16, std::uint32_t>;
using TestField3 = field<decltype("TestField3"_sc), 1, 15, 0, std::uint32_t>;

using TestMsg =
message_base<decltype("TestMsg"_sc), 4, 2, TestIdField::WithRequired<0x80>,
message_base<decltype("TestMsg"_sc), 2, TestIdField::WithRequired<0x80>,
TestField1, TestField2, TestField3>;

TEST_CASE("TestMessageDataFieldConstruction", "[message]") {
Expand Down

0 comments on commit bd34119

Please sign in to comment.