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.