common_traits
A collection of traits and types that can be used to write code
that is generic over numerical types. It also provides atomic floats
implemented using the integer atomic type with the same number of
bits, and support for half-precision floats via the crate half.
Additionally, there are a few traits missing from the standard
library, such as Sequence, variants of existing library traits
such as Rng and Hash, and macros like invariant.
Finally, we provide traits for casting between types, such as
UpcastableInto, and fast implementations of a few primitives
such as FastRange and SelectInWord.
Everything is experimental and I'll change them to my needs, respecting semantic versioning. :)
Examples
Mixed precision generic dot products!
use *;
let x: = vec!;
let w: = vec!;
// compute the dot product between f32 and u8, casting to f64 and
// accumulating as u16
let res: u16 = ;
println!;
Numerical traits at a glance
The numerical traits dependency chain is the following. Black arcs represent the trait dependencies, the blue arcs represent the possibility to access an associated type implementing that trait.
Why?
The point of making this crate public is to be able to discuss this as it covers many core missing features from Rust.
The traits in this crate are similar to the ones from num-traits
but they are more interconnected (the blue arcs in the previous
graph), which makes it possible to write generic code (e.g., code
mixing a type and its associated atomic type) more easily and with
less trait bounds.
Summary
A highlight of common_traits' most noteworthy features.
Macros
This crate adds the following macros: invariant,
invariant_eq, invariant_ne, which are similar to the
debug_assert macros, which get checked during debug runs and get
replaced with core::hint::unreachable_unchecked on release builds.
Structs
This crate adds emulated atomic floats implemented via
fetch_update for the following types:
f64asAtomicF64f32asAtomicF32half::f16asAtomicF16half::bf16asAtomicBF16
Numerical Traits
This crate provides the following traits for numerical types:
Number: something that can be added, subtracted, multiplied, divided and has a zero and a one.FiniteRangeNumber: aNumberwhich has a minimum and a maximum.Float: float numbers.Integer: an integer number represented as a sequence of bits.SignedInt: a signed integer represented in two's complement.UnsignedInt: an unsigned integer.
Atomic Numerical Traits
There are two main traits for working with atomic values:
Atomic: for values that can be read and written atomically.IntoAtomic: for values that can be converted into atomic types.
Each numerical trait has an atomic equivalent:
Miscellaneous Traits
The crate also contains a couple of extra traits:
Sequence,SequenceMut, andSequenceGrowableto abstract over slices and other sequence-like types.AsBytes,ToBytes, andFromBytesare traits used to convert types to and from byte arrays.NonZero, a version ofSelfthat cannot be zero;UnsignedIntandSignedInthave an associated type implementing this.FastRangefor faster div, mod, and range operations.SelectInWordto find the position of the i-th 1 or 0 in words of memory.Splatto broadcast a smaller type on a larger type, mainly used for SWAR.Rngfor a generic random number generator.SameAs, an unsafe marker trait guaranteeing that a type and its atomic variant have the same memory layout.Hasher, that is likestd::hash::Hasherbut allows returning a generic type instead of au64.SeedableHasher, a standard way to initialize hashers.
Conversion Traits
Traits for conversion between types are also provided:
To, to cast primitive values usingas.DoubleTypeandHalfTypecan be used to access bigger or smaller types in a generic way.UpcastableIntoandUpcastableFromto cast primitive values which cannot lose precision.
DowncastableIntoandDowncastableFromto cast primitive values which can lose precision.
CastableIntoandCastableFromto cast primitive values which may or may not lose precision. This is the union ofDowncastableIntoandUpcastableInto.
The difference between CastableInto and To is that
CastableInto does not allow casting from f32 to u32 for
example, because CastableInto is implemented only between
integers and between floats, while To is implemented for all
primitive types.
Features
This crate has the following features:
simd: to enableportable_simdand be able to do generic SIMD codestd: to enable standard library supportalloc: to enable allocator support forVec/Boxwithout fullstdhalf: to enable support forhalf::f16(experimental)nightly_f16: to enable support for the nativef16type. Requires a nightly compiler and is mutually exclusive withhalf.