Skip to content

Commit fa3bd24

Browse files
committed
🎨 Change msg::combine to msg::overlay
Problem: - `combine` is a generic name that doesn't contrast with `pack` and doesn't have a clear meaning. Solution: - Change `combine` to `overlay` to make it clearer what the operation is. - Clarify documentation around `overlay` and `pack` - Add docs regarding `relaxed_message`.
1 parent 4bb55c6 commit fa3bd24

File tree

3 files changed

+58
-22
lines changed

3 files changed

+58
-22
lines changed

docs/message.adoc

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ using msg1_defn = extend<header_defn, "msg", type_f::with_required<1>, payload_f
162162
using msg2_defn = extend<header_defn, "msg", type_f::with_required<2>, payload_f>;
163163
----
164164

165-
==== Combining and packing messages
165+
==== Overlaying and packing messages
166166

167167
It is sometimes useful to combine multiple message definitions, to avoid
168168
repetition. For example, adding a payload message to a header:
@@ -176,13 +176,22 @@ using data_f = field<"data", std::uint32_t>::located<at{0_dw, 15_msb, 7_lsb}>;
176176
using payload_defn = message<"payload", data_f>;
177177
178178
using msg_defn = extend<
179-
combine<"msg", header_defn, payload_defn>,
179+
overlay<"msg", header_defn, payload_defn>,
180180
type_f::with_required<1>>;
181+
182+
// resulting message layout:
183+
// byte |0 |1 |
184+
// bit |01234567|01234567|
185+
// field |header |payload |
181186
----
182187

183-
The combined definition incorporates all the fields of the messages. And as
184-
shown, the combination might typically be `extend`​ed with a constraint on the
185-
header field.
188+
The combined (overlaid) definition incorporates all the fields of the messages.
189+
And as shown, the combination might typically be `extend`​ed with a constraint on
190+
the header field.
191+
192+
NOTE: It is possible to have overlapping message fields! Fields just determine
193+
which parts of the data are read/written, and overlapping field definitions are
194+
sometimes useful.
186195

187196
Other times it is useful to automatically concatenate or `pack` messages
188197
together, where the field locations in each message start at 0.
@@ -201,17 +210,16 @@ using msg_defn = extend<
201210
type_f::with_required<1>>;
202211
203212
// resulting message layout:
204-
// byte 0 1
205-
// bit 01234567 01234567
206-
// field |type|xx |data |
213+
// byte |0 |1 |
214+
// bit |012345|67|01234567|
215+
// field |type |xx|data |
207216
----
208217

209218
The second parameter to `pack` (`std::uint8_t` in the example above) defines how
210219
the messages are packed together - in this case, each subsequent message is
211220
byte-aligned.
212221

213-
CAUTION: After combining or packing messages, the fields inside them may have
214-
moved!
222+
CAUTION: After packing messages, the fields inside them may have moved!
215223

