[][src]Macro memoffset::span_of

macro_rules! span_of {
    (@helper $root:ident, [] ..=) => { ... };
    (@helper $root:ident, [] ..) => { ... };
    (@helper $root:ident, [] ..= $($field:tt)+) => { ... };
    (@helper $root:ident, [] .. $($field:tt)+) => { ... };
    (@helper $root:ident, $(# $begin:tt)+ [] ..= $($end:tt)+) => { ... };
    (@helper $root:ident, $(# $begin:tt)+ [] .. $($end:tt)+) => { ... };
    (@helper $root:ident, $(# $begin:tt)+ [] ..) => { ... };
    (@helper $root:ident, $(# $begin:tt)+ [] ..=) => { ... };
    (@helper $root:ident, $(# $begin:tt)+ [] ) => { ... };
    (@helper $root:ident, $(# $begin:tt)+ [] $tt:tt $($rest:tt)*) => { ... };
    (@helper $root:ident, [] $tt:tt $($rest:tt)*) => { ... };
    ($parent:ty, $($exp:tt)+) => { ... };
}

Produces a range instance representing the sub-slice containing the specified member.

This macro provides 2 forms of differing functionalities.

The first form is identical to the appearance of the offset_of! macro, and just like offset_of!, it has no limit on the depth of fields / subscripts used.

This example is not tested
span_of!(Struct, member[index].field)

The second form of span_of! returns a sub-slice which starts at one field, and ends at another. The general pattern of this form is:

This example is not tested
// Exclusive
span_of!(Struct, member_a .. member_b)
// Inclusive
span_of!(Struct, member_a ..= member_b)

// Open-ended ranges
span_of!(Struct, .. end)
span_of!(Struct, start ..)

Note: This macro uses recursion in order to resolve the range expressions, so there is a limit to the complexity of the expression. In order to raise the limit, the compiler's recursion limit should be lifted.

Note: This macro may not make much sense when used on structs that are not #[repr(C, packed)]

Examples

#[macro_use]
extern crate memoffset;

#[repr(C, packed)]
struct Florp {
    a: u32
}

#[repr(C, packed)]
struct Blarg {
    x: u64,
    y: [u8; 56],
    z: Florp,
    egg: [[u8; 4]; 4]
}

fn main() {
    assert_eq!(0..8,   span_of!(Blarg, x));
    assert_eq!(64..68, span_of!(Blarg, z.a));
    assert_eq!(79..80, span_of!(Blarg, egg[2][3]));

    assert_eq!(8..64,  span_of!(Blarg, y[0]  ..  z));
    assert_eq!(0..42,  span_of!(Blarg, x     ..  y[34]));
    assert_eq!(0..64,  span_of!(Blarg, x     ..= y));
    assert_eq!(58..68, span_of!(Blarg, y[50] ..= z));

    const SPAN: std::ops::Range<usize> = span_of!(Blarg, y[50] ..= z);
    assert_eq!(58..68, SPAN);
}