Skip to main content

cpubits

Macro cpubits 

Source
macro_rules! cpubits {
    ( 16 => { $( $tokens:tt )* } ) => { ... };
    ( 32 => { $( $tokens:tt )* } ) => { ... };
    ( 64 => { $( $tokens:tt )* } ) => { ... };
    ( 16 | 32 => { $( $tokens:tt )* } ) => { ... };
    ( 32 | 64 => { $( $tokens:tt )* } ) => { ... };
    (
        16 => { $( $tokens16:tt )* }
        32 => { $( $tokens32:tt )* }
    ) => { ... };
    (
        32 => { $( $tokens32:tt )* }
        64 => { $( $tokens64:tt )* }
    ) => { ... };
    (
        16 => { $( $tokens16:tt )* }
        32 | 64 => { $( $tokens32:tt )* }
    ) => { ... };
    (
        16 | 32 => { $( $tokens32:tt )* }
        64 => { $( $tokens64:tt )* }
    ) => { ... };
    (
        16 => { $( $tokens16:tt )* }
        32 => { $( $tokens32:tt )* }
        64 => { $( $tokens64:tt )* }
    ) => { ... };
    (
        #[cfg(enable_64_bit = $($enable_64_bit:tt)+ )]
        16 => { $( $tokens16:tt )* }
        32 => { $( $tokens32:tt )* }
        64 => { $( $tokens64:tt )* }
    ) => { ... };
}
Expand description

A macro for defining code based on the optimal word size to use for the target, as chosen heuristically at compile-time using cfg-based predicates.

§Usage

The macro works like a match expression that takes an implicit argument representing the number of CPU bits, which is one of 16, 32, or 64.

Use this macro to conditionally emit code specific to certain CPU word sizes, e.g. defining types at compile-time based on the word size.

The macro doesn’t create a new block and supports arbitrary statements in toplevel code, just like the cfg-if crate (whose guts it recycles).

§Basic usage

cpubits::cpubits! {
    16 => { pub type Word = u16; }
    32 => { pub type Word = u32; }
    64 => { pub type Word = u64; }
}

NOTE: rustc will complain: “warning: unexpected cfg condition name: cpubits

See the lint configuration for cfg(cpubits) documentation for how to silence the warning.

§Grouping multiple bit sizes

If you would like to group together 16-bit and 32-bit platforms, you can do so as follows:

cpubits::cpubits! {
    16 | 32 => { pub type Word = u32; }
    64      => { pub type Word = u64; }
}

§Handling single-size cases

If you only want a block to run for a specific size, e.g. to know when it’s possible to write impl From<u64> for MyWordNewtype, you can do the following:

pub struct MyWordNewtype(Word);

cpubits::cpubits! {
    64 => {
        impl From<u64> for MyWordNewtype {
            #[inline]
            fn from(n: u64) -> MyWordNewtype {
                MyWordNewtype(n)
            }
        }
    }
}

§Use as an expression

It’s also possible to use the macro as an expression, although in somewhat limited contexts due to its attribute handling:

fn detected_cpubits() -> u32 {
    cpubits::cpubits! {
        16 => { 16 }
        32 => { 32 }
        64 => { 64 }
    }
}

§Selection rules

The macro augments target_pointer_width-based selection with specific overrides which promote certain targets from 32-bit to 64-bit ones.

This 64-bit promotion occurs if any of the following cfgs are true:

  • armv7: all(target_arch = "arm", target_feature = "v7")
  • wasm32: target_arch = "wasm32"