| { | ||
| "git": { | ||
| "sha1": "fbfbc02b8aaffb25d9c19cd4161997fc69fad28f" | ||
| } | ||
| } |
| /*! Sieve of Eratosthenes | ||
| The `bit_vec` crate had this as an example, so I do too, I guess. | ||
| Run with | ||
| ```sh | ||
| $ cargo run --release --example sieve -- [max] [count] | ||
| ``` | ||
| where max is an optional maximum number below which all primes will be found, | ||
| and count is an optional number whose square will be used to display the bottom | ||
| primes. | ||
| For example, | ||
| ```sh | ||
| $ cargo run --release --example sieve -- 10000000 25 | ||
| ``` | ||
| will find all primes less than ten million, and print the primes below 625 in a | ||
| square 25x25. | ||
| !*/ | ||
| extern crate bitvec; | ||
| use bitvec::*; | ||
| use std::env; | ||
| fn main() { | ||
| let max_prime: usize = env::args() | ||
| .nth(1) | ||
| .unwrap_or("1000000".into()) | ||
| .parse() | ||
| .unwrap_or(1_000_000); | ||
| let primes = { | ||
| let mut bv = BitVec::<BigEndian, u64>::with_capacity(max_prime); | ||
| bv.set_store(!0u64); | ||
| // Consider the vector fully populated | ||
| unsafe { bv.set_len(max_prime); } | ||
| // 0 and 1 are not primes | ||
| bv.set(0, false); | ||
| bv.set(1, false); | ||
| for n in 2 .. (1 + (max_prime as f64).sqrt() as usize) { | ||
| // Adjust the frequency of log statements vaguely logarithmically. | ||
| if n < 20_000 && n % 1_000 == 0 | ||
| || n < 50_000 && n % 5_000 == 0 | ||
| || n < 100_000 && n % 10_000 == 0 { | ||
| println!("Calculating {}…", n); | ||
| } | ||
| // If n is prime, mark all multiples as non-prime | ||
| if bv[n] { | ||
| if n < 50 { | ||
| println!("Calculating {}…", n); | ||
| } | ||
| 'inner: | ||
| for i in n .. { | ||
| let j = n * i; | ||
| if j >= max_prime { | ||
| break 'inner; | ||
| } | ||
| bv.set(j, false); | ||
| } | ||
| } | ||
| } | ||
| println!("Calculation complete!"); | ||
| bv | ||
| }; | ||
| // Count primes and non-primes. | ||
| let (mut one, mut zero) = (0u64, 0u64); | ||
| for n in primes.iter() { | ||
| if n { | ||
| one += 1; | ||
| } | ||
| else { | ||
| zero += 1; | ||
| } | ||
| } | ||
| println!("Counting complete!"); | ||
| println!("There are {} primes and {} non-primes below {}", one, zero, max_prime); | ||
| let dim: usize = env::args() | ||
| .nth(2) | ||
| .unwrap_or("10".into()) | ||
| .parse() | ||
| .unwrap_or(10); | ||
| println!("The primes smaller than {} are:", dim * dim); | ||
| let len = primes.len(); | ||
| 'outer: | ||
| for i in 0 .. dim { | ||
| for j in 0 .. dim { | ||
| let k = i * dim + j; | ||
| if k >= len { | ||
| println!(); | ||
| break 'outer; | ||
| } | ||
| if primes[k] { | ||
| print!("{:>4} ", k); | ||
| } | ||
| else { | ||
| print!(" "); | ||
| } | ||
| } | ||
| println!(); | ||
| } | ||
| } |
+2
-1
@@ -14,4 +14,5 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| [package] | ||
| edition = "2018" | ||
| name = "bitvec" | ||
| version = "0.5.0" | ||
| version = "0.6.0-e2018" | ||
| authors = ["myrrlyn <myrrlyn@outlook.com>"] | ||
@@ -18,0 +19,0 @@ description = "A crate for manipulating memory, bit by bit" |
+18
-1
@@ -5,2 +5,19 @@ # Changelog | ||
| ## 0.6.0 | ||
| ### Changed | ||
| - Update minimum Rust version to `1.25.0` in order to use nested imports. | ||
| - Fix logic in `Endian::prev`, and re-enabled edge tests. | ||
| - Pluralize `BitSlice::count_one()` and `BitSlice::count_zero()` function names. | ||
| - Fix documentation and comments. | ||
| - Consolidate implementation of `bitvec!` to not use any other macros. | ||
| ### 2018 Edition Branch | ||
| The branch `edition/2018` implements the changes necessary for use under the | ||
| 2018 edition of Rust. It can be used with the `-e2018` version suffix starting | ||
| with `0.6.0`. This branch and version suffix will track all ongoing development | ||
| until the minimum stable compiler version on the main trunk uses 2018 edition. | ||
| ## 0.5.0 | ||
@@ -53,3 +70,3 @@ | ||
| { | ||
| fn eq(&self, rhs: E) { ... } | ||
| fn eq(&self, rhs: E) { … } | ||
| } | ||
@@ -56,0 +73,0 @@ ``` |
+4
-5
@@ -9,3 +9,2 @@ /*! Demonstrates construction and use of a big-endian, u8, `BitVec` | ||
| #[macro_use] | ||
| extern crate bitvec; | ||
@@ -59,6 +58,6 @@ | ||
| println!("\ | ||
| Notice that ^ did not affect the parts of the tail that were not in use, while ! | ||
| did affect them. ^ requires a second source, while ! can just flip all elements. | ||
| ! is faster, but ^ is less likely to break your assumptions about what the | ||
| memory looks like.\ | ||
| Notice that `^` did not affect the parts of the tail that were not in | ||
| use, while `!` did affect them. `^` requires a second source, while `!` | ||
| can just flip all elements. `!` is faster, but `^` is less likely to | ||
| break your assumptions about what the memory looks like.\ | ||
| "); | ||
@@ -65,0 +64,0 @@ |
+12
-3
@@ -41,3 +41,3 @@ # `BitVec` – Managing memory bit by bit | ||
| [dependencies] | ||
| bitvec = "0.5" | ||
| bitvec = "0.6" | ||
| ``` | ||
@@ -54,2 +54,7 @@ | ||
| > Note: For 2018 edition Rust, use `"0.6.0-e2018"` as your version string, and | ||
| > elide the `#[macro_use]` import directive. The `use bitvec::*;` import is | ||
| > still recommended for using the `bitvec!` macro while I figure out how to | ||
| > properly use, but conceal, implementation details of the macro suite. | ||
| This gives you access to the `bitvec!` macro for building `BitVec` types | ||
@@ -170,3 +175,7 @@ similarly to the `vec!` macro, and imports the following symbols: | ||
| `#![no_std]` support that uses core libraries for allocation, and `#![no_core]` | ||
| support that strips the vector type entirely and only provides the slice type. | ||
| - `#![no_std]` support that uses core libraries for allocation, and | ||
| `#![no_core]` support that strips the vector type entirely and only provides | ||
| the slice type. | ||
| - A `Box<BitSlice>` type that corresponds to `Box<[T]>` between `&[T]` and | ||
| `Vec<T>`. |
+21
-19
@@ -8,22 +8,24 @@ /*! Bit Management | ||
| use std::cmp::Eq; | ||
| use std::convert::From; | ||
| use std::default::Default; | ||
| use std::fmt::{ | ||
| Binary, | ||
| Debug, | ||
| Display, | ||
| LowerHex, | ||
| UpperHex, | ||
| use std::{ | ||
| cmp::Eq, | ||
| convert::From, | ||
| default::Default, | ||
| fmt::{ | ||
| Binary, | ||
| Debug, | ||
| Display, | ||
| LowerHex, | ||
| UpperHex, | ||
| }, | ||
| ops::{ | ||
| Not, | ||
| BitAnd, | ||
| BitAndAssign, | ||
| BitOrAssign, | ||
| Shl, | ||
| ShlAssign, | ||
| Shr, | ||
| ShrAssign, | ||
| }, | ||
| }; | ||
| use std::ops::{ | ||
| Not, | ||
| BitAnd, | ||
| BitAndAssign, | ||
| BitOrAssign, | ||
| Shl, | ||
| ShlAssign, | ||
| Shr, | ||
| ShrAssign, | ||
| }; | ||
@@ -30,0 +32,0 @@ /// A trait for types that can be used as direct storage of bits. |
+53
-59
@@ -8,3 +8,3 @@ /*! Endianness Markers | ||
| use super::bits::Bits; | ||
| use crate::Bits; | ||
@@ -27,5 +27,5 @@ /// Travels an element starting at the Most Significant Bit and ending at the | ||
| - `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 | ||
| is the identity function (bit indices count up “left” from LSb), and in | ||
| Big-Endian order, this subtracts the count given from `T::MASK` (bit indices | ||
| count down "right" from MSb). | ||
| count down “right” from MSb). | ||
| - `next` computes the next index forward from the count given. In Little-Endian | ||
@@ -40,7 +40,2 @@ order, this increments (moving up from LSb towards MSb); in Big-Endian order, | ||
| Note that if the value returned from `next` is 0, or if the value returned from | ||
| `prev` is `T::MASK`, then the client is responsible for moving to the | ||
| neighboring element. No other signal will be raised for crossing over element | ||
| boundaries. | ||
| You should use `curr` to look up a bit at a known point, such as when indexing a | ||
@@ -98,3 +93,4 @@ `BitVec`; you should use `next` or `prev` to implement push, pop, and iteration; | ||
| fn prev<T: Bits>(count: u8) -> (u8, bool) { | ||
| count.overflowing_sub(1) | ||
| let (next, wrap) = count.overflowing_sub(1); | ||
| (next & T::MASK, wrap) | ||
| } | ||
@@ -108,3 +104,3 @@ | ||
| fn jump<T: Bits>(count: u8, offset: isize) -> (isize, u8) { | ||
| assert!(count <= T::MASK, "Bit count out of range for the storage type"); | ||
| assert!(count < T::WIDTH, "Bit count out of range for the storage type"); | ||
| // Add offset to *count*, not to the current bit index, because this | ||
@@ -114,3 +110,3 @@ // math doesn't know how to move around in an ordering. The offset is | ||
| // Subtraction can never fail, because count is always >= 0 and | ||
| // 0 - isize::MIN is isize::MIN, which does not overflow. | ||
| // `0 - isize::MIN` is `isize::MIN`, which does not overflow. | ||
| // In a non-overflowing addition, the result will be the position of | ||
@@ -121,10 +117,10 @@ // the target bit | ||
| // unsigned and use that. | ||
| // Note that this is guaranteed not to overflow usize::MAX because | ||
| // converting two positive signed integers to unsigned doubles the | ||
| // domain, which will always be enormously wider than the domain of | ||
| // count. | ||
| // Note that this is guaranteed not to overflow `usize::MAX` | ||
| // because converting two positive signed integers to unsigned | ||
| // doubles the domain, which will always be enormously wider than | ||
| // the domain of count. | ||
| (_, true) => { | ||
| let far = Self::curr::<T>(count) as usize + offset as usize; | ||
| // The number of elements advanced is, conveniently, the number | ||
| // of bits advanced integer divided by the number of bits in | ||
| // of bits advanced integer-divided by the number of bits in | ||
| // the elements, which even more conveniently, is equivalent to | ||
@@ -141,6 +137,5 @@ // right-shift by the number of bits required to index an | ||
| }, | ||
| // If far_bit is negative, then the jump leaves the element going | ||
| // backward. | ||
| // If far_bit is greater than T::MASK, then the jump leaves the | ||
| // element going forward. | ||
| // If `far` is negative, then the jump leaves the element going | ||
| // backward. If `far` is greater than `T::MASK`, then the jump | ||
| // leaves the element going forward. | ||
| (far, _) if far < 0 || far > T::MASK as isize => { | ||
@@ -151,3 +146,3 @@ let elements = far >> T::BITS; | ||
| }, | ||
| // Otherwise, far_bit is the *bit count* in the current element. It | ||
| // Otherwise, `far` is the *bit count* in the current element. It | ||
| // must still be converted from count to bit index. | ||
@@ -166,3 +161,3 @@ (far, _) => { | ||
| fn curr<T: Bits>(count: u8) -> u8 { | ||
| assert!(count <= T::MASK, "Index out of range of the storage type"); | ||
| assert!(count < T::WIDTH, "Index out of range of the storage type"); | ||
| T::MASK - count | ||
@@ -176,3 +171,3 @@ } | ||
| fn curr<T: Bits>(count: u8) -> u8 { | ||
| assert!(count <= T::MASK, "Index out of range of the storage type"); | ||
| assert!(count < T::WIDTH, "Index out of range of the storage type"); | ||
| count | ||
@@ -188,26 +183,12 @@ } | ||
| /* | ||
| All the comments below are because I didn't actually do the math correctly | ||
| when writing the test cases, and kept getting test failures on perfectly | ||
| sound code because I didn't grok what was actually going on. If you (either | ||
| someone who is not me, or my future self) decide to add more test cases to | ||
| this to harden expectations about what jump does, be absolutely sure you | ||
| have correct expectations before changing the code if your tests fail. | ||
| Be sure to remember that all the functions take a *semantic count*, not a | ||
| *bit index*, and as such you should **not** pass different values to | ||
| different Endian implementations in order to try to account for their | ||
| different counting styles. | ||
| */ | ||
| #[test] | ||
| fn incr_edge() { | ||
| // assert_eq!(LittleEndian::next::<u8>(7), (0, true)); | ||
| // assert_eq!(BigEndian::next::<u8>(7), (7, true)); | ||
| // assert_eq!(LittleEndian::next::<u16>(15), (0, true)); | ||
| // assert_eq!(BigEndian::next::<u16>(15), (15, true)); | ||
| // assert_eq!(LittleEndian::next::<u32>(31), (0, true)); | ||
| // assert_eq!(BigEndian::next::<u32>(31), (31, true)); | ||
| // assert_eq!(LittleEndian::next::<u64>(63), (0, true)); | ||
| // assert_eq!(BigEndian::next::<u64>(63), (63, true)); | ||
| assert_eq!(LittleEndian::next::<u8>(7), (0, true)); | ||
| assert_eq!(BigEndian::next::<u8>(7), (0, true)); | ||
| assert_eq!(LittleEndian::next::<u16>(15), (0, true)); | ||
| assert_eq!(BigEndian::next::<u16>(15), (0, true)); | ||
| assert_eq!(LittleEndian::next::<u32>(31), (0, true)); | ||
| assert_eq!(BigEndian::next::<u32>(31), (0, true)); | ||
| assert_eq!(LittleEndian::next::<u64>(63), (0, true)); | ||
| assert_eq!(BigEndian::next::<u64>(63), (0, true)); | ||
| } | ||
@@ -217,10 +198,10 @@ | ||
| fn decr_edge() { | ||
| // assert_eq!(LittleEndian::prev::<u8>(0), (7, true)); | ||
| // assert_eq!(BigEndian::prev::<u8>(0), (0, true)); | ||
| // assert_eq!(LittleEndian::prev::<u16>(0), (15, true)); | ||
| // assert_eq!(BigEndian::prev::<u16>(0), (0, true)); | ||
| // assert_eq!(LittleEndian::prev::<u32>(0), (31, true)); | ||
| // assert_eq!(BigEndian::prev::<u32>(0), (0, true)); | ||
| // assert_eq!(LittleEndian::prev::<u64>(0), (63, true)); | ||
| // assert_eq!(BigEndian::prev::<u64>(0), (0, true)); | ||
| assert_eq!(LittleEndian::prev::<u8>(0), (7, true)); | ||
| assert_eq!(BigEndian::prev::<u8>(0), (7, true)); | ||
| assert_eq!(LittleEndian::prev::<u16>(0), (15, true)); | ||
| assert_eq!(BigEndian::prev::<u16>(0), (15, true)); | ||
| assert_eq!(LittleEndian::prev::<u32>(0), (31, true)); | ||
| assert_eq!(BigEndian::prev::<u32>(0), (31, true)); | ||
| assert_eq!(LittleEndian::prev::<u64>(0), (63, true)); | ||
| assert_eq!(BigEndian::prev::<u64>(0), (63, true)); | ||
| } | ||
@@ -230,3 +211,3 @@ | ||
| fn jump_inside_elt() { | ||
| // TODO: test the other two types. | ||
| // TODO(myrrlyn): test the other two types. | ||
@@ -255,3 +236,3 @@ let (elt, bit) = LittleEndian::jump::<u8>(5, 2); | ||
| fn jump_backwards() { | ||
| // TODO: Test the other three types. | ||
| // TODO(myrrlyn): Test the other three types. | ||
@@ -274,3 +255,3 @@ let (elt, bit) = LittleEndian::jump::<u32>(10, -15); | ||
| fn jump_forwards() { | ||
| // TODO: Test the other three types. | ||
| // TODO(myrrlyn): Test the other three types. | ||
@@ -291,8 +272,9 @@ let (elt, bit) = LittleEndian::jump::<u32>(25, 10); | ||
| fn jump_overflow() { | ||
| // TODO: Test the other three types. | ||
| // TODO(myrrlyn): Test the other three types. | ||
| // Force an overflowing stride. We expect the destination bit *count* | ||
| // to be one less than the starting point (which on BigEndian will be | ||
| // MASK - start - 1), and the elements skipped to be isize::MIN >> BITS | ||
| // (an overflowing isize add will set the high bit as the usize repr). | ||
| // `MASK - start - 1`), and the elements skipped to be | ||
| // `isize::MIN >> BITS` (an overflowing isize add will set the high bit | ||
| // as the `usize` repr). | ||
| let start = 20; | ||
@@ -323,3 +305,15 @@ let (elt, bit) = LittleEndian::jump::<u32>(start, ::std::isize::MAX); | ||
| } | ||
| for n in 0 .. 8 { | ||
| assert_eq!(n, LittleEndian::curr::<u8>(LittleEndian::curr::<u8>(n))); | ||
| } | ||
| for n in 0 .. 16 { | ||
| assert_eq!(n, LittleEndian::curr::<u16>(LittleEndian::curr::<u16>(n))); | ||
| } | ||
| for n in 0 .. 32 { | ||
| assert_eq!(n, LittleEndian::curr::<u32>(LittleEndian::curr::<u32>(n))); | ||
| } | ||
| for n in 0 .. 64 { | ||
| assert_eq!(n, LittleEndian::curr::<u64>(LittleEndian::curr::<u64>(n))); | ||
| } | ||
| } | ||
| } |
+12
-9
@@ -12,3 +12,3 @@ /*! `BitVec` – `Vec<bool>` in overdrive. | ||
| `u64` – and the order in which each primitive is traversed – big-endian, from | ||
| the most significant bit to the leasts, or little-endian, from the least | ||
| the most significant bit to the least, or little-endian, from the least | ||
| significant bit to the most. | ||
@@ -37,4 +37,5 @@ | ||
| #[doc(hidden)] | ||
| #[macro_use] | ||
| mod macros; | ||
| pub mod macros; | ||
@@ -46,10 +47,12 @@ mod bits; | ||
| pub use bits::Bits; | ||
| pub use endian::*; | ||
| pub use macros::*; | ||
| pub use slice::BitSlice; | ||
| pub use vec::BitVec; | ||
| pub use crate::{ | ||
| bits::Bits, | ||
| endian::*, | ||
| macros::*, | ||
| slice::BitSlice, | ||
| vec::BitVec, | ||
| }; | ||
| // The Index trait returns references to bools, and it is impossible to make an | ||
| // address for a bit in the middle of a byte. Therefore, Index::index | ||
| // The `Index` trait returns references to bools, and it is impossible to make | ||
| // an address for a bit in the middle of a byte. Therefore, `Index::index` | ||
| // references these static values depending on the value of the bit. | ||
@@ -56,0 +59,0 @@ // |
+124
-104
@@ -1,83 +0,85 @@ | ||
| /// Construct a `BitVec` out of a literal array in source code, analagous to | ||
| /// `vec!`. | ||
| /// | ||
| /// `bitvec!` can be invoked in a number of ways. It takes the name of an | ||
| /// `Endian` implementation, the name of a `Bits`-implementing primitive, and | ||
| /// zero or more primitives (integer, floating-point, or bool) which are used to | ||
| /// build the bits. Each primitive literal corresponds to one bit, and is | ||
| /// considered to represent 1 if *any* bit in the representation is set. | ||
| /// | ||
| /// `bitvec!` can be invoked with no specifiers, and `Endian` specifier, or an | ||
| /// `Endian` and a `Bits` specifier. It cannot be invoked with a `Bits` | ||
| /// specifier but no `Endian` specifier, due to overlap in how those tokens are | ||
| /// matched by the macro system. | ||
| /// | ||
| /// Like `vec!`, `bitvec!` supports bit lists `[0, 1, ...]` and repetition | ||
| /// markers `[1; n]`. | ||
| /// | ||
| /// # All Syntaxes | ||
| /// | ||
| /// ```rust | ||
| /// # use bitvec::*; | ||
| /// bitvec![BigEndian, u8; 0, 1]; | ||
| /// bitvec![LittleEndian, u8; 0, 1,]; | ||
| /// bitvec![BigEndian; 0, 1]; | ||
| /// bitvec![LittleEndian; 0, 1,]; | ||
| /// bitvec![0, 1]; | ||
| /// bitvec![0, 1,]; | ||
| /// bitvec![BigEndian, u8; 1; 5]; | ||
| /// bitvec![LittleEndian; 0; 5]; | ||
| /// bitvec![1; 5]; | ||
| /// ``` | ||
| /** Construct a `BitVec` out of a literal array in source code, like `vec!`. | ||
| `bitvec!` can be invoked in a number of ways. It takes the name of an | ||
| `Endian` implementation, the name of a `Bits`-implementing primitive, and | ||
| zero or more primitives (integer, floating-point, or bool) which are used to | ||
| build the bits. Each primitive literal corresponds to one bit, and is | ||
| considered to represent `1` if it is any other value than exactly zero. | ||
| `bitvec!` can be invoked with no specifiers, an `Endian` specifier, or an | ||
| `Endian` and a `Bits` specifier. It cannot be invoked with a `Bits` | ||
| specifier but no `Endian` specifier, due to overlap in how those tokens are | ||
| matched by the macro system. | ||
| Like `vec!`, `bitvec!` supports bit lists `[0, 1, …]` and repetition | ||
| markers `[1; n]`. | ||
| # All Syntaxes | ||
| ```rust | ||
| # use bitvec::*; | ||
| bitvec![BigEndian, u8; 0, 1]; | ||
| bitvec![LittleEndian, u8; 0, 1,]; | ||
| bitvec![BigEndian; 0, 1]; | ||
| bitvec![LittleEndian; 0, 1,]; | ||
| bitvec![0, 1]; | ||
| bitvec![0, 1,]; | ||
| bitvec![BigEndian, u8; 1; 5]; | ||
| bitvec![LittleEndian; 0; 5]; | ||
| bitvec![1; 5]; | ||
| ``` | ||
| **/ | ||
| #[macro_export] | ||
| macro_rules! bitvec { | ||
| // bitvec![endian, type ; 0, 1, ...] | ||
| ( $end:ident , $prim:ty ; $( $elt:expr ),* ) => { | ||
| __bitvec_impl![ $end, $prim ; $( $elt ),* ] | ||
| // bitvec![endian, type ; 0, 1, …] | ||
| ( $endian:ident , $primitive:ty ; $( $elt:expr ),* ) => { | ||
| bitvec![ __bv_impl__ $endian , $primitive ; $( $elt ),* ] | ||
| }; | ||
| // bitvec![endian, type ; 0, 1, ..., ] | ||
| ( $end:ident , $prim:ty ; $( $elt:expr , )* ) => { | ||
| __bitvec_impl![ $end , $prim ; $( $elt ),* ] | ||
| // bitvec![endian, type ; 0, 1, …, ] | ||
| ( $endian:ident , $primitive:ty ; $( $elt:expr , )* ) => { | ||
| bitvec![ __bv_impl__ $endian , $primitive ; $( $elt ),* ] | ||
| }; | ||
| // bitvec![endian ; 0, 1, ...] | ||
| ( $end:ident ; $( $elt:expr ),* ) => { | ||
| __bitvec_impl![ $end , u8 ; $( $elt ),* ] | ||
| // bitvec![endian ; 0, 1, …] | ||
| ( $endian:ident ; $( $elt:expr ),* ) => { | ||
| bitvec![ __bv_impl__ $endian , u8 ; $( $elt ),* ] | ||
| }; | ||
| // bitvec![endian ; 0, 1, ..., ] | ||
| ( $end:ident ; $( $elt:expr , )* ) => { | ||
| __bitvec_impl![ $end , u8 ; $( $elt ),* ] | ||
| // bitvec![endian ; 0, 1, …, ] | ||
| ( $endian:ident ; $( $elt:expr , )* ) => { | ||
| bitvec![ __bv_impl__ $endian , u8 ; $( $elt ),* ] | ||
| }; | ||
| // bitvec![0, 1, ...] | ||
| // bitvec![0, 1, …] | ||
| ( $( $elt:expr ),* ) => { | ||
| __bitvec_impl![ BigEndian , u8 ; $($elt),* ] | ||
| bitvec![ __bv_impl__ BigEndian , u8 ; $($elt),* ] | ||
| }; | ||
| // bitvec![0, 1, ..., ] | ||
| // bitvec![0, 1, …, ] | ||
| ( $( $elt:expr , )* ) => { | ||
| __bitvec_impl![ BigEndian , u8 ; $($elt),* ] | ||
| bitvec![ __bv_impl__ BigEndian , u8 ; $($elt),* ] | ||
| }; | ||
| // bitvec![endian, type, bit; rep] | ||
| ( $end:ident , $prim:ty ; $elt:expr ; $rep:expr ) => { | ||
| __bitvec_impl![ $end , $prim ; $elt; $rep ] | ||
| // bitvec![endian, type; bit; rep] | ||
| ( $endian:ident , $primitive:ty ; $elt:expr ; $rep:expr ) => { | ||
| bitvec![ __bv_impl__ $endian , $primitive ; $elt; $rep ] | ||
| }; | ||
| // bitvec![endian, bit; rep] | ||
| ( $end:ident ; $elt:expr ; $rep:expr ) => { | ||
| __bitvec_impl![ $end , u8 ; $elt; $rep ] | ||
| // bitvec![endian; bit; rep] | ||
| ( $endian:ident ; $elt:expr ; $rep:expr ) => { | ||
| bitvec![ __bv_impl__ $endian , u8 ; $elt; $rep ] | ||
| }; | ||
| // bitvec![bit; rep] | ||
| ( $elt:expr ; $rep:expr ) => { | ||
| __bitvec_impl![ BigEndian, u8 ; $elt; $rep ] | ||
| bitvec![ __bv_impl__ BigEndian , u8 ; $elt; $rep ] | ||
| }; | ||
| } | ||
| /// Build an array of `bool` (one bit per byte) and then build a `BitVec` from that (one | ||
| /// bit per bit). I have yet to think of a way to make the source array be | ||
| /// binary-compatible with a `BitVec` representation, so the static source is 8x larger | ||
| /// than it needs to be. | ||
| /// | ||
| /// I'm sure there is a way, but I don’t think I need to spend the effort yet. | ||
| #[macro_export] | ||
| #[doc(hidden)] | ||
| macro_rules! __bitvec_impl { | ||
| ( $end:ident , $prim:ty ; $( $elt:expr ),* ) => {{ | ||
| // Build an array of `bool` (one bit per byte) and then build a `BitVec` | ||
| // from that (one bit per bit). I have yet to think of a way to make the | ||
| // source array be binary-compatible with a `BitVec` representation, so the | ||
| // static source is 8x larger than it needs to be. | ||
| // | ||
| // I'm sure there is a way, but I don’t think I need to spend the effort | ||
| // yet. | ||
| ( __bv_impl__ $end:ident , $prim:ty ; $( $elt:expr ),* ) => {{ | ||
| let init: &[bool] = &[ | ||
@@ -89,3 +91,3 @@ $( $elt as u8 > 0 ),* | ||
| ( $end:ident , $prim:ty ; $elt:expr; $rep:expr ) => {{ | ||
| ( __bv_impl__ $end:ident , $prim:ty ; $elt:expr; $rep:expr ) => {{ | ||
| ::std::iter::repeat( $elt as u8 > 0 ) | ||
@@ -100,15 +102,19 @@ .take( $rep ) | ||
| ( $( $t:ty ),+ ) => { $( | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ShlAssign< $t > for $crate::BitSlice<E, T> { | ||
| fn shl_assign(&mut self, shamt: $t ) { | ||
| ShlAssign::<usize>::shl_assign(self, shamt as usize); | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ::std::ops::ShlAssign< $t > | ||
| for $crate::BitSlice<E, T> | ||
| { | ||
| fn shl_assign(&mut self, shamt: $t ) { | ||
| ::std::ops::ShlAssign::<usize>::shl_assign(self, shamt as usize); | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ShrAssign< $t > for $crate::BitSlice<E, T> { | ||
| fn shr_assign(&mut self, shamt: $t ) { | ||
| ShrAssign::<usize>::shr_assign(self, shamt as usize); | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ::std::ops::ShrAssign< $t > | ||
| for $crate::BitSlice<E, T> | ||
| { | ||
| fn shr_assign(&mut self, shamt: $t ) { | ||
| ::std::ops::ShrAssign::<usize>::shr_assign(self, shamt as usize); | ||
| } | ||
| } | ||
| )+ }; | ||
@@ -120,33 +126,41 @@ } | ||
| ( $( $t:ty ),+ ) => { $( | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> Shl< $t > for $crate::BitVec<E, T> { | ||
| type Output = <Self as Shl<usize>>::Output; | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ::std::ops::Shl< $t > | ||
| for $crate::BitVec<E, T> | ||
| { | ||
| type Output = <Self as ::std::ops::Shl<usize>>::Output; | ||
| fn shl(self, shamt: $t ) -> Self::Output { | ||
| Shl::<usize>::shl(self, shamt as usize) | ||
| } | ||
| } | ||
| fn shl(self, shamt: $t ) -> Self::Output { | ||
| ::std::ops::Shl::<usize>::shl(self, shamt as usize) | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ShlAssign< $t > for $crate::BitVec<E, T> { | ||
| fn shl_assign(&mut self, shamt: $t ) { | ||
| ShlAssign::<usize>::shl_assign(self, shamt as usize) | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ::std::ops::ShlAssign< $t > | ||
| for $crate::BitVec<E, T> | ||
| { | ||
| fn shl_assign(&mut self, shamt: $t ) { | ||
| ::std::ops::ShlAssign::<usize>::shl_assign(self, shamt as usize) | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> Shr< $t > for $crate::BitVec<E, T> { | ||
| type Output = <Self as Shr<usize>>::Output; | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ::std::ops::Shr< $t > | ||
| for $crate::BitVec<E, T> | ||
| { | ||
| type Output = <Self as ::std::ops::Shr<usize>>::Output; | ||
| fn shr(self, shamt: $t ) -> Self::Output { | ||
| Shr::<usize>::shr(self, shamt as usize) | ||
| } | ||
| } | ||
| fn shr(self, shamt: $t ) -> Self::Output { | ||
| ::std::ops::Shr::<usize>::shr(self, shamt as usize) | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ShrAssign< $t > for $crate::BitVec<E, T> { | ||
| fn shr_assign(&mut self, shamt: $t ) { | ||
| ShrAssign::<usize>::shr_assign(self, shamt as usize) | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| impl<E: $crate::Endian, T: $crate::Bits> ::std::ops::ShrAssign< $t > | ||
| for $crate::BitVec<E, T> | ||
| { | ||
| fn shr_assign(&mut self, shamt: $t ) { | ||
| ::std::ops::ShrAssign::<usize>::shr_assign(self, shamt as usize) | ||
| } | ||
| } | ||
| )+ }; | ||
@@ -157,2 +171,8 @@ } | ||
| mod tests { | ||
| #[allow(unused_imports)] | ||
| use crate::{ | ||
| BigEndian, | ||
| LittleEndian, | ||
| }; | ||
| #[test] | ||
@@ -159,0 +179,0 @@ fn compile_macros() { |
+161
-147
| /*! `BitSlice` Wide Reference | ||
| This module bears some explanation. Let's get *uncomfortable* here. | ||
| This module bears some explanation. Let’s get *uncomfortable* here. | ||
| Safe Rust is very strict about concepts like lifetimes and size in memory. It | ||
| won't allow you to have arbitrary *references* to things where Rust doesn't feel | ||
| absolutely confident that the referent will outlive the reference, and it won't | ||
| won’t allow you to have arbitrary *references* to things where Rust doesn’t feel | ||
| absolutely confident that the referent will outlive the reference, and it won’t | ||
| let you have things *at all* that it can't size at compile time. This makes | ||
@@ -20,3 +20,3 @@ dealing with runtime-sized memory of uncertain lifetime tricky to do, and the | ||
| `Deref` requires returning a reference to a type, and it is impossible to tell | ||
| Rust "this type is a named reference", and two, ... the lifetime parameter of | ||
| Rust "this type is a named reference", and two, … the lifetime parameter of | ||
| `BitSlice` is not able to be provided by the `Deref` trait, the `deref` trait | ||
@@ -39,3 +39,3 @@ function, or even by using Higher Ranked Trait Bounds because HRTB just allows | ||
| use super::{ | ||
| use crate::{ | ||
| Bits, | ||
@@ -48,46 +48,48 @@ Endian, | ||
| }; | ||
| use std::borrow::ToOwned; | ||
| use std::cmp::{ | ||
| Eq, | ||
| Ord, | ||
| Ordering, | ||
| PartialEq, | ||
| PartialOrd, | ||
| use std::{ | ||
| borrow::ToOwned, | ||
| cmp::{ | ||
| Eq, | ||
| Ord, | ||
| Ordering, | ||
| PartialEq, | ||
| PartialOrd, | ||
| }, | ||
| convert::{ | ||
| AsMut, | ||
| AsRef, | ||
| From, | ||
| }, | ||
| fmt::{ | ||
| self, | ||
| Debug, | ||
| Display, | ||
| Formatter, | ||
| }, | ||
| hash::{ | ||
| Hash, | ||
| Hasher, | ||
| }, | ||
| iter::{ | ||
| DoubleEndedIterator, | ||
| ExactSizeIterator, | ||
| Iterator, | ||
| IntoIterator, | ||
| }, | ||
| marker::PhantomData, | ||
| mem, | ||
| ops::{ | ||
| AddAssign, | ||
| BitAndAssign, | ||
| BitOrAssign, | ||
| BitXorAssign, | ||
| Index, | ||
| Neg, | ||
| Not, | ||
| ShlAssign, | ||
| ShrAssign, | ||
| }, | ||
| ptr, | ||
| slice, | ||
| }; | ||
| use std::convert::{ | ||
| AsMut, | ||
| AsRef, | ||
| From, | ||
| }; | ||
| use std::fmt::{ | ||
| self, | ||
| Debug, | ||
| Display, | ||
| Formatter, | ||
| }; | ||
| use std::hash::{ | ||
| Hash, | ||
| Hasher, | ||
| }; | ||
| use std::iter::{ | ||
| DoubleEndedIterator, | ||
| ExactSizeIterator, | ||
| Iterator, | ||
| IntoIterator, | ||
| }; | ||
| use std::marker::PhantomData; | ||
| use std::mem; | ||
| use std::ops::{ | ||
| AddAssign, | ||
| BitAndAssign, | ||
| BitOrAssign, | ||
| BitXorAssign, | ||
| Index, | ||
| Neg, | ||
| Not, | ||
| ShlAssign, | ||
| ShrAssign, | ||
| }; | ||
| use std::ptr; | ||
| use std::slice; | ||
@@ -100,3 +102,3 @@ /** A compact slice of bits, whose cursor and storage type can be customized. | ||
| responsible. **Do not try to create a `Box<BitSlice>`.** If you want an owned | ||
| bit collection, use `BitVec`. | ||
| bit collection, use `BitVec`. (This may change in a future release.) | ||
@@ -131,3 +133,3 @@ `BitSlice` is strictly a reference type. The memory it governs must be owned by | ||
| where E: Endian, T: Bits { | ||
| /// Get the bit value at the given position. | ||
| /// Gets the bit value at the given position. | ||
| /// | ||
@@ -151,3 +153,3 @@ /// The index value is a semantic count, not a bit address. It converts to a | ||
| /// Set the bit value at the given position. | ||
| /// Sets the bit value at the given position. | ||
| /// | ||
@@ -172,3 +174,3 @@ /// The index value is a semantic count, not a bit address. It converts to a | ||
| /// Return true if *all* bits in the slice are set (logical `∧`). | ||
| /// Returns true if *all* bits in the slice are set (logical `∧`). | ||
| /// | ||
@@ -219,3 +221,3 @@ /// # Truth Table | ||
| /// Return true if *any* bit in the slice is set (logical `∨`). | ||
| /// Returns true if *any* bit in the slice is set (logical `∨`). | ||
| /// | ||
@@ -266,3 +268,3 @@ /// # Truth Table | ||
| /// Return true if *any* bit in the slice is unset (logical `¬∧`). | ||
| /// Returns true if *any* bit in the slice is unset (logical `¬∧`). | ||
| /// | ||
@@ -296,3 +298,3 @@ /// # Truth Table | ||
| /// Return true if *all* bits in the slice are uset (logical `¬∨`). | ||
| /// Returns true if *all* bits in the slice are unset (logical `¬∨`). | ||
| /// | ||
@@ -326,5 +328,7 @@ /// # Truth Table | ||
| /// Return true if some, but not all, bits are set and some, but not all, | ||
| /// Returns true if some, but not all, bits are set and some, but not all, | ||
| /// are unset. | ||
| /// | ||
| /// This is false if either `all()` or `none()` are true. | ||
| /// | ||
| /// # Truth Table | ||
@@ -355,3 +359,3 @@ /// | ||
| /// Count how many bits are set high. | ||
| /// Counts how many bits are set high. | ||
| /// | ||
@@ -363,9 +367,9 @@ /// # Examples | ||
| /// let bv = bitvec![1, 0, 1, 0, 1]; | ||
| /// assert_eq!(bv.count_one(), 3); | ||
| /// assert_eq!(bv.count_ones(), 3); | ||
| /// ``` | ||
| pub fn count_one(&self) -> usize { | ||
| pub fn count_ones(&self) -> usize { | ||
| self.into_iter().filter(|b| *b).count() | ||
| } | ||
| /// Count how many bits are set low. | ||
| /// Counts how many bits are set low. | ||
| /// | ||
@@ -377,9 +381,9 @@ /// # Examples | ||
| /// let bv = bitvec![0, 1, 0, 1, 0]; | ||
| /// assert_eq!(bv.count_zero(), 3); | ||
| /// assert_eq!(bv.count_zeros(), 3); | ||
| /// ``` | ||
| pub fn count_zero(&self) -> usize { | ||
| pub fn count_zeros(&self) -> usize { | ||
| self.into_iter().filter(|b| !b).count() | ||
| } | ||
| /// Return the number of bits contained in the `BitSlice`. | ||
| /// Returns the number of bits contained in the `BitSlice`. | ||
| /// | ||
@@ -398,3 +402,3 @@ /// # Examples | ||
| /// Count how many *whole* storage elements are in the `BitSlice`. | ||
| /// Counts how many *whole* storage elements are in the `BitSlice`. | ||
| /// | ||
@@ -424,3 +428,3 @@ /// If the `BitSlice` length is not an even multiple of the width of `T`, | ||
| /// Count how many bits are in the trailing partial storage element. | ||
| /// Counts how many bits are in the trailing partial storage element. | ||
| /// | ||
@@ -450,3 +454,3 @@ /// If the `BitSlice` length is an even multiple of the width of `T`, then | ||
| /// Return `true` if the slice contains no bits. | ||
| /// Returns `true` if the slice contains no bits. | ||
| /// | ||
@@ -472,3 +476,3 @@ /// # Examples | ||
| /// Provide read-only iteration across the collection. | ||
| /// Provides read-only iteration across the collection. | ||
| /// | ||
@@ -482,3 +486,3 @@ /// The iterator returned from this method implements `ExactSizeIterator` | ||
| /// Provide mutable traversal of the collection. | ||
| /// Provides mutable traversal of the collection. | ||
| /// | ||
@@ -514,3 +518,3 @@ /// It is impossible to implement `IndexMut` on `BitSlice` because bits do | ||
| /// Retrieve a read pointer to the start of the data slice. | ||
| /// Retrieves a read pointer to the start of the data slice. | ||
| pub(crate) fn as_ptr(&self) -> *const T { | ||
@@ -520,3 +524,3 @@ self.inner.as_ptr() | ||
| /// Retrieve a write pointer to the start of the data slice. | ||
| /// Retrieves a write pointer to the start of the data slice. | ||
| pub(crate) fn as_mut_ptr(&mut self) -> *mut T { | ||
@@ -526,4 +530,4 @@ self.inner.as_mut_ptr() | ||
| /// Compute the actual length of the data slice, including the partial tail | ||
| /// if any. | ||
| /// Computes the actual length of the data slice, including the partial tail | ||
| /// if present. | ||
| /// | ||
@@ -543,3 +547,3 @@ /// # Examples | ||
| /// Print a type header into the Formatter. | ||
| /// Prints a type header into the Formatter. | ||
| pub(crate) fn fmt_header(&self, fmt: &mut Formatter) -> fmt::Result { | ||
@@ -549,3 +553,3 @@ write!(fmt, "BitSlice<{}, {}>", E::TY, T::TY) | ||
| /// Format the contents data slice. | ||
| /// Formats the contents data slice. | ||
| /// | ||
@@ -580,3 +584,3 @@ /// The debug flag indicates whether to indent each line (`Debug` does, | ||
| /// Format a whole storage element of the data slice. | ||
| /// Formats a whole storage element of the data slice. | ||
| pub(crate) fn fmt_element(fmt: &mut Formatter, elt: &T) -> fmt::Result { | ||
@@ -586,3 +590,3 @@ Self::fmt_bits(fmt, elt, T::WIDTH) | ||
| /// Format a partial element of the data slice. | ||
| /// Formats a partial element of the data slice. | ||
| pub(crate) fn fmt_bits(fmt: &mut Formatter, elt: &T, bits: u8) -> fmt::Result { | ||
@@ -593,3 +597,3 @@ use std::fmt::Write; | ||
| let cur = E::curr::<T>(bit); | ||
| write!(out, "{}", if elt.get(cur) { "1" } else { "0" })?; | ||
| out.write_str(if elt.get(cur) { "1" } else { "0" })?; | ||
| } | ||
@@ -600,3 +604,3 @@ fmt.write_str(&out) | ||
| /// Clone a borrowed `BitSlice` into an owned `BitVec`. | ||
| /// Creates a new `BitVec` out of a `BitSlice`. | ||
| impl<E, T> ToOwned for BitSlice<E, T> | ||
@@ -606,2 +610,4 @@ where E: Endian, T: Bits { | ||
| /// Clones a borrowed `BitSlice` into an owned `BitVec`. | ||
| /// | ||
| /// # Examples | ||
@@ -642,3 +648,3 @@ /// | ||
| /// Test if two `BitSlice`s are semantically — not bitwise — equal. | ||
| /// Tests if two `BitSlice`s are semantically — not bitwise — equal. | ||
| /// | ||
@@ -651,3 +657,3 @@ /// It is valid to compare two slices of different endianness or element types. | ||
| where A: Endian, B: Bits, C: Endian, D: Bits { | ||
| /// Perform a comparison by `==`. | ||
| /// Performs a comparison by `==`. | ||
| /// | ||
@@ -674,3 +680,3 @@ /// # Examples | ||
| /// Compare two `BitSlice`s by semantic — not bitwise — ordering. | ||
| /// Compares two `BitSlice`s by semantic — not bitwise — ordering. | ||
| /// | ||
@@ -685,3 +691,3 @@ /// The comparison sorts by testing each index for one slice to have a set bit | ||
| where A: Endian, B: Bits, C: Endian, D: Bits { | ||
| /// Perform a comparison by `<` or `>`. | ||
| /// Performs a comparison by `<` or `>`. | ||
| /// | ||
@@ -713,7 +719,7 @@ /// # Examples | ||
| /// Give write access to all elements in the underlying storage, including the | ||
| /// Gives write access to all elements in the underlying storage, including the | ||
| /// partially-filled tail element (if present). | ||
| impl<E, T> AsMut<[T]> for BitSlice<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Access the underlying store. | ||
| /// Accesses the underlying store. | ||
| /// | ||
@@ -728,3 +734,3 @@ /// # Examples | ||
| /// } | ||
| /// assert_eq!(&[2, 0b1000_0010], bv.as_ref()); | ||
| /// assert_eq!(&[2, 130], bv.as_ref()); | ||
| /// ``` | ||
@@ -737,7 +743,7 @@ fn as_mut(&mut self) -> &mut [T] { | ||
| /// Give read access to all elements in the underlying storage, including the | ||
| /// Gives read access to all elements in the underlying storage, including the | ||
| /// partially-filled tail element (if present). | ||
| impl<E, T> AsRef<[T]> for BitSlice<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Access the underlying store. | ||
| /// Accesses the underlying store. | ||
| /// | ||
@@ -758,7 +764,7 @@ /// # Examples | ||
| /// Build a `BitSlice` from a slice of elements. The resulting `BitSlice` will | ||
| /// Builds a `BitSlice` from a slice of elements. The resulting `BitSlice` will | ||
| /// always completely fill the original slice, and will not have a partial tail. | ||
| impl<'a, E, T> From<&'a [T]> for &'a BitSlice<E, T> | ||
| where E: Endian, T: 'a + Bits { | ||
| /// Wrap an `&[T: Bits]` in an `&BitSlice<E: Endian, T>`. The endianness | ||
| /// Wraps an `&[T: Bits]` in an `&BitSlice<E: Endian, T>`. The endianness | ||
| /// must be specified by the call site. The element type cannot be changed. | ||
@@ -792,3 +798,3 @@ /// | ||
| /// Build a mutable `BitSlice` from a slice of mutable elements. The resulting | ||
| /// Builds a mutable `BitSlice` from a slice of mutable elements. The resulting | ||
| /// `BitSlice` will always completely fill the original slice, and will not have | ||
@@ -798,3 +804,3 @@ /// a partial tail. | ||
| where E: Endian, T: 'a + Bits { | ||
| /// Wrap an `&mut [T: Bits]` in an `&mut BitSlice<E: Endian, T>`. The | ||
| /// Wraps an `&mut [T: Bits]` in an `&mut BitSlice<E: Endian, T>`. The | ||
| /// endianness must be specified by the call site. The element type cannot | ||
@@ -826,3 +832,3 @@ /// be changed. | ||
| /// Print the `BitSlice` for debugging. | ||
| /// Prints the `BitSlice` for debugging. | ||
| /// | ||
@@ -839,3 +845,3 @@ /// The output is of the form `BitSlice<E, T> [ELT, *]` where `<E, T>` is the | ||
| where E: Endian, T: Bits { | ||
| /// Render the `BitSlice` type header and contents for debug. | ||
| /// Renders the `BitSlice` type header and contents for debug. | ||
| /// | ||
@@ -893,4 +899,6 @@ /// # Examples | ||
| /// Writes the contents of the `BitSlice`, in semantic bit order, into a hasher. | ||
| impl<E, T> Hash for BitSlice<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Writes each bit of the `BitSlice`, as a full `bool`, into the hasher. | ||
| fn hash<H>(&self, hasher: &mut H) | ||
@@ -904,3 +912,3 @@ where H: Hasher { | ||
| /// Produce a read-only iterator over all the bits in the `BitSlice`. | ||
| /// Produces a read-only iterator over all the bits in the `BitSlice`. | ||
| /// | ||
@@ -915,3 +923,3 @@ /// This iterator follows the ordering in the `BitSlice` type, and implements | ||
| /// Iterate over the slice. | ||
| /// Iterates over the slice. | ||
| /// | ||
@@ -935,6 +943,7 @@ /// # Examples | ||
| /// Perform unsigned addition in place on a `BitSlice`. | ||
| /// Performs unsigned addition in place on a `BitSlice`. | ||
| /// | ||
| /// If the addend `BitSliec` is shorter than `self`, the addend is zero-extended | ||
| /// to the right. If the addend is longer, the excess front length is unused. | ||
| /// If the addend `BitSlice` is shorter than `self`, the addend is zero-extended | ||
| /// at the left (so that its final bit matches with `self`’s final bit). If the | ||
| /// addend is longer, the excess front length is unused. | ||
| /// | ||
@@ -948,7 +957,7 @@ /// Addition proceeds from the right ends of each slice towards the left. | ||
| /// | ||
| /// Subtraction can be implemented by negating the intended subtrahend yourself, | ||
| /// then using addition, or by using `BitVec`s instead of `BitSlice`s. | ||
| /// Subtraction can be implemented by negating the intended subtrahend yourself | ||
| /// and then using addition, or by using `BitVec`s instead of `BitSlice`s. | ||
| impl<'a, E, T> AddAssign<&'a BitSlice<E, T>> for BitSlice<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Perform unsigned wrapping addition in place. | ||
| /// Performs unsigned wrapping addition in place. | ||
| /// | ||
@@ -976,7 +985,7 @@ /// # Examples | ||
| use std::iter::repeat; | ||
| // zero-extend the addend if it's shorter than self | ||
| // zero-extend the addend if it’s shorter than self | ||
| let mut addend_iter = addend.into_iter().rev().chain(repeat(false)); | ||
| let mut c = false; | ||
| for place in (0 .. self.len()).rev() { | ||
| // See BitVec::AddAssign | ||
| // See `BitVec::AddAssign` | ||
| static JUMP: [u8; 8] = [0, 2, 2, 1, 2, 1, 1, 3]; | ||
@@ -994,8 +1003,8 @@ let a = self.get(place); | ||
| /// Perform the Boolean AND operation against another bitstream and writes the | ||
| /// result into `self`. If the other bitstream ends before `self` does, it is | ||
| /// extended with zero, clearing all remaining bits in `self`. | ||
| /// Performs the Boolean `AND` operation against another bitstream and writes | ||
| /// the result into `self`. If the other bitstream ends before `self` does, it | ||
| /// is extended with zero, clearing all remaining bits in `self`. | ||
| impl<E, T, I> BitAndAssign<I> for BitSlice<E, T> | ||
| where E: Endian, T: Bits, I: IntoIterator<Item=bool> { | ||
| /// AND a bitstream inta a slice. | ||
| /// `AND`s a bitstream into a slice. | ||
| /// | ||
@@ -1020,3 +1029,3 @@ /// # Examples | ||
| /// Perform the Boolean OR operation against another bitstream and writes the | ||
| /// Performs the Boolean `OR` operation against another bitstream and writes the | ||
| /// result into `self`. If the other bitstream ends before `self` does, it is | ||
@@ -1026,3 +1035,3 @@ /// extended with zero, leaving all remaining bits in `self` as they were. | ||
| where E: Endian, T: Bits, I: IntoIterator<Item=bool> { | ||
| /// OR a bitstream into a slice. | ||
| /// `OR`s a bitstream into a slice. | ||
| /// | ||
@@ -1046,8 +1055,8 @@ /// # Examples | ||
| /// Perform the Boolean XOR operation against another bitstream and writes the | ||
| /// result into `self`. If the other bitstream ends before `self` does, it is | ||
| /// extended with zero, leaving all remaining bits in `self` as they were. | ||
| /// Performs the Boolean `XOR` operation against another bitstream and writes | ||
| /// the result into `self`. If the other bitstream ends before `self` does, it | ||
| /// is extended with zero, leaving all remaining bits in `self` as they were. | ||
| impl<E, T, I> BitXorAssign<I> for BitSlice<E, T> | ||
| where E: Endian, T: Bits, I: IntoIterator<Item=bool> { | ||
| /// XOR a bitstream into a slice. | ||
| /// `XOR`s a bitstream into a slice. | ||
| /// | ||
@@ -1072,4 +1081,4 @@ /// # Examples | ||
| /// Index a single bit by semantic count. The index must be less than the length | ||
| /// of the `BitSlice`. | ||
| /// Indexes a single bit by semantic count. The index must be less than the | ||
| /// length of the `BitSlice`. | ||
| impl<'a, E, T> Index<usize> for &'a BitSlice<E, T> | ||
@@ -1079,3 +1088,3 @@ where E: Endian, T: 'a + Bits { | ||
| /// Look up a single bit by semantic count. | ||
| /// Looks up a single bit by semantic count. | ||
| /// | ||
@@ -1099,5 +1108,5 @@ /// # Examples | ||
| /// Index a single bit by element and bit index within the element. The element | ||
| /// index must be less than the length of the underlying store, and the bit | ||
| /// index must be less than the width of the underlying element. | ||
| /// Indexes a single bit by element and bit index within the element. The | ||
| /// element index must be less than the length of the underlying store, and the | ||
| /// bit index must be less than the width of the underlying element. | ||
| /// | ||
@@ -1109,3 +1118,3 @@ /// This index is not recommended for public use. | ||
| /// Look up a single bit by storage element and bit indices. The bit index | ||
| /// Looks up a single bit by storage element and bit indices. The bit index | ||
| /// is still a semantic count, not an absolute index into the element. | ||
@@ -1131,7 +1140,7 @@ /// | ||
| /// Perform fixed-width 2's-complement negation of a `BitSlice`. | ||
| /// Performs fixed-width 2’s-complement negation of a `BitSlice`. | ||
| /// | ||
| /// Unlike the `!` operator (`Not` trait), the unary `-` operator treats the | ||
| /// `BitSlice` as if it represents a signed 2's-complement integer of fixed | ||
| /// width. The negation of a number in 2's complement is defined as its | ||
| /// `BitSlice` as if it represents a signed 2’s-complement integer of fixed | ||
| /// width. The negation of a number in 2’s complement is defined as its | ||
| /// inversion (using `!`) plus one, and on fixed-width numbers has the following | ||
@@ -1156,3 +1165,3 @@ /// discontinuities: | ||
| /// Perform 2's-complement fixed-width negation. | ||
| /// Perform 2’s-complement fixed-width negation. | ||
| /// | ||
@@ -1201,7 +1210,8 @@ /// # Examples | ||
| } | ||
| Not::not(&mut *self); | ||
| let _ = Not::not(&mut *self); | ||
| // Fill an element with all 1 bits | ||
| let elt: [T; 1] = [!T::default()]; | ||
| if self.any() { | ||
| // Turn a slice reference [T; 1] into a bit-slice reference [u1; 1] | ||
| // Turn a slice reference `[T; 1]` into a bit-slice reference | ||
| // `[u1; 1]` | ||
| let addend: &BitSlice<E, T> = { | ||
@@ -1217,3 +1227,3 @@ unsafe { mem::transmute::<&[T], &BitSlice<E, T>>(&elt) } | ||
| /// Flip all bits in the slice, in place. | ||
| /// Flips all bits in the slice, in place. | ||
| /// | ||
@@ -1229,3 +1239,3 @@ /// This invokes the `!` operator on each element of the borrowed storage, and | ||
| /// Invert all bits in the slice. | ||
| /// Inverts all bits in the slice. | ||
| /// | ||
@@ -1254,3 +1264,3 @@ /// # Examples | ||
| /// Shift all bits in the array to the left — DOWN AND TOWARDS THE FRONT. | ||
| /// Shifts all bits in the array to the left — **DOWN AND TOWARDS THE FRONT**. | ||
| /// | ||
@@ -1286,3 +1296,3 @@ /// On primitives, the left-shift operator `<<` moves bits away from the origin | ||
| where E: Endian, T: Bits { | ||
| /// Shift a slice left, in place. | ||
| /// Shifts a slice left, in place. | ||
| /// | ||
@@ -1323,5 +1333,4 @@ /// # Examples | ||
| // [ 0 1 2 3 4 5 6 7 8 9 a b c d e f ] | ||
| // | ^---------+---------^ <- before | ||
| // ^-------------------^ ^-------^ <- zero-filled | ||
| // after | ||
| // ^-------before------^ | ||
| // ^-------after-------^ 0 0 0 0 0 | ||
| // Pointer to the front of the slice | ||
@@ -1353,3 +1362,3 @@ let head: *mut T = self.as_mut_ptr(); | ||
| /// Shift all bits in the array to the right — UP AND TOWARDS THE BACK. | ||
| /// Shifts all bits in the array to the right — **UP AND TOWARDS THE BACK**. | ||
| /// | ||
@@ -1385,3 +1394,3 @@ /// On primitives, the right-shift operator `>>` moves bits towards the origin | ||
| where E: Endian, T: Bits { | ||
| /// Shift a slice right, in place. | ||
| /// Shifts a slice right, in place. | ||
| /// | ||
@@ -1421,5 +1430,4 @@ /// # Examples | ||
| // [ 0 1 2 3 4 5 6 7 8 9 a b c d e f ] | ||
| // ^---------+---------^ | <- before | ||
| // ^-------^ ^-------------------^ <- after | ||
| // zero-filled | ||
| // ^-------before------^ | ||
| // 0 0 0 0 0 ^-------after-------^ | ||
| let head: *mut T = self.as_mut_ptr(); | ||
@@ -1443,5 +1451,6 @@ let body: *mut T = &mut self.as_mut()[offset]; | ||
| /// Permit iteration over a `BitSlice` | ||
| /// Permits iteration over a `BitSlice` | ||
| #[doc(hidden)] | ||
| pub struct Iter<'a, E: 'a + Endian, T: 'a + Bits> { | ||
| pub struct Iter<'a, E, T> | ||
| where E: 'a + Endian, T: 'a + Bits { | ||
| inner: &'a BitSlice<E, T>, | ||
@@ -1452,3 +1461,4 @@ head: usize, | ||
| impl<'a, E: 'a + Endian, T: 'a + Bits> Iter<'a, E, T> { | ||
| impl<'a, E, T> Iter<'a, E, T> | ||
| where E: 'a + Endian, T: 'a + Bits { | ||
| fn reset(&mut self) { | ||
@@ -1460,3 +1470,4 @@ self.head = 0; | ||
| impl<'a, E: 'a + Endian, T: 'a + Bits> DoubleEndedIterator for Iter<'a, E, T> { | ||
| impl<'a, E, T> DoubleEndedIterator for Iter<'a, E, T> | ||
| where E: 'a + Endian, T: 'a + Bits { | ||
| fn next_back(&mut self) -> Option<Self::Item> { | ||
@@ -1474,3 +1485,4 @@ if self.tail > self.head { | ||
| impl<'a, E: 'a + Endian, T: 'a + Bits> ExactSizeIterator for Iter<'a, E, T> { | ||
| impl<'a, E, T> ExactSizeIterator for Iter<'a, E, T> | ||
| where E: 'a + Endian, T: 'a + Bits { | ||
| fn len(&self) -> usize { | ||
@@ -1481,3 +1493,4 @@ self.tail - self.head | ||
| impl<'a, E: 'a + Endian, T: 'a + Bits> From<&'a BitSlice<E, T>> for Iter<'a, E, T> { | ||
| impl<'a, E, T> From<&'a BitSlice<E, T>> for Iter<'a, E, T> | ||
| where E: 'a + Endian, T: 'a + Bits { | ||
| fn from(src: &'a BitSlice<E, T>) -> Self { | ||
@@ -1493,3 +1506,4 @@ let len = src.len(); | ||
| impl<'a, E: 'a + Endian, T: 'a + Bits> Iterator for Iter<'a, E, T> { | ||
| impl<'a, E, T> Iterator for Iter<'a, E, T> | ||
| where E: 'a + Endian, T: 'a + Bits { | ||
| type Item = bool; | ||
@@ -1543,3 +1557,3 @@ | ||
| /// This example intentionally overshoots the iterator bounds, which causes | ||
| /// a reset to the initiol state. It then demonstrates that `nth` is | ||
| /// a reset to the initial state. It then demonstrates that `nth` is | ||
| /// stateful, and is not an absolute index, by seeking ahead by two (to the | ||
@@ -1559,3 +1573,3 @@ /// third zero bit) and then taking the bit immediately after it, which is | ||
| fn nth(&mut self, n: usize) -> Option<bool> { | ||
| self.head += n; | ||
| self.head = self.head.saturating_add(n); | ||
| self.next() | ||
@@ -1562,0 +1576,0 @@ } |
+280
-211
@@ -1,2 +0,11 @@ | ||
| use super::{ | ||
| /*! `BitVec` structure | ||
| This module holds the main working type of the library. Clients can use | ||
| `BitSlice` directly, but `BitVec` is much more useful for most work. | ||
| The `BitSlice` module discusses the design decisions for the separation between | ||
| slice and vector types. | ||
| !*/ | ||
| use crate::{ | ||
| BitSlice, | ||
@@ -10,63 +19,65 @@ Bits, | ||
| }; | ||
| use std::borrow::{ | ||
| Borrow, | ||
| BorrowMut, | ||
| use std::{ | ||
| borrow::{ | ||
| Borrow, | ||
| BorrowMut, | ||
| }, | ||
| clone::Clone, | ||
| cmp::{ | ||
| Eq, | ||
| Ord, | ||
| Ordering, | ||
| PartialEq, | ||
| PartialOrd, | ||
| }, | ||
| convert::{ | ||
| AsMut, | ||
| AsRef, | ||
| From, | ||
| }, | ||
| default::Default, | ||
| fmt::{ | ||
| self, | ||
| Debug, | ||
| Display, | ||
| Formatter, | ||
| }, | ||
| hash::{ | ||
| Hash, | ||
| Hasher, | ||
| }, | ||
| iter::{ | ||
| DoubleEndedIterator, | ||
| ExactSizeIterator, | ||
| Extend, | ||
| FromIterator, | ||
| Iterator, | ||
| IntoIterator, | ||
| }, | ||
| marker::PhantomData, | ||
| mem, | ||
| ops::{ | ||
| Add, | ||
| AddAssign, | ||
| BitAnd, | ||
| BitAndAssign, | ||
| BitOr, | ||
| BitOrAssign, | ||
| BitXor, | ||
| BitXorAssign, | ||
| Deref, | ||
| DerefMut, | ||
| Drop, | ||
| Index, | ||
| Neg, | ||
| Not, | ||
| Shl, | ||
| ShlAssign, | ||
| Shr, | ||
| ShrAssign, | ||
| Sub, | ||
| SubAssign, | ||
| }, | ||
| ptr, | ||
| }; | ||
| use std::clone::Clone; | ||
| use std::cmp::{ | ||
| Eq, | ||
| Ord, | ||
| Ordering, | ||
| PartialEq, | ||
| PartialOrd, | ||
| }; | ||
| use std::convert::{ | ||
| AsMut, | ||
| AsRef, | ||
| From, | ||
| }; | ||
| use std::default::Default; | ||
| use std::fmt::{ | ||
| self, | ||
| Debug, | ||
| Display, | ||
| Formatter, | ||
| }; | ||
| use std::hash::{ | ||
| Hash, | ||
| Hasher, | ||
| }; | ||
| use std::iter::{ | ||
| DoubleEndedIterator, | ||
| ExactSizeIterator, | ||
| Extend, | ||
| FromIterator, | ||
| Iterator, | ||
| IntoIterator, | ||
| }; | ||
| use std::marker::PhantomData; | ||
| use std::mem; | ||
| use std::ops::{ | ||
| Add, | ||
| AddAssign, | ||
| BitAnd, | ||
| BitAndAssign, | ||
| BitOr, | ||
| BitOrAssign, | ||
| BitXor, | ||
| BitXorAssign, | ||
| Deref, | ||
| DerefMut, | ||
| Drop, | ||
| Index, | ||
| Neg, | ||
| Not, | ||
| Shl, | ||
| ShlAssign, | ||
| Shr, | ||
| ShrAssign, | ||
| Sub, | ||
| SubAssign, | ||
| }; | ||
| use std::ptr; | ||
@@ -78,8 +89,8 @@ /** A compact `Vec` of bits, whose cursor and storage type can be customized. | ||
| **IMPORTANT NOTE:** It is **wildly** unsafe to use `mem::transmute` between | ||
| `Vec<T>` and `BitVec<_, T>`, because `BitVec` achieves its size by using the | ||
| length field of the underlying `Vec` to count bits, rather than elements. This | ||
| means that it has a fixed maximum bit width regardless of element type, and the | ||
| length field will always be horrifically wrong to be treated as a `Vec`. Safe | ||
| methods exist to move between `Vec` and `BitVec` – USE THEM. | ||
| **IMPORTANT NOTE:** It is **horrifically** unsafe to use `mem::transmute` | ||
| between `Vec<T>` and `BitVec<_, T>`, because `BitVec` achieves its size by using | ||
| the length field of the underlying `Vec` to count bits, rather than elements. | ||
| This means that it has a fixed maximum bit width regardless of element type, and | ||
| the length field will always be horrifically wrong to be treated as a `Vec`. | ||
| Safe methods exist to move between `Vec` and `BitVec` – **USE THEM**. | ||
@@ -99,6 +110,7 @@ `BitVec` takes two type parameters. | ||
| **/ | ||
| #[cfg_attr(nightly, repr(transparent))] | ||
| pub struct BitVec<E = BigEndian, T = u8> | ||
| where E: Endian, T: Bits { | ||
| _endian: PhantomData<E>, | ||
| inner: Vec<T>, | ||
| _endian: PhantomData<E>, | ||
| } | ||
@@ -108,3 +120,3 @@ | ||
| where E: Endian, T: Bits { | ||
| /// Construct a new, empty, `BitVec<E, T>`. | ||
| /// Constructs a new, empty, `BitVec<E, T>`. | ||
| /// | ||
@@ -128,3 +140,3 @@ /// The vector will not allocate until bits are pushed onto it. | ||
| /// Construct a new, empty `BitVec<T>` with the specified capacity. | ||
| /// Constructs a new, empty `BitVec<T>` with the specified capacity. | ||
| /// | ||
@@ -151,3 +163,3 @@ /// The vector will be able to hold exactly `capacity` elements without | ||
| /// Return the number of bits the vector can hold without reallocating. | ||
| /// Returns the number of bits the vector can hold without reallocating. | ||
| /// | ||
@@ -167,3 +179,3 @@ /// # Examples | ||
| /// Append a bit to the collection. | ||
| /// Appends a bit to the collection. | ||
| /// | ||
@@ -198,3 +210,3 @@ /// # Examples | ||
| /// Remove the last bit from the collection. | ||
| /// Removes the last bit from the collection. | ||
| /// | ||
@@ -230,3 +242,3 @@ /// Returns `None` if the collection is empty. | ||
| /// Empty out the `BitVec`, resetting it to length zero. | ||
| /// Empties out the `BitVec`, resetting it to length zero. | ||
| /// | ||
@@ -251,6 +263,6 @@ /// This does not affect the memory store! It will not zero the raw memory | ||
| pub fn clear(&mut self) { | ||
| self.do_with_vec(|v| v.clear()); | ||
| self.do_with_vec(Vec::<T>::clear); | ||
| } | ||
| /// Reserve capacity for additional bits. | ||
| /// Reserves capacity for additional bits. | ||
| /// | ||
@@ -275,3 +287,3 @@ /// # Examples | ||
| /// Shrink the capacity to fit at least as much as is needed, but with as | ||
| /// Shrinks the capacity to fit at least as much as is needed, but with as | ||
| /// little or as much excess as the allocator chooses. | ||
@@ -282,6 +294,6 @@ /// | ||
| pub fn shrink_to_fit(&mut self) { | ||
| self.do_with_vec(|v| v.shrink_to_fit()); | ||
| self.do_with_vec(Vec::<T>::shrink_to_fit); | ||
| } | ||
| /// Shrink the `BitVec` to the given size, dropping all excess storage. | ||
| /// Shrinks the `BitVec` to the given size, dropping all excess storage. | ||
| /// | ||
@@ -309,3 +321,3 @@ /// This does not affect the memory store! It will not zero the raw memory | ||
| /// Convert the `BitVec` into a boxed slice of storage elements. This drops | ||
| /// Converts the `BitVec` into a boxed slice of storage elements. This drops | ||
| /// all `BitVec` management semantics, including partial fill status of the | ||
@@ -336,4 +348,32 @@ /// trailing element or endianness, and gives ownership the raw storage. | ||
| /// Set the bit count to a new value. | ||
| /// Sets the backing storage to the provided element. | ||
| /// | ||
| /// This unconditionally sets each element in the backing storage to the | ||
| /// provided value, without altering the `BitVec` length or capacity. It | ||
| /// operates an the underlying `Vec` directly, and will ignore any partial | ||
| /// bounds on the tail. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ```rust | ||
| /// use bitvec::*; | ||
| /// let mut bv = bitvec![0; 10]; | ||
| /// assert_eq!(bv.as_ref(), &[0, 0]); | ||
| /// bv.set_store(0xA5); | ||
| /// assert_eq!(bv.as_ref(), &[0xA5, 0xA5]); | ||
| /// ``` | ||
| pub fn set_store(&mut self, element: T) { | ||
| self.do_with_vec(|v| { | ||
| let len = v.len(); | ||
| let cap = v.capacity(); | ||
| unsafe { v.set_len(cap); } | ||
| for elt in v.iter_mut() { | ||
| *elt = element; | ||
| } | ||
| unsafe { v.set_len(len); } | ||
| }); | ||
| } | ||
| /// Sets the bit count to a new value. | ||
| /// | ||
| /// This utility function unconditionally sets the bottom `T::BITS` bits of | ||
@@ -348,3 +388,3 @@ /// `inner.len` to reflect how many bits of the tail are live. It should | ||
| /// Set the element count to a new value. | ||
| /// Sets the element count to a new value. | ||
| /// | ||
@@ -362,8 +402,13 @@ /// This utility function unconditionally sets the rest of the bits of | ||
| /// Set the length directly. | ||
| pub(crate) unsafe fn set_len(&mut self, len: usize) { | ||
| /// Sets the length directly. | ||
| /// | ||
| /// This is *wildly* unsafe! It directly sets the length of the vector to | ||
| /// whatever you provide. As a sanity check, this absolutely will panic if | ||
| /// the provided length would go past the vector's allocated capacity. | ||
| pub unsafe fn set_len(&mut self, len: usize) { | ||
| assert!(len <= self.capacity(), "Length cannot exceed capacity"); | ||
| self.inner.set_len(len); | ||
| } | ||
| /// Execute some operation with the storage `Vec` in sane condition. | ||
| /// Executes some operation with the storage `Vec` in sane condition. | ||
| /// | ||
@@ -419,3 +464,3 @@ /// The given function receives a sane `Vec<T>`, with the `len` attribute | ||
| /// Execute some operation with the tail storage element. | ||
| /// Executes some operation with the tail storage element. | ||
| /// | ||
@@ -446,3 +491,3 @@ /// If the bit cursor is at zero when this is called, then the current tail | ||
| /// Push an element onto the end of the underlying store. This may or may | ||
| /// Pushes an element onto the end of the underlying store. This may or may | ||
| /// not call the allocator. After the element ensured to be allocated, the | ||
@@ -458,3 +503,3 @@ /// old length is restored. | ||
| /// Format the debug header for the type. | ||
| /// Formats the debug header for the type. | ||
| /// | ||
@@ -467,6 +512,6 @@ /// The body format is provided by `BitSlice`. | ||
| /// Signify that `BitSlice` is the borrowed form of `BitVec`. | ||
| /// Signifies that `BitSlice` is the borrowed form of `BitVec`. | ||
| impl<E, T> Borrow<BitSlice<E, T>> for BitVec<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Borrow the `BitVec` as a `BitSlice`. | ||
| /// Borrows the `BitVec` as a `BitSlice`. | ||
| /// | ||
@@ -487,6 +532,6 @@ /// # Examples | ||
| /// Signify that `BitSlice` is the borrowed form of `BitVec`. | ||
| /// Signifies that `BitSlice` is the borrowed form of `BitVec`. | ||
| impl<E, T> BorrowMut<BitSlice<E, T>> for BitVec<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Mutably borow the `BitVec` as a `BitSlice`. | ||
| /// Mutably borrows the `BitVec` as a `BitSlice`. | ||
| /// | ||
@@ -541,3 +586,3 @@ /// # Examples | ||
| /// Test if two `BitVec`s are semantically — not bitwise — equal. | ||
| /// Tests if two `BitVec`s are semantically — not bitwise — equal. | ||
| /// | ||
@@ -550,3 +595,3 @@ /// It is valid to compare two vectors of different endianness or element types. | ||
| where A: Endian, B: Bits, C: Endian, D: Bits { | ||
| /// Perform a comparison by `==`. | ||
| /// Performs a comparison by `==`. | ||
| /// | ||
@@ -561,2 +606,14 @@ /// # Examples | ||
| /// ``` | ||
| /// | ||
| /// This example uses the same types to prove that raw, bitwise, values are | ||
| /// not used for equality comparison. | ||
| /// | ||
| /// ```rust | ||
| /// use bitvec::*; | ||
| /// let l: BitVec<BigEndian, u8> = bitvec![BigEndian, u8; 0, 1, 0, 1]; | ||
| /// let r: BitVec<LittleEndian, u8> = bitvec![LittleEndian, u8; 0, 1, 0, 1]; | ||
| /// | ||
| /// assert_eq!(l, r); | ||
| /// assert_ne!(l.as_ref(), r.as_ref()); | ||
| /// ``` | ||
| fn eq(&self, rhs: &BitVec<C, D>) -> bool { | ||
@@ -567,3 +624,3 @@ BitSlice::eq(&self, &rhs) | ||
| /// Compare two `BitVec`s by semantic — not bitwise — ordering. | ||
| /// Compares two `BitVec`s by semantic — not bitwise — ordering. | ||
| /// | ||
@@ -578,3 +635,3 @@ /// The comparison sorts by testing each index for one vector to have a set bit | ||
| where A: Endian, B: Bits, C: Endian, D: Bits { | ||
| /// Perform a comparison by `<` or `>`. | ||
| /// Performs a comparison by `<` or `>`. | ||
| /// | ||
@@ -597,7 +654,7 @@ /// # Examples | ||
| /// Give write access to all live elements in the underlying storage, including | ||
| /// Gives write access to all live elements in the underlying storage, including | ||
| /// the partially-filled tail. | ||
| impl<E, T> AsMut<[T]> for BitVec<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Access the underlying store. | ||
| /// Accesses the underlying store. | ||
| /// | ||
@@ -610,3 +667,3 @@ /// # Examples | ||
| /// for elt in bv.as_mut() { | ||
| /// *elt += 2; | ||
| /// *elt += 2; | ||
| /// } | ||
@@ -620,7 +677,7 @@ /// assert_eq!(&[2, 0b1000_0010], bv.as_ref()); | ||
| /// Give read access to all live elements in the underlying storage, including | ||
| /// Gives read access to all live elements in the underlying storage, including | ||
| /// the partially-filled tail. | ||
| impl<E, T> AsRef<[T]> for BitVec<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Access the underlying store. | ||
| /// Accesses the underlying store. | ||
| /// | ||
@@ -639,3 +696,3 @@ /// # Examples | ||
| /// Clone a `BitSlice` into an owned `BitVec`. | ||
| /// Copies a `BitSlice` into an owned `BitVec`. | ||
| /// | ||
@@ -651,3 +708,3 @@ /// The idiomatic `BitSlice` to `BitVec` conversion is `BitSlice::to_owned`, but | ||
| /// Build a `BitVec` out of a slice of `bool`. | ||
| /// Builds a `BitVec` out of a slice of `bool`. | ||
| /// | ||
@@ -667,3 +724,3 @@ /// This is primarily for the `bitvec!` macro; it is not recommended for general | ||
| /// Build a `BitVec` out of a borrowed slice of elements. | ||
| /// Builds a `BitVec` out of a borrowed slice of elements. | ||
| /// | ||
@@ -678,3 +735,3 @@ /// This copies the memory as-is from the source buffer into the new `BitVec`. | ||
| where E: Endian, T: 'a + Bits { | ||
| /// Build a `BitVec<E: Endian, T: Bits>` from a borrowed `&[T]`. | ||
| /// Builds a `BitVec<E: Endian, T: Bits>` from a borrowed `&[T]`. | ||
| /// | ||
@@ -694,3 +751,3 @@ /// # Examples | ||
| /// Build a `BitVec` out of an owned slice of elements. | ||
| /// Builds a `BitVec` out of an owned slice of elements. | ||
| /// | ||
@@ -702,3 +759,4 @@ /// This moves the memory as-is from the source buffer into the new `BitVec`. | ||
| where E: Endian, T: Bits { | ||
| /// Consume a `Box<[T: Bits]>` and creates a `BitVec<E: Endian, T>` from it. | ||
| /// Consumes a `Box<[T: Bits]>` and creates a `BitVec<E: Endian, T>` from | ||
| /// it. | ||
| /// | ||
@@ -719,3 +777,3 @@ /// # Examples | ||
| /// Build a `BitVec` out of a `Vec` of elements. | ||
| /// Builds a `BitVec` out of a `Vec` of elements. | ||
| /// | ||
@@ -727,3 +785,3 @@ /// This moves the memory as-is from the source buffer into the new `BitVec`. | ||
| where E: Endian, T: Bits { | ||
| /// Consume a `Vec<T: Bits>` and creates a `BitVec<E: Endian, T>` from it. | ||
| /// Consumes a `Vec<T: Bits>` and creates a `BitVec<E: Endian, T>` from it. | ||
| /// | ||
@@ -753,3 +811,3 @@ /// # Examples | ||
| /// Change cursors on a `BitVec` without mutating the underlying data. | ||
| /// Changes cursors on a `BitVec` without mutating the underlying data. | ||
| /// | ||
@@ -783,3 +841,3 @@ /// I don't know why this would be useful at the time of writing, as the `From` | ||
| /// Change cursors on a `BitVec` without mutating the underlying data. | ||
| /// Changes cursors on a `BitVec` without mutating the underlying data. | ||
| /// | ||
@@ -815,3 +873,3 @@ /// I don't know why this would be useful at the time of writing, as the `From` | ||
| /// Print the `BitVec` for debugging. | ||
| /// Prints the `BitVec` for debugging. | ||
| /// | ||
@@ -828,3 +886,3 @@ /// The output is of the form `BitVec<E, T> [ELT, *]`, where `<E, T>` is the | ||
| where E: Endian, T: Bits { | ||
| /// Render the `BitVec` type header and contents for debug. | ||
| /// Renders the `BitVec` type header and contents for debug. | ||
| /// | ||
@@ -847,3 +905,3 @@ /// # Examples | ||
| fmt.write_str(" [")?; | ||
| if alt { writeln!(fmt)?; } | ||
| if alt { writeln!(fmt)?; fmt.write_str(" ")?; } | ||
| self.fmt_body(fmt, true)?; | ||
@@ -855,3 +913,3 @@ if alt { writeln!(fmt)?; } | ||
| /// Print the `BitVec` for displaying. | ||
| /// Prints the `BitVec` for displaying. | ||
| /// | ||
@@ -868,3 +926,3 @@ /// This prints each element in turn, formatted in binary in semantic order (so | ||
| where E: Endian, T: Bits { | ||
| /// Render the `BitVec` contents for display. | ||
| /// Renders the `BitVec` contents for display. | ||
| /// | ||
@@ -883,4 +941,6 @@ /// # Examples | ||
| /// Writes the contents of the `BitVec`, in semantic bit order, into a hasher. | ||
| impl<E, T> Hash for BitVec<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Writes each bit of the `BitVec`, as a full `bool`, into the hasher. | ||
| fn hash<H>(&self, hasher: &mut H) | ||
@@ -892,3 +952,3 @@ where H: Hasher { | ||
| /// Extend a `BitVec` with the contents of another bitstream. | ||
| /// Extends a `BitVec` with the contents of another bitstream. | ||
| /// | ||
@@ -900,3 +960,3 @@ /// At present, this just calls `.push()` in a loop. When specialization becomes | ||
| where E: Endian, T: Bits { | ||
| /// Extend a `BitVec` from another bitstream. | ||
| /// Extends a `BitVec` from another bitstream. | ||
| /// | ||
@@ -925,7 +985,7 @@ /// # Examples | ||
| /// Permit the construction of a `BitVec` by using `.collect()` on an iterator | ||
| /// Permits the construction of a `BitVec` by using `.collect()` on an iterator | ||
| /// of `bool`. | ||
| impl<E, T> FromIterator<bool> for BitVec<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Collect an iterator of `bool` into a vector. | ||
| /// Collects an iterator of `bool` into a vector. | ||
| /// | ||
@@ -954,3 +1014,3 @@ /// # Examples | ||
| /// Produce an iterator over all the bits in the vector. | ||
| /// Produces an iterator over all the bits in the vector. | ||
| /// | ||
@@ -966,3 +1026,3 @@ /// This iterator follows the ordering in the vector type, and implements | ||
| /// Iterate over the vector. | ||
| /// Iterates over the vector. | ||
| /// | ||
@@ -985,3 +1045,3 @@ /// # Examples | ||
| /// Add two `BitVec`s together, zero-extending the shorter. | ||
| /// Adds two `BitVec`s together, zero-extending the shorter. | ||
| /// | ||
@@ -1005,3 +1065,3 @@ /// `BitVec` addition works just like adding numbers longhand on paper. The | ||
| /// Add two `BitVec`s. | ||
| /// Adds two `BitVec`s. | ||
| /// | ||
@@ -1034,3 +1094,3 @@ /// # Examples | ||
| /// Add another `BitVec` into `self`, zero-extending the shorter. | ||
| /// Adds another `BitVec` into `self`, zero-extending the shorter. | ||
| /// | ||
@@ -1052,3 +1112,3 @@ /// `BitVec` addition works just like adding numbers longhand on paper. The | ||
| where E: Endian, T: Bits { | ||
| /// Add another `BitVec` into `self`. | ||
| /// Adds another `BitVec` into `self`. | ||
| /// | ||
@@ -1089,22 +1149,15 @@ /// # Examples | ||
| for (a, b) in self.iter().rev().zip(addend.into_iter().rev().chain(repeat(false))) { | ||
| // Addition is a finite state machine that can be precomputed into a single | ||
| // jump table rather than requiring more complex branching. | ||
| // The table is indexed as (carry, a, b) and returns (bit, carry). | ||
| // Addition is a finite state machine that can be precomputed into | ||
| // a single jump table rather than requiring more complex | ||
| // branching. The table is indexed as (carry, a, b) and returns | ||
| // (bit, carry). | ||
| static JUMP: [u8; 8] = [ | ||
| // 0 + 0 + 0 = 0, 0 | ||
| 0, | ||
| // 0 + 1 + 0 = 1, 0 | ||
| 2, | ||
| // 1 + 0 + 0 = 1, 0 | ||
| 2, | ||
| // 1 + 1 + 1 = 0, 1 | ||
| 1, | ||
| // 0 + 0 + 1 = 1, 0 | ||
| 2, | ||
| // 0 + 1 + 0 = 0, 1 | ||
| 1, | ||
| // 1 + 0 + 0 = 0, 1 | ||
| 1, | ||
| // 1 + 1 + 1 = 1, 1 | ||
| 3, | ||
| 0, // 0 + 0 + 0 => (0, 0) | ||
| 2, // 0 + 1 + 0 => (1, 0) | ||
| 2, // 1 + 0 + 0 => (1, 0) | ||
| 1, // 1 + 1 + 1 => (0, 1) | ||
| 2, // 0 + 0 + 1 => (1, 0) | ||
| 1, // 0 + 1 + 0 => (0, 1) | ||
| 1, // 1 + 0 + 0 => (0, 1) | ||
| 3, // 1 + 1 + 1 => (1, 1) | ||
| ]; | ||
@@ -1133,3 +1186,3 @@ let idx = ((c as u8) << 2) | ((a as u8) << 1) | (b as u8); | ||
| /// Perform the Boolean AND operation between each element of a `BitVec` and | ||
| /// Performs the Boolean `AND` operation between each element of a `BitVec` and | ||
| /// anything that can provide a stream of `bool` values (such as another | ||
@@ -1143,3 +1196,3 @@ /// `BitVec`, or any `bool` generator of your choice). The `BitVec` emitted will | ||
| /// AND a vector and a bitstream, producing a new vector. | ||
| /// `AND`s a vector and a bitstream, producing a new vector. | ||
| /// | ||
@@ -1161,8 +1214,8 @@ /// # Examples | ||
| /// Perform the Boolean AND operation in place on a `BitVec`, using a stream of | ||
| /// `bool` values as the other bit for each operation. If the other stream is | ||
| /// Performs the Boolean `AND` operation in place on a `BitVec`, using a stream | ||
| /// of `bool` values as the other bit for each operation. If the other stream is | ||
| /// shorter than `self`, `self` will be truncated when the other stream expires. | ||
| impl<E, T, I> BitAndAssign<I> for BitVec<E, T> | ||
| where E: Endian, T: Bits, I: IntoIterator<Item=bool> { | ||
| /// AND another bitstream into a vector. | ||
| /// `AND`s another bitstream into a vector. | ||
| /// | ||
@@ -1188,3 +1241,3 @@ /// # Examples | ||
| /// Perform the Boolean OR operation between each element of a `BitVec` and | ||
| /// Performs the Boolean `OR` operation between each element of a `BitVec` and | ||
| /// anything that can provide a stream of `bool` values (such as another | ||
@@ -1198,3 +1251,3 @@ /// `BitVec`, or any `bool` generator of your choice). The `BitVec` emitted will | ||
| /// OR a vector and a bitstream, producing a new vector. | ||
| /// `OR`s a vector and a bitstream, producing a new vector. | ||
| /// | ||
@@ -1205,4 +1258,4 @@ /// # Examples | ||
| /// use bitvec::*; | ||
| /// let lhs = bitvec![BigEndian, u8; 0, 1, 0, 1]; | ||
| /// let rhs = bitvec![BigEndian, u8; 0, 0, 1, 1]; | ||
| /// let lhs = bitvec![0, 1, 0, 1]; | ||
| /// let rhs = bitvec![0, 0, 1, 1]; | ||
| /// let or = lhs | rhs; | ||
@@ -1217,8 +1270,8 @@ /// assert_eq!("0111", &format!("{}", or)); | ||
| /// Perform the Boolean OR operation in place on a `BitVec`, using a stream of | ||
| /// `bool` values as the other bit for each operation. If the other stream is | ||
| /// Performs the Boolean `OR` operation in place on a `BitVec`, using a stream | ||
| /// of `bool` values as the other bit for each operation. If the other stream is | ||
| /// shorter than `self`, `self` will be truncated when the other stream expires. | ||
| impl<E, T, I> BitOrAssign<I> for BitVec<E, T> | ||
| where E: Endian, T: Bits, I: IntoIterator<Item=bool> { | ||
| /// OR another bitstream into a vector. | ||
| /// `OR`s another bitstream into a vector. | ||
| /// | ||
@@ -1229,4 +1282,4 @@ /// # Examples | ||
| /// use bitvec::*; | ||
| /// let mut src = bitvec![BigEndian, u8; 0, 1, 0, 1]; | ||
| /// src |= bitvec![BigEndian, u8; 0, 0, 1, 1]; | ||
| /// let mut src = bitvec![0, 1, 0, 1]; | ||
| /// src |= bitvec![0, 0, 1, 1]; | ||
| /// assert_eq!("0111", &format!("{}", src)); | ||
@@ -1245,3 +1298,3 @@ /// ``` | ||
| /// Perform the Boolean XOR operation between each element of a `BitVec` and | ||
| /// Performs the Boolean `XOR` operation between each element of a `BitVec` and | ||
| /// anything that can provide a stream of `bool` values (such as another | ||
@@ -1255,3 +1308,3 @@ /// `BitVec`, or any `bool` generator of your choice). The `BitVec` emitted will | ||
| /// XOR a vector and a bitstream, producing a new vector. | ||
| /// `XOR`s a vector and a bitstream, producing a new vector. | ||
| /// | ||
@@ -1262,4 +1315,4 @@ /// # Examples | ||
| /// use bitvec::*; | ||
| /// let lhs = bitvec![BigEndian, u8; 0, 1, 0, 1]; | ||
| /// let rhs = bitvec![BigEndian, u8; 0, 0, 1, 1]; | ||
| /// let lhs = bitvec![0, 1, 0, 1]; | ||
| /// let rhs = bitvec![0, 0, 1, 1]; | ||
| /// let xor = lhs ^ rhs; | ||
@@ -1274,8 +1327,8 @@ /// assert_eq!("0110", &format!("{}", xor)); | ||
| /// Perform the Boolean XOR operation in place on a `BitVec`, using a stream of | ||
| /// `bool` values as the other bit for each operation. If the other stream is | ||
| /// Performs the Boolean `XOR` operation in place on a `BitVec`, using a stream | ||
| /// of `bool` values as the other bit for each operation. If the other stream is | ||
| /// shorter than `self`, `self` will be truncated when the other stream expires. | ||
| impl<E, T, I> BitXorAssign<I> for BitVec<E, T> | ||
| where E: Endian, T: Bits, I: IntoIterator<Item=bool> { | ||
| /// XOR another bitstream into a vector. | ||
| /// `XOR`s another bitstream into a vector. | ||
| /// | ||
@@ -1286,4 +1339,4 @@ /// # Examples | ||
| /// use bitvec::*; | ||
| /// let mut src = bitvec![BigEndian, u8; 0, 1, 0, 1]; | ||
| /// src ^= bitvec![BigEndian, u8; 0, 0, 1, 1]; | ||
| /// let mut src = bitvec![0, 1, 0, 1]; | ||
| /// src ^= bitvec![0, 0, 1, 1]; | ||
| /// assert_eq!("0110", &format!("{}", src)); | ||
@@ -1302,3 +1355,3 @@ /// ``` | ||
| /// Reborrow the `BitVec` as a `BitSlice`. | ||
| /// Reborrows the `BitVec` as a `BitSlice`. | ||
| /// | ||
@@ -1310,3 +1363,3 @@ /// This mimics the separation between `Vec<T>` and `[T]`. | ||
| /// Dereference `&BitVec` down to `&BitSlice`. | ||
| /// Dereferences `&BitVec` down to `&BitSlice`. | ||
| /// | ||
@@ -1328,3 +1381,3 @@ /// # Examples | ||
| /// Reborrow the `BitVec` as a `BitSlice`. | ||
| /// Mutably reborrows the `BitVec` as a `BitSlice`. | ||
| /// | ||
@@ -1334,3 +1387,3 @@ /// This mimics the separation between `Vec<T>` and `[T]`. | ||
| where E: Endian, T: Bits { | ||
| /// Dereference `&mut BitVec` down to `&mut BitSlice`. | ||
| /// Dereferences `&mut BitVec` down to `&mut BitSlice`. | ||
| /// | ||
@@ -1352,5 +1405,7 @@ /// # Examples | ||
| /// Ready the underlying storage for Drop. | ||
| /// Readies the underlying storage for Drop. | ||
| impl<E, T> Drop for BitVec<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Sets the interior `Vec` instance to the format its `Drop` implementation | ||
| /// expects. | ||
| fn drop(&mut self) { | ||
@@ -1369,3 +1424,3 @@ // If the `Vec` is non-empty, set the length to the number of used | ||
| /// Get the bit at a specific index. The index must be less than the length of | ||
| /// Gets the bit at a specific index. The index must be less than the length of | ||
| /// the `BitVec`. | ||
@@ -1376,3 +1431,3 @@ impl<E, T> Index<usize> for BitVec<E, T> | ||
| /// Look up a single bit by semantic count. | ||
| /// Looks up a single bit by semantic count. | ||
| /// | ||
@@ -1385,9 +1440,11 @@ /// # Examples | ||
| /// assert!(!bv[7]); // ---------------------------------^ | | | ||
| /// assert!( bv[8]); //-------------------------------------^ | | ||
| /// assert!( bv[8]); // ------------------------------------^ | | ||
| /// assert!(!bv[9]); // ---------------------------------------^ | ||
| /// ``` | ||
| /// | ||
| /// If the index is greater than or equal to the length, indexing will panic. | ||
| /// If the index is greater than or equal to the length, indexing will | ||
| /// panic. | ||
| /// | ||
| /// The below test will panic when accessing index 1, as only index 0 is valid. | ||
| /// The below test will panic when accessing index 1, as only index 0 is | ||
| /// valid. | ||
| /// | ||
@@ -1406,3 +1463,3 @@ /// ```rust,should_panic | ||
| /// Get the bit in a specific element. The element index must be less than or | ||
| /// Gets the bit in a specific element. The element index must be less than or | ||
| /// equal to the value returned by `elts()`, and the bit index must be less | ||
@@ -1422,4 +1479,4 @@ /// than the width of the storage type. | ||
| /// Index into a `BitVec` using a known element index and a count into that | ||
| /// element. The count must not be converted for endianness outside the | ||
| /// Indexes into a `BitVec` using a known element index and a count into | ||
| /// that element. The count must not be converted for endianness outside the | ||
| /// call. | ||
@@ -1443,5 +1500,5 @@ /// | ||
| /// 2's-complement negation of a `BitVec`. | ||
| /// 2’s-complement negation of a `BitVec`. | ||
| /// | ||
| /// In 2's-complement, negation is defined as bit-inversion followed by adding | ||
| /// In 2’s-complement, negation is defined as bit-inversion followed by adding | ||
| /// one. | ||
@@ -1458,2 +1515,12 @@ /// | ||
| /// Numerically negates a `BitVec` using 2’s-complement arithmetic. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ```rust | ||
| /// use bitvec::*; | ||
| /// let bv = bitvec![0, 1, 1]; | ||
| /// let ne = -bv; | ||
| /// assert_eq!("101", &format!("{}", ne)); | ||
| /// ``` | ||
| fn neg(mut self) -> Self::Output { | ||
@@ -1471,3 +1538,3 @@ // An empty vector does nothing. | ||
| /// Flip all bits in the vector. | ||
| /// Flips all bits in the vector. | ||
| /// | ||
@@ -1479,3 +1546,2 @@ /// This invokes the `!` operator on each element of the borrowed storage, and | ||
| /// rather than a consuming/returning operator. | ||
| /// ``` | ||
| impl<E, T> Not for BitVec<E, T> | ||
@@ -1485,3 +1551,3 @@ where E: Endian, T: Bits { | ||
| /// Invert all bits in the vector. | ||
| /// Inverts all bits in the vector. | ||
| /// | ||
@@ -1495,2 +1561,3 @@ /// # Examples | ||
| /// assert_eq!(!0u32, flip.as_ref()[0]); | ||
| /// ``` | ||
| // Because self does not have to interact with any other `BitVec`, and bits | ||
@@ -1500,3 +1567,4 @@ // beyond `BitVec.len()` are uninitialized and don't matter, this is free | ||
| fn not(mut self) -> Self::Output { | ||
| !&mut *self; | ||
| // ignore the returned reference | ||
| let _ = !(&mut *self); | ||
| self | ||
@@ -1508,3 +1576,3 @@ } | ||
| /// Shift all bits in the vector to the left – DOWN AND TOWARDS THE FRONT. | ||
| /// Shifts all bits in the vector to the left – **DOWN AND TOWARDS THE FRONT**. | ||
| /// | ||
@@ -1541,3 +1609,3 @@ /// On primitives, the left-shift operator `<<` moves bits away from origin and | ||
| /// Shift a `BitVec` to the left, shortening it. | ||
| /// Shifts a `BitVec` to the left, shortening it. | ||
| /// | ||
@@ -1563,3 +1631,3 @@ /// # Examples | ||
| /// Shift all bits in the vector to the left – DOWN AND TOWARDS THE FRONT. | ||
| /// Shifts all bits in the vector to the left – **DOWN AND TOWARDS THE FRONT**. | ||
| /// | ||
@@ -1594,3 +1662,3 @@ /// On primitives, the left-shift operator `<<` moves bits away from origin and | ||
| where E: Endian, T: Bits { | ||
| /// Shift a `BitVec` to the left in place, shortening it. | ||
| /// Shifts a `BitVec` to the left in place, shortening it. | ||
| /// | ||
@@ -1632,3 +1700,3 @@ /// # Examples | ||
| /// Shift all bits in the vector to the right – UP AND TOWARDS THE BACK. | ||
| /// Shifts all bits in the vector to the right – **UP AND TOWARDS THE BACK**. | ||
| /// | ||
@@ -1666,3 +1734,4 @@ /// On primitives, the right-shift operator `>>` moves bits towards the origin | ||
| /// Shift a `BitVec` to the right, lengthening it and filling the front with 0. | ||
| /// Shifts a `BitVec` to the right, lengthening it and filling the front | ||
| /// with 0. | ||
| /// | ||
@@ -1688,3 +1757,3 @@ /// # Examples | ||
| /// Shift all bits in the vector to the right – UP AND TOWARDS THE BACK. | ||
| /// Shifts all bits in the vector to the right – **UP AND TOWARDS THE BACK**. | ||
| /// | ||
@@ -1720,3 +1789,3 @@ /// On primitives, the right-shift operator `>>` moves bits towards the origin | ||
| where E: Endian, T: Bits { | ||
| /// Shift a `BitVec` to the right in place, lengthening it and filling the | ||
| /// Shifts a `BitVec` to the right in place, lengthening it and filling the | ||
| /// front with 0. | ||
@@ -1752,3 +1821,3 @@ /// | ||
| /// Subtract one `BitVec` from another assuming 2's-complement encoding. | ||
| /// Subtracts one `BitVec` from another assuming 2’s-complement encoding. | ||
| /// | ||
@@ -1760,3 +1829,3 @@ /// Subtraction is a more complex operation than addition. The bit-level work is | ||
| /// | ||
| /// Because of the properties of 2's-complement arithmetic, M - S is equivalent | ||
| /// Because of the properties of 2’s-complement arithmetic, M - S is equivalent | ||
| /// to M + (!S + 1). Subtraction therefore bitflips the subtrahend and adds one. | ||
@@ -1771,3 +1840,3 @@ /// This may, in a degenerate case, cause the subtrahend to increase in length. | ||
| /// by the `<BitVec as Add>` implementation. The output will be encoded in | ||
| /// 2's-complement, so a leading one means that the output is considered | ||
| /// 2’s-complement, so a leading one means that the output is considered | ||
| /// negative. | ||
@@ -1787,3 +1856,3 @@ /// | ||
| /// Subtract one `BitVec` from another. | ||
| /// Subtracts one `BitVec` from another. | ||
| /// | ||
@@ -1827,3 +1896,3 @@ /// # Examples | ||
| /// Subtract another `BitVec` from `self`, assuming 2's-complement encoding. | ||
| /// Subtracts another `BitVec` from `self`, assuming 2’s-complement encoding. | ||
| /// | ||
@@ -1842,3 +1911,3 @@ /// The minuend is zero-extended, or the subtrahend sign-extended, as needed to | ||
| where E: Endian, T: Bits { | ||
| /// Subtract another `BitVec` from `self`. | ||
| /// Subtracts another `BitVec` from `self`. | ||
| /// | ||
@@ -1892,3 +1961,3 @@ /// # Examples | ||
| /// Iterate over an owned `BitVec`. | ||
| /// Iterates over an owned `BitVec`. | ||
| #[doc(hidden)] | ||
@@ -1921,3 +1990,3 @@ pub struct IntoIter<E, T> | ||
| where E: Endian, T: Bits { | ||
| /// Yield the back-most bit of the collection. | ||
| /// Yields the back-most bit of the collection. | ||
| /// | ||
@@ -1968,3 +2037,3 @@ /// This iterator is self-resetting; when the cursor reaches the front of | ||
| /// Advance the iterator forward, yielding the front-most bit. | ||
| /// Advances the iterator forward, yielding the front-most bit. | ||
| /// | ||
@@ -1987,7 +2056,7 @@ /// This iterator is self-resetting: when the cursor reaches the back of the | ||
| // Note that the default ExactSizeIterator::len calls this method, so | ||
| // Note that the default `ExactSizeIterator::len` calls this method, so | ||
| // removing that implementation will cause an infinite mutual recursion, | ||
| // only detectable *at runtime* when the stack blows. | ||
| // | ||
| // THIS METHOD MUST BE CHANGED TO NOT CALL ExactSizeIterator::len BEFORE | ||
| // THIS METHOD MUST BE CHANGED TO NOT CALL `ExactSizeIterator::len` BEFORE | ||
| // REMOVING THE SPECIALIZATION FOR ESI! THE DEFAULT IMPLEMENTATION OF ESI | ||
@@ -2001,3 +2070,3 @@ // CALLS THIS FUNCTION, WHICH WILL COMPILE CLEANLY AND THEN BLOW THE STACK | ||
| /// Count how many bits are live in the iterator, consuming it. | ||
| /// Counts how many bits are live in the iterator, consuming it. | ||
| /// | ||
@@ -2018,3 +2087,3 @@ /// You are probably looking to use this on a borrowed iterator rather than | ||
| /// Advance the iterator by `n` bits, starting from zero. | ||
| /// Advances the iterator by `n` bits, starting from zero. | ||
| /// | ||
@@ -2035,3 +2104,3 @@ /// It is not an error to advance past the end of the iterator! Doing so | ||
| /// This example intentionally overshoots the iterator bounds, which causes | ||
| /// a reset to the initiol state. It then demonstrates that `nth` is | ||
| /// a reset to the initial state. It then demonstrates that `nth` is | ||
| /// stateful, and is not an absolute index, by seeking ahead by two (to the | ||
@@ -2051,7 +2120,7 @@ /// third zero bit) and then taking the bit immediately after it, which is | ||
| fn nth(&mut self, n: usize) -> Option<bool> { | ||
| self.head += n; | ||
| self.head = self.head.saturating_add(n); | ||
| self.next() | ||
| } | ||
| /// Consume the iterator, returning only the last bit. | ||
| /// Consumes the iterator, returning only the last bit. | ||
| /// | ||
@@ -2058,0 +2127,0 @@ /// # Examples |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet