Skip to main content

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