|
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;
|
@@ -995,75 +996,65 @@ fn test_rsplitnator() {
|
995 | 996 |
|
996 | 997 | #[test]
|
997 | 998 | fn test_split_iterators_size_hint() {
|
998 |
| - for len in 0..=2 { |
999 |
| - let mut v: Vec<u8> = (0..len).collect(); |
1000 |
| - fn verify_descending(sequence: &[usize], context: &str) { |
1001 |
| - let len = sequence.len(); |
1002 |
| - let target: Vec<usize> = (0..len).rev().collect(); |
1003 |
| - assert_eq!(sequence, target, "while testing: {}", context); |
1004 |
| - } |
1005 |
| - |
1006 |
| - macro_rules! test_size_hint { |
1007 |
| - ($create_iterator:expr) => {{ |
1008 |
| - // with a predicate always returning false, the split*-iterators |
1009 |
| - // become maximally short, so the size_hint lower bounds are correct |
1010 |
| - |
1011 |
| - macro_rules! p { |
1012 |
| - () => { |
1013 |
| - |_| false |
1014 |
| - }; |
1015 |
| - } |
1016 |
| - let mut short_iterator = $create_iterator; |
1017 |
| - let mut lower_bounds = vec![short_iterator.size_hint().0]; |
1018 |
| - while let Some(_) = short_iterator.next() { |
1019 |
| - lower_bounds.push(short_iterator.size_hint().0); |
| 999 | + #[derive(Copy, Clone)] |
| 1000 | + enum Bounds { |
| 1001 | + Lower, |
| 1002 | + Upper, |
| 1003 | + } |
| 1004 | + fn assert_precise_size_hints<I: Iterator>( |
| 1005 | + mut it: I, |
| 1006 | + which: Bounds, |
| 1007 | + context: impl fmt::Display, |
| 1008 | + ) { |
| 1009 | + match which { |
| 1010 | + Bounds::Lower => { |
| 1011 | + let mut lower_bounds = vec![it.size_hint().0]; |
| 1012 | + while let Some(_) = it.next() { |
| 1013 | + lower_bounds.push(it.size_hint().0); |
1020 | 1014 | }
|
1021 |
| - verify_descending(&lower_bounds, stringify!($create_iterator)); |
| 1015 | + let target: Vec<_> = (0..lower_bounds.len()).rev().collect(); |
| 1016 | + assert_eq!(lower_bounds, target, "incorrect lower bounds: {}", context); |
1022 | 1017 | }
|
1023 |
| - { |
1024 |
| - // with a predicate always returning true, the split*-iterators |
1025 |
| - // become maximally long, so the size_hint upper bounds are correct |
1026 |
| - |
1027 |
| - macro_rules! p { |
1028 |
| - () => { |
1029 |
| - |_| true |
1030 |
| - }; |
1031 |
| - } |
1032 |
| - let mut long_iterator = $create_iterator; |
1033 |
| - let mut upper_bounds = vec![ |
1034 |
| - long_iterator.size_hint().1.expect("split*-methods have known upper bound"), |
1035 |
| - ]; |
1036 |
| - while let Some(_) = long_iterator.next() { |
1037 |
| - upper_bounds.push( |
1038 |
| - long_iterator.size_hint().1.expect("split*-methods have known upper bound"), |
1039 |
| - ); |
| 1018 | + Bounds::Upper => { |
| 1019 | + let mut upper_bounds = vec![it.size_hint().1]; |
| 1020 | + while let Some(_) = it.next() { |
| 1021 | + upper_bounds.push(it.size_hint().1); |
1040 | 1022 | }
|
1041 |
| - verify_descending(&upper_bounds, stringify!($create_iterator)); |
1042 |
| - }}; |
| 1023 | + let target: Vec<_> = (0..upper_bounds.len()).map(Some).rev().collect(); |
| 1024 | + assert_eq!(upper_bounds, target, "incorrect upper bounds: {}", context); |
| 1025 | + } |
1043 | 1026 | }
|
| 1027 | + } |
1044 | 1028 |
|
1045 |
| - test_size_hint!(v.split(p!())); |
1046 |
| - test_size_hint!(v.split_mut(p!())); |
1047 |
| - test_size_hint!(v.splitn(0, p!())); |
1048 |
| - test_size_hint!(v.splitn(1, p!())); |
1049 |
| - test_size_hint!(v.splitn(2, p!())); |
1050 |
| - test_size_hint!(v.splitn(3, p!())); |
1051 |
| - test_size_hint!(v.splitn_mut(0, p!())); |
1052 |
| - test_size_hint!(v.splitn_mut(1, p!())); |
1053 |
| - test_size_hint!(v.splitn_mut(2, p!())); |
1054 |
| - test_size_hint!(v.splitn_mut(3, p!())); |
1055 |
| - test_size_hint!(v.split_inclusive(p!())); |
1056 |
| - test_size_hint!(v.split_inclusive_mut(p!())); |
1057 |
| - test_size_hint!(v.rsplit(p!())); |
1058 |
| - test_size_hint!(v.rsplit_mut(p!())); |
1059 |
| - test_size_hint!(v.rsplitn(0, p!())); |
1060 |
| - test_size_hint!(v.rsplitn(1, p!())); |
1061 |
| - test_size_hint!(v.rsplitn(2, p!())); |
1062 |
| - test_size_hint!(v.rsplitn(3, p!())); |
1063 |
| - test_size_hint!(v.rsplitn_mut(0, p!())); |
1064 |
| - test_size_hint!(v.rsplitn_mut(1, p!())); |
1065 |
| - test_size_hint!(v.rsplitn_mut(2, p!())); |
1066 |
| - test_size_hint!(v.rsplitn_mut(3, p!())); |
| 1029 | + for len in 0..=2 { |
| 1030 | + let mut v: Vec<u8> = (0..len).collect(); |
| 1031 | + |
| 1032 | + // p: predicate, b: bound selection |
| 1033 | + for (p, b) in [ |
| 1034 | + // with a predicate always returning false, the split*-iterators |
| 1035 | + // become maximally short, so the size_hint lower bounds are correct |
| 1036 | + ((|_| false) as fn(&_) -> _, Bounds::Lower), |
| 1037 | + // with a predicate always returning true, the split*-iterators |
| 1038 | + // become maximally long, so the size_hint upper bounds are correct |
| 1039 | + ((|_| true) as fn(&_) -> _, Bounds::Upper), |
| 1040 | + ] { |
| 1041 | + use assert_precise_size_hints as a; |
| 1042 | + use format_args as f; |
| 1043 | + |
| 1044 | + a(v.split(p), b, "split"); |
| 1045 | + a(v.split_mut(p), b, "split_mut"); |
| 1046 | + a(v.split_inclusive(p), b, "split_inclusive"); |
| 1047 | + a(v.split_inclusive_mut(p), b, "split_inclusive_mut"); |
| 1048 | + a(v.rsplit(p), b, "rsplit"); |
| 1049 | + a(v.rsplit_mut(p), b, "rsplit_mut"); |
| 1050 | + |
| 1051 | + for n in 0..=3 { |
| 1052 | + a(v.splitn(n, p), b, f!("splitn, n = {}", n)); |
| 1053 | + a(v.splitn_mut(n, p), b, f!("splitn_mut, n = {}", n)); |
| 1054 | + a(v.rsplitn(n, p), b, f!("rsplitn, n = {}", n)); |
| 1055 | + a(v.rsplitn_mut(n, p), b, f!("rsplitn_mut, n = {}", n)); |
| 1056 | + } |
| 1057 | + } |
1067 | 1058 | }
|
1068 | 1059 | }
|
1069 | 1060 |
|
|
0 commit comments