closed_interval_set/
union.rs1use crate::Backing;
2use crate::ClosedRange;
3use crate::Endpoint;
4use crate::RangeCase;
5use crate::RangeVec;
6
7#[inline]
17pub fn union_vec<T: Endpoint>(
18 acc: impl Into<RangeCase<T>>,
19 src: impl IntoIterator<Item: ClosedRange<EndT = T>>,
20) -> RangeVec<T> {
21 fn doit<T: Endpoint>(
22 mut acc: Backing<T>,
23 src: impl Iterator<Item: ClosedRange<EndT = T>>,
24 ) -> RangeVec<T> {
25 acc.extend(src.map(|range| range.get()));
26 crate::normalize_vec(acc)
27 }
28
29 doit(acc.into().into_inner(), src.into_iter())
30}
31
32impl<T: Endpoint> RangeVec<T> {
33 #[inline(always)]
46 pub fn into_union(self, other: impl Into<RangeCase<T>>) -> Self {
47 #[cfg(feature = "internal_checks")]
48 use crate::NormalizedRangeIter;
49
50 fn doit<T: Endpoint>(mut x: Backing<T>, mut y: Backing<T>) -> RangeVec<T> {
51 if y.len() > x.len() {
52 core::mem::swap(&mut x, &mut y);
53 }
54
55 debug_assert!(x.len() >= y.len());
57 union_vec(x, y)
58 }
59
60 let other = other.into().into_inner();
61
62 #[cfg(feature = "internal_checks")]
63 let expected = (
64 self.iter()
65 .union(RangeVec::from_smallvec(other.clone()))
66 .collect_range_vec(),
67 RangeVec::from_smallvec(other.clone())
68 .iter()
69 .union(self.iter())
70 .collect_range_vec(),
71 );
72
73 let ret = doit(self.into_inner(), other);
74
75 #[cfg(feature = "internal_checks")]
76 {
77 assert!(expected.0.eqv(&ret));
78 assert!(expected.1.eqv(&ret));
79 }
80
81 ret
82 }
83}
84
85#[cfg(test)]
86#[cfg_attr(coverage_nightly, coverage(off))]
87mod test {
88 use super::*;
89 use alloc::vec;
90 use alloc::vec::Vec;
91
92 #[test]
93 fn test_union_smoke() {
94 use crate::NormalizedRangeIter;
95
96 let acc = vec![(1u8, 4u8), (5u8, 1u8), (5u8, 10u8)];
97 let src = [(0u8, 2u8), (11u8, 15u8)];
98
99 assert_eq!(
100 crate::normalize_vec(acc.clone())
101 .into_union(src.to_vec())
102 .into_vec(),
103 vec![(0u8, 15u8)]
104 );
105
106 assert_eq!(
107 crate::normalize_vec(src.to_vec())
108 .union(crate::normalize_vec(vec![]))
109 .into_vec(),
110 src.to_vec()
111 );
112
113 let result = union_vec(acc, src);
114 assert_eq!(&*result, &vec![(0u8, 15u8)]);
115 assert_eq!(result.inner(), &vec![(0u8, 15u8)]);
116 assert_eq!(result.iter().collect::<Vec<_>>(), vec![(0u8, 15u8)]);
117 assert_eq!(
118 result.iter().collect_range_vec().into_vec(),
119 vec![(0u8, 15u8)]
120 );
121 assert_eq!(result.into_vec(), vec![(0u8, 15u8)]);
122 }
123
124 proptest::proptest! {
125 #[test]
126 fn test_union(xs: Vec<(u8, u8)>, ys: Vec<(u8, u8)>)
127 {
128 use crate::ranges_to_bits;
129
130 let bits = {
131 let mut all_ranges = xs.clone();
132 all_ranges.extend(&ys);
133 ranges_to_bits(&all_ranges)
134 };
135
136 {
138 let union = union_vec(xs.clone(), &ys);
139 assert_eq!(bits, ranges_to_bits(&union));
140 }
141
142 {
143 let union = union_vec(RangeVec::from_vec(xs.clone()), &ys);
144 assert_eq!(bits, ranges_to_bits(&union));
145 }
146
147 {
148 let union = union_vec(xs.clone(), RangeVec::from_vec(ys.clone()).iter());
149 assert_eq!(bits, ranges_to_bits(&union));
150 }
151
152 {
153 let union = union_vec(RangeVec::from_vec(xs.clone()), RangeVec::from_vec(ys.clone()).iter());
154 assert_eq!(bits, ranges_to_bits(&union));
155 }
156
157 {
159 let union = RangeVec::from_vec(xs.clone()).into_union(ys.clone());
160 assert_eq!(bits, ranges_to_bits(&union));
161 }
162
163 {
164 let union = RangeVec::from_vec(ys.clone()).union(RangeVec::from_vec(xs.clone()));
165 assert_eq!(bits, ranges_to_bits(&union));
166 }
167 }
168 }
169}