summaryrefslogtreecommitdiffstats
path: root/third_party/rust/itertools/tests/specializations.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/itertools/tests/specializations.rs')
-rw-r--r--third_party/rust/itertools/tests/specializations.rs149
1 files changed, 149 insertions, 0 deletions
diff --git a/third_party/rust/itertools/tests/specializations.rs b/third_party/rust/itertools/tests/specializations.rs
new file mode 100644
index 0000000000..ef51bbedf0
--- /dev/null
+++ b/third_party/rust/itertools/tests/specializations.rs
@@ -0,0 +1,149 @@
+use itertools::{EitherOrBoth, Itertools};
+use std::fmt::Debug;
+use std::ops::BitXor;
+use quickcheck::quickcheck;
+
+struct Unspecialized<I>(I);
+impl<I> Iterator for Unspecialized<I>
+where
+ I: Iterator,
+{
+ type Item = I::Item;
+
+ #[inline(always)]
+ fn next(&mut self) -> Option<I::Item> {
+ self.0.next()
+ }
+
+ #[inline(always)]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
+}
+
+fn check_specialized<'a, V, IterItem, Iter, F>(iterator: &Iter, mapper: F)
+where
+ V: Eq + Debug,
+ IterItem: 'a,
+ Iter: Iterator<Item = IterItem> + Clone + 'a,
+ F: Fn(Box<dyn Iterator<Item = IterItem> + 'a>) -> V,
+{
+ assert_eq!(
+ mapper(Box::new(Unspecialized(iterator.clone()))),
+ mapper(Box::new(iterator.clone()))
+ )
+}
+
+fn check_specialized_count_last_nth_sizeh<'a, IterItem, Iter>(
+ it: &Iter,
+ known_expected_size: Option<usize>,
+) where
+ IterItem: 'a + Eq + Debug,
+ Iter: Iterator<Item = IterItem> + Clone + 'a,
+{
+ let size = it.clone().count();
+ if let Some(expected_size) = known_expected_size {
+ assert_eq!(size, expected_size);
+ }
+ check_specialized(it, |i| i.count());
+ check_specialized(it, |i| i.last());
+ for n in 0..size + 2 {
+ check_specialized(it, |mut i| i.nth(n));
+ }
+ let mut it_sh = it.clone();
+ for n in 0..size + 2 {
+ let len = it_sh.clone().count();
+ let (min, max) = it_sh.size_hint();
+ assert_eq!((size - n.min(size)), len);
+ assert!(min <= len);
+ if let Some(max) = max {
+ assert!(len <= max);
+ }
+ it_sh.next();
+ }
+}
+
+fn check_specialized_fold_xor<'a, IterItem, Iter>(it: &Iter)
+where
+ IterItem: 'a
+ + BitXor
+ + Eq
+ + Debug
+ + BitXor<<IterItem as BitXor>::Output, Output = <IterItem as BitXor>::Output>
+ + Clone,
+ <IterItem as BitXor>::Output:
+ BitXor<Output = <IterItem as BitXor>::Output> + Eq + Debug + Clone,
+ Iter: Iterator<Item = IterItem> + Clone + 'a,
+{
+ check_specialized(it, |mut i| {
+ let first = i.next().map(|f| f.clone() ^ (f.clone() ^ f));
+ i.fold(first, |acc, v: IterItem| acc.map(move |a| v ^ a))
+ });
+}
+
+fn put_back_test(test_vec: Vec<i32>, known_expected_size: Option<usize>) {
+ {
+ // Lexical lifetimes support
+ let pb = itertools::put_back(test_vec.iter());
+ check_specialized_count_last_nth_sizeh(&pb, known_expected_size);
+ check_specialized_fold_xor(&pb);
+ }
+
+ let mut pb = itertools::put_back(test_vec.into_iter());
+ pb.put_back(1);
+ check_specialized_count_last_nth_sizeh(&pb, known_expected_size.map(|x| x + 1));
+ check_specialized_fold_xor(&pb)
+}
+
+#[test]
+fn put_back() {
+ put_back_test(vec![7, 4, 1], Some(3));
+}
+
+quickcheck! {
+ fn put_back_qc(test_vec: Vec<i32>) -> () {
+ put_back_test(test_vec, None)
+ }
+}
+
+fn merge_join_by_test(i1: Vec<usize>, i2: Vec<usize>, known_expected_size: Option<usize>) {
+ let i1 = i1.into_iter();
+ let i2 = i2.into_iter();
+ let mjb = i1.clone().merge_join_by(i2.clone(), std::cmp::Ord::cmp);
+ check_specialized_count_last_nth_sizeh(&mjb, known_expected_size);
+ // Rust 1.24 compatibility:
+ fn eob_left_z(eob: EitherOrBoth<usize, usize>) -> usize {
+ eob.left().unwrap_or(0)
+ }
+ fn eob_right_z(eob: EitherOrBoth<usize, usize>) -> usize {
+ eob.left().unwrap_or(0)
+ }
+ fn eob_both_z(eob: EitherOrBoth<usize, usize>) -> usize {
+ let (a, b) = eob.both().unwrap_or((0, 0));
+ assert_eq!(a, b);
+ a
+ }
+ check_specialized_fold_xor(&mjb.clone().map(eob_left_z));
+ check_specialized_fold_xor(&mjb.clone().map(eob_right_z));
+ check_specialized_fold_xor(&mjb.clone().map(eob_both_z));
+
+ // And the other way around
+ let mjb = i2.merge_join_by(i1, std::cmp::Ord::cmp);
+ check_specialized_count_last_nth_sizeh(&mjb, known_expected_size);
+ check_specialized_fold_xor(&mjb.clone().map(eob_left_z));
+ check_specialized_fold_xor(&mjb.clone().map(eob_right_z));
+ check_specialized_fold_xor(&mjb.clone().map(eob_both_z));
+}
+
+#[test]
+fn merge_join_by() {
+ let i1 = vec![1, 3, 5, 7, 8, 9];
+ let i2 = vec![0, 3, 4, 5];
+ merge_join_by_test(i1, i2, Some(8));
+}
+
+quickcheck! {
+ fn merge_join_by_qc(i1: Vec<usize>, i2: Vec<usize>) -> () {
+ merge_join_by_test(i1, i2, None)
+ }
+}