diff --git a/README.md b/README.md index 80e19e6f..83e4507e 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,6 @@ fid_rs = "0.1" ### Usage Overview ```rust -extern crate fid_rs; - use fid_rs::Fid; let fid = Fid::from("0100_1"); // Tips: Fid::from::<&str>() ignores '_'. @@ -62,7 +60,6 @@ assert_eq!(fid.select0(4), None); // There is no i where range [0, i] has 4 ' ### Constructors ```rust -extern crate fid_rs; use fid_rs::Fid; // Most human-friendly way: Fid::from::<&str>() @@ -75,6 +72,24 @@ arr[4] = true; let fid = Fid::from(&arr[..]); ``` +### Iterator + +```rust +use fid_rs::Fid; + +let fid = Fid::from("0100_1"); + +for bit in fid.iter() { + println!("{}", bit); +} +// => +// false +// true +// false +// false +// true +``` + ## Features - **Arbitrary length support with minimum working memory**: fid-rs provides virtually _arbitrary size_ of FID. It is carefully designed to use as small memory space as possible. diff --git a/src/fid.rs b/src/fid.rs index 7dad7e5b..0c60eff5 100644 --- a/src/fid.rs +++ b/src/fid.rs @@ -3,6 +3,7 @@ mod blocks; mod chunk; mod chunks; mod fid; +mod fid_iter; use super::internal_data_structure::popcount_table::PopcountTable; use super::internal_data_structure::raw_bit_vector::RawBitVector; @@ -108,6 +109,11 @@ pub struct Fid { table: PopcountTable, } +pub struct FidIter<'a> { + fid: &'a Fid, + i: u64, +} + /// Collection of Chunk. struct Chunks { chunks: Vec, diff --git a/src/fid/fid_iter.rs b/src/fid/fid_iter.rs new file mode 100644 index 00000000..b19f8a35 --- /dev/null +++ b/src/fid/fid_iter.rs @@ -0,0 +1,56 @@ +use super::{Fid, FidIter}; + +impl Fid { + /// Creates an iterator over FID's bit vector. + /// + /// # Examples + /// ``` + /// use fid_rs::Fid; + /// + /// let fid = Fid::from("1010_1010"); + /// for (i, bit) in fid.iter().enumerate() { + /// assert_eq!(bit, fid.access(i as u64)); + /// } + /// ``` + pub fn iter(&self) -> FidIter { + FidIter { fid: self, i: 0 } + } +} + +impl<'a> IntoIterator for &'a Fid { + type Item = bool; + type IntoIter = FidIter<'a>; + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a> Iterator for FidIter<'a> { + type Item = bool; + fn next(&mut self) -> Option { + if self.i >= self.fid.rbv.length() { + None + } else { + self.i += 1; + Some(self.fid.access(self.i - 1)) + } + } +} + +#[cfg(test)] +mod iter_success_tests { + use crate::Fid; + + #[test] + fn iter() { + let fid = Fid::from("1010_1010"); + for (i, bit) in fid.iter().enumerate() { + assert_eq!(bit, fid.access(i as u64)); + } + } +} + +#[cfg(test)] +mod iter_failure_tests { + // Nothing to test +} diff --git a/src/lib.rs b/src/lib.rs index 5e022d0d..4b843402 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,8 +26,6 @@ //! ## Usage Overview //! //! ```rust -//! extern crate fid_rs; -//! //! use fid_rs::Fid; //! //! let fid = Fid::from("0100_1"); // Tips: Fid::from::<&str>() ignores '_'. @@ -60,7 +58,6 @@ //! ## Constructors //! //! ```rust -//! extern crate fid_rs; //! use fid_rs::Fid; //! //! // Most human-friendly way: Fid::from::<&str>() @@ -73,6 +70,24 @@ //! let fid = Fid::from(&arr[..]); //! ``` //! +//! ## Iterator +//! +//! ```rust +//! use fid_rs::Fid; +//! +//! let fid = Fid::from("0100_1"); +//! +//! for bit in fid.iter() { +//! println!("{}", bit); +//! } +//! // => +//! // false +//! // true +//! // false +//! // false +//! // true +//! ``` +//! //! # Features //! //! - **Arbitrary length support with minimum working memory**: fid-rs provides virtually _arbitrary size_ of FID. It is carefully designed to use as small memory space as possible.