6 releases
Uses old Rust 2015
0.2.3 | Sep 5, 2017 |
---|---|
0.2.2 | Aug 25, 2017 |
0.1.1 | Aug 8, 2017 |
#443 in No standard library
26 downloads per month
Used in zdex
17KB
251 lines
bit_collection
A Rust library that allows for iterating over the bits of a collection.
License
This project is released under either:
at your choosing.
lib.rs
:
Iterate over a collection of bits.
Usage
This crate is available on crates.io and can be used by adding the
following to your project's Cargo.toml
:
[dependencies]
bit_collection = "0.2.3"
and this to your crate root:
#[macro_use]
extern crate bit_collection;
#[bit]
Attribute
The #[bit]
attribute is composed of three parts, two of which are optional
in some cases. The components can be provided in any order.
Type:
The type used to represent individual bits. This part is required.
#[bit(Type, ...)]
Mask:
A mask indicating the valid bits of the collection. This should be a constant expression.
If not provided, the mask is assumed to have all bits set (i.e. !0
).
BitCollection::FULL
returns this value.
Attention: Please read the section on safety to ensure that this is used in a correct and safe manner.
#[bit(..., mask = "0b11", ...)]
Retriever:
The suffix for retrieving the inner integer value of the bit type. It
expands to $value.$retr
. Because of this, the provided retriever must be
visible where the derive is located.
If not provided, the bit type is assumed to be an enum
that can be
casted to an integer.
#[bit(..., retr = "inner", ...)]
Iterator:
The iterator for a given BitCollection
. If BitIter
isn't imported
as-is, this option allows for specifying its module path.
extern crate bit_collection as bc;
#[bit(..., iter = "bc::BitIter", ...)]
Examples
In computer chess, one popular way of representing the occupants of a board
is through a Bitboard
type. In this type, each individual bit
is a square on a chess board.
#[derive(Copy, Clone)]
pub struct Square(u8);
/// A set of sixty-four `Square`s.
#[bit(Square, mask = "!0", retr = "0")]
#[derive(BitCollection)]
pub struct Bitboard(u64);
We can also represent castle rights this way.
#[derive(Copy, Clone)]
pub enum CastleRight {
WhiteKingside,
BlackKingside,
WhiteQueenside,
BlackQueenside,
}
/// A set of `CastleRight`s.
#[bit(CastleRight, mask = "0b1111")]
#[derive(BitCollection)]
pub struct CastleRights {
bits: u8
}
fn iterate_over(rights: CastleRights) {
for right in rights {
match right {
CastleRight::WhiteKingside => { /* ... */ },
CastleRight::BlackKingside => { /* ... */ },
CastleRight::WhiteQueenside => { /* ... */ },
CastleRight::BlackQueenside => { /* ... */ },
}
}
}
Safety
This crate makes certain assumptions that, if unmet, may have unsafe and unexpected results.
The mask
option for #[bit]
must have the
correct bits set. It must not have bits set that correspond to invalid
instances of the bit type.
Similarly, the bit type must be defined such that corresponding bit patterns
from mask
provide legitimate values. Ask yourself, do 1 << item
and its
reversal (undo) operations, pop_{lsb,msb}
, make sense in terms of the
provided mask?
Dependencies
~1.5MB
~42K SLoC