diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
commit | 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch) | |
tree | bdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/sized-chunks/src/arbitrary.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff) | |
download | rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/sized-chunks/src/arbitrary.rs')
-rw-r--r-- | vendor/sized-chunks/src/arbitrary.rs | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/vendor/sized-chunks/src/arbitrary.rs b/vendor/sized-chunks/src/arbitrary.rs new file mode 100644 index 000000000..fc49984ff --- /dev/null +++ b/vendor/sized-chunks/src/arbitrary.rs @@ -0,0 +1,152 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use bitmaps::Bits; +use core::iter; + +use ::arbitrary::{size_hint, Arbitrary, Result, Unstructured}; + +use crate::{types::ChunkLength, Chunk, InlineArray, SparseChunk}; + +#[cfg(feature = "ringbuffer")] +use crate::RingBuffer; + +fn empty<T: 'static>() -> Box<dyn Iterator<Item = T>> { + Box::new(iter::empty()) +} + +fn shrink_collection<T: Clone, A: Arbitrary>( + entries: impl Iterator<Item = T>, + f: impl Fn(&T) -> Box<dyn Iterator<Item = A>>, +) -> Box<dyn Iterator<Item = Vec<A>>> { + let entries: Vec<_> = entries.collect(); + if entries.is_empty() { + return empty(); + } + + let mut shrinkers: Vec<Vec<_>> = vec![]; + let mut i = entries.len(); + loop { + shrinkers.push(entries.iter().take(i).map(&f).collect()); + i /= 2; + if i == 0 { + break; + } + } + Box::new(iter::once(Vec::new()).chain(iter::from_fn(move || loop { + let mut shrinker = shrinkers.pop()?; + let x: Option<Vec<A>> = shrinker.iter_mut().map(|s| s.next()).collect(); + if x.is_none() { + continue; + } + shrinkers.push(shrinker); + return x; + }))) +} + +impl<A, N> Arbitrary for Chunk<A, N> +where + A: Arbitrary, + N: ChunkLength<A> + 'static, +{ + fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> { + u.arbitrary_iter()?.take(Self::CAPACITY).collect() + } + + fn arbitrary_take_rest(u: Unstructured<'_>) -> Result<Self> { + u.arbitrary_take_rest_iter()?.take(Self::CAPACITY).collect() + } + + fn size_hint(depth: usize) -> (usize, Option<usize>) { + size_hint::recursion_guard(depth, |depth| { + let (_, upper) = A::size_hint(depth); + (0, upper.map(|upper| upper * Self::CAPACITY)) + }) + } + + fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { + let collections = shrink_collection(self.iter(), |x| x.shrink()); + Box::new(collections.map(|entries| entries.into_iter().collect())) + } +} + +#[cfg(feature = "ringbuffer")] +impl<A, N> Arbitrary for RingBuffer<A, N> +where + A: Arbitrary, + N: ChunkLength<A> + 'static, +{ + fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> { + u.arbitrary_iter()?.take(Self::CAPACITY).collect() + } + + fn arbitrary_take_rest(u: Unstructured<'_>) -> Result<Self> { + u.arbitrary_take_rest_iter()?.take(Self::CAPACITY).collect() + } + + fn size_hint(depth: usize) -> (usize, Option<usize>) { + size_hint::recursion_guard(depth, |depth| { + let (_, upper) = A::size_hint(depth); + (0, upper.map(|upper| upper * Self::CAPACITY)) + }) + } + + fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { + let collections = shrink_collection(self.iter(), |x| x.shrink()); + Box::new(collections.map(|entries| entries.into_iter().collect())) + } +} + +impl<A, N> Arbitrary for SparseChunk<A, N> +where + A: Clone, + Option<A>: Arbitrary, + N: ChunkLength<A> + Bits + 'static, +{ + fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> { + u.arbitrary_iter()?.take(Self::CAPACITY).collect() + } + + fn arbitrary_take_rest(u: Unstructured<'_>) -> Result<Self> { + u.arbitrary_take_rest_iter()?.take(Self::CAPACITY).collect() + } + + fn size_hint(depth: usize) -> (usize, Option<usize>) { + size_hint::recursion_guard(depth, |depth| { + let (_, upper) = Option::<A>::size_hint(depth); + (0, upper.map(|upper| upper * Self::CAPACITY)) + }) + } + + fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { + let collections = shrink_collection(self.clone().option_drain(), |x| x.shrink()); + Box::new(collections.map(|entries| entries.into_iter().collect())) + } +} + +impl<A, T> Arbitrary for InlineArray<A, T> +where + A: Arbitrary, + T: 'static, +{ + fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> { + u.arbitrary_iter()?.take(Self::CAPACITY).collect() + } + + fn arbitrary_take_rest(u: Unstructured<'_>) -> Result<Self> { + u.arbitrary_take_rest_iter()?.take(Self::CAPACITY).collect() + } + + fn size_hint(depth: usize) -> (usize, Option<usize>) { + size_hint::recursion_guard(depth, |depth| { + let (_, upper) = A::size_hint(depth); + (0, upper.map(|upper| upper * Self::CAPACITY)) + }) + } + + fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { + let collections = shrink_collection(self.iter(), |x| x.shrink()); + Box::new(collections.map(|entries| entries.into_iter().collect())) + } +} |