1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use std::mem;
pub fn partition<'a, T: 'a, I, F>(mut it: I, pred: F) -> usize
where I: DoubleEndedIterator<Item = &'a mut T>,
F: Fn(&T) -> bool {
let mut split_idx = 0;
loop {
let mut front = None;
let mut back = None;
while let Some(f) = it.next() {
if !pred(f) {
front = Some(f);
break;
} else {
split_idx += 1;
}
}
while let Some(b) = it.next_back() {
if pred(b) {
back = Some(b);
break;
}
}
match (front, back) {
(Some(f), Some(b)) => {
mem::swap(f, b);
split_idx += 1;
},
_ => break,
}
}
split_idx
}
#[test]
fn test_partition() {
let mut vals = vec![1u32, 2, 3, 4, 5, 6];
let idx = partition(vals.iter_mut(), |x| *x % 2 == 0);
println!("Partition idx = {}", idx);
println!("Partitioned: {:?}", vals);
assert_eq!(idx, 3);
assert!(vals.iter().take(3).fold(true, |f, x| *x % 2 == 0 && f));
assert!(vals.iter().skip(3).fold(true, |f, x| *x % 2 != 0 && f));
}