bit_collection/
lib.rs

1//! Iterate over a collection of bits.
2//!
3//! # Usage
4//!
5//! This crate is available [on crates.io][crate] and can be used by adding the
6//! following to your project's `Cargo.toml`:
7//!
8//! ```toml
9//! [dependencies]
10//! bit_collection = "0.2.3"
11//! ```
12//!
13//! and this to your crate root:
14//!
15//! ```
16//! #[macro_use]
17//! extern crate bit_collection;
18//! # fn main() {}
19//! ```
20//!
21//! # `#[bit]` Attribute
22//!
23//! The `#[bit]` attribute is composed of three parts, two of which are optional
24//! in some cases. The components can be provided in any order.
25//!
26//! ## Type:
27//!
28//! The type used to represent individual bits. This part is required.
29//!
30//! ```rust,ignore
31//! #[bit(Type, ...)]
32//! ```
33//!
34//! ## Mask:
35//! A mask indicating the valid bits of the collection. This should be a
36//! constant expression.
37//!
38//! If not provided, the mask is assumed to have all bits set (i.e. `!0`).
39//!
40//! [`BitCollection::FULL`][FULL] returns this value.
41//!
42//! **Attention:** Please read the section on [safety](#safety) to ensure
43//! that this is used in a _correct_ and _safe_ manner.
44//!
45//! ```rust,ignore
46//! #[bit(..., mask = "0b11", ...)]
47//! ```
48//!
49//! ## Retriever:
50//! The suffix for retrieving the inner integer value of the bit type. It
51//! expands to `$value.$retr`. Because of this, the provided retriever must be
52//! visible where the derive is located.
53//!
54//! If not provided, the bit type is assumed to be an `enum` that can be
55//! casted to an integer.
56//!
57//! ```rust,ignore
58//! #[bit(..., retr = "inner", ...)]
59//! ```
60//!
61//! ## Iterator:
62//! The iterator for a given [`BitCollection`]. If [`BitIter`] isn't imported
63//! as-is, this option allows for specifying its module path.
64//!
65//! ```rust,ignore
66//! extern crate bit_collection as bc;
67//!
68//! #[bit(..., iter = "bc::BitIter", ...)]
69//! ```
70//!
71//! # Examples
72//!
73//! In computer chess, one popular way of representing the occupants of a board
74//! is through a [`Bitboard`][bitboard] type. In this type, each individual bit
75//! is a square on a chess board.
76//!
77//! ```
78//! # include!("../templates/imports.rs");
79//! #[derive(Copy, Clone)]
80//! pub struct Square(u8);
81//!
82//! /// A set of sixty-four `Square`s.
83//! #[bit(Square, mask = "!0", retr = "0")]
84//! #[derive(BitCollection)]
85//! pub struct Bitboard(u64);
86//!
87//! # fn main() {}
88//! ```
89//!
90//! We can also represent castle rights this way.
91//!
92//! ```
93//! # include!("../templates/imports.rs");
94//! #[derive(Copy, Clone)]
95//! pub enum CastleRight {
96//!     WhiteKingside,
97//!     BlackKingside,
98//!     WhiteQueenside,
99//!     BlackQueenside,
100//! }
101//!
102//! /// A set of `CastleRight`s.
103//! #[bit(CastleRight, mask = "0b1111")]
104//! #[derive(BitCollection)]
105//! pub struct CastleRights {
106//!     bits: u8
107//! }
108//!
109//! fn iterate_over(rights: CastleRights) {
110//!     for right in rights {
111//!         match right {
112//!             CastleRight::WhiteKingside  => { /* ... */ },
113//!             CastleRight::BlackKingside  => { /* ... */ },
114//!             CastleRight::WhiteQueenside => { /* ... */ },
115//!             CastleRight::BlackQueenside => { /* ... */ },
116//!         }
117//!     }
118//! }
119//!
120//! # fn main() {}
121//! ```
122//!
123//! # Safety
124//! This crate makes certain assumptions that, if unmet, may have unsafe and
125//! unexpected results.
126//!
127//! The [`mask`](#mask) option for [`#[bit]`](#bit-attribute) _must_ have the
128//! correct bits set. It _must not_ have bits set that correspond to invalid
129//! instances of the bit type.
130//!
131//! Similarly, the bit type must be defined such that corresponding bit patterns
132//! from `mask` provide legitimate values. Ask yourself, do `1 << item` and its
133//! reversal (undo) operations, `pop_{lsb,msb}`, make sense in terms of the
134//! provided mask?
135//!
136//! [crate]: https://crates.io/crates/bit_collection
137//! [`BitCollection`]: trait.BitCollection.html
138//! [`BitIter`]: struct.BitIter.html
139//! [FULL]: trait.BitCollection.html#associatedconstant.FULL
140//! [bitboard]: https://chessprogramming.wikispaces.com/Bitboards
141
142#![cfg_attr(not(feature = "std"), no_std)]
143
144#[cfg(feature = "std")]
145extern crate core;
146
147use core::borrow::{Borrow, BorrowMut};
148use core::cmp::Ordering;
149use core::iter::FromIterator;
150use core::ops;
151
152// Reexport derive macro.
153#[allow(unused_imports)]
154#[macro_use]
155extern crate bit_collection_derive;
156#[doc(hidden)]
157pub use bit_collection_derive::*;
158
159/// A type that represents a collection of bits that can be iterated over.
160pub trait BitCollection: From<<Self as IntoIterator>::Item>
161    + From<BitIter<Self>>
162    + IntoIterator<IntoIter=BitIter<Self>>
163    + FromIterator<<Self as IntoIterator>::Item>
164    + Extend<<Self as IntoIterator>::Item>
165    + ops::Not<Output=Self>
166    + ops::BitAnd<Output=Self>
167    + ops::BitAndAssign
168    + ops::BitOr<Output=Self>
169    + ops::BitOrAssign
170    + ops::BitXor<Output=Self>
171    + ops::BitXorAssign
172    + ops::Sub<Output=Self>
173    + ops::SubAssign
174{
175    /// A full instance with all bits set.
176    const FULL: Self;
177
178    /// An empty instance with no bits set.
179    const EMPTY: Self;
180
181    /// Returns the number of bits set in `self`.
182    ///
183    /// If checking whether `self` has zero, one, or multiple bits set, use
184    /// [`quantity`](#method.quantity).
185    fn len(&self) -> usize;
186
187    /// Returns whether `self` is empty.
188    fn is_empty(&self) -> bool;
189
190    /// Returns whether `self` has multiple bits set.
191    fn has_multiple(&self) -> bool;
192
193    /// Returns the quantity of bits set.
194    ///
195    /// For an exact measurement of the number of bits set, use
196    /// [`len`](#tymethod.len).
197    ///
198    /// This is much more optimal than matching [`len`](#tymethod.len) against
199    /// `0`, `1`, and `_`.
200    #[inline]
201    fn quantity(&self) -> Quantity {
202        use self::Quantity::*;
203        if self.is_empty() {
204            None
205        } else if self.has_multiple() {
206            Multiple
207        } else {
208            Single
209        }
210    }
211
212    /// Returns `self` as an iterator over itself.
213    ///
214    /// # Examples
215    ///
216    /// This method is useful for partially iterating over a `BitCollection`
217    /// in-place, and thus mutating it.
218    ///
219    /// ```
220    /// # include!("../templates/imports.rs");
221    /// # include!("../templates/castle_rights.rs");
222    /// # fn main() {
223    /// let mut rights = CastleRights::FULL;
224    /// assert_eq!(rights.len(), 4);
225    ///
226    /// for right in rights.as_iter().take(3) { /* ... */ }
227    /// assert_eq!(rights.len(), 1);
228    /// # }
229    /// ```
230    #[inline]
231    fn as_iter(&mut self) -> &mut BitIter<Self> {
232        unsafe { &mut *(self as *mut _ as *mut _) }
233    }
234
235    /// Converts `self` into the only bit set.
236    #[inline]
237    fn into_bit(mut self) -> Option<Self::Item> {
238        let bit = self.pop_lsb();
239        if self.is_empty() { bit } else { None }
240    }
241
242    /// Returns the least significant bit in `self` if `self` is not empty.
243    #[inline]
244    fn lsb(&self) -> Option<Self::Item> {
245        if self.is_empty() { None } else {
246            unsafe { Some(self.lsb_unchecked()) }
247        }
248    }
249
250    /// Returns the most significant bit in `self` if `self` is not empty.
251    #[inline]
252    fn msb(&self) -> Option<Self::Item> {
253        if self.is_empty() { None } else {
254            unsafe { Some(self.msb_unchecked()) }
255        }
256    }
257
258    /// Returns the least significant bit in `self` without checking whether
259    /// `self` is empty.
260    unsafe fn lsb_unchecked(&self) -> Self::Item;
261
262    /// Returns the most significant bit in `self` without checking whether
263    /// `self` is empty.
264    unsafe fn msb_unchecked(&self) -> Self::Item;
265
266    /// Removes the least significant bit from `self`.
267    fn remove_lsb(&mut self);
268
269    /// Removes the most significant bit from `self`.
270    fn remove_msb(&mut self);
271
272    /// Removes the least significant bit from `self` and returns it.
273    fn pop_lsb(&mut self) -> Option<Self::Item>;
274
275    /// Removes the most significant bit from `self` and returns it.
276    fn pop_msb(&mut self) -> Option<Self::Item>;
277
278    /// Returns whether `self` contains the value.
279    fn contains<T: Into<Self>>(&self, T) -> bool;
280
281    /// Returns the result of removing the value from `self`.
282    #[inline]
283    fn removing<T: Into<Self>>(self, other: T) -> Self {
284        self - other.into()
285    }
286
287    /// Returns the result of inserting the value into `self`.
288    #[inline]
289    fn inserting<T: Into<Self>>(self, other: T) -> Self {
290        self | other.into()
291    }
292
293    /// Returns the result of toggling the bits of the value in `self`.
294    #[inline]
295    fn toggling<T: Into<Self>>(self, other: T) -> Self {
296        self ^ other.into()
297    }
298
299    /// Returns the result of intersecting the bits of the value with `self`.
300    #[inline]
301    fn intersecting<T: Into<Self>>(self, other: T) -> Self {
302        self & other.into()
303    }
304
305    /// Returns the result of setting the bits of the value in `self` based on
306    /// `condition`.
307    #[inline]
308    fn setting<T: Into<Self>>(self, other: T, condition: bool) -> Self {
309        if condition {
310            self.inserting(other)
311        } else {
312            self.removing(other)
313        }
314    }
315
316    /// Removes the value from `self`.
317    #[inline]
318    fn remove<T: Into<Self>>(&mut self, other: T) -> &mut Self {
319        *self -= other.into();
320        self
321    }
322
323    /// Inserts the value into `self`.
324    #[inline]
325    fn insert<T: Into<Self>>(&mut self, other: T) -> &mut Self {
326        *self |= other.into();
327        self
328    }
329
330    /// Toggles bits of the value in `self`.
331    #[inline]
332    fn toggle<T: Into<Self>>(&mut self, other: T) -> &mut Self {
333        *self ^= other.into();
334        self
335    }
336
337    /// Intersects the bits of the value with `self`.
338    #[inline]
339    fn intersect<T: Into<Self>>(&mut self, other: T) -> &mut Self {
340        *self &= other.into();
341        self
342    }
343
344    /// Sets the bits of the value in `self` based on `condition`.
345    #[inline]
346    fn set<T: Into<Self>>(&mut self, other: T, condition: bool) -> &mut Self {
347        if condition {
348            self.insert(other)
349        } else {
350            self.remove(other)
351        }
352    }
353}
354
355/// An iterator over the bits of a [`BitCollection`](trait.BitCollection.html).
356#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
357pub struct BitIter<C: BitCollection>(pub C);
358
359impl<C: BitCollection> From<C> for BitIter<C> {
360    #[inline(always)]
361    fn from(bits: C) -> Self { BitIter(bits) }
362}
363
364impl<C: BitCollection> AsRef<C> for BitIter<C> {
365    #[inline(always)]
366    fn as_ref(&self) -> &C { &self.0 }
367}
368
369impl<C: BitCollection> AsMut<C> for BitIter<C> {
370    #[inline(always)]
371    fn as_mut(&mut self) -> &mut C { &mut self.0 }
372}
373
374impl<C: BitCollection> Borrow<C> for BitIter<C> {
375    #[inline(always)]
376    fn borrow(&self) -> &C { self.as_ref() }
377}
378
379impl<C: BitCollection> BorrowMut<C> for BitIter<C> {
380    #[inline(always)]
381    fn borrow_mut(&mut self) -> &mut C { self.as_mut() }
382}
383
384impl<C: BitCollection> Iterator for BitIter<C> {
385    type Item = C::Item;
386
387    #[inline]
388    fn next(&mut self) -> Option<Self::Item> {
389        self.0.pop_lsb()
390    }
391
392    #[inline]
393    fn size_hint(&self) -> (usize, Option<usize>) {
394        let len = self.len();
395        (len, Some(len))
396    }
397
398    #[inline]
399    fn count(self) -> usize {
400        self.len()
401    }
402
403    #[inline]
404    fn last(self) -> Option<Self::Item> {
405        self.0.msb()
406    }
407}
408
409impl<C: BitCollection> DoubleEndedIterator for BitIter<C> {
410    #[inline]
411    fn next_back(&mut self) -> Option<Self::Item> {
412        self.0.pop_msb()
413    }
414}
415
416impl<C: BitCollection> ExactSizeIterator for BitIter<C> {
417    #[inline]
418    fn len(&self) -> usize {
419        self.0.len()
420    }
421}
422
423/// How many bits are set in a [`BitCollection`](trait.BitCollection.html) as
424/// returned by [`quantity`](trait.BitCollection.html#method.quantity).
425#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
426pub enum Quantity {
427    // NOTE: The variant order is optimized for the quantity method
428    /// Multiple bits set.
429    Multiple,
430    /// Single bit set.
431    Single,
432    /// No bits set.
433    None,
434}
435
436impl PartialOrd for Quantity {
437    #[inline]
438    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
439        Some(self.cmp(other))
440    }
441
442    #[inline]
443    fn lt(&self, other: &Self) -> bool { (*self as usize) > (*other as usize) }
444
445    #[inline]
446    fn gt(&self, other: &Self) -> bool { (*self as usize) < (*other as usize) }
447
448    #[inline]
449    fn le(&self, other: &Self) -> bool { (*self as usize) >= (*other as usize) }
450
451    #[inline]
452    fn ge(&self, other: &Self) -> bool { (*self as usize) <= (*other as usize) }
453}
454
455impl Ord for Quantity {
456    #[inline]
457    fn cmp(&self, other: &Self) -> Ordering {
458        use Ordering::*;
459        match (*self as usize).cmp(&(*other as usize)) {
460            Equal => Equal,
461            Greater => Less,
462            Less => Greater,
463        }
464    }
465}