Skip to main content

range_set_blaze/
sorted_disjoint_map.rs

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