Skip to main content

MapEntryOrder

Enum MapEntryOrder 

Source
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 ffffffff

A 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-long puts -1234567 first, so a signed integer key is compared signed. An unsigned reading would put it last.
  • map-key-ulonglong puts 7 before 16045690984833335998, so an unsigned integer key is compared unsigned. A signed reading of 0xdeadbeefdeadc2be is negative and would put it first.
  • map-key-string’s ["", "alpha", "üሴ"] stays as declared, so a string key is compared by unsigned octets — std::string’s char_traits<char>::compare, which is memcmp semantics. A signed octet comparison reads üሴ’s leading c3 as 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

Source

pub const ALL: [Self; 2]

Both.

Source

pub const fn is_default(self) -> bool

Whether this is the default.

Source

pub const fn as_str(self) -> &'static str

Short name, for configuration and diagnostics.

Source

pub fn parse(value: &str) -> Option<Self>

Parse a configuration value.

An unknown value returns None rather than falling back to the default: a typo in a wire-affecting setting must be loud.

Trait Implementations§

Source§

impl Clone for MapEntryOrder

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for MapEntryOrder

Source§

impl Debug for MapEntryOrder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for MapEntryOrder

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for MapEntryOrder

Source§

impl Hash for MapEntryOrder

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Ord for MapEntryOrder

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to)
Restrict a value to a certain range. Read more
Source§

impl PartialEq for MapEntryOrder

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl PartialOrd for MapEntryOrder

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl StructuralPartialEq for MapEntryOrder

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.