pub enum MapEntryOrder {
Declaration,
AscendingKey,
}Expand description
In what order a map’s entries go on the wire.
XTypes 1.3 §7.4.3.5.3 rules (14) and (15) give MAP_TYPE as a length
and a run of key-value pairs and say nothing about the order of
the pairs. Rule (16) is the same for encoding version 1. The order is
therefore not a reading of the clause in either direction; it is
whatever the binding’s container does.
§What one implementation does
fastddsgen 4.3.0 maps an IDL map<K,V> to std::map<K,V>, which
is ordered by key, so Fast DDS serialises entries in ascending key
order whatever order the sample declared them in. Measured on
map-key-long, entries [(-1234567, 1), (2147483647, -2), (1, 3)],
plain-cdr1 big endian:
ours 00000003 ffed2979 00000001 7fffffff fffffffe 00000001 00000003 ffffffff
theirs 00000003 ffed2979 00000001 00000001 00000003 7fffffff fffffffe ffffffffA permutation, and nothing else: the count is the same, the length is the same and every entry is present.
The evidence is complete rather than illustrative. Exactly the four
map-key-* cases whose sample is not already in ascending key order
diverge, and every map case whose sample already is agrees.
map-key-boolean is [true, false], map-key-char is
['a', 'Z', '~'], map-key-long is [-1234567, 2147483647, 1] and
map-key-ulonglong is [16045690984833335998, 7]; map-bounded,
map-nested, map-value-sequence, map-value-string,
map-value-struct, sequence-map, array-1d-map,
evolution-mutable-map and map-key-string are all ascending
already and all agree byte for byte.
§The order is the key’s own, and the corpus separates three of them
Not the encoded octets and not the canonical text — the key type’s
own value order, which is what std::map’s default std::less
gives:
map-key-longputs-1234567first, so a signed integer key is compared signed. An unsigned reading would put it last.map-key-ulonglongputs7before16045690984833335998, so an unsigned integer key is compared unsigned. A signed reading of0xdeadbeefdeadc2beis negative and would put it first.map-key-string’s["", "alpha", "üሴ"]stays as declared, so astringkey is compared by unsigned octets —std::string’schar_traits<char>::compare, which ismemcmpsemantics. A signed octet comparison readsüሴ’s leadingc3as negative and would put that entry first, which Fast DDS does not.
§What the corpus does not separate, stated rather than assumed
map-key-char’s keys are 'a', 'Z' and '~' — all below 0x80,
so nothing here says whether a char key is compared signed or
unsigned. An IDL char is a C++ char, whose signedness is
implementation-defined and which is signed on x86-64 Linux, where
the corpus was recorded. That is what is written, in all three
columns and explicitly rather than by following each column’s
compiler, so that the answer is the same on a host whose char is
unsigned. The same class as WstringUnitOrder::HostUnswapped and
recorded for the same reason.
map-key-enum says nothing either: wireprobe-fastdds records it as
refused — fastddsgen failed in every slot, because its key is a
@bit_bound(16) enumeration. An enumeration key is ordered by its
declared value here — enum class Colour : int32_t under
std::less is the underlying integer — and no recorded octets reach
that arm.
§Two dialects select the second value
Dialect::FastDds and Dialect::OpenDds. Fast DDS was the only
implementation in the corpus that produced map octets when this
axis was built; the Cyclone and RTI probes still refuse a map,
because the IDL-to-C mapping §7.5.1 has no map type, and OpenDDS’s
column joined on 2026-08-24. Both write ascending keys —
map-key-long and map-key-ulonglong under OpenDDS reorder the
sample’s declared entries in all four encodings — so judgement 3’s
threshold of two implementations is met on the position.
It stays a compatibility setting all the same, and that is what
judgement 3’s addendum in docs/wire-axes-followup.md says: the
order is a property of the ordered container each code generator
chose and not of a serialisation rule either product could have
written differently. §7.4.3.5.3 rules (14) to (16) give a map as a
length and a run of pairs and say nothing about their order.
--map-entries ascending-key reaches it, and so does the
configuration of that name.
§It is not a planner setting, and not a reader setting
A permutation changes no length and moves no offset, so it stays out
of LayoutKey::offset_key for the same reason UnionLabelMatch
does. And a reader is unaffected: decode::read_map and both other
columns sort a map’s entries into the canonical order before they
hand it back, because a map is a mapping and not a list. All 32 rows
decode to the case’s own sample under either value — they are the one
cause in this corpus where a reader sees no difference and the wire
decision is real all the same.
Variants§
Declaration
The order the sample declares its entries in.
The default, and what this project has always written: the clause gives no order, so the one the caller handed over is kept.
AscendingKey
Ascending by key, under the key type’s own value order.
What a binding that holds a map in an ordered container writes.
Named for the behaviour and not for the vendor, so that a reader
does not take it for a reading of §7.4.3.5.3.
Implementations§
Source§impl MapEntryOrder
impl MapEntryOrder
Sourcepub const fn is_default(self) -> bool
pub const fn is_default(self) -> bool
Whether this is the default.