| #![doc = include_str!("../../doc/slice/api.md")] |
| |
| use core::{ |
| cmp, |
| ops::{ |
| Range, |
| RangeFrom, |
| RangeFull, |
| RangeInclusive, |
| RangeTo, |
| RangeToInclusive, |
| }, |
| }; |
| |
| use wyz::{ |
| comu::{ |
| Const, |
| Mut, |
| }, |
| range::RangeExt, |
| }; |
| |
| use super::{ |
| BitSlice, |
| Chunks, |
| ChunksExact, |
| ChunksExactMut, |
| ChunksMut, |
| Iter, |
| IterMut, |
| RChunks, |
| RChunksExact, |
| RChunksExactMut, |
| RChunksMut, |
| RSplit, |
| RSplitMut, |
| RSplitN, |
| RSplitNMut, |
| Split, |
| SplitInclusive, |
| SplitInclusiveMut, |
| SplitMut, |
| SplitN, |
| SplitNMut, |
| Windows, |
| }; |
| #[cfg(feature = "alloc")] |
| use crate::vec::BitVec; |
| use crate::{ |
| array::BitArray, |
| domain::Domain, |
| mem::{ |
| self, |
| BitRegister, |
| }, |
| order::BitOrder, |
| ptr::{ |
| BitPtr, |
| BitRef, |
| BitSpan, |
| BitSpanError, |
| }, |
| store::BitStore, |
| }; |
| |
| /// Port of the `[T]` inherent API. |
| impl<T, O> BitSlice<T, O> |
| where |
| T: BitStore, |
| O: BitOrder, |
| { |
| /// Gets the number of bits in the bit-slice. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::len`](https://doc.rust-lang.org/std/primitive.slice.html#method.len) |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// assert_eq!(bits![].len(), 0); |
| /// assert_eq!(bits![0; 10].len(), 10); |
| /// ``` |
| #[inline] |
| pub fn len(&self) -> usize { |
| self.as_bitspan().len() |
| } |
| |
| /// Tests if the bit-slice is empty (length zero). |
| /// |
| /// ## Original |
| /// |
| /// [`slice::is_empty`](https://doc.rust-lang.org/std/primitive.slice.html#method.is_empty) |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// assert!(bits![].is_empty()); |
| /// assert!(!bits![0; 10].is_empty()); |
| /// ``` |
| #[inline] |
| pub fn is_empty(&self) -> bool { |
| self.len() == 0 |
| } |
| |
| /// Gets a reference to the first bit of the bit-slice, or `None` if it is |
| /// empty. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::first`](https://doc.rust-lang.org/std/primitive.slice.html#method.first) |
| /// |
| /// ## API Differences |
| /// |
| /// `bitvec` uses a custom structure for both read-only and mutable |
| /// references to `bool`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![1, 0, 0]; |
| /// assert_eq!(bits.first().as_deref(), Some(&true)); |
| /// |
| /// assert!(bits![].first().is_none()); |
| /// ``` |
| #[inline] |
| pub fn first(&self) -> Option<BitRef<Const, T, O>> { |
| self.get(0) |
| } |
| |
| /// Gets a mutable reference to the first bit of the bit-slice, or `None` if |
| /// it is empty. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::first_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.first_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// `bitvec` uses a custom structure for both read-only and mutable |
| /// references to `bool`. This must be bound as `mut` in order to write |
| /// through it. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0; 3]; |
| /// if let Some(mut first) = bits.first_mut() { |
| /// *first = true; |
| /// } |
| /// assert_eq!(bits, bits![1, 0, 0]); |
| /// |
| /// assert!(bits![mut].first_mut().is_none()); |
| /// ``` |
| #[inline] |
| pub fn first_mut(&mut self) -> Option<BitRef<Mut, T, O>> { |
| self.get_mut(0) |
| } |
| |
| /// Splits the bit-slice into a reference to its first bit, and the rest of |
| /// the bit-slice. Returns `None` when empty. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split_first`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_first) |
| /// |
| /// ## API Differences |
| /// |
| /// `bitvec` uses a custom structure for both read-only and mutable |
| /// references to `bool`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![1, 0, 0]; |
| /// let (first, rest) = bits.split_first().unwrap(); |
| /// assert_eq!(first, &true); |
| /// assert_eq!(rest, bits![0; 2]); |
| /// ``` |
| #[inline] |
| pub fn split_first(&self) -> Option<(BitRef<Const, T, O>, &Self)> { |
| match self.len() { |
| 0 => None, |
| _ => unsafe { |
| let (head, rest) = self.split_at_unchecked(1); |
| Some((head.get_unchecked(0), rest)) |
| }, |
| } |
| } |
| |
| /// Splits the bit-slice into mutable references of its first bit, and the |
| /// rest of the bit-slice. Returns `None` when empty. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split_first_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_first_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// `bitvec` uses a custom structure for both read-only and mutable |
| /// references to `bool`. This must be bound as `mut` in order to write |
| /// through it. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0; 3]; |
| /// if let Some((mut first, rest)) = bits.split_first_mut() { |
| /// *first = true; |
| /// assert_eq!(rest, bits![0; 2]); |
| /// } |
| /// assert_eq!(bits, bits![1, 0, 0]); |
| /// ``` |
| #[inline] |
| pub fn split_first_mut( |
| &mut self, |
| ) -> Option<(BitRef<Mut, T::Alias, O>, &mut BitSlice<T::Alias, O>)> { |
| match self.len() { |
| 0 => None, |
| _ => unsafe { |
| let (head, rest) = self.split_at_unchecked_mut(1); |
| Some((head.get_unchecked_mut(0), rest)) |
| }, |
| } |
| } |
| |
| /// Splits the bit-slice into a reference to its last bit, and the rest of |
| /// the bit-slice. Returns `None` when empty. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split_last`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_last) |
| /// |
| /// ## API Differences |
| /// |
| /// `bitvec` uses a custom structure for both read-only and mutable |
| /// references to `bool`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 0, 1]; |
| /// let (last, rest) = bits.split_last().unwrap(); |
| /// assert_eq!(last, &true); |
| /// assert_eq!(rest, bits![0; 2]); |
| /// ``` |
| #[inline] |
| pub fn split_last(&self) -> Option<(BitRef<Const, T, O>, &Self)> { |
| match self.len() { |
| 0 => None, |
| n => unsafe { |
| let (rest, tail) = self.split_at_unchecked(n - 1); |
| Some((tail.get_unchecked(0), rest)) |
| }, |
| } |
| } |
| |
| /// Splits the bit-slice into mutable references to its last bit, and the |
| /// rest of the bit-slice. Returns `None` when empty. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split_last_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_last_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// `bitvec` uses a custom structure for both read-only and mutable |
| /// references to `bool`. This must be bound as `mut` in order to write |
| /// through it. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0; 3]; |
| /// if let Some((mut last, rest)) = bits.split_last_mut() { |
| /// *last = true; |
| /// assert_eq!(rest, bits![0; 2]); |
| /// } |
| /// assert_eq!(bits, bits![0, 0, 1]); |
| /// ``` |
| #[inline] |
| pub fn split_last_mut( |
| &mut self, |
| ) -> Option<(BitRef<Mut, T::Alias, O>, &mut BitSlice<T::Alias, O>)> { |
| match self.len() { |
| 0 => None, |
| n => unsafe { |
| let (rest, tail) = self.split_at_unchecked_mut(n - 1); |
| Some((tail.get_unchecked_mut(0), rest)) |
| }, |
| } |
| } |
| |
| /// Gets a reference to the last bit of the bit-slice, or `None` if it is |
| /// empty. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::last`](https://doc.rust-lang.org/std/primitive.slice.html#method.last) |
| /// |
| /// ## API Differences |
| /// |
| /// `bitvec` uses a custom structure for both read-only and mutable |
| /// references to `bool`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 0, 1]; |
| /// assert_eq!(bits.last().as_deref(), Some(&true)); |
| /// |
| /// assert!(bits![].last().is_none()); |
| /// ``` |
| #[inline] |
| pub fn last(&self) -> Option<BitRef<Const, T, O>> { |
| match self.len() { |
| 0 => None, |
| n => Some(unsafe { self.get_unchecked(n - 1) }), |
| } |
| } |
| |
| /// Gets a mutable reference to the last bit of the bit-slice, or `None` if |
| /// it is empty. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::last_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.last_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// `bitvec` uses a custom structure for both read-only and mutable |
| /// references to `bool`. This must be bound as `mut` in order to write |
| /// through it. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0; 3]; |
| /// if let Some(mut last) = bits.last_mut() { |
| /// *last = true; |
| /// } |
| /// assert_eq!(bits, bits![0, 0, 1]); |
| /// |
| /// assert!(bits![mut].last_mut().is_none()); |
| /// ``` |
| #[inline] |
| pub fn last_mut(&mut self) -> Option<BitRef<Mut, T, O>> { |
| match self.len() { |
| 0 => None, |
| n => Some(unsafe { self.get_unchecked_mut(n - 1) }), |
| } |
| } |
| |
| /// Gets a reference to a single bit or a subsection of the bit-slice, |
| /// depending on the type of `index`. |
| /// |
| /// - If given a `usize`, this produces a reference structure to the `bool` |
| /// at the position. |
| /// - If given any form of range, this produces a smaller bit-slice. |
| /// |
| /// This returns `None` if the `index` departs the bounds of `self`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::get`](https://doc.rust-lang.org/std/primitive.slice.html#method.get) |
| /// |
| /// ## API Differences |
| /// |
| /// `BitSliceIndex` uses discrete types for immutable and mutable |
| /// references, rather than a single referent type. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0]; |
| /// assert_eq!(bits.get(1).as_deref(), Some(&true)); |
| /// assert_eq!(bits.get(0 .. 2), Some(bits![0, 1])); |
| /// assert!(bits.get(3).is_none()); |
| /// assert!(bits.get(0 .. 4).is_none()); |
| /// ``` |
| #[inline] |
| pub fn get<'a, I>(&'a self, index: I) -> Option<I::Immut> |
| where I: BitSliceIndex<'a, T, O> { |
| index.get(self) |
| } |
| |
| /// Gets a mutable reference to a single bit or a subsection of the |
| /// bit-slice, depending on the type of `index`. |
| /// |
| /// - If given a `usize`, this produces a reference structure to the `bool` |
| /// at the position. |
| /// - If given any form of range, this produces a smaller bit-slice. |
| /// |
| /// This returns `None` if the `index` departs the bounds of `self`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::get_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.get_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// `BitSliceIndex` uses discrete types for immutable and mutable |
| /// references, rather than a single referent type. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0; 3]; |
| /// |
| /// *bits.get_mut(0).unwrap() = true; |
| /// bits.get_mut(1 ..).unwrap().fill(true); |
| /// assert_eq!(bits, bits![1; 3]); |
| /// ``` |
| #[inline] |
| pub fn get_mut<'a, I>(&'a mut self, index: I) -> Option<I::Mut> |
| where I: BitSliceIndex<'a, T, O> { |
| index.get_mut(self) |
| } |
| |
| /// Gets a reference to a single bit or to a subsection of the bit-slice, |
| /// without bounds checking. |
| /// |
| /// This has the same arguments and behavior as [`.get()`], except that it |
| /// does not check that `index` is in bounds. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::get_unchecked`](https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked) |
| /// |
| /// ## Safety |
| /// |
| /// You must ensure that `index` is within bounds (within the range `0 .. |
| /// self.len()`), or this method will introduce memory safety and/or |
| /// undefined behavior. |
| /// |
| /// It is library-level undefined behavior to index beyond the length of any |
| /// bit-slice, even if you **know** that the offset remains within an |
| /// allocation as measured by Rust or LLVM. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let data = 0b0001_0010u8; |
| /// let bits = &data.view_bits::<Lsb0>()[.. 3]; |
| /// |
| /// unsafe { |
| /// assert!(bits.get_unchecked(1)); |
| /// assert!(bits.get_unchecked(4)); |
| /// } |
| /// ``` |
| /// |
| /// [`.get()`]: Self::get |
| #[inline] |
| pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Immut |
| where I: BitSliceIndex<'a, T, O> { |
| index.get_unchecked(self) |
| } |
| |
| /// Gets a mutable reference to a single bit or a subsection of the |
| /// bit-slice, depending on the type of `index`. |
| /// |
| /// This has the same arguments and behavior as [`.get_mut()`], except that |
| /// it does not check that `index` is in bounds. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::get_unchecked_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked_mut) |
| /// |
| /// ## Safety |
| /// |
| /// You must ensure that `index` is within bounds (within the range `0 .. |
| /// self.len()`), or this method will introduce memory safety and/or |
| /// undefined behavior. |
| /// |
| /// It is library-level undefined behavior to index beyond the length of any |
| /// bit-slice, even if you **know** that the offset remains within an |
| /// allocation as measured by Rust or LLVM. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let mut data = 0u8; |
| /// let bits = &mut data.view_bits_mut::<Lsb0>()[.. 3]; |
| /// |
| /// unsafe { |
| /// bits.get_unchecked_mut(1).commit(true); |
| /// bits.get_unchecked_mut(4 .. 6).fill(true); |
| /// } |
| /// assert_eq!(data, 0b0011_0010); |
| /// ``` |
| /// |
| /// [`.get_mut()`]: Self::get_mut |
| #[inline] |
| pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::Mut |
| where I: BitSliceIndex<'a, T, O> { |
| index.get_unchecked_mut(self) |
| } |
| |
| #[inline] |
| #[cfg(not(tarpaulin_include))] |
| #[deprecated = "use `.as_bitptr()` instead"] |
| #[allow(missing_docs, clippy::missing_docs_in_private_items)] |
| pub fn as_ptr(&self) -> BitPtr<Const, T, O> { |
| self.as_bitptr() |
| } |
| |
| #[inline] |
| #[cfg(not(tarpaulin_include))] |
| #[deprecated = "use `.as_mut_bitptr()` instead"] |
| #[allow(missing_docs, clippy::missing_docs_in_private_items)] |
| pub fn as_mut_ptr(&mut self) -> BitPtr<Mut, T, O> { |
| self.as_mut_bitptr() |
| } |
| |
| /// Produces a range of bit-pointers to each bit in the bit-slice. |
| /// |
| /// This is a standard-library range, which has no real functionality for |
| /// pointer types. You should prefer [`.as_bitptr_range()`] instead, as it |
| /// produces a custom structure that provides expected ranging |
| /// functionality. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::as_ptr_range`](https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr_range) |
| /// |
| /// [`.as_bitptr_range()`]: Self::as_bitptr_range |
| #[inline] |
| #[cfg(not(tarpaulin_include))] |
| pub fn as_ptr_range(&self) -> Range<BitPtr<Const, T, O>> { |
| self.as_bitptr_range().into_range() |
| } |
| |
| /// Produces a range of mutable bit-pointers to each bit in the bit-slice. |
| /// |
| /// This is a standard-library range, which has no real functionality for |
| /// pointer types. You should prefer [`.as_mut_bitptr_range()`] instead, as |
| /// it produces a custom structure that provides expected ranging |
| /// functionality. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::as_mut_ptr_range`](https://doc.rust-lang.org/std/primitive.slice.html#method.as_mut_ptr_range) |
| /// |
| /// [`.as_mut_bitptr_range()`]: Self::as_mut_bitptr_range |
| #[inline] |
| #[cfg(not(tarpaulin_include))] |
| pub fn as_mut_ptr_range(&mut self) -> Range<BitPtr<Mut, T, O>> { |
| self.as_mut_bitptr_range().into_range() |
| } |
| |
| /// Exchanges the bit values at two indices. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::swap`](https://doc.rust-lang.org/std/primitive.slice.html#method.swap) |
| /// |
| /// ## Panics |
| /// |
| /// This panics if either `a` or `b` are out of bounds. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0, 1]; |
| /// bits.swap(0, 1); |
| /// assert_eq!(bits, bits![1, 0]); |
| /// ``` |
| #[inline] |
| pub fn swap(&mut self, a: usize, b: usize) { |
| let bounds = 0 .. self.len(); |
| self.assert_in_bounds(a, bounds.clone()); |
| self.assert_in_bounds(b, bounds); |
| unsafe { |
| self.swap_unchecked(a, b); |
| } |
| } |
| |
| /// Reverses the order of bits in a bit-slice. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::reverse`](https://doc.rust-lang.org/std/primitive.slice.html#method.reverse) |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0, 0, 1, 0, 1, 1, 0, 0, 1]; |
| /// bits.reverse(); |
| /// assert_eq!(bits, bits![1, 0, 0, 1, 1, 0, 1, 0, 0]); |
| /// ``` |
| #[inline] |
| pub fn reverse(&mut self) { |
| let mut iter = self.as_mut_bitptr_range(); |
| while let (Some(a), Some(b)) = (iter.next(), iter.next_back()) { |
| unsafe { |
| crate::ptr::swap(a, b); |
| } |
| } |
| } |
| |
| /// Produces an iterator over each bit in the bit-slice. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::iter`](https://doc.rust-lang.org/std/primitive.slice.html#method.iter) |
| /// |
| /// ## API Differences |
| /// |
| /// This iterator yields proxy-reference structures, not `&bool`. It can be |
| /// adapted to yield `&bool` with the [`.by_refs()`] method, or `bool` with |
| /// [`.by_vals()`]. |
| /// |
| /// This iterator, and its adapters, are fast. Do not try to be more clever |
| /// than them by abusing `.as_bitptr_range()`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0, 1]; |
| /// let mut iter = bits.iter(); |
| /// |
| /// assert!(!iter.next().unwrap()); |
| /// assert!( iter.next().unwrap()); |
| /// assert!( iter.next_back().unwrap()); |
| /// assert!(!iter.next_back().unwrap()); |
| /// assert!( iter.next().is_none()); |
| /// ``` |
| /// |
| /// [`.by_refs()`]: crate::slice::Iter::by_refs |
| /// [`.by_vals()`]: crate::slice::Iter::by_vals |
| #[inline] |
| pub fn iter(&self) -> Iter<T, O> { |
| Iter::new(self) |
| } |
| |
| /// Produces a mutable iterator over each bit in the bit-slice. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::iter_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.iter_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// This iterator yields proxy-reference structures, not `&mut bool`. In |
| /// addition, it marks each proxy as alias-tainted. |
| /// |
| /// If you are using this in an ordinary loop and **not** keeping multiple |
| /// yielded proxy-references alive at the same scope, you may use the |
| /// [`.remove_alias()`] adapter to undo the alias marking. |
| /// |
| /// This iterator is fast. Do not try to be more clever than it by abusing |
| /// `.as_mut_bitptr_range()`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0; 4]; |
| /// let mut iter = bits.iter_mut(); |
| /// |
| /// iter.nth(1).unwrap().commit(true); // index 1 |
| /// iter.next_back().unwrap().commit(true); // index 3 |
| /// |
| /// assert!(iter.next().is_some()); // index 2 |
| /// assert!(iter.next().is_none()); // complete |
| /// assert_eq!(bits, bits![0, 1, 0, 1]); |
| /// ``` |
| /// |
| /// [`.remove_alias()`]: crate::slice::IterMut::remove_alias |
| #[inline] |
| pub fn iter_mut(&mut self) -> IterMut<T, O> { |
| IterMut::new(self) |
| } |
| |
| /// Iterates over consecutive windowing subslices in a bit-slice. |
| /// |
| /// Windows are overlapping views of the bit-slice. Each window advances one |
| /// bit from the previous, so in a bit-slice `[A, B, C, D, E]`, calling |
| /// `.windows(3)` will yield `[A, B, C]`, `[B, C, D]`, and `[C, D, E]`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::windows`](https://doc.rust-lang.org/std/primitive.slice.html#method.windows) |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `size` is `0`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0, 0, 1]; |
| /// let mut iter = bits.windows(3); |
| /// |
| /// assert_eq!(iter.next(), Some(bits![0, 1, 0])); |
| /// assert_eq!(iter.next(), Some(bits![1, 0, 0])); |
| /// assert_eq!(iter.next(), Some(bits![0, 0, 1])); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| #[inline] |
| pub fn windows(&self, size: usize) -> Windows<T, O> { |
| Windows::new(self, size) |
| } |
| |
| /// Iterates over non-overlapping subslices of a bit-slice. |
| /// |
| /// Unlike `.windows()`, the subslices this yields do not overlap with each |
| /// other. If `self.len()` is not an even multiple of `chunk_size`, then the |
| /// last chunk yielded will be shorter. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::chunks`](https://doc.rust-lang.org/std/primitive.slice.html#method.chunks) |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.chunks_mut()`] has the same division logic, but each yielded |
| /// bit-slice is mutable. |
| /// - [`.chunks_exact()`] does not yield the final chunk if it is shorter |
| /// than `chunk_size`. |
| /// - [`.rchunks()`] iterates from the back of the bit-slice to the front, |
| /// with the final, possibly-shorter, segment at the front edge. |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `chunk_size` is `0`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0, 0, 1]; |
| /// let mut iter = bits.chunks(2); |
| /// |
| /// assert_eq!(iter.next(), Some(bits![0, 1])); |
| /// assert_eq!(iter.next(), Some(bits![0, 0])); |
| /// assert_eq!(iter.next(), Some(bits![1])); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// [`.chunks_exact()`]: Self::chunks_exact |
| /// [`.chunks_mut()`]: Self::chunks_mut |
| /// [`.rchunks()`]: Self::rchunks |
| #[inline] |
| pub fn chunks(&self, chunk_size: usize) -> Chunks<T, O> { |
| Chunks::new(self, chunk_size) |
| } |
| |
| /// Iterates over non-overlapping mutable subslices of a bit-slice. |
| /// |
| /// Iterators do not require that each yielded item is destroyed before the |
| /// next is produced. This means that each bit-slice yielded must be marked |
| /// as aliased. If you are using this in a loop that does not collect |
| /// multiple yielded subslices for the same scope, then you can remove the |
| /// alias marking by calling the (`unsafe`) method [`.remove_alias()`] on |
| /// the iterator. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::chunks_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_mut) |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.chunks()`] has the same division logic, but each yielded bit-slice |
| /// is immutable. |
| /// - [`.chunks_exact_mut()`] does not yield the final chunk if it is |
| /// shorter than `chunk_size`. |
| /// - [`.rchunks_mut()`] iterates from the back of the bit-slice to the |
| /// front, with the final, possibly-shorter, segment at the front edge. |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `chunk_size` is `0`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut u8, Msb0; 0; 5]; |
| /// |
| /// for (idx, chunk) in unsafe { |
| /// bits.chunks_mut(2).remove_alias() |
| /// }.enumerate() { |
| /// chunk.store(idx + 1); |
| /// } |
| /// assert_eq!(bits, bits![0, 1, 1, 0, 1]); |
| /// // ^^^^ ^^^^ ^ |
| /// ``` |
| /// |
| /// [`.chunks()`]: Self::chunks |
| /// [`.chunks_exact_mut()`]: Self::chunks_exact_mut |
| /// [`.rchunks_mut()`]: Self::rchunks_mut |
| /// [`.remove_alias()`]: crate::slice::ChunksMut::remove_alias |
| #[inline] |
| pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T, O> { |
| ChunksMut::new(self, chunk_size) |
| } |
| |
| /// Iterates over non-overlapping subslices of a bit-slice. |
| /// |
| /// If `self.len()` is not an even multiple of `chunk_size`, then the last |
| /// few bits are not yielded by the iterator at all. They can be accessed |
| /// with the [`.remainder()`] method if the iterator is bound to a name. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::chunks_exact`](https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_exact) |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.chunks()`] yields any leftover bits at the end as a shorter chunk |
| /// during iteration. |
| /// - [`.chunks_exact_mut()`] has the same division logic, but each yielded |
| /// bit-slice is mutable. |
| /// - [`.rchunks_exact()`] iterates from the back of the bit-slice to the |
| /// front, with the unyielded remainder segment at the front edge. |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `chunk_size` is `0`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0, 0, 1]; |
| /// let mut iter = bits.chunks_exact(2); |
| /// |
| /// assert_eq!(iter.next(), Some(bits![0, 1])); |
| /// assert_eq!(iter.next(), Some(bits![0, 0])); |
| /// assert!(iter.next().is_none()); |
| /// assert_eq!(iter.remainder(), bits![1]); |
| /// ``` |
| /// |
| /// [`.chunks()`]: Self::chunks |
| /// [`.chunks_exact_mut()`]: Self::chunks_exact_mut |
| /// [`.rchunks_exact()`]: Self::rchunks_exact |
| /// [`.remainder()`]: crate::slice::ChunksExact::remainder |
| #[inline] |
| pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<T, O> { |
| ChunksExact::new(self, chunk_size) |
| } |
| |
| /// Iterates over non-overlapping mutable subslices of a bit-slice. |
| /// |
| /// If `self.len()` is not an even multiple of `chunk_size`, then the last |
| /// few bits are not yielded by the iterator at all. They can be accessed |
| /// with the [`.into_remainder()`] method if the iterator is bound to a |
| /// name. |
| /// |
| /// Iterators do not require that each yielded item is destroyed before the |
| /// next is produced. This means that each bit-slice yielded must be marked |
| /// as aliased. If you are using this in a loop that does not collect |
| /// multiple yielded subslices for the same scope, then you can remove the |
| /// alias marking by calling the (`unsafe`) method [`.remove_alias()`] on |
| /// the iterator. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::chunks_exact_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_exact_mut) |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.chunks_mut()`] yields any leftover bits at the end as a shorter |
| /// chunk during iteration. |
| /// - [`.chunks_exact()`] has the same division logic, but each yielded |
| /// bit-slice is immutable. |
| /// - [`.rchunks_exact_mut()`] iterates from the back of the bit-slice |
| /// forwards, with the unyielded remainder segment at the front edge. |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `chunk_size` is `0`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut u8, Msb0; 0; 5]; |
| /// let mut iter = bits.chunks_exact_mut(2); |
| /// |
| /// for (idx, chunk) in iter.by_ref().enumerate() { |
| /// chunk.store(idx + 1); |
| /// } |
| /// iter.into_remainder().store(1u8); |
| /// |
| /// assert_eq!(bits, bits![0, 1, 1, 0, 1]); |
| /// // remainder ^ |
| /// ``` |
| /// |
| /// [`.chunks_exact()`]: Self::chunks_exact |
| /// [`.chunks_mut()`]: Self::chunks_mut |
| /// [`.into_remainder()`]: crate::slice::ChunksExactMut::into_remainder |
| /// [`.rchunks_exact_mut()`]: Self::rchunks_exact_mut |
| /// [`.remove_alias()`]: crate::slice::ChunksExactMut::remove_alias |
| #[inline] |
| pub fn chunks_exact_mut( |
| &mut self, |
| chunk_size: usize, |
| ) -> ChunksExactMut<T, O> { |
| ChunksExactMut::new(self, chunk_size) |
| } |
| |
| /// Iterates over non-overlapping subslices of a bit-slice, from the back |
| /// edge. |
| /// |
| /// Unlike `.chunks()`, this aligns its chunks to the back edge of `self`. |
| /// If `self.len()` is not an even multiple of `chunk_size`, then the |
| /// leftover partial chunk is `self[0 .. len % chunk_size]`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::rchunks`](https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks) |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.rchunks_mut()`] has the same division logic, but each yielded |
| /// bit-slice is mutable. |
| /// - [`.rchunks_exact()`] does not yield the final chunk if it is shorter |
| /// than `chunk_size`. |
| /// - [`.chunks()`] iterates from the front of the bit-slice to the back, |
| /// with the final, possibly-shorter, segment at the back edge. |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `chunk_size` is `0`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0, 0, 1]; |
| /// let mut iter = bits.rchunks(2); |
| /// |
| /// assert_eq!(iter.next(), Some(bits![0, 1])); |
| /// assert_eq!(iter.next(), Some(bits![1, 0])); |
| /// assert_eq!(iter.next(), Some(bits![0])); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// [`.chunks()`]: Self::chunks |
| /// [`.rchunks_exact()`]: Self::rchunks_exact |
| /// [`.rchunks_mut()`]: Self::rchunks_mut |
| #[inline] |
| pub fn rchunks(&self, chunk_size: usize) -> RChunks<T, O> { |
| RChunks::new(self, chunk_size) |
| } |
| |
| /// Iterates over non-overlapping mutable subslices of a bit-slice, from the |
| /// back edge. |
| /// |
| /// Unlike `.chunks_mut()`, this aligns its chunks to the back edge of |
| /// `self`. If `self.len()` is not an even multiple of `chunk_size`, then |
| /// the leftover partial chunk is `self[0 .. len % chunk_size]`. |
| /// |
| /// Iterators do not require that each yielded item is destroyed before the |
| /// next is produced. This means that each bit-slice yielded must be marked |
| /// as aliased. If you are using this in a loop that does not collect |
| /// multiple yielded values for the same scope, then you can remove the |
| /// alias marking by calling the (`unsafe`) method [`.remove_alias()`] on |
| /// the iterator. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::rchunks_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_mut) |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.rchunks()`] has the same division logic, but each yielded bit-slice |
| /// is immutable. |
| /// - [`.rchunks_exact_mut()`] does not yield the final chunk if it is |
| /// shorter than `chunk_size`. |
| /// - [`.chunks_mut()`] iterates from the front of the bit-slice to the |
| /// back, with the final, possibly-shorter, segment at the back edge. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut u8, Msb0; 0; 5]; |
| /// for (idx, chunk) in unsafe { |
| /// bits.rchunks_mut(2).remove_alias() |
| /// }.enumerate() { |
| /// chunk.store(idx + 1); |
| /// } |
| /// assert_eq!(bits, bits![1, 1, 0, 0, 1]); |
| /// // remainder ^ ^^^^ ^^^^ |
| /// ``` |
| /// |
| /// [`.chunks_mut()`]: Self::chunks_mut |
| /// [`.rchunks()`]: Self::rchunks |
| /// [`.rchunks_exact_mut()`]: Self::rchunks_exact_mut |
| /// [`.remove_alias()`]: crate::slice::RChunksMut::remove_alias |
| #[inline] |
| pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<T, O> { |
| RChunksMut::new(self, chunk_size) |
| } |
| |
| /// Iterates over non-overlapping subslices of a bit-slice, from the back |
| /// edge. |
| /// |
| /// If `self.len()` is not an even multiple of `chunk_size`, then the first |
| /// few bits are not yielded by the iterator at all. They can be accessed |
| /// with the [`.remainder()`] method if the iterator is bound to a name. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::rchunks_exact`](https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_exact) |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.rchunks()`] yields any leftover bits at the front as a shorter |
| /// chunk during iteration. |
| /// - [`.rchunks_exact_mut()`] has the same division logic, but each yielded |
| /// bit-slice is mutable. |
| /// - [`.chunks_exact()`] iterates from the front of the bit-slice to the |
| /// back, with the unyielded remainder segment at the back edge. |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `chunk_size` is `0`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0, 0, 1]; |
| /// let mut iter = bits.rchunks_exact(2); |
| /// |
| /// assert_eq!(iter.next(), Some(bits![0, 1])); |
| /// assert_eq!(iter.next(), Some(bits![1, 0])); |
| /// assert!(iter.next().is_none()); |
| /// assert_eq!(iter.remainder(), bits![0]); |
| /// ``` |
| /// |
| /// [`.chunks_exact()`]: Self::chunks_exact |
| /// [`.rchunks()`]: Self::rchunks |
| /// [`.rchunks_exact_mut()`]: Self::rchunks_exact_mut |
| /// [`.remainder()`]: crate::slice::RChunksExact::remainder |
| #[inline] |
| pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<T, O> { |
| RChunksExact::new(self, chunk_size) |
| } |
| |
| /// Iterates over non-overlapping mutable subslices of a bit-slice, from the |
| /// back edge. |
| /// |
| /// If `self.len()` is not an even multiple of `chunk_size`, then the first |
| /// few bits are not yielded by the iterator at all. They can be accessed |
| /// with the [`.into_remainder()`] method if the iterator is bound to a |
| /// name. |
| /// |
| /// Iterators do not require that each yielded item is destroyed before the |
| /// next is produced. This means that each bit-slice yielded must be marked |
| /// as aliased. If you are using this in a loop that does not collect |
| /// multiple yielded subslices for the same scope, then you can remove the |
| /// alias marking by calling the (`unsafe`) method [`.remove_alias()`] on |
| /// the iterator. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.rchunks_mut()`] yields any leftover bits at the front as a shorter |
| /// chunk during iteration. |
| /// - [`.rchunks_exact()`] has the same division logic, but each yielded |
| /// bit-slice is immutable. |
| /// - [`.chunks_exact_mut()`] iterates from the front of the bit-slice |
| /// backwards, with the unyielded remainder segment at the back edge. |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `chunk_size` is `0`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut u8, Msb0; 0; 5]; |
| /// let mut iter = bits.rchunks_exact_mut(2); |
| /// |
| /// for (idx, chunk) in iter.by_ref().enumerate() { |
| /// chunk.store(idx + 1); |
| /// } |
| /// iter.into_remainder().store(1u8); |
| /// |
| /// assert_eq!(bits, bits![1, 1, 0, 0, 1]); |
| /// // remainder ^ |
| /// ``` |
| /// |
| /// [`.chunks_exact_mut()`]: Self::chunks_exact_mut |
| /// [`.into_remainder()`]: crate::slice::RChunksExactMut::into_remainder |
| /// [`.rchunks_exact()`]: Self::rchunks_exact |
| /// [`.rchunks_mut()`]: Self::rchunks_mut |
| /// [`.remove_alias()`]: crate::slice::RChunksExactMut::remove_alias |
| #[inline] |
| pub fn rchunks_exact_mut( |
| &mut self, |
| chunk_size: usize, |
| ) -> RChunksExactMut<T, O> { |
| RChunksExactMut::new(self, chunk_size) |
| } |
| |
| /// Splits a bit-slice in two parts at an index. |
| /// |
| /// The returned bit-slices are `self[.. mid]` and `self[mid ..]`. `mid` is |
| /// included in the right bit-slice, not the left. |
| /// |
| /// If `mid` is `0` then the left bit-slice is empty; if it is `self.len()` |
| /// then the right bit-slice is empty. |
| /// |
| /// This method guarantees that even when either partition is empty, the |
| /// encoded bit-pointer values of the bit-slice references is `&self[0]` and |
| /// `&self[mid]`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split_at`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_at) |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `mid` is greater than `self.len()`. It is allowed to be |
| /// equal to the length, in which case the right bit-slice is simply empty. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 0, 0, 1, 1, 1]; |
| /// let base = bits.as_bitptr(); |
| /// |
| /// let (a, b) = bits.split_at(0); |
| /// assert_eq!(unsafe { a.as_bitptr().offset_from(base) }, 0); |
| /// assert_eq!(unsafe { b.as_bitptr().offset_from(base) }, 0); |
| /// |
| /// let (a, b) = bits.split_at(6); |
| /// assert_eq!(unsafe { b.as_bitptr().offset_from(base) }, 6); |
| /// |
| /// let (a, b) = bits.split_at(3); |
| /// assert_eq!(a, bits![0; 3]); |
| /// assert_eq!(b, bits![1; 3]); |
| /// ``` |
| #[inline] |
| pub fn split_at(&self, mid: usize) -> (&Self, &Self) { |
| self.assert_in_bounds(mid, 0 ..= self.len()); |
| unsafe { self.split_at_unchecked(mid) } |
| } |
| |
| /// Splits a mutable bit-slice in two parts at an index. |
| /// |
| /// The returned bit-slices are `self[.. mid]` and `self[mid ..]`. `mid` is |
| /// included in the right bit-slice, not the left. |
| /// |
| /// If `mid` is `0` then the left bit-slice is empty; if it is `self.len()` |
| /// then the right bit-slice is empty. |
| /// |
| /// This method guarantees that even when either partition is empty, the |
| /// encoded bit-pointer values of the bit-slice references is `&self[0]` and |
| /// `&self[mid]`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split_at_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_at_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// The end bits of the left half and the start bits of the right half might |
| /// be stored in the same memory element. In order to avoid breaking |
| /// `bitvec`’s memory-safety guarantees, both bit-slices are marked as |
| /// `T::Alias`. This marking allows them to be used without interfering with |
| /// each other when they interact with memory. |
| /// |
| /// ## Panics |
| /// |
| /// This panics if `mid` is greater than `self.len()`. It is allowed to be |
| /// equal to the length, in which case the right bit-slice is simply empty. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut u8, Msb0; 0; 6]; |
| /// let base = bits.as_mut_bitptr(); |
| /// |
| /// let (a, b) = bits.split_at_mut(0); |
| /// assert_eq!(unsafe { a.as_mut_bitptr().offset_from(base) }, 0); |
| /// assert_eq!(unsafe { b.as_mut_bitptr().offset_from(base) }, 0); |
| /// |
| /// let (a, b) = bits.split_at_mut(6); |
| /// assert_eq!(unsafe { b.as_mut_bitptr().offset_from(base) }, 6); |
| /// |
| /// let (a, b) = bits.split_at_mut(3); |
| /// a.store(3); |
| /// b.store(5); |
| /// |
| /// assert_eq!(bits, bits![0, 1, 1, 1, 0, 1]); |
| /// ``` |
| #[inline] |
| pub fn split_at_mut( |
| &mut self, |
| mid: usize, |
| ) -> (&mut BitSlice<T::Alias, O>, &mut BitSlice<T::Alias, O>) { |
| self.assert_in_bounds(mid, 0 ..= self.len()); |
| unsafe { self.split_at_unchecked_mut(mid) } |
| } |
| |
| /// Iterates over subslices separated by bits that match a predicate. The |
| /// matched bit is *not* contained in the yielded bit-slices. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split`](https://doc.rust-lang.org/std/primitive.slice.html#method.split) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.split_mut()`] has the same splitting logic, but each yielded |
| /// bit-slice is mutable. |
| /// - [`.split_inclusive()`] includes the matched bit in the yielded |
| /// bit-slice. |
| /// - [`.rsplit()`] iterates from the back of the bit-slice instead of the |
| /// front. |
| /// - [`.splitn()`] times out after `n` yields. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 1, 0]; |
| /// // ^ |
| /// let mut iter = bits.split(|pos, _bit| pos % 3 == 2); |
| /// |
| /// assert_eq!(iter.next().unwrap(), bits![0, 1]); |
| /// assert_eq!(iter.next().unwrap(), bits![0]); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// If the first bit is matched, then an empty bit-slice will be the first |
| /// item yielded by the iterator. Similarly, if the last bit in the |
| /// bit-slice matches, then an empty bit-slice will be the last item |
| /// yielded. |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 0, 1]; |
| /// // ^ |
| /// let mut iter = bits.split(|_pos, bit| *bit); |
| /// |
| /// assert_eq!(iter.next().unwrap(), bits![0; 2]); |
| /// assert!(iter.next().unwrap().is_empty()); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// If two matched bits are directly adjacent, then an empty bit-slice will |
| /// be yielded between them: |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![1, 0, 0, 1]; |
| /// // ^ ^ |
| /// let mut iter = bits.split(|_pos, bit| !*bit); |
| /// |
| /// assert_eq!(iter.next().unwrap(), bits![1]); |
| /// assert!(iter.next().unwrap().is_empty()); |
| /// assert_eq!(iter.next().unwrap(), bits![1]); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// [`.rsplit()`]: Self::rsplit |
| /// [`.splitn()`]: Self::splitn |
| /// [`.split_inclusive()`]: Self::split_inclusive |
| /// [`.split_mut()`]: Self::split_mut |
| #[inline] |
| pub fn split<F>(&self, pred: F) -> Split<T, O, F> |
| where F: FnMut(usize, &bool) -> bool { |
| Split::new(self, pred) |
| } |
| |
| /// Iterates over mutable subslices separated by bits that match a |
| /// predicate. The matched bit is *not* contained in the yielded bit-slices. |
| /// |
| /// Iterators do not require that each yielded item is destroyed before the |
| /// next is produced. This means that each bit-slice yielded must be marked |
| /// as aliased. If you are using this in a loop that does not collect |
| /// multiple yielded subslices for the same scope, then you can remove the |
| /// alias marking by calling the (`unsafe`) method [`.remove_alias()`] on |
| /// the iterator. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.split()`] has the same splitting logic, but each yielded bit-slice |
| /// is immutable. |
| /// - [`.split_inclusive_mut()`] includes the matched bit in the yielded |
| /// bit-slice. |
| /// - [`.rsplit_mut()`] iterates from the back of the bit-slice instead of |
| /// the front. |
| /// - [`.splitn_mut()`] times out after `n` yields. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0, 0, 1, 0, 1, 0]; |
| /// // ^ ^ |
| /// for group in bits.split_mut(|_pos, bit| *bit) { |
| /// group.set(0, true); |
| /// } |
| /// assert_eq!(bits, bits![1, 0, 1, 1, 1, 1]); |
| /// ``` |
| /// |
| /// [`.remove_alias()`]: crate::slice::SplitMut::remove_alias |
| /// [`.rsplit_mut()`]: Self::rsplit_mut |
| /// [`.split()`]: Self::split |
| /// [`.split_inclusive_mut()`]: Self::split_inclusive_mut |
| /// [`.splitn_mut()`]: Self::splitn_mut |
| #[inline] |
| pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, O, F> |
| where F: FnMut(usize, &bool) -> bool { |
| SplitMut::new(self.alias_mut(), pred) |
| } |
| |
| /// Iterates over subslices separated by bits that match a predicate. Unlike |
| /// `.split()`, this *does* include the matching bit as the last bit in the |
| /// yielded bit-slice. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split_inclusive`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_inclusive) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.split_inclusive_mut()`] has the same splitting logic, but each |
| /// yielded bit-slice is mutable. |
| /// - [`.split()`] does not include the matched bit in the yielded |
| /// bit-slice. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 0, 1, 0, 1]; |
| /// // ^ ^ |
| /// let mut iter = bits.split_inclusive(|_pos, bit| *bit); |
| /// |
| /// assert_eq!(iter.next().unwrap(), bits![0, 0, 1]); |
| /// assert_eq!(iter.next().unwrap(), bits![0, 1]); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// [`.split()`]: Self::split |
| /// [`.split_inclusive_mut()`]: Self::split_inclusive_mut |
| #[inline] |
| pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<T, O, F> |
| where F: FnMut(usize, &bool) -> bool { |
| SplitInclusive::new(self, pred) |
| } |
| |
| /// Iterates over mutable subslices separated by bits that match a |
| /// predicate. Unlike `.split_mut()`, this *does* include the matching bit |
| /// as the last bit in the bit-slice. |
| /// |
| /// Iterators do not require that each yielded item is destroyed before the |
| /// next is produced. This means that each bit-slice yielded must be marked |
| /// as aliased. If you are using this in a loop that does not collect |
| /// multiple yielded subslices for the same scope, then you can remove the |
| /// alias marking by calling the (`unsafe`) method [`.remove_alias()`] on |
| /// the iterator. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::split_inclusive_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.split_inclusive_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.split_inclusive()`] has the same splitting logic, but each yielded |
| /// bit-slice is immutable. |
| /// - [`.split_mut()`] does not include the matched bit in the yielded |
| /// bit-slice. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0, 0, 0, 0, 0]; |
| /// // ^ |
| /// for group in bits.split_inclusive_mut(|pos, _bit| pos % 3 == 2) { |
| /// group.set(0, true); |
| /// } |
| /// assert_eq!(bits, bits![1, 0, 0, 1, 0]); |
| /// ``` |
| /// |
| /// [`.remove_alias()`]: crate::slice::SplitInclusiveMut::remove_alias |
| /// [`.split_inclusive()`]: Self::split_inclusive |
| /// [`.split_mut()`]: Self::split_mut |
| #[inline] |
| pub fn split_inclusive_mut<F>( |
| &mut self, |
| pred: F, |
| ) -> SplitInclusiveMut<T, O, F> |
| where |
| F: FnMut(usize, &bool) -> bool, |
| { |
| SplitInclusiveMut::new(self.alias_mut(), pred) |
| } |
| |
| /// Iterates over subslices separated by bits that match a predicate, from |
| /// the back edge. The matched bit is *not* contained in the yielded |
| /// bit-slices. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::rsplit`](https://doc.rust-lang.org/std/primitive.slice.html#method.rsplit) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.rsplit_mut()`] has the same splitting logic, but each yielded |
| /// bit-slice is mutable. |
| /// - [`.split()`] iterates from the front of the bit-slice instead of the |
| /// back. |
| /// - [`.rsplitn()`] times out after `n` yields. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 1, 0]; |
| /// // ^ |
| /// let mut iter = bits.rsplit(|pos, _bit| pos % 3 == 2); |
| /// |
| /// assert_eq!(iter.next().unwrap(), bits![0]); |
| /// assert_eq!(iter.next().unwrap(), bits![0, 1]); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// If the last bit is matched, then an empty bit-slice will be the first |
| /// item yielded by the iterator. Similarly, if the first bit in the |
| /// bit-slice matches, then an empty bit-slice will be the last item |
| /// yielded. |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 0, 1]; |
| /// // ^ |
| /// let mut iter = bits.rsplit(|_pos, bit| *bit); |
| /// |
| /// assert!(iter.next().unwrap().is_empty()); |
| /// assert_eq!(iter.next().unwrap(), bits![0; 2]); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// If two yielded bits are directly adjacent, then an empty bit-slice will |
| /// be yielded between them: |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![1, 0, 0, 1]; |
| /// // ^ ^ |
| /// let mut iter = bits.split(|_pos, bit| !*bit); |
| /// |
| /// assert_eq!(iter.next().unwrap(), bits![1]); |
| /// assert!(iter.next().unwrap().is_empty()); |
| /// assert_eq!(iter.next().unwrap(), bits![1]); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// [`.rsplitn()`]: Self::rsplitn |
| /// [`.rsplit_mut()`]: Self::rsplit_mut |
| /// [`.split()`]: Self::split |
| #[inline] |
| pub fn rsplit<F>(&self, pred: F) -> RSplit<T, O, F> |
| where F: FnMut(usize, &bool) -> bool { |
| RSplit::new(self, pred) |
| } |
| |
| /// Iterates over mutable subslices separated by bits that match a |
| /// predicate, from the back. The matched bit is *not* contained in the |
| /// yielded bit-slices. |
| /// |
| /// Iterators do not require that each yielded item is destroyed before the |
| /// next is produced. This means that each bit-slice yielded must be marked |
| /// as aliased. If you are using this in a loop that does not collect |
| /// multiple yielded subslices for the same scope, then you can remove the |
| /// alias marking by calling the (`unsafe`) method [`.remove_alias()`] on |
| /// the iterator. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::rsplit_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.rsplit_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.rsplit()`] has the same splitting logic, but each yielded bit-slice |
| /// is immutable. |
| /// - [`.split_mut()`] iterates from the front of the bit-slice to the back. |
| /// - [`.rsplitn_mut()`] iterates from the front of the bit-slice to the |
| /// back. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0, 0, 1, 0, 1, 0]; |
| /// // ^ ^ |
| /// for group in bits.rsplit_mut(|_pos, bit| *bit) { |
| /// group.set(0, true); |
| /// } |
| /// assert_eq!(bits, bits![1, 0, 1, 1, 1, 1]); |
| /// ``` |
| /// |
| /// [`.remove_alias()`]: crate::slice::RSplitMut::remove_alias |
| /// [`.rsplit()`]: Self::rsplit |
| /// [`.rsplitn_mut()`]: Self::rsplitn_mut |
| /// [`.split_mut()`]: Self::split_mut |
| #[inline] |
| pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<T, O, F> |
| where F: FnMut(usize, &bool) -> bool { |
| RSplitMut::new(self.alias_mut(), pred) |
| } |
| |
| /// Iterates over subslices separated by bits that match a predicate, giving |
| /// up after yielding `n` times. The `n`th yield contains the rest of the |
| /// bit-slice. As with `.split()`, the yielded bit-slices do not contain the |
| /// matched bit. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::splitn`](https://doc.rust-lang.org/std/primitive.slice.html#method.splitn) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.splitn_mut()`] has the same splitting logic, but each yielded |
| /// bit-slice is mutable. |
| /// - [`.rsplitn()`] iterates from the back of the bit-slice instead of the |
| /// front. |
| /// - [`.split()`] has the same splitting logic, but never times out. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 0, 1, 0, 1, 0]; |
| /// let mut iter = bits.splitn(2, |_pos, bit| *bit); |
| /// |
| /// assert_eq!(iter.next().unwrap(), bits![0, 0]); |
| /// assert_eq!(iter.next().unwrap(), bits![0, 1, 0]); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// [`.rsplitn()`]: Self::rsplitn |
| /// [`.split()`]: Self::split |
| /// [`.splitn_mut()`]: Self::splitn_mut |
| #[inline] |
| pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, O, F> |
| where F: FnMut(usize, &bool) -> bool { |
| SplitN::new(self, pred, n) |
| } |
| |
| /// Iterates over mutable subslices separated by bits that match a |
| /// predicate, giving up after yielding `n` times. The `n`th yield contains |
| /// the rest of the bit-slice. As with `.split_mut()`, the yielded |
| /// bit-slices do not contain the matched bit. |
| /// |
| /// Iterators do not require that each yielded item is destroyed before the |
| /// next is produced. This means that each bit-slice yielded must be marked |
| /// as aliased. If you are using this in a loop that does not collect |
| /// multiple yielded subslices for the same scope, then you can remove the |
| /// alias marking by calling the (`unsafe`) method [`.remove_alias()`] on |
| /// the iterator. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::splitn_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.splitn_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.splitn()`] has the same splitting logic, but each yielded bit-slice |
| /// is immutable. |
| /// - [`.rsplitn_mut()`] iterates from the back of the bit-slice instead of |
| /// the front. |
| /// - [`.split_mut()`] has the same splitting logic, but never times out. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0, 0, 1, 0, 1, 0]; |
| /// for group in bits.splitn_mut(2, |_pos, bit| *bit) { |
| /// group.set(0, true); |
| /// } |
| /// assert_eq!(bits, bits![1, 0, 1, 1, 1, 0]); |
| /// ``` |
| /// |
| /// [`.remove_alias()`]: crate::slice::SplitNMut::remove_alias |
| /// [`.rsplitn_mut()`]: Self::rsplitn_mut |
| /// [`.split_mut()`]: Self::split_mut |
| /// [`.splitn()`]: Self::splitn |
| #[inline] |
| pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, O, F> |
| where F: FnMut(usize, &bool) -> bool { |
| SplitNMut::new(self.alias_mut(), pred, n) |
| } |
| |
| /// Iterates over mutable subslices separated by bits that match a |
| /// predicate from the back edge, giving up after yielding `n` times. The |
| /// `n`th yield contains the rest of the bit-slice. As with `.split_mut()`, |
| /// the yielded bit-slices do not contain the matched bit. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::rsplitn`](https://doc.rust-lang.org/std/primitive.slice.html#method.rsplitn) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.rsplitn_mut()`] has the same splitting logic, but each yielded |
| /// bit-slice is mutable. |
| /// - [`.splitn()`]: iterates from the front of the bit-slice instead of the |
| /// back. |
| /// - [`.rsplit()`] has the same splitting logic, but never times out. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 0, 1, 1, 0]; |
| /// // ^ |
| /// let mut iter = bits.rsplitn(2, |_pos, bit| *bit); |
| /// |
| /// assert_eq!(iter.next().unwrap(), bits![0]); |
| /// assert_eq!(iter.next().unwrap(), bits![0, 0, 1]); |
| /// assert!(iter.next().is_none()); |
| /// ``` |
| /// |
| /// [`.rsplit()`]: Self::rsplit |
| /// [`.rsplitn_mut()`]: Self::rsplitn_mut |
| /// [`.splitn()`]: Self::splitn |
| #[inline] |
| pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, O, F> |
| where F: FnMut(usize, &bool) -> bool { |
| RSplitN::new(self, pred, n) |
| } |
| |
| /// Iterates over mutable subslices separated by bits that match a |
| /// predicate from the back edge, giving up after yielding `n` times. The |
| /// `n`th yield contains the rest of the bit-slice. As with `.split_mut()`, |
| /// the yielded bit-slices do not contain the matched bit. |
| /// |
| /// Iterators do not require that each yielded item is destroyed before the |
| /// next is produced. This means that each bit-slice yielded must be marked |
| /// as aliased. If you are using this in a loop that does not collect |
| /// multiple yielded subslices for the same scope, then you can remove the |
| /// alias marking by calling the (`unsafe`) method [`.remove_alias()`] on |
| /// the iterator. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::rsplitn_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.rsplitn_mut) |
| /// |
| /// ## API Differences |
| /// |
| /// The predicate function receives the index being tested as well as the |
| /// bit value at that index. This allows the predicate to have more than one |
| /// bit of information about the bit-slice being traversed. |
| /// |
| /// ## Sibling Methods |
| /// |
| /// - [`.rsplitn()`] has the same splitting logic, but each yielded |
| /// bit-slice is immutable. |
| /// - [`.splitn_mut()`] iterates from the front of the bit-slice instead of |
| /// the back. |
| /// - [`.rsplit_mut()`] has the same splitting logic, but never times out. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0, 0, 1, 0, 0, 1, 0, 0, 0]; |
| /// for group in bits.rsplitn_mut(2, |_idx, bit| *bit) { |
| /// group.set(0, true); |
| /// } |
| /// assert_eq!(bits, bits![1, 0, 1, 0, 0, 1, 1, 0, 0]); |
| /// // ^ group 2 ^ group 1 |
| /// ``` |
| /// |
| /// [`.remove_alias()`]: crate::slice::RSplitNMut::remove_alias |
| /// [`.rsplitn()`]: Self::rsplitn |
| /// [`.rsplit_mut()`]: Self::rsplit_mut |
| /// [`.splitn_mut()`]: Self::splitn_mut |
| #[inline] |
| pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<T, O, F> |
| where F: FnMut(usize, &bool) -> bool { |
| RSplitNMut::new(self.alias_mut(), pred, n) |
| } |
| |
| /// Tests if the bit-slice contains the given sequence anywhere within it. |
| /// |
| /// This scans over `self.windows(other.len())` until one of the windows |
| /// matches. The search key does not need to share type parameters with the |
| /// bit-slice being tested, as the comparison is bit-wise. However, sharing |
| /// type parameters will accelerate the comparison. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::contains`](https://doc.rust-lang.org/std/primitive.slice.html#method.contains) |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 0, 1, 0, 1, 1, 0, 0]; |
| /// assert!( bits.contains(bits![0, 1, 1, 0])); |
| /// assert!(!bits.contains(bits![1, 0, 0, 1])); |
| /// ``` |
| #[inline] |
| pub fn contains<T2, O2>(&self, other: &BitSlice<T2, O2>) -> bool |
| where |
| T2: BitStore, |
| O2: BitOrder, |
| { |
| self.len() >= other.len() |
| && self.windows(other.len()).any(|window| window == other) |
| } |
| |
| /// Tests if the bit-slice begins with the given sequence. |
| /// |
| /// The search key does not need to share type parameters with the bit-slice |
| /// being tested, as the comparison is bit-wise. However, sharing type |
| /// parameters will accelerate the comparison. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::starts_with`](https://doc.rust-lang.org/std/primitive.slice.html#method.starts_with) |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 1, 0]; |
| /// assert!( bits.starts_with(bits![0, 1])); |
| /// assert!(!bits.starts_with(bits![1, 0])); |
| /// ``` |
| /// |
| /// This always returns `true` if the needle is empty: |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0]; |
| /// let empty = bits![]; |
| /// assert!(bits.starts_with(empty)); |
| /// assert!(empty.starts_with(empty)); |
| /// ``` |
| #[inline] |
| pub fn starts_with<T2, O2>(&self, needle: &BitSlice<T2, O2>) -> bool |
| where |
| T2: BitStore, |
| O2: BitOrder, |
| { |
| self.get(.. needle.len()) |
| .map(|slice| slice == needle) |
| .unwrap_or(false) |
| } |
| |
| /// Tests if the bit-slice ends with the given sequence. |
| /// |
| /// The search key does not need to share type parameters with the bit-slice |
| /// being tested, as the comparison is bit-wise. However, sharing type |
| /// parameters will accelerate the comparison. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::ends_with`](https://doc.rust-lang.org/std/primitive.slice.html#method.ends_with) |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 1, 0]; |
| /// assert!( bits.ends_with(bits![1, 0])); |
| /// assert!(!bits.ends_with(bits![0, 1])); |
| /// ``` |
| /// |
| /// This always returns `true` if the needle is empty: |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0]; |
| /// let empty = bits![]; |
| /// assert!(bits.ends_with(empty)); |
| /// assert!(empty.ends_with(empty)); |
| /// ``` |
| #[inline] |
| pub fn ends_with<T2, O2>(&self, needle: &BitSlice<T2, O2>) -> bool |
| where |
| T2: BitStore, |
| O2: BitOrder, |
| { |
| self.get(self.len() - needle.len() ..) |
| .map(|slice| slice == needle) |
| .unwrap_or(false) |
| } |
| |
| /// Removes a prefix bit-slice, if present. |
| /// |
| /// Like [`.starts_with()`], the search key does not need to share type |
| /// parameters with the bit-slice being stripped. If |
| /// `self.starts_with(suffix)`, then this returns `Some(&self[prefix.len() |
| /// ..])`, otherwise it returns `None`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::strip_prefix`](https://doc.rust-lang.org/std/primitive.slice.html#method.strip_prefix) |
| /// |
| /// ## API Differences |
| /// |
| /// `BitSlice` does not support pattern searches; instead, it permits `self` |
| /// and `prefix` to differ in type parameters. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0, 0, 1, 0, 1, 1, 0]; |
| /// assert_eq!(bits.strip_prefix(bits![0, 1]).unwrap(), bits[2 ..]); |
| /// assert_eq!(bits.strip_prefix(bits![0, 1, 0, 0,]).unwrap(), bits[4 ..]); |
| /// assert!(bits.strip_prefix(bits![1, 0]).is_none()); |
| /// ``` |
| /// |
| /// [`.starts_with()`]: Self::starts_with |
| #[inline] |
| pub fn strip_prefix<T2, O2>( |
| &self, |
| prefix: &BitSlice<T2, O2>, |
| ) -> Option<&Self> |
| where |
| T2: BitStore, |
| O2: BitOrder, |
| { |
| if self.starts_with(prefix) { |
| self.get(prefix.len() ..) |
| } |
| else { |
| None |
| } |
| } |
| |
| /// Removes a suffix bit-slice, if present. |
| /// |
| /// Like [`.ends_with()`], the search key does not need to share type |
| /// parameters with the bit-slice being stripped. If |
| /// `self.ends_with(suffix)`, then this returns `Some(&self[.. self.len() - |
| /// suffix.len()])`, otherwise it returns `None`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::strip_suffix`](https://doc.rust-lang.org/std/primitive.slice.html#method.strip_suffix) |
| /// |
| /// ## API Differences |
| /// |
| /// `BitSlice` does not support pattern searches; instead, it permits `self` |
| /// and `suffix` to differ in type parameters. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![0, 1, 0, 0, 1, 0, 1, 1, 0]; |
| /// assert_eq!(bits.strip_suffix(bits![1, 0]).unwrap(), bits[.. 7]); |
| /// assert_eq!(bits.strip_suffix(bits![0, 1, 1, 0]).unwrap(), bits[.. 5]); |
| /// assert!(bits.strip_suffix(bits![0, 1]).is_none()); |
| /// ``` |
| /// |
| /// [`.ends_with()`]: Self::ends_with. |
| #[inline] |
| pub fn strip_suffix<T2, O2>( |
| &self, |
| suffix: &BitSlice<T2, O2>, |
| ) -> Option<&Self> |
| where |
| T2: BitStore, |
| O2: BitOrder, |
| { |
| if self.ends_with(suffix) { |
| self.get(.. self.len() - suffix.len()) |
| } |
| else { |
| None |
| } |
| } |
| |
| /// Rotates the contents of a bit-slice to the left (towards the zero |
| /// index). |
| /// |
| /// This essentially splits the bit-slice at `by`, then exchanges the two |
| /// pieces. `self[.. by]` becomes the first section, and is then followed by |
| /// `self[.. by]`. |
| /// |
| /// The implementation is batch-accelerated where possible. It should have a |
| /// runtime complexity much lower than `O(by)`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::rotate_left`](https://doc.rust-lang.org/std/primitive.slice.html#method.rotate_left) |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0, 0, 1, 0, 1, 0]; |
| /// // split occurs here ^ |
| /// bits.rotate_left(2); |
| /// assert_eq!(bits, bits![1, 0, 1, 0, 0, 0]); |
| /// ``` |
| #[inline] |
| pub fn rotate_left(&mut self, mut by: usize) { |
| let len = self.len(); |
| assert!( |
| by <= len, |
| "bit-slices cannot be rotated by more than their length", |
| ); |
| if by == 0 || by == len { |
| return; |
| } |
| let mut tmp = BitArray::<usize, O>::ZERO; |
| while by > 0 { |
| let shamt = cmp::min(mem::bits_of::<usize>(), by); |
| unsafe { |
| let tmp_bits = tmp.get_unchecked_mut(.. shamt); |
| tmp_bits.clone_from_bitslice(self.get_unchecked(.. shamt)); |
| self.copy_within_unchecked(shamt .., 0); |
| self.get_unchecked_mut(len - shamt ..) |
| .clone_from_bitslice(tmp_bits); |
| } |
| by -= shamt; |
| } |
| } |
| |
| /// Rotates the contents of a bit-slice to the right (away from the zero |
| /// index). |
| /// |
| /// This essentially splits the bit-slice at `self.len() - by`, then |
| /// exchanges the two pieces. `self[len - by ..]` becomes the first section, |
| /// and is then followed by `self[.. len - by]`. |
| /// |
| /// The implementation is batch-accelerated where possible. It should have a |
| /// runtime complexity much lower than `O(by)`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::rotate_right`](https://doc.rust-lang.org/std/primitive.slice.html#method.rotate_right) |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0, 0, 1, 1, 1, 0]; |
| /// // split occurs here ^ |
| /// bits.rotate_right(2); |
| /// assert_eq!(bits, bits![1, 0, 0, 0, 1, 1]); |
| /// ``` |
| #[inline] |
| pub fn rotate_right(&mut self, mut by: usize) { |
| let len = self.len(); |
| assert!( |
| by <= len, |
| "bit-slices cannot be rotated by more than their length", |
| ); |
| if by == 0 || by == len { |
| return; |
| } |
| let mut tmp = BitArray::<usize, O>::ZERO; |
| while by > 0 { |
| let shamt = cmp::min(mem::bits_of::<usize>(), by); |
| let mid = len - shamt; |
| unsafe { |
| let tmp_bits = tmp.get_unchecked_mut(.. shamt); |
| tmp_bits.clone_from_bitslice(self.get_unchecked(mid ..)); |
| self.copy_within_unchecked(.. mid, shamt); |
| self.get_unchecked_mut(.. shamt) |
| .clone_from_bitslice(tmp_bits); |
| } |
| by -= shamt; |
| } |
| } |
| |
| /// Fills the bit-slice with a given bit. |
| /// |
| /// This is a recent stabilization in the standard library. `bitvec` |
| /// previously offered this behavior as the novel API `.set_all()`. That |
| /// method name is now removed in favor of this standard-library analogue. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::fill`](https://doc.rust-lang.org/std/primitive.slice.html#method.fill) |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0; 5]; |
| /// bits.fill(true); |
| /// assert_eq!(bits, bits![1; 5]); |
| /// ``` |
| #[inline] |
| pub fn fill(&mut self, value: bool) { |
| let fill = if value { T::Mem::ALL } else { T::Mem::ZERO }; |
| match self.domain_mut() { |
| Domain::Enclave(mut elem) => { |
| elem.store_value(fill); |
| }, |
| Domain::Region { head, body, tail } => { |
| if let Some(mut elem) = head { |
| elem.store_value(fill); |
| } |
| for elem in body { |
| elem.store_value(fill); |
| } |
| if let Some(mut elem) = tail { |
| elem.store_value(fill); |
| } |
| }, |
| } |
| } |
| |
| /// Fills the bit-slice with bits produced by a generator function. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::fill_with`](https://doc.rust-lang.org/std/primitive.slice.html#method.fill_with) |
| /// |
| /// ## API Differences |
| /// |
| /// The generator function receives the index of the bit being initialized |
| /// as an argument. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 0; 5]; |
| /// bits.fill_with(|idx| idx % 2 == 0); |
| /// assert_eq!(bits, bits![1, 0, 1, 0, 1]); |
| /// ``` |
| #[inline] |
| pub fn fill_with<F>(&mut self, mut func: F) |
| where F: FnMut(usize) -> bool { |
| for (idx, ptr) in self.as_mut_bitptr_range().enumerate() { |
| unsafe { |
| ptr.write(func(idx)); |
| } |
| } |
| } |
| |
| #[inline] |
| #[cfg(not(tarpaulin_include))] |
| #[deprecated = "use `.clone_from_bitslice()` instead"] |
| #[allow(missing_docs, clippy::missing_docs_in_private_items)] |
| pub fn clone_from_slice<T2, O2>(&mut self, src: &BitSlice<T2, O2>) |
| where |
| T2: BitStore, |
| O2: BitOrder, |
| { |
| self.clone_from_bitslice(src); |
| } |
| |
| #[inline] |
| #[cfg(not(tarpaulin_include))] |
| #[deprecated = "use `.copy_from_bitslice()` instead"] |
| #[allow(missing_docs, clippy::missing_docs_in_private_items)] |
| pub fn copy_from_slice(&mut self, src: &Self) { |
| self.copy_from_bitslice(src) |
| } |
| |
| /// Copies a span of bits to another location in the bit-slice. |
| /// |
| /// `src` is the range of bit-indices in the bit-slice to copy, and `dest is |
| /// the starting index of the destination range. `src` and `dest .. dest + |
| /// src.len()` are permitted to overlap; the copy will automatically detect |
| /// and manage this. However, both `src` and `dest .. dest + src.len()` |
| /// **must** fall within the bounds of `self`. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::copy_within`](https://doc.rust-lang.org/std/primitive.slice.html#method.copy_within) |
| /// |
| /// ## Panics |
| /// |
| /// This panics if either the source or destination range exceed |
| /// `self.len()`. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bits = bits![mut 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]; |
| /// bits.copy_within(1 .. 5, 8); |
| /// // v v v v |
| /// assert_eq!(bits, bits![1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0]); |
| /// // ^ ^ ^ ^ |
| /// ``` |
| #[inline] |
| pub fn copy_within<R>(&mut self, src: R, dest: usize) |
| where R: RangeExt<usize> { |
| let len = self.len(); |
| let src = src.normalize(0, len); |
| self.assert_in_bounds(src.start, 0 .. len); |
| self.assert_in_bounds(src.end, 0 ..= len); |
| self.assert_in_bounds(dest, 0 .. len); |
| self.assert_in_bounds(dest + src.len(), 0 ..= len); |
| unsafe { |
| self.copy_within_unchecked(src, dest); |
| } |
| } |
| |
| #[inline] |
| #[deprecated = "use `.swap_with_bitslice()` instead"] |
| #[allow(missing_docs, clippy::missing_docs_in_private_items)] |
| pub fn swap_with_slice<T2, O2>(&mut self, other: &mut BitSlice<T2, O2>) |
| where |
| T2: BitStore, |
| O2: BitOrder, |
| { |
| self.swap_with_bitslice(other); |
| } |
| |
| /// Produces bit-slice view(s) with different underlying storage types. |
| /// |
| /// This may have unexpected effects, and you cannot assume that |
| /// `before[idx] == after[idx]`! Consult the [tables in the manual][layout] |
| /// for information about memory layouts. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::align_to`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to) |
| /// |
| /// ## Notes |
| /// |
| /// Unlike the standard library documentation, this explicitly guarantees |
| /// that the middle bit-slice will have maximal size. You may rely on this |
| /// property. |
| /// |
| /// ## Safety |
| /// |
| /// You may not use this to cast away alias protections. Rust does not have |
| /// support for higher-kinded types, so this cannot express the relation |
| /// `Outer<T> -> Outer<U> where Outer: BitStoreContainer`, but memory safety |
| /// does require that you respect this rule. Reälign integers to integers, |
| /// `Cell`s to `Cell`s, and atomics to atomics, but do not cross these |
| /// boundaries. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7]; |
| /// let bits = bytes.view_bits::<Lsb0>(); |
| /// let (pfx, mid, sfx) = unsafe { |
| /// bits.align_to::<u16>() |
| /// }; |
| /// assert!(pfx.len() <= 8); |
| /// assert_eq!(mid.len(), 48); |
| /// assert!(sfx.len() <= 8); |
| /// ``` |
| /// |
| /// [layout]: https://bitvecto-rs.github.io/bitvec/memory-layout.html |
| #[inline] |
| pub unsafe fn align_to<U>(&self) -> (&Self, &BitSlice<U, O>, &Self) |
| where U: BitStore { |
| let (l, c, r) = self.as_bitspan().align_to::<U>(); |
| ( |
| l.into_bitslice_ref(), |
| c.into_bitslice_ref(), |
| r.into_bitslice_ref(), |
| ) |
| } |
| |
| /// Produces bit-slice view(s) with different underlying storage types. |
| /// |
| /// This may have unexpected effects, and you cannot assume that |
| /// `before[idx] == after[idx]`! Consult the [tables in the manual][layout] |
| /// for information about memory layouts. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::align_to_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to_mut) |
| /// |
| /// ## Notes |
| /// |
| /// Unlike the standard library documentation, this explicitly guarantees |
| /// that the middle bit-slice will have maximal size. You may rely on this |
| /// property. |
| /// |
| /// ## Safety |
| /// |
| /// You may not use this to cast away alias protections. Rust does not have |
| /// support for higher-kinded types, so this cannot express the relation |
| /// `Outer<T> -> Outer<U> where Outer: BitStoreContainer`, but memory safety |
| /// does require that you respect this rule. Reälign integers to integers, |
| /// `Cell`s to `Cell`s, and atomics to atomics, but do not cross these |
| /// boundaries. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7]; |
| /// let bits = bytes.view_bits_mut::<Lsb0>(); |
| /// let (pfx, mid, sfx) = unsafe { |
| /// bits.align_to_mut::<u16>() |
| /// }; |
| /// assert!(pfx.len() <= 8); |
| /// assert_eq!(mid.len(), 48); |
| /// assert!(sfx.len() <= 8); |
| /// ``` |
| /// |
| /// [layout]: https://bitvecto-rs.github.io/bitvec/memory-layout.html |
| #[inline] |
| pub unsafe fn align_to_mut<U>( |
| &mut self, |
| ) -> (&mut Self, &mut BitSlice<U, O>, &mut Self) |
| where U: BitStore { |
| let (l, c, r) = self.as_mut_bitspan().align_to::<U>(); |
| ( |
| l.into_bitslice_mut(), |
| c.into_bitslice_mut(), |
| r.into_bitslice_mut(), |
| ) |
| } |
| } |
| |
| #[cfg(feature = "alloc")] |
| impl<T, O> BitSlice<T, O> |
| where |
| T: BitStore, |
| O: BitOrder, |
| { |
| #[inline] |
| #[deprecated = "use `.to_bitvec()` instead"] |
| #[allow(missing_docs, clippy::missing_docs_in_private_items)] |
| pub fn to_vec(&self) -> BitVec<T::Unalias, O> { |
| self.to_bitvec() |
| } |
| |
| /// Creates a bit-vector by repeating a bit-slice `n` times. |
| /// |
| /// ## Original |
| /// |
| /// [`slice::repeat`](https://doc.rust-lang.org/std/primitive.slice.html#method.repeat) |
| /// |
| /// ## Panics |
| /// |
| /// This method panics if `self.len() * n` exceeds the `BitVec` capacity. |
| /// |
| /// ## Examples |
| /// |
| /// ```rust |
| /// use bitvec::prelude::*; |
| /// |
| /// assert_eq!(bits![0, 1].repeat(3), bitvec![0, 1, 0, 1, 0, 1]); |
| /// ``` |
| /// |
| /// This panics by exceeding bit-vector maximum capacity: |
| /// |
| /// ```rust,should_panic |
| /// use bitvec::prelude::*; |
| /// |
| /// bits![0, 1].repeat(BitSlice::<usize, Lsb0>::MAX_BITS); |
| /// ``` |
| #[inline] |
| pub fn repeat(&self, n: usize) -> BitVec<T::Unalias, O> { |
| let len = self.len(); |
| let total = len.checked_mul(n).expect("capacity overflow"); |
| |
| let mut out = BitVec::repeat(false, total); |
| |
| let iter = unsafe { out.chunks_exact_mut(len).remove_alias() }; |
| for chunk in iter { |
| chunk.clone_from_bitslice(self); |
| } |
| |
| out |
| } |
| |
| /* As of 1.56, the `concat` and `join` methods use still-unstable traits |
| * to govern the collection of multiple subslices into one vector. These |
| * are possible to copy over and redefine locally, but unless a user asks |
| * for it, doing so is considered a low priority. |
| */ |
| } |
| |
| #[inline] |
| #[allow(missing_docs, clippy::missing_docs_in_private_items)] |
| #[deprecated = "use `BitSlice::from_element()` instead"] |
| pub fn from_ref<T, O>(elem: &T) -> &BitSlice<T, O> |
| where |
| T: BitStore, |
| O: BitOrder, |
| { |
| BitSlice::from_element(elem) |
| } |
| |
| #[inline] |
| #[allow(missing_docs, clippy::missing_docs_in_private_items)] |
| #[deprecated = "use `BitSlice::from_element_mut()` instead"] |
| pub fn from_mut<T, O>(elem: &mut T) -> &mut BitSlice<T, O> |
| where |
| T: BitStore, |
| O: BitOrder, |
| { |
| BitSlice::from_element_mut(elem) |
| } |
| |
| #[inline] |
| #[doc = include_str!("../../doc/slice/from_raw_parts.md")] |
| pub unsafe fn from_raw_parts<'a, T, O>( |
| data: BitPtr<Const, T, O>, |
| len: usize, |
| ) -> Result<&'a BitSlice<T, O>, BitSpanError<T>> |
| where |
| O: BitOrder, |
| T: 'a + BitStore, |
| { |
| data.span(len).map(|bp| bp.into_bitslice_ref()) |
| } |
| |
| #[inline] |
| #[doc = include_str!("../../doc/slice/from_raw_parts_mut.md")] |
| pub unsafe fn from_raw_parts_mut<'a, T, O>( |
| data: BitPtr<Mut, T, O>, |
| len: usize, |
| ) -> Result<&'a mut BitSlice<T, O>, BitSpanError<T>> |
| where |
| O: BitOrder, |
| T: 'a + BitStore, |
| { |
| data.span(len).map(|bp| bp.into_bitslice_mut()) |
| } |
| |
| #[doc = include_str!("../../doc/slice/BitSliceIndex.md")] |
| pub trait BitSliceIndex<'a, T, O> |
| where |
| T: BitStore, |
| O: BitOrder, |
| { |
| /// The output type of immutable access. |
| type Immut; |
| |
| /// The output type of mutable access. |
| type Mut; |
| |
| /// Immutably indexes into a bit-slice, returning `None` if `self` is out of |
| /// bounds. |
| /// |
| /// ## Original |
| /// |
| /// [`SliceIndex::get`](core::slice::SliceIndex::get) |
| fn get(self, bits: &'a BitSlice<T, O>) -> Option<Self::Immut>; |
| |
| /// Mutably indexes into a bit-slice, returning `None` if `self` is out of |
| /// bounds. |
| /// |
| /// ## Original |
| /// |
| /// [`SliceIndex::get_mut`](core::slice::SliceIndex::get_mut) |
| fn get_mut(self, bits: &'a mut BitSlice<T, O>) -> Option<Self::Mut>; |
| |
| /// Immutably indexes into a bit-slice without doing any bounds checking. |
| /// |
| /// ## Original |
| /// |
| /// [`SliceIndex::get_unchecked`](core::slice::SliceIndex::get_unchecked) |
| /// |
| /// ## Safety |
| /// |
| /// If `self` is not in bounds, then memory accesses through it are illegal |
| /// and the program becomes undefined. You must ensure that `self` is |
| /// appropriately within `0 .. bits.len()` at the call site. |
| unsafe fn get_unchecked(self, bits: &'a BitSlice<T, O>) -> Self::Immut; |
| |
| /// Mutably indexes into a bit-slice without doing any bounds checking. |
| /// |
| /// ## Original |
| /// |
| /// [`SliceIndex::get_unchecked_mut`][0] |
| /// |
| /// ## Safety |
| /// |
| /// If `self` is not in bounds, then memory accesses through it bare illegal |
| /// and the program becomes undefined. You must ensure that `self` is |
| /// appropriately within `0 .. bits.len()` at the call site. |
| /// |
| /// [0]: core::slice::SliceIndex::get_unchecked_mut |
| unsafe fn get_unchecked_mut(self, bits: &'a mut BitSlice<T, O>) |
| -> Self::Mut; |
| |
| /// Immutably indexes into a bit-slice, panicking if `self` is out of |
| /// bounds. |
| /// |
| /// ## Original |
| /// |
| /// [`SliceIndex::index`](core::slice::SliceIndex::index) |
| /// |
| /// ## Panics |
| /// |
| /// Implementations are required to panic if `self` exceeds `bits.len()` in |
| /// any way. |
| fn index(self, bits: &'a BitSlice<T, O>) -> Self::Immut; |
| |
| /// Mutably indexes into a bit-slice, panicking if `self` is out of bounds. |
| /// |
| /// ## Original |
| /// |
| /// [`SliceIndex::index_mut`](core::slice::SliceIndex::index_mut) |
| /// |
| /// ## Panics |
| /// |
| /// Implementations are required to panic if `self` exceeds `bits.len()` in |
| /// any way. |
| fn index_mut(self, bits: &'a mut BitSlice<T, O>) -> Self::Mut; |
| } |
| |
| impl<'a, T, O> BitSliceIndex<'a, T, O> for usize |
| where |
| T: BitStore, |
| O: BitOrder, |
| { |
| type Immut = BitRef<'a, Const, T, O>; |
| type Mut = BitRef<'a, Mut, T, O>; |
| |
| #[inline] |
| fn get(self, bits: &'a BitSlice<T, O>) -> Option<Self::Immut> { |
| if self < bits.len() { |
| Some(unsafe { self.get_unchecked(bits) }) |
| } |
| else { |
| None |
| } |
| } |
| |
| #[inline] |
| fn get_mut(self, bits: &'a mut BitSlice<T, O>) -> Option<Self::Mut> { |
| if self < bits.len() { |
| Some(unsafe { self.get_unchecked_mut(bits) }) |
| } |
| else { |
| None |
| } |
| } |
| |
| #[inline] |
| unsafe fn get_unchecked(self, bits: &'a BitSlice<T, O>) -> Self::Immut { |
| bits.as_bitptr().add(self).as_ref().unwrap() |
| } |
| |
| #[inline] |
| unsafe fn get_unchecked_mut( |
| self, |
| bits: &'a mut BitSlice<T, O>, |
| ) -> Self::Mut { |
| bits.as_mut_bitptr().add(self).as_mut().unwrap() |
| } |
| |
| #[inline] |
| fn index(self, bits: &'a BitSlice<T, O>) -> Self::Immut { |
| self.get(bits).unwrap_or_else(|| { |
| panic!("index {} out of bounds: {}", self, bits.len()) |
| }) |
| } |
| |
| #[inline] |
| fn index_mut(self, bits: &'a mut BitSlice<T, O>) -> Self::Mut { |
| let len = bits.len(); |
| self.get_mut(bits) |
| .unwrap_or_else(|| panic!("index {} out of bounds: {}", self, len)) |
| } |
| } |
| |
| /// Implements indexing on bit-slices by various range types. |
| macro_rules! range_impl { |
| ($r:ty { check $check:expr; select $select:expr; }) => { |
| #[allow(clippy::redundant_closure_call)] |
| impl<'a, T, O> BitSliceIndex<'a, T, O> for $r |
| where |
| O: BitOrder, |
| T: BitStore, |
| { |
| type Immut = &'a BitSlice<T, O>; |
| type Mut = &'a mut BitSlice<T, O>; |
| |
| #[inline] |
| #[allow( |
| clippy::blocks_in_if_conditions, |
| clippy::redundant_closure_call |
| )] |
| fn get(self, bits: Self::Immut) -> Option<Self::Immut> { |
| if ($check)(self.clone(), bits.as_bitspan()) { |
| Some(unsafe { self.get_unchecked(bits) }) |
| } |
| else { |
| None |
| } |
| } |
| |
| #[inline] |
| #[allow( |
| clippy::blocks_in_if_conditions, |
| clippy::redundant_closure_call |
| )] |
| fn get_mut(self, bits: Self::Mut) -> Option<Self::Mut> { |
| if ($check)(self.clone(), bits.as_bitspan()) { |
| Some(unsafe { self.get_unchecked_mut(bits) }) |
| } |
| else { |
| None |
| } |
| } |
| |
| #[inline] |
| #[allow(clippy::redundant_closure_call)] |
| unsafe fn get_unchecked(self, bits: Self::Immut) -> Self::Immut { |
| ($select)(self, bits.as_bitspan()).into_bitslice_ref() |
| } |
| |
| #[inline] |
| #[allow(clippy::redundant_closure_call)] |
| unsafe fn get_unchecked_mut(self, bits: Self::Mut) -> Self::Mut { |
| ($select)(self, bits.as_mut_bitspan()).into_bitslice_mut() |
| } |
| |
| #[inline] |
| #[track_caller] |
| fn index(self, bits: Self::Immut) -> Self::Immut { |
| let r = self.clone(); |
| let l = bits.len(); |
| self.get(bits).unwrap_or_else(|| { |
| panic!("range {:?} out of bounds: {}", r, l) |
| }) |
| } |
| |
| #[inline] |
| #[track_caller] |
| fn index_mut(self, bits: Self::Mut) -> Self::Mut { |
| let r = self.clone(); |
| let l = bits.len(); |
| self.get_mut(bits).unwrap_or_else(|| { |
| panic!("range {:?} out of bounds: {}", r, l) |
| }) |
| } |
| } |
| }; |
| } |
| |
| range_impl!(Range<usize> { |
| check |Range { start, end }, span: BitSpan<_, _, _>| { |
| let len = span.len(); |
| start <= len && end <= len && start <= end |
| }; |
| |
| select |Range { start, end }, span: BitSpan<_, _, _>| { |
| span.to_bitptr().add(start).span_unchecked(end - start) |
| }; |
| }); |
| |
| range_impl!(RangeFrom<usize> { |
| check |RangeFrom { start }, span: BitSpan<_, _, _>| { |
| start <= span.len() |
| }; |
| |
| select |RangeFrom { start }, span: BitSpan<_, _, _>| { |
| span.to_bitptr().add(start).span_unchecked(span.len() - start) |
| }; |
| }); |
| |
| range_impl!(RangeTo<usize> { |
| check |RangeTo { end }, span: BitSpan<_, _, _>| { |
| end <= span.len() |
| }; |
| |
| select |RangeTo { end }, mut span: BitSpan<_, _, _>| { |
| span.set_len(end); |
| span |
| }; |
| }); |
| |
| range_impl!(RangeInclusive<usize> { |
| check |range: Self, span: BitSpan<_, _, _>| { |
| let len = span.len(); |
| let start = *range.start(); |
| let end = *range.end(); |
| |
| start < len && end < len && start <= end |
| }; |
| |
| select |range: Self, span: BitSpan<_, _, _>| { |
| let start = *range.start(); |
| let end = *range.end(); |
| span.to_bitptr().add(start).span_unchecked(end + 1 - start) |
| }; |
| }); |
| |
| range_impl!(RangeToInclusive<usize> { |
| check |RangeToInclusive { end }, span: BitSpan<_, _, _>| { |
| end < span.len() |
| }; |
| |
| select |RangeToInclusive { end }, mut span: BitSpan<_, _, _>| { |
| span.set_len(end + 1); |
| span |
| }; |
| }); |
| |
| #[cfg(not(tarpaulin_include))] |
| impl<'a, T, O> BitSliceIndex<'a, T, O> for RangeFull |
| where |
| T: BitStore, |
| O: BitOrder, |
| { |
| type Immut = &'a BitSlice<T, O>; |
| type Mut = &'a mut BitSlice<T, O>; |
| |
| #[inline] |
| fn get(self, bits: Self::Immut) -> Option<Self::Immut> { |
| Some(bits) |
| } |
| |
| #[inline] |
| fn get_mut(self, bits: Self::Mut) -> Option<Self::Mut> { |
| Some(bits) |
| } |
| |
| #[inline] |
| unsafe fn get_unchecked(self, bits: Self::Immut) -> Self::Immut { |
| bits |
| } |
| |
| #[inline] |
| unsafe fn get_unchecked_mut(self, bits: Self::Mut) -> Self::Mut { |
| bits |
| } |
| |
| #[inline] |
| fn index(self, bits: Self::Immut) -> Self::Immut { |
| bits |
| } |
| |
| #[inline] |
| fn index_mut(self, bits: Self::Mut) -> Self::Mut { |
| bits |
| } |
| } |