Skip to main content

cv

Macro cv 

Source
macro_rules! cv {
    (@cast $v:expr => $t:ty) => { ... };
    ($v:expr => u8) => { ... };
    ($v:expr => u16) => { ... };
    ($v:expr => u32) => { ... };
    ($v:expr => u64) => { ... };
    ($v:expr => u128) => { ... };
    ($v:expr => usize) => { ... };
    ($v:expr => i8) => { ... };
    ($v:expr => i16) => { ... };
    ($v:expr => i32) => { ... };
    ($v:expr => i64) => { ... };
    ($v:expr => i128) => { ... };
    ($v:expr => isize) => { ... };
    ($v:expr => $t:ty) => { ... };
    ($v:expr) => { ... };
}
Expand description

Creates a constant value (“cv”) from an integer constant expression, with validity checked at compile time.

This works for any type that implements FromConst, with the target type inferred from the context, or named explicitly with cv!(value => Type). It can also be used in const contexts.

§Pitfalls

Only the target type is inferred from the context. The expression passed to cv! is typed by itself. So, unsuffixed integer literal expressions default to i32. For example cv!(2 << 31) does not evaluate to the same value as cv!(2i64 << 31), since 2 << 31 is treated as an i32 before being widened to i128 internally. Literals and arithmetic expressions that overflow i32 are a compile error, it’s just left shifts that require care.

§Examples

use core::num::NonZero;

use kernel::{
    num::Bounded,
    ptr::Alignment, //
};

let v: NonZero<usize> = cv!(8);
assert_eq!(v.get(), 8);

// Any integer constant expression works, not only literals.
let m: NonZero<usize> = cv!(usize::MAX);
assert_eq!(m.get(), usize::MAX);

let b: Bounded<u32, 4> = cv!(15);
assert_eq!(b.get(), 15);

let a: Alignment = cv!(4096);
assert_eq!(a.as_usize(), 4096);

// Checked narrowing of integer constants, including in `const` items.
const SMALL: u8 = cv!(200u32);
assert_eq!(SMALL, 200);

const N: NonZero<u8> = cv!(5);
assert_eq!(N.get(), 5);

// The target type can be given explicitly.
let e = cv!(200u32 => u8);
assert_eq!(e, 200);

// With an explicit primitive target, the expression can use generic parameters.
const fn as_u64<const KEY: u16>() -> u64 {
    cv!(KEY => u64)
}
assert_eq!(as_u64::<0x40>(), 0x40);