1use std::iter::{FusedIterator};
2use crate::TopSet;
3
4pub struct IntoIterSorted<X,C>(TopSet<X,C>)
5 where C: Fn(&X,&X) -> bool;
6
7impl<X,C> From<TopSet<X,C>> for IntoIterSorted<X,C>
8 where C: Fn(&X,&X) -> bool
9{
10 #[inline] fn from(topset: TopSet<X, C>) -> Self { Self(topset) }
11}
12
13impl<X,C> IntoIterSorted<X,C>
14 where C: Fn(&X,&X) -> bool
15{
16 #[inline] pub fn peek(&self) -> Option<&X> { self.0.peek() }
17}
18
19impl<X,C> Iterator for IntoIterSorted<X,C>
20 where C: Fn(&X,&X) -> bool
21{
22 type Item = X;
23 #[inline] fn next(&mut self) -> Option<Self::Item> { self.0.pop() }
24 #[inline] fn count(self) -> usize { self.0.len() }
25 #[inline] fn size_hint(&self) -> (usize, Option<usize>) { (self.0.len(), Some(self.0.len())) }
26 #[inline] fn last(self) -> Option<X> {
27 self.0.heap.into_iter().reduce(|a,b| if (self.0.beat)(&a,&b) {a} else {b})
28 }
29}
30
31impl<X,C:Fn(&X,&X)->bool> FusedIterator for IntoIterSorted<X,C> { }
32
33impl<X,C> ExactSizeIterator for IntoIterSorted<X,C>
36 where C: Fn(&X,&X) -> bool
37{
38 #[inline] fn len(&self) -> usize { self.0.len() }
39
40 }
42
43pub trait TopSetReducing
44{
45 type Item;
46
47 fn topset<C>(self, n: usize, beat: C) -> TopSet<Self::Item, C>
49 where C: Fn(&Self::Item, &Self::Item) -> bool;
50
51 #[inline]
53 #[allow(clippy::type_complexity)]
54 fn topset_greatest(self, n: usize) -> TopSet<Self::Item, fn(&Self::Item,&Self::Item)->bool>
55 where Self::Item: PartialOrd, Self: Sized
56 {
57 self.topset(n, <Self::Item as PartialOrd>::gt)
58 }
59
60 #[inline]
62 #[allow(clippy::type_complexity)]
63 fn topset_lowest(self, n: usize) -> TopSet<Self::Item, fn(&Self::Item,&Self::Item)->bool>
64 where Self::Item: PartialOrd, Self: Sized
65 {
66 self.topset(n, <Self::Item as PartialOrd>::lt)
67 }
68}
69
70impl<I:IntoIterator> TopSetReducing for I
71{
72 type Item = I::Item;
73
74 #[inline]
75 fn topset<C>(self, n: usize, beat: C) -> TopSet<Self::Item, C>
76 where C: Fn(&Self::Item, &Self::Item) -> bool
77 {
78 self.into_iter().fold(TopSet::new(n,beat), |mut top, e| { top.insert(e); top })
79 }
80}
81
82
83#[cfg(test)]
84mod tests {
85 use crate::iter::TopSetReducing;
86
87 #[test]
88 fn lowest_cost()
89 {
90 let mut top = vec![
91 81.5, 4.5, 4., 1., 45., 22., 11., 81.5, 4.5, 4., 1., 45., 22., 11.
92 ].topset_lowest(5);
93
94 assert_eq![top.pop(), Some(4.5)];
95 assert_eq![top.pop(), Some(4.)];
96 assert_eq![top.pop(), Some(4.)];
97 assert_eq![top.pop(), Some(1.)];
98 assert_eq![top.pop(), Some(1.)];
99 assert_eq![top.pop(), None];
100 }
101
102 #[test]
103 fn greatest_score()
104 {
105 assert_eq![
106 vec![81, 5, 4, 5, 4, 1, 45, 22, 1, 5, 97, 5, 877, 12, 0]
107 .topset_greatest(5)
108 .into_iter()
109 .last(),
110 Some(877)];
111 }
112
113 #[test]
114 fn iterator()
115 {
116 let top = vec![ 4, 9, 7, 3, 4, 1 ].topset_lowest(3);
117
118 let iter = top.clone().into_iter_sorted();
119 assert_eq!( iter.len(), 3);
120 assert_eq!( iter.count(), 3);
121
122 let iter = top.into_iter_sorted();
123 assert_eq!( iter.peek(), Some(&4));
124 assert_eq!( iter.size_hint(), (3, Some(3)));
125 assert_eq!( iter.last(), Some(1));
126 }
127}