range_set_blaze/
iter_map.rs

1use core::{iter::FusedIterator, ops::RangeInclusive};
2
3use alloc::collections::btree_map;
4
5use crate::{
6    Integer, SortedDisjointMap,
7    map::{EndValue, ValueRef},
8};
9
10/// An iterator over the integer elements of a [`RangeMapBlaze`]. Double-ended.
11///
12/// This `struct` is created by the [`iter`] method on [`RangeMapBlaze`]. See its
13/// documentation for more.
14///
15/// [`RangeMapBlaze`]: crate::map::RangeMapBlaze
16/// [`iter`]: crate::RangeMapBlaze::iter
17#[must_use = "iterators are lazy and do nothing unless consumed"]
18#[derive(Clone, Debug)]
19pub struct IterMap<T, VR, I>
20where
21    T: Integer,
22    VR: ValueRef,
23    I: SortedDisjointMap<T, VR>,
24{
25    iter: I,
26    option_range_value_front: Option<(RangeInclusive<T>, VR)>,
27    option_range_value_back: Option<(RangeInclusive<T>, VR)>,
28}
29
30impl<T, VR, I> IterMap<T, VR, I>
31where
32    T: Integer,
33    VR: ValueRef,
34    I: SortedDisjointMap<T, VR>,
35{
36    pub(crate) const fn new(iter: I) -> Self {
37        Self {
38            iter,
39            option_range_value_front: None,
40            option_range_value_back: None,
41        }
42    }
43}
44
45impl<T, VR, I> FusedIterator for IterMap<T, VR, I>
46where
47    T: Integer,
48    VR: ValueRef,
49    I: SortedDisjointMap<T, VR> + FusedIterator,
50{
51}
52
53impl<T, VR, I> Iterator for IterMap<T, VR, I>
54where
55    T: Integer,
56    VR: ValueRef,
57    I: SortedDisjointMap<T, VR>,
58{
59    type Item = (T, VR);
60
61    fn next(&mut self) -> Option<Self::Item> {
62        let mut range_value = self
63            .option_range_value_front
64            .take()
65            .or_else(|| self.iter.next())
66            .or_else(|| self.option_range_value_back.take())?;
67
68        let (start, end) = range_value.0.into_inner();
69        debug_assert!(start <= end);
70        let value = range_value.1.clone();
71        if start < end {
72            range_value.0 = start.add_one()..=end;
73            self.option_range_value_front = Some(range_value);
74        }
75        Some((start, value))
76    }
77
78    // We'll have at least as many integers as intervals. There could be more that usize MAX
79    // The option_range field could increase the number of integers, but we can ignore that.
80    fn size_hint(&self) -> (usize, Option<usize>) {
81        let (low, _high) = self.iter.size_hint();
82        (low, None)
83    }
84}
85
86impl<T, VR, I> DoubleEndedIterator for IterMap<T, VR, I>
87where
88    T: Integer,
89    VR: ValueRef,
90    I: SortedDisjointMap<T, VR> + DoubleEndedIterator,
91{
92    fn next_back(&mut self) -> Option<Self::Item> {
93        let mut range_value = self
94            .option_range_value_back
95            .take()
96            .or_else(|| self.iter.next_back())
97            .or_else(|| self.option_range_value_front.take())?;
98        let (start, end) = range_value.0.into_inner();
99        debug_assert!(start <= end);
100        let value = range_value.1.clone();
101        if start < end {
102            range_value.0 = start..=end.sub_one();
103            self.option_range_value_back = Some(range_value);
104        }
105
106        Some((end, value))
107    }
108}
109
110/// An iterator over the integer elements of a [`RangeMapBlaze`]. Double-ended.
111///
112/// This `struct` is created by the [`into_iter`] method on [`RangeMapBlaze`]. See its
113/// documentation for more.
114///
115/// [`RangeMapBlaze`]: crate::map::RangeMapBlaze
116/// [`into_iter`]: crate::RangeMapBlaze::into_iter
117#[derive(Debug)]
118#[must_use = "iterators are lazy and do nothing unless consumed"]
119pub struct IntoIterMap<T, V>
120where
121    T: Integer,
122    V: Eq + Clone,
123{
124    option_start_end_value_front: Option<(T, EndValue<T, V>)>,
125    option_start_end_value_back: Option<(T, EndValue<T, V>)>,
126    into_iter: btree_map::IntoIter<T, EndValue<T, V>>,
127}
128
129impl<T, V> IntoIterMap<T, V>
130where
131    T: Integer,
132    V: Eq + Clone,
133{
134    pub(crate) const fn new(into_iter: btree_map::IntoIter<T, EndValue<T, V>>) -> Self {
135        Self {
136            option_start_end_value_front: None,
137            option_start_end_value_back: None,
138            into_iter,
139        }
140    }
141}
142
143impl<T, V> FusedIterator for IntoIterMap<T, V>
144where
145    T: Integer,
146    V: Eq + Clone,
147{
148}
149
150impl<T, V> Iterator for IntoIterMap<T, V>
151where
152    T: Integer,
153    V: Eq + Clone,
154{
155    type Item = (T, V);
156
157    fn next(&mut self) -> Option<Self::Item> {
158        let (start, end_value) = self
159            .option_start_end_value_front
160            .take()
161            .or_else(|| self.into_iter.next())
162            .or_else(|| self.option_start_end_value_back.take())?;
163
164        let end = end_value.end;
165        let value = end_value.value.clone();
166        debug_assert!(start <= end);
167        if start < end {
168            let start_plus1_end_value = (start.add_one(), end_value);
169            self.option_start_end_value_front = Some(start_plus1_end_value);
170        }
171        Some((start, value))
172    }
173
174    // We'll have at least as many integers as intervals. There could be more that usize MAX
175    // the option_range field could increase the number of integers, but we can ignore that.
176    fn size_hint(&self) -> (usize, Option<usize>) {
177        let (low, _high) = self.into_iter.size_hint();
178        (low, None)
179    }
180}
181
182impl<T, V> DoubleEndedIterator for IntoIterMap<T, V>
183where
184    T: Integer,
185    V: Eq + Clone,
186{
187    fn next_back(&mut self) -> Option<Self::Item> {
188        let (start, mut end_value) = self
189            .option_start_end_value_back
190            .take()
191            .or_else(|| self.into_iter.next_back())
192            .or_else(|| self.option_start_end_value_front.take())?;
193
194        let end = end_value.end;
195        let value = end_value.value.clone();
196        debug_assert!(start <= end);
197
198        if start < end {
199            end_value.end.assign_sub_one();
200            let start_end_less1_value = (start, end_value);
201            self.option_start_end_value_back = Some(start_end_less1_value);
202        }
203
204        Some((end, value))
205    }
206}