Module mem

Source
Expand description

Integer wrappers that are constrained to the range of usize or isize.

This module defines a number of wrappers around underlying basic integer types which ensure that the value fits both within usize (respectively isize) as well as the basic integer type, without loss of data.

Additionally, the types are optimized for size. That is, the types occupy the minimum size of both the underlying integer and the respective pointer sized alternative. This ensure that platform-compatible code is easier to write without wasting memory for the data representation in the process.

§Usage

Imagine some interface defining indices to be in the range of a u64. A 32-bit platform implementing this interface may be torn between using u64 for the intent, as well as its own isize for the smaller representation. The corresponding type from this module can combine both properties. A demonstration by types beyond the size of most platforms:

use core::mem::size_of;
use index_ext::mem::Imem128;

assert!(size_of::<Imem128>() <= size_of::<usize>());
assert!(size_of::<Imem128>() <= size_of::<i128>());

Keep in mind the types are most useful for representing values in and relative to your own program’s memory. In the interface you would generally prefer to declare argument as the specified platform independent underlying integer (e.g. u64 above). In these cases, there is however a security risk associated with delaying the (fallible) conversions to your platform’s capabilities. Firstly, implicit loss of precision when using as may occur on some distributions but not others which may result in incomplete test coverage missing a bug. Secondly, utilizing fallible conversion at the site of use creates many error paths. You might prefer converting to Umem64 immediately.

Consider the case of a matrix where dimensions are stored as u32 for compatibility reasons. We would now like to allocate a buffer for it which requires calculating the number of elements as a u64 and then convert to usize. However, no matter in which number type you intend to store the result you lose semantic meaning because there is no ‘proof’ attached to the value that it will also fit into the other value range.

use index_ext::mem::Umem64;

struct Matrix {
    width: u32,
    height: u32,
}

let elements = u64::from(mat.width) * u64::from(mat.height);
let length: Umem64 = Umem64::new(elements)?;

let matrix = vec![0; length.get()];

Structs§

Idiff8
An i8 that is also in the value range of an isize.
Idiff16
An i16 that is also in the value range of an isize.
Idiff32
An i32 that is also in the value range of an isize.
Idiff64
An i64 that is also in the value range of an isize.
Idiff128
A i128 that is also in the value range of an isize.
Imem
An isize that is also in the value range of a usize.
Imem8
An i8 that is also in the value range of a usize.
Imem16
An i16 that is also in the value range of a usize.
Imem32
An i32 that is also in the value range of a usize.
Imem64
An i64 that is also in the value range of a usize.
Imem128
An i128 that is also in the value range of a usize.
Udiff
A usize that is also in the value range of an isize.
Udiff8
A u8 that is also in the value range of an isize.
Udiff16
A u16 that is also in the value range of an isize.
Udiff32
A u32 that is also in the value range of an isize.
Udiff64
A u64 that is also in the value range of an isize.
Udiff128
A u128 that is also in the value range of an isize.
Umem8
A u8 that is also in the value range of a usize.
Umem16
A u16 that is also in the value range of a usize.
Umem32
A u32 that is also in the value range of a usize.
Umem64
A u64 that is also in the value range of a usize.
Umem128
A u128 that is also in the value range of a usize.