pub trait BitStore: Sealed + Sized + Debug {
type Mem: BitMemory + BitOps + BitStore + Into<Self>;
type Access: BitAccess<Self::Mem>;
type Alias: BitStore + Radium<Self::Mem> + Radium<<Self::Alias as BitStore>::Mem>;
}
Expand description
Common interface for memory regions.
This trait is implemented on the fundamental integers no wider than the target
processor word size, their Cell
wrappers, and (if present) their Atomic
variants. Users provide this type as a parameter to their data structures in
order to inform the structure of how it may access the memory it describes.
Currently, bitvec
is only tested on 32- and 64- bit architectures. This means
that u8
, u16
, u32
, and usize
unconditionally implement BitStore
, but
u64
will only do so on 64-bit targets, and will be unavailable on 32-bit
targets. This is a necessary restriction of bitvec
internals. Please comment
on Issue #76 if this affects you.
Specifically, this has the davantage that a BitSlice<_, Cell<_>>
knows that it
has a view of memory that will not undergo concurrent modification. As such, it
can forego atomic accesses, and just use ordinary load/store instructions
without fear of causing observable race conditions.
The associated types Mem
and Alias
allow implementors to know the register
width of the memory they describe (Mem
) and to know the aliasing status of the
region.
Generic Programming
Generic programming with associated types is hard, especially when using them, as in this trait, to implement a closed graph of relationships between types.
For example, this trait is implemented such that for any given type T
,
T::Alias::Mem
== T::Mem
== T::NoAlias::Mem
, T::Alias::Alias == T::Alias
,
and T::NoAlias::NoAlias == T::NoAlias
. Unfortunately, the Rust type system
does not allow these relationships to be described, so generic programming that
performs type transitions will rapidly become uncomfortable to use.
Internally, bitvec
makes use of type-manipulation functions that are known to
be correct with respect to the implementations of BitStore
in order to ease
implementation of library methods.
You are not expected to do significant programming that is generic over the
BitStore
memory parameter. When using a concrete type, the compiler will
gladly reduce the abstract type associations into their instantiated selections,
allowing monomorphized code to be much more convenient than generic.
If you have a use case that involves generic programming over this trait, and you are encountering difficulties dealing with the type associations, please file an issue asking for support in this area.
Supertraits
This trait has trait requirements that better express its behavior:
Sealed
prevents it from being implemented by downstream libraries (Sealed
is a public trait in a private module, that only this crate can name).Sized
instructs the compiler that values of this type can be used as immediates.Debug
informs the compiler that other structures using this trait bound can correctly deriveDebug
. *
Associated Types
The register type that the implementor describes.
The modifier type over Self::Mem
used to perform memory access.
A sibling BitStore
implementor that performs alias-aware memory
access.
While the associated type always has the same Mem
concrete type as
Self
, attempting to encode this requirement as `<Mem = Self::Mem>
causes Rust to enter an infinite recursion in the trait solver.
Instead, the two Radium
bounds inform the compiler that the Alias
is
irradiant over both the current memory and the destination memory types,
allowing generic type algebra to resolve correctly even though the fact
that Radium
is only implemented once is not guaranteed.