Skip to content

Commit

Permalink
🩹 Relax message_base range constructor constraints
Browse files Browse the repository at this point in the history
Accept a range of T as a constructor argument for `message_base`, where T is
convertible to `std::uint32_t`.

This unblocks issue #315.

TODO: properly relax the value type of `message_base`'s storage, as discussed
with @mjcaisse-intel.
  • Loading branch information
bdeane-intel committed Jun 28, 2023
1 parent 4b22051 commit 32b91b5
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
11 changes: 9 additions & 2 deletions include/msg/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ concept range = requires(T &t) {
std::begin(t);
std::end(t);
};

template <typename T>
using iterator_t = decltype(std::begin(std::declval<T &>()));

template <typename T, typename V>
concept convertible_range_of =
range<T> and std::convertible_to<std::iter_value_t<iterator_t<T>>, V>;
} // namespace detail

template <std::uint32_t MaxNumDWords>
Expand Down Expand Up @@ -96,8 +103,8 @@ struct message_base : public message_data<MaxNumDWords> {
(set(FieldsT{}), ...);
}

template <detail::range R> explicit constexpr message_base(R const &r) {
static_assert(std::is_same_v<typename R::value_type, std::uint32_t>);
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);
Expand Down
12 changes: 12 additions & 0 deletions test/msg/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@ TEST_CASE("TestMessageDataPartialRangeConstruction", "[message]") {
CHECK(0x0042d00d == msg[1]);
}

TEST_CASE("TestMessageDataConvertibleRangeConstruction", "[message]") {
TestMsg msg{std::array<std::uint16_t, 2>{0xba11, 0xd00d}};

CHECK(0xba11 == msg.get<TestField1>());
CHECK(0x0 == msg.get<TestField2>());
CHECK(0xd00d == msg.get<TestField3>());

REQUIRE(msg.size() == 2u);
CHECK(0x0000ba11 == msg[0]);
CHECK(0x0000d00d == msg[1]);
}

TEST_CASE("EqualToMatcher", "[message]") {
TestMsg msg{std::array<uint32_t, 2>{0x8000ba11, 0x0042d00d}};

Expand Down

0 comments on commit 32b91b5

Please sign in to comment.