diff --git a/include/msg/field.hpp b/include/msg/field.hpp index 25b47637..76f71cfd 100644 --- a/include/msg/field.hpp +++ b/include/msg/field.hpp @@ -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 > class field { @@ -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; - using This = field; + using This = field; using ValueType = T; + using NameType = NameTypeT; + constexpr static auto MaxDWordExtent = DWordIndex + (MsbT / 32); + template 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) { @@ -80,34 +80,34 @@ class field { template using WithGreaterThan = - field>; template using WithDefault = - field; + field; template using WithRequired = - field>; template - using WithIn = field>; template - using WithMatch = field; template using WithGreaterThanOrEqualTo = - field>; template using WithLessThanOrEqualTo = - field>; constexpr explicit field(T const &new_value) : value{new_value} {} diff --git a/include/msg/message.hpp b/include/msg/message.hpp index 45ee29be..4ed1cb32 100644 --- a/include/msg/message.hpp +++ b/include/msg/message.hpp @@ -55,11 +55,11 @@ template return is_valid_msg_t{}; } -template +template struct message_base : public message_data { 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; template @@ -99,31 +99,33 @@ struct message_base : public message_data { 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 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 explicit constexpr message_base(ArgFields... argFields) { if constexpr ((std::is_integral_v> 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(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{}), ...); diff --git a/test/msg/handler.cpp b/test/msg/handler.cpp index a934662a..27a91e50 100644 --- a/test/msg/handler.cpp +++ b/test/msg/handler.cpp @@ -14,25 +14,25 @@ using TestField2 = field; using TestField3 = field; -using TestBaseMsg = message_data<4>; +using TestBaseMsg = message_data<2>; using TestMsg = - message_base, + message_base, TestField1, TestField2, TestField3>; using TestMsgMultiCb = - message_base, + message_base, TestField1, TestField2, TestField3>; using TestMsgFieldRequired = message_base, + 2, TestIdField::WithRequired<0x44>, TestField1, TestField2, TestField3>; enum class Opcode { A = 0x8, B = 0x9, C = 0xA }; using TestOpField = field; -using TestMsgOp = message_base, TestField1, TestField2>; diff --git a/test/msg/handler_builder.cpp b/test/msg/handler_builder.cpp index 484a883b..287f6126 100644 --- a/test/msg/handler_builder.cpp +++ b/test/msg/handler_builder.cpp @@ -14,9 +14,9 @@ using test_field_2 = using test_field_3 = field; -using test_msg_t = message_base, test_field_1, - test_field_2, test_field_3>; +using test_msg_t = + message_base, + test_field_1, test_field_2, test_field_3>; struct test_service : ::msg::service {}; diff --git a/test/msg/message.cpp b/test/msg/message.cpp index c65cba63..66a53435 100644 --- a/test/msg/message.cpp +++ b/test/msg/message.cpp @@ -12,7 +12,7 @@ using TestField2 = field; using TestField3 = field; using TestMsg = - message_base, + message_base, TestField1, TestField2, TestField3>; TEST_CASE("TestMessageDataFieldConstruction", "[message]") {