@@ -8,8 +8,7 @@ Everything in the msg library is in the `msg` namespace.
88=== Fields
99
1010A `field` represents a value, specified in bits, inside a unit of addressable
11- storage. Currently in the _cib_ library, storage is assumed to be in units of
12- `std::uint32_t`. A field is a view type: it defines how to access storage, but
11+ storage. A field is a view type: it defines how to access storage, but
1312it is an empty type.
1413
1514Two things specify a `field`:
@@ -32,7 +31,7 @@ A field may also specify a xref:match.adoc#_what_is_a_matcher[`matcher`]; this
3231can be used to verify that a particular storage area contains the field. By
3332default this is xref:match.adoc#_basic_matchers[`match::always`].
3433
35- For example, a field type looks like this:
34+ For example, a field declaration looks like this:
3635[source,cpp]
3736----
3837using namespace msg;
@@ -44,17 +43,44 @@ using my_field =
4443 24_lsb}>; // least significant bit
4544----
4645
46+ Or like this:
47+ [source,cpp]
48+ ----
49+ using namespace msg;
50+ using my_field_spec = field<"my field", std::uint32_t>;
51+
52+ // these two declarations specify the same locations
53+ using my_field1 = my_field_spec::located_at<{1_dw, 23_msb, 20_lsb}>;
54+ using my_field2 = my_field_spec::located_at<{55_msb, 52_lsb}>;
55+ ----
56+ The 32-bit word offset in storage may be omitted in favour of using "raw" bit
57+ positions, according to convention.
58+
4759A field can specify multiple `at` arguments if it has several disjoint parts. In
4860that case, earlier `at` arguments specify more significant bits in the field,
4961with later `at` arguments being less significant. For example:
5062[source,cpp]
5163----
5264using namespace msg;
5365using my_field =
54- field<"my field", // name
55- std::uint16_t> // type
56- ::located<at{0_dw, 31_msb, 24_lsb}, // high byte
57- at{0_dw, 7_msb, 0_lsb}>; // low byte
66+ field<"my field", std::uint16_t>
67+ ::located<at{0_dw, 31_msb, 24_lsb}, // high byte
68+ at{0_dw, 7_msb, 0_lsb}>; // low byte
69+ ----
70+
71+ The maximum size of a field is 64 bits.
72+
73+ NOTE: It is a compile-time error to specify a field location where the number of
74+ bits in storage exceeds the capacity of the field's type. (The inverse is fine:
75+ it's common to have limited bits in storage handled by larger types.)
76+ [source,cpp]
77+ ----
78+ using namespace msg;
79+
80+ // this is a compilation error:
81+ // the field location is 9 bits, but the field type only holds 8 bits
82+ using my_field = field<"my field", std::uint8_t>
83+ ::located<at{8_msb, 0_lsb}>;
5884----
5985
6086Fields also expose several matcher aliases which can typically be used to
@@ -78,7 +104,7 @@ For example, a message type looks like this:
78104----
79105using my_message_defn = msg::message<
80106 "my_message", // name
81- my_field::with_required<0x80>>; // field(s)
107+ my_field::with_required<0x80>>; // field(s)
82108
83109using my_message = msg::owning<my_message_defn>;
84110----
@@ -155,7 +181,7 @@ using msg_defn = extend<
155181----
156182
157183The combined definition incorporates all the fields of the messages. And as
158- shown, the combination might typically be `extend`ed with a constraint on the
184+ shown, the combination might typically be `extend` ed with a constraint on the
159185header field.
160186
161187Other times it is useful to automatically concatenate or `pack` messages
0 commit comments