range_set_blaze/map_from_iter.rs
1use alloc::rc::Rc;
2
3use crate::union_iter_map::UnionIterMap;
4use crate::{Integer, RangeMapBlaze};
5use core::ops::RangeInclusive;
6
7// We create a RangeMapBlaze from an iterator of integers or integer ranges by
8// 1. turning them into a UnionIterMap (internally, it collects into intervals and sorts by start).
9// 2. Turning the SortedDisjointMap into a BTreeMap.
10impl<'a, T, V> FromIterator<(T, &'a V)> for RangeMapBlaze<T, V>
11where
12 T: Integer,
13 V: Eq + Clone + 'a,
14{
15 /// Create a [`RangeMapBlaze`] from an iterator of integers. Duplicates and out-of-order elements are fine.
16 ///
17 /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
18 ///
19 /// # Examples
20 ///
21 /// ```
22 /// use range_set_blaze::RangeMapBlaze;
23 ///
24 /// let a0 = RangeMapBlaze::from_iter([(3, &"a"), (2, &"a"), (1, &"a"), (100, &"b"), (1, &"c")]);
25 /// let a1: RangeMapBlaze<i32, &str> = [(3, &"a"), (2, &"a"), (1, &"a"), (100, &"b"), (1, &"c")].into_iter().collect();
26 /// assert!(a0 == a1 && a0.to_string() == r#"(1..=3, "a"), (100..=100, "b")"#);
27 /// ```
28 fn from_iter<I>(iter: I) -> Self
29 where
30 I: IntoIterator<Item = (T, &'a V)>,
31 {
32 iter.into_iter().map(|(x, r)| (x..=x, r)).collect()
33 }
34}
35
36impl<'a, T, V> FromIterator<(RangeInclusive<T>, &'a V)> for RangeMapBlaze<T, V>
37where
38 T: Integer,
39 V: Eq + Clone,
40{
41 /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
42 /// Overlapping, out-of-order, and empty ranges are fine.
43 ///
44 /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
45 ///
46 /// # Examples
47 ///
48 /// ```
49 /// use range_set_blaze::prelude::*;
50 ///
51 /// #[allow(clippy::reversed_empty_ranges)]
52 /// let a0 = RangeMapBlaze::from_iter([(1..=2, &"a"), (2..=2, &"b"), (-10..=-5, &"c"), (1..=0, &"d")]);
53 /// #[allow(clippy::reversed_empty_ranges)]
54 /// let a1: RangeMapBlaze<i32, &str> = [(1..=2, &"a"), (2..=2, &"b"), (-10..=-5, &"c"), (1..=0, &"d")].into_iter().collect();
55 /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
56 /// ```
57 fn from_iter<I>(iter: I) -> Self
58 where
59 I: IntoIterator<Item = (RangeInclusive<T>, &'a V)>,
60 {
61 let iter = iter.into_iter();
62 let union_iter_map: UnionIterMap<T, &V, _> = iter.collect();
63 Self::from_sorted_disjoint_map(union_iter_map)
64 }
65}
66
67impl<T: Integer, V: Eq + Clone> FromIterator<(RangeInclusive<T>, V)> for RangeMapBlaze<T, V> {
68 /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
69 /// Overlapping, out-of-order, and empty ranges are fine.
70 ///
71 /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
72 ///
73 /// # Examples
74 ///
75 /// ```
76 /// use range_set_blaze::RangeMapBlaze;
77 ///
78 /// #[allow(clippy::reversed_empty_ranges)]
79 /// let a0 = RangeMapBlaze::from_iter([(1..=2, "a"), (2..=2, "b"), (-10..=-5, "c"), (1..=0, "d")]);
80 /// #[allow(clippy::reversed_empty_ranges)]
81 /// let a1: RangeMapBlaze<i32, &str> = [(1..=2, "a"), (2..=2, "b"), (-10..=-5, "c"), (1..=0, "d")].into_iter().collect();
82 /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
83 /// ```
84 fn from_iter<I>(iter: I) -> Self
85 where
86 I: IntoIterator<Item = (RangeInclusive<T>, V)>,
87 {
88 let union_iter_map = iter
89 .into_iter()
90 .map(|(r, v)| (r, Rc::new(v)))
91 .collect::<UnionIterMap<T, Rc<V>, _>>();
92 Self::from_sorted_disjoint_map(union_iter_map)
93 }
94}
95
96impl<T: Integer, V: Eq + Clone> FromIterator<(T, V)> for RangeMapBlaze<T, V> {
97 /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
98 /// Overlapping, out-of-order, and empty ranges are fine.
99 ///
100 /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
101 ///
102 /// # Examples
103 ///
104 /// ```
105 /// use range_set_blaze::prelude::*;
106 ///
107 /// #[allow(clippy::reversed_empty_ranges)]
108 /// let a0 = RangeMapBlaze::from_iter([(3, "a"), (2, "a"), (1, "a"), (100, "b"), (1, "c")]);
109 /// let a1: RangeMapBlaze<i32, &str> = [(3, "a"), (2, "a"), (1, "a"), (100, "b"), (1, "c")].into_iter().collect();
110 /// assert!(a0 == a1 && a0.to_string() == r#"(1..=3, "a"), (100..=100, "b")"#);
111 /// ```
112 fn from_iter<I>(iter: I) -> Self
113 where
114 I: IntoIterator<Item = (T, V)>,
115 {
116 iter.into_iter().map(|(k, v)| (k..=k, v)).collect()
117 }
118}
119
120impl<'a, T, V> FromIterator<&'a (T, &'a V)> for RangeMapBlaze<T, V>
121where
122 T: Integer,
123 V: Eq + Clone + 'a,
124{
125 /// Create a [`RangeMapBlaze`] from an iterator of integers. Duplicates and out-of-order elements are fine.
126 ///
127 /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
128 ///
129 /// # Examples
130 ///
131 /// ```
132 /// use range_set_blaze::RangeMapBlaze;
133 ///
134 /// let v = vec![(3, &"a"), (2, &"a"), (1, &"a"), (100, &"b"), (1, &"c")];
135 /// let a0 = RangeMapBlaze::from_iter(&v);
136 /// let a1: RangeMapBlaze<i32, &str> = (&v).into_iter().collect();
137 /// assert!(a0 == a1 && a0.to_string() == r#"(1..=3, "a"), (100..=100, "b")"#);
138 /// ```
139 fn from_iter<I>(iter: I) -> Self
140 where
141 I: IntoIterator<Item = &'a (T, &'a V)>,
142 {
143 iter.into_iter().map(|&(x, r)| (x..=x, r)).collect()
144 }
145}
146
147impl<'a, T, V> FromIterator<&'a (RangeInclusive<T>, &'a V)> for RangeMapBlaze<T, V>
148where
149 T: Integer,
150 V: Eq + Clone,
151{
152 /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
153 /// Overlapping, out-of-order, and empty ranges are fine.
154 ///
155 /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
156 ///
157 /// # Examples
158 ///
159 /// ```
160 /// use range_set_blaze::prelude::*;
161 ///
162 /// let v = vec![(1..=2, &"a"), (2..=2, &"b"), (-10..=-5, &"c"), (1..=0, &"d")];
163 /// let a0: RangeMapBlaze<i32, &str> = RangeMapBlaze::from_iter(&v);
164 /// let a1: RangeMapBlaze<i32, &str> = (&v).into_iter().collect();
165 /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
166 /// ```
167 fn from_iter<I>(iter: I) -> Self
168 where
169 I: IntoIterator<Item = &'a (RangeInclusive<T>, &'a V)>,
170 {
171 iter.into_iter().map(|(r, v)| (r.clone(), *v)).collect()
172 }
173}
174
175impl<'a, T: Integer, V: Eq + Clone> FromIterator<&'a (RangeInclusive<T>, V)>
176 for RangeMapBlaze<T, V>
177{
178 /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
179 /// Overlapping, out-of-order, and empty ranges are fine.
180 ///
181 /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
182 ///
183 /// # Examples
184 ///
185 /// ```
186 /// use range_set_blaze::prelude::*;
187 ///
188 /// #[allow(clippy::reversed_empty_ranges)]
189 /// let vec_range = vec![(1..=2, "a"), (2..=2, "b"), (-10..=-5, "c"), (1..=0, "d")];
190 /// let a0 = RangeMapBlaze::from_iter(&vec_range);
191 /// let a1: RangeMapBlaze<i32, &str> = vec_range.iter().collect();
192 /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
193 /// ```
194 fn from_iter<I>(iter: I) -> Self
195 where
196 I: IntoIterator<Item = &'a (RangeInclusive<T>, V)>,
197 {
198 iter.into_iter().map(|(r, v)| (r.clone(), v)).collect()
199 }
200}
201
202impl<'a, T: Integer, V: Eq + Clone> FromIterator<&'a (T, V)> for RangeMapBlaze<T, V> {
203 /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
204 /// Overlapping, out-of-order, and empty ranges are fine.
205 ///
206 /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
207 ///
208 /// # Examples
209 ///
210 /// ```
211 /// use range_set_blaze::prelude::*;
212 ///
213 /// let v = vec![(1, "a"), (2, "a"), (2, "b")];
214 /// let a0 = RangeMapBlaze::from_iter(&v);
215 /// let a1: RangeMapBlaze<i32, &str> = v.iter().collect();
216 /// assert!(a0 == a1 && a0.to_string() == r#"(1..=2, "a")"#);
217 /// ```
218 fn from_iter<I>(iter: I) -> Self
219 where
220 I: IntoIterator<Item = &'a (T, V)>,
221 {
222 iter.into_iter()
223 .map(|(k, v)| {
224 let k = *k;
225 (k..=k, v)
226 })
227 .collect()
228 }
229}