about summary refs log tree commit diff
path: root/library/compiler-builtins/libm-test/src/generate.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/compiler-builtins/libm-test/src/generate.rs')
-rw-r--r--library/compiler-builtins/libm-test/src/generate.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/library/compiler-builtins/libm-test/src/generate.rs b/library/compiler-builtins/libm-test/src/generate.rs
new file mode 100644
index 00000000000..da080d23fa7
--- /dev/null
+++ b/library/compiler-builtins/libm-test/src/generate.rs
@@ -0,0 +1,50 @@
+//! Different generators that can create random or systematic bit patterns.
+
+pub mod case_list;
+pub mod edge_cases;
+pub mod random;
+pub mod spaced;
+
+/// A wrapper to turn any iterator into an `ExactSizeIterator`. Asserts the final result to ensure
+/// the provided size was correct.
+#[derive(Debug)]
+pub struct KnownSize<I> {
+    total: u64,
+    current: u64,
+    iter: I,
+}
+
+impl<I> KnownSize<I> {
+    pub fn new(iter: I, total: u64) -> Self {
+        Self {
+            total,
+            current: 0,
+            iter,
+        }
+    }
+}
+
+impl<I: Iterator> Iterator for KnownSize<I> {
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let next = self.iter.next();
+        if next.is_some() {
+            self.current += 1;
+            return next;
+        }
+
+        assert_eq!(
+            self.current, self.total,
+            "total items did not match expected"
+        );
+        None
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let remaining = usize::try_from(self.total - self.current).unwrap();
+        (remaining, Some(remaining))
+    }
+}
+
+impl<I: Iterator> ExactSizeIterator for KnownSize<I> {}