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#[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 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#[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 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}