|
1 | 1 | use std::cell::Cell;
|
2 | 2 | use std::cmp::Ordering::{self, Equal, Greater, Less};
|
3 | 3 | use std::convert::identity;
|
| 4 | +use std::fmt; |
4 | 5 | use std::mem;
|
5 | 6 | use std::panic;
|
6 | 7 | use std::rc::Rc;
|
@@ -993,6 +994,66 @@ fn test_rsplitnator() {
|
993 | 994 | assert!(xs.rsplitn(0, |x| *x % 2 == 0).next().is_none());
|
994 | 995 | }
|
995 | 996 |
|
| 997 | +#[test] |
| 998 | +fn test_split_iterators_size_hint() { |
| 999 | + #[derive(Copy, Clone)] |
| 1000 | + enum Bounds { |
| 1001 | + Lower, |
| 1002 | + Upper, |
| 1003 | + } |
| 1004 | + fn assert_tight_size_hints(mut it: impl Iterator, which: Bounds, ctx: impl fmt::Display) { |
| 1005 | + match which { |
| 1006 | + Bounds::Lower => { |
| 1007 | + let mut lower_bounds = vec![it.size_hint().0]; |
| 1008 | + while let Some(_) = it.next() { |
| 1009 | + lower_bounds.push(it.size_hint().0); |
| 1010 | + } |
| 1011 | + let target: Vec<_> = (0..lower_bounds.len()).rev().collect(); |
| 1012 | + assert_eq!(lower_bounds, target, "lower bounds incorrect or not tight: {}", ctx); |
| 1013 | + } |
| 1014 | + Bounds::Upper => { |
| 1015 | + let mut upper_bounds = vec![it.size_hint().1]; |
| 1016 | + while let Some(_) = it.next() { |
| 1017 | + upper_bounds.push(it.size_hint().1); |
| 1018 | + } |
| 1019 | + let target: Vec<_> = (0..upper_bounds.len()).map(Some).rev().collect(); |
| 1020 | + assert_eq!(upper_bounds, target, "upper bounds incorrect or not tight: {}", ctx); |
| 1021 | + } |
| 1022 | + } |
| 1023 | + } |
| 1024 | + |
| 1025 | + for len in 0..=2 { |
| 1026 | + let mut v: Vec<u8> = (0..len).collect(); |
| 1027 | + |
| 1028 | + // p: predicate, b: bound selection |
| 1029 | + for (p, b) in [ |
| 1030 | + // with a predicate always returning false, the split*-iterators |
| 1031 | + // become maximally short, so the size_hint lower bounds are tight |
| 1032 | + ((|_| false) as fn(&_) -> _, Bounds::Lower), |
| 1033 | + // with a predicate always returning true, the split*-iterators |
| 1034 | + // become maximally long, so the size_hint upper bounds are tight |
| 1035 | + ((|_| true) as fn(&_) -> _, Bounds::Upper), |
| 1036 | + ] { |
| 1037 | + use assert_tight_size_hints as a; |
| 1038 | + use format_args as f; |
| 1039 | + |
| 1040 | + a(v.split(p), b, "split"); |
| 1041 | + a(v.split_mut(p), b, "split_mut"); |
| 1042 | + a(v.split_inclusive(p), b, "split_inclusive"); |
| 1043 | + a(v.split_inclusive_mut(p), b, "split_inclusive_mut"); |
| 1044 | + a(v.rsplit(p), b, "rsplit"); |
| 1045 | + a(v.rsplit_mut(p), b, "rsplit_mut"); |
| 1046 | + |
| 1047 | + for n in 0..=3 { |
| 1048 | + a(v.splitn(n, p), b, f!("splitn, n = {}", n)); |
| 1049 | + a(v.splitn_mut(n, p), b, f!("splitn_mut, n = {}", n)); |
| 1050 | + a(v.rsplitn(n, p), b, f!("rsplitn, n = {}", n)); |
| 1051 | + a(v.rsplitn_mut(n, p), b, f!("rsplitn_mut, n = {}", n)); |
| 1052 | + } |
| 1053 | + } |
| 1054 | + } |
| 1055 | +} |
| 1056 | + |
996 | 1057 | #[test]
|
997 | 1058 | fn test_windowsator() {
|
998 | 1059 | let v = &[1, 2, 3, 4];
|
|
0 commit comments