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