Skip to main content

range_set_blaze/
sorted_disjoint_map.rs

1use crate::DifferenceMap;
2use crate::DifferenceMapInternal;
3use crate::DynSortedDisjointMap;
4use crate::FillGapsIter;
5use crate::FillGapsIterMap;
6use crate::IntersectionMap;
7use crate::IntoRangeValuesIter;
8use crate::NotIter;
9use crate::NotMap;
10use crate::SymDiffMergeMap;
11use crate::UnionMergeMap;
12use crate::intersection_iter_map::IntersectionIterMap;
13use crate::map::ValueCarrier;
14use crate::range_values::RangeValuesIter;
15use crate::range_values::RangeValuesToRangesIter;
16use crate::sorted_disjoint::SortedDisjoint;
17use crate::sym_diff_iter_map::SymDiffIterMap;
18use crate::{Integer, RangeMapBlaze, union_iter_map::UnionIterMap};
19use alloc::format;
20use alloc::rc::Rc;
21use alloc::string::String;
22use alloc::vec::Vec;
23use core::{
24    cmp::Ordering,
25    fmt::Debug,
26    iter::{
27        Empty, Filter, FlatMap, Flatten, Fuse, FusedIterator, Once, Peekable, Skip, SkipWhile,
28        Take, TakeWhile,
29    },
30    marker::PhantomData,
31    ops,
32    ops::RangeInclusive,
33    option,
34};
35
36/// Used internally. Marks iterators that provide `(range, value)` pairs that are sorted by the range's start, but
37/// that are not necessarily disjoint.
38pub trait SortedStartsMap<T, VC>: Iterator<Item = (RangeInclusive<T>, VC)> + FusedIterator
39where
40    T: Integer,
41    VC: ValueCarrier,
42{
43}
44
45impl<T, VC, I, P> SortedStartsMap<T, VC> for Filter<I, P>
46where
47    T: Integer,
48    VC: ValueCarrier,
49    I: SortedStartsMap<T, VC>,
50    P: FnMut(&I::Item) -> bool,
51{
52}
53
54impl<T, VC, I, P> SortedDisjointMap<T, VC> for Filter<I, P>
55where
56    T: Integer,
57    VC: ValueCarrier,
58    I: SortedDisjointMap<T, VC>,
59    P: FnMut(&I::Item) -> bool,
60{
61}
62
63impl<T, VC, I, P> SortedStartsMap<T, VC> for TakeWhile<I, P>
64where
65    T: Integer,
66    VC: ValueCarrier,
67    I: SortedStartsMap<T, VC>,
68    P: FnMut(&I::Item) -> bool,
69{
70}
71
72impl<T, VC, I, P> SortedDisjointMap<T, VC> for TakeWhile<I, P>
73where
74    T: Integer,
75    VC: ValueCarrier,
76    I: SortedDisjointMap<T, VC>,
77    P: FnMut(&I::Item) -> bool,
78{
79}
80
81impl<T, VC, I, P> SortedStartsMap<T, VC> for SkipWhile<I, P>
82where
83    T: Integer,
84    VC: ValueCarrier,
85    I: SortedStartsMap<T, VC>,
86    P: FnMut(&I::Item) -> bool,
87{
88}
89
90impl<T, VC, I, P> SortedDisjointMap<T, VC> for SkipWhile<I, P>
91where
92    T: Integer,
93    VC: ValueCarrier,
94    I: SortedDisjointMap<T, VC>,
95    P: FnMut(&I::Item) -> bool,
96{
97}
98
99impl<T, VC, I> SortedStartsMap<T, VC> for Fuse<I>
100where
101    T: Integer,
102    VC: ValueCarrier,
103    I: SortedStartsMap<T, VC>,
104{
105}
106
107impl<T, VC, I> SortedDisjointMap<T, VC> for Fuse<I>
108where
109    T: Integer,
110    VC: ValueCarrier,
111    I: SortedDisjointMap<T, VC>,
112{
113}
114
115impl<T, VC, I> SortedStartsMap<T, VC> for Skip<I>
116where
117    T: Integer,
118    VC: ValueCarrier,
119    I: SortedStartsMap<T, VC>,
120{
121}
122
123impl<T, VC, I> SortedDisjointMap<T, VC> for Skip<I>
124where
125    T: Integer,
126    VC: ValueCarrier,
127    I: SortedDisjointMap<T, VC>,
128{
129}
130
131impl<T, VC, I> SortedStartsMap<T, VC> for Take<I>
132where
133    T: Integer,
134    VC: ValueCarrier,
135    I: SortedStartsMap<T, VC>,
136{
137}
138
139impl<T, VC, I> SortedDisjointMap<T, VC> for Take<I>
140where
141    T: Integer,
142    VC: ValueCarrier,
143    I: SortedDisjointMap<T, VC>,
144{
145}
146
147impl<T, VC, I> SortedStartsMap<T, VC> for Peekable<I>
148where
149    T: Integer,
150    VC: ValueCarrier,
151    I: SortedStartsMap<T, VC>,
152{
153}
154
155impl<T, VC, I> SortedDisjointMap<T, VC> for Peekable<I>
156where
157    T: Integer,
158    VC: ValueCarrier,
159    I: SortedDisjointMap<T, VC>,
160{
161}
162
163impl<T, VC> SortedStartsMap<T, VC> for Empty<(RangeInclusive<T>, VC)>
164where
165    T: Integer,
166    VC: ValueCarrier,
167{
168}
169
170impl<T, VC> SortedDisjointMap<T, VC> for Empty<(RangeInclusive<T>, VC)>
171where
172    T: Integer,
173    VC: ValueCarrier,
174{
175}
176
177impl<T, VC> SortedStartsMap<T, VC> for Once<(RangeInclusive<T>, VC)>
178where
179    T: Integer,
180    VC: ValueCarrier,
181{
182}
183
184impl<T, VC> SortedDisjointMap<T, VC> for Once<(RangeInclusive<T>, VC)>
185where
186    T: Integer,
187    VC: ValueCarrier,
188{
189}
190
191impl<T, VC, I, IInner, TMap> SortedStartsMap<T, VC> for FlatMap<option::IntoIter<I>, IInner, TMap>
192where
193    T: Integer,
194    VC: ValueCarrier,
195    IInner: SortedStartsMap<T, VC>,
196    I: SortedStartsMap<T, VC>,
197    TMap: FnMut(I) -> IInner,
198{
199}
200
201impl<T, VC, I> SortedStartsMap<T, VC> for Flatten<option::IntoIter<I>>
202where
203    T: Integer,
204    VC: ValueCarrier,
205    I: SortedStartsMap<T, VC>,
206{
207}
208
209impl<T, VC, I> SortedDisjointMap<T, VC> for Flatten<option::IntoIter<I>>
210where
211    T: Integer,
212    VC: ValueCarrier,
213    I: SortedDisjointMap<T, VC>,
214{
215}
216
217impl<T, VC, I, IInner, TMap> SortedDisjointMap<T, VC> for FlatMap<option::IntoIter<I>, IInner, TMap>
218where
219    T: Integer,
220    VC: ValueCarrier,
221    IInner: SortedDisjointMap<T, VC>,
222    I: SortedDisjointMap<T, VC>,
223    TMap: FnMut(I) -> IInner,
224{
225}
226/// Used internally by [`UnionIterMap`] and [`SymDiffIterMap`].
227pub trait PrioritySortedStartsMap<T, VC>: Iterator<Item = Priority<T, VC>> + FusedIterator
228where
229    T: Integer,
230    VC: ValueCarrier,
231{
232}
233
234/// Marks iterators that provide `(range, value)` pairs that are sorted and disjoint. Set operations on
235/// iterators that implement this trait can be performed in linear time.
236///
237/// # Table of Contents
238/// * [`SortedDisjointMap` Constructors](#sorteddisjointmap-constructors)
239///   * [Examples](#constructor-examples)
240/// * [`SortedDisjointMap` Set Operations](#sorteddisjointmap-set-operations)
241///   * [Performance](#performance)
242///   * [Examples](#examples)
243/// * [How to mark your type as `SortedDisjointMap`](#how-to-mark-your-type-as-sorteddisjointmap)
244///
245/// # `SortedDisjointMap` Constructors
246///
247/// You'll usually construct a `SortedDisjointMap` iterator from a [`RangeMapBlaze`] or a [`CheckSortedDisjointMap`].
248/// Here is a summary table, followed by [examples](#constructor-examples).  You can also [define your own
249/// `SortedDisjointMap`](#how-to-mark-your-type-as-sorteddisjointmap).
250///
251/// | Input type | Method |
252/// |------------|--------|
253/// | [`RangeMapBlaze`] | [`range_values`] |
254/// | [`RangeMapBlaze`] | [`into_range_values`] |
255/// | sorted & disjoint ranges and values | [`CheckSortedDisjointMap::new`] |
256/// |  *your iterator type* | *[How to mark your type as `SortedDisjointMap`][1]* |
257///
258/// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
259/// [`range_values`]: RangeMapBlaze::range_values
260/// [`into_range_values`]: RangeMapBlaze::into_range_values
261/// [1]: #how-to-mark-your-type-as-sorteddisjointmap
262/// [`RangesIter`]: crate::RangesIter
263/// [`BitAnd`]: core::ops::BitAnd
264/// [`Not`]: core::ops::Not
265///
266/// ## Constructor Examples
267/// ```
268/// use range_set_blaze::prelude::*;
269///
270/// // RangeMapBlaze's .range_values(), and .into_range_values()
271/// let r = RangeMapBlaze::from_iter([ (100, "b"), (1, "c"), (3, "a"), (2, "a"), (1, "a")]);
272/// let a = r.range_values();
273/// assert_eq!(a.into_string(), r#"(1..=3, "a"), (100..=100, "b")"#);
274/// // 'into_range_values' takes ownership of the 'RangeMapBlaze'
275/// let a = r.into_range_values();
276/// assert_eq!(a.into_string(), r#"(1..=3, "a"), (100..=100, "b")"#);
277///
278/// // CheckSortedDisjointMap -- unsorted or overlapping input ranges will cause a panic.
279/// let a = CheckSortedDisjointMap::new([(1..=3, &"a"), (100..=100, &"b")]);
280/// assert_eq!(a.into_string(), r#"(1..=3, "a"), (100..=100, "b")"#);
281/// ```
282///
283/// # `SortedDisjointMap` Set Operations
284///
285/// You can perform set operations on `SortedDisjointMap`s and `SortedDisjoint` sets using operators.
286/// In the table below, `a`, `b`, and `c` are `SortedDisjointMap` and `s` is a `SortedDisjoint` set.
287///
288/// | Set Operator               | Operator                      | Multiway (same type)                                      | Multiway (different types)                     |
289/// |----------------------------|-------------------------------|-----------------------------------------------------------|-----------------------------------------------|
290/// | [`union`]                  | [`a` &#124; `b`]              | <code>[a, b, c].[union][multiway_union]() </code>                | [`union_map_dyn!`](a, b, c)                    |
291/// | [`intersection`]           | [`a & b`]                     | <code>[a, b, c].[intersection][multiway_intersection]() </code>  | [`intersection_map_dyn!`](a, b, c)             |
292/// | `intersection`             | [`a.map_and_set_intersection(s)`] | *n/a*                                                     | *n/a*                                          |
293/// | [`difference`]             | [`a - b`]                     | *n/a*                                                     | *n/a*                                          |
294/// | `difference`               | [`a.map_and_set_difference(s)`] | *n/a*                                                     | *n/a*                                          |
295/// | [`symmetric_difference`]   | [`a ^ b`]                     | <code>[a, b, c].[symmetric_difference][multiway_symmetric_difference]() </code> | [`symmetric_difference_map_dyn!`](a, b, c) |
296/// | [`complement`] (to set)    | [`!a`]                        | *n/a*                                                     | *n/a*                                          |
297/// | `complement` (to map)      | [`a.complement_with(&value)`] | *n/a*                                                     | *n/a*                                          |
298///
299/// [`union`]: trait.SortedDisjointMap.html#method.union
300/// [`intersection`]: trait.SortedDisjointMap.html#method.intersection
301/// [`difference`]: trait.SortedDisjointMap.html#method.difference
302/// [`symmetric_difference`]: trait.SortedDisjointMap.html#method.symmetric_difference
303/// [`complement`]: trait.SortedDisjointMap.html#method.complement
304/// [`a` &#124; `b`]: trait.SortedDisjointMap.html#method.union
305/// [`a & b`]: trait.SortedDisjointMap.html#method.intersection
306/// [`a.map_and_set_intersection(s)`]: trait.SortedDisjointMap.html#method.map_and_set_intersection
307/// [`a - b`]: trait.SortedDisjointMap.html#method.difference
308/// [`a.map_and_set_difference(s)`]: trait.SortedDisjointMap.html#method.map_and_set_difference
309/// [`a ^ b`]: trait.SortedDisjointMap.html#method.symmetric_difference
310/// [`!a`]: trait.SortedDisjointMap.html#method.complement
311/// [`a.complement_with(&value)`]: trait.SortedDisjointMap.html#method.complement_with
312/// [multiway_union]: trait.MultiwaySortedDisjointMap.html#method.union
313/// [multiway_intersection]: trait.MultiwaySortedDisjointMap.html#method.intersection
314/// [multiway_symmetric_difference]: trait.MultiwaySortedDisjointMap.html#method.symmetric_difference
315/// [`union_map_dyn!`]: macro.union_map_dyn.html
316/// [`intersection_map_dyn!`]: macro.intersection_map_dyn.html
317/// [`symmetric_difference_map_dyn!`]: macro.symmetric_difference_map_dyn.html
318///
319/// The union of any number of maps is defined such that, for any overlapping keys,
320/// the values from the right-most input take precedence. This approach ensures
321/// that the data from the right-most inputs remains dominant when merging with
322/// later inputs. Likewise, for symmetric difference of three or more maps.
323///
324/// ## Performance
325///
326/// Every operation is implemented as a single pass over the sorted & disjoint ranges, with minimal memory.
327///
328/// This is true even when applying multiple operations. The last example below demonstrates this.
329///
330/// ## Standard Iterators
331///
332/// Many `core::iter` adapters preserve this marker trait when the inner iterator already
333/// implements it, including `filter`, `take_while`, `skip_while`, `fuse`, `skip`, `take`,
334/// and `peekable`. `empty`/`once` iterators and `Option`-based `flatten`/`flat_map` are also
335/// supported.
336///
337/// ## Examples
338///
339/// ```
340/// use range_set_blaze::prelude::*;
341///
342/// let a0 = RangeMapBlaze::from_iter([(2..=6, "a")]);
343/// let b0 = RangeMapBlaze::from_iter([(1..=2, "b"), (5..=100, "b")]);
344///
345/// // 'union' method and 'into_string' method
346/// let (a, b) = (a0.range_values(), b0.range_values());
347/// let result = a.union(b);
348/// assert_eq!(result.into_string(), r#"(1..=2, "b"), (3..=4, "a"), (5..=100, "b")"#);
349///
350/// // '|' operator and 'equal' method
351/// let (a, b) = (a0.range_values(), b0.range_values());
352/// let result = a | b;
353/// assert!(result.equal(CheckSortedDisjointMap::new([(1..=2, &"b"),  (3..=4, &"a"), (5..=100, &"b")])));
354///
355/// // multiway union of same type
356/// let z0 = RangeMapBlaze::from_iter([(2..=2, "z"), (6..=200, "z")]);
357/// let (z, a, b) = (z0.range_values(), a0.range_values(), b0.range_values());
358/// let result = [z, a, b].union();
359/// assert_eq!(result.into_string(), r#"(1..=2, "b"), (3..=4, "a"), (5..=100, "b"), (101..=200, "z")"#
360/// );
361///
362/// // multiway union of different types
363/// let (a, b) = (a0.range_values(), b0.range_values());
364/// let z = CheckSortedDisjointMap::new([(2..=2, &"z"), (6..=200, &"z")]);
365/// let result = union_map_dyn!(z, a, b);
366/// assert_eq!(result.into_string(), r#"(1..=2, "b"), (3..=4, "a"), (5..=100, "b"), (101..=200, "z")"# );
367///
368/// // Applying multiple operators makes only one pass through the inputs with minimal memory.
369/// let (z, a, b) = (z0.range_values(), a0.range_values(), b0.range_values());
370/// let result = b - (z | a);
371/// assert_eq!(result.into_string(), r#"(1..=1, "b")"#);
372/// ```
373/// # How to mark your type as `SortedDisjointMap`
374///
375/// To mark your iterator type as `SortedDisjointMap`, you implement the `SortedStartsMap` and `SortedDisjointMap` traits.
376/// This is your promise to the compiler that your iterator will provide nonempty inclusive ranges
377/// that are sorted by start and do not overlap. Touching ranges with logically equal values, as
378/// determined by [`ValueCarrier::value_eq`], must be coalesced; touching ranges with different values
379/// may remain separate.
380///
381/// When you do this, your iterator will get access to the
382/// efficient set operations methods, such as [`intersection`] and [`complement`].
383///
384/// > To use operators such as `&` and `!`, you must also implement the [`BitAnd`], [`Not`], etc. traits.
385/// >
386/// > If you want others to use your marked iterator type, reexport:
387/// > `pub use range_set_blaze::{SortedDisjointMap, SortedStartsMap};`
388pub trait SortedDisjointMap<T, VC>: SortedStartsMap<T, VC>
389where
390    T: Integer,
391    VC: ValueCarrier,
392{
393    /// Fills the gaps in this sorted, disjoint map stream with `None` values.
394    ///
395    /// The returned stream covers the full integer domain from `T::min_value()`
396    /// through `T::max_value()`. Existing ranges retain their values as
397    /// `Some(value)`.
398    ///
399    /// The result implements `SortedDisjointMap<T, Option<VC>>`. Here, `None`
400    /// is an ordinary logical map value, so the result's key domain is universal:
401    /// [`SortedDisjointMap::into_sorted_disjoint`] covers the full domain and
402    /// [`SortedDisjointMap::complement`] is empty.
403    ///
404    /// This is the lazy streaming form of the operation. To obtain a
405    /// materialized [`RangeMapBlaze<T, Option<VC::Value>>`] instead, use
406    /// [`RangeMapBlaze::fill_gaps`].
407    ///
408    /// See the [Ranges and gaps guide][crate::gaps] for set and map examples,
409    /// including the leading and trailing gaps at the integer-domain bounds.
410    ///
411    /// [`RangeMapBlaze<T, Option<VC::Value>>`]: crate::RangeMapBlaze
412    /// [`RangeMapBlaze::fill_gaps`]: crate::RangeMapBlaze::fill_gaps
413    ///
414    /// # Examples
415    ///
416    /// ```
417    /// use range_set_blaze::{CheckSortedDisjointMap, SortedDisjointMap};
418    ///
419    /// let stream = CheckSortedDisjointMap::new([(1..=3, &"red"), (7..=10, &"blue")]);
420    /// let filled = stream.fill_gaps().collect::<Vec<_>>();
421    /// assert_eq!(filled[0], (0..=0, None));
422    /// assert_eq!(filled[1], (1..=3, Some(&"red")));
423    /// assert_eq!(filled[2], (4..=6, None));
424    /// assert_eq!(filled[3], (7..=10, Some(&"blue")));
425    /// assert_eq!(filled[4], (11..=u8::MAX, None));
426    /// ```
427    #[inline]
428    fn fill_gaps(self) -> FillGapsIterMap<T, VC, Self>
429    where
430        Self: Sized,
431    {
432        FillGapsIterMap::new(self)
433    }
434
435    /// Converts a [`SortedDisjointMap`] iterator into a [`SortedDisjoint`] iterator.
436    ///```
437    /// use range_set_blaze::prelude::*;
438    ///
439    /// let a = CheckSortedDisjointMap::new([(1..=3, &"a"), (100..=100, &"b")]);
440    /// let b = a.into_sorted_disjoint();
441    /// assert!(b.into_string() == "1..=3, 100..=100");
442    /// ```
443    #[inline]
444    fn into_sorted_disjoint(self) -> RangeValuesToRangesIter<T, VC, Self>
445    where
446        Self: Sized,
447    {
448        RangeValuesToRangesIter::new(self)
449    }
450    /// Given two [`SortedDisjointMap`] iterators, efficiently returns a [`SortedDisjointMap`] iterator of their union.
451    ///
452    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
453    ///
454    /// # Examples
455    ///
456    /// ```
457    /// use range_set_blaze::prelude::*;
458    ///
459    /// let a0 = RangeMapBlaze::from_iter([(2..=3, "a")]);
460    /// let a = a0.range_values();
461    /// let b = CheckSortedDisjointMap::new([(1..=2, &"b")]);
462    /// let union = a.union(b);
463    /// assert_eq!(union.into_string(), r#"(1..=2, "b"), (3..=3, "a")"#);
464    ///
465    /// // Alternatively, we can use "|" because CheckSortedDisjointMap defines
466    /// // ops::bitor as SortedDisjointMap::union.
467    /// let a = a0.range_values();
468    /// let b = CheckSortedDisjointMap::new([(1..=2, &"b")]);
469    /// let union = a | b;
470    /// assert_eq!(union.into_string(), r#"(1..=2, "b"), (3..=3, "a")"#);
471    /// ```
472    #[inline]
473    fn union<R>(self, other: R) -> UnionMergeMap<T, VC, Self, R::IntoIter>
474    where
475        R: IntoIterator<Item = Self::Item>,
476        R::IntoIter: SortedDisjointMap<T, VC>,
477        Self: Sized,
478    {
479        UnionIterMap::new2(self, other.into_iter())
480    }
481
482    /// Given two [`SortedDisjointMap`] iterators, efficiently returns a [`SortedDisjointMap`] iterator of their intersection.
483    ///
484    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
485    ///
486    /// # Examples
487    ///
488    /// ```
489    /// use range_set_blaze::prelude::*;
490    ///
491    /// let a0 = RangeMapBlaze::from_iter([(2..=3, "a")]);
492    /// let a = a0.range_values();
493    /// let b = CheckSortedDisjointMap::new([(1..=2, &"b")]);
494    /// let intersection = a.intersection(b);
495    /// assert_eq!(intersection.into_string(), r#"(2..=2, "b")"#);
496    ///
497    /// // Alternatively, we can use "&" because CheckSortedDisjointMap defines
498    /// // `ops::BitAnd` as `SortedDisjointMap::intersection`.
499    /// let a0 = RangeMapBlaze::from_iter([(2..=3, "a")]);
500    /// let a = a0.range_values();
501    /// let b = CheckSortedDisjointMap::new([(1..=2, &"b")]);
502    /// let intersection = a & b;
503    /// assert_eq!(intersection.into_string(), r#"(2..=2, "b")"#);
504    /// ```
505    #[inline]
506    fn intersection<R>(self, other: R) -> IntersectionMap<T, VC, Self, R::IntoIter>
507    where
508        R: IntoIterator<Item = Self::Item>,
509        R::IntoIter: SortedDisjointMap<T, VC>,
510        Self: Sized,
511    {
512        let other = other.into_iter();
513        let sorted_disjoint = self.into_sorted_disjoint();
514        IntersectionIterMap::new(other, sorted_disjoint)
515    }
516
517    /// Given a [`SortedDisjointMap`] iterator and a [`SortedDisjoint`] iterator,
518    /// efficiently returns a [`SortedDisjointMap`] iterator of their intersection.
519    ///
520    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
521    /// [`SortedDisjoint`]: crate::SortedDisjoint.html#table-of-contents
522    ///
523    /// # Examples
524    ///
525    /// ```
526    /// use range_set_blaze::prelude::*;
527    ///
528    /// let a = CheckSortedDisjointMap::new([(1..=2, &"a")]);
529    /// let b = CheckSortedDisjoint::new([2..=3]);
530    /// let intersection = a.map_and_set_intersection(b);
531    /// assert_eq!(intersection.into_string(), r#"(2..=2, "a")"#);
532    /// ```
533    #[inline]
534    fn map_and_set_intersection<R>(self, other: R) -> IntersectionIterMap<T, VC, Self, R::IntoIter>
535    where
536        R: IntoIterator<Item = RangeInclusive<T>>,
537        R::IntoIter: SortedDisjoint<T>,
538        Self: Sized,
539    {
540        IntersectionIterMap::new(self, other.into_iter())
541    }
542
543    /// Given two [`SortedDisjointMap`] iterators, efficiently returns a [`SortedDisjointMap`] iterator of their set difference.
544    ///
545    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
546    ///
547    /// # Examples
548    ///
549    /// ```
550    /// use range_set_blaze::prelude::*;
551    ///
552    /// let a = CheckSortedDisjointMap::new([(1..=2, &"a")]);
553    /// let b0 = RangeMapBlaze::from_iter([(2..=3, "b")]);
554    /// let b = b0.range_values();
555    /// let difference = a.difference(b);
556    /// assert_eq!(difference.into_string(), r#"(1..=1, "a")"#);
557    ///
558    /// // Alternatively, we can use "-" because `CheckSortedDisjointMap` defines
559    /// // `ops::Sub` as `SortedDisjointMap::difference`.
560    /// let a = CheckSortedDisjointMap::new([(1..=2, &"a")]);
561    /// let b = b0.range_values();
562    /// let difference = a - b;
563    /// assert_eq!(difference.into_string(), r#"(1..=1, "a")"#);
564    /// ```
565    #[inline]
566    fn difference<R>(self, other: R) -> DifferenceMap<T, VC, Self, R::IntoIter>
567    where
568        R: IntoIterator<Item = Self::Item>,
569        R::IntoIter: SortedDisjointMap<T, VC>,
570        Self: Sized,
571    {
572        let sorted_disjoint_map = other.into_iter();
573        let complement = sorted_disjoint_map.complement();
574        IntersectionIterMap::new(self, complement)
575    }
576
577    /// Given a [`SortedDisjointMap`] iterator and a [`SortedDisjoint`] iterator,
578    /// efficiently returns a [`SortedDisjointMap`] iterator of their set difference.
579    ///
580    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
581    /// [`SortedDisjoint`]: crate::SortedDisjoint.html#table-of-contents
582    ///
583    /// # Examples
584    ///
585    /// ```
586    /// use range_set_blaze::prelude::*;
587    ///
588    /// let a = CheckSortedDisjointMap::new([(1..=2, &"a")]);
589    /// let b = RangeMapBlaze::from_iter([(2..=3, "b")]).into_ranges();
590    /// let difference = a.map_and_set_difference(b);
591    /// assert_eq!(difference.into_string(), r#"(1..=1, "a")"#);
592    /// ```
593    #[inline]
594    fn map_and_set_difference<R>(self, other: R) -> DifferenceMapInternal<T, VC, Self, R::IntoIter>
595    where
596        R: IntoIterator<Item = RangeInclusive<T>>,
597        R::IntoIter: SortedDisjoint<T>,
598        Self: Sized,
599    {
600        let sorted_disjoint = other.into_iter();
601        let complement = sorted_disjoint.complement();
602        IntersectionIterMap::new(self, complement)
603    }
604
605    /// Returns the complement of a [`SortedDisjointMap`]'s keys as a [`SortedDisjoint`] iterator.
606    ///
607    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
608    /// [`SortedDisjoint`]: crate::SortedDisjoint.html#table-of-contents
609    ///
610    /// # Examples
611    ///
612    /// ```
613    /// use range_set_blaze::prelude::*;
614    ///
615    /// let a = CheckSortedDisjointMap::new([(10_u8..=20, &"a"), (100..=200, &"b")]);
616    /// let complement = a.complement();
617    /// assert_eq!(complement.into_string(), "0..=9, 21..=99, 201..=255");
618    ///
619    /// // Alternatively, we can use "!" because `CheckSortedDisjointMap` implements
620    /// // `ops::Not` as `complement`.
621    /// let a = CheckSortedDisjointMap::new([(10_u8..=20, &"a"), (100..=200, &"b")]);
622    /// let complement_using_not = !a;
623    /// assert_eq!(complement_using_not.into_string(), "0..=9, 21..=99, 201..=255");
624    /// ```
625    #[inline]
626    fn complement(self) -> NotIter<T, RangeValuesToRangesIter<T, VC, Self>>
627    where
628        Self: Sized,
629    {
630        let sorted_disjoint = self.into_sorted_disjoint();
631        sorted_disjoint.complement()
632    }
633
634    /// Returns the complement of a [`SortedDisjointMap`]'s keys, associating each range with the provided value `v`.
635    /// The result is a [`SortedDisjointMap`] iterator.
636    ///
637    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
638    ///
639    /// # Examples
640    ///
641    /// ```
642    /// use range_set_blaze::prelude::*;
643    ///
644    /// let a = CheckSortedDisjointMap::new([(10_u8..=20, &"a"), (100..=200, &"b")]);
645    /// let complement = a.complement_with(&"z");
646    /// assert_eq!(complement.into_string(), r#"(0..=9, "z"), (21..=99, "z"), (201..=255, "z")"#);
647    /// ```
648    #[inline]
649    fn complement_with(
650        self,
651        v: &VC::Value,
652    ) -> RangeToRangeValueIter<'_, T, VC::Value, NotIter<T, impl SortedDisjoint<T>>>
653    where
654        Self: Sized,
655    {
656        let complement = self.complement();
657        RangeToRangeValueIter::new(complement, v)
658    }
659
660    /// Given two [`SortedDisjointMap`] iterators, efficiently returns a [`SortedDisjointMap`] iterator
661    /// of their symmetric difference.
662    ///
663    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
664    ///
665    /// # Examples
666    ///
667    /// ```
668    /// use range_set_blaze::prelude::*;
669    ///
670    /// let a = CheckSortedDisjointMap::new([(1..=2, &"a")]);
671    /// let b0 = RangeMapBlaze::from_iter([(2..=3, "b")]);
672    /// let b = b0.range_values();
673    /// let symmetric_difference = a.symmetric_difference(b);
674    /// assert_eq!(symmetric_difference.into_string(), r#"(1..=1, "a"), (3..=3, "b")"#);
675    ///
676    /// // Alternatively, we can use "^" because CheckSortedDisjointMap defines
677    /// // ops::bitxor as SortedDisjointMap::symmetric_difference.
678    /// let a = CheckSortedDisjointMap::new([(1..=2, &"a")]);
679    /// let b = b0.range_values();
680    /// let symmetric_difference = a ^ b;
681    /// assert_eq!(symmetric_difference.into_string(), r#"(1..=1, "a"), (3..=3, "b")"#);
682    /// ```
683    #[inline]
684    fn symmetric_difference<R>(self, other: R) -> SymDiffMergeMap<T, VC, Self, R::IntoIter>
685    where
686        R: IntoIterator<Item = Self::Item>,
687        R::IntoIter: SortedDisjointMap<T, VC>,
688        Self: Sized,
689        VC: ValueCarrier,
690    {
691        SymDiffIterMap::new2(self, other.into_iter())
692    }
693
694    /// Given two [`SortedDisjointMap`] iterators, efficiently tells if they are equal. Unlike most equality testing in Rust,
695    /// this method takes ownership of the iterators and consumes them.
696    ///
697    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
698    ///
699    /// # Examples
700    ///
701    /// ```
702    /// use range_set_blaze::prelude::*;
703    ///
704    /// let a = CheckSortedDisjointMap::new([(1..=2, &"a")]);
705    /// let b0 = RangeMapBlaze::from_iter([(1..=2, "a")]);
706    /// let b = b0.range_values();
707    /// assert!(a.equal(b));
708    /// ```
709    fn equal<R>(self, other: R) -> bool
710    where
711        R: IntoIterator<Item = Self::Item>,
712        R::IntoIter: SortedDisjointMap<T, VC>,
713        Self: Sized,
714    {
715        use itertools::Itertools;
716
717        self.zip_longest(other).all(|pair| {
718            match pair {
719                itertools::EitherOrBoth::Both(
720                    (self_range, self_value),
721                    (other_range, other_value),
722                ) => {
723                    // Place your custom equality logic here for matching elements
724                    self_range == other_range && self_value.value_eq(&other_value)
725                }
726                _ => false, // Handles the case where iterators are of different lengths
727            }
728        })
729    }
730
731    /// Returns `true` if the [`SortedDisjointMap`] contains no elements.
732    ///
733    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
734    ///
735    /// # Examples
736    ///
737    /// ```
738    /// use range_set_blaze::prelude::*;
739    ///
740    /// let a = CheckSortedDisjointMap::new([(1..=2, &"a")]);
741    /// assert!(!a.is_empty());
742    /// ```
743    #[inline]
744    #[allow(clippy::wrong_self_convention)]
745    fn is_empty(mut self) -> bool
746    where
747        Self: Sized,
748    {
749        self.next().is_none()
750    }
751
752    /// Returns `true` if the map contains all possible integers.
753    ///
754    /// For type `T`, this means the ranges start at `T::min_value()` and continue contiguously up to `T::max_value()`.
755    /// Complexity: O(n) to verify contiguity across ranges.
756    ///
757    /// # Examples
758    ///
759    /// ```
760    /// use range_set_blaze::prelude::*;
761    ///
762    /// let b = CheckSortedDisjointMap::new([(0_u8..=100, &"x"), (101..=255, &"y")]);
763    /// assert!(b.is_universal());
764    ///
765    /// let c = CheckSortedDisjointMap::new([(1_u8..=255, &"z")]);
766    /// assert!(!c.is_universal());
767    /// ```
768    #[inline]
769    #[allow(clippy::wrong_self_convention)]
770    fn is_universal(self) -> bool
771    where
772        Self: Sized,
773    {
774        let mut expected_start = T::min_value();
775
776        for (range, _) in self {
777            let (start, end) = range.into_inner();
778
779            // Check if this range starts where we expect
780            if start != expected_start {
781                return false;
782            }
783
784            // If this range reaches the maximum value, we're done
785            if end == T::max_value() {
786                return true;
787            }
788
789            // Set up for the next range
790            expected_start = end.add_one();
791        }
792
793        // If we get here, we didn't reach the maximum value
794        false
795    }
796
797    /// Create a [`RangeMapBlaze`] from a [`SortedDisjointMap`] iterator.
798    ///
799    /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
800    ///
801    /// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
802    /// # Examples
803    ///
804    /// ```
805    /// use range_set_blaze::prelude::*;
806    ///
807    /// let a0 = RangeMapBlaze::from_sorted_disjoint_map(CheckSortedDisjointMap::new([(-10..=-5, &"a"), (1..=2, &"b")]));
808    /// let a1: RangeMapBlaze<i32,_> = CheckSortedDisjointMap::new([(-10..=-5, &"a"), (1..=2, &"b")]).into_range_map_blaze();
809    /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "a"), (1..=2, "b")"#);
810    /// ```
811    fn into_range_map_blaze(self) -> RangeMapBlaze<T, VC::Value>
812    where
813        Self: Sized,
814    {
815        RangeMapBlaze::from_sorted_disjoint_map(self)
816    }
817}
818
819/// Converts the implementing type into a String by consuming it.
820pub trait IntoString {
821    /// Consumes the implementing type and converts it into a String.
822    fn into_string(self) -> String;
823}
824
825impl<T, I> IntoString for I
826where
827    T: Debug,
828    I: Iterator<Item = T>,
829{
830    fn into_string(self) -> String {
831        self.map(|item| format!("{item:?}"))
832            .collect::<Vec<String>>()
833            .join(", ")
834    }
835}
836
837/// Gives the [`SortedDisjointMap`] trait to any iterator of range-value pairs. Will panic
838/// if the trait is not satisfied.
839///
840/// The iterator will panic
841/// if/when it finds that the ranges are not actually sorted and disjoint or if the values overlap inappropriately.
842///
843/// [`SortedDisjointMap`]: crate::SortedDisjointMap.html#table-of-contents
844///
845/// # Performance
846///
847/// All checking is done at runtime, but it should still be fast.
848///
849/// # Example
850///
851/// ```
852/// use range_set_blaze::prelude::*;
853///
854/// let a = CheckSortedDisjointMap::new([(4..=6, &"a")]);
855/// let b = CheckSortedDisjointMap::new([(1..=3, &"z"), (5..=10, &"b")]);
856/// let union = a | b;
857/// assert_eq!(union.into_string(), r#"(1..=3, "z"), (4..=4, "a"), (5..=10, "b")"#);
858/// ```
859///
860/// Here the ranges are not sorted and disjoint, so the iterator will panic.
861/// ```should_panic
862/// use range_set_blaze::prelude::*;
863///
864/// let a = CheckSortedDisjointMap::new([(1..=3, &"a"), (5..=10, &"b")]);
865/// let b = CheckSortedDisjointMap::new([(4..=6, &"c"), (-10..=12, &"d")]);
866/// let union = a | b;
867/// assert_eq!(union.into_string(), "1..=3 -> a, 5..=10 -> b");
868/// ```
869#[allow(clippy::module_name_repetitions)]
870#[must_use = "iterators are lazy and do nothing unless consumed"]
871#[derive(Debug, Clone)]
872pub struct CheckSortedDisjointMap<T, VC, I> {
873    iter: I,
874    seen_none: bool,
875    previous: Option<(RangeInclusive<T>, VC)>,
876}
877
878// define new
879impl<T, VC, I> CheckSortedDisjointMap<T, VC, I>
880where
881    T: Integer,
882    VC: ValueCarrier,
883    I: Iterator<Item = (RangeInclusive<T>, VC)>,
884{
885    /// Creates a new [`CheckSortedDisjointMap`] from an iterator of ranges and values. See [`CheckSortedDisjointMap`] for details and examples.
886    #[inline]
887    #[must_use = "iterators are lazy and do nothing unless consumed"]
888    pub fn new<J>(iter: J) -> Self
889    where
890        J: IntoIterator<Item = (RangeInclusive<T>, VC), IntoIter = I>,
891    {
892        Self {
893            iter: iter.into_iter(),
894            seen_none: false,
895            previous: None,
896        }
897    }
898}
899
900impl<T, VC, I> Default for CheckSortedDisjointMap<T, VC, I>
901where
902    T: Integer,
903    VC: ValueCarrier,
904    I: Iterator<Item = (RangeInclusive<T>, VC)> + Default,
905{
906    fn default() -> Self {
907        // Utilize I::default() to satisfy the iterator requirement.
908        Self::new(I::default())
909    }
910}
911
912impl<T, VC, I> FusedIterator for CheckSortedDisjointMap<T, VC, I>
913where
914    T: Integer,
915    VC: ValueCarrier,
916    I: Iterator<Item = (RangeInclusive<T>, VC)>,
917{
918}
919
920fn range_value_clone<T, VC>(range_value: &(RangeInclusive<T>, VC)) -> (RangeInclusive<T>, VC)
921where
922    T: Integer,
923    VC: ValueCarrier,
924{
925    let (range, value) = range_value;
926    (range.clone(), value.clone())
927}
928
929impl<T, VC, I> Iterator for CheckSortedDisjointMap<T, VC, I>
930where
931    T: Integer,
932    VC: ValueCarrier,
933    I: Iterator<Item = (RangeInclusive<T>, VC)>,
934{
935    type Item = (RangeInclusive<T>, VC);
936
937    #[allow(clippy::manual_assert)] // We use "if...panic!" for coverage auditing.
938    fn next(&mut self) -> Option<Self::Item> {
939        // Get the next item
940        let range_value = self.iter.next();
941
942        // If it's None, we're done (but remember that we've seen None)
943        let Some(range_value) = range_value else {
944            self.seen_none = true;
945            return None;
946        };
947
948        // if the next item is Some, check that we haven't seen None before
949        if self.seen_none {
950            panic!("a value must not be returned after None")
951        }
952
953        // Check that the range is not empty
954        let (range, _) = &range_value;
955        let (start, end) = range.clone().into_inner();
956        if start > end {
957            panic!("start must be <= end")
958        }
959
960        // If previous is None, we're done (but remember this pair as previous)
961        let Some(previous) = self.previous.take() else {
962            self.previous = Some(range_value_clone(&range_value));
963            return Some(range_value);
964        };
965
966        // The next_item is Some and previous is Some, so check that the ranges are disjoint and sorted
967        let (previous_range, previous_value) = previous;
968        let previous_end = *previous_range.end();
969        if previous_end >= start {
970            panic!("ranges must be disjoint and sorted")
971        }
972
973        let (_, range_value_value) = &range_value;
974        if previous_end.add_one() == start && previous_value.value_eq(range_value_value) {
975            panic!("touching ranges must have different values")
976        }
977
978        // Remember this pair as previous
979        self.previous = Some(range_value_clone(&range_value));
980        Some(range_value)
981    }
982
983    fn size_hint(&self) -> (usize, Option<usize>) {
984        self.iter.size_hint()
985    }
986}
987
988/// Used internally by `MergeMap`.
989#[derive(Clone, Debug)]
990pub struct Priority<T, VC> {
991    range_value: (RangeInclusive<T>, VC),
992    priority_number: usize,
993}
994
995impl<T, VC> Priority<T, VC> {
996    pub(crate) const fn new(range_value: (RangeInclusive<T>, VC), priority_number: usize) -> Self {
997        Self {
998            range_value,
999            priority_number,
1000        }
1001    }
1002}
1003
1004impl<T, VC> Priority<T, VC>
1005where
1006    T: Integer,
1007    VC: ValueCarrier,
1008{
1009    /// Returns a reference to `range_value`.
1010    pub const fn range_value(&self) -> &(RangeInclusive<T>, VC) {
1011        &self.range_value
1012    }
1013
1014    /// Consumes `Priority` and returns `range_value`.
1015    pub fn into_range_value(self) -> (RangeInclusive<T>, VC) {
1016        self.range_value
1017    }
1018
1019    /// Updates the range part of `range_value`.
1020    pub const fn set_range(&mut self, range: RangeInclusive<T>) {
1021        let (stored_range, _) = &mut self.range_value;
1022        *stored_range = range;
1023    }
1024
1025    /// Returns the start of the range.
1026    pub const fn start(&self) -> T {
1027        let (range, _) = &self.range_value;
1028        *range.start()
1029    }
1030
1031    /// Returns the end of the range.
1032    pub const fn end(&self) -> T {
1033        let (range, _) = &self.range_value;
1034        *range.end()
1035    }
1036
1037    /// Returns the start and end of the range. (Assuming direct access to start and end)
1038    pub const fn start_and_end(&self) -> (T, T) {
1039        let (range, _) = &self.range_value;
1040        (*range.start(), *range.end())
1041    }
1042
1043    /// Returns a reference to the value part of `range_value`.
1044    pub const fn value(&self) -> &VC {
1045        let (_, value) = &self.range_value;
1046        value
1047    }
1048}
1049
1050// Implement `PartialEq` to allow comparison (needed for `Eq`).
1051impl<T, VC> PartialEq for Priority<T, VC>
1052where
1053    T: Integer,
1054    VC: ValueCarrier,
1055{
1056    fn eq(&self, other: &Self) -> bool {
1057        self.priority_number == other.priority_number
1058    }
1059}
1060
1061// Implement `Eq` because `BinaryHeap` requires it.
1062impl<T, VC> Eq for Priority<T, VC>
1063where
1064    T: Integer,
1065    VC: ValueCarrier,
1066{
1067}
1068
1069// Implement `Ord` so the heap knows how to compare elements.
1070impl<T, VC> Ord for Priority<T, VC>
1071where
1072    T: Integer,
1073    VC: ValueCarrier,
1074{
1075    fn cmp(&self, other: &Self) -> Ordering {
1076        debug_assert_ne!(
1077            self.priority_number, other.priority_number,
1078            "Priority numbers are expected to be distinct for comparison."
1079        );
1080        // bigger is better
1081        self.priority_number.cmp(&other.priority_number)
1082    }
1083}
1084
1085// Implement `PartialOrd` to allow comparison (needed for `Ord`).
1086impl<T, VC> PartialOrd for Priority<T, VC>
1087where
1088    T: Integer,
1089    VC: ValueCarrier,
1090{
1091    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1092        Some(self.cmp(other))
1093    }
1094}
1095
1096/// Used internally by `complement_with`.
1097#[must_use = "iterators are lazy and do nothing unless consumed"]
1098#[derive(Clone, Debug)]
1099pub struct RangeToRangeValueIter<'a, T, V, I> {
1100    inner: I,
1101    value: &'a V,
1102    phantom: PhantomData<T>,
1103}
1104
1105impl<'a, T, V, I> RangeToRangeValueIter<'a, T, V, I>
1106where
1107    T: Integer,
1108    V: Eq + Clone,
1109    I: SortedDisjoint<T>,
1110{
1111    pub(crate) const fn new(inner: I, value: &'a V) -> Self {
1112        Self {
1113            inner,
1114            value,
1115            phantom: PhantomData,
1116        }
1117    }
1118}
1119
1120impl<T, V, I> FusedIterator for RangeToRangeValueIter<'_, T, V, I>
1121where
1122    T: Integer,
1123    V: Eq + Clone,
1124    I: SortedDisjoint<T>,
1125{
1126}
1127
1128impl<'a, T, V, I> Iterator for RangeToRangeValueIter<'a, T, V, I>
1129where
1130    T: Integer,
1131    V: Eq + Clone,
1132    I: SortedDisjoint<T>,
1133{
1134    type Item = (RangeInclusive<T>, &'a V);
1135
1136    fn next(&mut self) -> Option<Self::Item> {
1137        self.inner.next().map(|range| (range, self.value))
1138    }
1139}
1140
1141// implements SortedDisjointMap
1142impl<'a, T, V, I> SortedStartsMap<T, &'a V> for RangeToRangeValueIter<'a, T, V, I>
1143where
1144    T: Integer,
1145    V: Eq + Clone,
1146    I: SortedDisjoint<T>,
1147{
1148}
1149impl<'a, T, V, I> SortedDisjointMap<T, &'a V> for RangeToRangeValueIter<'a, T, V, I>
1150where
1151    T: Integer,
1152    V: Eq + Clone,
1153    I: SortedDisjoint<T>,
1154{
1155}
1156
1157macro_rules! impl_sorted_map_traits_and_ops {
1158    ($IterType:ty, $V:ty, $VC:ty, $($more_generics:tt)*) => {
1159
1160        #[allow(single_use_lifetimes)]
1161        impl<$($more_generics)*, T> SortedStartsMap<T, $VC> for $IterType
1162        where
1163            T: Integer,
1164        {
1165        }
1166
1167        #[allow(single_use_lifetimes)]
1168        impl<$($more_generics)*, T> SortedDisjointMap<T, $VC> for $IterType
1169        where
1170            T: Integer,
1171        {
1172        }
1173
1174        #[allow(single_use_lifetimes)]
1175        impl<$($more_generics)*, T> ops::Not for $IterType
1176        where
1177            T: Integer,
1178        {
1179            type Output = NotMap<T, $VC, Self>;
1180
1181            #[inline]
1182            fn not(self) -> Self::Output {
1183                self.complement()
1184            }
1185        }
1186
1187        #[allow(single_use_lifetimes)]
1188        impl<$($more_generics)*, T, R> ops::BitOr<R> for $IterType
1189        where
1190            T: Integer,
1191            R: SortedDisjointMap<T, $VC>,
1192        {
1193            type Output = UnionMergeMap<T, $VC, Self, R>;
1194
1195            #[inline]
1196            fn bitor(self, other: R) -> Self::Output {
1197                SortedDisjointMap::union(self, other)
1198            }
1199        }
1200
1201        #[allow(single_use_lifetimes)]
1202        impl<$($more_generics)*, T, R> ops::Sub<R> for $IterType
1203        where
1204            T: Integer,
1205            R: SortedDisjointMap<T, $VC>,
1206        {
1207            type Output = DifferenceMap<T, $VC, Self, R>;
1208
1209            #[inline]
1210            fn sub(self, other: R) -> Self::Output {
1211                SortedDisjointMap::difference(self, other)
1212            }
1213        }
1214
1215        #[allow(single_use_lifetimes)]
1216        impl<$($more_generics)*, T, R> ops::BitXor<R> for $IterType
1217        where
1218            T: Integer,
1219            R: SortedDisjointMap<T, $VC>,
1220        {
1221            type Output = SymDiffMergeMap<T,  $VC, Self, R>;
1222
1223            #[allow(clippy::suspicious_arithmetic_impl)]
1224            #[inline]
1225            fn bitxor(self, other: R) -> Self::Output {
1226                SortedDisjointMap::symmetric_difference(self, other)
1227            }
1228        }
1229
1230        #[allow(single_use_lifetimes)]
1231        impl<$($more_generics)*, T, R> ops::BitAnd<R> for $IterType
1232        where
1233            T: Integer,
1234            R: SortedDisjointMap<T, $VC>,
1235        {
1236            type Output = IntersectionMap<T, $VC, Self, R>;
1237
1238            #[inline]
1239            fn bitand(self, other: R) -> Self::Output {
1240                SortedDisjointMap::intersection(self, other)
1241            }
1242        }
1243
1244    }
1245}
1246
1247// CheckList: Be sure that these are all tested in 'test_every_sorted_disjoint_map_method'
1248impl_sorted_map_traits_and_ops!(CheckSortedDisjointMap<T, VC, I>, VC::Value, VC, VC: ValueCarrier, I: Iterator<Item = (RangeInclusive<T>,  VC)>);
1249impl_sorted_map_traits_and_ops!(DynSortedDisjointMap<'a, T, VC>, VC::Value, VC, 'a, VC: ValueCarrier);
1250impl_sorted_map_traits_and_ops!(FillGapsIterMap<T, VC, I>, Option<VC::Value>, Option<VC>, VC: ValueCarrier, I: SortedDisjointMap<T, VC>);
1251impl_sorted_map_traits_and_ops!(FillGapsIter<T, I>, bool, bool, I: SortedDisjoint<T>);
1252impl_sorted_map_traits_and_ops!(IntersectionIterMap<T, VC, I0, I1>,  VC::Value, VC, VC: ValueCarrier, I0: SortedDisjointMap<T, VC>, I1: SortedDisjoint<T>);
1253impl_sorted_map_traits_and_ops!(IntoRangeValuesIter<T, V>, V, Rc<V>, V: Eq + Clone);
1254impl_sorted_map_traits_and_ops!(RangeValuesIter<'a, T, V>, V, &'a V, 'a, V: Eq + Clone);
1255impl_sorted_map_traits_and_ops!(SymDiffIterMap<T, VC, I>, VC::Value, VC, VC: ValueCarrier, I: PrioritySortedStartsMap<T, VC>);
1256impl_sorted_map_traits_and_ops!(UnionIterMap<T, VC, I>, VC::Value, VC, VC: ValueCarrier, I: PrioritySortedStartsMap<T, VC>);
1257
1258#[cfg(test)]
1259mod tests {
1260    use super::*;
1261    use core::iter::{empty, once};
1262
1263    #[test]
1264    fn test_union_std_iters_map() {
1265        let a = empty::<(RangeInclusive<u64>, &&str)>();
1266        #[allow(clippy::iter_skip_zero)]
1267        let b = once((10u64..=20, &"a"))
1268            .skip_while(|_| false)
1269            .take_while(|_| true)
1270            .fuse()
1271            .skip(0)
1272            .peekable();
1273        #[allow(clippy::iter_on_single_items)]
1274        let b = Some(b).into_iter().flat_map(|x| x.filter(|_| true));
1275        #[allow(clippy::iter_on_single_items)]
1276        let b = Some(b).into_iter().flatten();
1277        assert_eq!(Some((10u64..=20, &"a")), a.union(b).next());
1278    }
1279}