| { | ||
| "git": { | ||
| "sha1": "ea9fab5a514af6e9492c85fe6b310d95cc22f9ea" | ||
| "sha1": "ab289dadce27076664b6039f4029404d856beb09" | ||
| } | ||
| } |
+32
-27
@@ -5,11 +5,12 @@ # This file is automatically @generated by Cargo. | ||
| name = "bitvec" | ||
| version = "0.19.0" | ||
| version = "0.19.1" | ||
| dependencies = [ | ||
| "funty 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "radium 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "serde_test 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "wyz 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "funty", | ||
| "radium", | ||
| "serde", | ||
| "serde_json", | ||
| "serde_test", | ||
| "static_assertions", | ||
| "tap", | ||
| "wyz", | ||
| ] | ||
@@ -21,2 +22,3 @@ | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8" | ||
@@ -27,7 +29,9 @@ [[package]] | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" | ||
| [[package]] | ||
| name = "radium" | ||
| version = "0.3.0" | ||
| version = "0.4.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "53c9ec32b903ef247fbd5d56040d0e0e773ed6f9b5e116bd2ee27a3833d81938" | ||
@@ -38,16 +42,19 @@ [[package]] | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" | ||
| [[package]] | ||
| name = "serde" | ||
| version = "1.0.114" | ||
| version = "1.0.116" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" | ||
| [[package]] | ||
| name = "serde_json" | ||
| version = "1.0.56" | ||
| version = "1.0.57" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" | ||
| dependencies = [ | ||
| "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "itoa", | ||
| "ryu", | ||
| "serde", | ||
| ] | ||
@@ -57,6 +64,7 @@ | ||
| name = "serde_test" | ||
| version = "1.0.114" | ||
| version = "1.0.116" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "923edec3f1ab4a2f489f384e117dc4f826fd977a9d189b28717cba8474dd5c6b" | ||
| dependencies = [ | ||
| "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "serde", | ||
| ] | ||
@@ -68,17 +76,14 @@ | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" | ||
| [[package]] | ||
| name = "tap" | ||
| version = "1.0.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e" | ||
| [[package]] | ||
| name = "wyz" | ||
| version = "0.2.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| [metadata] | ||
| "checksum funty 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8" | ||
| "checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" | ||
| "checksum radium 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" | ||
| "checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" | ||
| "checksum serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" | ||
| "checksum serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)" = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3" | ||
| "checksum serde_test 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "f58190d074af17bd48118303db08afadbd506bc2ba511b4582cebd8f882a9b8d" | ||
| "checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" | ||
| "checksum wyz 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" | ||
| checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" |
+5
-2
@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| name = "bitvec" | ||
| version = "0.19.0" | ||
| version = "0.19.1" | ||
| authors = ["myrrlyn <self@myrrlyn.dev>"] | ||
@@ -35,3 +35,3 @@ include = ["Cargo.toml", "src/**/*.rs"] | ||
| [dependencies.radium] | ||
| version = "0.3" | ||
| version = "0.4" | ||
@@ -43,2 +43,5 @@ [dependencies.serde] | ||
| [dependencies.tap] | ||
| version = "1" | ||
| [dependencies.wyz] | ||
@@ -45,0 +48,0 @@ version = "0.2" |
+3
-58
@@ -175,44 +175,2 @@ /*! Memory access control. | ||
| /// Fetches the value of one bit in a memory element. | ||
| /// | ||
| /// # Type Parameters | ||
| /// | ||
| /// - `O`: A bit ordering. | ||
| /// | ||
| /// # Parameters | ||
| /// | ||
| /// - `&self` | ||
| /// - `index`: The semantic index of the bit in `*self` to read. | ||
| /// | ||
| /// # Returns | ||
| /// | ||
| /// The value of the bit in `*self` corresponding to `index`. | ||
| #[inline] | ||
| fn get_bit<O>(&self, index: BitIdx<R>) -> bool | ||
| where O: BitOrder { | ||
| unsafe { BitMask::new(self.load_value()) }.test(index.select::<O>()) | ||
| } | ||
| /// Fetches any number of bits from a memory element. | ||
| /// | ||
| /// The mask provided to this method must be constructed from indices that | ||
| /// are valid in the caller’s context. As the mask is already computed by | ||
| /// the caller, this does not take an ordering type parameter. | ||
| /// | ||
| /// # Parameters | ||
| /// | ||
| /// - `&self` | ||
| /// - `mask`: A mask of any number of bits. This is a selection mask of bits | ||
| /// to read. | ||
| /// | ||
| /// # Returns | ||
| /// | ||
| /// A copy of the memory element at `*self`, with all bits not selected (set | ||
| /// to `0`) in `mask` erased and all bits selected (set to `1`) in `mask` | ||
| /// preserved. | ||
| #[inline] | ||
| fn get_bits(&self, mask: BitMask<R>) -> R { | ||
| self.load_value() & mask.value() | ||
| } | ||
| /// Writes a bit to an index within the `self` element. | ||
@@ -316,16 +274,2 @@ /// | ||
| /// Copies a memory element into the caller’s local context. | ||
| /// | ||
| /// # Parameters | ||
| /// | ||
| /// - `&self` | ||
| /// | ||
| /// # Returns | ||
| /// | ||
| /// A copy of the value at `*self`. | ||
| #[inline] | ||
| fn load_value(&self) -> R { | ||
| self.load(Ordering::Relaxed) | ||
| } | ||
| /// Unconditionally writes a value into a memory location. | ||
@@ -392,3 +336,3 @@ /// | ||
| assert!(!BitAccess::get_bit::<Lsb0>(accessor, BitIdx::ZERO)); | ||
| assert!(!BitStore::get_bit::<Lsb0>(accessor, BitIdx::ZERO)); | ||
| assert_eq!(accessor.get(), !1); | ||
@@ -403,3 +347,3 @@ | ||
| assert_eq!( | ||
| BitAccess::get_bits(accessor, Lsb0::mask(BitIdx::new(2), None)), | ||
| BitStore::get_bits(accessor, Lsb0::mask(BitIdx::new(2), None)), | ||
| 0 | ||
@@ -419,2 +363,3 @@ ); | ||
| #[test] | ||
| #[cfg(not(miri))] | ||
| fn sanity_check_prefetch() { | ||
@@ -421,0 +366,0 @@ use core::cell::Cell; |
+2
-5
@@ -51,6 +51,3 @@ /*! A dynamically-allocated, fixed-size, buffer containing a `BitSlice` region. | ||
| use wyz::pipe::{ | ||
| Pipe, | ||
| PipeRef, | ||
| }; | ||
| use tap::pipe::Pipe; | ||
@@ -455,3 +452,3 @@ /** A frozen heap-allocated buffer of individual bits. | ||
| .pipe(ManuallyDrop::new) | ||
| .pipe_mut(func) | ||
| .pipe_ref_mut(func) | ||
| } | ||
@@ -458,0 +455,0 @@ } |
+1
-1
@@ -18,3 +18,3 @@ //! Port of the `Box<[T]>` function API. | ||
| use wyz::pipe::Pipe; | ||
| use tap::pipe::Pipe; | ||
@@ -21,0 +21,0 @@ impl<O, T> BitBox<O, T> |
@@ -39,3 +39,3 @@ //! Trait implementations for `BitBox` | ||
| use wyz::pipe::Pipe; | ||
| use tap::pipe::Pipe; | ||
@@ -42,0 +42,0 @@ #[cfg(not(tarpaulin_include))] |
+2
-5
@@ -16,3 +16,2 @@ /*! Utilities needed to develop `bitvec` itself. | ||
| use crate::{ | ||
| access::BitAccess, | ||
| index::BitMask, | ||
@@ -35,3 +34,3 @@ pointer::BitPtr, | ||
| use wyz::pipe::Pipe; | ||
| use tap::pipe::Pipe; | ||
@@ -69,5 +68,3 @@ /// Views a `BitStore` reference as its accessor. | ||
| where T: BitStore { | ||
| x.pipe(accessor::<T::Alias>) | ||
| .pipe(BitAccess::load_value) | ||
| .pipe(remove_alias::<T>) | ||
| x.load_value().pipe(remove_alias::<T>) | ||
| } | ||
@@ -74,0 +71,0 @@ |
+33
-73
@@ -19,3 +19,2 @@ /*! Representation of the `BitSlice` region memory model | ||
| use crate::{ | ||
| devel as dvl, | ||
| index::{ | ||
@@ -44,4 +43,3 @@ BitIdx, | ||
| use wyz::{ | ||
| fmt::FmtForward, | ||
| use tap::{ | ||
| pipe::Pipe, | ||
@@ -51,20 +49,4 @@ tap::Tap, | ||
| /* Implementation note: | ||
| use wyz::fmt::FmtForward; | ||
| Demain views are required to use aliasing types for read-only views to a | ||
| location that may nevertheless receive writes from other views. This is a | ||
| requirement of the Rust memory model, even though views constructed from | ||
| read-only `&BitSlice` references should not allow mutation. The `::Alias` types, | ||
| which implement `Radium`, allow mutation through `&` shared references. | ||
| Consider implementing, either locally or in a separate crate, the following: | ||
| ```rust | ||
| pub struct Immut<R: Radium<T>, T>(R); | ||
| impl<R: Radium<T>, T> Immut<R, T> { | ||
| // forward read-only methods to `Radium` | ||
| } | ||
| ``` | ||
| */ | ||
| macro_rules! bit_domain { | ||
@@ -99,2 +81,8 @@ ($t:ident $(=> $m:ident)? $(@ $a:ident)?) => { | ||
| /// | ||
| /// # Aliasing Awareness | ||
| /// | ||
| /// This enum does not grant access to memory outside the scope of the | ||
| /// original `&BitSlice` handle, and so does not need to modfiy any | ||
| /// aliasing conditions. | ||
| /// | ||
| /// [`Domain`]: enum.Domain.html | ||
@@ -146,16 +134,2 @@ /// [`DomainMut`]: enum.DomainMut.html | ||
| /// can safely remove its aliasing protections. | ||
| /// | ||
| /// # Safety Exception | ||
| /// | ||
| /// `&BitSlice<O, T::Alias>` references have access to a | ||
| /// `.set_aliased` method, which represents the only means in | ||
| /// `bitvec` of writing to memory without an exclusive `&mut ` | ||
| /// reference. | ||
| /// | ||
| /// Construction of two such shared, aliasing, references over | ||
| /// the same data, then construction of a bit-domain view over | ||
| /// one of them and simultaneous writing through the other to | ||
| /// interior elements marked as unaliased, will cause the | ||
| /// bit-domain view to be undefined behavior. Do not combine | ||
| /// bit-domain views and `.set_aliased` calls. | ||
| body: &'a $($m)? BitSlice<O, T::Mem>, | ||
@@ -171,3 +145,3 @@ /// Any bits that partially fill the last element of the slice | ||
| impl<'a, O, T> $t<'a, O, T> | ||
| impl<'a, O, T> $t <'a, O, T> | ||
| where | ||
@@ -393,3 +367,3 @@ O: BitOrder, | ||
| macro_rules! domain { | ||
| ($t:ident $(=> $m:ident)?) => { | ||
| ($t:ident $(=> $m:ident @ $a:ident)?) => { | ||
| /// Granular representation of the memory region containing a | ||
@@ -437,3 +411,3 @@ /// `BitSlice`. | ||
| /// views to the referent element may be permitted to modify it. | ||
| elem: &'a T::Alias, | ||
| elem: &'a T $(::$a)?, | ||
| /// The end index of the `BitSlice`. | ||
@@ -452,3 +426,3 @@ tail: BitTail<T::Mem>, | ||
| /// address. | ||
| head: Option<(BitIdx<T::Mem>, &'a T::Alias)>, | ||
| head: Option<(BitIdx<T::Mem>, &'a T $(::$a)?)>, | ||
| /// All fully-spanned, unaliased, elements. | ||
@@ -479,3 +453,3 @@ /// | ||
| /// this contains the ending index and the last address. | ||
| tail: Option<(&'a T::Alias, BitTail<T::Mem>)>, | ||
| tail: Option<(&'a T $(::$a)?, BitTail<T::Mem>)>, | ||
| } | ||
@@ -503,3 +477,3 @@ } | ||
| BitIdx<T::Mem>, | ||
| &'a T::Alias, | ||
| &'a T $(::$a)?, | ||
| BitTail<T::Mem>, | ||
@@ -528,5 +502,5 @@ )> { | ||
| pub fn region(self) -> Option<( | ||
| Option<(BitIdx<T::Mem>, &'a T::Alias)>, | ||
| Option<(BitIdx<T::Mem>, &'a T $(::$a)?)>, | ||
| &'a $($m)? [T::Mem], | ||
| Option<(&'a T::Alias, BitTail<T::Mem>)>, | ||
| Option<(&'a T $(::$a)?, BitTail<T::Mem>)>, | ||
| )> { | ||
@@ -549,3 +523,3 @@ if let Self::Region { head, body, tail } = self { | ||
| let bits = T::Mem::BITS; | ||
| let base = bitptr.pointer().to_alias(); | ||
| let base = bitptr.pointer().to_const() as *const _; | ||
| match (head.value(), elts, tail.value()) { | ||
@@ -572,3 +546,3 @@ (_, 0, _) => Self::empty(), | ||
| fn major( | ||
| base: *const T::Alias, | ||
| base: *const T $(::$a)?, | ||
| elts: usize, | ||
@@ -590,3 +564,3 @@ head: BitIdx<T::Mem>, | ||
| fn minor( | ||
| addr: *const T::Alias, | ||
| addr: *const T $(::$a)?, | ||
| head: BitIdx<T::Mem>, | ||
@@ -604,3 +578,3 @@ tail: BitTail<T::Mem>, | ||
| fn partial_head( | ||
| base: *const T::Alias, | ||
| base: *const T $(::$a)?, | ||
| elts: usize, | ||
@@ -620,3 +594,3 @@ head: BitIdx<T::Mem>, | ||
| fn partial_tail( | ||
| base: *const T::Alias, | ||
| base: *const T $(::$a)?, | ||
| elts: usize, | ||
@@ -635,3 +609,3 @@ tail: BitTail<T::Mem>, | ||
| #[inline] | ||
| fn spanning(base: *const T::Alias, elts: usize) -> Self { | ||
| fn spanning(base: *const T $(::$a)?, elts: usize) -> Self { | ||
| Self::Region { | ||
@@ -655,3 +629,3 @@ head: None, | ||
| domain!(Domain); | ||
| domain!(DomainMut => mut); | ||
| domain!(DomainMut => mut @ Alias); | ||
@@ -676,12 +650,8 @@ impl<T> Clone for Domain<'_, T> | ||
| match self { | ||
| Self::Enclave { elem, .. } => (*elem) | ||
| .pipe(dvl::load_aliased_local::<T>) | ||
| .pipe(Some) | ||
| .tap(|_| *self = Self::empty()), | ||
| Self::Enclave { elem, .. } => { | ||
| elem.load_value().pipe(Some).tap(|_| *self = Self::empty()) | ||
| }, | ||
| Self::Region { head, body, tail } => { | ||
| if let Some((_, elem)) = *head { | ||
| return elem | ||
| .pipe(dvl::load_aliased_local::<T>) | ||
| .pipe(Some) | ||
| .tap(|_| *head = None); | ||
| return elem.load_value().pipe(Some).tap(|_| *head = None); | ||
| } | ||
@@ -693,6 +663,3 @@ if let Some((elem, rest)) = body.split_first() { | ||
| if let Some((elem, _)) = *tail { | ||
| return elem | ||
| .pipe(dvl::load_aliased_local::<T>) | ||
| .pipe(Some) | ||
| .tap(|_| *tail = None); | ||
| return elem.load_value().pipe(Some).tap(|_| *tail = None); | ||
| } | ||
@@ -711,12 +678,8 @@ None | ||
| match self { | ||
| Self::Enclave { elem, .. } => (*elem) | ||
| .pipe(dvl::load_aliased_local::<T>) | ||
| .pipe(Some) | ||
| .tap(|_| *self = Self::empty()), | ||
| Self::Enclave { elem, .. } => { | ||
| elem.load_value().pipe(Some).tap(|_| *self = Self::empty()) | ||
| }, | ||
| Self::Region { head, body, tail } => { | ||
| if let Some((elem, _)) = *tail { | ||
| return elem | ||
| .pipe(dvl::load_aliased_local::<T>) | ||
| .pipe(Some) | ||
| .tap(|_| *tail = None); | ||
| return elem.load_value().pipe(Some).tap(|_| *tail = None); | ||
| } | ||
@@ -728,6 +691,3 @@ if let Some((elem, rest)) = body.split_last() { | ||
| if let Some((_, elem)) = *head { | ||
| return elem | ||
| .pipe(dvl::load_aliased_local::<T>) | ||
| .pipe(Some) | ||
| .tap(|_| *head = None); | ||
| return elem.load_value().pipe(Some).tap(|_| *head = None); | ||
| } | ||
@@ -734,0 +694,0 @@ None |
+3
-3
@@ -70,3 +70,3 @@ /*! Parallel bitfield access. | ||
| use wyz::pipe::Pipe; | ||
| use tap::pipe::Pipe; | ||
@@ -761,3 +761,3 @@ #[cfg(feature = "alloc")] | ||
| #[inline] | ||
| fn get<T, M>(elem: &T::Alias, mask: BitMask<T::Mem>, shamt: u8) -> M | ||
| fn get<T, M>(elem: &T, mask: BitMask<T::Mem>, shamt: u8) -> M | ||
| where | ||
@@ -767,3 +767,3 @@ T: BitStore, | ||
| { | ||
| elem.pipe(dvl::load_aliased_local::<T>) | ||
| elem.load_value() | ||
| .pipe(|val| mask & val) | ||
@@ -770,0 +770,0 @@ .value() |
@@ -8,2 +8,4 @@ /*! Permutation testing | ||
| use super::*; | ||
| #[cfg(not(miri))] | ||
| use crate::prelude::*; | ||
@@ -43,2 +45,3 @@ | ||
| #[test] | ||
| #[cfg(not(miri))] | ||
| fn l08() { | ||
@@ -63,2 +66,3 @@ let bits = bits![mut Lsb0, u8; 0; 32]; | ||
| #[test] | ||
| #[cfg(not(miri))] | ||
| fn m08() { | ||
@@ -83,2 +87,3 @@ let bits = bits![mut Msb0, u8; 0; 32]; | ||
| #[test] | ||
| #[cfg(not(miri))] | ||
| fn l16() { | ||
@@ -103,2 +108,3 @@ let bits = bits![mut Lsb0, u16; 0; 32]; | ||
| #[test] | ||
| #[cfg(not(miri))] | ||
| fn m16() { | ||
@@ -105,0 +111,0 @@ let bits = bits![mut Msb0, u16; 0; 32]; |
+16
-16
@@ -52,5 +52,5 @@ //! Constructor macros for the crate’s collection types. | ||
| (mut $order:ident, $store:ident; $($val:expr),* $(,)?) => {( | ||
| (mut $order:ident, $store:ident; $($val:expr),* $(,)?) => {{ | ||
| &mut $crate::bitarr![$order, $store; $($val),*][.. $crate::__count!($($val),*)] | ||
| )}; | ||
| }}; | ||
@@ -65,5 +65,5 @@ /* These arms differ in `$order:ident` and `$order:path` in order to force | ||
| (mut $order:path, $store:ident; $($val:expr),* $(,)?) => {( | ||
| (mut $order:path, $store:ident; $($val:expr),* $(,)?) => {{ | ||
| &mut $crate::bitarr![$order, $store; $($val),*][.. $crate::__count!($($val),*)] | ||
| )}; | ||
| }}; | ||
@@ -91,9 +91,9 @@ // Explicit order, default store. | ||
| (mut $order:ident, $store:ident; $val:expr; $len:expr) => {( | ||
| (mut $order:ident, $store:ident; $val:expr; $len:expr) => {{ | ||
| &mut $crate::bitarr![$order, $store; $val; $len][.. $len] | ||
| )}; | ||
| }}; | ||
| (mut $order:path, $store:ident; $val:expr; $len:expr) => {( | ||
| (mut $order:path, $store:ident; $val:expr; $len:expr) => {{ | ||
| &mut $crate::bitarr![$order, $store; $val; $len][.. $len] | ||
| )}; | ||
| }}; | ||
@@ -118,9 +118,9 @@ // Explicit order, default store. | ||
| ($order:ident, $store:ident; $($val:expr),* $(,)?) => {( | ||
| ($order:ident, $store:ident; $($val:expr),* $(,)?) => {{ | ||
| &$crate::bitarr![$order, $store; $($val),*][.. $crate::__count!($($val),*)] | ||
| )}; | ||
| }}; | ||
| ($order:path, $store:ident; $($val:expr),* $(,)?) => {( | ||
| ($order:path, $store:ident; $($val:expr),* $(,)?) => {{ | ||
| &$crate::bitarr![$order, $store; $($val),*][.. $crate::__count!($($val),*)] | ||
| )}; | ||
| }}; | ||
@@ -139,9 +139,9 @@ ($order:ident; $($val:expr),* $(,)?) => { | ||
| ($order:ident, $store:ident; $val:expr; $len:expr) => {( | ||
| ($order:ident, $store:ident; $val:expr; $len:expr) => {{ | ||
| &$crate::bitarr![$order, $store; $val; $len][.. $len] | ||
| )}; | ||
| }}; | ||
| ($order:path, $store:ident; $val:expr; $len:expr) => {( | ||
| ($order:path, $store:ident; $val:expr; $len:expr) => {{ | ||
| &$crate::bitarr![$order, $store; $val; $len][.. $len] | ||
| )}; | ||
| }}; | ||
@@ -148,0 +148,0 @@ ($order:ident; $val:expr; $len:expr) => { |
+1
-1
@@ -543,3 +543,3 @@ /*! Ordering of bits within register elements. | ||
| #[cfg(test)] | ||
| #[cfg(all(test, not(miri)))] | ||
| mod tests { | ||
@@ -546,0 +546,0 @@ use super::*; |
+1
-1
@@ -782,3 +782,3 @@ /*! Bitslice pointer encoding | ||
| let (elt, bit) = self.head().offset(index as isize); | ||
| let base = self.pointer().to_access(); | ||
| let base = self.pointer().to_const(); | ||
| (&*base.offset(elt)).get_bit::<O>(bit) | ||
@@ -785,0 +785,0 @@ } |
+1
-1
@@ -67,3 +67,3 @@ /*! `serde`-powered de/serialization. | ||
| use wyz::pipe::Pipe; | ||
| use tap::pipe::Pipe; | ||
@@ -70,0 +70,0 @@ #[cfg(feature = "alloc")] |
+17
-25
@@ -73,3 +73,3 @@ /*! A dynamically-sized view into individual bits of a memory region. | ||
| use wyz::pipe::Pipe; | ||
| use tap::pipe::Pipe; | ||
@@ -833,13 +833,10 @@ /** A slice of individual bits, anywhere in memory. | ||
| */ | ||
| !O::mask(head, tail) | dvl::load_aliased_local::<T>(elem) | ||
| == BitMask::ALL | ||
| !O::mask(head, tail) | elem.load_value() == BitMask::ALL | ||
| }, | ||
| Domain::Region { head, body, tail } => { | ||
| head.map_or(true, |(head, elem)| { | ||
| !O::mask(head, None) | dvl::load_aliased_local::<T>(elem) | ||
| == BitMask::ALL | ||
| !O::mask(head, None) | elem.load_value() == BitMask::ALL | ||
| }) && body.iter().copied().all(|e| e == T::Mem::ALL) | ||
| && tail.map_or(true, |(elem, tail)| { | ||
| !O::mask(None, tail) | dvl::load_aliased_local::<T>(elem) | ||
| == BitMask::ALL | ||
| !O::mask(None, tail) | elem.load_value() == BitMask::ALL | ||
| }) | ||
@@ -883,13 +880,10 @@ }, | ||
| Domain::Enclave { head, elem, tail } => { | ||
| O::mask(head, tail) & dvl::load_aliased_local::<T>(elem) | ||
| != BitMask::ZERO | ||
| O::mask(head, tail) & elem.load_value() != BitMask::ZERO | ||
| }, | ||
| Domain::Region { head, body, tail } => { | ||
| head.map_or(false, |(head, elem)| { | ||
| O::mask(head, None) & dvl::load_aliased_local::<T>(elem) | ||
| != BitMask::ZERO | ||
| O::mask(head, None) & elem.load_value() != BitMask::ZERO | ||
| }) || body.iter().copied().any(|e| e != T::Mem::ZERO) | ||
| || tail.map_or(false, |(elem, tail)| { | ||
| O::mask(None, tail) & dvl::load_aliased_local::<T>(elem) | ||
| != BitMask::ZERO | ||
| O::mask(None, tail) & elem.load_value() != BitMask::ZERO | ||
| }) | ||
@@ -1036,3 +1030,3 @@ }, | ||
| Domain::Enclave { head, elem, tail } => (O::mask(head, tail) | ||
| & dvl::load_aliased_local::<T>(elem)) | ||
| & elem.load_value()) | ||
| .value() | ||
@@ -1042,3 +1036,3 @@ .count_ones() as usize, | ||
| head.map_or(0, |(head, elem)| { | ||
| (O::mask(head, None) & dvl::load_aliased_local::<T>(elem)) | ||
| (O::mask(head, None) & elem.load_value()) | ||
| .value() | ||
@@ -1051,3 +1045,3 @@ .count_ones() as usize | ||
| .sum::<usize>() + tail.map_or(0, |(elem, tail)| { | ||
| (O::mask(None, tail) & dvl::load_aliased_local::<T>(elem)) | ||
| (O::mask(None, tail) & elem.load_value()) | ||
| .value() | ||
@@ -1087,3 +1081,3 @@ .count_ones() as usize | ||
| Domain::Enclave { head, elem, tail } => (!O::mask(head, tail) | ||
| | dvl::load_aliased_local::<T>(elem)) | ||
| | elem.load_value()) | ||
| .value() | ||
@@ -1093,6 +1087,5 @@ .count_zeros() as usize, | ||
| head.map_or(0, |(head, elem)| { | ||
| (!O::mask(head, None) | ||
| | elem.pipe(dvl::load_aliased_local::<T>)) | ||
| .value() | ||
| .count_zeros() as usize | ||
| (!O::mask(head, None) | elem.load_value()) | ||
| .value() | ||
| .count_zeros() as usize | ||
| }) + body | ||
@@ -1103,6 +1096,5 @@ .iter() | ||
| .sum::<usize>() + tail.map_or(0, |(elem, tail)| { | ||
| (!O::mask(None, tail) | ||
| | elem.pipe(dvl::load_aliased_local::<T>)) | ||
| .value() | ||
| .count_zeros() as usize | ||
| (!O::mask(None, tail) | elem.load_value()) | ||
| .value() | ||
| .count_zeros() as usize | ||
| }) | ||
@@ -1109,0 +1101,0 @@ }, |
+84
-36
| //! `BitSlice` iterators | ||
| use crate::{ | ||
| access::BitAccess, | ||
| index::BitIdx, | ||
@@ -66,3 +65,3 @@ mem::BitMemory, | ||
| /// Address of the element with the first live bit. | ||
| base: NonNull<T::Access>, | ||
| base: *const T, | ||
| /// Address of the element containing the first dead bit. | ||
@@ -76,3 +75,3 @@ /// | ||
| /// region, but that is not important here. | ||
| last: NonNull<T::Access>, | ||
| last: *const T, | ||
| /// Semantic index of the first live bit. | ||
@@ -137,10 +136,4 @@ head: BitIdx<T::Mem>, | ||
| pub fn as_bitslice(&self) -> &'a BitSlice<O, T> { | ||
| unsafe { | ||
| BitPtr::new_unchecked( | ||
| self.base.as_ptr() as *const T::Access as *const T, | ||
| self.head, | ||
| self.len(), | ||
| ) | ||
| } | ||
| .to_bitslice_ref() | ||
| unsafe { BitPtr::new_unchecked(self.base, self.head, self.len()) } | ||
| .to_bitslice_ref() | ||
| } | ||
@@ -167,7 +160,5 @@ | ||
| fn pop_front(&mut self) -> <Self as Iterator>::Item { | ||
| let out = unsafe { &*self.base.as_ptr() }.get_bit::<O>(self.head); | ||
| let out = unsafe { &*self.base }.get_bit::<O>(self.head); | ||
| let (head, incr) = self.head.incr(); | ||
| self.base = unsafe { | ||
| NonNull::new_unchecked(self.base.as_ptr().add(incr as usize)) | ||
| }; | ||
| self.base = unsafe { self.base.add(incr as usize) }; | ||
| self.head = head; | ||
@@ -181,7 +172,5 @@ | ||
| let (tail, offset) = self.tail.decr(); | ||
| self.last = unsafe { | ||
| NonNull::new_unchecked(self.last.as_ptr().offset(-(offset as isize))) | ||
| }; | ||
| self.last = unsafe { self.last.offset(-(offset as isize)) }; | ||
| self.tail = tail; | ||
| if unsafe { &*self.last.as_ptr() }.get_bit::<O>(self.tail) { | ||
| if unsafe { &*self.last }.get_bit::<O>(self.tail) { | ||
| &true | ||
@@ -227,7 +216,6 @@ } | ||
| let addr = addr.to_access() as *mut T::Access; | ||
| let base = unsafe { NonNull::new_unchecked(addr) }; | ||
| let base = addr.to_const(); | ||
| let (elts, tail) = head.offset(bits as isize); | ||
| let last = unsafe { NonNull::new_unchecked(addr.offset(elts)) }; | ||
| let last = unsafe { base.offset(elts) }; | ||
@@ -441,2 +429,72 @@ Self::IntoIter { | ||
| impl<'a, O, T> Iter<'a, O, T> | ||
| where | ||
| O: 'a + BitOrder, | ||
| T: 'a + BitStore, | ||
| { | ||
| /// The canonical empty iterator. | ||
| const EMPTY: Self = Self { | ||
| base: NonNull::dangling().as_ptr() as *const T, | ||
| last: NonNull::dangling().as_ptr() as *const T, | ||
| head: BitIdx::ZERO, | ||
| tail: BitIdx::ZERO, | ||
| _ref: PhantomData, | ||
| }; | ||
| #[inline(always)] | ||
| fn get_base(&self) -> *const T { | ||
| self.base | ||
| } | ||
| #[inline(always)] | ||
| fn get_last(&self) -> *const T { | ||
| self.last | ||
| } | ||
| #[inline(always)] | ||
| fn set_base(&mut self, base: *const T) { | ||
| self.base = base | ||
| } | ||
| #[inline(always)] | ||
| fn set_last(&mut self, last: *const T) { | ||
| self.last = last | ||
| } | ||
| } | ||
| impl<'a, O, T> IterMut<'a, O, T> | ||
| where | ||
| O: 'a + BitOrder, | ||
| T: 'a + BitStore, | ||
| { | ||
| /// The canonical empty iterator. | ||
| const EMPTY: Self = Self { | ||
| base: NonNull::dangling(), | ||
| last: NonNull::dangling(), | ||
| head: BitIdx::ZERO, | ||
| tail: BitIdx::ZERO, | ||
| _ref: PhantomData, | ||
| }; | ||
| #[inline(always)] | ||
| fn get_base(&self) -> *mut <T::Alias as BitStore>::Access { | ||
| self.base.as_ptr() | ||
| } | ||
| #[inline(always)] | ||
| fn get_last(&self) -> *mut <T::Alias as BitStore>::Access { | ||
| self.last.as_ptr() | ||
| } | ||
| #[inline(always)] | ||
| fn set_base(&mut self, base: *mut <T::Alias as BitStore>::Access) { | ||
| self.base = unsafe { NonNull::new_unchecked(base) } | ||
| } | ||
| #[inline(always)] | ||
| fn set_last(&mut self, last: *mut <T::Alias as BitStore>::Access) { | ||
| self.last = unsafe { NonNull::new_unchecked(last) } | ||
| } | ||
| } | ||
| /// `Iter` and `IterMut` have very nearly the same implementation text. | ||
@@ -450,11 +508,2 @@ macro_rules! iter { | ||
| { | ||
| /// The canonical empty iterator. | ||
| const EMPTY: Self = Self { | ||
| base: NonNull::dangling(), | ||
| last: NonNull::dangling(), | ||
| head: BitIdx::ZERO, | ||
| tail: BitIdx::ZERO, | ||
| _ref: PhantomData, | ||
| }; | ||
| /// Tests whether the iterator is *any* empty iterator. | ||
@@ -501,4 +550,3 @@ pub(crate) fn inherent_is_empty(&self) -> bool { | ||
| let (elts, head) = self.head.offset(n as isize); | ||
| self.base = | ||
| unsafe { NonNull::new_unchecked(self.base.as_ptr().offset(elts)) }; | ||
| self.set_base(unsafe{self.get_base().offset(elts)}); | ||
| self.head = head; | ||
@@ -537,4 +585,3 @@ Some(self.pop_front()) | ||
| let (elts, tail) = self.tail.offset(-(n as isize)); | ||
| self.last = | ||
| unsafe { NonNull::new_unchecked(self.last.as_ptr().offset(elts)) }; | ||
| self.set_last(unsafe{self.get_last().offset(elts)}); | ||
| self.tail = tail; | ||
@@ -552,3 +599,3 @@ Some(self.pop_back()) | ||
| let (base, last) = | ||
| (self.base.as_ptr() as usize, self.last.as_ptr() as usize); | ||
| (self.get_base() as usize, self.get_last() as usize); | ||
| /* Get the total number of bits in the element range | ||
@@ -1682,2 +1729,3 @@ `self.base .. self.last`. Wrapping arithmetic is used because | ||
| #[cfg_attr(not(tarpaulin), inline(always))] | ||
| #[allow(clippy::redundant_field_names)] | ||
| pub(super) fn new( | ||
@@ -1684,0 +1732,0 @@ slice: &'a $($m)? BitSlice<O, T>, |
+1
-1
@@ -30,3 +30,3 @@ //! Operator trait implementations | ||
| use wyz::pipe::Pipe; | ||
| use tap::pipe::Pipe; | ||
@@ -33,0 +33,0 @@ impl<O, T, Rhs> BitAndAssign<Rhs> for BitSlice<O, T> |
@@ -127,3 +127,3 @@ /*! Proxy reference for `&mut bool` | ||
| head, | ||
| data: (&*addr).get_bit::<O>(head), | ||
| data: (&*(addr as *const T)).get_bit::<O>(head), | ||
| } | ||
@@ -130,0 +130,0 @@ } |
@@ -9,3 +9,5 @@ //! Unit tests for the `slice` module. | ||
| fn construction() { | ||
| #[cfg(not(miri))] | ||
| use core::slice; | ||
| let data = 0u8; | ||
@@ -15,2 +17,3 @@ let bits = data.view_bits::<LocalBits>(); | ||
| #[cfg(not(miri))] | ||
| assert!( | ||
@@ -26,2 +29,3 @@ BitSlice::<LocalBits, u8>::from_slice(unsafe { | ||
| #[cfg(not(miri))] | ||
| assert!( | ||
@@ -28,0 +32,0 @@ BitSlice::<LocalBits, u8>::from_slice_mut(unsafe { |
| //! Trait implementations for `BitSlice` | ||
| use crate::{ | ||
| devel as dvl, | ||
| domain::Domain, | ||
@@ -35,3 +34,3 @@ mem::BitMemory, | ||
| use wyz::pipe::Pipe; | ||
| use tap::pipe::Pipe; | ||
@@ -428,4 +427,3 @@ #[cfg(feature = "alloc")] | ||
| // Load a copy of `*elem` into the stack, | ||
| let tmp: T::Mem = | ||
| elem.pipe(dvl::load_aliased_local::<T>); | ||
| let tmp = elem.load_value(); | ||
| // View it as a `BitSlice` over the whole element, | ||
@@ -444,3 +442,3 @@ // narrow it to the live range, and render it. | ||
| if let Some((head, elem)) = head { | ||
| let tmp = elem.pipe(dvl::load_aliased_local::<T>); | ||
| let tmp = elem.load_value(); | ||
| let bits = tmp.view_bits::<O>(); | ||
@@ -457,3 +455,3 @@ unsafe { | ||
| if let Some((elem, tail)) = tail { | ||
| let tmp = elem.pipe(dvl::load_aliased_local::<T>); | ||
| let tmp = elem.load_value(); | ||
| let bits = tmp.view_bits::<O>(); | ||
@@ -460,0 +458,0 @@ unsafe { |
+79
-10
@@ -9,4 +9,9 @@ /*! Memory modeling. | ||
| access::BitAccess, | ||
| index::BitRegister, | ||
| index::{ | ||
| BitIdx, | ||
| BitMask, | ||
| BitRegister, | ||
| }, | ||
| mem, | ||
| order::BitOrder, | ||
| }; | ||
@@ -21,5 +26,2 @@ | ||
| #[cfg(feature = "atomic")] | ||
| use core::sync::atomic; | ||
| /** Common interface for memory regions. | ||
@@ -120,2 +122,54 @@ | ||
| const __ALIAS_WIDTH: [(); 0]; | ||
| /// Copies a memory element into the caller’s local context. | ||
| /// | ||
| /// # Parameters | ||
| /// | ||
| /// - `&self` | ||
| /// | ||
| /// # Returns | ||
| /// | ||
| /// A copy of the value at `*self`. | ||
| fn load_value(&self) -> Self::Mem; | ||
| /// Fetches the value of one bit in a memory element. | ||
| /// | ||
| /// # Type Parameters | ||
| /// | ||
| /// - `O`: A bit ordering. | ||
| /// | ||
| /// # Parameters | ||
| /// | ||
| /// - `&self` | ||
| /// - `index`: The semantic index of the bit in `*self` to read. | ||
| /// | ||
| /// # Returns | ||
| /// | ||
| /// The value of the bit in `*self` corresponding to `index`. | ||
| fn get_bit<O>(&self, index: BitIdx<Self::Mem>) -> bool | ||
| where O: BitOrder { | ||
| unsafe { BitMask::new(self.load_value()) }.test(index.select::<O>()) | ||
| } | ||
| /// Fetches any number of bits from a memory element. | ||
| /// | ||
| /// The mask provided to this method must be constructed from indices that | ||
| /// are valid in the caller’s context. As the mask is already computed by | ||
| /// the caller, this does not take an ordering type parameter. | ||
| /// | ||
| /// # Parameters | ||
| /// | ||
| /// - `&self` | ||
| /// - `mask`: A mask of any number of bits. This is a selection mask of bits | ||
| /// to read. | ||
| /// | ||
| /// # Returns | ||
| /// | ||
| /// A copy of the memory element at `*self`, with all bits not selected (set | ||
| /// to `0`) in `mask` erased and all bits selected (set to `1`) in `mask` | ||
| /// preserved. | ||
| #[inline] | ||
| fn get_bits(&self, mask: BitMask<Self::Mem>) -> Self::Mem { | ||
| self.load_value() & mask.value() | ||
| } | ||
| } | ||
@@ -132,3 +186,3 @@ | ||
| /// In atomic builds, use atomic types for aliased access. | ||
| /// In atomic builds, use `radium`’s best-effort atomic export. | ||
| #[cfg(feature = "atomic")] | ||
@@ -151,2 +205,7 @@ type Alias = $a; | ||
| const __ALIAS_WIDTH: [(); 0] = [(); mem::cmp_layout::<Self::Mem, Self::Alias>()]; | ||
| #[inline(always)] | ||
| fn load_value(&self) -> Self::Mem { | ||
| *self | ||
| } | ||
| } | ||
@@ -170,2 +229,7 @@ | ||
| const __ALIAS_WIDTH: [(); 0] = [(); mem::cmp_layout::<Self::Mem, Self::Alias>()]; | ||
| #[inline(always)] | ||
| fn load_value(&self) -> Self::Mem { | ||
| Self::load(self, core::sync::atomic::Ordering::Relaxed) | ||
| } | ||
| } | ||
@@ -181,11 +245,11 @@ | ||
| store!( | ||
| u8 => atomic::AtomicU8, | ||
| u16 => atomic::AtomicU16, | ||
| u32 => atomic::AtomicU32, | ||
| u8 => radium::types::RadiumU8, | ||
| u16 => radium::types::RadiumU16, | ||
| u32 => radium::types::RadiumU32, | ||
| ); | ||
| #[cfg(target_pointer_width = "64")] | ||
| store!(u64 => atomic::AtomicU64); | ||
| store!(u64 => radium::types::RadiumU64); | ||
| store!(usize => atomic::AtomicUsize); | ||
| store!(usize => radium::types::RadiumUsize); | ||
@@ -211,2 +275,7 @@ impl<R> BitStore for Cell<R> | ||
| const __ALIGNED_TO_SIZE: [(); 0] = []; | ||
| #[inline(always)] | ||
| fn load_value(&self) -> Self::Mem { | ||
| self.get() | ||
| } | ||
| } | ||
@@ -213,0 +282,0 @@ |
+3
-4
@@ -23,3 +23,2 @@ /*! A dynamically-allocated buffer containing a `BitSlice<O, T>` region. | ||
| use crate::{ | ||
| access::BitAccess, | ||
| boxed::BitBox, | ||
@@ -47,3 +46,3 @@ index::BitIdx, | ||
| use wyz::{ | ||
| use tap::{ | ||
| pipe::Pipe, | ||
@@ -201,3 +200,3 @@ tap::Tap, | ||
| let mut bitptr = slice.bitptr(); | ||
| let (base, elts) = (bitptr.pointer().to_access(), bitptr.elements()); | ||
| let (base, elts) = (bitptr.pointer().to_const(), bitptr.elements()); | ||
| let source = unsafe { slice::from_raw_parts(base, elts) }; | ||
@@ -207,3 +206,3 @@ | ||
| vec.extend(source.iter().map(BitAccess::load_value)); | ||
| vec.extend(source.iter().map(BitStore::load_value)); | ||
@@ -210,0 +209,0 @@ unsafe { |
+1
-1
@@ -32,3 +32,3 @@ //! Port of the `Vec<T>` function API. | ||
| use wyz::{ | ||
| use tap::{ | ||
| pipe::Pipe, | ||
@@ -35,0 +35,0 @@ tap::Tap, |
+2
-2
@@ -32,5 +32,5 @@ //! `BitVec` iterators | ||
| use wyz::{ | ||
| use tap::{ | ||
| pipe::Pipe, | ||
| tap::TapOption, | ||
| tap::TapOptional, | ||
| }; | ||
@@ -37,0 +37,0 @@ |
+11
-5
@@ -151,16 +151,22 @@ #![cfg(test)] | ||
| Switch to a by-value comparison instead of by-ref if this test fails. | ||
| Fun fact: Addresses are not stably observable in Miri. | ||
| */ | ||
| #[cfg(not(miri))] | ||
| assert_eq!(l as *const _, r as *const _); | ||
| #[cfg(miri)] | ||
| assert_eq!(*l, *r); | ||
| } | ||
| let mut iter = bv.clone().into_iter(); | ||
| let mut iter = bv.into_iter(); | ||
| assert!(!iter.next().unwrap()); | ||
| assert_eq!(iter.as_bitslice(), data[1 ..]); | ||
| let mut bv = bitvec![0, 0, 1, 0, 0, 1, 0, 0]; | ||
| let mut splice = bv.splice(2 .. 6, iter::repeat(false).take(4)); | ||
| let mut bv = bitvec![0, 0, 1, 0, 1, 1, 0, 1, 0, 0]; | ||
| let mut splice = bv.splice(2 .. 8, iter::repeat(false).take(4)); | ||
| assert!(splice.next().unwrap()); | ||
| assert!(splice.next_back().unwrap()); | ||
| assert!(!splice.nth(0).unwrap()); | ||
| assert!(!splice.nth_back(0).unwrap()); | ||
| assert!(splice.nth(1).unwrap()); | ||
| assert!(splice.nth_back(1).unwrap()); | ||
| drop(splice); | ||
@@ -167,0 +173,0 @@ assert_eq!(bv, bits![0; 8]); |
+2
-10
| //! Trait implementations for `BitVec`. | ||
| use crate::{ | ||
| access::BitAccess, | ||
| boxed::BitBox, | ||
| devel as dvl, | ||
| order::BitOrder, | ||
@@ -40,3 +38,3 @@ slice::BitSlice, | ||
| use wyz::{ | ||
| use tap::{ | ||
| pipe::Pipe, | ||
@@ -85,9 +83,3 @@ tap::Tap, | ||
| self.with_vec(|v| { | ||
| v.extend( | ||
| other | ||
| .as_slice() | ||
| .iter() | ||
| .map(dvl::accessor) | ||
| .map(BitAccess::load_value), | ||
| ) | ||
| v.extend(other.as_slice().iter().map(BitStore::load_value)) | ||
| }); | ||
@@ -94,0 +86,0 @@ unsafe { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display