chronologic/iter/
compl.rs

1use std::iter::{Fuse, FusedIterator};
2use crate::*;
3use crate::iter::*;
4
5/// # The complementary iterator of a time set
6pub 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            // just starting the iteration
56            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}