| { | ||
| "git": { | ||
| "sha1": "b9bf6ee8b924493adbb1247decda1c02fed217d0" | ||
| } | ||
| } |
| [*] | ||
| charset = utf-8 | ||
| end_of_line = lf | ||
| insert_final_newline = true | ||
| trim_trailing_whitespace = true | ||
| [*.md] | ||
| indent_size = 2 | ||
| indent_style = space | ||
| [*.rs] | ||
| indent_size = 4 | ||
| indent_style = tab | ||
| [*.toml] | ||
| indent_size = 8 | ||
| indent_style = tab | ||
| [*.yml] | ||
| indent_size = 2 | ||
| indent_style = space |
+40
| language: rust | ||
| sudo: required | ||
| rust: | ||
| - stable | ||
| - beta | ||
| - nightly | ||
| matrix: | ||
| allow_failures: | ||
| - rust: nightly | ||
| # codecov | ||
| addons: | ||
| apt: | ||
| packages: | ||
| - libcurl4-openssl-dev | ||
| - libelf-dev | ||
| - libdw-dev | ||
| - cmake | ||
| - gcc | ||
| - binutils-dev | ||
| - libiberty-dev | ||
| # codecov | ||
| after_success: | | ||
| wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz && | ||
| tar xzf master.tar.gz && | ||
| cd kcov-master && | ||
| mkdir build && | ||
| cd build && | ||
| cmake .. && | ||
| make && | ||
| make install DESTDIR=../../kcov-build && | ||
| cd ../.. && | ||
| rm -rf kcov-master && | ||
| for file in target/debug/bitvec-*[^\.d]; do mkdir -p "target/cov/$(basename $file)"; ./kcov-build/usr/local/bin/kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; done && | ||
| bash <(curl -s https://codecov.io/bash) && | ||
| echo "Uploaded code coverage" |
+306
| /*! Bit Cursors | ||
| `BitVec` is parametric over any ordering of bits within an element. The `Cursor` | ||
| trait maps a cursor position to a bit index within an element, and the order of | ||
| traversal over an element. | ||
| The only requirement on implementors of `Cursor` is that the transform function | ||
| from cursor to index is *total* (every integer in the range `0 .. T::BITS` is | ||
| used), *unique* (each cursor maps to one and only one index, and each index is | ||
| mapped by one and only one cursor). Contiguity is not required. | ||
| !*/ | ||
| use super::bits::Bits; | ||
| /// Travels an element starting at the Most Significant Bit and ending at the | ||
| /// Least Significant Bit. | ||
| pub struct BigEndian; | ||
| /// Travels an element starting at the Least Significant Bit and ending at the | ||
| /// Most Significant Bit. | ||
| pub struct LittleEndian; | ||
| /** A cursor over an element. | ||
| # Usage | ||
| `BitVec` stores semantic count, not a cursor into an element, as its `bits` | ||
| value. The methods on `Cursor` all return a cursor into a storage element. | ||
| - `curr` computes the bit index of the count given. In Little-Endian order, this | ||
| is the identity function (bit indices count up “left” from LSb), and in | ||
| Big-Endian order, this subtracts the count given from `T::MASK` (bit indices | ||
| count down “right” from MSb). | ||
| - `next` computes the next index forward from the count given. In Little-Endian | ||
| order, this increments (moving up from LSb towards MSb); in Big-Endian order, | ||
| this decrements (moving down from MSb towards LSb). | ||
| - `prev` computes the previous index backward from the count given. In | ||
| Little-Endian order, this decrements (moving down towards LSb from MSb); in | ||
| Big-Endian order, this increments (moving up towards MSb from LSb). | ||
| - `jump` computes a number of whole elements to move, as well as the bit index | ||
| within the destination element of the target bit. | ||
| You should use `curr` to look up a bit at a known point, such as when indexing a | ||
| `BitVec`; you should use `next` or `prev` to implement push, pop, and iteration; | ||
| you should use `jump` only to implement striding iterators in a manner faster | ||
| than the default (which just repeatedly calls `next` and drops most yielded | ||
| values). | ||
| # Notes | ||
| All functions *take* a semantic count into a storage element, which will always | ||
| move upwards from zero, but all functions *return* an actual index to a specific | ||
| bit in the element achieved by shifting right and masking off all but the LSb of | ||
| the output. The output is *not* a semantic count, and does not need converted to | ||
| an index with `curr`. It therefore cannot be stored as the new semantic count | ||
| during a mutation. The caller is responsible for maintaining count status. | ||
| `next` and `prev` signal when they cross the boundary of a storage element. If | ||
| their second return value is true, then the first return value is an index into | ||
| the storage element either after (`next`) or before (`prev`) the element for | ||
| which the input count referred. The caller is responsible for ensuring that they | ||
| use the returned index in the correct storage element by inspecting this flag | ||
| and moving their selection accordingly. | ||
| `jump` returns the number of storage elements the caller will have to move their | ||
| cursor before indexing. `next` and `prev` can only move zero or one elements, so | ||
| their flag is a `bool` rather than an `isize`. The order swap for `jump` is | ||
| because the number of elements to move is expected to be a more significant part | ||
| of its return value than the edge flag is in `next` and `prev`. | ||
| **/ | ||
| pub trait Cursor { | ||
| /// Compute the bit index at a given count. | ||
| /// | ||
| /// In Little-Endian, this is a no-op; in Big-Endian, it subtracts the index | ||
| /// from `T::MASK` (the maximum value). | ||
| fn curr<T: Bits>(count: u8) -> u8; | ||
| /// Compute the semantic index that logically follows the given index. | ||
| /// | ||
| /// The first value returned must be passed into `curr` in order to index | ||
| /// into an element. The second value indicates whether the increment points | ||
| /// into a different element. | ||
| fn next<T: Bits>(count: u8) -> (u8, bool) { | ||
| let next = count.wrapping_add(1) & T::MASK; | ||
| let wrap = next == 0; | ||
| (next, wrap) | ||
| } | ||
| /// Compute the semantic index that logically precedes the given index. | ||
| /// | ||
| /// The first value returned must be passed into `curr` in order to index | ||
| /// into an element. The second value indicates whether the decrement points | ||
| /// into a different element. | ||
| fn prev<T: Bits>(count: u8) -> (u8, bool) { | ||
| let (next, wrap) = count.overflowing_sub(1); | ||
| (next & T::MASK, wrap) | ||
| } | ||
| /// Computes the bit index at a given semantic offset from the current | ||
| /// cursor. | ||
| /// | ||
| /// Returns a tuple where the first value is the number of whole storage | ||
| /// elements to move, and the second is the bit index within the element. | ||
| fn jump<T: Bits>(count: u8, offset: isize) -> (isize, u8) { | ||
| 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 | ||
| // math doesn't know how to move around in an ordering. The offset is | ||
| // signed in count order, not Endian order. | ||
| // Subtraction can never fail, because count is always >= 0 and | ||
| // `0 - isize::MIN` is `isize::MIN`, which does not overflow. | ||
| // In a non-overflowing addition, the result will be the position of | ||
| // the target bit | ||
| match (count as isize).overflowing_add(offset) { | ||
| // If the addition overflows, then the offset is positive. Add as | ||
| // 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. | ||
| (_, 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 | ||
| // the elements, which even more conveniently, is equivalent to | ||
| // right-shift by the number of bits required to index an | ||
| // element. Note that we don't cast until *after* the shift, in | ||
| // order to ensure that it is zero-filled at the high bits. | ||
| let elements = (far >> T::BITS) as isize; | ||
| // The new bit position of the cursor is the new position | ||
| // modulo the number of bits in the element (equivalent to | ||
| // bit-and of the provided mask). | ||
| let pos = (far & (T::MASK as usize)) as u8; | ||
| (elements, pos) | ||
| }, | ||
| // 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 => { | ||
| let elements = far >> T::BITS; | ||
| let pos = (far & (T::MASK as isize)) as u8; | ||
| (elements, Self::curr::<T>(pos)) | ||
| }, | ||
| // Otherwise, `far` is the *bit count* in the current element. It | ||
| // must still be converted from count to bit index. | ||
| (far, _) => { | ||
| (0, Self::curr::<T>(far as u8)) | ||
| }, | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| const TY: &'static str = ""; | ||
| } | ||
| impl Cursor for BigEndian { | ||
| fn curr<T: Bits>(count: u8) -> u8 { | ||
| assert!(count < T::WIDTH, "Index out of range of the storage type"); | ||
| T::MASK - count | ||
| } | ||
| const TY: &'static str = "BigEndian"; | ||
| } | ||
| impl Cursor for LittleEndian { | ||
| fn curr<T: Bits>(count: u8) -> u8 { | ||
| assert!(count < T::WIDTH, "Index out of range of the storage type"); | ||
| count | ||
| } | ||
| const TY: &'static str = "LittleEndian"; | ||
| } | ||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| #[test] | ||
| fn incr_edge() { | ||
| 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)); | ||
| } | ||
| #[test] | ||
| fn decr_edge() { | ||
| 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)); | ||
| } | ||
| #[test] | ||
| fn jump_inside_elt() { | ||
| // TODO(myrrlyn): test the other two types. | ||
| let (elt, bit) = LittleEndian::jump::<u8>(5, 2); | ||
| assert_eq!(elt, 0); | ||
| assert_eq!(bit, 7); | ||
| // Counts start from 0, so count 5 is the SIXTH bit | ||
| let (elt, bit) = BigEndian::jump::<u8>(5, 2); | ||
| assert_eq!(elt, 0); | ||
| assert_eq!(bit, 0); | ||
| let (elt, bit) = LittleEndian::jump::<u32>(20, 8); | ||
| assert_eq!(elt, 0); | ||
| assert_eq!(bit, 28); | ||
| // In Big-Endian order, count 20 is bit 11, and moving that backward by | ||
| // 8 is addition, up to 19. | ||
| let (elt, bit) = BigEndian::jump::<u32>(20, -8); | ||
| assert_eq!(elt, 0); | ||
| assert_eq!(bit, 19); | ||
| } | ||
| #[test] | ||
| fn jump_backwards() { | ||
| // TODO(myrrlyn): Test the other three types. | ||
| let (elt, bit) = LittleEndian::jump::<u32>(10, -15); | ||
| assert_eq!(elt, -1); | ||
| // Moving backwards through LE starts at MSb and decrements | ||
| // 10 - 10 is 0, 0 - 1 is 31, 31 - 4 is 27 | ||
| assert_eq!(bit, 27); | ||
| let (elt, bit) = BigEndian::jump::<u32>(10, -15); | ||
| assert_eq!(elt, -1); | ||
| // Moving backwards through BE starts at LSb and increments | ||
| // 10 - 10 is count 0 (bit 31), then the cursor crosses the boundary | ||
| // and counts 0, 1, 2, 3, 4. | ||
| assert_eq!(bit, 4); | ||
| } | ||
| #[test] | ||
| fn jump_forwards() { | ||
| // TODO(myrrlyn): Test the other three types. | ||
| let (elt, bit) = LittleEndian::jump::<u32>(25, 10); | ||
| assert_eq!(elt, 1); | ||
| assert_eq!(bit, 3); | ||
| let (elt, bit) = BigEndian::jump::<u32>(25, 10); | ||
| assert_eq!(elt, 1); | ||
| // Moving forwards through BE starts at MSb and decrements. 25 + 6 is | ||
| // count 31 (bit 0), then the cursor crosses the boundary and counts | ||
| // 31, 30, 29, 28. | ||
| assert_eq!(bit, 28); | ||
| } | ||
| #[test] | ||
| fn jump_overflow() { | ||
| // 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). | ||
| let start = 20; | ||
| let (elt, bit) = LittleEndian::jump::<u32>(start, core::isize::MAX); | ||
| assert_eq!(elt as usize, core::isize::MIN as usize >> u32::BITS); | ||
| assert_eq!(bit, start - 1); | ||
| let (elt, bit) = BigEndian::jump::<u32>(start, core::isize::MAX); | ||
| assert_eq!(elt as usize, core::isize::MIN as usize >> u32::BITS); | ||
| assert_eq!(bit, BigEndian::curr::<u32>(start) - 1); | ||
| } | ||
| #[test] | ||
| fn curr_reversible() { | ||
| for n in 0 .. 8 { | ||
| assert_eq!(n, BigEndian::curr::<u8>(BigEndian::curr::<u8>(n))); | ||
| } | ||
| for n in 0 .. 16 { | ||
| assert_eq!(n, BigEndian::curr::<u16>(BigEndian::curr::<u16>(n))); | ||
| } | ||
| for n in 0 .. 32 { | ||
| assert_eq!(n, BigEndian::curr::<u32>(BigEndian::curr::<u32>(n))); | ||
| } | ||
| for n in 0 .. 64 { | ||
| assert_eq!(n, BigEndian::curr::<u64>(BigEndian::curr::<u64>(n))); | ||
| } | ||
| 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))); | ||
| } | ||
| } | ||
| } |
+20
-2
@@ -14,4 +14,5 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| [package] | ||
| edition = "2018" | ||
| name = "bitvec" | ||
| version = "0.8.0" | ||
| version = "0.9.0-e2018" | ||
| authors = ["myrrlyn <myrrlyn@outlook.com>"] | ||
@@ -21,3 +22,6 @@ description = "A crate for manipulating memory, bit by bit" | ||
| documentation = "https://docs.rs/bitvec" | ||
| license-file = "LICENSE.txt" | ||
| readme = "README.md" | ||
| keywords = ["bits", "bitvec"] | ||
| categories = ["data-structures", "embedded", "no-std", "rust-patterns"] | ||
| license = "MIT" | ||
| repository = "https://github.com/myrrlyn/bitvec" | ||
@@ -31,1 +35,15 @@ | ||
| std = ["alloc"] | ||
| testing = ["std"] | ||
| [badges.codecov] | ||
| branch = "master" | ||
| repository = "myrrlyn/bitvec" | ||
| service = "github" | ||
| [badges.is-it-maintained-issue-resolution] | ||
| repository = "myrrlyn/bitvec" | ||
| [badges.is-it-maintained-open-issues] | ||
| repository = "myrrlyn/bitvec" | ||
| [badges.maintenance] | ||
| status = "actively-developed" |
+9
-0
@@ -5,2 +5,11 @@ # Changelog | ||
| ## 0.9.0 | ||
| ### Changed | ||
| - The trait `Endian` has been renamed to `Cursor`, and all type variables | ||
| `E: Endian` have been renamed to `C: Cursor`. | ||
| - The `Bits` trait is no longer bound by `Default`. | ||
| ## 0.8.0 | ||
@@ -7,0 +16,0 @@ |
@@ -5,5 +5,2 @@ /*! Prove that the example code in `README.md` executes. | ||
| #[cfg(feature = "alloc")] | ||
| extern crate bitvec; | ||
| #[cfg(feature = "alloc")] | ||
| use bitvec::*; | ||
@@ -10,0 +7,0 @@ |
@@ -26,5 +26,2 @@ /*! Sieve of Eratosthenes | ||
| #[cfg(feature = "alloc")] | ||
| extern crate bitvec; | ||
| #[cfg(feature = "alloc")] | ||
| use bitvec::{ | ||
@@ -31,0 +28,0 @@ BitVec, |
+2
-5
@@ -10,5 +10,2 @@ /*! Demonstrates construction and use of a big-endian, u8, `BitVec` | ||
| #[cfg(feature = "alloc")] | ||
| extern crate bitvec; | ||
| #[cfg(feature = "alloc")] | ||
| use bitvec::{ | ||
@@ -22,3 +19,3 @@ // `bitvec!` macro | ||
| // element-traversal trait (you shouldn’t explicitly need this) | ||
| Endian, | ||
| Cursor, | ||
| // directionality type marker (the default for `BitVec`; you will rarely | ||
@@ -98,3 +95,3 @@ // explicitly need this) | ||
| fn render<E: Endian, T: Bits>(bv: &BitVec<E, T>) { | ||
| fn render<C: Cursor, T: Bits>(bv: &BitVec<C, T>) { | ||
| println!("Memory information: {} {} {}", bv.elts(), bv.bits(), bv.len()); | ||
@@ -101,0 +98,0 @@ println!("Print out the semantic contents"); |
+7
-7
@@ -14,3 +14,3 @@ # `BitVec` – Managing memory bit by bit | ||
| `BitVec` is generic over an ordering cursor, using the trait `Endian`, and the | ||
| `BitVec` is generic over an ordering cursor, using the trait `Cursor`, and the | ||
| primitive type, using the trait `Bits`. This means that `BitVec` structures can | ||
@@ -77,3 +77,3 @@ be built with a great deal of flexibility over how they manage their memory and | ||
| - `BitSlice<E: Endian, T: Bits>` – the actual bit-slice reference type It is | ||
| - `BitSlice<C: Cursor, T: Bits>` – the actual bit-slice reference type It is | ||
| generic over a cursor type (`E`) and storage type (`T`). Note that `BitSlice` | ||
@@ -89,8 +89,8 @@ is unsized, and can never be held directly; it must always be behind a | ||
| - `BitVec<E: Endian, T: Bits>` – the actual bit-vector structure type. It is | ||
| - `BitVec<C: Cursor, T: Bits>` – the actual bit-vector structure type. It is | ||
| generic over a cursor type (`E`) and storage type (`T`). | ||
| - `Endian` – an open trait that defines an ordering schema for `BitVec` to use. | ||
| - `Cursor` – an open trait that defines an ordering schema for `BitVec` to use. | ||
| Little and big endian orderings are provided by default. If you wish to | ||
| implement other ordering types, the `Endian` trait requires one function: | ||
| implement other ordering types, the `Cursor` trait requires one function: | ||
@@ -111,6 +111,6 @@ - `fn curr<T: Bits>(index: u8) -> u8` takes a semantic index and computes a | ||
| - `BigEndian` – a zero-sized struct that implements `Endian` by defining the | ||
| - `BigEndian` – a zero-sized struct that implements `Cursor` by defining the | ||
| forward direction as towards LSb and the backward direction as towards MSb. | ||
| - `LittleEndian` – a zero-sized struct that implements `Endian` by defining the | ||
| - `LittleEndian` – a zero-sized struct that implements `Cursor` by defining the | ||
| forward direction as towards MSb and the backward direction as towards LSb. | ||
@@ -117,0 +117,0 @@ |
+30
-24
@@ -11,3 +11,2 @@ /*! Bit Management | ||
| convert::From, | ||
| default::Default, | ||
| fmt::{ | ||
@@ -50,5 +49,2 @@ Binary, | ||
| + Debug | ||
| // `BitVec` cannot push new elements without this. (Well, it CAN, but | ||
| // `mem::uninitialized` is Considered Harmful.) | ||
| + Default | ||
| + Display | ||
@@ -77,5 +73,5 @@ // Permit testing a value against 1 in `get()`. | ||
| /// | ||
| /// Incidentally, this can be computed as `size_of().trailing_zeroes()` once | ||
| /// Incidentally, this can be computed as `size_of().trailing_zeros()` once | ||
| /// that becomes a valid constexpr. | ||
| const BITS: u8; // = size_of::<Self>().trailing_zeros(); | ||
| const BITS: u8; // = size_of::<Self>().trailing_zeros() as u8; | ||
@@ -106,6 +102,8 @@ /// The bitmask to turn an arbitrary usize into the bit index. Bit indices | ||
| /// Counts how many bits are set. | ||
| fn ones(&self) -> u32; | ||
| #[inline(always)] | ||
| fn ones(&self) -> usize; | ||
| /// Counts how many bits are unset. | ||
| fn zeros(&self) -> u32; | ||
| #[inline(always)] | ||
| fn zeros(&self) -> usize; | ||
@@ -137,8 +135,10 @@ /// Splits a `usize` cursor into an (element, bit) tuple. | ||
| fn ones(&self) -> u32 { | ||
| self.count_ones() | ||
| #[inline(always)] | ||
| fn ones(&self) -> usize { | ||
| self.count_ones() as usize | ||
| } | ||
| fn zeros(&self) -> u32 { | ||
| self.count_zeros() | ||
| #[inline(always)] | ||
| fn zeros(&self) -> usize { | ||
| self.count_zeros() as usize | ||
| } | ||
@@ -152,8 +152,10 @@ | ||
| fn ones(&self) -> u32 { | ||
| self.count_ones() | ||
| #[inline(always)] | ||
| fn ones(&self) -> usize { | ||
| self.count_ones() as usize | ||
| } | ||
| fn zeros(&self) -> u32 { | ||
| self.count_zeros() | ||
| #[inline(always)] | ||
| fn zeros(&self) -> usize { | ||
| self.count_zeros() as usize | ||
| } | ||
@@ -167,8 +169,10 @@ | ||
| fn ones(&self) -> u32 { | ||
| self.count_ones() | ||
| #[inline(always)] | ||
| fn ones(&self) -> usize { | ||
| self.count_ones() as usize | ||
| } | ||
| fn zeros(&self) -> u32 { | ||
| self.count_zeros() | ||
| #[inline(always)] | ||
| fn zeros(&self) -> usize { | ||
| self.count_zeros() as usize | ||
| } | ||
@@ -184,8 +188,10 @@ | ||
| fn ones(&self) -> u32 { | ||
| self.count_ones() | ||
| #[inline(always)] | ||
| fn ones(&self) -> usize { | ||
| self.count_ones() as usize | ||
| } | ||
| fn zeros(&self) -> u32 { | ||
| self.count_zeros() | ||
| #[inline(always)] | ||
| fn zeros(&self) -> usize { | ||
| self.count_zeros() as usize | ||
| } | ||
@@ -192,0 +198,0 @@ |
+3
-9
@@ -39,8 +39,2 @@ /*! `BitVec` – `Vec<bool>` in overdrive. | ||
| #[cfg(all(feature = "alloc", not(feature = "std")))] | ||
| extern crate alloc; | ||
| #[cfg(feature = "std")] | ||
| extern crate core; | ||
| #[macro_use] | ||
@@ -50,3 +44,3 @@ mod macros; | ||
| mod bits; | ||
| mod endian; | ||
| mod cursor; | ||
| mod slice; | ||
@@ -56,4 +50,4 @@ | ||
| bits::Bits, | ||
| endian::{ | ||
| Endian, | ||
| cursor::{ | ||
| Cursor, | ||
| BigEndian, | ||
@@ -60,0 +54,0 @@ LittleEndian, |
+17
-17
| /** 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 | ||
| `Cursor` implementation, the name of a `Bits`-implementing primitive, and | ||
| zero or more primitives (integer, floating-point, or bool) which are used to | ||
@@ -9,6 +9,6 @@ build the bits. Each primitive literal corresponds to one bit, and is | ||
| `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. | ||
| `bitvec!` can be invoked with no specifiers, a `Cursor` specifier, or a `Cursor` | ||
| and a `Bits` specifier. It cannot be invoked with a `Bits` specifier but no | ||
| `Cursor` specifier, due to overlap in how those tokens are matched by the macro | ||
| system. | ||
@@ -104,4 +104,4 @@ Like `vec!`, `bitvec!` supports bit lists `[0, 1, …]` and repetition | ||
| #[doc(hidden)] | ||
| impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::ShlAssign< $t > | ||
| for crate::BitSlice<E, T> | ||
| impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::ShlAssign< $t > | ||
| for crate::BitSlice<C, T> | ||
| { | ||
@@ -114,4 +114,4 @@ fn shl_assign(&mut self, shamt: $t ) { | ||
| #[doc(hidden)] | ||
| impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::ShrAssign< $t > | ||
| for crate::BitSlice<E, T> | ||
| impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::ShrAssign< $t > | ||
| for crate::BitSlice<C, T> | ||
| { | ||
@@ -130,4 +130,4 @@ fn shr_assign(&mut self, shamt: $t ) { | ||
| #[doc(hidden)] | ||
| impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::Shl< $t > | ||
| for $crate :: BitVec<E, T> | ||
| impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::Shl< $t > | ||
| for $crate :: BitVec<C, T> | ||
| { | ||
@@ -142,4 +142,4 @@ type Output = <Self as core::ops::Shl<usize>>::Output; | ||
| #[doc(hidden)] | ||
| impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::ShlAssign< $t > | ||
| for $crate :: BitVec<E, T> | ||
| impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::ShlAssign< $t > | ||
| for $crate :: BitVec<C, T> | ||
| { | ||
@@ -152,4 +152,4 @@ fn shl_assign(&mut self, shamt: $t ) { | ||
| #[doc(hidden)] | ||
| impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::Shr< $t > | ||
| for $crate :: BitVec<E, T> | ||
| impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::Shr< $t > | ||
| for $crate :: BitVec<C, T> | ||
| { | ||
@@ -164,4 +164,4 @@ type Output = <Self as core::ops::Shr<usize>>::Output; | ||
| #[doc(hidden)] | ||
| impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::ShrAssign< $t > | ||
| for $crate :: BitVec<E, T> | ||
| impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::ShrAssign< $t > | ||
| for $crate :: BitVec<C, T> | ||
| { | ||
@@ -168,0 +168,0 @@ fn shr_assign(&mut self, shamt: $t ) { |
+244
-106
@@ -95,3 +95,3 @@ /*! `BitSlice` Wide Reference | ||
| `BitSlice` is a newtype wrapper over `[T]`, and as such can only be held by | ||
| reference. It is impossible to create a `Box<BitSlice<E, T>>` from this library, | ||
| reference. It is impossible to create a `Box<BitSlice<C, T>>` from this library, | ||
| and assembling one yourself is Undefined Behavior for which this library is not | ||
@@ -109,3 +109,3 @@ responsible. **Do not try to create a `Box<BitSlice>`.** If you want an owned | ||
| - `E: Endian` must be an implementor of the `Endian` trait. `BitVec` takes a | ||
| - `C: Cursor` must be an implementor of the `Cursor` trait. `BitVec` takes a | ||
| `PhantomData` marker for access to the associated functions, and will never | ||
@@ -121,11 +121,11 @@ make use of an instance of the trait. The default implementations, | ||
| **/ | ||
| #[cfg_attr(nightly, repr(transparent))] | ||
| pub struct BitSlice<E = crate::BigEndian, T = u8> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| _endian: PhantomData<E>, | ||
| #[repr(transparent)] | ||
| pub struct BitSlice<C = crate::BigEndian, T = u8> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| _cursor: PhantomData<C>, | ||
| inner: [T], | ||
| } | ||
| impl<E, T> BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Gets the bit value at the given position. | ||
@@ -149,3 +149,3 @@ /// | ||
| let (elt, bit) = T::split(index); | ||
| self.as_ref()[elt].get(E::curr::<T>(bit)) | ||
| self.as_ref()[elt].get(C::curr::<T>(bit)) | ||
| } | ||
@@ -172,3 +172,3 @@ | ||
| let (elt, bit) = T::split(index); | ||
| self.as_mut()[elt].set(E::curr::<T>(bit), value); | ||
| self.as_mut()[elt].set(C::curr::<T>(bit), value); | ||
| } | ||
@@ -205,4 +205,3 @@ | ||
| // Gallop the filled elements | ||
| let store = self.as_ref(); | ||
| for elt in &store[.. self.elts()] { | ||
| for elt in self.body() { | ||
| if *elt != T::from(!0) { | ||
@@ -213,7 +212,5 @@ return false; | ||
| // Walk the partial tail | ||
| let bits = self.bits(); | ||
| if bits > 0 { | ||
| let tail = store[self.elts()]; | ||
| for bit in 0 .. bits { | ||
| if !tail.get(E::curr::<T>(bit)) { | ||
| if let Some(tail) = self.tail() { | ||
| for bit in 0 .. self.bits() { | ||
| if !tail.get(C::curr::<T>(bit)) { | ||
| return false; | ||
@@ -255,4 +252,3 @@ } | ||
| // Gallop the filled elements | ||
| let store = self.as_ref(); | ||
| for elt in &store[.. self.elts()] { | ||
| for elt in self.body() { | ||
| if *elt != T::from(0) { | ||
@@ -263,7 +259,5 @@ return true; | ||
| // Walk the partial tail | ||
| let bits = self.bits(); | ||
| if bits > 0 { | ||
| let tail = store[self.elts()]; | ||
| for bit in 0 .. bits { | ||
| if tail.get(E::curr::<T>(bit)) { | ||
| if let Some(tail) = self.tail() { | ||
| for bit in 0 .. self.bits() { | ||
| if tail.get(C::curr::<T>(bit)) { | ||
| return true; | ||
@@ -377,8 +371,11 @@ } | ||
| /// use bitvec::*; | ||
| /// let bv = bitvec![1, 0, 1, 0, 1]; | ||
| /// assert_eq!(bv.count_ones(), 3); | ||
| /// let bv = bitvec![1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1]; | ||
| /// assert_eq!(bv.count_ones(), 7); | ||
| /// # } | ||
| /// ``` | ||
| pub fn count_ones(&self) -> usize { | ||
| self.into_iter().filter(|b| *b).count() | ||
| self.body().iter().map(T::ones).sum::<usize>() + | ||
| self.tail().map(|t| (0 .. self.bits()) | ||
| .map(|n| t.get(C::curr::<T>(n))).filter(|b| *b).count() | ||
| ).unwrap_or(0) | ||
| } | ||
@@ -393,8 +390,11 @@ | ||
| /// use bitvec::*; | ||
| /// let bv = bitvec![0, 1, 0, 1, 0]; | ||
| /// assert_eq!(bv.count_zeros(), 3); | ||
| /// let bv = bitvec![1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1]; | ||
| /// assert_eq!(bv.count_zeros(), 6); | ||
| /// # } | ||
| /// ``` | ||
| pub fn count_zeros(&self) -> usize { | ||
| self.into_iter().filter(|b| !b).count() | ||
| self.body().iter().map(T::zeros).sum::<usize>() + | ||
| self.tail().map(|t| (0 .. self.bits()) | ||
| .map(|n| t.get(C::curr::<T>(n))).filter(|b| !*b).count() | ||
| ).unwrap_or(0) | ||
| } | ||
@@ -506,3 +506,3 @@ | ||
| /// iterator does. | ||
| pub fn iter(&self) -> Iter<E, T> { | ||
| pub fn iter(&self) -> Iter<C, T> { | ||
| self.into_iter() | ||
@@ -557,6 +557,9 @@ } | ||
| /// | ||
| /// This is a crate-local function. It only appears in the docs so that it | ||
| /// can be tested. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ```rust,ignore | ||
| /// # #[cfg(feature = "alloc")] { | ||
| /// ```rust | ||
| /// # #[cfg(all(feature = "alloc", feature = "testing"))] { | ||
| /// use bitvec::*; | ||
@@ -569,13 +572,148 @@ /// let bv = bitvec![1; 10]; | ||
| /// ``` | ||
| /// | ||
| /// This test is never compiled because the functions it calls are not | ||
| /// accessible to the test crate. | ||
| pub(crate) fn raw_len(&self) -> usize { | ||
| #[cfg(feature = "testing")] | ||
| pub fn raw_len(&self) -> usize { self.raw_len_inner() } | ||
| #[cfg(not(feature = "testing"))] | ||
| pub(crate) fn raw_len(&self) -> usize { self.raw_len_inner() } | ||
| #[doc(hidden)] | ||
| #[inline(always)] | ||
| fn raw_len_inner(&self) -> usize { | ||
| self.elts() + if self.bits() > 0 { 1 } else { 0 } | ||
| } | ||
| /// Gets access to the set of all filled elements as a slice. | ||
| /// | ||
| /// This is primarily useful for bulk operations on the filled elements. | ||
| /// | ||
| /// This is a crate-local function. It only appears in the docs so that it | ||
| /// can be tested. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ```rust | ||
| /// # #[cfg(all(feature = "alloc", feature = "testing"))] { | ||
| /// use bitvec::*; | ||
| /// let bv = bitvec![1; 10]; | ||
| /// let body: &[u8] = bv.body(); | ||
| /// assert_eq!(body.len(), 1); | ||
| /// # } | ||
| /// ``` | ||
| #[cfg(feature = "testing")] | ||
| pub fn body(&self) -> &[T] { self.body_inner() } | ||
| #[cfg(not(feature = "testing"))] | ||
| pub(crate) fn body(&self) -> &[T] { self.body_inner() } | ||
| #[doc(hidden)] | ||
| #[inline(always)] | ||
| fn body_inner(&self) -> &[T] { | ||
| let elts = self.elts(); | ||
| &self.as_ref()[.. elts] | ||
| } | ||
| /// Gets mutable access to the set of all filled elements as a slice. | ||
| /// | ||
| /// This is primarily useful for bulk operations on the filled elements. | ||
| /// | ||
| /// This is a crate-local function. It only appears in the docs so that it | ||
| /// can be tested. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ```rust | ||
| /// # #[cfg(all(feature = "alloc", feature = "testing"))] { | ||
| /// use bitvec::*; | ||
| /// let mut bv = bitvec![1; 10]; | ||
| /// assert!(bv[0]); | ||
| /// { | ||
| /// let body: &mut [u8] = bv.body_mut(); | ||
| /// assert_eq!(body.len(), 1); | ||
| /// assert_eq!(body[0], 0xFF); | ||
| /// body[0] = 0; | ||
| /// assert_eq!(body[0], 0x00); | ||
| /// } | ||
| /// assert!(!bv[0]); | ||
| /// # } | ||
| /// ``` | ||
| #[cfg(feature = "testing")] | ||
| pub fn body_mut(&mut self) -> &mut [T] { self.body_mut_inner() } | ||
| #[cfg(not(feature = "testing"))] | ||
| pub(crate) fn body_mut(&mut self) -> &mut [T] { self.body_mut_inner() } | ||
| #[doc(hidden)] | ||
| #[inline(always)] | ||
| fn body_mut_inner(&mut self) -> &mut [T] { | ||
| let elts = self.elts(); | ||
| &mut self.as_mut()[.. elts] | ||
| } | ||
| /// Gets access to the partially-filled tail, if it exists. | ||
| /// | ||
| /// This is a crate-local function. It only appears in the docs so that it | ||
| /// can be tested. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ```rust | ||
| /// # #[cfg(all(feature = "alloc", feature = "testing"))] { | ||
| /// use bitvec::*; | ||
| /// let bv = bitvec![1; 10]; | ||
| /// let tail: &u8 = bv.tail().unwrap(); | ||
| /// assert_eq!(*tail, 0b1100_0000); | ||
| /// # } | ||
| /// ``` | ||
| #[cfg(feature = "testing")] | ||
| pub fn tail(&self) -> Option<&T> { self.tail_inner() } | ||
| #[cfg(not(feature = "testing"))] | ||
| pub(crate) fn tail(&self) -> Option<&T> { self.tail_inner() } | ||
| #[doc(hidden)] | ||
| #[inline(always)] | ||
| fn tail_inner(&self) -> Option<&T> { | ||
| if self.bits() > 0 { | ||
| let elts = self.elts(); | ||
| Some(&self.as_ref()[elts]) | ||
| } | ||
| else { | ||
| None | ||
| } | ||
| } | ||
| /// Gets mutable access to the partially-filled tail, if it exists. | ||
| /// | ||
| /// This is a crate-local function. It only appears in the docs so that it | ||
| /// can be tested. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ```rust | ||
| /// # #[cfg(all(feature = "alloc", feature = "testing"))] { | ||
| /// use bitvec::*; | ||
| /// let mut bv = bitvec![1; 10]; | ||
| /// bv.push(false); | ||
| /// assert!(!bv[10]); | ||
| /// { | ||
| /// let tail: &mut u8 = bv.tail_mut().unwrap(); | ||
| /// assert_eq!(*tail, 0b1100_0000); | ||
| /// *tail = 0xFF; | ||
| /// assert_eq!(*tail, 0xFF); | ||
| /// } | ||
| /// assert!(bv[10]); | ||
| /// # } | ||
| /// ``` | ||
| #[cfg(feature = "testing")] | ||
| pub fn tail_mut(&mut self) -> Option<&mut T> { self.tail_mut_inner() } | ||
| #[cfg(not(feature = "testing"))] | ||
| pub(crate) fn tail_mut(&mut self) -> Option<&mut T> { self.tail_mut_inner() } | ||
| #[doc(hidden)] | ||
| #[inline(always)] | ||
| fn tail_mut_inner(&mut self) -> Option<&mut T> { | ||
| if self.bits() > 0 { | ||
| let elts = self.elts(); | ||
| Some(&mut self.as_mut()[elts]) | ||
| } | ||
| else { | ||
| None | ||
| } | ||
| } | ||
| /// Prints a type header into the Formatter. | ||
| #[cfg(feature = "alloc")] | ||
| pub(crate) fn fmt_header(&self, fmt: &mut Formatter) -> fmt::Result { | ||
| write!(fmt, "BitSlice<{}, {}>", E::TY, T::TY) | ||
| write!(fmt, "BitSlice<{}, {}>", C::TY, T::TY) | ||
| } | ||
@@ -630,3 +768,3 @@ | ||
| for bit in 0 .. bits { | ||
| let cur = E::curr::<T>(bit); | ||
| let cur = C::curr::<T>(bit); | ||
| out.write_str(if elt.get(cur) { "1" } else { "0" })?; | ||
@@ -640,5 +778,5 @@ } | ||
| #[cfg(feature = "alloc")] | ||
| impl<E, T> ToOwned for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| type Owned = crate::BitVec<E, T>; | ||
| impl<C, T> ToOwned for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Owned = crate::BitVec<C, T>; | ||
@@ -671,7 +809,7 @@ /// Clones a borrowed `BitSlice` into an owned `BitVec`. | ||
| impl<E, T> Eq for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits {} | ||
| impl<C, T> Eq for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits {} | ||
| impl<E, T> Ord for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Ord for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| fn cmp(&self, rhs: &Self) -> Ordering { | ||
@@ -692,3 +830,3 @@ match self.partial_cmp(rhs) { | ||
| impl<A, B, C, D> PartialEq<BitSlice<C, D>> for BitSlice<A, B> | ||
| where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits { | ||
| where A: crate::Cursor, B: crate::Bits, C: crate::Cursor, D: crate::Bits { | ||
| /// Performs a comparison by `==`. | ||
@@ -727,3 +865,3 @@ /// | ||
| impl<A, B, C, D> PartialOrd<BitSlice<C, D>> for BitSlice<A, B> | ||
| where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits { | ||
| where A: crate::Cursor, B: crate::Bits, C: crate::Cursor, D: crate::Bits { | ||
| /// Performs a comparison by `<` or `>`. | ||
@@ -760,4 +898,4 @@ /// | ||
| /// partially-filled tail element (if present). | ||
| impl<E, T> AsMut<[T]> for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> AsMut<[T]> for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Accesses the underlying store. | ||
@@ -785,4 +923,4 @@ /// | ||
| /// partially-filled tail element (if present). | ||
| impl<E, T> AsRef<[T]> for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> AsRef<[T]> for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Accesses the underlying store. | ||
@@ -808,5 +946,5 @@ /// | ||
| /// 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: crate::Endian, T: 'a + crate::Bits { | ||
| /// Wraps an `&[T: Bits]` in an `&BitSlice<E: Endian, T>`. The endianness | ||
| impl<'a, C, T> From<&'a [T]> for &'a BitSlice<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| /// Wraps an `&[T: Bits]` in an `&BitSlice<C: Cursor, T>`. The endianness | ||
| /// must be specified by the call site. The element type cannot be changed. | ||
@@ -845,5 +983,5 @@ /// | ||
| /// a partial tail. | ||
| impl<'a, E, T> From<&'a mut [T]> for &'a mut BitSlice<E, T> | ||
| where E: crate::Endian, T: 'a + crate::Bits { | ||
| /// Wraps an `&mut [T: Bits]` in an `&mut BitSlice<E: Endian, T>`. The | ||
| impl<'a, C, T> From<&'a mut [T]> for &'a mut BitSlice<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| /// Wraps an `&mut [T: Bits]` in an `&mut BitSlice<C: Cursor, T>`. The | ||
| /// endianness must be specified by the call site. The element type cannot | ||
@@ -879,3 +1017,3 @@ /// be changed. | ||
| /// | ||
| /// The output is of the form `BitSlice<E, T> [ELT, *]` where `<E, T>` is the | ||
| /// The output is of the form `BitSlice<C, T> [ELT, *]` where `<C, T>` is the | ||
| /// endianness and element type, with square brackets on each end of the bits | ||
@@ -889,4 +1027,4 @@ /// and all the elements of the array printed in binary. The printout is always | ||
| #[cfg(feature = "alloc")] | ||
| impl<E, T> Debug for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Debug for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Renders the `BitSlice` type header and contents for debug. | ||
@@ -932,4 +1070,4 @@ /// | ||
| #[cfg(feature = "alloc")] | ||
| impl<E, T> Display for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Display for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Renders the `BitSlice` contents for display. | ||
@@ -952,4 +1090,4 @@ /// | ||
| /// Writes the contents of the `BitSlice`, in semantic bit order, into a hasher. | ||
| impl<E, T> Hash for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Hash for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Writes each bit of the `BitSlice`, as a full `bool`, into the hasher. | ||
@@ -969,6 +1107,6 @@ fn hash<H>(&self, hasher: &mut H) | ||
| /// `DoubleEndedIterator` as it has known ends. | ||
| impl<'a, E, T> IntoIterator for &'a BitSlice<E, T> | ||
| where E: crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> IntoIterator for &'a BitSlice<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| type Item = bool; | ||
| type IntoIter = Iter<'a, E, T>; | ||
| type IntoIter = Iter<'a, C, T>; | ||
@@ -1011,4 +1149,4 @@ /// Iterates over the slice. | ||
| /// 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: crate::Endian, T: crate::Bits { | ||
| impl<'a, C, T> AddAssign<&'a BitSlice<C, T>> for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Performs unsigned wrapping addition in place. | ||
@@ -1037,3 +1175,3 @@ /// | ||
| /// ``` | ||
| fn add_assign(&mut self, addend: &'a BitSlice<E, T>) { | ||
| fn add_assign(&mut self, addend: &'a BitSlice<C, T>) { | ||
| use core::iter::repeat; | ||
@@ -1060,4 +1198,4 @@ // zero-extend the addend if it’s shorter than self | ||
| /// is extended with zero, clearing all remaining bits in `self`. | ||
| impl<E, T, I> BitAndAssign<I> for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| impl<C, T, I> BitAndAssign<I> for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| /// `AND`s a bitstream into a slice. | ||
@@ -1088,4 +1226,4 @@ /// | ||
| /// extended with zero, leaving all remaining bits in `self` as they were. | ||
| impl<E, T, I> BitOrAssign<I> for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| impl<C, T, I> BitOrAssign<I> for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| /// `OR`s a bitstream into a slice. | ||
@@ -1115,4 +1253,4 @@ /// | ||
| /// 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: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| impl<C, T, I> BitXorAssign<I> for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| /// `XOR`s a bitstream into a slice. | ||
@@ -1142,4 +1280,4 @@ /// | ||
| /// length of the `BitSlice`. | ||
| impl<'a, E, T> Index<usize> for &'a BitSlice<E, T> | ||
| where E: crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> Index<usize> for &'a BitSlice<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| type Output = bool; | ||
@@ -1170,4 +1308,4 @@ | ||
| /// This index is not recommended for public use. | ||
| impl<'a, E, T> Index<(usize, u8)> for &'a BitSlice<E, T> | ||
| where E: crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> Index<(usize, u8)> for &'a BitSlice<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| type Output = bool; | ||
@@ -1215,4 +1353,4 @@ | ||
| /// Because `BitSlice` cannot move, the negation is performed in place. | ||
| impl<'a, E, T> Neg for &'a mut BitSlice<E, T> | ||
| where E: crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> Neg for &'a mut BitSlice<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| type Output = Self; | ||
@@ -1272,8 +1410,8 @@ | ||
| // Fill an element with all 1 bits | ||
| let elt: [T; 1] = [!T::default()]; | ||
| let elt: [T; 1] = [! unsafe { mem::zeroed() }]; | ||
| if self.any() { | ||
| // Turn a slice reference `[T; 1]` into a bit-slice reference | ||
| // `[u1; 1]` | ||
| let addend: &BitSlice<E, T> = { | ||
| unsafe { mem::transmute::<&[T], &BitSlice<E, T>>(&elt) } | ||
| let addend: &BitSlice<C, T> = { | ||
| unsafe { mem::transmute::<&[T], &BitSlice<C, T>>(&elt) } | ||
| }; | ||
@@ -1294,4 +1432,4 @@ // And add it (if the slice was not all-ones). | ||
| /// operator rather than a consuming/returning operator. | ||
| impl<'a, E, T> Not for &'a mut BitSlice<E, T> | ||
| where E: crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> Not for &'a mut BitSlice<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| type Output = Self; | ||
@@ -1354,4 +1492,4 @@ | ||
| /// A shift amount of zero is a no-op, and returns immediately. | ||
| impl<E, T> ShlAssign<usize> for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> ShlAssign<usize> for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Shifts a slice left, in place. | ||
@@ -1452,4 +1590,4 @@ /// | ||
| /// A shift amount of zero is a no-op, and returns immediately. | ||
| impl<E, T> ShrAssign<usize> for BitSlice<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> ShrAssign<usize> for BitSlice<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Shifts a slice right, in place. | ||
@@ -1514,5 +1652,5 @@ /// | ||
| #[doc(hidden)] | ||
| pub struct Iter<'a, E, T> | ||
| where E: 'a + crate::Endian, T: 'a + crate::Bits { | ||
| inner: &'a BitSlice<E, T>, | ||
| pub struct Iter<'a, C, T> | ||
| where C: 'a + crate::Cursor, T: 'a + crate::Bits { | ||
| inner: &'a BitSlice<C, T>, | ||
| head: usize, | ||
@@ -1522,4 +1660,4 @@ tail: usize, | ||
| impl<'a, E, T> Iter<'a, E, T> | ||
| where E: 'a + crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> Iter<'a, C, T> | ||
| where C: 'a + crate::Cursor, T: 'a + crate::Bits { | ||
| fn reset(&mut self) { | ||
@@ -1531,4 +1669,4 @@ self.head = 0; | ||
| impl<'a, E, T> DoubleEndedIterator for Iter<'a, E, T> | ||
| where E: 'a + crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> DoubleEndedIterator for Iter<'a, C, T> | ||
| where C: 'a + crate::Cursor, T: 'a + crate::Bits { | ||
| fn next_back(&mut self) -> Option<Self::Item> { | ||
@@ -1546,4 +1684,4 @@ if self.tail > self.head { | ||
| impl<'a, E, T> ExactSizeIterator for Iter<'a, E, T> | ||
| where E: 'a + crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> ExactSizeIterator for Iter<'a, C, T> | ||
| where C: 'a + crate::Cursor, T: 'a + crate::Bits { | ||
| fn len(&self) -> usize { | ||
@@ -1554,5 +1692,5 @@ self.tail - self.head | ||
| impl<'a, E, T> From<&'a BitSlice<E, T>> for Iter<'a, E, T> | ||
| where E: 'a + crate::Endian, T: 'a + crate::Bits { | ||
| fn from(src: &'a BitSlice<E, T>) -> Self { | ||
| impl<'a, C, T> From<&'a BitSlice<C, T>> for Iter<'a, C, T> | ||
| where C: 'a + crate::Cursor, T: 'a + crate::Bits { | ||
| fn from(src: &'a BitSlice<C, T>) -> Self { | ||
| let len = src.len(); | ||
@@ -1567,4 +1705,4 @@ Self { | ||
| impl<'a, E, T> Iterator for Iter<'a, E, T> | ||
| where E: 'a + crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> Iterator for Iter<'a, C, T> | ||
| where C: 'a + crate::Cursor, T: 'a + crate::Bits { | ||
| type Item = bool; | ||
@@ -1571,0 +1709,0 @@ |
+127
-127
@@ -100,3 +100,3 @@ /*! `BitVec` structure | ||
| - `E: Endian` must be an implementor of the `Endian` trait. `BitVec` takes a | ||
| - `C: Cursor` must be an implementor of the `Cursor` trait. `BitVec` takes a | ||
| `PhantomData` marker for access to the associated functions, and will never | ||
@@ -112,12 +112,12 @@ make use of an instance of the trait. The default implementations, | ||
| **/ | ||
| #[cfg_attr(nightly, repr(transparent))] | ||
| pub struct BitVec<E = crate::BigEndian, T = u8> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| _endian: PhantomData<E>, | ||
| #[repr(transparent)] | ||
| pub struct BitVec<C = crate::BigEndian, T = u8> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| _cursor: PhantomData<C>, | ||
| inner: Vec<T>, | ||
| } | ||
| impl<E, T> BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| /// Constructs a new, empty, `BitVec<E, T>`. | ||
| impl<C, T> BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Constructs a new, empty, `BitVec<C, T>`. | ||
| /// | ||
@@ -136,3 +136,3 @@ /// The vector will not allocate until bits are pushed onto it. | ||
| Self { | ||
| _endian: PhantomData, | ||
| _cursor: PhantomData, | ||
| inner: Vec::new(), | ||
@@ -160,3 +160,3 @@ } | ||
| inner: Vec::with_capacity(cap), | ||
| _endian: PhantomData, | ||
| _cursor: PhantomData, | ||
| } | ||
@@ -196,3 +196,3 @@ } | ||
| // Get a cursor to the bit that matches the semantic count. | ||
| let cursor = E::curr::<T>(bit); | ||
| let cursor = C::curr::<T>(bit); | ||
| // Insert `value` at the current cursor. | ||
@@ -487,3 +487,3 @@ self.do_with_tail(|elt| elt.set(cursor, value)); | ||
| let len = self.len(); | ||
| self.do_with_vec(|v| v.push(Default::default())); | ||
| self.do_with_vec(|v| v.push(unsafe { mem::zeroed() })); | ||
| unsafe { | ||
@@ -498,3 +498,3 @@ self.inner.set_len(len); | ||
| fn fmt_header(&self, fmt: &mut Formatter) -> fmt::Result { | ||
| write!(fmt, "BitVec<{}, {}>", E::TY, T::TY) | ||
| write!(fmt, "BitVec<{}, {}>", C::TY, T::TY) | ||
| } | ||
@@ -504,4 +504,4 @@ } | ||
| /// Signifies that `BitSlice` is the borrowed form of `BitVec`. | ||
| impl<E, T> Borrow<crate::BitSlice<E, T>> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Borrow<crate::BitSlice<C, T>> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Borrows the `BitVec` as a `BitSlice`. | ||
@@ -518,3 +518,3 @@ /// | ||
| /// ``` | ||
| fn borrow(&self) -> &crate::BitSlice<E, T> { | ||
| fn borrow(&self) -> &crate::BitSlice<C, T> { | ||
| &*self | ||
@@ -525,4 +525,4 @@ } | ||
| /// Signifies that `BitSlice` is the borrowed form of `BitVec`. | ||
| impl<E, T> BorrowMut<crate::BitSlice<E, T>> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> BorrowMut<crate::BitSlice<C, T>> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Mutably borrows the `BitVec` as a `BitSlice`. | ||
@@ -541,3 +541,3 @@ /// | ||
| /// ``` | ||
| fn borrow_mut(&mut self) -> &mut crate::BitSlice<E, T> { | ||
| fn borrow_mut(&mut self) -> &mut crate::BitSlice<C, T> { | ||
| &mut *self | ||
@@ -547,4 +547,4 @@ } | ||
| impl<E, T> Clone for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Clone for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| fn clone(&self) -> Self { | ||
@@ -570,7 +570,7 @@ let mut out = Self::from(self.as_ref()); | ||
| impl<E, T> Eq for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits {} | ||
| impl<C, T> Eq for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits {} | ||
| impl<E, T> Ord for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Ord for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| fn cmp(&self, rhs: &Self) -> Ordering { | ||
@@ -588,3 +588,3 @@ crate::BitSlice::cmp(&self, &rhs) | ||
| impl<A, B, C, D> PartialEq<BitVec<C, D>> for BitVec<A, B> | ||
| where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits { | ||
| where A: crate::Cursor, B: crate::Bits, C: crate::Cursor, D: crate::Bits { | ||
| /// Performs a comparison by `==`. | ||
@@ -626,3 +626,3 @@ /// | ||
| impl<A, B, C, D> PartialOrd<BitVec<C, D>> for BitVec<A, B> | ||
| where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits { | ||
| where A: crate::Cursor, B: crate::Bits, C: crate::Cursor, D: crate::Bits { | ||
| /// Performs a comparison by `<` or `>`. | ||
@@ -648,4 +648,4 @@ /// | ||
| /// the partially-filled tail. | ||
| impl<E, T> AsMut<[T]> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> AsMut<[T]> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Accesses the underlying store. | ||
@@ -670,4 +670,4 @@ /// | ||
| /// the partially-filled tail. | ||
| impl<E, T> AsRef<[T]> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> AsRef<[T]> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Accesses the underlying store. | ||
@@ -691,5 +691,5 @@ /// | ||
| /// just as `&[T].into()` yields a `Vec`, `&BitSlice.into()` yields a `BitVec`. | ||
| impl<'a, E, T> From<&'a crate::BitSlice<E, T>> for BitVec<E, T> | ||
| where E: crate::Endian, T: 'a + crate::Bits { | ||
| fn from(src: &'a crate::BitSlice<E, T>) -> Self { | ||
| impl<'a, C, T> From<&'a crate::BitSlice<C, T>> for BitVec<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| fn from(src: &'a crate::BitSlice<C, T>) -> Self { | ||
| src.to_owned() | ||
@@ -703,4 +703,4 @@ } | ||
| /// use. | ||
| impl<'a, E, T> From<&'a [bool]> for BitVec<E, T> | ||
| where E: crate::Endian, T: 'a + crate::Bits { | ||
| impl<'a, C, T> From<&'a [bool]> for BitVec<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| fn from(src: &'a [bool]) -> Self { | ||
@@ -723,5 +723,5 @@ let mut out = Self::with_capacity(src.len()); | ||
| /// it can only borrow the source and not take ownership. | ||
| impl<'a, E, T> From<&'a [T]> for BitVec<E, T> | ||
| where E: crate::Endian, T: 'a + crate::Bits { | ||
| /// Builds a `BitVec<E: Endian, T: Bits>` from a borrowed `&[T]`. | ||
| impl<'a, C, T> From<&'a [T]> for BitVec<C, T> | ||
| where C: crate::Cursor, T: 'a + crate::Bits { | ||
| /// Builds a `BitVec<C: Cursor, T: Bits>` from a borrowed `&[T]`. | ||
| /// | ||
@@ -737,3 +737,3 @@ /// # Examples | ||
| fn from(src: &'a [T]) -> Self { | ||
| <&crate::BitSlice<E, T>>::from(src).to_owned() | ||
| <&crate::BitSlice<C, T>>::from(src).to_owned() | ||
| } | ||
@@ -747,5 +747,5 @@ } | ||
| /// worry about using the correct cursor type. | ||
| impl<E, T> From<Box<[T]>> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| /// Consumes a `Box<[T: Bits]>` and creates a `BitVec<E: Endian, T>` from | ||
| impl<C, T> From<Box<[T]>> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Consumes a `Box<[T: Bits]>` and creates a `BitVec<C: Cursor, T>` from | ||
| /// it. | ||
@@ -772,5 +772,5 @@ /// | ||
| /// worry about using the correct cursor type. | ||
| impl<E, T> From<Vec<T>> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| /// Consumes a `Vec<T: Bits>` and creates a `BitVec<E: Endian, T>` from it. | ||
| impl<C, T> From<Vec<T>> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Consumes a `Vec<T: Bits>` and creates a `BitVec<C: Cursor, T>` from it. | ||
| /// | ||
@@ -790,3 +790,3 @@ /// # Examples | ||
| inner: src, | ||
| _endian: PhantomData::<E>, | ||
| _cursor: PhantomData::<C>, | ||
| }; | ||
@@ -853,8 +853,8 @@ unsafe { | ||
| impl<E, T> Default for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Default for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| fn default() -> Self { | ||
| Self { | ||
| inner: Default::default(), | ||
| _endian: Default::default(), | ||
| _cursor: Default::default(), | ||
| } | ||
@@ -866,3 +866,3 @@ } | ||
| /// | ||
| /// The output is of the form `BitVec<E, T> [ELT, *]`, where `<E, T>` is the | ||
| /// The output is of the form `BitVec<C, T> [ELT, *]`, where `<C, T>` is the | ||
| /// endianness and element type, with square brackets on each end of the bits | ||
@@ -875,4 +875,4 @@ /// and all the live elements in the vector printed in binary. The printout is | ||
| /// than separated by a space. | ||
| impl<E, T> Debug for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Debug for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Renders the `BitVec` type header and contents for debug. | ||
@@ -913,4 +913,4 @@ /// | ||
| /// elements and print that slice instead. | ||
| impl<E, T> Display for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Display for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Renders the `BitVec` contents for display. | ||
@@ -931,8 +931,8 @@ /// | ||
| /// Writes the contents of the `BitVec`, in semantic bit order, into a hasher. | ||
| impl<E, T> Hash for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Hash for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Writes each bit of the `BitVec`, as a full `bool`, into the hasher. | ||
| fn hash<H>(&self, hasher: &mut H) | ||
| where H: Hasher { | ||
| <crate::BitSlice<E, T> as Hash>::hash(&self, hasher) | ||
| <crate::BitSlice<C, T> as Hash>::hash(&self, hasher) | ||
| } | ||
@@ -946,4 +946,4 @@ } | ||
| /// source into `self` when the source is `BitSlice`-compatible. | ||
| impl<E, T> Extend<bool> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Extend<bool> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Extends a `BitVec` from another bitstream. | ||
@@ -975,4 +975,4 @@ /// | ||
| /// of `bool`. | ||
| impl<E, T> FromIterator<bool> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> FromIterator<bool> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Collects an iterator of `bool` into a vector. | ||
@@ -1007,7 +1007,7 @@ /// | ||
| /// and `DoubleEndedIterator`, since they have known ends. | ||
| impl<E, T> IntoIterator for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> IntoIterator for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Item = bool; | ||
| #[doc(hidden)] | ||
| type IntoIter = IntoIter<E, T>; | ||
| type IntoIter = IntoIter<C, T>; | ||
@@ -1047,4 +1047,4 @@ /// Iterates over the vector. | ||
| /// correctness in arithmetic at this time. | ||
| impl<E, T> Add for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Add for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Output = Self; | ||
@@ -1095,4 +1095,4 @@ | ||
| /// correctness in arithmetic at this time. | ||
| impl<E, T> AddAssign for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> AddAssign for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Adds another `BitVec` into `self`. | ||
@@ -1125,3 +1125,3 @@ /// | ||
| let mut c = false; | ||
| let mut stack = BitVec::<E, T>::with_capacity(self.len()); | ||
| let mut stack = BitVec::<C, T>::with_capacity(self.len()); | ||
| // Reverse self, reverse addend and zero-extend, and zip both together. | ||
@@ -1176,4 +1176,4 @@ // This walks both vecs from rightmost to leftmost, and considers an | ||
| /// other, the extra bits will be ignored. | ||
| impl<E, T, I> BitAnd<I> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| impl<C, T, I> BitAnd<I> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| type Output = Self; | ||
@@ -1201,4 +1201,4 @@ | ||
| /// shorter than `self`, `self` will be truncated when the other stream expires. | ||
| impl<E, T, I> BitAndAssign<I> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| impl<C, T, I> BitAndAssign<I> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| /// `AND`s another bitstream into a vector. | ||
@@ -1230,4 +1230,4 @@ /// | ||
| /// other, the extra bits will be ignored. | ||
| impl<E, T, I> BitOr<I> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| impl<C, T, I> BitOr<I> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| type Output = Self; | ||
@@ -1255,4 +1255,4 @@ | ||
| /// shorter than `self`, `self` will be truncated when the other stream expires. | ||
| impl<E, T, I> BitOrAssign<I> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| impl<C, T, I> BitOrAssign<I> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| /// `OR`s another bitstream into a vector. | ||
@@ -1284,4 +1284,4 @@ /// | ||
| /// other, the extra bits will be ignored. | ||
| impl<E, T, I> BitXor<I> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| impl<C, T, I> BitXor<I> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| type Output = Self; | ||
@@ -1309,4 +1309,4 @@ | ||
| /// shorter than `self`, `self` will be truncated when the other stream expires. | ||
| impl<E, T, I> BitXorAssign<I> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| impl<C, T, I> BitXorAssign<I> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> { | ||
| /// `XOR`s another bitstream into a vector. | ||
@@ -1336,5 +1336,5 @@ /// | ||
| /// This mimics the separation between `Vec<T>` and `[T]`. | ||
| impl<E, T> Deref for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| type Target = crate::BitSlice<E, T>; | ||
| impl<C, T> Deref for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Target = crate::BitSlice<C, T>; | ||
@@ -1361,4 +1361,4 @@ /// Dereferences `&BitVec` down to `&BitSlice`. | ||
| /// This mimics the separation between `Vec<T>` and `[T]`. | ||
| impl<E, T> DerefMut for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> DerefMut for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Dereferences `&mut BitVec` down to `&mut BitSlice`. | ||
@@ -1382,4 +1382,4 @@ /// | ||
| /// Readies the underlying storage for Drop. | ||
| impl<E, T> Drop for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Drop for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Restore the interior `Vec` to sane condition before it drops. | ||
@@ -1397,4 +1397,4 @@ fn drop(&mut self) { | ||
| /// the `BitVec`. | ||
| impl<E, T> Index<usize> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Index<usize> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Output = bool; | ||
@@ -1429,3 +1429,3 @@ | ||
| let (elt, bit) = T::split(cursor); | ||
| if (self.inner[elt]).get(E::curr::<T>(bit)) { &true } else { &false } | ||
| if (self.inner[elt]).get(C::curr::<T>(bit)) { &true } else { &false } | ||
| } | ||
@@ -1445,4 +1445,4 @@ } | ||
| /// This index is not recommended for public use. | ||
| impl<E, T> Index<(usize, u8)> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Index<(usize, u8)> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Output = bool; | ||
@@ -1463,3 +1463,3 @@ | ||
| assert!(T::join(elt, bit) < self.len(), "Index out of range!"); | ||
| if (self.inner[elt]).get(E::curr::<T>(bit)) { &true } else { &false } | ||
| if (self.inner[elt]).get(C::curr::<T>(bit)) { &true } else { &false } | ||
| } | ||
@@ -1478,4 +1478,4 @@ } | ||
| /// correctness in arithmetic at this time. | ||
| impl<E, T> Neg for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Neg for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Output = Self; | ||
@@ -1500,3 +1500,3 @@ | ||
| self = !self; | ||
| self += BitVec::<E, T>::from(&[true] as &[bool]); | ||
| self += BitVec::<C, T>::from(&[true] as &[bool]); | ||
| self | ||
@@ -1513,4 +1513,4 @@ } | ||
| /// rather than a consuming/returning operator. | ||
| impl<E, T> Not for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Not for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Output = Self; | ||
@@ -1568,4 +1568,4 @@ | ||
| /// and zeroes its memory. This is *not* an error. | ||
| impl<E, T> Shl<usize> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Shl<usize> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Output = Self; | ||
@@ -1622,4 +1622,4 @@ | ||
| /// and zeroes its memory. This is *not* an error. | ||
| impl<E, T> ShlAssign<usize> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> ShlAssign<usize> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Shifts a `BitVec` to the left in place, shortening it. | ||
@@ -1691,4 +1691,4 @@ /// | ||
| /// error. | ||
| impl<E, T> Shr<usize> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Shr<usize> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Output = Self; | ||
@@ -1747,4 +1747,4 @@ | ||
| /// error. | ||
| impl<E, T> ShrAssign<usize> for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> ShrAssign<usize> for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Shifts a `BitVec` to the right in place, lengthening it and filling the | ||
@@ -1809,4 +1809,4 @@ /// front with 0. | ||
| /// correctness in arithmetic at this time. | ||
| impl<E, T> Sub for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Sub for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Output = Self; | ||
@@ -1865,4 +1865,4 @@ | ||
| /// correctness in arithmetic at this time. | ||
| impl<E, T> SubAssign for BitVec<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> SubAssign for BitVec<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Subtracts another `BitVec` from `self`. | ||
@@ -1919,5 +1919,5 @@ /// | ||
| #[doc(hidden)] | ||
| pub struct IntoIter<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| bv: BitVec<E, T>, | ||
| pub struct IntoIter<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| bv: BitVec<C, T>, | ||
| head: usize, | ||
@@ -1927,5 +1927,5 @@ tail: usize, | ||
| impl<E, T> IntoIter<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| fn new(bv: BitVec<E, T>) -> Self { | ||
| impl<C, T> IntoIter<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| fn new(bv: BitVec<C, T>) -> Self { | ||
| let tail = bv.len(); | ||
@@ -1945,4 +1945,4 @@ Self { | ||
| impl<E, T> DoubleEndedIterator for IntoIter<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> DoubleEndedIterator for IntoIter<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| /// Yields the back-most bit of the collection. | ||
@@ -1966,4 +1966,4 @@ /// | ||
| impl<E, T> ExactSizeIterator for IntoIter<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> ExactSizeIterator for IntoIter<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| // Override the default implementation with a fixed calculation. The type | ||
@@ -1984,5 +1984,5 @@ // is guaranteed to be well-behaved, so there is no point in building two | ||
| impl<E, T> From<BitVec<E, T>> for IntoIter<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| fn from(bv: BitVec<E, T>) -> Self { | ||
| impl<C, T> From<BitVec<C, T>> for IntoIter<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| fn from(bv: BitVec<C, T>) -> Self { | ||
| Self::new(bv) | ||
@@ -1992,4 +1992,4 @@ } | ||
| impl<E, T> Iterator for IntoIter<E, T> | ||
| where E: crate::Endian, T: crate::Bits { | ||
| impl<C, T> Iterator for IntoIter<C, T> | ||
| where C: crate::Cursor, T: crate::Bits { | ||
| type Item = bool; | ||
@@ -1996,0 +1996,0 @@ |
-34
| # Development Notes | ||
| ## Features | ||
| By default, this crate assumes `std` is present, and links against it. | ||
| `#![no_std]` can be turned on by disabling default features and enabling the | ||
| `alloc` feature, with either the `--features=alloc` Cargo flag or the | ||
| ```toml | ||
| [dependencies.bitvec] | ||
| version = "*" | ||
| default-features = false | ||
| features = ["alloc"] | ||
| ``` | ||
| configuration. | ||
| The `alloc` feature links agains the `alloc` crate, and changes the symbol | ||
| imports needed to retain full functionality even without `std`. | ||
| Disabling the `alloc` feature removes the `BitVec` type, the `bitvec!` macro, | ||
| and all dynamic memory usage. The `BitSlice` type only loses its formatting | ||
| traits. | ||
| The configuration attributes in the source code are arrayed in order of | ||
| increasing functionality. That is, `#[cfg(not(feature = "alloc"))]` is first, | ||
| since it is only true when both `alloc` and `std` features are disabled, then | ||
| `#[cfg(all(feature = "alloc", not(feature = "std")))]` is second, since it is | ||
| true when `alloc` is enabled but `std` is not, and `#[cfg(feature = "std")]` is | ||
| last, since it is true when both `alloc` and `std` are present. | ||
| The `std` feature depends on `alloc`, so it is impossible to have `std` enabled | ||
| but `alloc` disabled. |
-301
| /*! Endianness Markers | ||
| `BitVec` does not have a concept of byte- or element- level endianness, but | ||
| *does* have a concept of bit-level endianness. This module defines orders of | ||
| traversal of an element in the `BitVec` storage. | ||
| !*/ | ||
| use super::bits::Bits; | ||
| /// Travels an element starting at the Most Significant Bit and ending at the | ||
| /// Least Significant Bit. | ||
| pub struct BigEndian; | ||
| /// Travels an element starting at the Least Significant Bit and ending at the | ||
| /// Most Significant Bit. | ||
| pub struct LittleEndian; | ||
| /** A manipulator trait for Endianness. | ||
| # Usage | ||
| `BitVec` stores semantic count, not a cursor into an element, as its `bits` | ||
| value. The methods on `Endian` all return a cursor into a storage element. | ||
| - `curr` computes the bit index of the count given. In Little-Endian order, this | ||
| is the identity function (bit indices count up “left” from LSb), and in | ||
| Big-Endian order, this subtracts the count given from `T::MASK` (bit indices | ||
| count down “right” from MSb). | ||
| - `next` computes the next index forward from the count given. In Little-Endian | ||
| order, this increments (moving up from LSb towards MSb); in Big-Endian order, | ||
| this decrements (moving down from MSb towards LSb). | ||
| - `prev` computes the previous index backward from the count given. In | ||
| Little-Endian order, this decrements (moving down towards LSb from MSb); in | ||
| Big-Endian order, this increments (moving up towards MSb from LSb). | ||
| - `jump` computes a number of whole elements to move, as well as the bit index | ||
| within the destination element of the target bit. | ||
| You should use `curr` to look up a bit at a known point, such as when indexing a | ||
| `BitVec`; you should use `next` or `prev` to implement push, pop, and iteration; | ||
| you should use `jump` only to implement striding iterators in a manner faster | ||
| than the default (which just repeatedly calls `next` and drops most yielded | ||
| values). | ||
| # Notes | ||
| All functions *take* a semantic count into a storage element, which will always | ||
| move upwards from zero, but all functions *return* an actual index to a specific | ||
| bit in the element achieved by shifting right and masking off all but the LSb of | ||
| the output. The output is *not* a semantic count, and does not need converted to | ||
| an index with `curr`. It therefore cannot be stored as the new semantic count | ||
| during a mutation. The caller is responsible for maintaining count status. | ||
| `next` and `prev` signal when they cross the boundary of a storage element. If | ||
| their second return value is true, then the first return value is an index into | ||
| the storage element either after (`next`) or before (`prev`) the element for | ||
| which the input count referred. The caller is responsible for ensuring that they | ||
| use the returned index in the correct storage element by inspecting this flag | ||
| and moving their selection accordingly. | ||
| `jump` returns the number of storage elements the caller will have to move their | ||
| cursor before indexing. `next` and `prev` can only move zero or one elements, so | ||
| their flag is a `bool` rather than an `isize`. The order swap for `jump` is | ||
| because the number of elements to move is expected to be a more significant part | ||
| of its return value than the edge flag is in `next` and `prev`. | ||
| **/ | ||
| pub trait Endian { | ||
| /// Compute the bit index at a given count. | ||
| /// | ||
| /// In Little-Endian, this is a no-op; in Big-Endian, it subtracts the index | ||
| /// from `T::MASK` (the maximum value). | ||
| fn curr<T: Bits>(count: u8) -> u8; | ||
| /// Compute the semantic index that logically follows the given index. | ||
| /// | ||
| /// The first value returned must be passed into `curr` in order to index | ||
| /// into an element. The second value indicates whether the increment points | ||
| /// into a different element. | ||
| fn next<T: Bits>(count: u8) -> (u8, bool) { | ||
| let next = count.wrapping_add(1) & T::MASK; | ||
| let wrap = next == 0; | ||
| (next, wrap) | ||
| } | ||
| /// Compute the semantic index that logically precedes the given index. | ||
| /// | ||
| /// The first value returned must be passed into `curr` in order to index | ||
| /// into an element. The second value indicates whether the decrement points | ||
| /// into a different element. | ||
| fn prev<T: Bits>(count: u8) -> (u8, bool) { | ||
| let (next, wrap) = count.overflowing_sub(1); | ||
| (next & T::MASK, wrap) | ||
| } | ||
| /// Computes the bit index at a given semantic offset from the current | ||
| /// cursor. | ||
| /// | ||
| /// Returns a tuple where the first value is the number of whole storage | ||
| /// elements to move, and the second is the bit index within the element. | ||
| fn jump<T: Bits>(count: u8, offset: isize) -> (isize, u8) { | ||
| 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 | ||
| // math doesn't know how to move around in an ordering. The offset is | ||
| // signed in count order, not Endian order. | ||
| // Subtraction can never fail, because count is always >= 0 and | ||
| // `0 - isize::MIN` is `isize::MIN`, which does not overflow. | ||
| // In a non-overflowing addition, the result will be the position of | ||
| // the target bit | ||
| match (count as isize).overflowing_add(offset) { | ||
| // If the addition overflows, then the offset is positive. Add as | ||
| // 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. | ||
| (_, 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 | ||
| // the elements, which even more conveniently, is equivalent to | ||
| // right-shift by the number of bits required to index an | ||
| // element. Note that we don't cast until *after* the shift, in | ||
| // order to ensure that it is zero-filled at the high bits. | ||
| let elements = (far >> T::BITS) as isize; | ||
| // The new bit position of the cursor is the new position | ||
| // modulo the number of bits in the element (equivalent to | ||
| // bit-and of the provided mask). | ||
| let pos = (far & (T::MASK as usize)) as u8; | ||
| (elements, pos) | ||
| }, | ||
| // 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 => { | ||
| let elements = far >> T::BITS; | ||
| let pos = (far & (T::MASK as isize)) as u8; | ||
| (elements, Self::curr::<T>(pos)) | ||
| }, | ||
| // Otherwise, `far` is the *bit count* in the current element. It | ||
| // must still be converted from count to bit index. | ||
| (far, _) => { | ||
| (0, Self::curr::<T>(far as u8)) | ||
| }, | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| const TY: &'static str = ""; | ||
| } | ||
| impl Endian for BigEndian { | ||
| fn curr<T: Bits>(count: u8) -> u8 { | ||
| assert!(count < T::WIDTH, "Index out of range of the storage type"); | ||
| T::MASK - count | ||
| } | ||
| const TY: &'static str = "BigEndian"; | ||
| } | ||
| impl Endian for LittleEndian { | ||
| fn curr<T: Bits>(count: u8) -> u8 { | ||
| assert!(count < T::WIDTH, "Index out of range of the storage type"); | ||
| count | ||
| } | ||
| const TY: &'static str = "LittleEndian"; | ||
| } | ||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| #[test] | ||
| fn incr_edge() { | ||
| 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)); | ||
| } | ||
| #[test] | ||
| fn decr_edge() { | ||
| 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)); | ||
| } | ||
| #[test] | ||
| fn jump_inside_elt() { | ||
| // TODO(myrrlyn): test the other two types. | ||
| let (elt, bit) = LittleEndian::jump::<u8>(5, 2); | ||
| assert_eq!(elt, 0); | ||
| assert_eq!(bit, 7); | ||
| // Counts start from 0, so count 5 is the SIXTH bit | ||
| let (elt, bit) = BigEndian::jump::<u8>(5, 2); | ||
| assert_eq!(elt, 0); | ||
| assert_eq!(bit, 0); | ||
| let (elt, bit) = LittleEndian::jump::<u32>(20, 8); | ||
| assert_eq!(elt, 0); | ||
| assert_eq!(bit, 28); | ||
| // In Big-Endian order, count 20 is bit 11, and moving that backward by | ||
| // 8 is addition, up to 19. | ||
| let (elt, bit) = BigEndian::jump::<u32>(20, -8); | ||
| assert_eq!(elt, 0); | ||
| assert_eq!(bit, 19); | ||
| } | ||
| #[test] | ||
| fn jump_backwards() { | ||
| // TODO(myrrlyn): Test the other three types. | ||
| let (elt, bit) = LittleEndian::jump::<u32>(10, -15); | ||
| assert_eq!(elt, -1); | ||
| // Moving backwards through LE starts at MSb and decrements | ||
| // 10 - 10 is 0, 0 - 1 is 31, 31 - 4 is 27 | ||
| assert_eq!(bit, 27); | ||
| let (elt, bit) = BigEndian::jump::<u32>(10, -15); | ||
| assert_eq!(elt, -1); | ||
| // Moving backwards through BE starts at LSb and increments | ||
| // 10 - 10 is count 0 (bit 31), then the cursor crosses the boundary | ||
| // and counts 0, 1, 2, 3, 4. | ||
| assert_eq!(bit, 4); | ||
| } | ||
| #[test] | ||
| fn jump_forwards() { | ||
| // TODO(myrrlyn): Test the other three types. | ||
| let (elt, bit) = LittleEndian::jump::<u32>(25, 10); | ||
| assert_eq!(elt, 1); | ||
| assert_eq!(bit, 3); | ||
| let (elt, bit) = BigEndian::jump::<u32>(25, 10); | ||
| assert_eq!(elt, 1); | ||
| // Moving forwards through BE starts at MSb and decrements. 25 + 6 is | ||
| // count 31 (bit 0), then the cursor crosses the boundary and counts | ||
| // 31, 30, 29, 28. | ||
| assert_eq!(bit, 28); | ||
| } | ||
| #[test] | ||
| fn jump_overflow() { | ||
| // 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). | ||
| let start = 20; | ||
| let (elt, bit) = LittleEndian::jump::<u32>(start, core::isize::MAX); | ||
| assert_eq!(elt as usize, core::isize::MIN as usize >> u32::BITS); | ||
| assert_eq!(bit, start - 1); | ||
| let (elt, bit) = BigEndian::jump::<u32>(start, core::isize::MAX); | ||
| assert_eq!(elt as usize, core::isize::MIN as usize >> u32::BITS); | ||
| assert_eq!(bit, BigEndian::curr::<u32>(start) - 1); | ||
| } | ||
| #[test] | ||
| fn curr_reversible() { | ||
| for n in 0 .. 8 { | ||
| assert_eq!(n, BigEndian::curr::<u8>(BigEndian::curr::<u8>(n))); | ||
| } | ||
| for n in 0 .. 16 { | ||
| assert_eq!(n, BigEndian::curr::<u16>(BigEndian::curr::<u16>(n))); | ||
| } | ||
| for n in 0 .. 32 { | ||
| assert_eq!(n, BigEndian::curr::<u32>(BigEndian::curr::<u32>(n))); | ||
| } | ||
| for n in 0 .. 64 { | ||
| assert_eq!(n, BigEndian::curr::<u64>(BigEndian::curr::<u64>(n))); | ||
| } | ||
| 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))); | ||
| } | ||
| } | ||
| } |
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