Expand description
§Integers types which cannot be their minimum/maximum value.
The standard library contains a collection of std::num::NonZeroX types: integer types which
cannot be zero. This crate extends this idea further by providing NonMinX/NonMaxX: integer
types which cannot be their minimum/maximum value.
// Create a regular NonMinU32
let x = 123 as i32;
let y = NonMinI32::new(x).unwrap();
assert_eq!(y.get(), 123);
// -2147483648 is the minimum value for a 32-bit integer.
let z = NonMinI32::new(-2147483648);
assert_eq!(z, None);§Memory optimization
Simlarity to NonZeroX types from, these NonMinX/NonMaxX types allow for the niche filling
optimization. This means that types such as Option<NonMinX>/Option<NonMaxX> takes up the
same amount of space as X, while a regular Option<X> takes up twice the size of X due to
the need of storing the variant tag.
use std::mem::size_of;
// Option<u32> is larger than a regular u32
assert!(size_of::<Option<u32>>() == 2 * size_of::<u32>());
// Option<NonMinU32>/Option<NonMaxU32> is the same size as a regular u32.
assert!(size_of::<Option<NonMinU32>>() == size_of::<u32>());
assert!(size_of::<Option<NonMaxU32>>() == size_of::<u32>());While this may seem like a micro-optimization, it becomes important when frequently passing an
Option<X> around or when creating a large array of Option<X>.
// 1000 x u32 takes up 4000 bytes
assert!(size_of::<[u32; 1000]>() == 4000);
// 1000 x Option<u32> takes up 8000 bytes, ouch
assert!(size_of::<[Option<u32>; 1000]>() == 8000);
// 1000 x Option<NonMaxU32> takes up only 4000 bytes
assert!(size_of::<[Option<NonMaxU32>; 1000]>() == 4000);§Internal details
Internally, these types work by wrapping the existing NonZeroX types and xor-ing with a mask when
accessing the inner value. This means that there is the cost of a single xor instruction each
time get is called.
§Supported types
The following types are supported
i8/u8i16/u16i32/u32i64/u64i128/u128isize/usize
Structs§
- NonMax
I8 - An integer of type
i8which is known to not equali8::MAX. - NonMax
I16 - An integer of type
i16which is known to not equali16::MAX. - NonMax
I32 - An integer of type
i32which is known to not equali32::MAX. - NonMax
I64 - An integer of type
i64which is known to not equali64::MAX. - NonMax
I128 - An integer of type
i128which is known to not equali128::MAX. - NonMax
Isize - An integer of type
isizewhich is known to not equalisize::MAX. - NonMax
U8 - An integer of type
u8which is known to not equalu8::MAX. - NonMax
U16 - An integer of type
u16which is known to not equalu16::MAX. - NonMax
U32 - An integer of type
u32which is known to not equalu32::MAX. - NonMax
U64 - An integer of type
u64which is known to not equalu64::MAX. - NonMax
U128 - An integer of type
u128which is known to not equalu128::MAX. - NonMax
Usize - An integer of type
usizewhich is known to not equalusize::MAX. - NonMin
I8 - An integer of type
i8which is known to not equali8::MIN. - NonMin
I16 - An integer of type
i16which is known to not equali16::MIN. - NonMin
I32 - An integer of type
i32which is known to not equali32::MIN. - NonMin
I64 - An integer of type
i64which is known to not equali64::MIN. - NonMin
I128 - An integer of type
i128which is known to not equali128::MIN. - NonMin
Isize - An integer of type
isizewhich is known to not equalisize::MIN. - NonMin
U8 - An integer of type
u8which is known to not equalu8::MIN. - NonMin
U16 - An integer of type
u16which is known to not equalu16::MIN. - NonMin
U32 - An integer of type
u32which is known to not equalu32::MIN. - NonMin
U64 - An integer of type
u64which is known to not equalu64::MIN. - NonMin
U128 - An integer of type
u128which is known to not equalu128::MIN. - NonMin
Usize - An integer of type
usizewhich is known to not equalusize::MIN.