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