pub trait Cursor {
fn curr<T: Bits>(count: u8) -> u8;
fn next<T: Bits>(count: u8) -> (u8, bool) { ... }
fn prev<T: Bits>(count: u8) -> (u8, bool) { ... }
fn jump<T: Bits>(count: u8, offset: isize) -> (isize, u8) { ... }
}
Expand description
A cursor over an element.
Usage
BitVec
stores semantic count, not a cursor into an element, as its bits
value. The methods on Cursor
all return a cursor into a storage element.
curr
computes the bit index of the count given. In Little-Endian order, this is the identity function (bit indices count up “left” from LSb), and in Big-Endian order, this subtracts the count given fromT::MASK
(bit indices count down “right” from MSb).next
computes the next index forward from the count given. In Little-Endian order, this increments (moving up from LSb towards MSb); in Big-Endian order, this decrements (moving down from MSb towards LSb).prev
computes the previous index backward from the count given. In Little-Endian order, this decrements (moving down towards LSb from MSb); in Big-Endian order, this increments (moving up towards MSb from LSb).jump
computes a number of whole elements to move, as well as the bit index within the destination element of the target bit.
You should use curr
to look up a bit at a known point, such as when indexing a
BitVec
; you should use next
or prev
to implement push, pop, and iteration;
you should use jump
only to implement striding iterators in a manner faster
than the default (which just repeatedly calls next
and drops most yielded
values).
Notes
All functions take a semantic count into a storage element, which will always
move upwards from zero, but all functions return an actual index to a specific
bit in the element achieved by shifting right and masking off all but the LSb of
the output. The output is not a semantic count, and does not need converted to
an index with curr
. It therefore cannot be stored as the new semantic count
during a mutation. The caller is responsible for maintaining count status.
next
and prev
signal when they cross the boundary of a storage element. If
their second return value is true, then the first return value is an index into
the storage element either after (next
) or before (prev
) the element for
which the input count referred. The caller is responsible for ensuring that they
use the returned index in the correct storage element by inspecting this flag
and moving their selection accordingly.
jump
returns the number of storage elements the caller will have to move their
cursor before indexing. next
and prev
can only move zero or one elements, so
their flag is a bool
rather than an isize
. The order swap for jump
is
because the number of elements to move is expected to be a more significant part
of its return value than the edge flag is in next
and prev
.
Required Methods
Provided Methods
sourcefn next<T: Bits>(count: u8) -> (u8, bool)
fn next<T: Bits>(count: u8) -> (u8, bool)
Compute the semantic index that logically follows the given index.
The first value returned must be passed into curr
in order to index
into an element. The second value indicates whether the increment points
into a different element.