Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions include/msg/field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,28 +362,30 @@ template <at... Ats> constexpr inline auto field_size = (0u + ... + Ats.size());

template <typename T, T V = T{}> struct with_default {
constexpr static auto default_value = V;
template <typename F> using default_matcher_t = msg::equal_to_t<F, V>;
using is_mutable_t = void;
template <T X> constexpr static auto is_compatible_value = true;
};

template <typename T, T V = T{}> struct with_const_default {
constexpr static auto default_value = V;
template <typename F> using default_matcher_t = msg::equal_to_t<F, V>;
template <T X> constexpr static auto is_compatible_value = X == V;
};

struct without_default {
template <typename F> using default_matcher_t = match::never_t;
using is_mutable_t = void;
template <auto X> constexpr static auto is_compatible_value = true;
};

struct uninitialized {
template <auto X> constexpr static auto is_compatible_value = true;
};

template <typename T>
concept has_default_value = requires { T::default_value; };

template <typename T>
using has_default_value_t = std::bool_constant<has_default_value<T>>;
using initializable_t = std::bool_constant<has_default_value<T> or
std::is_base_of_v<uninitialized, T>>;

template <typename T>
concept is_mutable_value = requires { typename T::is_mutable_t; };
Expand Down Expand Up @@ -489,6 +491,8 @@ class field_t : public field_spec_t<Name, T, detail::field_size<Ats...>>,
using without_default =
field_t<Name, T, detail::without_default, M, Ats...>;

using uninitialized = field_t<Name, T, detail::uninitialized, M, Ats...>;

// ======================================================================
// matcher values
template <typename NewMatcher>
Expand Down
4 changes: 2 additions & 2 deletions include/msg/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ struct message {
constexpr owner_t() {
using uninit_fields =
boost::mp11::mp_remove_if<boost::mp11::mp_list<Fields...>,
has_default_value_t>;
initializable_t>;
static_assert(boost::mp11::mp_empty<uninit_fields>::value,
"All fields must be initialized or defaulted");
this->set(Fields{}...);
Expand All @@ -507,7 +507,7 @@ struct message {
using defaulted_fields = boost::mp11::mp_transform<
name_for,
boost::mp11::mp_copy_if<boost::mp11::mp_list<Fields...>,
has_default_value_t>>;
initializable_t>>;
using initialized_fields =
boost::mp11::mp_transform<name_for,
boost::mp11::mp_list<Vs...>>;
Expand Down
16 changes: 16 additions & 0 deletions test/msg/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -824,3 +824,19 @@ TEST_CASE("write indexing operator on message", "[message]") {
CHECK((0xba11 == msg["f1"_field]));
}
#endif

namespace {
using bit_field1 =
field<"f1",
std::uint32_t>::located<at{0_dw, 0_msb, 0_lsb}>::with_required<1>;
using all_fields =
field<"all", std::uint32_t>::located<at{0_dw, 31_msb, 0_lsb}>;

using overlap_msg_defn = message<"msg", bit_field1, all_fields::uninitialized>;
} // namespace

TEST_CASE("message with uninitialized field", "[message]") {
owning<overlap_msg_defn> msg{};
auto data = msg.data();
CHECK(data[0] == 1);
}
Loading