216224
Any matchers defined on the original fields may cause problems when matching
217225
against raw data, because they will be looking in the wrong place. (Matching
@@ -238,6 +246,34 @@ using msg_defn = extend<
238246
using new_data_f = msg_defn::field_t<"data">;
239247
----
240248

249+
==== Relaxed messages
250+
251+
During prototyping, it can be useful to specify message types, but not worry
252+
about where they are located yet. The compiler can automatically place them in
253+
storage for us, and this is what `relaxed_message` is for.
254+
255+
[source,cpp]
256+
----
257+
// just prototyping: we want field types, but we don't care about layout yet
258+
using type_f = field<"type", std::uint8_t>;
259+
using data_f = field<"data">, std::uint32_t>;
260+
using msg_defn = relaxed_message<"msg", type_f, data_f>;
261+
262+
// msg_defn has both fields, at unspecified locations
263+
----
264+
265+
[source,cpp]
266+
----
267+
// we want to fix the type, but we don't care about the rest
268+
using type_f = field<"type", std::uint8_t>::located<at{0_dw, 3_msb, 0_lsb}>;
269+
using field0_f = field<"f0">, std::uint8_t>;
270+
using field1_f = field<"f1">, std::uint16_t>;
271+
using field2_f = field<"f2">, std::uint32_t>;
272+
using msg_defn = relaxed_message<"msg", type_f, field0_f, field1_f, field2_f>;
273+
274+
// msg_defn has type as the first 4 bits; the other fields are at unspecified locations
275+
----
276+
241277
==== Owning vs view types
242278

243279
An owning message uses underlying storage: by default, this is a `std::array` of

include/msg/message.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -699,26 +699,26 @@ using shifted_msgs =
699699
msg_offsets<AlignTo, Msgs...>,
700700
stdx::type_list<Msgs..., msg::message<"end">>>;
701701

702-
template <stdx::ct_string Name, stdx::envlike Env> struct combiner {
702+
template <stdx::ct_string Name, stdx::envlike Env> struct overlayer {
703703
template <typename... Fields> using fn = msg::message<Name, Env, Fields...>;
704704
};
705705

706-
template <stdx::ct_string Name> struct combine_q {
706+
template <stdx::ct_string Name> struct overlay_q {
707707
template <typename... Msgs>
708708
requires(sizeof...(Msgs) > 0)
709709
using fn = boost::mp11::mp_apply_q<
710-
combiner<Name, stdx::append_env_t<typename Msgs::env_t...>>,
710+
overlayer<Name, stdx::append_env_t<typename Msgs::env_t...>>,
711711
boost::mp11::mp_append<typename Msgs::fields_t...>>;
712712
};
713713
} // namespace detail
714714

715715
template <stdx::ct_string Name, typename... Msgs>
716716
requires(sizeof...(Msgs) > 0)
717-
using combine = typename detail::combine_q<Name>::template fn<Msgs...>;
717+
using overlay = typename detail::overlay_q<Name>::template fn<Msgs...>;
718718

719719
template <stdx::ct_string Name, typename AlignTo, typename... Msgs>
720720
requires(sizeof...(Msgs) > 0)
721-
using pack = boost::mp11::mp_apply_q<detail::combine_q<Name>,
721+
using pack = boost::mp11::mp_apply_q<detail::overlay_q<Name>,
722722
detail::shifted_msgs<AlignTo, Msgs...>>;
723723

724724
namespace detail {
@@ -739,7 +739,7 @@ struct field_locator<Name, Env, Fields...> {
739739
using unlocated_fields = boost::mp11::mp_second<fields>;
740740

741741
using located_msg =
742-
boost::mp11::mp_apply_q<combiner<Name, stdx::env<>>, located_fields>;
742+
boost::mp11::mp_apply_q<overlayer<Name, stdx::env<>>, located_fields>;
743743

744744
using auto_fields =
745745
boost::mp11::mp_sort<unlocated_fields, field_size_sort_fn>;

test/msg/message.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ TEST_CASE("shift all fields in a message", "[message]") {
614614
STATIC_REQUIRE(std::is_same_v<defn, expected_defn>);
615615
}
616616

617-
TEST_CASE("combine messages", "[message]") {
617+
TEST_CASE("overlay messages", "[message]") {
618618
using f1 = field<"f1", std::uint32_t>::located<at{23_msb, 16_lsb}>;
619619
using f2 = field<"f2", std::uint32_t>::located<at{15_msb, 0_lsb}>;
620620
using m1 = message<"m1", f1, f2>;
@@ -623,19 +623,19 @@ TEST_CASE("combine messages", "[message]") {
623623
using f4 = field<"f4", std::uint32_t>::located<at{15_msb, 0_lsb}>;
624624
using m2 = message<"m2", f3, f4>;
625625

626-
using defn = combine<"defn", m1, m2::shifted_by<1, std::uint32_t>>;
626+
using defn = overlay<"defn", m1, m2::shifted_by<1, std::uint32_t>>;
627627
using expected_defn =
628628
message<"defn", f1, f2, f3::shifted_by<1, std::uint32_t>,
629629
f4::shifted_by<1, std::uint32_t>>;
630630
STATIC_REQUIRE(std::is_same_v<defn, expected_defn>);
631631
}
632632

633-
TEST_CASE("combine 1 message", "[message]") {
633+
TEST_CASE("overlay 1 message", "[message]") {
634634
using f1 = field<"f1", std::uint32_t>::located<at{15_msb, 0_lsb}>;
635635
using f2 = field<"f2", std::uint32_t>::located<at{23_msb, 16_lsb}>;
636636
using m1 = message<"m1", f1, f2>;
637637

638-
using defn = combine<"defn", m1>;
638+
using defn = overlay<"defn", m1>;
639639
using expected_defn = message<"defn", f1, f2>;
640640
STATIC_REQUIRE(std::is_same_v<defn, expected_defn>);
641641
}
@@ -771,14 +771,14 @@ TEST_CASE("supplement message environment", "[message]") {
771771
STATIC_REQUIRE(custom(new_defn::env_t{}) == 18);
772772
}
773773

774-
TEST_CASE("combine appends environments", "[message]") {
774+
TEST_CASE("overlay appends environments", "[message]") {
775775
using env1_t = stdx::make_env_t<custom, 17>;
776776
using m1 = message<"m1", env1_t>;
777777

778778
using env2_t = stdx::make_env_t<custom, 18>;
779779
using m2 = message<"m2", env2_t>;
780780

781-
using defn = combine<"defn", m1, m2>;
781+
using defn = overlay<"defn", m1, m2>;
782782
STATIC_REQUIRE(custom(defn::env_t{}) == 18);
783783
}
784784

0 commit comments

Comments
 (0)