chronologic/iter/
compl.rs1use std::iter::{Fuse, FusedIterator};
2use crate::*;
3use crate::iter::*;
4
5pub trait TimeComplementary: TimeConvexIterator {
7 type Output:TimeConvexIterator<TimePoint=Self::TimePoint>;
8 fn complementary(self) -> Self::Output;
9}
10
11
12impl<TW> TimeComplementary for TW
13 where
14 TW: TimeConvexIterator
15{
16 type Output = IterComplementary<Self>;
17
18 #[inline]
19 fn complementary(self) -> Self::Output {
20 IterComplementary::new(self)
21 }
22}
23
24
25pub struct IterComplementary<I:TimeConvexIterator>
26{
27 iter: Fuse<I>,
28 lower: I::TimePoint
29}
30
31impl<I:TimeConvexIterator> IterComplementary<I>
32{
33 fn new(iter: I) -> Self {
34 Self {
35 iter: iter.fuse(),
36 lower: -I::TimePoint::INFINITE
37 }
38 }
39}
40
41impl<I:TimeConvexIterator> TimeConvexIterator for IterComplementary<I> {
42 type TimePoint = I::TimePoint;
43}
44
45impl<I:TimeConvexIterator> FusedIterator for IterComplementary<I> { }
46
47
48impl<I:TimeConvexIterator> Iterator for IterComplementary<I>
49{
50 type Item = TimeInterval<I::TimePoint>;
51
52 fn next(&mut self) -> Option<Self::Item>
53 {
54 if self.lower.is_past_infinite() {
55 let start = self.iter.next()
57 .and_then(|next| {
58 let upper = next.lower_bound().just_before();
59 self.lower = next.upper_bound().just_after();
60 if upper == -I::TimePoint::INFINITE {
61 None
62 } else {
63 Some(TimeInterval { lower: -I::TimePoint::INFINITE, upper})
64 }
65 });
66 if start.is_some() { return start; }
67 }
68 for next in self.iter.by_ref()
69 {
70 if self.lower < next.lower_bound() {
71 let result = TimeInterval {
72 lower: self.lower,
73 upper: next.lower_bound().just_before()
74 };
75 self.lower = next.upper_bound().just_after();
76 return Some(result);
77 }
78 }
79 if self.lower.is_future_infinite() {
80 None
81 } else {
82 let result = TimeInterval {
83 lower: self.lower,
84 upper: I::TimePoint::INFINITE
85 };
86 self.lower = I::TimePoint::INFINITE;
87 Some(result)
88 }
89 }
90
91 fn size_hint(&self) -> (usize, Option<usize>)
92 {
93 let (min,max) = self.iter.size_hint();
94 if self.lower.is_finite() {
95 (min.saturating_sub(1), max)
96 } else {
97 (min.saturating_sub(1), max.map(|i| i + 1))
98 }
99 }
100}