range_set_blaze/map.rs
1use crate::{
2 CheckSortedDisjoint, Integer, IntoKeys, Keys, RangeSetBlaze, SortedDisjoint,
3 iter_map::{IntoIterMap, IterMap},
4 range_values::{IntoRangeValuesIter, MapIntoRangesIter, MapRangesIter, RangeValuesIter},
5 set::extract_range,
6 sorted_disjoint_map::{IntoString, SortedDisjointMap},
7 sym_diff_iter_map::SymDiffIterMap,
8 unsorted_priority_map::{SortedDisjointMapWithLenSoFar, UnsortedPriorityMap},
9 values::{IntoValues, Values},
10};
11#[cfg(feature = "std")]
12use alloc::sync::Arc;
13use alloc::vec::Vec;
14use alloc::{collections::BTreeMap, rc::Rc};
15use core::{
16 borrow::Borrow,
17 cmp::{Ordering, max},
18 convert::From,
19 fmt, mem,
20 ops::{BitOr, BitOrAssign, Index, RangeBounds, RangeInclusive},
21 panic,
22};
23use gen_ops::gen_ops_ex;
24use num_traits::{One, Zero};
25
26const STREAM_OVERHEAD: usize = 10;
27
28/// A trait for references to `Eq + Clone` values, used by the [`SortedDisjointMap`] trait.
29///
30/// `ValueRef` enables [`SortedDisjointMap`] to map sorted, disjoint ranges of integers
31/// to values of type `V: Eq + Clone`. It supports both references (`&V`) and shared ownership types
32/// (`Rc<V>` and `Arc<V>`), avoiding unnecessary cloning of the underlying values while allowing ownership when needed.
33///
34/// References must also implement `Clone`. Standard reference types like `&V`, `Rc<V>`, and `Arc<V>`
35/// implement `Clone` efficiently, as cloning typically involves copying a pointer.
36///
37/// # Motivation
38///
39/// Iterating over `(range, value)` pairs, such as with [`RangeMapBlaze::ranges`], benefits from
40/// references to values, which are cheap to clone. However, iterators like [`RangeMapBlaze::into_ranges`]
41/// require ownership. By supporting `Rc<Eq + Clone>` and `Arc<Eq + Clone>`, `ValueRef` allows shared ownership,
42/// freeing memory when the reference count drops to zero.
43///
44// # Examples
45///
46/// The following demonstrates the [`SortedDisjointMap::intersection`] operation working with
47/// iterators of both `(RangeInclusive<Integer>, &Eq + Clone)` and `(RangeInclusive<Integer>, Rc<Eq + Clone>)`.
48/// (However, types cannot be mixed in the same operation due to Rust's strong type system.)
49///
50/// ```rust
51/// use range_set_blaze::prelude::*;
52/// use std::rc::Rc;
53///
54/// let a = RangeMapBlaze::from_iter([(2..=3, "a".to_string()), (5..=100, "a".to_string())]);
55/// let b = RangeMapBlaze::from_iter([(3..=10, "b".to_string())]);
56///
57/// let mut c = a.range_values() & b.range_values();
58/// assert_eq!(c.next(), Some((3..=3, &"a".to_string())));
59/// assert_eq!(c.next(), Some((5..=10, &"a".to_string())));
60/// assert_eq!(c.next(), None);
61///
62/// let mut c = a.into_range_values() & b.into_range_values();
63/// assert_eq!(c.next(), Some((3..=3, Rc::new("a".to_string()))));
64/// assert_eq!(c.next(), Some((5..=10, Rc::new("a".to_string()))));
65/// assert_eq!(c.next(), None);
66/// ```
67pub trait ValueRef: Borrow<Self::Target> + Clone {
68 /// The `Eq + Clone` value type to which the reference points.
69 type Target: Eq + Clone;
70}
71
72// Implementations for references and smart pointers
73impl<V> ValueRef for &V
74where
75 V: Eq + Clone,
76{
77 type Target = V;
78}
79
80impl<V> ValueRef for Rc<V>
81where
82 V: Eq + Clone,
83{
84 type Target = V;
85}
86
87#[cfg(feature = "std")]
88impl<V> ValueRef for Arc<V>
89where
90 V: Eq + Clone,
91{
92 type Target = V;
93}
94
95#[expect(clippy::redundant_pub_crate)]
96#[derive(Clone, Hash, Default, PartialEq, Eq, Debug)]
97pub(crate) struct EndValue<T, V>
98where
99 T: Integer,
100 V: Eq + Clone,
101{
102 pub(crate) end: T,
103 pub(crate) value: V,
104}
105
106/// A map from integers to values stored as a map of sorted & disjoint ranges to values.
107///
108/// Internally, the map stores the
109/// ranges and values in a cache-efficient [`BTreeMap`].
110///
111/// # Table of Contents
112/// * [`RangeMapBlaze` Constructors](#rangemapblaze-constructors)
113/// * [Performance](#constructor-performance)
114/// * [Examples](struct.RangeMapBlaze.html#constructor-examples)
115/// * [`RangeMapBlaze` Set Operations](#rangemapblaze-set-operations)
116/// * [Performance](struct.RangeMapBlaze.html#set-operation-performance)
117/// * [Examples](struct.RangeMapBlaze.html#set-operation-examples)
118/// * [`RangeMapBlaze` Union- and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods)
119/// * [`RangeMapBlaze` Comparisons](#rangemapblaze-comparisons)
120/// * [Additional Examples](#additional-examples)
121///
122/// # `RangeMapBlaze` Constructors
123///
124/// You can create `RangeMapBlaze`'s from unsorted and overlapping integers (or ranges), along with values.
125/// However, if you know that your input is sorted and disjoint, you can speed up construction.
126///
127/// Here are the constructors, followed by a
128/// description of the performance, and then some examples.
129///
130///
131/// | Methods | Input | Notes |
132/// |---------------------------------------------|------------------------------|--------------------------|
133/// | [`new`]/[`default`] | | |
134/// | [`from_iter`][1]/[`collect`][1] | iterator of `(integer, value)` | References to the pair or value is OK. |
135/// | [`from_iter`][2]/[`collect`][2] | iterator of `(range, value)` | References to the pair or value is OK. |
136/// | [`from_sorted_disjoint_map`][3]/<br>[`into_range_set_blaze`][3b] | [`SortedDisjointMap`] iterator | |
137/// | [`from`][4] /[`into`][4] | array of `(integer, value)` | |
138///
139///
140/// [`BTreeMap`]: alloc::collections::BTreeMap
141/// [`new`]: RangeMapBlaze::new
142/// [`default`]: RangeMapBlaze::default
143/// [1]: struct.RangeMapBlaze.html#impl-FromIterator<(T,+V)>-for-RangeMapBlaze<T,+V>
144/// [2]: struct.RangeMapBlaze.html#impl-FromIterator<(RangeInclusive<T>,+V)>-for-RangeMapBlaze<T,+V>
145/// [3]: `RangeMapBlaze::from_sorted_disjoint_map`
146/// [3b]: `SortedDisjointMap::into_range_map_blaze
147/// [`SortedDisjointMap`]: trait.SortedDisjointMap.html#table-of-contents
148/// [4]: `RangeMapBlaze::from`
149///
150/// # Constructor Performance
151///
152/// The [`from_iter`][1]/[`collect`][1] constructors are designed to work fast on 'clumpy' data.
153/// By 'clumpy', we mean that the number of ranges needed to represent the data is
154/// small compared to the number of input integers. To understand this, consider the internals
155/// of the constructors:
156///
157/// Internally, the `from_iter`/`collect` constructors take these steps:
158/// * collect adjacent integers/ranges with equal values into disjoint ranges, O(*n₁*)
159/// * sort the disjoint ranges by their `start`, O(*n₂* ln *n₂*)
160/// * merge ranges giving precedence to the original left-most values, O(*n₂*)
161/// * create a `BTreeMap` from the now sorted & disjoint ranges, O(*n₃* ln *n₃*)
162///
163/// where *n₁* is the number of input integers/ranges, *n₂* is the number of disjoint & unsorted ranges,
164/// and *n₃* is the final number of sorted & disjoint ranges with equal values.
165///
166/// For example, an input of
167/// * `(3, "a"), (2, "a"), (1, "a"), (4, "a"), (100, "c"), (5, "b"), (4, "b"), (5, "b")`, becomes
168/// * `(1..=4, "a"), (100..=100, "c"), (4..=5, "b")`, and then
169/// * `(1..=4, "a"), (4..=5, "b"), (100..=100, "c")`, and finally
170/// * `(1..=4, "a"), (5..=5, "b"), (100..=100, "c")`.
171///
172/// What is the effect of clumpy data?
173/// Notice that if *n₂* ≈ sqrt(*n₁*), then construction is O(*n₁*).
174/// Indeed, as long as *n₂* ≤ *n₁*/ln(*n₁*), then construction is O(*n₁*).
175/// Moreover, we'll see that set operations are O(*n₃*). Thus, if *n₃* ≈ sqrt(*n₁*) then set operations are O(sqrt(*n₁*)),
176/// a quadratic improvement an O(*n₁*) implementation that ignores the clumps.
177///
178/// ## Constructor Examples
179///
180/// ```
181/// use range_set_blaze::prelude::*;
182///
183/// // Create an empty set with 'new' or 'default'.
184/// let a0 = RangeMapBlaze::<i32, &str>::new();
185/// let a1 = RangeMapBlaze::<i32, &str>::default();
186/// assert!(a0 == a1 && a0.is_empty());
187///
188/// // 'from_iter'/'collect': From an iterator of integers.
189/// // Duplicates and out-of-order elements are fine.
190/// // Values have left-to-right precedence.
191/// let a0 = RangeMapBlaze::from_iter([(3, "a"), (2, "a"), (1, "a"), (100, "b"), (1, "c")]);
192/// let a1: RangeMapBlaze<i32, &str> = [(3, "a"), (2, "a"), (1, "a"), (100, "b"), (1, "c")].into_iter().collect();
193/// assert!(a0 == a1 && a0.to_string() == r#"(1..=3, "a"), (100..=100, "b")"#);
194///
195/// // 'from_iter'/'collect': From an iterator of inclusive ranges, start..=end.
196/// // Overlapping, out-of-order, and empty ranges are fine.
197/// // Values have left-to-right precedence.
198/// #[allow(clippy::reversed_empty_ranges)]
199/// let a0 = RangeMapBlaze::from_iter([(1..=2, "a"), (2..=2, "b"), (-10..=-5, "c"), (1..=0, "d")]);
200/// #[allow(clippy::reversed_empty_ranges)]
201/// let a1: RangeMapBlaze<i32, &str> = [(1..=2, "a"), (2..=2, "b"), (-10..=-5, "c"), (1..=0, "d")].into_iter().collect();
202/// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
203///
204/// // If we know the ranges are already sorted and disjoint,
205/// // we can avoid work and use 'from_sorted_disjoint_map'/'into_sorted_disjoint_map'.
206/// let a0 = RangeMapBlaze::from_sorted_disjoint_map(CheckSortedDisjointMap::new([(-10..=-5, &"c"), (1..=2, &"a")]));
207/// let a1: RangeMapBlaze<i32, &str> = CheckSortedDisjointMap::new([(-10..=-5, &"c"), (1..=2, &"a")]).into_range_map_blaze();
208/// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
209///
210/// // For compatibility with `BTreeMap`, we also support
211/// // 'from'/'into' from arrays of integers.
212/// let a0 = RangeMapBlaze::from([(3, "a"), (2, "a"), (1, "a"), (100, "b"), (1, "c")]);
213/// let a1: RangeMapBlaze<i32, &str> = [(3, "a"), (2, "a"), (1, "a"), (100, "b"), (1, "c")].into();
214/// assert!(a0 == a1 && a0.to_string() == r#"(1..=3, "a"), (100..=100, "b")"#);
215/// ```
216///
217/// # `RangeMapBlaze` Set Operations
218///
219/// You can perform set operations on `RangeMapBlaze`s
220/// and `RangeSetBlaze`s using operators. In the table below, `a`, `b`, and `c` are `RangeMapBlaze`s and `s` is a `RangeSetBlaze`.
221///
222/// | Set Operation | Operator | Multiway Method |
223/// |--------------------------|------------------------------------|----------------------------------------|
224/// | union | [`a` | `b`] | `[a, b, c]`.[`union`]\(\) |
225/// | intersection | [`a & b`] | `[a, b, c]`.[`intersection`]\(\) |
226/// | intersection | [`a & s`] | *n/a* |
227/// | difference | [`a - b`] | *n/a* |
228/// | difference | [`a - s`] | *n/a* |
229/// | symmetric difference | [`a ^ b`] | `[a, b, c]`.[`symmetric_difference`]\(\) |
230/// | complement (to set) | [`!a`] | *n/a* |
231/// | complement (to map) | [`a.complement_with(&value)`] | *n/a* |
232///
233/// The result of all operations is a new `RangeMapBlaze` except for `!a`, which returns a `RangeSetBlaze`.
234///
235/// The union of any number of maps is defined such that, for any overlapping keys,
236/// the values from the left-most input take precedence. This approach ensures
237/// that the data from the left-most inputs remains dominant when merging with
238/// later inputs. Likewise, for symmetric difference of three or more maps.
239///
240/// `RangeMapBlaze` also implements many other methods, such as [`insert`], [`pop_first`] and [`split_off`]. Many of
241/// these methods match those of `BTreeMap`.
242///
243/// [`a` | `b`]: struct.RangeMapBlaze.html#impl-BitOr-for-RangeMapBlaze<T,+V>
244/// [`a & b`]: struct.RangeMapBlaze.html#impl-BitAnd-for-RangeMapBlaze<T,+V>
245/// [`a & s`]: struct.RangeMapBlaze.html#impl-BitAnd<%26RangeSetBlaze<T>>-for-%26RangeMapBlaze<T,+V>
246/// [`a - b`]: struct.RangeMapBlaze.html#impl-Sub-for-RangeMapBlaze<T,+V>
247/// [`a - s`]: struct.RangeMapBlaze.html#impl-Sub<%26RangeSetBlaze<T>>-for-%26RangeMapBlaze<T,+V>
248/// [`a ^ b`]: struct.RangeMapBlaze.html#impl-BitXor-for-RangeMapBlaze<T,+V>
249/// [`!a`]: struct.RangeMapBlaze.html#impl-Not-for-%26RangeMapBlaze<T,+V>
250/// [`a.complement_with(&value)`]: struct.RangeMapBlaze.html#method.complement_with
251/// [`union`]: trait.MultiwayRangeMapBlazeRef.html#method.union
252/// [`intersection`]: trait.MultiwayRangeMapBlazeRef.html#method.intersection
253/// [`symmetric_difference`]: trait.MultiwayRangeMapBlazeRef.html#method.symmetric_difference
254/// [`insert`]: RangeMapBlaze::insert
255/// [`pop_first`]: RangeMapBlaze::pop_first
256/// [`split_off`]: RangeMapBlaze::split_off
257///
258/// ## Set Operation Performance
259///
260/// Every operation is implemented as
261/// 1. a single pass over the sorted & disjoint ranges
262/// 2. the construction of a new `RangeMapBlaze`
263///
264/// Thus, applying multiple operators creates intermediate
265/// `RangeMapBlaze`'s. If you wish, you can avoid these intermediate
266/// `RangeMapBlaze`'s by switching to the [`SortedDisjointMap`] API. The last example below
267/// demonstrates this.
268///
269/// Several union-related operators — such as [`|`] (union) and [`|=`] (union append) — include performance
270/// optimizations for common cases, including when one operand is much smaller than the other.
271/// These optimizations reduce allocations and merging overhead.
272/// **See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
273///
274/// [`SortedDisjointMap`]: trait.SortedDisjointMap.html#table-of-contents
275/// [`|`]: struct.RangeMapBlaze.html#impl-BitOr-for-RangeMapBlaze%3CT,+V%3E
276/// [`|=`]: struct.RangeMapBlaze.html#impl-BitOrAssign-for-RangeMapBlaze%3CT,+V%3E
277///
278/// ## Set Operation Examples
279///
280/// ```
281/// use range_set_blaze::prelude::*;
282///
283/// let a = RangeMapBlaze::from_iter([(1..=2, "a"), (5..=100, "a")]);
284/// let b = RangeMapBlaze::from_iter([(2..=6, "b")]);
285///
286/// // Union of two 'RangeMapBlaze's. Alternatively, we can take ownership via 'a | b'.
287/// // Values have left-to-right precedence.
288/// let result = &a | &b;
289/// assert_eq!(result.to_string(), r#"(1..=2, "a"), (3..=4, "b"), (5..=100, "a")"#);
290///
291/// // Intersection of two 'RangeMapBlaze's.
292/// let result = &a & &b; // Alternatively, 'a & b'.
293/// assert_eq!(result.to_string(), r#"(2..=2, "a"), (5..=6, "a")"#);
294///
295/// // Set difference of two 'RangeMapBlaze's.
296/// let result = &a - &b; // Alternatively, 'a - b'.
297/// assert_eq!(result.to_string(), r#"(1..=1, "a"), (7..=100, "a")"#);
298///
299/// // Symmetric difference of two 'RangeMapBlaze's.
300/// let result = &a ^ &b; // Alternatively, 'a ^ b'.
301/// assert_eq!(result.to_string(), r#"(1..=1, "a"), (3..=4, "b"), (7..=100, "a")"#);
302///
303/// // complement of a 'RangeMapBlaze' is a `RangeSetBlaze`.
304/// let result = !&a; // Alternatively, '!a'.
305/// assert_eq!(result.to_string(), "-2147483648..=0, 3..=4, 101..=2147483647"
306/// );
307/// // use `complement_with` to create a 'RangeMapBlaze'.
308/// let result = a.complement_with(&"z");
309/// assert_eq!(result.to_string(), r#"(-2147483648..=0, "z"), (3..=4, "z"), (101..=2147483647, "z")"#);
310///
311/// // Multiway union of 'RangeMapBlaze's.
312/// let c = RangeMapBlaze::from_iter([(2..=2, "c"), (6..=200, "c")]);
313/// let result = [&a, &b, &c].union();
314/// assert_eq!(result.to_string(), r#"(1..=2, "a"), (3..=4, "b"), (5..=100, "a"), (101..=200, "c")"# );
315///
316/// // Multiway intersection of 'RangeMapBlaze's.
317/// let result = [&a, &b, &c].intersection();
318/// assert_eq!(result.to_string(), r#"(2..=2, "a"), (6..=6, "a")"#);
319///
320/// // Applying multiple operators
321/// let result0 = &a - (&b | &c); // Creates an intermediate 'RangeMapBlaze'.
322/// // Alternatively, we can use the 'SortedDisjointMap' API and avoid the intermediate 'RangeMapBlaze'.
323/// let result1 = RangeMapBlaze::from_sorted_disjoint_map(
324/// a.range_values() - (b.range_values() | c.range_values()));
325/// assert!(result0 == result1 && result0.to_string() == r#"(1..=1, "a")"#);
326/// ```
327///
328/// # `RangeMapBlaze` Union- and Extend-like Methods
329///
330/// | Operation & Syntax | Input Type | Precedence | Pre-merge Touching | Cases Optimized |
331/// |-------------------------------------|----------------------|----------------|---------------------|------------------|
332/// | [`a` |= `b`] | `RangeMapBlaze` | Left-to-right | - | 3 |
333/// | [`a` |= `&b`] | `&RangeMapBlaze` | Left-to-right | - | 3 |
334/// | [`a` | `b`] | `RangeMapBlaze` | Left-to-right | - | 3 |
335/// | [`a` | `&b`] | `&RangeMapBlaze` | Left-to-right | - | 3 |
336/// | [`&a` | `b`] | `RangeMapBlaze` | Left-to-right | - | 3 |
337/// | [`&a` | `&b`] | `&RangeMapBlaze` | Left-to-right | - | 3 |
338/// | [`a.extend([(r, v)])`][extend_rv] | iter `(range, value)` | Right-to-left | Yes | 1 |
339/// | [`a.extend([(i, v)])`][extend_iv] | iter `(integer, value)` | Right-to-left | Yes | 1 |
340/// | [`a.extend_simple(...)`][extend_simple] | iter `(range, value)` | Right-to-left | No | 1 |
341/// | [`a.extend_with(&b)`][extend_with] | `&RangeMapBlaze` | Right-to-left | - | 1 |
342/// | [`a.extend_from(b)`][extend_from] | `RangeMapBlaze` | Right-to-left | - | 1 |
343/// | [`b.append(&mut a)`][append] | `&mut RangeMapBlaze` | Right-to-left | - | 1 |
344///
345/// Notes:
346///
347/// - **Pre-merge Touching** means adjacent or overlapping ranges with the same value are combined into a single range before insertions.
348/// - **Cases Optimized** indicates how many usage scenarios have dedicated performance paths:
349/// - `3` = optimized for small-left, small-right, and similar-sized inputs
350/// - `1` = optimized for small-right inputs only
351///
352/// [`a` |= `b`]: struct.RangeMapBlaze.html#impl-BitOrAssign-for-RangeMapBlaze%3CT,+V%3E
353/// [`a` |= `&b`]: struct.RangeMapBlaze.html#impl-BitOrAssign%3C%26RangeMapBlaze%3CT,+V%3E%3E-for-RangeMapBlaze%3CT,+V%3E
354/// [`a` | `b`]: struct.RangeMapBlaze.html#impl-BitOr-for-RangeMapBlaze%3CT,+V%3E
355/// [`a` | `&b`]: struct.RangeMapBlaze.html#impl-BitOr%3C%26RangeMapBlaze%3CT,+V%3E%3E-for-RangeMapBlaze%3CT,+V%3E
356/// [`&a` | `b`]: struct.RangeMapBlaze.html#impl-BitOr%3CRangeMapBlaze%3CT,+V%3E%3E-for-%26RangeMapBlaze%3CT,+V%3E
357/// [`&a` | `&b`]: struct.RangeMapBlaze.html#impl-BitOr%3C%26RangeMapBlaze%3CT,+V%3E%3E-for-%26RangeMapBlaze%3CT,+V%3E
358/// [extend_rv]: struct.RangeMapBlaze.html#impl-Extend%3C(RangeInclusive%3CT%3E,+V)%3E-for-RangeMapBlaze%3CT,+V%3E
359/// [extend_iv]: struct.RangeMapBlaze.html#impl-Extend%3C(T,+V)%3E-for-RangeMapBlaze%3CT,+V%3E
360/// [extend_simple]: struct.RangeMapBlaze.html#method.extend_simple
361/// [extend_with]: struct.RangeMapBlaze.html#method.extend_with
362/// [extend_from]: struct.RangeMapBlaze.html#method.extend_from
363/// [append]: struct.RangeMapBlaze.html#method.append
364///
365/// # `RangeMapBlaze` Comparisons
366///
367/// `RangeMapBlaze` supports comparisons for equality and lexicographic order:
368///
369/// - **Equality**: Use `==` and `!=` to check if two `RangeMapBlaze` instances
370/// are equal. Two `RangeMapBlaze` instances are considered equal if they
371/// contain the same ranges and associated values.
372/// - **Ordering**: If the values implement `Ord`, you can use `<`, `<=`, `>`, and `>=`
373/// to compare two `RangeMapBlaze` instances. These comparisons are lexicographic,
374/// similar to `BTreeMap`, meaning they compare the ranges and their values in sequence.
375/// - **Partial Ordering**: If the values implement `PartialOrd` but not `Ord`, you can use
376/// the [`partial_cmp`] method to compare two `RangeMapBlaze` instances. This method returns
377/// an `Option<Ordering>` that indicates the relative order of the instances or `None` if the
378/// values are not comparable.
379///
380/// See [`partial_cmp`] and [`cmp`] for more examples.
381///
382///
383/// [`BTreeMap`]: alloc::collections::BTreeMap
384/// [`partial_cmp`]: RangeMapBlaze::partial_cmp
385/// [`cmp`]: RangeMapBlaze::cmp
386///
387/// # Additional Examples
388///
389/// See the [module-level documentation] for additional examples.
390///
391/// [module-level documentation]: index.html
392#[derive(Clone, Hash, PartialEq)]
393pub struct RangeMapBlaze<T: Integer, V: Eq + Clone> {
394 pub(crate) len: <T as Integer>::SafeLen,
395 pub(crate) btree_map: BTreeMap<T, EndValue<T, V>>,
396}
397
398/// Creates a new, empty `RangeMapBlaze`.
399///
400/// # Examples
401///
402/// ```
403/// use range_set_blaze::RangeMapBlaze;
404///
405/// let a = RangeMapBlaze::<i32, &str>::default();
406/// assert!(a.is_empty());
407/// ```
408impl<T: Integer, V: Eq + Clone> Default for RangeMapBlaze<T, V> {
409 fn default() -> Self {
410 Self {
411 len: <T as Integer>::SafeLen::zero(),
412 btree_map: BTreeMap::new(),
413 }
414 }
415}
416
417impl<T: Integer, V: Eq + Clone + fmt::Debug> fmt::Debug for RangeMapBlaze<T, V> {
418 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
419 write!(f, "{}", self.range_values().into_string())
420 }
421}
422
423impl<T: Integer, V: Eq + Clone + fmt::Debug> fmt::Display for RangeMapBlaze<T, V> {
424 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
425 write!(f, "{}", self.range_values().into_string())
426 }
427}
428
429impl<T: Integer, V: Eq + Clone> RangeMapBlaze<T, V> {
430 /// Gets an iterator that visits the integer elements in the [`RangeMapBlaze`] in
431 /// ascending and/or descending order. Double-ended.
432 ///
433 /// Also see the [`RangeMapBlaze::ranges`] method.
434 ///
435 /// # Examples
436 ///
437 /// ```
438 /// use range_set_blaze::RangeMapBlaze;
439 ///
440 /// let map = RangeMapBlaze::from_iter([(1..=3,"a")]);
441 /// let mut map_iter = map.iter();
442 /// assert_eq!(map_iter.next(), Some((1, &"a")));
443 /// assert_eq!(map_iter.next(), Some((2, &"a")));
444 /// assert_eq!(map_iter.next(), Some((3, &"a")));
445 /// assert_eq!(map_iter.next(), None);
446 /// ```
447 ///
448 /// Values returned by `.next()` are in ascending order.
449 /// Values returned by `.next_back()` are in descending order.
450 ///
451 /// ```
452 /// use range_set_blaze::RangeMapBlaze;
453 ///
454 /// let map = RangeMapBlaze::from_iter([(3,"c"), (1,"a"), (2,"b")]);
455 /// let mut map_iter = map.iter();
456 /// assert_eq!(map_iter.next(), Some((1, &"a")));
457 /// assert_eq!(map_iter.next_back(), Some((3, &"c")));
458 /// assert_eq!(map_iter.next(), Some((2, &"b")));
459 /// assert_eq!(map_iter.next_back(), None);
460 /// ```
461 pub fn iter(&self) -> IterMap<T, &V, RangeValuesIter<'_, T, V>> {
462 // If the user asks for an iter, we give them a RangesIter iterator
463 // and we iterate that one integer at a time.
464 IterMap::new(self.range_values())
465 }
466
467 /// Gets an iterator that visits the integer elements in the [`RangeMapBlaze`] in
468 /// ascending and/or descending order. Double-ended.
469 ///
470 /// For a consuming version, see the [`RangeMapBlaze::into_keys`] method.
471 ///
472 /// # Examples
473 ///
474 /// ```
475 /// use range_set_blaze::RangeMapBlaze;
476 ///
477 /// let map = RangeMapBlaze::from_iter([(1..=3,"a")]);
478 /// let mut keys_iter = map.keys();
479 /// assert_eq!(keys_iter.next(), Some(1));
480 /// assert_eq!(keys_iter.next(), Some(2));
481 /// assert_eq!(keys_iter.next(), Some(3));
482 /// assert_eq!(keys_iter.next(), None);
483 /// ```
484 ///
485 /// Keys returned by `.next()` are in ascending order.
486 /// Keys returned by `.next_back()` are in descending order.
487 ///
488 /// ```
489 /// # use range_set_blaze::RangeMapBlaze;
490 /// let map = RangeMapBlaze::from_iter([(3,"c"), (1,"a"), (2,"b")]);
491 /// let mut keys_iter = map.keys();
492 /// assert_eq!(keys_iter.next(), Some(1));
493 /// assert_eq!(keys_iter.next_back(), Some(3));
494 /// assert_eq!(keys_iter.next(), Some(2));
495 /// assert_eq!(keys_iter.next_back(), None);
496 /// ```
497 pub fn keys(&self) -> Keys<T, &V, RangeValuesIter<'_, T, V>> {
498 Keys::new(self.range_values())
499 }
500
501 /// Gets an iterator that visits the integer elements in the [`RangeMapBlaze`] in
502 /// ascending and/or descending order. Double-ended.
503 ///
504 /// The iterator consumes the [`RangeMapBlaze`], yielding one integer at a time from its ranges.
505 /// For a non-consuming version, see the [`RangeMapBlaze::keys`] method.
506 ///
507 /// # Examples
508 ///
509 /// Iterating in ascending order:
510 ///
511 /// ```
512 /// use range_set_blaze::RangeMapBlaze;
513 ///
514 /// let map = RangeMapBlaze::from_iter([(1..=3, "a")]);
515 /// let mut into_keys_iter = map.into_keys();
516 /// assert_eq!(into_keys_iter.next(), Some(1));
517 /// assert_eq!(into_keys_iter.next(), Some(2));
518 /// assert_eq!(into_keys_iter.next(), Some(3));
519 /// assert_eq!(into_keys_iter.next(), None);
520 /// ```
521 ///
522 /// Iterating in both ascending and descending order:
523 ///
524 /// ```
525 /// # use range_set_blaze::RangeMapBlaze;
526 /// let map = RangeMapBlaze::from_iter([(1..=3, "a"), (5..=5, "b")]);
527 /// let mut into_keys_iter = map.into_keys();
528 /// assert_eq!(into_keys_iter.next(), Some(1));
529 /// assert_eq!(into_keys_iter.next_back(), Some(5));
530 /// assert_eq!(into_keys_iter.next(), Some(2));
531 /// assert_eq!(into_keys_iter.next_back(), Some(3));
532 /// assert_eq!(into_keys_iter.next(), None);
533 /// ```
534 ///
535 /// Keys returned by `.next()` are in ascending order.
536 /// Keys returned by `.next_back()` are in descending order.
537 #[inline]
538 pub fn into_keys(self) -> IntoKeys<T, V> {
539 IntoKeys::new(self.btree_map.into_iter())
540 }
541
542 /// Gets an iterator that visits the values in the [`RangeMapBlaze`] in
543 /// the order corresponding to the integer elements. Double-ended.
544 ///
545 /// For a consuming version, see the [`RangeMapBlaze::into_values`] method.
546 ///
547 /// # Examples
548 ///
549 /// Iterating over values:
550 ///
551 /// ```rust
552 /// use range_set_blaze::RangeMapBlaze;
553 ///
554 /// let map = RangeMapBlaze::from_iter([(3, "c"), (1, "a"), (2, "b")]);
555 /// let mut values_iter = map.values();
556 /// assert_eq!(values_iter.next(), Some(&"a"));
557 /// assert_eq!(values_iter.next(), Some(&"b"));
558 /// assert_eq!(values_iter.next(), Some(&"c"));
559 /// assert_eq!(values_iter.next(), None);
560 /// ```
561 ///
562 /// Values returned by `.next()` are in the order of corresponding integer elements.
563 /// Values returned by `.next_back()` correspond to elements in descending integer order.
564 ///
565 /// ```rust
566 /// # use range_set_blaze::RangeMapBlaze;
567 /// let map = RangeMapBlaze::from_iter([(3, "c"), (1, "a"), (2, "b")]);
568 /// let mut values_iter = map.values();
569 /// assert_eq!(values_iter.next(), Some(&"a"));
570 /// assert_eq!(values_iter.next_back(), Some(&"c"));
571 /// assert_eq!(values_iter.next(), Some(&"b"));
572 /// assert_eq!(values_iter.next_back(), None);
573 /// ```
574 pub fn values(&self) -> Values<T, &V, RangeValuesIter<'_, T, V>> {
575 Values::new(self.range_values())
576 }
577
578 /// Gets an iterator that visits the values in the [`RangeMapBlaze`] in
579 /// the order corresponding to the integer elements. Double-ended.
580 ///
581 /// The iterator consumes the [`RangeMapBlaze`], yielding one value at a time for
582 /// each integer in its ranges. For a non-consuming version, see the [`RangeMapBlaze::values`] method.
583 ///
584 /// # Examples
585 ///
586 /// Iterating over values in ascending order:
587 ///
588 /// ```rust
589 /// use range_set_blaze::RangeMapBlaze;
590 ///
591 /// let map = RangeMapBlaze::from_iter([(3, "c"), (1, "a"), (2, "b")]);
592 /// let mut into_values_iter = map.into_values();
593 /// assert_eq!(into_values_iter.next(), Some("a"));
594 /// assert_eq!(into_values_iter.next(), Some("b"));
595 /// assert_eq!(into_values_iter.next(), Some("c"));
596 /// assert_eq!(into_values_iter.next(), None);
597 /// ```
598 ///
599 /// Iterating over values in both ascending and descending order:
600 ///
601 /// ```rust
602 /// use range_set_blaze::RangeMapBlaze;
603 ///
604 /// let map = RangeMapBlaze::from_iter([(1..=3, "a"), (5..=5, "b")]);
605 /// let mut into_values_iter = map.into_values();
606 /// assert_eq!(into_values_iter.next(), Some("a"));
607 /// assert_eq!(into_values_iter.next_back(), Some("b"));
608 /// assert_eq!(into_values_iter.next(), Some("a"));
609 /// assert_eq!(into_values_iter.next_back(), Some("a"));
610 /// assert_eq!(into_values_iter.next(), None);
611 /// ```
612 ///
613 /// Values returned by `.next()` correspond to elements in ascending integer order.
614 /// Values returned by `.next_back()` correspond to elements in descending integer order.
615 #[inline]
616 pub fn into_values(self) -> IntoValues<T, V> {
617 IntoValues::new(self.btree_map.into_iter())
618 }
619
620 /// Returns the first element in the set, if any.
621 /// This element is always the minimum of all integer elements in the set.
622 ///
623 /// # Examples
624 ///
625 /// Basic usage:
626 ///
627 /// ```
628 /// use range_set_blaze::RangeMapBlaze;
629 ///
630 /// let mut map = RangeMapBlaze::new();
631 /// assert_eq!(map.first_key_value(), None);
632 /// map.insert(1,"a");
633 /// assert_eq!(map.first_key_value(), Some((1, &"a")));
634 /// map.insert(2,"b");
635 /// assert_eq!(map.first_key_value(), Some((1, &"a")));
636 /// ```
637 #[must_use]
638 pub fn first_key_value(&self) -> Option<(T, &V)> {
639 self.btree_map
640 .first_key_value()
641 .map(|(k, end_value)| (*k, &end_value.value))
642 }
643
644 /// Returns the element in the set, if any, that is equal to
645 /// the value.
646 ///
647 /// # Examples
648 ///
649 /// ```
650 /// use range_set_blaze::RangeMapBlaze;
651 ///
652 /// let map = RangeMapBlaze::from_iter([(3,"c"), (1,"a"), (2,"b")]);
653 /// assert_eq!(map.get(2), Some(&"b"));
654 /// assert_eq!(map.get(4), None);
655 /// ```
656 pub fn get(&self, key: T) -> Option<&V> {
657 self.get_key_value(key).map(|(_, value)| value)
658 }
659
660 /// Returns the key and value in the map, if any, that contains the given key.
661 ///
662 /// # Examples
663 ///
664 /// ```
665 /// use range_set_blaze::RangeMapBlaze;
666 ///
667 /// let map = RangeMapBlaze::from_iter([(3..=5, "c"), (1..=2, "a")]);
668 /// assert_eq!(map.get_key_value(2), Some((2, &"a")));
669 /// assert_eq!(map.get_key_value(4), Some((4, &"c")));
670 /// assert_eq!(map.get_key_value(6), None);
671 /// ```
672 pub fn get_key_value(&self, key: T) -> Option<(T, &V)> {
673 self.btree_map
674 .range(..=key)
675 .next_back()
676 .and_then(|(_start, end_value)| {
677 if key <= end_value.end {
678 Some((key, &end_value.value))
679 } else {
680 None
681 }
682 })
683 }
684
685 /// Returns the last element in the set, if any.
686 /// This element is always the maximum of all elements in the set.
687 ///
688 /// # Examples
689 ///
690 /// Basic usage:
691 ///
692 /// ```
693 /// use range_set_blaze::RangeMapBlaze;
694 ///
695 /// let mut map = RangeMapBlaze::new();
696 /// assert_eq!(map.last_key_value(), None);
697 /// map.insert(1, "a");
698 /// assert_eq!(map.last_key_value(), Some((1, &"a")));
699 /// map.insert(2, "b");
700 /// assert_eq!(map.last_key_value(), Some((2, &"b")));
701 /// ```
702 #[must_use]
703 pub fn last_key_value(&self) -> Option<(T, &V)> {
704 self.btree_map
705 .last_key_value()
706 .map(|(_, end_value)| (end_value.end, &end_value.value))
707 }
708
709 /// Create a [`RangeMapBlaze`] from a [`SortedDisjointMap`] iterator.
710 ///
711 /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
712 ///
713 /// [`SortedDisjointMap`]: trait.SortedDisjointMap.html#table-of-contents
714 ///
715 /// # Examples
716 ///
717 /// ```
718 /// use range_set_blaze::prelude::*;
719 ///
720 /// let a0 = RangeMapBlaze::from_sorted_disjoint_map(CheckSortedDisjointMap::new([(-10..=-5, &"a"), (1..=2, &"b")]));
721 /// let a1: RangeMapBlaze<i32,_> = CheckSortedDisjointMap::new([(-10..=-5, &"a"), (1..=2, &"b")]).into_range_map_blaze();
722 /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "a"), (1..=2, "b")"#);
723 /// ```
724 pub fn from_sorted_disjoint_map<VR, I>(iter: I) -> Self
725 where
726 VR: ValueRef<Target = V>,
727 I: SortedDisjointMap<T, VR>,
728 {
729 let mut iter_with_len = SortedDisjointMapWithLenSoFar::new(iter);
730 let btree_map: BTreeMap<T, EndValue<T, VR::Target>> = (&mut iter_with_len).collect();
731 Self {
732 btree_map,
733 len: iter_with_len.len_so_far(),
734 }
735 }
736
737 #[allow(dead_code)]
738 #[must_use]
739 pub(crate) fn len_slow(&self) -> <T as Integer>::SafeLen {
740 Self::btree_map_len(&self.btree_map)
741 }
742
743 /// Moves all elements from `other` into `self`, leaving `other` empty.
744 ///
745 /// This method has *right-to-left precedence*: if any ranges overlap, values in `other`
746 /// will overwrite those in `self`.
747 ///
748 /// # Performance
749 ///
750 /// This method inserts each range from `other` into `self` one-by-one, with overall time
751 /// complexity `O(n log m)`, where `n` is the number of ranges in `other` and `m` is the number
752 /// of ranges in `self`.
753 ///
754 /// For large `n`, consider using the `|` operator, which performs a sorted merge and runs in `O(n + m)` time.
755 ///
756 /// **See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
757 ///
758 /// # Examples
759 ///
760 /// ```
761 /// use range_set_blaze::RangeMapBlaze;
762 ///
763 /// let mut a = RangeMapBlaze::from_iter([(1..=3,"a")]);
764 /// let mut b = RangeMapBlaze::from_iter([(3..=5,"b")]);
765 ///
766 /// a.append(&mut b);
767 ///
768 /// assert_eq!(a.len(), 5u64);
769 /// assert_eq!(b.len(), 0u64);
770 ///
771 /// assert_eq!(a[1], "a");
772 /// assert_eq!(a[2], "a");
773 /// assert_eq!(a[3], "b");
774 /// assert_eq!(a[4], "b");
775 /// assert_eq!(a[5], "b");
776 /// ```
777 pub fn append(&mut self, other: &mut Self) {
778 let original_other_btree_map = core::mem::take(&mut other.btree_map);
779 other.len = <T as Integer>::SafeLen::zero();
780
781 for (start, end_value) in original_other_btree_map {
782 self.internal_add(start..=end_value.end, end_value.value);
783 }
784 }
785
786 /// Clears the map, removing all elements.
787 ///
788 /// # Examples
789 ///
790 /// ```
791 /// use range_set_blaze::RangeMapBlaze;
792 ///
793 /// let mut a = RangeMapBlaze::new();
794 /// a.insert(1, "a");
795 /// a.clear();
796 /// assert!(a.is_empty());
797 /// ```
798 pub fn clear(&mut self) {
799 self.btree_map.clear();
800 self.len = <T as Integer>::SafeLen::zero();
801 }
802
803 /// Returns `true` if the map contains no elements.
804 ///
805 /// # Examples
806 ///
807 /// ```
808 /// use range_set_blaze::RangeMapBlaze;
809 ///
810 /// let mut a = RangeMapBlaze::new();
811 /// assert!(a.is_empty());
812 /// a.insert(1, "a");
813 /// assert!(!a.is_empty());
814 /// ```
815 #[must_use]
816 #[inline]
817 pub fn is_empty(&self) -> bool {
818 self.btree_map.is_empty()
819 }
820
821 /// Returns `true` if the set contains an element equal to the value.
822 ///
823 /// # Examples
824 ///
825 /// ```
826 /// use range_set_blaze::RangeMapBlaze;
827 ///
828 /// let map = RangeMapBlaze::from_iter([(3,"c"), (1,"a"), (2,"b")]);
829 /// assert_eq!(map.contains_key(1), true);
830 /// assert_eq!(map.contains_key(4), false);
831 /// ```
832 pub fn contains_key(&self, key: T) -> bool {
833 self.btree_map
834 .range(..=key)
835 .next_back()
836 .is_some_and(|(_, end_value)| key <= end_value.end)
837 }
838
839 // LATER: might be able to shorten code by combining cases
840 fn delete_extra(&mut self, internal_range: &RangeInclusive<T>) {
841 let (start, end) = internal_range.clone().into_inner();
842 let mut after = self.btree_map.range_mut(start..);
843 let (start_after, end_value_after) = after
844 .next()
845 .expect("Real Assert: There will always be a next");
846 debug_assert!(start == *start_after && end == end_value_after.end);
847
848 let mut end_new = end;
849 let mut end_new_same_val = end;
850 let delete_list = after
851 .map_while(|(start_delete, end_value_delete)| {
852 // same values
853 if end_value_after.value == end_value_delete.value {
854 // must check this in two parts to avoid overflow
855 if *start_delete <= end || *start_delete <= end.add_one() {
856 end_new_same_val = max(end_new_same_val, end_value_delete.end);
857 end_new = max(end_new, end_value_delete.end);
858 self.len -= T::safe_len(&(*start_delete..=end_value_delete.end));
859 Some(*start_delete)
860 } else {
861 None
862 }
863 // different values
864 } else if *start_delete <= end {
865 end_new = max(end_new, end_value_delete.end);
866 self.len -= T::safe_len(&(*start_delete..=end_value_delete.end));
867 Some(*start_delete)
868 } else {
869 None
870 }
871 })
872 .collect::<Vec<_>>();
873 if end >= end_new {
874 for start in delete_list {
875 self.btree_map.remove(&start);
876 }
877 } else if end_new_same_val > end {
878 // last item is the same as the new and extends beyond the new
879 self.len += T::safe_len(&(end..=end_new.sub_one()));
880 debug_assert!(*start_after <= end_new);
881 end_value_after.end = end_new;
882 for start in delete_list {
883 self.btree_map.remove(&start);
884 }
885 } else {
886 // last item extends beyond the new but has a different value.
887 for &start in &delete_list[0..delete_list.len() - 1] {
888 self.btree_map.remove(&start);
889 // take the last one
890 }
891 let last = self
892 .btree_map
893 .remove(&delete_list[delete_list.len() - 1])
894 .expect("Real Assert: There will always be a last");
895 let last_end = last.end;
896 debug_assert!(end.add_one() <= last.end); // real assert
897 self.btree_map.insert(end.add_one(), last);
898 self.len += T::safe_len(&(end.add_one()..=last_end));
899 }
900 }
901
902 /// Adds a value to the set.
903 ///
904 /// Returns whether the value was newly inserted. That is:
905 ///
906 /// - If the set did not previously contain an equal value, `true` is
907 /// returned.
908 /// - If the set already contained an equal value, `false` is returned, and
909 /// the entry is not updated.
910 ///
911 /// # Performance
912 /// Inserting n items will take in O(n log m) time, where n is the number of inserted items and m is the number of ranges in `self`.
913 /// When n is large, consider using `|` which is O(n+m) time.
914 ///
915 /// # Examples
916 ///
917 /// ```
918 /// use range_set_blaze::RangeMapBlaze;
919 ///
920 /// let mut map = RangeMapBlaze::new();
921 /// assert_eq!(map.insert(37, "a"), None);
922 /// assert_eq!(map.is_empty(), false);
923 ///
924 /// map.insert(37, "b");
925 /// assert_eq!(map.insert(37, "c"), Some("b"));
926 /// assert_eq!(map[37], "c");
927 /// ```
928 pub fn insert(&mut self, key: T, value: V) -> Option<V> {
929 let old = self.get(key).cloned();
930 self.internal_add(key..=key, value);
931 old
932 }
933
934 // LATER: Think about an entry API with or_insert and or_insert_with
935
936 /// Constructs an iterator over a sub-range of elements in the set.
937 ///
938 /// Not to be confused with [`RangeMapBlaze::ranges`], which returns an iterator over the ranges in the set.
939 ///
940 /// The simplest way is to use the range syntax `min..max`, thus `range(min..max)` will
941 /// yield elements from min (inclusive) to max (exclusive).
942 /// The range may also be entered as `(Bound<T, V, VR>, Bound<T, V, VR>)`, so for example
943 /// `range((Excluded(4), Included(10)))` will yield a left-exclusive, right-inclusive
944 /// range from 4 to 10.
945 ///
946 /// # Panics
947 ///
948 /// Panics if start (inclusive) is greater than end (inclusive).
949 ///
950 /// # Performance
951 ///
952 /// Although this could be written to run in time O(ln(n)) in the number of ranges, it is currently O(n) in the number of ranges.
953 ///
954 /// # Examples
955 ///
956 /// ```
957 /// use range_set_blaze::RangeMapBlaze;
958 /// use core::ops::Bound::Included;
959 ///
960 /// let mut map = RangeMapBlaze::new();
961 /// map.insert(3, "a");
962 /// map.insert(5, "b");
963 /// map.insert(8, "c");
964 /// for (key, value) in map.range((Included(4), Included(8))) {
965 /// println!("{key}: {value}");
966 /// } // prints "5: b" and "8: c"
967 /// assert_eq!(Some((5, "b")), map.range(4..).next());
968 /// ```
969 #[allow(clippy::manual_assert)] // We use "if...panic!" for coverage auditing.
970 pub fn range<R>(&self, range: R) -> IntoIterMap<T, V>
971 where
972 R: RangeBounds<T>,
973 {
974 // LATER 'range' could be made more efficient (it currently creates a RangeMapBlaze for no good reason)
975 let (start, end) = extract_range(range);
976 assert!(
977 start <= end,
978 "start (inclusive) must be less than or equal to end (inclusive)"
979 );
980
981 let bounds = CheckSortedDisjoint::new([start..=end]);
982 let range_map_blaze = self
983 .range_values()
984 .map_and_set_intersection(bounds)
985 .into_range_map_blaze();
986 range_map_blaze.into_iter()
987 }
988
989 /// Adds a range to the set.
990 ///
991 /// Returns whether any values where newly inserted. That is:
992 ///
993 /// - If the set did not previously contain some value in the range, `true` is
994 /// returned.
995 /// - If the set already contained every value in the range, `false` is returned, and
996 /// the entry is not updated.
997 ///
998 /// # Performance
999 /// Inserting n items will take in O(n log m) time, where n is the number of inserted items and m is the number of ranges in `self`.
1000 /// When n is large, consider using `|` which is O(n+m) time.
1001 ///
1002 /// # Examples
1003 ///
1004 /// ```
1005 /// use range_set_blaze::RangeMapBlaze;
1006 ///
1007 /// let mut map = RangeMapBlaze::new();
1008 /// assert_eq!(map.ranges_insert(2..=5, "a"), true);
1009 /// assert_eq!(map.ranges_insert(5..=6, "b"), true);
1010 /// assert_eq!(map.ranges_insert(3..=4, "c"), false);
1011 /// assert_eq!(map.len(), 5u64);
1012 /// ```
1013 pub fn ranges_insert(&mut self, range: RangeInclusive<T>, value: V) -> bool {
1014 let len_before = self.len;
1015 self.internal_add(range, value);
1016 self.len != len_before
1017 }
1018
1019 /// If the set contains an element equal to the value, removes it from the
1020 /// set and drops it. Returns whether such an element was present.
1021 ///
1022 /// # Examples
1023 ///
1024 /// ```
1025 /// use range_set_blaze::RangeMapBlaze;
1026 ///
1027 /// let mut map = RangeMapBlaze::new();
1028 /// map.insert(1, "a");
1029 /// assert_eq!(map.remove(1), Some("a"));
1030 /// assert_eq!(map.remove(1), None);
1031 /// ```
1032 #[allow(clippy::missing_panics_doc)]
1033 pub fn remove(&mut self, key: T) -> Option<V> {
1034 // The code can have only one mutable reference to self.btree_map.
1035
1036 // Find that range that might contain the key
1037 let (start_ref, end_value_mut) = self.btree_map.range_mut(..=key).next_back()?;
1038 let end = end_value_mut.end;
1039
1040 // If the key is not in the range, we're done
1041 if end < key {
1042 return None;
1043 }
1044 let start = *start_ref;
1045 debug_assert!(start <= key, "Real Assert: start <= key");
1046
1047 // It's in the range.
1048 self.len -= <T::SafeLen>::one();
1049
1050 let value = if start == key {
1051 self.btree_map
1052 .remove(&start)
1053 .expect("Real Assert: There will always be a start")
1054 .value
1055 } else {
1056 debug_assert!(start < key, "Real Assert: start < key");
1057 // This range will now end at key-1.
1058 end_value_mut.end = key.sub_one();
1059 end_value_mut.value.clone()
1060 };
1061
1062 // If needed, add a new range after key
1063 if key < end {
1064 self.btree_map.insert(
1065 key.add_one(),
1066 EndValue {
1067 end,
1068 value: value.clone(),
1069 },
1070 );
1071 }
1072
1073 Some(value)
1074 }
1075
1076 /// Splits the collection into two at the value. Returns a new collection
1077 /// with all elements greater than or equal to the value.
1078 ///
1079 /// # Examples
1080 ///
1081 /// Basic usage:
1082 ///
1083 /// ```
1084 /// use range_set_blaze::RangeMapBlaze;
1085 ///
1086 /// let mut a = RangeMapBlaze::new();
1087 /// a.insert(1, "a");
1088 /// a.insert(2, "b");
1089 /// a.insert(3, "c");
1090 /// a.insert(17, "d");
1091 /// a.insert(41, "e");
1092 ///
1093 /// let b = a.split_off(3);
1094 ///
1095 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=1, "a"), (2..=2, "b")]));
1096 /// assert_eq!(b, RangeMapBlaze::from_iter([(3..=3, "c"), (17..=17, "d"), (41..=41, "e")]));
1097 /// ```
1098 #[must_use]
1099 pub fn split_off(&mut self, key: T) -> Self {
1100 let old_len = self.len;
1101 let old_btree_len = self.btree_map.len();
1102 let mut new_btree = self.btree_map.split_off(&key);
1103 let Some(last_entry) = self.btree_map.last_entry() else {
1104 // Left is empty
1105 self.len = T::SafeLen::zero();
1106 return Self {
1107 btree_map: new_btree,
1108 len: old_len,
1109 };
1110 };
1111
1112 let end_value = last_entry.get();
1113 let end = end_value.end;
1114 if end < key {
1115 // The split is clean
1116 let (a_len, b_len) = self.two_element_lengths(old_btree_len, &new_btree, old_len);
1117 self.len = a_len;
1118 return Self {
1119 btree_map: new_btree,
1120 len: b_len,
1121 };
1122 }
1123
1124 // The split is not clean, so we must move some keys from the end of self to the start of b.
1125 let value = end_value.value.clone();
1126 last_entry.into_mut().end = key.sub_one();
1127 new_btree.insert(key, EndValue { end, value });
1128 let (a_len, b_len) = self.two_element_lengths(old_btree_len, &new_btree, old_len);
1129 self.len = a_len;
1130 Self {
1131 btree_map: new_btree,
1132 len: b_len,
1133 }
1134 }
1135
1136 // Find the len of the smaller btree_map and then the element len of self & b.
1137 fn two_element_lengths(
1138 &self,
1139 old_btree_len: usize,
1140 new_btree: &BTreeMap<T, EndValue<T, V>>,
1141 mut old_len: <T as Integer>::SafeLen,
1142 ) -> (<T as Integer>::SafeLen, <T as Integer>::SafeLen) {
1143 if old_btree_len / 2 < new_btree.len() {
1144 let a_len = Self::btree_map_len(&self.btree_map);
1145 old_len -= a_len;
1146 (a_len, old_len)
1147 } else {
1148 let b_len = Self::btree_map_len(new_btree);
1149 old_len -= b_len;
1150 (old_len, b_len)
1151 }
1152 }
1153
1154 fn btree_map_len(btree_map: &BTreeMap<T, EndValue<T, V>>) -> T::SafeLen {
1155 btree_map.iter().fold(
1156 <T as Integer>::SafeLen::zero(),
1157 |acc, (start, end_value)| acc + T::safe_len(&(*start..=end_value.end)),
1158 )
1159 }
1160
1161 #[inline]
1162 fn has_gap(end_before: T, start: T) -> bool {
1163 end_before
1164 .checked_add_one()
1165 .is_some_and(|end_before_succ| end_before_succ < start)
1166 }
1167
1168 #[cfg(never)]
1169 // TODO: Look at other TODOs before enabling this.
1170 // #![cfg_attr(feature = "cursor", feature(btree_cursors, new_range_api))]
1171 // #[cfg(feature = "cursor")]
1172 // use core::{cmp::min, range::Bound};
1173 #[inline]
1174 fn adjust_touching_for_insert(
1175 &mut self,
1176 stored_start: T,
1177 stored_end_value: EndValue<T, V>,
1178 range: &mut RangeInclusive<T>,
1179 value: &V,
1180 ) {
1181 let stored_value = &stored_end_value.value;
1182 let stored_end = stored_end_value.end;
1183
1184 // ── 1. Same value → coalesce completely ──────────────────────────────
1185 if stored_value == value {
1186 let new_start = min(*range.start(), stored_start);
1187 let new_end = max(*range.end(), stored_end);
1188 *range = new_start..=new_end;
1189
1190 self.len -= T::safe_len(&(stored_start..=stored_end));
1191 self.btree_map.remove(&stored_start);
1192 return;
1193 }
1194
1195 // ── 2. Different value → may need to split ───────────────────────────
1196 let overlaps = stored_start <= *range.end() && stored_end >= *range.start();
1197
1198 if overlaps {
1199 // Remove the overlapping range first.
1200 self.len -= T::safe_len(&(stored_start..=stored_end));
1201 self.btree_map.remove(&stored_start);
1202
1203 // Left residual slice
1204 if stored_start < *range.start() {
1205 let left_end = range.start().sub_one(); // TODO are we sure this won't underflow?
1206 self.len += T::safe_len(&(stored_start..=left_end));
1207 self.btree_map.insert(
1208 stored_start,
1209 EndValue {
1210 end: left_end,
1211 value: stored_value.clone(),
1212 },
1213 );
1214 }
1215
1216 // Right residual slice
1217 if stored_end > *range.end() {
1218 let right_start = range.end().add_one();
1219 self.len += T::safe_len(&(right_start..=stored_end));
1220 self.btree_map.insert(
1221 right_start,
1222 EndValue {
1223 end: stored_end,
1224 value: stored_end_value.value, // already owned
1225 },
1226 );
1227 }
1228 }
1229 // Otherwise: no overlap → keep ranges as they are.
1230 }
1231
1232 #[cfg(never)]
1233 // For benchmarking, based on https://github.com/jeffparsons/rangemap's `insert` method.
1234 pub(crate) fn internal_add(&mut self, mut range: RangeInclusive<T>, value: V) {
1235 use core::ops::Bound::{Included, Unbounded}; // TODO: Move to the top
1236
1237 let start = *range.start();
1238 let end = *range.end();
1239
1240 // === case: empty
1241 if end < start {
1242 return;
1243 }
1244
1245 // Walk *backwards* from the first stored range whose start ≤ `start`.
1246 // Take the nearest two so we can look at “before” and “before-before”.
1247 let mut candidates = self
1248 .btree_map
1249 .range::<T, _>((Unbounded, Included(&start))) // ..= start
1250 .rev()
1251 .take(2)
1252 .filter(|(_stored_start, stored_end_value)| {
1253 // TODO use saturation arithmetic to avoid underflow
1254 let end = stored_end_value.end;
1255 end >= start || (start != T::min_value() && end >= start.sub_one())
1256 });
1257
1258 if let Some(mut candidate) = candidates.next() {
1259 // Or the one before it if both cases described above exist.
1260 if let Some(another_candidate) = candidates.next() {
1261 candidate = another_candidate;
1262 }
1263
1264 let stored_start: T = *candidate.0;
1265 let stored_end_value: EndValue<T, V> = candidate.1.clone();
1266 self.adjust_touching_for_insert(
1267 stored_start,
1268 stored_end_value,
1269 &mut range, // `end` is the current (possibly growing) tail
1270 &value,
1271 );
1272 }
1273
1274 // let range = &mut range; // &mut RangeInclusive<T>
1275
1276 loop {
1277 // first range whose start ≥ new_range.start()
1278 let next_entry = self
1279 .btree_map
1280 .range::<T, _>((Included(range.start()), Unbounded))
1281 .next();
1282
1283 let Some((&stored_start, stored_end_value)) = next_entry else {
1284 break; // nothing more
1285 };
1286
1287 let second_last_possible_start = *range.end();
1288 let maybe_latest_start = if second_last_possible_start == T::max_value() {
1289 None
1290 } else {
1291 Some(second_last_possible_start.add_one())
1292 };
1293
1294 if maybe_latest_start.map_or(false, |latest| stored_start > latest) {
1295 break; // beyond end + 1
1296 }
1297 if let Some(latest) = maybe_latest_start {
1298 if stored_start == latest && stored_end_value.value != value {
1299 break; // touches but diff value
1300 }
1301 }
1302
1303 // clone so we can mutate the map in the helper
1304 let end_value_clone = stored_end_value.clone();
1305
1306 self.adjust_touching_for_insert(stored_start, end_value_clone, &mut range, &value);
1307
1308 // loop again; `new_range` might have grown on the right
1309 }
1310
1311 let start_key = *range.start();
1312 let end_key = *range.end();
1313 // self.len += T::safe_len(&(start_key..=end_key));
1314 self.btree_map.insert(
1315 start_key,
1316 EndValue {
1317 end: end_key,
1318 value,
1319 },
1320 );
1321
1322 debug_assert!(self.len == self.len_slow());
1323 }
1324
1325 #[cfg(never)]
1326 // #[cfg(feature = "cursor")]
1327 pub(crate) fn internal_add(&mut self, mut range: RangeInclusive<T>, value: V) {
1328 // Based on https://github.com/jeffparsons/rangemap's `insert` method but with cursor's added
1329 use core::ops::Bound::{Included, Unbounded};
1330 use std::collections::btree_map::CursorMut;
1331
1332 let start = *range.start();
1333 let end = *range.end();
1334
1335 // === case: empty
1336 if end < start {
1337 return;
1338 }
1339
1340 // Walk *backwards* from the first stored range whose start ≤ `start`.
1341 // Take the nearest two so we can look at “before” and “before-before”.
1342 let mut candidates = self
1343 .btree_map
1344 .range::<T, _>((Unbounded, Included(&start))) // ..= start
1345 .rev()
1346 .take(2)
1347 .filter(|(_stored_start, stored_end_value)| {
1348 let end = stored_end_value.end;
1349 end >= start || (start != T::min_value() && end >= start.sub_one())
1350 });
1351
1352 if let Some(mut candidate) = candidates.next() {
1353 // Or the one before it if both cases described above exist.
1354 if let Some(another_candidate) = candidates.next() {
1355 candidate = another_candidate;
1356 }
1357
1358 let stored_start: T = *candidate.0;
1359 let stored_end_value: EndValue<T, V> = candidate.1.clone();
1360 self.adjust_touching_for_insert(
1361 stored_start,
1362 stored_end_value,
1363 &mut range, // `end` is the current (possibly growing) tail
1364 &value,
1365 );
1366 }
1367 // keep looping until we hit the stop window
1368 loop {
1369 // create a fresh cursor _for this iteration only_
1370 let mut cur: CursorMut<'_, T, EndValue<T, V>> = self
1371 .btree_map
1372 .lower_bound_mut(Bound::Included(range.start()));
1373
1374 let Some(peeked) = cur.peek_next() else {
1375 break;
1376 };
1377 let (&stored_start, maybe_end_value) = peeked;
1378
1379 let last_ok = *range.end();
1380 if last_ok == T::max_value() {
1381 if stored_start > last_ok {
1382 break;
1383 }
1384 } else {
1385 let latest = last_ok.add_one();
1386 if stored_start > latest {
1387 break;
1388 }
1389 if stored_start == latest && maybe_end_value.value != value {
1390 break;
1391 }
1392 }
1393
1394 // now clone and remove
1395 let cloned = maybe_end_value.clone();
1396 cur.remove_next();
1397
1398 // now we can call any &mut-self helper safely
1399 self.adjust_touching_for_insert(stored_start, cloned, &mut range, &value);
1400 }
1401
1402 let start_key = *range.start();
1403 let end_key = *range.end();
1404
1405 self.btree_map.insert(
1406 start_key,
1407 EndValue {
1408 end: end_key,
1409 value, // moves `value`
1410 },
1411 );
1412 self.len += T::safe_len(&(start_key..=end_key));
1413
1414 debug_assert!(self.len == self.len_slow());
1415 }
1416
1417 // https://stackoverflow.com/questions/49599833/how-to-find-next-smaller-key-in-btreemap-btreeset
1418 // https://stackoverflow.com/questions/35663342/how-to-modify-partially-remove-a-range-from-a-btreemap
1419 // LATER might be able to shorten code by combining cases
1420 // FUTURE: would be nice of BTreeMap to have a partition_point function that returns two iterators
1421 #[allow(clippy::too_many_lines)]
1422 #[allow(clippy::cognitive_complexity)]
1423 pub(crate) fn internal_add(&mut self, range: RangeInclusive<T>, value: V) {
1424 let (start, end) = range.clone().into_inner();
1425
1426 // === case: empty
1427 if end < start {
1428 return;
1429 }
1430 let mut before_iter = self.btree_map.range_mut(..=start).rev();
1431
1432 // === case: no before
1433 let Some((start_before, end_value_before)) = before_iter.next() else {
1434 // no before, so must be first
1435 self.internal_add2(&range, value);
1436 // You must return or break out of the current block after handling the failure case
1437 return;
1438 };
1439
1440 let start_before = *start_before;
1441 let end_before = end_value_before.end;
1442
1443 // === case: gap between before and new
1444 if Self::has_gap(end_before, start) {
1445 // there is a gap between the before and the new
1446 // ??? aa...
1447 self.internal_add2(&range, value);
1448 return;
1449 }
1450
1451 let before_contains_new = end_before >= end;
1452 let same_value = value == end_value_before.value;
1453
1454 // === case: same value and before contains new
1455 if before_contains_new && same_value {
1456 // same value, so do nothing
1457 // AAAAA
1458 // aaa
1459 return;
1460 }
1461
1462 // === case: same value and new extends beyond before
1463 if !before_contains_new && same_value {
1464 // same value, so just extend the before
1465 // AAA
1466 // aaaa...
1467 self.len += T::safe_len(&(end_before..=end.sub_one()));
1468 debug_assert!(start_before <= end); // real assert
1469 end_value_before.end = end;
1470 self.delete_extra(&(start_before..=end));
1471 return;
1472 }
1473
1474 // Thus, the values are different
1475
1476 let same_start = start == start_before;
1477
1478 // === case: new goes beyond before and different values
1479 if !before_contains_new && !same_value && same_start {
1480 // Thus, values are different, before contains new, and they start together
1481
1482 let interesting_before_before = match before_iter.next() {
1483 Some(bb) if bb.1.end.add_one() == start && bb.1.value == value => Some(bb),
1484 _ => None,
1485 };
1486
1487 // === case: values are different, new extends beyond before, and they start together and an interesting before-before
1488 // an interesting before-before: something before before, touching and with the same value as new
1489 if let Some(bb) = interesting_before_before {
1490 debug_assert!(!before_contains_new && !same_value && same_start);
1491
1492 // AABBBB
1493 // aaaaaaa
1494 // AAAAAAAAA
1495 self.len += T::safe_len(&(bb.1.end.add_one()..=end));
1496 let bb_start = *bb.0;
1497 debug_assert!(bb_start <= end); // real assert
1498 bb.1.end = end;
1499 self.delete_extra(&(bb_start..=end));
1500 return;
1501 }
1502
1503 // === case: values are different, they start together but new ends later and no interesting before-before
1504 debug_assert!(!same_value && same_start && interesting_before_before.is_none());
1505
1506 // ^BBBB
1507 // aaaaaaa
1508 // ^AAAAAAA
1509 debug_assert!(end_before < end); // real assert
1510 self.len += T::safe_len(&(end_before.add_one()..=end));
1511 end_value_before.end = end;
1512 end_value_before.value = value;
1513 self.delete_extra(&range);
1514 return;
1515 }
1516 if !before_contains_new && !same_value && !same_start {
1517 // different value, so must trim the before and then insert the new
1518 // BBB
1519 // aaaa...
1520 if start <= end_before {
1521 self.len -= T::safe_len(&(start..=end_before));
1522 debug_assert!(start_before <= start.sub_one()); // real assert
1523 end_value_before.end = start.sub_one(); // safe because !same_start
1524 }
1525 self.internal_add2(&range, value);
1526 return;
1527 }
1528
1529 // Thus, the values are different and before contains new
1530 debug_assert!(before_contains_new && !same_value);
1531
1532 let same_end = end == end_before;
1533
1534 // === case: values are different and new is surrounded by before
1535 if !same_start && !same_end {
1536 debug_assert!(before_contains_new && !same_value);
1537 debug_assert!(start_before < start && end < end_before);
1538 // Different values still ...
1539 // The new starts later and ends before,
1540 // BBBBBB
1541 // aaa
1542 // BBAAAB
1543 // so trim the before and then insert two
1544 debug_assert!(start_before <= start.sub_one()); // real assert
1545 end_value_before.end = start.sub_one();
1546 let before_value = end_value_before.value.clone();
1547 debug_assert!(start <= end); // real assert
1548 self.btree_map.insert(start, EndValue { end, value });
1549 debug_assert!(end.add_one() <= end_before); // real assert
1550 self.btree_map.insert(
1551 end.add_one(),
1552 EndValue {
1553 end: end_before,
1554 value: before_value,
1555 },
1556 );
1557 return;
1558 }
1559
1560 // === case: values are different, new instead of before and they end together
1561 if !same_start && same_end {
1562 debug_assert!(before_contains_new && !same_value);
1563 debug_assert!(start_before < start && end == end_before);
1564 // Different values still ...
1565 // The new starts later but they end together,
1566 // BBBBB???
1567 // aaa
1568 // BBAAA???
1569 // so trim the before and then insert the new.
1570 debug_assert!(start_before <= start.sub_one()); // real assert
1571 end_value_before.end = start.sub_one();
1572 debug_assert!(start <= end); // real assert
1573 self.btree_map.insert(start, EndValue { end, value });
1574 self.delete_extra(&(start..=end));
1575 return;
1576 }
1577
1578 // Thus, values are different, before contains new, and they start together
1579
1580 let interesting_before_before = match before_iter.next() {
1581 Some(bb) if bb.1.end.add_one() == start && bb.1.value == value => Some(bb),
1582 _ => None,
1583 };
1584
1585 // === case: values are different, before contains new, and they start together and an interesting before-before
1586 // an interesting before-before: something before before, touching and with the same value as new
1587 if let Some(bb) = interesting_before_before {
1588 debug_assert!(before_contains_new && !same_value && same_start);
1589
1590 // AABBBB???
1591 // aaaa
1592 // AAAAAA???
1593 self.len += T::safe_len(&(bb.1.end.add_one()..=end));
1594 let bb_start = *bb.0;
1595 debug_assert!(bb_start <= end); // real assert
1596 bb.1.end = end;
1597 self.delete_extra(&(bb_start..=end));
1598 return;
1599 }
1600
1601 // === case: values are different, they start and end together and no interesting before-before
1602 if same_end {
1603 debug_assert!(!same_value && same_start && interesting_before_before.is_none());
1604
1605 // ^BBBB???
1606 // aaaa
1607 // ^AAAA???
1608 end_value_before.value = value;
1609 self.delete_extra(&(start_before..=end));
1610 return;
1611 }
1612
1613 // === case: values are different, they start together, new ends first, and no interesting before-before
1614 {
1615 debug_assert!(
1616 !same_value
1617 && same_start
1618 && end < end_before
1619 && interesting_before_before.is_none()
1620 );
1621
1622 // ^BBBB
1623 // aaa
1624 // ^AAAB
1625 let value_before = core::mem::replace(&mut end_value_before.value, value);
1626 debug_assert!(start_before <= end); // real assert
1627 end_value_before.end = end;
1628 debug_assert!(end.add_one() <= end_before); // real assert
1629 self.btree_map.insert(
1630 end.add_one(),
1631 EndValue {
1632 end: end_before,
1633 value: value_before,
1634 },
1635 );
1636 }
1637 }
1638
1639 #[inline]
1640 fn internal_add2(&mut self, internal_range: &RangeInclusive<T>, value: V) {
1641 let (start, end) = internal_range.clone().into_inner();
1642 let end_value = EndValue { end, value };
1643 debug_assert!(start <= end_value.end); // real assert
1644 let was_there = self.btree_map.insert(start, end_value);
1645 debug_assert!(was_there.is_none()); // no range with the same start should be there
1646 self.delete_extra(internal_range);
1647 self.len += T::safe_len(internal_range);
1648 }
1649
1650 /// Returns the number of elements in the set.
1651 ///
1652 /// The number is allowed to be very, very large.
1653 ///
1654 /// # Examples
1655 ///
1656 /// ```
1657 /// use range_set_blaze::prelude::*;
1658 ///
1659 /// let mut a = RangeMapBlaze::new();
1660 /// assert_eq!(a.len(), 0u64);
1661 /// a.insert(1, "a");
1662 /// assert_eq!(a.len(), 1u64);
1663 ///
1664 /// let a = RangeMapBlaze::from_iter([
1665 /// (-170_141_183_460_469_231_731_687_303_715_884_105_728_i128..=10, "a"),
1666 /// (-10..=170_141_183_460_469_231_731_687_303_715_884_105_726, "a")]);
1667 /// assert_eq!(
1668 /// a.len(),
1669 /// UIntPlusOne::UInt(340282366920938463463374607431768211455)
1670 /// );
1671 /// ```
1672 #[must_use]
1673 pub const fn len(&self) -> <T as Integer>::SafeLen {
1674 self.len
1675 }
1676
1677 /// Makes a new, empty [`RangeMapBlaze`].
1678 ///
1679 /// # Examples
1680 ///
1681 /// ```
1682 /// # #![allow(unused_mut)]
1683 /// use range_set_blaze::RangeMapBlaze;
1684 ///
1685 /// let mut map = RangeMapBlaze::new();
1686 ///
1687 /// // entries can now be inserted into the empty map
1688 /// map.insert(1, "a");
1689 /// assert_eq!(map[1], "a");
1690 /// ```
1691 #[inline]
1692 #[must_use]
1693 pub fn new() -> Self {
1694 Self {
1695 btree_map: BTreeMap::new(),
1696 len: <T as Integer>::SafeLen::zero(),
1697 }
1698 }
1699
1700 /// Extends the [`RangeMapBlaze`] with an iterator of `(range, value)` pairs without pre-merging.
1701 ///
1702 /// Unlike [`RangeMapBlaze::extend`], this method does **not** merge adjacent or overlapping ranges
1703 /// before inserting. Each `(range, value)` pair is added as-is, making it faster when the input
1704 /// is already well-structured or disjoint.
1705 ///
1706 /// This method has *right-to-left precedence*: later ranges in the iterator overwrite earlier ones.
1707 ///
1708 /// **See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
1709 ///
1710 /// # Examples
1711 /// ```
1712 /// use range_set_blaze::RangeMapBlaze;
1713 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
1714 /// a.extend_simple([(3..=5, "b"), (5..=5, "c")]);
1715 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=5, "c")]));
1716 ///
1717 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
1718 /// a.extend([(3..=5, "b"), (5..=5, "c")]);
1719 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=5, "c")]));
1720 ///
1721 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
1722 /// let mut b = RangeMapBlaze::from_iter([(3..=5, "b"), (5..=5, "c")]);
1723 /// a |= b;
1724 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=4, "a"), (5..=5, "b")]));
1725 /// ```
1726 pub fn extend_simple<I>(&mut self, iter: I)
1727 where
1728 I: IntoIterator<Item = (RangeInclusive<T>, V)>,
1729 {
1730 let iter = iter.into_iter();
1731
1732 for (range, value) in iter {
1733 self.internal_add(range, value);
1734 }
1735 }
1736
1737 /// Extends the [`RangeMapBlaze`] with the contents of an owned [`RangeMapBlaze`].
1738 ///
1739 /// This method has *right-to-left precedence* — like `BTreeMap`, but unlike most
1740 /// other `RangeMapBlaze` methods. If the maps contain overlapping ranges,
1741 /// values from `other` will overwrite those in `self`.
1742 ///
1743 /// Compared to [`RangeMapBlaze::extend_with`], this method can be more efficient because it can
1744 /// consume the internal data structures of `other` directly, avoiding some cloning.
1745 ///
1746 /// **See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
1747 ///
1748 /// # Examples
1749 ///
1750 /// ```
1751 /// use range_set_blaze::RangeMapBlaze;
1752 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
1753 /// let mut b = RangeMapBlaze::from_iter([(3..=4, "b"), (5..=5, "c")]);
1754 /// a.extend_from(b);
1755 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=5, "c")]));
1756 /// ```
1757 #[inline]
1758 pub fn extend_from(&mut self, other: Self) {
1759 for (start, end_value) in other.btree_map {
1760 let range = start..=end_value.end;
1761 self.internal_add(range, end_value.value);
1762 }
1763 }
1764
1765 /// Extends the [`RangeMapBlaze`] with the contents of a borrowed [`RangeMapBlaze`].
1766 ///
1767 /// This method has *right-to-left precedence* — like `BTreeMap`, but unlike most
1768 /// other `RangeMapBlaze` methods. If the maps contain overlapping ranges,
1769 /// values from `other` will overwrite those in `self`.
1770 ///
1771 /// This method is simple and predictable but not the most efficient option when
1772 /// the right-hand side is larger. For better performance when ownership is available,
1773 /// consider using [`RangeMapBlaze::extend_from`] or the `|=` operator.
1774 ///
1775 /// **See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
1776 ///
1777 /// # Examples
1778 ///
1779 /// ```
1780 /// use range_set_blaze::RangeMapBlaze;
1781 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
1782 /// let mut b = RangeMapBlaze::from_iter([(3..=4, "b"), (5..=5, "c")]);
1783 /// a.extend_from(b);
1784 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=5, "c")]));
1785 /// ```
1786 #[inline]
1787 pub fn extend_with(&mut self, other: &Self) {
1788 for (start, end_value) in &other.btree_map {
1789 let range = *start..=end_value.end;
1790 self.internal_add(range, end_value.value.clone());
1791 }
1792 }
1793
1794 /// Removes the first element from the set and returns it, if any.
1795 /// The first element is always the minimum element in the set.
1796 ///
1797 /// Often, internally, the value must be cloned.
1798 ///
1799 /// # Examples
1800 ///
1801 /// ```
1802 /// use range_set_blaze::RangeMapBlaze;
1803 ///
1804 /// let mut map = RangeMapBlaze::new();
1805 ///
1806 /// map.insert(1, "a");
1807 /// map.insert(2, "b");
1808 /// while let Some((key, _val)) = map.pop_first() {
1809 /// assert!(map.iter().all(|(k, _v)| k > key));
1810 /// }
1811 /// assert!(map.is_empty());
1812 /// ```
1813 pub fn pop_first(&mut self) -> Option<(T, V)>
1814 where
1815 V: Clone,
1816 {
1817 let entry = self.btree_map.first_entry()?;
1818 // We must remove the entry because the key will change
1819 let (start, end_value) = entry.remove_entry();
1820
1821 self.len -= T::SafeLen::one();
1822 if start == end_value.end {
1823 Some((start, end_value.value))
1824 } else {
1825 let value = end_value.value.clone();
1826 self.btree_map.insert(start.add_one(), end_value);
1827 Some((start, value))
1828 }
1829 }
1830
1831 /// Removes the last value from the set and returns it, if any.
1832 /// The last value is always the maximum value in the set.
1833 ///
1834 /// Often, internally, the value must be cloned.
1835 ///
1836 /// # Examples
1837 ///
1838 /// ```
1839 /// use range_set_blaze::RangeMapBlaze;
1840 ///
1841 /// let mut map = RangeMapBlaze::new();
1842 /// map.insert(1, "a");
1843 /// map.insert(2, "b");
1844 /// while let Some((key, _val)) = map.pop_last() {
1845 /// assert!(map.iter().all(|(k, _v)| k < key));
1846 /// }
1847 /// assert!(map.is_empty());
1848 /// ```
1849 pub fn pop_last(&mut self) -> Option<(T, V)> {
1850 let mut entry = self.btree_map.last_entry()?;
1851 let start = *entry.key();
1852 self.len -= T::SafeLen::one();
1853 let end = entry.get().end;
1854 if start == end {
1855 let value = entry.remove_entry().1.value;
1856 Some((end, value))
1857 } else {
1858 let value = entry.get().value.clone();
1859 entry.get_mut().end.assign_sub_one();
1860 Some((end, value))
1861 }
1862 }
1863
1864 /// An iterator that visits the ranges and values in the [`RangeMapBlaze`],
1865 ///
1866 /// Also see [`RangeMapBlaze::iter`] and [`RangeMapBlaze::into_range_values`].
1867 ///
1868 /// # Examples
1869 ///
1870 /// ```
1871 /// use range_set_blaze::RangeMapBlaze;
1872 ///
1873 /// let map = RangeMapBlaze::from_iter([(10..=20, "a"), (15..=25, "b"), (30..=40, "c")]);
1874 /// let mut range_values = map.range_values();
1875 /// assert_eq!(range_values.next(), Some((10..=20, &"a")));
1876 /// assert_eq!(range_values.next(), Some((21..=25, &"b")));
1877 /// assert_eq!(range_values.next(), Some((30..=40, &"c")));
1878 /// assert_eq!(range_values.next(), None);
1879 /// ```
1880 ///
1881 /// Values returned by the iterator are returned in ascending order
1882 /// with left-to-right precedence.
1883 ///
1884 /// ```
1885 /// use range_set_blaze::RangeMapBlaze;
1886 ///
1887 /// let map = RangeMapBlaze::from_iter([(30..=40, "c"), (15..=25, "b"), (10..=20, "a")]);
1888 /// let mut range_values = map.range_values();
1889 /// assert_eq!(range_values.next(), Some((10..=14, &"a")));
1890 /// assert_eq!(range_values.next(), Some((15..=25, &"b")));
1891 /// assert_eq!(range_values.next(), Some((30..=40, &"c")));
1892 /// assert_eq!(range_values.next(), None);
1893 /// ```
1894 pub fn range_values(&self) -> RangeValuesIter<'_, T, V> {
1895 RangeValuesIter::new(&self.btree_map)
1896 }
1897
1898 /// An iterator that visits the ranges and values in the [`RangeMapBlaze`]. Double-ended.
1899 ///
1900 /// Also see [`RangeMapBlaze::iter`] and [`RangeMapBlaze::range_values`].
1901 ///
1902 /// # Examples
1903 ///
1904 /// ```
1905 /// extern crate alloc;
1906 /// use alloc::rc::Rc;
1907 /// use range_set_blaze::RangeMapBlaze;
1908 ///
1909 /// let map = RangeMapBlaze::from_iter([(10..=20, "a"), (15..=25, "b"), (30..=40, "c")]);
1910 /// let mut range_values = map.into_range_values();
1911 /// assert_eq!(range_values.next(), Some((10..=20, Rc::new("a"))));
1912 /// assert_eq!(range_values.next(), Some((21..=25, Rc::new("b"))));
1913 /// assert_eq!(range_values.next(), Some((30..=40, Rc::new("c"))));
1914 /// assert_eq!(range_values.next(), None);
1915 /// ```
1916 ///
1917 /// Values returned by the iterator are returned in ascending order
1918 /// with left-to-right precedence.
1919 ///
1920 /// ```
1921 /// # extern crate alloc;
1922 /// use alloc::rc::Rc;
1923 /// use range_set_blaze::RangeMapBlaze;
1924 ///
1925 /// let map = RangeMapBlaze::from_iter([(30..=40, "c"), (15..=25, "b"), (10..=20, "a")]);
1926 /// let mut range_values = map.into_range_values();
1927 /// assert_eq!(range_values.next(), Some((10..=14, Rc::new("a"))));
1928 /// assert_eq!(range_values.next(), Some((15..=25, Rc::new("b"))));
1929 /// assert_eq!(range_values.next(), Some((30..=40, Rc::new("c"))));
1930 /// assert_eq!(range_values.next(), None);
1931 /// ```
1932 pub fn into_range_values(self) -> IntoRangeValuesIter<T, V> {
1933 IntoRangeValuesIter::new(self.btree_map)
1934 }
1935
1936 /// An iterator that visits the ranges in the [`RangeMapBlaze`],
1937 /// i.e., the integers as sorted & disjoint ranges.
1938 ///
1939 /// Also see [`RangeMapBlaze::iter`] and [`RangeMapBlaze::into_range_values`].
1940 ///
1941 /// # Examples
1942 ///
1943 /// ```
1944 /// use range_set_blaze::RangeMapBlaze;
1945 ///
1946 /// let map = RangeMapBlaze::from_iter([(10..=20, "a"), (15..=25, "b"), (30..=40, "c")]);
1947 /// let mut ranges = map.ranges();
1948 /// assert_eq!(ranges.next(), Some(10..=25));
1949 /// assert_eq!(ranges.next(), Some(30..=40));
1950 /// assert_eq!(ranges.next(), None);
1951 /// ```
1952 ///
1953 /// Values returned by the iterator are returned in ascending order
1954 /// with left-to-right precedence.
1955 ///
1956 /// ```
1957 /// use range_set_blaze::RangeMapBlaze;
1958 ///
1959 /// let map = RangeMapBlaze::from_iter([(30..=40, "c"), (15..=25, "b"), (10..=20, "a")]);
1960 /// let mut ranges = map.ranges();
1961 /// assert_eq!(ranges.next(), Some(10..=25));
1962 /// assert_eq!(ranges.next(), Some(30..=40));
1963 /// assert_eq!(ranges.next(), None);
1964 /// ```
1965 pub fn ranges(&self) -> MapRangesIter<'_, T, V> {
1966 MapRangesIter::new(self.btree_map.iter())
1967 }
1968
1969 /// An iterator that visits the ranges in the [`RangeMapBlaze`],
1970 /// i.e., the integers as sorted & disjoint ranges.
1971 ///
1972 /// Also see [`RangeMapBlaze::iter`] and [`RangeMapBlaze::into_range_values`].
1973 ///
1974 /// # Examples
1975 ///
1976 /// ```
1977 /// use range_set_blaze::RangeMapBlaze;
1978 ///
1979 /// let map = RangeMapBlaze::from_iter([(10..=20, "a"), (15..=25, "b"), (30..=40, "c")]);
1980 /// let mut ranges = map.into_ranges();
1981 /// assert_eq!(ranges.next(), Some(10..=25));
1982 /// assert_eq!(ranges.next(), Some(30..=40));
1983 /// assert_eq!(ranges.next(), None);
1984 /// ```
1985 ///
1986 /// Values returned by the iterator are returned in ascending order
1987 /// with left-to-right precedence.
1988 ///
1989 /// ```
1990 /// use range_set_blaze::RangeMapBlaze;
1991 ///
1992 /// let map = RangeMapBlaze::from_iter([(30..=40, "c"), (15..=25, "b"), (10..=20, "a")]);
1993 /// let mut ranges = map.into_ranges();
1994 /// assert_eq!(ranges.next(), Some(10..=25));
1995 /// assert_eq!(ranges.next(), Some(30..=40));
1996 /// assert_eq!(ranges.next(), None);
1997 /// ```
1998 pub fn into_ranges(self) -> MapIntoRangesIter<T, V> {
1999 MapIntoRangesIter::new(self.btree_map.into_iter())
2000 }
2001
2002 /// Returns the number of sorted & disjoint ranges in the set.
2003 ///
2004 /// # Example
2005 ///
2006 /// ```
2007 /// use range_set_blaze::RangeMapBlaze;
2008 ///
2009 /// // We put in three ranges, but they are not sorted & disjoint.
2010 /// let map = RangeMapBlaze::from_iter([(10..=20,"a"), (15..=25,"a"), (30..=40,"b")]);
2011 /// // After RangeMapBlaze sorts & 'disjoint's them, we see two ranges.
2012 /// assert_eq!(map.ranges_len(), 2);
2013 /// assert_eq!(map.to_string(), r#"(10..=25, "a"), (30..=40, "b")"#);
2014 /// ```
2015 #[must_use]
2016 pub fn ranges_len(&self) -> usize {
2017 self.btree_map.len()
2018 }
2019
2020 /// ```
2021 /// use range_set_blaze::RangeMapBlaze;
2022 ///
2023 /// let map = RangeMapBlaze::from_iter([(10u16..=20, "a"), (15..=25, "b"), (30..=40, "c")]);
2024 /// let complement = map.complement_with(&"z");
2025 /// assert_eq!(complement.to_string(), r#"(0..=9, "z"), (26..=29, "z"), (41..=65535, "z")"#);
2026 /// ```
2027 #[must_use]
2028 pub fn complement_with(&self, value: &V) -> Self {
2029 self.ranges()
2030 .complement()
2031 .map(|r| (r, value.clone()))
2032 .collect()
2033 }
2034
2035 // FUTURE BTreeSet some of these as 'const' but it uses unstable. When stable, add them here and elsewhere.
2036
2037 /// Returns the number of sorted & disjoint ranges in the set.
2038 ///
2039 /// # Example
2040 ///
2041 /// ```
2042 /// use range_set_blaze::RangeMapBlaze;
2043 ///
2044 /// // We put in four ranges, but they are not sorted & disjoint.
2045 /// let map = RangeMapBlaze::from_iter([(10..=20, "a"), (15..=25, "b"), (30..=40, "c"), (28..=35, "c")]);
2046 /// // After RangeMapBlaze sorts & 'disjoint's them, we see three ranges.
2047 /// assert_eq!(map.range_values_len(), 3);
2048 /// assert_eq!(map.to_string(), r#"(10..=20, "a"), (21..=25, "b"), (28..=40, "c")"#);
2049 /// ```
2050 #[must_use]
2051 pub fn range_values_len(&self) -> usize {
2052 self.btree_map.len()
2053 }
2054
2055 /// Retains only the elements specified by the predicate.
2056 ///
2057 /// In other words, remove all pairs `(k, v)` for which `f(&k, &mut v)` returns `false`.
2058 /// The elements are visited in ascending key order.
2059 ///
2060 /// Because if visits every element in every range, it is expensive compared to
2061 /// [`RangeMapBlaze::ranges_retain`].
2062 ///
2063 /// # Examples
2064 ///
2065 /// ```
2066 /// use range_set_blaze::RangeMapBlaze;
2067 ///
2068 /// let mut map: RangeMapBlaze<i32, i32> = (0..8).map(|x| (x, x*10)).collect();
2069 /// // Keep only the elements with even-numbered keys.
2070 /// map.retain(|&k, _| k % 2 == 0);
2071 /// assert!(map.into_iter().eq(vec![(0, 0), (2, 20), (4, 40), (6, 60)]));
2072 /// ```
2073 pub fn retain<F>(&mut self, f: F)
2074 where
2075 F: Fn(&T, &V) -> bool,
2076 {
2077 *self = self.iter().filter(|(k, v)| f(k, v)).collect();
2078 }
2079
2080 /// Retains only the `(range, value)` pairs specified by the predicate.
2081 ///
2082 /// In other words, removes all `(range, value)` pairs for which `f(&range, &value)`
2083 /// returns `false`. The `(range, value)` pairs are visited in ascending range order.
2084 ///
2085 /// # Examples
2086 ///
2087 /// ```
2088 /// use range_set_blaze::RangeMapBlaze;
2089 ///
2090 /// let mut map: RangeMapBlaze<i32, &str> = RangeMapBlaze::from_iter([(0..=3, "low"), (4..=7, "high")]);
2091 /// // Keep only the ranges with a specific value.
2092 /// map.ranges_retain(|range, &value| value == "low");
2093 /// assert_eq!(map, RangeMapBlaze::from_iter([(0..=3, "low")]));
2094 /// ```
2095 pub fn ranges_retain<F>(&mut self, mut f: F)
2096 where
2097 F: FnMut(&RangeInclusive<T>, &V) -> bool,
2098 {
2099 self.btree_map.retain(|start, end_value| {
2100 let range = *start..=end_value.end;
2101 if f(&range, &end_value.value) {
2102 true
2103 } else {
2104 self.len -= T::safe_len(&range);
2105 false
2106 }
2107 });
2108 }
2109}
2110
2111impl<T, V> IntoIterator for RangeMapBlaze<T, V>
2112where
2113 T: Integer,
2114 V: Eq + Clone,
2115{
2116 type Item = (T, V);
2117 type IntoIter = IntoIterMap<T, V>;
2118
2119 /// Gets an iterator for moving out the [`RangeSetBlaze`]'s integer contents.
2120 /// Double-ended.
2121 ///
2122 /// # Examples
2123 ///
2124 /// ```
2125 /// use range_set_blaze::RangeSetBlaze;
2126 ///
2127 /// let set = RangeSetBlaze::from_iter([1, 2, 3, 4]);
2128 ///
2129 /// let v: Vec<_> = set.into_iter().collect();
2130 /// assert_eq!(v, [1, 2, 3, 4]);
2131 ///
2132 /// let set = RangeSetBlaze::from_iter([1, 2, 3, 4]);
2133 /// let v: Vec<_> = set.into_iter().rev().collect();
2134 /// assert_eq!(v, [4, 3, 2, 1]);
2135 /// ```
2136 fn into_iter(self) -> IntoIterMap<T, V> {
2137 IntoIterMap::new(self.btree_map.into_iter())
2138 }
2139}
2140
2141// Implementing `IntoIterator` for `&RangeMapBlaze<T, V>` because BTreeMap does.
2142impl<'a, T: Integer, V: Eq + Clone> IntoIterator for &'a RangeMapBlaze<T, V> {
2143 type IntoIter = IterMap<T, &'a V, RangeValuesIter<'a, T, V>>;
2144 type Item = (T, &'a V);
2145
2146 fn into_iter(self) -> Self::IntoIter {
2147 self.iter()
2148 }
2149}
2150
2151impl<T: Integer, V: Eq + Clone> BitOr<Self> for RangeMapBlaze<T, V> {
2152 /// Unions the contents of two [`RangeMapBlaze`]'s.
2153 ///
2154 /// This operator has *left precedence*: when overlapping ranges are present,
2155 /// values in `self` take priority over those in the right-hand side.
2156 ///
2157 /// This method is optimized for three usage scenarios:
2158 /// when the left-hand side is much smaller, when the right-hand side is much smaller,
2159 /// and when both sides are of similar size.
2160 ///
2161 /// **Also See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
2162 ///
2163 /// # Examples
2164 /// ```
2165 /// use range_set_blaze::RangeMapBlaze;
2166 /// let a = RangeMapBlaze::from_iter([(1..=2, "a"), (5..=100, "a")]);
2167 /// let b = RangeMapBlaze::from_iter([(2..=6, "b")]);
2168 /// let union = a | b; // Alternatively, '&a | &b', etc.
2169 /// assert_eq!(union, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=100, "a")]));
2170 /// ```
2171 type Output = Self;
2172 fn bitor(self, mut other: Self) -> Self {
2173 let b_len = other.ranges_len();
2174 if b_len == 0 {
2175 return self;
2176 }
2177 let a_len = self.ranges_len();
2178 if a_len == 0 {
2179 return other;
2180 }
2181 if choose_insert(b_len, a_len) {
2182 // 'a' is small, insert its elements into 'other'
2183 for (start, end_value) in self.btree_map {
2184 other.internal_add(start..=end_value.end, end_value.value);
2185 }
2186 return other;
2187 }
2188 if choose_insert(a_len, b_len) {
2189 // 'b' is small, calculate elements in 'other' not in 'self' and add them to 'self'.
2190 let mut result = self; // Take ownership of self
2191 let difference = other - &result; // Calculate elements in 'other' not in 'result'
2192 result.extend_simple(
2193 difference
2194 .btree_map
2195 .into_iter()
2196 .map(|(start, v)| (start..=v.end, v.value)),
2197 );
2198 return result;
2199 }
2200 // Sizes are comparable, use the iterator union
2201 (self.range_values() | other.range_values()).into_range_map_blaze()
2202 }
2203}
2204
2205impl<T: Integer, V: Eq + Clone> BitOr<&Self> for RangeMapBlaze<T, V> {
2206 /// Unions the contents of two [`RangeMapBlaze`]'s.
2207 ///
2208 /// This operator has *left precedence*: when overlapping ranges are present,
2209 /// values in `self` take priority over those in the right-hand side.
2210 ///
2211 /// This method is optimized for three usage scenarios:
2212 /// when the left-hand side is much smaller, when the right-hand side is much smaller,
2213 /// and when both sides are of similar size.
2214 ///
2215 /// **Also See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
2216 ///
2217 /// # Examples
2218 /// ```
2219 /// use range_set_blaze::RangeMapBlaze;
2220 /// let a = RangeMapBlaze::from_iter([(1..=2, "a"), (5..=100, "a")]);
2221 /// let b = RangeMapBlaze::from_iter([(2..=6, "b")]);
2222 /// let union = a | &b; // Alternatively, 'a | b', etc.
2223 /// assert_eq!(union, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=100, "a")]));
2224 /// ```
2225 type Output = Self;
2226 fn bitor(mut self, other: &Self) -> Self {
2227 let b_len = other.ranges_len();
2228 if b_len == 0 {
2229 return self;
2230 }
2231 let a_len = self.ranges_len();
2232 if a_len == 0 {
2233 return other.clone();
2234 }
2235 // Check if 'a' is small compared to 'b'
2236 if choose_insert(b_len, a_len) {
2237 // 'a' is small, clone 'other' and insert 'a' into it
2238 let mut result = other.clone();
2239 for (start, end_value) in self.btree_map {
2240 result.internal_add(start..=end_value.end, end_value.value);
2241 }
2242 return result;
2243 }
2244 if choose_insert(a_len, b_len) {
2245 // 'b' is small, calculate elements in 'other' not in 'self' and add them to 'self'.
2246 let difference = other - &self; // Calculate elements in 'other' not in 'self'
2247 self.extend_simple(
2248 difference
2249 .btree_map
2250 .into_iter()
2251 .map(|(start, v)| (start..=v.end, v.value)),
2252 );
2253 return self;
2254 }
2255 // Sizes are comparable, use the iterator union
2256 (self.range_values() | other.range_values()).into_range_map_blaze()
2257 }
2258}
2259
2260impl<T: Integer, V: Eq + Clone> BitOr<RangeMapBlaze<T, V>> for &RangeMapBlaze<T, V> {
2261 type Output = RangeMapBlaze<T, V>;
2262 /// Unions the contents of two [`RangeMapBlaze`]'s.
2263 ///
2264 /// This operator has *left precedence*: when overlapping ranges are present,
2265 /// values in `self` take priority over those in the right-hand side.
2266 ///
2267 /// This method is optimized for three usage scenarios:
2268 /// when the left-hand side is much smaller, when the right-hand side is much smaller,
2269 /// and when both sides are of similar size.
2270 ///
2271 /// **Also See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
2272 ///
2273 /// # Examples
2274 /// ```
2275 /// use range_set_blaze::RangeMapBlaze;
2276 /// let a = RangeMapBlaze::from_iter([(1..=2, "a"), (5..=100, "a")]);
2277 /// let b = RangeMapBlaze::from_iter([(2..=6, "b")]);
2278 /// let union = &a | b; // Alternatively, 'a | b', etc.
2279 /// assert_eq!(union, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=100, "a")]));
2280 /// ```
2281 fn bitor(self, mut other: RangeMapBlaze<T, V>) -> RangeMapBlaze<T, V> {
2282 let a_len = self.ranges_len();
2283 if a_len == 0 {
2284 return other;
2285 }
2286 let b_len = other.ranges_len();
2287 if b_len == 0 {
2288 return self.clone();
2289 }
2290 // Check if 'a' is small compared to 'b'
2291 if choose_insert(b_len, a_len) {
2292 // 'a' is small, insert its elements into 'other'
2293 for (start, end_value) in &self.btree_map {
2294 other.internal_add(*start..=end_value.end, end_value.value.clone());
2295 }
2296 return other;
2297 }
2298 // Check if 'b' is small compared to 'a'
2299 if choose_insert(a_len, b_len) {
2300 // 'b' is small, clone 'self', calculate elements in 'other' not in 'self', and add them.
2301 let mut result = self.clone();
2302 let difference = other - self; // Calculate elements in 'other' not in 'self'
2303 result.extend_simple(
2304 difference
2305 .btree_map
2306 .into_iter()
2307 .map(|(start, v)| (start..=v.end, v.value)),
2308 );
2309 return result;
2310 }
2311 // Sizes are comparable, use the iterator union
2312 (self.range_values() | other.range_values()).into_range_map_blaze()
2313 }
2314}
2315
2316impl<T: Integer, V: Eq + Clone> BitOr<&RangeMapBlaze<T, V>> for &RangeMapBlaze<T, V> {
2317 type Output = RangeMapBlaze<T, V>;
2318 /// Unions the contents of two [`RangeMapBlaze`]'s.
2319 ///
2320 /// This operator has *left precedence*: when overlapping ranges are present,
2321 /// values in `self` take priority over those in the right-hand side.
2322 ///
2323 /// This method is optimized for three usage scenarios:
2324 /// when the left-hand side is much smaller, when the right-hand side is much smaller,
2325 /// and when both sides are of similar size.
2326 ///
2327 /// **Also See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
2328 ///
2329 /// # Examples
2330 /// ```
2331 /// use range_set_blaze::RangeMapBlaze;
2332 /// let a = RangeMapBlaze::from_iter([(1..=2, "a"), (5..=100, "a")]);
2333 /// let b = RangeMapBlaze::from_iter([(2..=6, "b")]);
2334 /// let union = &a | &b; // Alternatively, 'a | b', etc.
2335 /// assert_eq!(union, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=100, "a")]));
2336 /// ```
2337 fn bitor(self, other: &RangeMapBlaze<T, V>) -> RangeMapBlaze<T, V> {
2338 let a_len = self.ranges_len();
2339 if a_len == 0 {
2340 return other.clone();
2341 }
2342 let b_len = other.ranges_len();
2343 if b_len == 0 {
2344 return self.clone();
2345 }
2346 if choose_insert(b_len, a_len) {
2347 // 'a' is small, clone 'other' and insert 'a' into it
2348 let mut result = other.clone();
2349 for (start, end_value) in &self.btree_map {
2350 result.internal_add(*start..=end_value.end, end_value.value.clone());
2351 }
2352 return result;
2353 }
2354 // Check if 'b' is small compared to 'a'
2355 if choose_insert(a_len, b_len) {
2356 // 'b' is small, clone 'self', calculate elements in 'other' not in 'self', and add them.
2357 let mut result = self.clone();
2358 let difference = other - self; // Calculate elements in 'other' not in 'self'
2359 result.extend_simple(
2360 difference
2361 .btree_map
2362 .into_iter()
2363 .map(|(start, v)| (start..=v.end, v.value)),
2364 );
2365 return result;
2366 }
2367 // Sizes are comparable, use the iterator union
2368 (self.range_values() | other.range_values()).into_range_map_blaze()
2369 }
2370}
2371
2372gen_ops_ex!(
2373 <T, V>;
2374 types ref RangeMapBlaze<T,V>, ref RangeMapBlaze<T,V> => RangeMapBlaze<T,V>;
2375
2376 /// Intersects the contents of two [`RangeMapBlaze`]'s.
2377 ///
2378 /// Either, neither, or both inputs may be borrowed.
2379 ///
2380 /// # Examples
2381 /// ```
2382 /// use range_set_blaze::prelude::*;
2383 ///
2384 /// let a = RangeMapBlaze::from_iter([(1..=2, "a"), (5..=100, "a")]);
2385 /// let b = RangeMapBlaze::from_iter([(2..=6, "b")]);
2386 /// let result = &a & &b; // Alternatively, 'a & b'.
2387 /// assert_eq!(result.to_string(), r#"(2..=2, "a"), (5..=6, "a")"#);
2388 /// ```
2389 for & call |a: &RangeMapBlaze<T, V>, b: &RangeMapBlaze<T, V>| {
2390 a.range_values().map_and_set_intersection(b.ranges()).into_range_map_blaze()
2391 };
2392/// Symmetric difference the contents of two [`RangeMapBlaze`]'s.
2393///
2394/// Either, neither, or both inputs may be borrowed.
2395///
2396/// # Examples
2397/// ```
2398/// use range_set_blaze::prelude::*;
2399///
2400/// let a = RangeMapBlaze::from_iter([(1..=2, "a"), (5..=100, "a")]);
2401/// let b = RangeMapBlaze::from_iter([(2..=6, "b")]);
2402/// let result = &a ^ &b; // Alternatively, 'a ^ b'.
2403/// assert_eq!(result.to_string(), r#"(1..=1, "a"), (3..=4, "b"), (7..=100, "a")"#);
2404/// ```
2405for ^ call |a: &RangeMapBlaze<T, V>, b: &RangeMapBlaze<T, V>| {
2406 SymDiffIterMap::new2(a.range_values(), b.range_values()).into_range_map_blaze()
2407};
2408/// Difference the contents of two [`RangeSetBlaze`]'s.
2409///
2410/// Either, neither, or both inputs may be borrowed.
2411///
2412/// # Examples
2413/// ```
2414/// use range_set_blaze::prelude::*;
2415///
2416/// let a = RangeMapBlaze::from_iter([(1..=2, "a"), (5..=100, "a")]);
2417/// let b = RangeMapBlaze::from_iter([(2..=6, "b")]);
2418/// let result = &a - &b; // Alternatively, 'a - b'.
2419/// assert_eq!(result.to_string(), r#"(1..=1, "a"), (7..=100, "a")"#);
2420/// ```
2421
2422for - call |a: &RangeMapBlaze<T, V>, b: &RangeMapBlaze<T, V>| {
2423 a.range_values().map_and_set_difference(b.ranges()).into_range_map_blaze()
2424};
2425where T: Integer, V: Eq + Clone
2426);
2427
2428gen_ops_ex!(
2429 <T, V>;
2430 types ref RangeMapBlaze<T,V>, ref RangeSetBlaze<T> => RangeMapBlaze<T,V>;
2431
2432
2433/// Find the difference between a [`RangeMapBlaze`] and a [`RangeSetBlaze`]. The result is a new [`RangeMapBlaze`].
2434///
2435/// Either, neither, or both inputs may be borrowed.
2436///
2437/// # Examples
2438/// ```
2439/// use range_set_blaze::prelude::*;
2440///
2441/// let a = RangeMapBlaze::from_iter([(1..=100, "a")]);
2442/// let b = RangeSetBlaze::from_iter([2..=6]);
2443/// let result = &a - &b; // Alternatively, 'a - b'.
2444/// assert_eq!(result.to_string(), r#"(1..=1, "a"), (7..=100, "a")"#);
2445/// ```
2446for - call |a: &RangeMapBlaze<T, V>, b: &RangeSetBlaze<T>| {
2447 a.range_values().map_and_set_difference(b.ranges()).into_range_map_blaze()
2448};
2449
2450/// Find the intersection between a [`RangeMapBlaze`] and a [`RangeSetBlaze`]. The result is a new [`RangeMapBlaze`].
2451///
2452/// Either, neither, or both inputs may be borrowed.
2453///
2454/// # Examples
2455/// ```
2456/// use range_set_blaze::prelude::*;
2457///
2458/// let a = RangeMapBlaze::from_iter([(1..=100, "a")]);
2459/// let b = RangeSetBlaze::from_iter([2..=6]);
2460/// let result = &a & &b; // Alternatively, 'a & b'.
2461/// assert_eq!(result.to_string(), r#"(2..=6, "a")"#);
2462/// ```
2463for & call |a: &RangeMapBlaze<T, V>, b: &RangeSetBlaze<T>| {
2464 a.range_values().map_and_set_intersection(b.ranges()).into_range_map_blaze()
2465};
2466
2467where T: Integer, V: Eq + Clone
2468);
2469
2470gen_ops_ex!(
2471 <T, V>;
2472 types ref RangeMapBlaze<T,V> => RangeSetBlaze<T>;
2473
2474
2475/// Takes the complement of a `RangeMapBlaze`. The result is a new `RangeSetBlaze`.
2476///
2477/// # Examples
2478/// ```
2479/// use range_set_blaze::RangeMapBlaze;
2480///
2481/// let map = RangeMapBlaze::from_iter([(10u8..=20, "a"), (15..=25, "b"), (30..=40, "c")]);
2482/// let complement = !↦ // Alternatively, '!map'.
2483/// assert_eq!(complement.to_string(), "0..=9, 26..=29, 41..=255");
2484/// ```
2485for ! call |a: &RangeMapBlaze<T, V>| {
2486 a.ranges().complement().into_range_set_blaze()
2487};
2488where T: Integer, V: Eq + Clone
2489);
2490
2491impl<T, V> Extend<(T, V)> for RangeMapBlaze<T, V>
2492where
2493 T: Integer,
2494 V: Eq + Clone,
2495{
2496 /// Extends the [`RangeMapBlaze`] with the contents of an iterator of integer-value pairs.
2497 ///
2498 /// This method has *right-to-left precedence*: later values in the iterator take priority
2499 /// over earlier ones, matching the behavior of standard `BTreeMap::extend`.
2500 ///
2501 /// Each integer is treated as a singleton range. Adjacent integers with the same value
2502 /// are merged before insertion. For alternatives that skip merging or accept full ranges,
2503 /// see [`RangeMapBlaze::extend_simple`] and [`RangeMapBlaze::extend`].
2504 ///
2505 /// **See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
2506 ///
2507 /// # Examples
2508 /// ```
2509 /// use range_set_blaze::RangeMapBlaze;
2510 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
2511 /// a.extend([(3, "b"), (4, "e"), (5, "f"), (5, "g")]);
2512 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=3, "b"), (4..=4, "e"), (5..=5, "g")]));
2513 ///
2514 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
2515 /// let mut b = RangeMapBlaze::from_iter([(3, "b"), (4, "e"), (5, "f"), (5, "g")]);
2516 /// a |= b;
2517 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=4, "a"), (5..=5, "f")]));
2518 /// ```
2519 #[inline]
2520 fn extend<I>(&mut self, iter: I)
2521 where
2522 I: IntoIterator<Item = (T, V)>,
2523 {
2524 let iter = iter.into_iter();
2525
2526 // We gather adjacent values into ranges via UnsortedPriorityMap, but ignore the priority.
2527 for priority in UnsortedPriorityMap::new(iter.map(|(r, v)| (r..=r, Rc::new(v)))) {
2528 let (range, value) = priority.into_range_value();
2529 let value: V = Rc::try_unwrap(value).unwrap_or_else(|_| unreachable!());
2530 self.internal_add(range, value);
2531 }
2532 }
2533}
2534
2535impl<T, V> Extend<(RangeInclusive<T>, V)> for RangeMapBlaze<T, V>
2536where
2537 T: Integer,
2538 V: Eq + Clone,
2539{
2540 /// Extends the [`RangeMapBlaze`] with the contents of an iterator of range-value pairs.
2541 ///
2542 /// This method has *right-to-left precedence* — like `BTreeMap`, but unlike most other
2543 /// `RangeMapBlaze` methods.
2544 ///
2545 /// It first merges any adjacent or overlapping ranges with the same value, then adds them one by one.
2546 /// For alternatives that skip merging or that accept integer-value pairs, see
2547 /// [`RangeMapBlaze::extend_simple`] and the `(integer, value)` overload.
2548 ///
2549 /// For *left-to-right* precedence, use the union-related methods.
2550 ///
2551 /// **See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
2552 /// # Examples
2553 /// ```
2554 /// use range_set_blaze::RangeMapBlaze;
2555 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
2556 /// a.extend([(3..=5, "b"), (5..=5, "c")]);
2557 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=5, "c")]));
2558 ///
2559 /// // `extend_simple` is a more efficient for the case where the ranges a likely disjoint.
2560 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
2561 /// a.extend_simple([(3..=5, "b"), (5..=5, "c")]);
2562 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=2, "a"), (3..=4, "b"), (5..=5, "c")]));
2563 ///
2564 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
2565 /// let mut b = RangeMapBlaze::from_iter([(3..=5, "b"), (5..=5, "c")]);
2566 /// a |= b;
2567 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=4, "a"), (5..=5, "b")]));
2568 /// ```
2569 #[inline]
2570 fn extend<I>(&mut self, iter: I)
2571 where
2572 I: IntoIterator<Item = (RangeInclusive<T>, V)>,
2573 {
2574 let iter = iter.into_iter();
2575
2576 // We gather adjacent values into ranges via UnsortedPriorityMap, but ignore the priority.
2577 for priority in UnsortedPriorityMap::new(iter.map(|(r, v)| (r, Rc::new(v)))) {
2578 let (range, value) = priority.into_range_value();
2579 let value = Rc::try_unwrap(value).unwrap_or_else(|_| unreachable!());
2580 self.internal_add(range, value);
2581 }
2582 }
2583}
2584
2585impl<T, V, const N: usize> From<[(T, V); N]> for RangeMapBlaze<T, V>
2586where
2587 T: Integer,
2588 V: Eq + Clone,
2589{
2590 /// For compatibility with [`BTreeMap`] you may create a [`RangeSetBlaze`] from an array of integers.
2591 ///
2592 /// *For more about constructors and performance, see [`RangeSetBlaze` Constructors](struct.RangeSetBlaze.html#rangesetblaze-constructors).*
2593 ///
2594 /// [`BTreeMap`]: alloc::collections::BTreeMap
2595 ///
2596 /// # Examples
2597 ///
2598 /// ```
2599 /// use range_set_blaze::RangeSetBlaze;
2600 ///
2601 /// let a0 = RangeSetBlaze::from([3, 2, 1, 100, 1]);
2602 /// let a1: RangeSetBlaze<i32> = [3, 2, 1, 100, 1].into();
2603 /// assert!(a0 == a1 && a0.to_string() == "1..=3, 100..=100")
2604 /// ```
2605 fn from(arr: [(T, V); N]) -> Self {
2606 arr.into_iter().collect()
2607 }
2608}
2609
2610// implement Index trait
2611impl<T: Integer, V: Eq + Clone> Index<T> for RangeMapBlaze<T, V> {
2612 type Output = V;
2613
2614 /// Returns a reference to the value corresponding to the supplied key.
2615 ///
2616 /// # Panics
2617 ///
2618 /// Panics if the key is not present in the `BTreeMap`.
2619 #[inline]
2620 #[allow(clippy::manual_assert)] // We use "if...panic!" for coverage auditing.
2621 fn index(&self, index: T) -> &Self::Output {
2622 self.get(index).unwrap_or_else(|| {
2623 panic!("no entry found for key");
2624 })
2625 }
2626}
2627
2628// LATER define value_per_range and into_value_per_range
2629
2630impl<T, V> PartialOrd for RangeMapBlaze<T, V>
2631where
2632 T: Integer,
2633 V: Eq + Clone + Ord,
2634{
2635 /// We define a partial ordering on `RangeMapBlaze`. Following the convention of
2636 /// [`BTreeMap`], the ordering is lexicographic, *not* by subset/superset.
2637 ///
2638 /// [`BTreeMap`]: alloc::collections::BTreeMap
2639 ///
2640 /// # Examples
2641 /// ```
2642 /// use range_set_blaze::prelude::*;
2643 ///
2644 /// let a = RangeMapBlaze::from_iter([(1..=3, "a"), (5..=100, "a")]);
2645 /// let b = RangeMapBlaze::from_iter([(2..=2, "b")] );
2646 /// assert!(a < b); // Lexicographic comparison
2647 /// // More lexicographic comparisons
2648 /// assert!(a <= b);
2649 /// assert!(b > a);
2650 /// assert!(b >= a);
2651 /// assert!(a != b);
2652 /// assert!(a == a);
2653 /// use core::cmp::Ordering;
2654 /// assert_eq!(a.cmp(&b), Ordering::Less);
2655 ///
2656 /// // Floats aren't comparable, but we can convert them to comparable bits.
2657 /// let a = RangeMapBlaze::from_iter([(2..=3, 1.0f32.to_bits()), (5..=100, 2.0f32.to_bits())]);
2658 /// let b = RangeMapBlaze::from_iter([(2..=2, f32::NAN.to_bits())] );
2659 /// assert_eq!(a.partial_cmp(&b), Some(Ordering::Less));
2660 /// ```
2661 #[inline]
2662 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2663 Some(self.cmp(other))
2664 }
2665}
2666
2667impl<T, V> Ord for RangeMapBlaze<T, V>
2668where
2669 T: Integer,
2670 V: Eq + Clone + Ord,
2671{
2672 /// We define an ordering on `RangeMapBlaze`. Following the convention of
2673 /// [`BTreeMap`], the ordering is lexicographic, *not* by subset/superset.
2674 ///
2675 /// [`BTreeMap`]: alloc::collections::BTreeMap
2676 ///
2677 /// # Examples
2678 /// ```
2679 /// use range_set_blaze::prelude::*;
2680 ///
2681 /// let a = RangeMapBlaze::from_iter([(1..=3, "a"), (5..=100, "a")]);
2682 /// let b = RangeMapBlaze::from_iter([(2..=2, "b")] );
2683 /// assert!(a < b); // Lexicographic comparison
2684 /// // More lexicographic comparisons
2685 /// assert!(a <= b);
2686 /// assert!(b > a);
2687 /// assert!(b >= a);
2688 /// assert!(a != b);
2689 /// assert!(a == a);
2690 /// use core::cmp::Ordering;
2691 /// assert_eq!(a.cmp(&b), Ordering::Less);
2692 ///
2693 /// // Floats aren't comparable, but we can convert them to comparable bits.
2694 /// let a = RangeMapBlaze::from_iter([(2..=3, 1.0f32.to_bits()), (5..=100, 2.0f32.to_bits())]);
2695 /// let b = RangeMapBlaze::from_iter([(2..=2, f32::NAN.to_bits())] );
2696 /// assert_eq!(a.partial_cmp(&b), Some(Ordering::Less));
2697 /// ```
2698 #[inline]
2699 fn cmp(&self, other: &Self) -> Ordering {
2700 // fast by ranges:
2701 let mut a = self.range_values();
2702 let mut b = other.range_values();
2703 let mut a_rx = a.next();
2704 let mut b_rx = b.next();
2705 loop {
2706 // compare Some/None
2707 match (a_rx, &b_rx) {
2708 (Some(_), None) => return Ordering::Greater,
2709 (None, Some(_)) => return Ordering::Less,
2710 (None, None) => return Ordering::Equal,
2711 (Some((a_r, a_v)), Some((b_r, b_v))) => {
2712 // if tie, compare starts
2713 match a_r.start().cmp(b_r.start()) {
2714 Ordering::Greater => return Ordering::Greater,
2715 Ordering::Less => return Ordering::Less,
2716 Ordering::Equal => { /* keep going */ }
2717 }
2718
2719 // if tie, compare values
2720 match a_v.cmp(b_v) {
2721 Ordering::Less => return Ordering::Less,
2722 Ordering::Greater => return Ordering::Greater,
2723 Ordering::Equal => { /* keep going */ }
2724 }
2725
2726 // if tie, compare ends
2727 match a_r.end().cmp(b_r.end()) {
2728 Ordering::Less => {
2729 a_rx = a.next();
2730 b_rx = Some(((*a_r.end()).add_one()..=*b_r.end(), b_v));
2731 }
2732 Ordering::Greater => {
2733 a_rx = Some(((*b_r.end()).add_one()..=*a_r.end(), a_v));
2734 b_rx = b.next();
2735 }
2736 Ordering::Equal => {
2737 a_rx = a.next();
2738 b_rx = b.next();
2739 }
2740 }
2741 }
2742 }
2743 }
2744 }
2745}
2746
2747impl<T: Integer, V: Eq + Clone> Eq for RangeMapBlaze<T, V> {}
2748
2749impl<T: Integer, V: Eq + Clone> BitOrAssign<&Self> for RangeMapBlaze<T, V> {
2750 /// Adds the contents of another [`RangeMapBlaze`] to this one.
2751 ///
2752 /// This operator has *left precedence*: when overlapping ranges are present,
2753 /// values in `self` take priority over those in the right-hand side.
2754 /// To get *right precedence*, swap the operands or use
2755 /// [`RangeMapBlaze::extend_with`].
2756 ///
2757 /// This method is optimized for three usage scenarios:
2758 /// when the left-hand side is much smaller, when the right-hand side is much smaller,
2759 /// and when both sides are of similar size
2760 ///
2761 /// Even greater efficiency is possible when the right-hand side is passed by value,
2762 /// allowing its internal data structures to be reused.
2763 ///
2764 /// **Also See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
2765 ///
2766 /// # Examples
2767 /// ```
2768 /// use range_set_blaze::RangeMapBlaze;
2769 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
2770 /// let mut b = RangeMapBlaze::from_iter([(3, "b"), (4, "e"), (5, "f"), (5, "g")]);
2771 /// a |= &b;
2772 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=4, "a"), (5..=5, "f")]));
2773 /// ```
2774 fn bitor_assign(&mut self, other: &Self) {
2775 let original_self = mem::take(self); // Take ownership of self
2776 *self = original_self | other; // Use the union operator to combine
2777 }
2778}
2779
2780impl<T: Integer, V: Eq + Clone> BitOrAssign<Self> for RangeMapBlaze<T, V> {
2781 /// Adds the contents of another [`RangeMapBlaze`] to this one.
2782 ///
2783 /// This operator has *left precedence*: when overlapping ranges are present,
2784 /// values in `self` take priority over those in the right-hand side.
2785 /// To get *right precedence*, swap the operands or use
2786 /// [`RangeMapBlaze::extend_with`].
2787 ///
2788 /// This method is optimized for three usage scenarios:
2789 /// when the left-hand side is much smaller, when the right-hand side is much smaller,
2790 /// and when both sides are of similar size
2791 ///
2792 /// **Also See:** [Summary of Union and Extend-like Methods](#rangemapblaze-union--and-extend-like-methods).
2793 ///
2794 /// # Examples
2795 /// ```
2796 /// use range_set_blaze::RangeMapBlaze;
2797 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
2798 /// let mut b = RangeMapBlaze::from_iter([(3, "b"), (4, "e"), (5, "f"), (5, "g")]);
2799 /// a |= &b;
2800 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=4, "a"), (5..=5, "f")]));
2801 /// ```
2802 ///
2803 /// # Examples
2804 /// ```
2805 /// use range_set_blaze::RangeMapBlaze;
2806 /// let mut a = RangeMapBlaze::from_iter([(1..=4, "a")]);
2807 /// let mut b = RangeMapBlaze::from_iter([(3, "b"), (4, "e"), (5, "f"), (5, "g")]);
2808 /// a |= b;
2809 /// assert_eq!(a, RangeMapBlaze::from_iter([(1..=4, "a"), (5..=5, "f")]));
2810 /// ```
2811 fn bitor_assign(&mut self, other: Self) {
2812 *self = mem::take(self) | other;
2813 }
2814}
2815
2816#[inline]
2817fn choose_insert(a_len: usize, b_len: usize) -> bool {
2818 let a_len_log2_plus_one: usize = a_len
2819 .checked_ilog2()
2820 .map_or(0, |log| log.try_into().expect("log2 fits usize"))
2821 + 1;
2822 b_len * a_len_log2_plus_one < STREAM_OVERHEAD * a_len + b_len
2823}