1use std::cmp::Ordering;
2use std::fmt;
3use std::iter::{Fuse, FusedIterator};
4use std::marker::PhantomData;
5
6use either::Either;
7
8use super::adaptors::{put_back, PutBack};
9use crate::either_or_both::EitherOrBoth;
10use crate::size_hint::{self, SizeHint};
11#[cfg(doc)]
12use crate::Itertools;
13
14#[derive(Clone, Debug)]
15pub struct MergeLte;
16
17pub type Merge<I, J> = MergeBy<I, J, MergeLte>;
24
25pub fn merge<I, J>(
37 i: I,
38 j: J,
39) -> Merge<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
40where
41 I: IntoIterator,
42 J: IntoIterator<Item = I::Item>,
43 I::Item: PartialOrd,
44{
45 merge_by_new(i, j, MergeLte)
46}
47
48#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
55pub struct MergeBy<I: Iterator, J: Iterator, F> {
56 left: PutBack<Fuse<I>>,
57 right: PutBack<Fuse<J>>,
58 cmp_fn: F,
59}
60
61pub fn merge_by_new<I, J, F>(a: I, b: J, cmp: F) -> MergeBy<I::IntoIter, J::IntoIter, F>
63where
64 I: IntoIterator,
65 J: IntoIterator<Item = I::Item>,
66{
67 MergeBy {
68 left: put_back(a.into_iter().fuse()),
69 right: put_back(b.into_iter().fuse()),
70 cmp_fn: cmp,
71 }
72}
73
74pub fn merge_join_by<I, J, F, T>(
78 left: I,
79 right: J,
80 cmp_fn: F,
81) -> MergeJoinBy<I::IntoIter, J::IntoIter, F>
82where
83 I: IntoIterator,
84 J: IntoIterator,
85 F: FnMut(&I::Item, &J::Item) -> T,
86{
87 MergeBy {
88 left: put_back(left.into_iter().fuse()),
89 right: put_back(right.into_iter().fuse()),
90 cmp_fn: MergeFuncLR(cmp_fn, PhantomData),
91 }
92}
93
94pub type MergeJoinBy<I, J, F> =
98 MergeBy<I, J, MergeFuncLR<F, <F as FuncLR<<I as Iterator>::Item, <J as Iterator>::Item>>::T>>;
99
100#[derive(Clone, Debug)]
101pub struct MergeFuncLR<F, T>(F, PhantomData<T>);
102
103pub trait FuncLR<L, R> {
104 type T;
105}
106
107impl<L, R, T, F: FnMut(&L, &R) -> T> FuncLR<L, R> for F {
108 type T = T;
109}
110
111pub trait OrderingOrBool<L, R> {
112 type MergeResult;
113 fn left(left: L) -> Self::MergeResult;
114 fn right(right: R) -> Self::MergeResult;
115 fn merge(&mut self, left: L, right: R) -> (Option<Either<L, R>>, Self::MergeResult);
119 fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint;
120}
121
122impl<L, R, F: FnMut(&L, &R) -> Ordering> OrderingOrBool<L, R> for MergeFuncLR<F, Ordering> {
123 type MergeResult = EitherOrBoth<L, R>;
124 fn left(left: L) -> Self::MergeResult {
125 EitherOrBoth::Left(left)
126 }
127 fn right(right: R) -> Self::MergeResult {
128 EitherOrBoth::Right(right)
129 }
130 fn merge(&mut self, left: L, right: R) -> (Option<Either<L, R>>, Self::MergeResult) {
131 match self.0(&left, &right) {
132 Ordering::Equal => (None, EitherOrBoth::Both(left, right)),
133 Ordering::Less => (Some(Either::Right(right)), EitherOrBoth::Left(left)),
134 Ordering::Greater => (Some(Either::Left(left)), EitherOrBoth::Right(right)),
135 }
136 }
137 fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint {
138 let (a_lower, a_upper) = left;
139 let (b_lower, b_upper) = right;
140 let lower = ::std::cmp::max(a_lower, b_lower);
141 let upper = match (a_upper, b_upper) {
142 (Some(x), Some(y)) => x.checked_add(y),
143 _ => None,
144 };
145 (lower, upper)
146 }
147}
148
149impl<L, R, F: FnMut(&L, &R) -> bool> OrderingOrBool<L, R> for MergeFuncLR<F, bool> {
150 type MergeResult = Either<L, R>;
151 fn left(left: L) -> Self::MergeResult {
152 Either::Left(left)
153 }
154 fn right(right: R) -> Self::MergeResult {
155 Either::Right(right)
156 }
157 fn merge(&mut self, left: L, right: R) -> (Option<Either<L, R>>, Self::MergeResult) {
158 if self.0(&left, &right) {
159 (Some(Either::Right(right)), Either::Left(left))
160 } else {
161 (Some(Either::Left(left)), Either::Right(right))
162 }
163 }
164 fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint {
165 size_hint::add(left, right)
167 }
168}
169
170impl<T, F: FnMut(&T, &T) -> bool> OrderingOrBool<T, T> for F {
171 type MergeResult = T;
172 fn left(left: T) -> Self::MergeResult {
173 left
174 }
175 fn right(right: T) -> Self::MergeResult {
176 right
177 }
178 fn merge(&mut self, left: T, right: T) -> (Option<Either<T, T>>, Self::MergeResult) {
179 if self(&left, &right) {
180 (Some(Either::Right(right)), left)
181 } else {
182 (Some(Either::Left(left)), right)
183 }
184 }
185 fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint {
186 size_hint::add(left, right)
188 }
189}
190
191impl<T: PartialOrd> OrderingOrBool<T, T> for MergeLte {
192 type MergeResult = T;
193 fn left(left: T) -> Self::MergeResult {
194 left
195 }
196 fn right(right: T) -> Self::MergeResult {
197 right
198 }
199 fn merge(&mut self, left: T, right: T) -> (Option<Either<T, T>>, Self::MergeResult) {
200 if left <= right {
201 (Some(Either::Right(right)), left)
202 } else {
203 (Some(Either::Left(left)), right)
204 }
205 }
206 fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint {
207 size_hint::add(left, right)
209 }
210}
211
212impl<I, J, F> Clone for MergeBy<I, J, F>
213where
214 I: Iterator,
215 J: Iterator,
216 PutBack<Fuse<I>>: Clone,
217 PutBack<Fuse<J>>: Clone,
218 F: Clone,
219{
220 clone_fields!(left, right, cmp_fn);
221}
222
223impl<I, J, F> fmt::Debug for MergeBy<I, J, F>
224where
225 I: Iterator + fmt::Debug,
226 I::Item: fmt::Debug,
227 J: Iterator + fmt::Debug,
228 J::Item: fmt::Debug,
229{
230 debug_fmt_fields!(MergeBy, left, right);
231}
232
233impl<I, J, F> Iterator for MergeBy<I, J, F>
234where
235 I: Iterator,
236 J: Iterator,
237 F: OrderingOrBool<I::Item, J::Item>,
238{
239 type Item = F::MergeResult;
240
241 fn next(&mut self) -> Option<Self::Item> {
242 match (self.left.next(), self.right.next()) {
243 (None, None) => None,
244 (Some(left), None) => Some(F::left(left)),
245 (None, Some(right)) => Some(F::right(right)),
246 (Some(left), Some(right)) => {
247 let (not_next, next) = self.cmp_fn.merge(left, right);
248 match not_next {
249 Some(Either::Left(l)) => {
250 self.left.put_back(l);
251 }
252 Some(Either::Right(r)) => {
253 self.right.put_back(r);
254 }
255 None => (),
256 }
257
258 Some(next)
259 }
260 }
261 }
262
263 fn fold<B, G>(mut self, init: B, mut f: G) -> B
264 where
265 Self: Sized,
266 G: FnMut(B, Self::Item) -> B,
267 {
268 let mut acc = init;
269 let mut left = self.left.next();
270 let mut right = self.right.next();
271
272 loop {
273 match (left, right) {
274 (Some(l), Some(r)) => match self.cmp_fn.merge(l, r) {
275 (Some(Either::Right(r)), x) => {
276 acc = f(acc, x);
277 left = self.left.next();
278 right = Some(r);
279 }
280 (Some(Either::Left(l)), x) => {
281 acc = f(acc, x);
282 left = Some(l);
283 right = self.right.next();
284 }
285 (None, x) => {
286 acc = f(acc, x);
287 left = self.left.next();
288 right = self.right.next();
289 }
290 },
291 (Some(l), None) => {
292 self.left.put_back(l);
293 acc = self.left.fold(acc, |acc, x| f(acc, F::left(x)));
294 break;
295 }
296 (None, Some(r)) => {
297 self.right.put_back(r);
298 acc = self.right.fold(acc, |acc, x| f(acc, F::right(x)));
299 break;
300 }
301 (None, None) => {
302 break;
303 }
304 }
305 }
306
307 acc
308 }
309
310 fn size_hint(&self) -> SizeHint {
311 F::size_hint(self.left.size_hint(), self.right.size_hint())
312 }
313
314 fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
315 loop {
316 if n == 0 {
317 break self.next();
318 }
319 n -= 1;
320 match (self.left.next(), self.right.next()) {
321 (None, None) => break None,
322 (Some(_left), None) => break self.left.nth(n).map(F::left),
323 (None, Some(_right)) => break self.right.nth(n).map(F::right),
324 (Some(left), Some(right)) => {
325 let (not_next, _) = self.cmp_fn.merge(left, right);
326 match not_next {
327 Some(Either::Left(l)) => {
328 self.left.put_back(l);
329 }
330 Some(Either::Right(r)) => {
331 self.right.put_back(r);
332 }
333 None => (),
334 }
335 }
336 }
337 }
338 }
339}
340
341impl<I, J, F> FusedIterator for MergeBy<I, J, F>
342where
343 I: Iterator,
344 J: Iterator,
345 F: OrderingOrBool<I::Item, J::Item>,
346{
347}