[][src]Crate nonminmax

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/u8
  • i16/u16
  • i32/u32
  • i64/u64
  • i128 / u128
  • isize / usize

Structs

NonMaxI8

An integer of type i8 which is known to not equal i8::MAX.

NonMaxI16

An integer of type i16 which is known to not equal i16::MAX.

NonMaxI32

An integer of type i32 which is known to not equal i32::MAX.

NonMaxI64

An integer of type i64 which is known to not equal i64::MAX.

NonMaxI128

An integer of type i128 which is known to not equal i128::MAX.

NonMaxIsize

An integer of type isize which is known to not equal isize::MAX.

NonMaxU8

An integer of type u8 which is known to not equal u8::MAX.

NonMaxU16

An integer of type u16 which is known to not equal u16::MAX.

NonMaxU32

An integer of type u32 which is known to not equal u32::MAX.

NonMaxU64

An integer of type u64 which is known to not equal u64::MAX.

NonMaxU128

An integer of type u128 which is known to not equal u128::MAX.

NonMaxUsize

An integer of type usize which is known to not equal usize::MAX.

NonMinI8

An integer of type i8 which is known to not equal i8::MIN.

NonMinI16

An integer of type i16 which is known to not equal i16::MIN.

NonMinI32

An integer of type i32 which is known to not equal i32::MIN.

NonMinI64

An integer of type i64 which is known to not equal i64::MIN.

NonMinI128

An integer of type i128 which is known to not equal i128::MIN.

NonMinIsize

An integer of type isize which is known to not equal isize::MIN.

NonMinU8

An integer of type u8 which is known to not equal u8::MIN.

NonMinU16

An integer of type u16 which is known to not equal u16::MIN.

NonMinU32

An integer of type u32 which is known to not equal u32::MIN.

NonMinU64

An integer of type u64 which is known to not equal u64::MIN.

NonMinU128

An integer of type u128 which is known to not equal u128::MIN.

NonMinUsize

An integer of type usize which is known to not equal usize::MIN.