range_set_blaze/set.rs
1#![allow(unexpected_cfgs)]
2use core::cmp::max;
3use core::mem;
4use core::{
5 cmp::Ordering,
6 fmt,
7 iter::FusedIterator,
8 ops::{BitOr, BitOrAssign, Bound, RangeBounds, RangeInclusive},
9};
10use num_traits::{One, Zero};
11#[cfg(all(not(coverage), feature = "std"))]
12use std::{
13 fs::File,
14 io::{self, BufRead, BufReader},
15 path::Path,
16 str::FromStr,
17};
18
19use crate::alloc::string::ToString;
20use crate::sorted_disjoint::RangeOnce;
21use alloc::collections::{BTreeMap, btree_map};
22use alloc::string::String;
23use alloc::vec::Vec;
24use gen_ops::gen_ops_ex;
25
26use crate::ranges_iter::RangesIter;
27use crate::unsorted_disjoint::{SortedDisjointWithLenSoFar, UnsortedDisjoint};
28use crate::{Integer, prelude::*};
29use crate::{IntoRangesIter, UnionIter};
30
31// // FUTURE: use fn range to implement one-at-a-time intersection, difference, etc. and then add more inplace ops.
32
33#[cfg(all(not(coverage), feature = "std"))]
34#[allow(dead_code)]
35#[doc(hidden)]
36pub fn demo_read_ranges_from_file<P, T>(path: P) -> io::Result<RangeSetBlaze<T>>
37where
38 P: AsRef<Path>,
39 T: FromStr + Integer,
40{
41 let lines = BufReader::new(File::open(&path)?).lines();
42
43 let mut set = RangeSetBlaze::new();
44 for line in lines {
45 let line = line?;
46 let mut split = line.split('\t');
47 let start = split
48 .next()
49 .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Missing start of range"))?
50 .parse::<T>()
51 .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid start of range"))?;
52 let end = split
53 .next()
54 .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Missing end of range"))?
55 .parse::<T>()
56 .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid end of range"))?;
57 set.ranges_insert(start..=end);
58 }
59
60 Ok(set)
61}
62
63/// A set of integers stored as sorted & disjoint ranges.
64///
65/// Internally, it stores the ranges in a cache-efficient [`BTreeMap`].
66///
67/// # Table of Contents
68/// * [`RangeSetBlaze` Constructors](#rangesetblaze-constructors)
69/// * [Performance](#constructor-performance)
70/// * [Examples](struct.RangeSetBlaze.html#constructor-examples)
71/// * [`RangeSetBlaze` Set Operations](#rangesetblaze-set-operations)
72/// * [Performance](struct.RangeSetBlaze.html#set-operation-performance)
73/// * [Examples](struct.RangeSetBlaze.html#set-operation-examples)
74/// * [`RangeSetBlaze` Comparisons](#rangesetblaze-comparisons)
75/// * [Additional Examples](#additional-examples)
76///
77/// # `RangeSetBlaze` Constructors
78///
79/// You can create `RangeSetBlaze`'s from unsorted and overlapping integers (or ranges).
80/// However, if you know that your input is sorted and disjoint, you can speed up construction.
81///
82/// Here are the constructors, followed by a
83/// description of the performance, and then some examples.
84///
85/// | Methods | Input | Notes |
86/// |---------------------------------------------|------------------------------|--------------------------|
87/// | [`new`]/[`default`] | | |
88/// | [`from_iter`][1]/[`collect`][1] | integer iterator | |
89/// | [`from_iter`][2]/[`collect`][2] | ranges iterator | |
90/// | [`from_slice`][5] | slice of integers | Fast, but nightly-only |
91/// | [`from_sorted_disjoint`][3]/[`into_range_set_blaze`][3] | [`SortedDisjoint`] iterator | |
92/// | [`from`][5] /[`into`][5] | array of integers | |
93/// | [`from`][7] | `RangeInclusive<T>` | |
94///
95///
96/// [`BTreeMap`]: alloc::collections::BTreeMap
97/// [`new`]: RangeSetBlaze::new
98/// [`default`]: RangeSetBlaze::default
99/// [1]: struct.RangeSetBlaze.html#impl-FromIterator<T>-for-RangeSetBlaze<T>
100/// [2]: struct.RangeSetBlaze.html#impl-FromIterator<RangeInclusive<T>>-for-RangeSetBlaze<T>
101/// [3]: RangeSetBlaze::from_sorted_disjoint
102/// [SortedDisjoint]: crate::SortedDisjoint.html#table-of-contents
103/// [5]: RangeSetBlaze::from
104/// [6]: RangeSetBlaze::from_slice()
105/// [7]: #method.from-1
106///
107/// # Constructor Performance
108///
109/// The [`from_iter`][1]/[`collect`][1] constructors are designed to work fast on 'clumpy' data.
110/// By 'clumpy', we mean that the number of ranges needed to represent the data is
111/// small compared to the number of input integers. To understand this, consider the internals
112/// of the constructors:
113///
114/// Internally, the `from_iter`/`collect` constructors take these steps:
115/// * collect adjacent integers/ranges into disjoint ranges, O(*n₁*)
116/// * sort the disjoint ranges by their `start`, O(*n₂* ln *n₂*)
117/// * merge adjacent ranges, O(*n₂*)
118/// * create a `BTreeMap` from the now sorted & disjoint ranges, O(*n₃* ln *n₃*)
119///
120/// where *n₁* is the number of input integers/ranges, *n₂* is the number of disjoint & unsorted ranges,
121/// and *n₃* is the final number of sorted & disjoint ranges.
122///
123/// For example, an input of
124/// * `3, 2, 1, 4, 5, 6, 7, 0, 8, 8, 8, 100, 1`, becomes
125/// * `0..=8, 100..=100, 1..=1`, and then
126/// * `0..=8, 1..=1, 100..=100`, and finally
127/// * `0..=8, 100..=100`.
128///
129/// What is the effect of clumpy data?
130/// Notice that if *n₂* ≈ sqrt(*n₁*), then construction is O(*n₁*).
131/// Indeed, as long as *n₂* ≤ *n₁*/ln(*n₁*), then construction is O(*n₁*).
132/// Moreover, we'll see that set operations are O(*n₃*). Thus, if *n₃* ≈ sqrt(*n₁*) then set operations are O(sqrt(*n₁*)),
133/// a quadratic improvement an O(*n₁*) implementation that ignores the clumps.
134///
135/// The [`from_slice`][5] constructor typically provides a constant-time speed up for array-like collections of clumpy integers.
136/// On a representative benchmark, the speed up was 7×.
137/// The method works by scanning the input for blocks of consecutive integers, and then using `from_iter` on the results.
138/// Where available, it uses SIMD instructions. It is nightly only and enabled by the `from_slice` feature.
139///
140/// ## Constructor Examples
141///
142/// ```
143/// use range_set_blaze::prelude::*;
144///
145/// // Create an empty set with 'new' or 'default'.
146/// let a0 = RangeSetBlaze::<i32>::new();
147/// let a1 = RangeSetBlaze::<i32>::default();
148/// assert!(a0 == a1 && a0.is_empty());
149///
150/// // 'from_iter'/'collect': From an iterator of integers.
151/// // Duplicates and out-of-order elements are fine.
152/// let a0 = RangeSetBlaze::from_iter([3, 2, 1, 100, 1]);
153/// let a1: RangeSetBlaze<i32> = [3, 2, 1, 100, 1].into_iter().collect();
154/// assert!(a0 == a1 && a0.to_string() == "1..=3, 100..=100");
155///
156/// // 'from_iter'/'collect': From an iterator of inclusive ranges, start..=end.
157/// // Overlapping, out-of-order, and empty ranges are fine.
158/// #[allow(clippy::reversed_empty_ranges)]
159/// let a0 = RangeSetBlaze::from_iter([1..=2, 2..=2, -10..=-5, 1..=0]);
160/// #[allow(clippy::reversed_empty_ranges)]
161/// let a1: RangeSetBlaze<i32> = [1..=2, 2..=2, -10..=-5, 1..=0].into_iter().collect();
162/// assert!(a0 == a1 && a0.to_string() == "-10..=-5, 1..=2");
163///
164/// // 'from_slice': From any array-like collection of integers.
165/// // Nightly-only, but faster than 'from_iter'/'collect' on integers.
166/// #[cfg(feature = "from_slice")]
167/// let a0 = RangeSetBlaze::from_slice(vec![3, 2, 1, 100, 1]);
168/// #[cfg(feature = "from_slice")]
169/// assert!(a0.to_string() == "1..=3, 100..=100");
170///
171/// // If we know the ranges are already sorted and disjoint,
172/// // we can avoid work and use 'from_sorted_disjoint'/'into_range_set_blaze'.
173/// let a0 = RangeSetBlaze::from_sorted_disjoint(CheckSortedDisjoint::new([-10..=-5, 1..=2]));
174/// let a1: RangeSetBlaze<i32> = CheckSortedDisjoint::new([-10..=-5, 1..=2]).into_range_set_blaze();
175/// assert!(a0 == a1 && a0.to_string() == "-10..=-5, 1..=2");
176///
177/// // For compatibility with `BTreeSet`, we also support
178/// // 'from'/'into' from arrays of integers.
179/// let a0 = RangeSetBlaze::from([3, 2, 1, 100, 1]);
180/// let a1: RangeSetBlaze<i32> = [3, 2, 1, 100, 1].into();
181/// assert!(a0 == a1 && a0.to_string() == "1..=3, 100..=100");
182/// ```
183///
184/// # `RangeSetBlaze` Set Operations
185///
186/// You can perform set operations on `RangeSetBlaze`s using operators.
187///
188/// | Set Operation | Operator | Multiway Method |
189/// |-------------------|-------------------------|-------------------------|
190/// | union | [`a` | `b`] | <code>[a, b, c].[union]()</code>`()` |
191/// | intersection | [`a & b`] | <code>[a, b, c].[intersection]()</code>`()` |
192/// | difference | [`a - b`] | *n/a* |
193/// | symmetric difference| [`a ^ b`] | <code>[a, b, c].[symmetric_difference]()</code>`()` |
194/// | complement | [`!a`] | *n/a* |
195///
196/// `RangeSetBlaze` also implements many other methods, such as [`insert`], [`pop_first`] and [`split_off`]. Many of
197/// these methods match those of `BTreeSet`.
198///
199/// [`a` | `b`]: struct.RangeSetBlaze.html#impl-BitOr-for-RangeSetBlaze<T>
200/// [`a & b`]: struct.RangeSetBlaze.html#impl-BitAnd-for-RangeSetBlaze<T>
201/// [`a - b`]: struct.RangeSetBlaze.html#impl-Sub-for-RangeSetBlaze<T>
202/// [`a ^ b`]: struct.RangeSetBlaze.html#impl-BitXor-for-RangeSetBlaze<T>
203/// [`!a`]: struct.RangeSetBlaze.html#method.not
204/// [`union`]: trait.MultiwayRangeSetBlazeRef.html#method.union
205/// [`intersection`]: trait.MultiwayRangeSetBlazeRef.html#method.intersection
206/// [`symmetric_difference`]: trait.MultiwayRangeSetBlazeRef.html#method.symmetric_difference
207/// [`insert`]: RangeSetBlaze::insert
208/// [`pop_first`]: RangeSetBlaze::pop_first
209/// [`split_off`]: RangeSetBlaze::split_off
210/// [SortedDisjoint]: crate::SortedDisjoint.html#table-of-contents
211///
212///
213/// ## Set Operation Performance
214///
215/// Every operation is implemented as
216/// 1. a single pass over the sorted & disjoint ranges
217/// 2. the construction of a new `RangeSetBlaze`
218///
219/// Thus, applying multiple operators creates intermediate
220/// `RangeSetBlaze`'s. If you wish, you can avoid these intermediate
221/// `RangeSetBlaze`'s by switching to the [`SortedDisjoint`] API. The last example below
222/// demonstrates this.
223///
224/// ## Set Operation Examples
225///
226/// ```
227/// use range_set_blaze::prelude::*;
228///
229/// let a = RangeSetBlaze::from_iter([1..=2, 5..=100]);
230/// let b = RangeSetBlaze::from_iter([2..=6]);
231///
232/// // Union of two 'RangeSetBlaze's.
233/// let result = &a | &b;
234/// // Alternatively, we can take ownership via 'a | b'.
235/// assert_eq!(result.to_string(), "1..=100");
236///
237/// // Intersection of two 'RangeSetBlaze's.
238/// let result = &a & &b; // Alternatively, 'a & b'.
239/// assert_eq!(result.to_string(), "2..=2, 5..=6");
240///
241/// // Set difference of two 'RangeSetBlaze's.
242/// let result = &a - &b; // Alternatively, 'a - b'.
243/// assert_eq!(result.to_string(), "1..=1, 7..=100");
244///
245/// // Symmetric difference of two 'RangeSetBlaze's.
246/// let result = &a ^ &b; // Alternatively, 'a ^ b'.
247/// assert_eq!(result.to_string(), "1..=1, 3..=4, 7..=100");
248///
249/// // complement of a 'RangeSetBlaze'.
250/// let result = !&a; // Alternatively, '!a'.
251/// assert_eq!(
252/// result.to_string(),
253/// "-2147483648..=0, 3..=4, 101..=2147483647"
254/// );
255///
256/// // Multiway union of 'RangeSetBlaze's.
257/// let c = RangeSetBlaze::from_iter([2..=2, 6..=200]);
258/// let result = [&a, &b, &c].union();
259/// assert_eq!(result.to_string(), "1..=200");
260///
261/// // Multiway intersection of 'RangeSetBlaze's.
262/// let result = [&a, &b, &c].intersection();
263/// assert_eq!(result.to_string(), "2..=2, 6..=6");
264///
265/// // Applying multiple operators
266/// let result0 = &a - (&b | &c); // Creates an intermediate 'RangeSetBlaze'.
267/// // Alternatively, we can use the 'SortedDisjoint' API and avoid the intermediate 'RangeSetBlaze'.
268/// let result1 = RangeSetBlaze::from_sorted_disjoint(a.ranges() - (b.ranges() | c.ranges()));
269/// assert!(result0 == result1 && result0.to_string() == "1..=1");
270/// ```
271/// # `RangeSetBlaze` Comparisons
272///
273/// We can compare `RangeSetBlaze`s using the following operators:
274/// `<`, `<=`, `>`, `>=`. Following the convention of `BTreeSet`,
275/// these comparisons are lexicographic. See [`cmp`] for more examples.
276///
277/// Use the [`is_subset`] and [`is_superset`] methods to check if one `RangeSetBlaze` is a subset
278/// or superset of another.
279///
280/// Use `==`, `!=` to check if two `RangeSetBlaze`s are equal or not.
281///
282/// [`BTreeSet`]: alloc::collections::BTreeSet
283/// [`is_subset`]: RangeSetBlaze::is_subset
284/// [`is_superset`]: RangeSetBlaze::is_superset
285/// [`cmp`]: RangeSetBlaze::cmp
286///
287/// # Additional Examples
288///
289/// See the [module-level documentation] for additional examples.
290///
291/// [module-level documentation]: index.html
292#[derive(Clone, Hash, PartialEq)]
293pub struct RangeSetBlaze<T: Integer> {
294 len: <T as Integer>::SafeLen,
295 pub(crate) btree_map: BTreeMap<T, T>,
296}
297
298// impl default
299impl<T: Integer> Default for RangeSetBlaze<T> {
300 /// Creates an empty `RangeSetBlaze`.
301 ///
302 /// # Examples
303 ///
304 /// ```
305 /// use range_set_blaze::RangeSetBlaze;
306 ///
307 /// let set: RangeSetBlaze<i32> = RangeSetBlaze::default();
308 /// assert!(set.is_empty());
309 /// ```
310 fn default() -> Self {
311 Self {
312 len: <T as Integer>::SafeLen::zero(),
313 btree_map: BTreeMap::new(),
314 }
315 }
316}
317
318// FUTURE: Make all RangeSetBlaze iterators DoubleEndedIterator and ExactSizeIterator.
319impl<T: Integer> fmt::Debug for RangeSetBlaze<T> {
320 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
321 write!(f, "{}", self.ranges().into_string())
322 }
323}
324
325impl<T: Integer> fmt::Display for RangeSetBlaze<T> {
326 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327 write!(f, "{}", self.ranges().into_string())
328 }
329}
330
331impl<T: Integer> RangeSetBlaze<T> {
332 /// Gets an iterator that visits the integer elements in the [`RangeSetBlaze`] in
333 /// ascending and/or descending order. Double-ended.
334 ///
335 /// Also see the [`RangeSetBlaze::ranges`] method.
336 ///
337 /// # Examples
338 ///
339 /// ```
340 /// use range_set_blaze::RangeSetBlaze;
341 ///
342 /// let set = RangeSetBlaze::from_iter([1..=3]);
343 /// let mut set_iter = set.iter();
344 /// assert_eq!(set_iter.next(), Some(1));
345 /// assert_eq!(set_iter.next(), Some(2));
346 /// assert_eq!(set_iter.next(), Some(3));
347 /// assert_eq!(set_iter.next(), None);
348 /// ```
349 ///
350 /// Values returned by `.next()` are in ascending order.
351 /// Values returned by `.next_back()` are in descending order.
352 ///
353 /// ```
354 /// use range_set_blaze::RangeSetBlaze;
355 ///
356 /// let set = RangeSetBlaze::from_iter([3, 1, 2]);
357 /// let mut set_iter = set.iter();
358 /// assert_eq!(set_iter.next(), Some(1));
359 /// assert_eq!(set_iter.next_back(), Some(3));
360 /// assert_eq!(set_iter.next(), Some(2));
361 /// assert_eq!(set_iter.next_back(), None);
362 /// ```
363 #[allow(clippy::iter_without_into_iter)]
364 pub fn iter(&self) -> Iter<T, RangesIter<'_, T>> {
365 // If the user asks for an iter, we give them a RangesIter iterator
366 // and we iterate that one integer at a time.
367 Iter {
368 range_front: T::exhausted_range(),
369 range_back: T::exhausted_range(),
370 btree_set_iter: self.ranges(),
371 }
372 }
373
374 /// Returns the first element in the set, if any.
375 /// This element is always the minimum of all integer elements in the set.
376 ///
377 /// # Examples
378 ///
379 /// Basic usage:
380 ///
381 /// ```
382 /// use range_set_blaze::RangeSetBlaze;
383 ///
384 /// let mut set = RangeSetBlaze::new();
385 /// assert_eq!(set.first(), None);
386 /// set.insert(1);
387 /// assert_eq!(set.first(), Some(1));
388 /// set.insert(2);
389 /// assert_eq!(set.first(), Some(1));
390 /// ```
391 #[must_use]
392 pub fn first(&self) -> Option<T> {
393 self.btree_map.iter().next().map(|(x, _)| *x)
394 }
395
396 /// Returns the element in the set, if any, that is equal to
397 /// the value.
398 ///
399 /// # Examples
400 ///
401 /// ```
402 /// use range_set_blaze::RangeSetBlaze;
403 ///
404 /// let set = RangeSetBlaze::from_iter([1, 2, 3]);
405 /// assert_eq!(set.get(2), Some(2));
406 /// assert_eq!(set.get(4), None);
407 /// ```
408 pub fn get(&self, value: T) -> Option<T> {
409 if self.contains(value) {
410 Some(value)
411 } else {
412 None
413 }
414 }
415
416 /// Returns the last element in the set, if any.
417 /// This element is always the maximum of all elements in the set.
418 ///
419 /// # Examples
420 ///
421 /// Basic usage:
422 ///
423 /// ```
424 /// use range_set_blaze::RangeSetBlaze;
425 ///
426 /// let mut set = RangeSetBlaze::new();
427 /// assert_eq!(set.last(), None);
428 /// set.insert(1);
429 /// assert_eq!(set.last(), Some(1));
430 /// set.insert(2);
431 /// assert_eq!(set.last(), Some(2));
432 /// ```
433 #[must_use]
434 pub fn last(&self) -> Option<T> {
435 self.btree_map.iter().next_back().map(|(_, x)| *x)
436 }
437
438 /// Create a [`RangeSetBlaze`] from a [`SortedDisjoint`] iterator.
439 ///
440 /// *For more about constructors and performance, see [`RangeSetBlaze` Constructors](struct.RangeSetBlaze.html#rangesetblaze-constructors).*
441 ///
442 /// # Examples
443 ///
444 /// ```
445 /// use range_set_blaze::prelude::*;
446 ///
447 /// let a0 = RangeSetBlaze::from_sorted_disjoint(CheckSortedDisjoint::new([-10..=-5, 1..=2]));
448 /// let a1: RangeSetBlaze<i32> = CheckSortedDisjoint::new([-10..=-5, 1..=2]).into_range_set_blaze();
449 /// assert!(a0 == a1 && a0.to_string() == "-10..=-5, 1..=2");
450 /// ```
451 pub fn from_sorted_disjoint<I>(iter: I) -> Self
452 where
453 I: SortedDisjoint<T>,
454 {
455 let mut iter_with_len = SortedDisjointWithLenSoFar::new(iter);
456 let btree_map = (&mut iter_with_len).collect();
457 Self {
458 btree_map,
459 len: iter_with_len.len_so_far(),
460 }
461 }
462
463 /// Creates a [`RangeSetBlaze`] from a collection of integers. It is typically many
464 /// times faster than [`from_iter`][1]/[`collect`][1].
465 /// On a representative benchmark, the speed up was 7×.
466 ///
467 /// **Warning: Requires the nightly compiler. Also, you must enable the `from_slice`
468 /// feature in your `Cargo.toml`. For example, with the command:**
469 /// ```bash
470 /// cargo add range-set-blaze --features "from_slice"
471 /// ```
472 /// The function accepts any type that can be referenced as a slice of integers,
473 /// including slices, arrays, and vectors. Duplicates and out-of-order elements are fine.
474 ///
475 /// Where available, this function leverages SIMD (Single Instruction, Multiple Data) instructions
476 /// for performance optimization. To enable SIMD optimizations, compile with the Rust compiler
477 /// (rustc) flag `-C target-cpu=native`. This instructs rustc to use the native instruction set
478 /// of the CPU on the machine compiling the code, potentially enabling more SIMD optimizations.
479 ///
480 /// **Caution**: Compiling with `-C target-cpu=native` optimizes the binary for your current CPU architecture,
481 /// which may lead to compatibility issues on other machines with different architectures.
482 /// This is particularly important for distributing the binary or running it in varied environments.
483 ///
484 /// *For more about constructors and performance, see [`RangeSetBlaze` Constructors](struct.RangeSetBlaze.html#rangesetblaze-constructors).*
485 ///
486 /// # Examples
487 ///
488 /// ```
489 /// use range_set_blaze::RangeSetBlaze;
490 ///
491 /// let a0 = RangeSetBlaze::from_slice(&[3, 2, 1, 100, 1]); // reference to a slice
492 /// let a1 = RangeSetBlaze::from_slice([3, 2, 1, 100, 1]); // array
493 /// let a2 = RangeSetBlaze::from_slice(vec![3, 2, 1, 100, 1]); // vector
494 /// assert!(a0 == a1 && a1 == a2 && a0.to_string() == "1..=3, 100..=100");
495 /// ```
496 /// [1]: struct.RangeSetBlaze.html#impl-FromIterator<T>-for-RangeSetBlaze<T>
497 #[cfg(feature = "from_slice")]
498 #[inline]
499 pub fn from_slice(slice: impl AsRef<[T]>) -> Self {
500 T::from_slice(slice)
501 }
502
503 #[allow(dead_code)]
504 #[must_use]
505 pub(crate) fn len_slow(&self) -> <T as Integer>::SafeLen {
506 Self::btree_map_len(&self.btree_map)
507 }
508
509 /// Moves all elements from `other` into `self`, leaving `other` empty.
510 ///
511 /// # Performance
512 /// It adds the integers in `other` to `self` in O(n log m) time, where n is the number of ranges in `other`
513 /// and m is the number of ranges in `self`.
514 /// When n is large, consider using `|` which is O(n+m) time.
515 ///
516 /// # Examples
517 ///
518 /// ```
519 /// use range_set_blaze::RangeSetBlaze;
520 ///
521 /// let mut a = RangeSetBlaze::from_iter([1..=3]);
522 /// let mut b = RangeSetBlaze::from_iter([3..=5]);
523 ///
524 /// a.append(&mut b);
525 ///
526 /// assert_eq!(a.len(), 5u64);
527 /// assert_eq!(b.len(), 0u64);
528 ///
529 /// assert!(a.contains(1));
530 /// assert!(a.contains(2));
531 /// assert!(a.contains(3));
532 /// assert!(a.contains(4));
533 /// assert!(a.contains(5));
534 ///
535 /// ```
536 pub fn append(&mut self, other: &mut Self) {
537 for range in other.ranges() {
538 self.internal_add(range);
539 }
540 other.clear();
541 }
542
543 /// Clears the set, removing all integer elements.
544 ///
545 /// # Examples
546 ///
547 /// ```
548 /// use range_set_blaze::RangeSetBlaze;
549 ///
550 /// let mut v = RangeSetBlaze::new();
551 /// v.insert(1);
552 /// v.clear();
553 /// assert!(v.is_empty());
554 /// ```
555 pub fn clear(&mut self) {
556 self.btree_map.clear();
557 self.len = <T as Integer>::SafeLen::zero();
558 }
559
560 /// Returns `true` if the set contains no elements.
561 ///
562 /// # Examples
563 ///
564 /// ```
565 /// use range_set_blaze::RangeSetBlaze;
566 ///
567 /// let mut v = RangeSetBlaze::new();
568 /// assert!(v.is_empty());
569 /// v.insert(1);
570 /// assert!(!v.is_empty());
571 /// ```
572 #[must_use]
573 #[inline]
574 pub fn is_empty(&self) -> bool {
575 self.ranges_len() == 0
576 }
577
578 /// Returns `true` if the set contains all possible integers.
579 ///
580 /// For type `T`, this means covering the full domain from `T::min_value()` to `T::max_value()`.
581 /// Complexity: O(1).
582 ///
583 /// # Examples
584 ///
585 /// ```
586 /// use range_set_blaze::RangeSetBlaze;
587 ///
588 /// let mut v = RangeSetBlaze::<u8>::new();
589 /// assert!(!v.is_universal());
590 ///
591 /// let universal = !RangeSetBlaze::<u8>::new();
592 /// assert!(universal.is_universal());
593 /// ```
594 #[must_use]
595 #[inline]
596 pub fn is_universal(&self) -> bool {
597 self.ranges().is_universal()
598 }
599
600 /// Returns `true` if the set is a subset of another,
601 /// i.e., `other` contains at least all the elements in `self`.
602 ///
603 /// # Examples
604 ///
605 /// ```
606 /// use range_set_blaze::RangeSetBlaze;
607 ///
608 /// let sup = RangeSetBlaze::from_iter([1..=3]);
609 /// let mut set = RangeSetBlaze::new();
610 ///
611 /// assert_eq!(set.is_subset(&sup), true);
612 /// set.insert(2);
613 /// assert_eq!(set.is_subset(&sup), true);
614 /// set.insert(4);
615 /// assert_eq!(set.is_subset(&sup), false);
616 /// ```
617 #[must_use]
618 #[inline]
619 pub fn is_subset(&self, other: &Self) -> bool {
620 // Add a fast path
621 if self.len() > other.len() {
622 return false;
623 }
624 self.ranges().is_subset(other.ranges())
625 }
626
627 /// Returns `true` if the set is a superset of another,
628 /// i.e., `self` contains at least all the elements in `other`.
629 ///
630 /// # Examples
631 ///
632 /// ```
633 /// use range_set_blaze::RangeSetBlaze;
634 ///
635 /// let sub = RangeSetBlaze::from_iter([1, 2]);
636 /// let mut set = RangeSetBlaze::new();
637 ///
638 /// assert_eq!(set.is_superset(&sub), false);
639 ///
640 /// set.insert(0);
641 /// set.insert(1);
642 /// assert_eq!(set.is_superset(&sub), false);
643 ///
644 /// set.insert(2);
645 /// assert_eq!(set.is_superset(&sub), true);
646 /// ```
647 #[must_use]
648 pub fn is_superset(&self, other: &Self) -> bool {
649 other.is_subset(self)
650 }
651
652 /// Returns `true` if the set contains an element equal to the value.
653 ///
654 /// # Examples
655 ///
656 /// ```
657 /// use range_set_blaze::RangeSetBlaze;
658 ///
659 /// let set = RangeSetBlaze::from_iter([1, 2, 3]);
660 /// assert_eq!(set.contains(1), true);
661 /// assert_eq!(set.contains(4), false);
662 /// ```
663 pub fn contains(&self, value: T) -> bool {
664 self.btree_map
665 .range(..=value)
666 .next_back()
667 .is_some_and(|(_, end)| value <= *end)
668 }
669
670 /// Returns `true` if `self` has no elements in common with `other`.
671 /// This is equivalent to checking for an empty intersection.
672 ///
673 /// # Examples
674 ///
675 /// ```
676 /// use range_set_blaze::RangeSetBlaze;
677 ///
678 /// let a = RangeSetBlaze::from_iter([1..=3]);
679 /// let mut b = RangeSetBlaze::new();
680 ///
681 /// assert_eq!(a.is_disjoint(&b), true);
682 /// b.insert(4);
683 /// assert_eq!(a.is_disjoint(&b), true);
684 /// b.insert(1);
685 /// assert_eq!(a.is_disjoint(&b), false);
686 /// ```
687 #[must_use]
688 #[inline]
689 pub fn is_disjoint(&self, other: &Self) -> bool {
690 self.ranges().is_disjoint(other.ranges())
691 }
692
693 fn delete_extra(&mut self, internal_range: &RangeInclusive<T>) {
694 let (start, end) = internal_range.clone().into_inner();
695 let mut after = self.btree_map.range_mut(start..);
696 let (start_after, end_after) = after
697 .next()
698 .expect("Real assert: there will always be a next");
699 debug_assert!(start == *start_after && end == *end_after);
700
701 let mut end_new = end;
702 let delete_list = after
703 .map_while(|(start_delete, end_delete)| {
704 // must check this in two parts to avoid overflow
705 if *start_delete <= end || *start_delete <= end.add_one() {
706 end_new = max(end_new, *end_delete);
707 self.len -= T::safe_len(&(*start_delete..=*end_delete));
708 Some(*start_delete)
709 } else {
710 None
711 }
712 })
713 .collect::<Vec<_>>();
714 if end_new > end {
715 self.len += T::safe_len(&(end..=end_new.sub_one()));
716 *end_after = end_new;
717 }
718 for start in delete_list {
719 self.btree_map.remove(&start);
720 }
721 }
722
723 /// Adds a value to the set.
724 ///
725 /// Returns whether the value was newly inserted. That is:
726 ///
727 /// - If the set did not previously contain an equal value, `true` is
728 /// returned.
729 /// - If the set already contained an equal value, `false` is returned, and
730 /// the entry is not updated.
731 ///
732 /// # Performance
733 /// 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`.
734 /// When n is large, consider using `|` which is O(n+m) time.
735 ///
736 /// # Examples
737 ///
738 /// ```
739 /// use range_set_blaze::RangeSetBlaze;
740 ///
741 /// let mut set = RangeSetBlaze::new();
742 ///
743 /// assert_eq!(set.insert(2), true);
744 /// assert_eq!(set.insert(2), false);
745 /// assert_eq!(set.len(), 1u64);
746 /// ```
747 pub fn insert(&mut self, value: T) -> bool {
748 let len_before = self.len;
749 self.internal_add(value..=value);
750 self.len != len_before
751 }
752
753 /// Constructs an iterator over a sub-range of elements in the set.
754 ///
755 /// Not to be confused with [`RangeSetBlaze::ranges`], which returns an iterator over the ranges in the set.
756 ///
757 /// The simplest way is to use the range syntax `min..max`, thus `range(min..max)` will
758 /// yield elements from min (inclusive) to max (exclusive).
759 /// The range may also be entered as `(Bound<T>, Bound<T>)`, so for example
760 /// `range((Excluded(4), Included(10)))` will yield a left-exclusive, right-inclusive
761 /// range from 4 to 10.
762 ///
763 /// # Panics
764 ///
765 /// Panics if range `start > end`.
766 /// Panics if range `start == end` and both bounds are `Excluded`.
767 ///
768 /// # Performance
769 ///
770 /// 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.
771 ///
772 /// # Examples
773 ///
774 /// ```
775 /// use range_set_blaze::RangeSetBlaze;
776 /// use core::ops::Bound::Included;
777 ///
778 /// let mut set = RangeSetBlaze::new();
779 /// set.insert(3);
780 /// set.insert(5);
781 /// set.insert(8);
782 /// for elem in set.range((Included(4), Included(8))) {
783 /// println!("{elem}");
784 /// }
785 /// assert_eq!(Some(5), set.range(4..).next());
786 /// ```
787 pub fn range<R>(&self, range: R) -> IntoIter<T>
788 where
789 R: RangeBounds<T>,
790 {
791 let (start, end) = extract_range(range);
792 assert!(
793 start <= end,
794 "start (inclusive) must be less than or equal to end (inclusive)"
795 );
796
797 let bounds = CheckSortedDisjoint::new([start..=end]);
798 Self::from_sorted_disjoint(self.ranges() & bounds).into_iter()
799 }
800
801 /// Adds a range to the set.
802 ///
803 /// Returns whether any values where newly inserted. That is:
804 ///
805 /// - If the set did not previously contain some value in the range, `true` is
806 /// returned.
807 /// - If the set already contained every value in the range, `false` is returned, and
808 /// the entry is not updated.
809 ///
810 /// # Performance
811 /// 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`.
812 /// When n is large, consider using `|` which is O(n+m) time.
813 ///
814 /// # Examples
815 ///
816 /// ```
817 /// use range_set_blaze::RangeSetBlaze;
818 ///
819 /// let mut set = RangeSetBlaze::new();
820 ///
821 /// assert_eq!(set.ranges_insert(2..=5), true);
822 /// assert_eq!(set.ranges_insert(5..=6), true);
823 /// assert_eq!(set.ranges_insert(3..=4), false);
824 /// assert_eq!(set.len(), 5u64);
825 /// ```
826 pub fn ranges_insert(&mut self, range: RangeInclusive<T>) -> bool {
827 let len_before = self.len;
828 self.internal_add(range);
829 self.len != len_before
830 }
831
832 /// If the set contains an element equal to the value, removes it from the
833 /// set and drops it. Returns whether such an element was present.
834 ///
835 /// # Examples
836 ///
837 /// ```
838 /// use range_set_blaze::RangeSetBlaze;
839 ///
840 /// let mut set = RangeSetBlaze::new();
841 ///
842 /// set.insert(2);
843 /// assert!(set.remove(2));
844 /// assert!(!set.remove(2));
845 /// ```
846 pub fn remove(&mut self, value: T) -> bool {
847 // The code can have only one mutable reference to self.btree_map.
848 let Some((start_ref, end_ref)) = self.btree_map.range_mut(..=value).next_back() else {
849 return false;
850 };
851
852 let end = *end_ref;
853 if end < value {
854 return false;
855 }
856 let start = *start_ref;
857 // special case if in range and start strictly less than value
858 if start < value {
859 *end_ref = value.sub_one();
860 // special, special case if value == end
861 if value == end {
862 self.len -= <T::SafeLen>::one();
863 return true;
864 }
865 }
866 self.len -= <T::SafeLen>::one();
867 if start == value {
868 self.btree_map.remove(&start);
869 }
870 if value < end {
871 self.btree_map.insert(value.add_one(), end);
872 }
873 true
874 }
875
876 /// Splits the collection into two at the value. Returns a new collection
877 /// with all elements greater than or equal to the value.
878 ///
879 /// # Examples
880 ///
881 /// Basic usage:
882 ///
883 /// ```
884 /// use range_set_blaze::RangeSetBlaze;
885 ///
886 /// let mut a = RangeSetBlaze::new();
887 /// a.insert(1);
888 /// a.insert(2);
889 /// a.insert(3);
890 /// a.insert(17);
891 /// a.insert(41);
892 ///
893 /// let b = a.split_off(3);
894 ///
895 /// assert_eq!(a, RangeSetBlaze::from_iter([1, 2]));
896 /// assert_eq!(b, RangeSetBlaze::from_iter([3, 17, 41]));
897 /// ```
898 #[must_use]
899 pub fn split_off(&mut self, key: T) -> Self {
900 let old_len = self.len;
901 let old_btree_len = self.btree_map.len();
902 let mut new_btree = self.btree_map.split_off(&key);
903 let Some(last_entry) = self.btree_map.last_entry() else {
904 // Left is empty
905 self.len = T::SafeLen::zero();
906 return Self {
907 btree_map: new_btree,
908 len: old_len,
909 };
910 };
911
912 let end = *last_entry.get();
913 if end < key {
914 // The split is clean
915 let (a_len, b_len) = self.two_element_lengths(old_btree_len, &new_btree, old_len);
916 self.len = a_len;
917 return Self {
918 btree_map: new_btree,
919 len: b_len,
920 };
921 }
922
923 // The split is not clean, so we must move some keys from the end of self to the start of b.
924 *(last_entry.into_mut()) = key.sub_one();
925 new_btree.insert(key, end);
926 let (a_len, b_len) = self.two_element_lengths(old_btree_len, &new_btree, old_len);
927 self.len = a_len;
928 Self {
929 btree_map: new_btree,
930 len: b_len,
931 }
932 }
933
934 // Find the len of the smaller btree_map and then the element len of self & b.
935 fn two_element_lengths(
936 &self,
937 old_btree_len: usize,
938 new_btree: &BTreeMap<T, T>,
939 mut old_len: <T as Integer>::SafeLen,
940 ) -> (<T as Integer>::SafeLen, <T as Integer>::SafeLen) {
941 if old_btree_len / 2 < new_btree.len() {
942 let a_len = Self::btree_map_len(&self.btree_map);
943 old_len -= a_len;
944 (a_len, old_len)
945 } else {
946 let b_len = Self::btree_map_len(new_btree);
947 old_len -= b_len;
948 (old_len, b_len)
949 }
950 }
951
952 fn btree_map_len(btree_map: &BTreeMap<T, T>) -> T::SafeLen {
953 btree_map
954 .iter()
955 .fold(<T as Integer>::SafeLen::zero(), |acc, (start, end)| {
956 acc + T::safe_len(&(*start..=*end))
957 })
958 }
959
960 /// Removes and returns the element in the set, if any, that is equal to
961 /// the value.
962 ///
963 /// # Examples
964 ///
965 /// ```
966 /// use range_set_blaze::RangeSetBlaze;
967 ///
968 /// let mut set = RangeSetBlaze::from_iter([1, 2, 3]);
969 /// assert_eq!(set.take(2), Some(2));
970 /// assert_eq!(set.take(2), None);
971 /// ```
972 pub fn take(&mut self, value: T) -> Option<T> {
973 if self.remove(value) {
974 Some(value)
975 } else {
976 None
977 }
978 }
979
980 /// Adds a value to the set, replacing the existing element, if any, that is
981 /// equal to the value. Returns the replaced element.
982 ///
983 /// Note: This is very similar to `insert`. It is included for consistency with [`BTreeSet`].
984 ///
985 /// [`BTreeSet`]: alloc::collections::BTreeSet
986 ///
987 /// # Examples
988 ///
989 /// ```
990 /// use range_set_blaze::RangeSetBlaze;
991 ///
992 /// let mut set = RangeSetBlaze::new();
993 /// assert!(set.replace(5).is_none());
994 /// assert!(set.replace(5).is_some());
995 /// ```
996 pub fn replace(&mut self, value: T) -> Option<T> {
997 if self.insert(value) {
998 None
999 } else {
1000 Some(value)
1001 }
1002 }
1003
1004 // https://stackoverflow.com/questions/49599833/how-to-find-next-smaller-key-in-btreemap-btreeset
1005 // https://stackoverflow.com/questions/35663342/how-to-modify-partially-remove-a-range-from-a-btreemap
1006 pub(crate) fn internal_add(&mut self, range: RangeInclusive<T>) {
1007 let (start, end) = range.clone().into_inner();
1008 if end < start {
1009 return;
1010 }
1011 // FUTURE: would be nice of BTreeMap to have a partition_point function that returns two iterators
1012 let mut before = self.btree_map.range_mut(..=start).rev();
1013 if let Some((start_before, end_before)) = before.next() {
1014 // Must check this in two parts to avoid overflow
1015 if (*end_before)
1016 .checked_add_one()
1017 .is_some_and(|end_before_succ| end_before_succ < start)
1018 {
1019 self.internal_add2(&range);
1020 } else if *end_before < end {
1021 self.len += T::safe_len(&(*end_before..=end.sub_one()));
1022 *end_before = end;
1023 let start_before = *start_before;
1024 self.delete_extra(&(start_before..=end));
1025 } else {
1026 // completely contained, so do nothing
1027 }
1028 } else {
1029 self.internal_add2(&range);
1030 }
1031 }
1032
1033 #[inline]
1034 fn internal_add2(&mut self, internal_range: &RangeInclusive<T>) {
1035 let (start, end) = internal_range.clone().into_inner();
1036 let was_there = self.btree_map.insert(start, end);
1037 debug_assert!(was_there.is_none()); // real assert
1038 self.delete_extra(internal_range);
1039 self.len += T::safe_len(internal_range);
1040 }
1041
1042 /// Returns the number of elements in the set.
1043 ///
1044 /// The number is allowed to be very, very large.
1045 ///
1046 /// # Examples
1047 ///
1048 /// ```
1049 /// use range_set_blaze::prelude::*;
1050 ///
1051 /// let mut v = RangeSetBlaze::new();
1052 /// assert_eq!(v.len(), 0u64);
1053 /// v.insert(1);
1054 /// assert_eq!(v.len(), 1u64);
1055 ///
1056 /// let v = RangeSetBlaze::from_iter([
1057 /// -170_141_183_460_469_231_731_687_303_715_884_105_728i128..=10,
1058 /// -10..=170_141_183_460_469_231_731_687_303_715_884_105_726,
1059 /// ]);
1060 /// assert_eq!(
1061 /// v.len(),
1062 /// UIntPlusOne::UInt(340282366920938463463374607431768211455)
1063 /// );
1064 /// ```
1065 #[must_use]
1066 pub const fn len(&self) -> <T as Integer>::SafeLen {
1067 self.len
1068 }
1069
1070 /// Makes a new, empty [`RangeSetBlaze`].
1071 ///
1072 /// # Examples
1073 ///
1074 /// ```
1075 /// # #![allow(unused_mut)]
1076 /// use range_set_blaze::RangeSetBlaze;
1077 ///
1078 /// let mut set: RangeSetBlaze<i32> = RangeSetBlaze::new();
1079 /// ```
1080 #[must_use]
1081 #[inline]
1082 pub fn new() -> Self {
1083 Self {
1084 btree_map: BTreeMap::new(),
1085 len: <T as Integer>::SafeLen::zero(),
1086 }
1087 }
1088
1089 /// Removes the first element from the set and returns it, if any.
1090 /// The first element is always the minimum element in the set.
1091 ///
1092 /// # Examples
1093 ///
1094 /// ```
1095 /// use range_set_blaze::RangeSetBlaze;
1096 ///
1097 /// let mut set = RangeSetBlaze::new();
1098 ///
1099 /// set.insert(1);
1100 /// while let Some(n) = set.pop_first() {
1101 /// assert_eq!(n, 1);
1102 /// }
1103 /// assert!(set.is_empty());
1104 /// ```
1105 pub fn pop_first(&mut self) -> Option<T> {
1106 if let Some(entry) = self.btree_map.first_entry() {
1107 let (start, end) = entry.remove_entry();
1108 self.len -= T::safe_len(&(start..=end));
1109 if start != end {
1110 let start = start.add_one();
1111 self.btree_map.insert(start, end);
1112 self.len += T::safe_len(&(start..=end));
1113 }
1114 Some(start)
1115 } else {
1116 None
1117 }
1118 }
1119
1120 /// Removes the last value from the set and returns it, if any.
1121 /// The last value is always the maximum value in the set.
1122 ///
1123 /// # Examples
1124 ///
1125 /// ```
1126 /// use range_set_blaze::RangeSetBlaze;
1127 ///
1128 /// let mut set = RangeSetBlaze::new();
1129 ///
1130 /// set.insert(1);
1131 /// while let Some(n) = set.pop_last() {
1132 /// assert_eq!(n, 1);
1133 /// }
1134 /// assert!(set.is_empty());
1135 /// ```
1136 pub fn pop_last(&mut self) -> Option<T> {
1137 let mut entry = self.btree_map.last_entry()?;
1138 let start = *entry.key();
1139 let end = entry.get_mut();
1140 let result = *end;
1141 self.len -= T::safe_len(&(start..=*end));
1142 if start == *end {
1143 entry.remove_entry();
1144 } else {
1145 (*end).assign_sub_one();
1146 self.len += T::safe_len(&(start..=*end));
1147 }
1148 Some(result)
1149 }
1150
1151 /// An iterator that visits the ranges in the [`RangeSetBlaze`],
1152 /// i.e., the integers as sorted & disjoint ranges. Double-ended.
1153 ///
1154 /// Also see [`RangeSetBlaze::iter`] and [`RangeSetBlaze::into_ranges`].
1155 ///
1156 /// # Examples
1157 ///
1158 /// ```
1159 /// use range_set_blaze::RangeSetBlaze;
1160 ///
1161 /// let set = RangeSetBlaze::from_iter([10..=20, 15..=25, 30..=40]);
1162 /// let mut ranges = set.ranges();
1163 /// assert_eq!(ranges.next(), Some(10..=25));
1164 /// assert_eq!(ranges.next(), Some(30..=40));
1165 /// assert_eq!(ranges.next(), None);
1166 /// ```
1167 ///
1168 /// Values returned by the iterator are returned in ascending order:
1169 ///
1170 /// ```
1171 /// use range_set_blaze::RangeSetBlaze;
1172 ///
1173 /// let set = RangeSetBlaze::from_iter([30..=40, 15..=25, 10..=20]);
1174 /// let mut ranges = set.ranges();
1175 /// assert_eq!(ranges.next(), Some(10..=25));
1176 /// assert_eq!(ranges.next(), Some(30..=40));
1177 /// assert_eq!(ranges.next(), None);
1178 /// ```
1179 pub fn ranges(&self) -> RangesIter<'_, T> {
1180 RangesIter {
1181 iter: self.btree_map.iter(),
1182 }
1183 }
1184
1185 /// An iterator that moves out the ranges in the [`RangeSetBlaze`],
1186 /// i.e., the integers as sorted & disjoint ranges.
1187 ///
1188 /// Also see [`RangeSetBlaze::into_iter`] and [`RangeSetBlaze::ranges`].
1189 ///
1190 /// # Examples
1191 ///
1192 /// ```
1193 /// use range_set_blaze::RangeSetBlaze;
1194 ///
1195 /// let mut ranges = RangeSetBlaze::from_iter([10..=20, 15..=25, 30..=40]).into_ranges();
1196 /// assert_eq!(ranges.next(), Some(10..=25));
1197 /// assert_eq!(ranges.next(), Some(30..=40));
1198 /// assert_eq!(ranges.next(), None);
1199 /// ```
1200 ///
1201 /// Values returned by the iterator are returned in ascending order:
1202 ///
1203 /// ```
1204 /// use range_set_blaze::RangeSetBlaze;
1205 ///
1206 /// let mut ranges = RangeSetBlaze::from_iter([30..=40, 15..=25, 10..=20]).into_ranges();
1207 /// assert_eq!(ranges.next(), Some(10..=25));
1208 /// assert_eq!(ranges.next(), Some(30..=40));
1209 /// assert_eq!(ranges.next(), None);
1210 /// ```
1211 pub fn into_ranges(self) -> IntoRangesIter<T> {
1212 IntoRangesIter {
1213 iter: self.btree_map.into_iter(),
1214 }
1215 }
1216
1217 /// Deprecated. Use `RangeSetBlaze::to_string` instead.
1218 #[deprecated(since = "0.2.0", note = "Use `RangeSetBlaze::to_string` instead.")]
1219 pub fn into_string(&self) -> String {
1220 self.to_string()
1221 }
1222
1223 // FUTURE BTreeSet some of these as 'const' but it uses unstable. When stable, add them here and elsewhere.
1224
1225 /// Returns the number of sorted & disjoint ranges in the set.
1226 ///
1227 /// # Example
1228 ///
1229 /// ```
1230 /// use range_set_blaze::RangeSetBlaze;
1231 ///
1232 /// // We put in three ranges, but they are not sorted & disjoint.
1233 /// let set = RangeSetBlaze::from_iter([10..=20, 15..=25, 30..=40]);
1234 /// // After RangeSetBlaze sorts & 'disjoint's them, we see two ranges.
1235 /// assert_eq!(set.ranges_len(), 2);
1236 /// assert_eq!(set.to_string(), "10..=25, 30..=40");
1237 /// ```
1238 #[must_use]
1239 pub fn ranges_len(&self) -> usize {
1240 self.btree_map.len()
1241 }
1242
1243 /// Retains only the elements specified by the predicate.
1244 ///
1245 /// In other words, remove all integers `t` for which `f(&t)` returns `false`.
1246 /// The integer elements are visited in ascending order.
1247 ///
1248 /// Because if visits every element in every range, it is expensive compared to
1249 /// [`RangeSetBlaze::ranges_retain`].
1250 ///
1251 /// # Examples
1252 ///
1253 /// ```
1254 /// use range_set_blaze::RangeSetBlaze;
1255 ///
1256 /// let mut set = RangeSetBlaze::from_iter([1..=6]);
1257 /// // Keep only the even numbers.
1258 /// set.retain(|k| k % 2 == 0);
1259 /// assert_eq!(set, RangeSetBlaze::from_iter([2, 4, 6]));
1260 /// ```
1261 pub fn retain<F>(&mut self, mut f: F)
1262 where
1263 F: FnMut(&T) -> bool,
1264 {
1265 *self = self.iter().filter(|t| f(t)).collect();
1266 }
1267
1268 /// Retains only the ranges specified by the predicate.
1269 ///
1270 /// In other words, remove all ranges `r` for which `f(&r)` returns `false`.
1271 /// The ranges are visited in ascending order.
1272 ///
1273 /// # Examples
1274 ///
1275 /// ```
1276 /// use range_set_blaze::RangeSetBlaze;
1277 ///
1278 /// let mut set = RangeSetBlaze::from_iter([1..=6, 10..=15]);
1279 /// // Keep only the ranges starting before 10.
1280 /// set.ranges_retain(|range| range.start() < &10);
1281 /// assert_eq!(set, RangeSetBlaze::from_iter([1..=6]));
1282 /// ```
1283 pub fn ranges_retain<F>(&mut self, mut f: F)
1284 where
1285 F: FnMut(&RangeInclusive<T>) -> bool,
1286 {
1287 self.btree_map.retain(|start, end| {
1288 let range = *start..=*end;
1289 if f(&range) {
1290 true
1291 } else {
1292 self.len -= T::safe_len(&range);
1293 false
1294 }
1295 });
1296 }
1297}
1298
1299// We create a RangeSetBlaze from an iterator of integers or integer ranges by
1300// 1. turning them into a UnionIter (internally, it collects into intervals and sorts by start).
1301// 2. Turning the SortedDisjoint into a BTreeMap.
1302impl<T: Integer> FromIterator<T> for RangeSetBlaze<T> {
1303 /// Create a [`RangeSetBlaze`] from an iterator of integers. Duplicates and out-of-order elements are fine.
1304 ///
1305 /// *For more about constructors and performance, see [`RangeSetBlaze` Constructors](struct.RangeSetBlaze.html#rangesetblaze-constructors).*
1306 ///
1307 /// # Examples
1308 ///
1309 /// ```
1310 /// use range_set_blaze::RangeSetBlaze;
1311 ///
1312 /// let a0 = RangeSetBlaze::from_iter([3, 2, 1, 100, 1]);
1313 /// let a1: RangeSetBlaze<i32> = [3, 2, 1, 100, 1].into_iter().collect();
1314 /// assert!(a0 == a1 && a0.to_string() == "1..=3, 100..=100");
1315 /// ```
1316 fn from_iter<I>(iter: I) -> Self
1317 where
1318 I: IntoIterator<Item = T>,
1319 {
1320 iter.into_iter().map(|x| x..=x).collect()
1321 }
1322}
1323
1324impl<'a, T: Integer> FromIterator<&'a T> for RangeSetBlaze<T> {
1325 /// Create a [`RangeSetBlaze`] from an iterator of integers references. Duplicates and out-of-order elements are fine.
1326 ///
1327 /// *For more about constructors and performance, see [`RangeSetBlaze` Constructors](struct.RangeSetBlaze.html#rangesetblaze-constructors).*
1328 ///
1329 /// # Examples
1330 ///
1331 /// ```
1332 /// use range_set_blaze::RangeSetBlaze;
1333 ///
1334 /// let a0 = RangeSetBlaze::from_iter(vec![3, 2, 1, 100, 1]);
1335 /// let a1: RangeSetBlaze<i32> = vec![3, 2, 1, 100, 1].into_iter().collect();
1336 /// assert!(a0 == a1 && a0.to_string() == "1..=3, 100..=100");
1337 /// ```
1338 fn from_iter<I>(iter: I) -> Self
1339 where
1340 I: IntoIterator<Item = &'a T>,
1341 {
1342 iter.into_iter().map(|x| *x..=*x).collect()
1343 }
1344}
1345
1346impl<T: Integer> FromIterator<RangeInclusive<T>> for RangeSetBlaze<T> {
1347 /// Create a [`RangeSetBlaze`] from an iterator of inclusive ranges, `start..=end`.
1348 /// Overlapping, out-of-order, and empty ranges are fine.
1349 ///
1350 /// *For more about constructors and performance, see [`RangeSetBlaze` Constructors](struct.RangeSetBlaze.html#rangesetblaze-constructors).*
1351 ///
1352 /// # Examples
1353 ///
1354 /// ```
1355 /// use range_set_blaze::RangeSetBlaze;
1356 ///
1357 /// #[allow(clippy::reversed_empty_ranges)]
1358 /// let a0 = RangeSetBlaze::from_iter([1..=2, 2..=2, -10..=-5, 1..=0]);
1359 /// #[allow(clippy::reversed_empty_ranges)]
1360 /// let a1: RangeSetBlaze<i32> = [1..=2, 2..=2, -10..=-5, 1..=0].into_iter().collect();
1361 /// assert!(a0 == a1 && a0.to_string() == "-10..=-5, 1..=2");
1362 /// ```
1363 fn from_iter<I>(iter: I) -> Self
1364 where
1365 I: IntoIterator<Item = RangeInclusive<T>>,
1366 {
1367 let union_iter: UnionIter<T, _> = iter.into_iter().collect();
1368 Self::from_sorted_disjoint(union_iter)
1369 }
1370}
1371
1372impl<'a, T: Integer> FromIterator<&'a RangeInclusive<T>> for RangeSetBlaze<T> {
1373 /// Create a [`RangeSetBlaze`] from an iterator of inclusive ranges, `start..=end`.
1374 /// Overlapping, out-of-order, and empty ranges are fine.
1375 ///
1376 /// *For more about constructors and performance, see [`RangeSetBlaze` Constructors](struct.RangeSetBlaze.html#rangesetblaze-constructors).*
1377 ///
1378 /// # Examples
1379 ///
1380 /// ```
1381 /// use range_set_blaze::RangeSetBlaze;
1382 ///
1383 /// #[allow(clippy::reversed_empty_ranges)]
1384 /// let vec_range = vec![1..=2, 2..=2, -10..=-5, 1..=0];
1385 /// let a0 = RangeSetBlaze::from_iter(&vec_range);
1386 /// let a1: RangeSetBlaze<i32> = vec_range.iter().collect();
1387 /// assert!(a0 == a1 && a0.to_string() == "-10..=-5, 1..=2");
1388 /// ```
1389 fn from_iter<I>(iter: I) -> Self
1390 where
1391 I: IntoIterator<Item = &'a RangeInclusive<T>>,
1392 {
1393 let union_iter: UnionIter<T, _> = iter.into_iter().cloned().collect();
1394 Self::from_sorted_disjoint(union_iter)
1395 }
1396}
1397
1398impl<T: Integer, const N: usize> From<[T; N]> for RangeSetBlaze<T> {
1399 /// For compatibility with [`BTreeSet`] you may create a [`RangeSetBlaze`] from an array of integers.
1400 ///
1401 /// *For more about constructors and performance, see [`RangeSetBlaze` Constructors](struct.RangeSetBlaze.html#rangesetblaze-constructors).*
1402 ///
1403 /// [`BTreeSet`]: alloc::collections::BTreeSet
1404 ///
1405 /// # Examples
1406 ///
1407 /// ```
1408 /// use range_set_blaze::RangeSetBlaze;
1409 ///
1410 /// let a0 = RangeSetBlaze::from([3, 2, 1, 100, 1]);
1411 /// let a1: RangeSetBlaze<i32> = [3, 2, 1, 100, 1].into();
1412 /// assert!(a0 == a1 && a0.to_string() == "1..=3, 100..=100")
1413 /// ```
1414 #[cfg(not(feature = "from_slice"))]
1415 fn from(arr: [T; N]) -> Self {
1416 arr.into_iter().collect()
1417 }
1418 #[cfg(feature = "from_slice")]
1419 fn from(arr: [T; N]) -> Self {
1420 Self::from_slice(arr)
1421 }
1422}
1423
1424impl<T: Integer> From<RangeInclusive<T>> for RangeSetBlaze<T> {
1425 /// Construct a [`RangeSetBlaze<T>`] directly from a [`RangeInclusive<T>`].
1426 fn from(value: RangeInclusive<T>) -> Self {
1427 Self::from_sorted_disjoint(RangeOnce::new(value))
1428 }
1429}
1430
1431gen_ops_ex!(
1432 <T>;
1433 types ref RangeSetBlaze<T>, ref RangeSetBlaze<T> => RangeSetBlaze<T>;
1434
1435 /// Intersects the contents of two [`RangeSetBlaze`]'s.
1436 ///
1437 /// Either, neither, or both inputs may be borrowed.
1438 ///
1439 /// # Examples
1440 /// ```
1441 /// use range_set_blaze::prelude::*;
1442 ///
1443 /// let a = RangeSetBlaze::from_iter([1..=2, 5..=100]);
1444 /// let b = RangeSetBlaze::from_iter([2..=6]);
1445 /// let result = &a & &b; // Alternatively, 'a & b'.
1446 /// assert_eq!(result.to_string(), "2..=2, 5..=6");
1447 /// ```
1448 for & call |a: &RangeSetBlaze<T>, b: &RangeSetBlaze<T>| {
1449 (a.ranges() & b.ranges()).into_range_set_blaze()
1450 };
1451
1452 /// Symmetric difference the contents of two [`RangeSetBlaze`]'s.
1453 ///
1454 /// Either, neither, or both inputs may be borrowed.
1455 ///
1456 /// # Examples
1457 /// ```
1458 /// use range_set_blaze::prelude::*;
1459 ///
1460 /// let a = RangeSetBlaze::from_iter([1..=2, 5..=100]);
1461 /// let b = RangeSetBlaze::from_iter([2..=6]);
1462 /// let result = &a ^ &b; // Alternatively, 'a ^ b'.
1463 /// assert_eq!(result.to_string(), "1..=1, 3..=4, 7..=100");
1464 /// ```
1465 for ^ call |a: &RangeSetBlaze<T>, b: &RangeSetBlaze<T>| {
1466 a.ranges().symmetric_difference(b.ranges()).into_range_set_blaze()
1467 };
1468
1469 /// Difference the contents of two [`RangeSetBlaze`]'s.
1470 ///
1471 /// Either, neither, or both inputs may be borrowed.
1472 ///
1473 /// # Examples
1474 /// ```
1475 /// use range_set_blaze::prelude::*;
1476 ///
1477 /// let a = RangeSetBlaze::from_iter([1..=2, 5..=100]);
1478 /// let b = RangeSetBlaze::from_iter([2..=6]);
1479 /// let result = &a - &b; // Alternatively, 'a - b'.
1480 /// assert_eq!(result.to_string(), "1..=1, 7..=100");
1481 /// ```
1482 for - call |a: &RangeSetBlaze<T>, b: &RangeSetBlaze<T>| {
1483 (a.ranges() - b.ranges()).into_range_set_blaze()
1484 };
1485 where T: Integer //Where clause for all impl's
1486);
1487
1488gen_ops_ex!(
1489 <T>;
1490 types ref RangeSetBlaze<T> => RangeSetBlaze<T>;
1491
1492 /// Complement the contents of a [`RangeSetBlaze`].
1493 ///
1494 /// The input may be borrowed or not.
1495 ///
1496 /// # Examples
1497 /// ```
1498 /// use range_set_blaze::prelude::*;
1499 ///
1500 /// let a = RangeSetBlaze::from_iter([1..=2, 5..=100]);
1501 /// let result = !&a; // Alternatively, '!a'.
1502 /// assert_eq!(
1503 /// result.to_string(),
1504 /// "-2147483648..=0, 3..=4, 101..=2147483647"
1505 /// );
1506 /// ```
1507 for ! call |a: &RangeSetBlaze<T>| {
1508 (!a.ranges()).into_range_set_blaze()
1509 };
1510
1511 where T: Integer //Where clause for all impl's
1512);
1513
1514// Implementing `IntoIterator` for `&RangeSetBlaze` because BTreeSet does.
1515impl<'a, T: Integer> IntoIterator for &'a RangeSetBlaze<T> {
1516 type Item = T;
1517 type IntoIter = Iter<T, RangesIter<'a, T>>;
1518 fn into_iter(self) -> Self::IntoIter {
1519 self.iter()
1520 }
1521}
1522
1523impl<T: Integer> IntoIterator for RangeSetBlaze<T> {
1524 type Item = T;
1525 type IntoIter = IntoIter<T>;
1526
1527 /// Gets an iterator for moving out the [`RangeSetBlaze`]'s integer contents.
1528 /// Double-ended.
1529 ///
1530 /// # Examples
1531 ///
1532 /// ```
1533 /// use range_set_blaze::RangeSetBlaze;
1534 ///
1535 /// let set = RangeSetBlaze::from_iter([1, 2, 3, 4]);
1536 ///
1537 /// let v: Vec<_> = set.into_iter().collect();
1538 /// assert_eq!(v, [1, 2, 3, 4]);
1539 ///
1540 /// let set = RangeSetBlaze::from_iter([1, 2, 3, 4]);
1541 /// let v: Vec<_> = set.into_iter().rev().collect();
1542 /// assert_eq!(v, [4, 3, 2, 1]);
1543 /// ```
1544 fn into_iter(self) -> IntoIter<T> {
1545 IntoIter {
1546 option_range_front: None,
1547 option_range_back: None,
1548 btree_map_into_iter: self.btree_map.into_iter(),
1549 }
1550 }
1551}
1552
1553/// An iterator over the integer elements of a [`RangeSetBlaze`]. Double-ended.
1554///
1555/// This `struct` is created by the [`iter`] method on [`RangeSetBlaze`]. See its
1556/// documentation for more.
1557///
1558/// [`iter`]: RangeSetBlaze::iter
1559#[must_use = "iterators are lazy and do nothing unless consumed"]
1560#[derive(Clone, Debug)]
1561#[allow(clippy::struct_field_names)]
1562pub struct Iter<T, I>
1563where
1564 T: Integer,
1565 I: SortedDisjoint<T>,
1566{
1567 btree_set_iter: I,
1568 // FUTURE: here and elsewhere, when core::iter:Step is available could
1569 // FUTURE: use RangeInclusive as an iterator (with exhaustion) rather than needing an Option
1570 range_front: RangeInclusive<T>,
1571 range_back: RangeInclusive<T>,
1572}
1573
1574impl<T: Integer, I> FusedIterator for Iter<T, I> where I: SortedDisjoint<T> + FusedIterator {}
1575
1576impl<T: Integer, I> Iterator for Iter<T, I>
1577where
1578 I: SortedDisjoint<T>,
1579{
1580 type Item = T;
1581 fn next(&mut self) -> Option<T> {
1582 // return the next integer (if any) from range_front
1583 if let Some(next_item) = T::range_next(&mut self.range_front) {
1584 return Some(next_item);
1585 }
1586
1587 // if range_front is exhausted, get the next range from the btree_set_iter and its next integer
1588 if let Some(next_range) = self.btree_set_iter.next() {
1589 debug_assert!(next_range.start() <= next_range.end()); // real assert
1590 self.range_front = next_range;
1591 return T::range_next(&mut self.range_front); // will never be None
1592 }
1593
1594 // if that doesn't work, move the back range to the front and get the next integer (if any)
1595 self.range_front = mem::replace(&mut self.range_back, T::exhausted_range());
1596 T::range_next(&mut self.range_front)
1597 }
1598
1599 // We'll have at least as many integers as intervals. There could be more that usize MAX
1600 // The option_range field could increase the number of integers, but we can ignore that.
1601 fn size_hint(&self) -> (usize, Option<usize>) {
1602 let (low, _high) = self.btree_set_iter.size_hint();
1603 (low, None)
1604 }
1605}
1606
1607impl<T: Integer, I> DoubleEndedIterator for Iter<T, I>
1608where
1609 I: SortedDisjoint<T> + DoubleEndedIterator,
1610{
1611 fn next_back(&mut self) -> Option<Self::Item> {
1612 // return the next_back integer (if any) from range_back
1613 if let Some(next_item) = T::range_next_back(&mut self.range_back) {
1614 return Some(next_item);
1615 }
1616
1617 // if the range_back is exhausted, get the next_back range from the btree_set_iter and its next_back integer
1618 if let Some(next_back_range) = self.btree_set_iter.next_back() {
1619 debug_assert!(next_back_range.start() <= next_back_range.end()); // real assert
1620 self.range_back = next_back_range;
1621 return T::range_next_back(&mut self.range_back); // will never be None
1622 }
1623
1624 // if that doesn't work, move the front range to the back and get the next back integer (if any)
1625 self.range_back = mem::replace(&mut self.range_front, T::exhausted_range());
1626 T::range_next_back(&mut self.range_back)
1627 }
1628}
1629
1630/// An iterator over the integer elements of a [`RangeSetBlaze`]. Double-ended.
1631///
1632/// This `struct` is created by the [`into_iter`] method on [`RangeSetBlaze`]. See its
1633/// documentation for more.
1634///
1635/// [`into_iter`]: RangeSetBlaze::into_iter
1636#[must_use = "iterators are lazy and do nothing unless consumed"]
1637#[derive(Debug)]
1638#[allow(clippy::struct_field_names)]
1639pub struct IntoIter<T: Integer> {
1640 option_range_front: Option<RangeInclusive<T>>,
1641 option_range_back: Option<RangeInclusive<T>>,
1642 btree_map_into_iter: btree_map::IntoIter<T, T>,
1643}
1644
1645impl<T: Integer> FusedIterator for IntoIter<T> {}
1646
1647impl<T: Integer> Iterator for IntoIter<T> {
1648 type Item = T;
1649
1650 fn next(&mut self) -> Option<Self::Item> {
1651 let range = self
1652 .option_range_front
1653 .take()
1654 .or_else(|| {
1655 self.btree_map_into_iter
1656 .next()
1657 .map(|(start, end)| start..=end)
1658 })
1659 .or_else(|| self.option_range_back.take())?;
1660
1661 let (start, end) = range.into_inner();
1662 debug_assert!(start <= end);
1663 if start < end {
1664 self.option_range_front = Some(start.add_one()..=end);
1665 }
1666 Some(start)
1667 }
1668
1669 // We'll have at least as many integers as intervals. There could be more that usize MAX
1670 // the option_range field could increase the number of integers, but we can ignore that.
1671 fn size_hint(&self) -> (usize, Option<usize>) {
1672 let (low, _high) = self.btree_map_into_iter.size_hint();
1673 (low, None)
1674 }
1675}
1676
1677impl<T: Integer> DoubleEndedIterator for IntoIter<T> {
1678 fn next_back(&mut self) -> Option<Self::Item> {
1679 let range = self
1680 .option_range_back
1681 .take()
1682 .or_else(|| {
1683 self.btree_map_into_iter
1684 .next_back()
1685 .map(|(start, end)| start..=end)
1686 })
1687 .or_else(|| self.option_range_front.take())?;
1688
1689 let (start, end) = range.into_inner();
1690 debug_assert!(start <= end);
1691 if start < end {
1692 self.option_range_back = Some(start..=end.sub_one());
1693 }
1694
1695 Some(end)
1696 }
1697}
1698
1699impl<T: Integer> Extend<T> for RangeSetBlaze<T> {
1700 /// Extends the [`RangeSetBlaze`] with the contents of an Integer iterator.
1701 ///
1702 /// Integers are added one-by-one. There is also a version
1703 /// that takes a range iterator.
1704 ///
1705 /// The [`|=`](RangeSetBlaze::bitor_assign) operator extends a [`RangeSetBlaze`]
1706 /// from another [`RangeSetBlaze`]. It is never slower
1707 /// than [`RangeSetBlaze::extend`] and often several times faster.
1708 ///
1709 /// # Examples
1710 /// ```
1711 /// use range_set_blaze::RangeSetBlaze;
1712 /// let mut a = RangeSetBlaze::from_iter([1..=4]);
1713 /// a.extend([5, 0, 0, 3, 4, 10]);
1714 /// assert_eq!(a, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1715 ///
1716 /// let mut a = RangeSetBlaze::from_iter([1..=4]);
1717 /// let mut b = RangeSetBlaze::from_iter([5, 0, 0, 3, 4, 10]);
1718 /// a |= b;
1719 /// assert_eq!(a, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1720 /// ```
1721 #[inline]
1722 fn extend<I>(&mut self, iter: I)
1723 where
1724 I: IntoIterator<Item = T>,
1725 {
1726 let iter = iter.into_iter();
1727 for range in UnsortedDisjoint::new(iter.map(|x| x..=x)) {
1728 self.internal_add(range);
1729 }
1730 }
1731}
1732
1733impl<T: Integer> BitOrAssign<&Self> for RangeSetBlaze<T> {
1734 /// Adds the contents of another [`RangeSetBlaze`] to this one.
1735 ///
1736 /// Passing the right-hand side by ownership rather than borrow
1737 /// will allow a many-times faster speed up when the
1738 /// right-hand side is much larger than the left-hand side.
1739 ///
1740 /// Also, this operation is never slower than [`RangeSetBlaze::extend`] and
1741 /// can often be many times faster.
1742 ///
1743 /// # Examples
1744 /// ```
1745 /// use range_set_blaze::RangeSetBlaze;
1746 /// let mut a = RangeSetBlaze::from_iter([1..=4]);
1747 /// let mut b = RangeSetBlaze::from_iter([0..=0, 3..=5, 10..=10]);
1748 /// a |= &b;
1749 /// assert_eq!(a, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1750 /// ```
1751 fn bitor_assign(&mut self, other: &Self) {
1752 let b_len = other.ranges_len();
1753 if b_len == 0 {
1754 return;
1755 }
1756 let a_len = self.ranges_len();
1757 if a_len == 0 {
1758 *self = other.clone();
1759 return;
1760 }
1761 let a_len_log2: usize = a_len
1762 .ilog2()
1763 .try_into() // u32 → usize
1764 .expect(
1765 "ilog2 result always fits in usize on our targets so this will be optimized away",
1766 );
1767
1768 if b_len * (a_len_log2 + 1) < a_len + b_len {
1769 for (start, end) in &other.btree_map {
1770 self.internal_add(*start..=*end);
1771 }
1772 } else {
1773 *self = (self.ranges() | other.ranges()).into_range_set_blaze();
1774 }
1775 }
1776}
1777
1778impl<T: Integer> BitOrAssign<Self> for RangeSetBlaze<T> {
1779 /// Adds the contents of another [`RangeSetBlaze`] to this one.
1780 ///
1781 /// Passing the right-hand side by ownership rather than borrow
1782 /// will allow a many-times faster speed up when the
1783 /// right-hand side is much larger than the left-hand side.
1784 ///
1785 /// Also, this operation is never slower than [`RangeSetBlaze::extend`] and
1786 /// can often be many times faster.
1787 ///
1788 ///
1789 /// # Examples
1790 /// ```
1791 /// use range_set_blaze::RangeSetBlaze;
1792 /// let mut a = RangeSetBlaze::from_iter([1..=4]);
1793 /// let mut b = RangeSetBlaze::from_iter([0..=0, 3..=5, 10..=10]);
1794 /// a |= b;
1795 /// assert_eq!(a, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1796 /// ```
1797 fn bitor_assign(&mut self, mut other: Self) {
1798 let a_len = self.ranges_len();
1799 let b_len = other.ranges_len();
1800 if b_len <= a_len {
1801 *self |= &other;
1802 } else {
1803 other |= &*self;
1804 *self = other;
1805 }
1806 }
1807}
1808
1809impl<T: Integer> BitOr<Self> for RangeSetBlaze<T> {
1810 /// Unions the contents of two [`RangeSetBlaze`]'s.
1811 ///
1812 /// Passing ownership rather than borrow sometimes allows a many-times
1813 /// faster speed up.
1814 ///
1815 /// Also see [`a |= b`](RangeSetBlaze::bitor_assign).
1816 ///
1817 /// # Examples
1818 /// ```
1819 /// use range_set_blaze::RangeSetBlaze;
1820 /// let a = RangeSetBlaze::from_iter([1..=4]);
1821 /// let b = RangeSetBlaze::from_iter([0..=0, 3..=5, 10..=10]);
1822 /// let union = a | b; // Alternatively, '&a | &b', etc.
1823 /// assert_eq!(union, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1824 /// ```
1825 type Output = Self;
1826 fn bitor(mut self, other: Self) -> Self {
1827 self |= other;
1828 self
1829 }
1830}
1831
1832impl<T: Integer> BitOr<&Self> for RangeSetBlaze<T> {
1833 /// Unions the contents of two [`RangeSetBlaze`]'s.
1834 ///
1835 /// Passing ownership rather than borrow sometimes allows a many-times
1836 /// faster speed up.
1837 ///
1838 /// Also see [`a |= b`](RangeSetBlaze::bitor_assign).
1839 ///
1840 /// # Examples
1841 /// ```
1842 /// use range_set_blaze::RangeSetBlaze;
1843 /// let a = RangeSetBlaze::from_iter([1..=4]);
1844 /// let b = RangeSetBlaze::from_iter([0..=0, 3..=5, 10..=10]);
1845 /// let union = a | &b; // Alternatively, 'a | b', etc.
1846 /// assert_eq!(union, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1847 /// ```
1848 type Output = Self;
1849 fn bitor(mut self, other: &Self) -> Self {
1850 self |= other;
1851 self
1852 }
1853}
1854
1855impl<T: Integer> BitOr<RangeSetBlaze<T>> for &RangeSetBlaze<T> {
1856 type Output = RangeSetBlaze<T>;
1857 /// Unions the contents of two [`RangeSetBlaze`]'s.
1858 ///
1859 /// Passing ownership rather than borrow sometimes allows a many-times
1860 /// faster speed up.
1861 ///
1862 /// Also see [`a |= b`](RangeSetBlaze::bitor_assign).
1863 ///
1864 /// # Examples
1865 /// ```
1866 /// use range_set_blaze::RangeSetBlaze;
1867 /// let a = RangeSetBlaze::from_iter([1..=4]);
1868 /// let b = RangeSetBlaze::from_iter([0..=0, 3..=5, 10..=10]);
1869 /// let union = &a | b; // Alternatively, 'a | b', etc.
1870 /// assert_eq!(union, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1871 /// ```
1872 fn bitor(self, mut other: RangeSetBlaze<T>) -> RangeSetBlaze<T> {
1873 other |= self;
1874 other
1875 }
1876}
1877
1878impl<T: Integer> BitOr<&RangeSetBlaze<T>> for &RangeSetBlaze<T> {
1879 type Output = RangeSetBlaze<T>;
1880 /// Unions the contents of two [`RangeSetBlaze`]'s.
1881 ///
1882 /// Passing ownership rather than borrow sometimes allows a many-times
1883 /// faster speed up.
1884 ///
1885 /// Also see [`a |= b`](RangeSetBlaze::bitor_assign).
1886 ///
1887 /// # Examples
1888 /// ```
1889 /// use range_set_blaze::RangeSetBlaze;
1890 /// let a = RangeSetBlaze::from_iter([1..=4]);
1891 /// let b = RangeSetBlaze::from_iter([0..=0, 3..=5, 10..=10]);
1892 /// let union = &a | &b; // Alternatively, 'a | b', etc.
1893 /// assert_eq!(union, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1894 /// ```
1895 fn bitor(self, other: &RangeSetBlaze<T>) -> RangeSetBlaze<T> {
1896 if other.ranges_len() == 0 {
1897 return self.clone();
1898 }
1899 if self.ranges_len() == 0 {
1900 return other.clone();
1901 }
1902 (self.ranges() | other.ranges()).into_range_set_blaze()
1903 }
1904}
1905
1906impl<T: Integer> Extend<RangeInclusive<T>> for RangeSetBlaze<T> {
1907 /// Extends the [`RangeSetBlaze`] with the contents of a
1908 /// range iterator.
1909 ///
1910 /// Elements are added one-by-one. There is also a version
1911 /// that takes an integer iterator.
1912 ///
1913 /// The [`|=`](RangeSetBlaze::bitor_assign) operator extends a [`RangeSetBlaze`]
1914 /// from another [`RangeSetBlaze`]. It is never slower
1915 /// than [`RangeSetBlaze::extend`] and often several times faster.
1916 ///
1917 /// # Examples
1918 /// ```
1919 /// use range_set_blaze::RangeSetBlaze;
1920 /// let mut a = RangeSetBlaze::from_iter([1..=4]);
1921 /// a.extend([5..=5, 0..=0, 0..=0, 3..=4, 10..=10]);
1922 /// assert_eq!(a, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1923 ///
1924 /// let mut a = RangeSetBlaze::from_iter([1..=4]);
1925 /// let b = RangeSetBlaze::from_iter([5..=5, 0..=0, 0..=0, 3..=4, 10..=10]);
1926 /// a |= b;
1927 /// assert_eq!(a, RangeSetBlaze::from_iter([0..=5, 10..=10]));
1928 /// ```
1929 #[inline]
1930 fn extend<I>(&mut self, iter: I)
1931 where
1932 I: IntoIterator<Item = RangeInclusive<T>>,
1933 {
1934 let iter = iter.into_iter();
1935 let iter = UnsortedDisjoint::new(iter);
1936 for range in iter {
1937 self.internal_add(range);
1938 }
1939 }
1940}
1941
1942impl<T: Integer> Ord for RangeSetBlaze<T> {
1943 /// We define a total ordering on `RangeSetBlaze`. Following the convention of
1944 /// [`BTreeSet`], the ordering is lexicographic, *not* by subset/superset.
1945 ///
1946 /// [`BTreeSet`]: alloc::collections::BTreeSet
1947 ///
1948 /// # Examples
1949 /// ```
1950 /// use range_set_blaze::RangeSetBlaze;
1951 ///
1952 /// let a = RangeSetBlaze::from_iter([1..=3, 5..=7]);
1953 /// let b = RangeSetBlaze::from_iter([2..=2]);
1954 /// assert!(a < b); // Lexicographic comparison
1955 /// assert!(b.is_subset(&a)); // Subset comparison
1956 /// // More lexicographic comparisons
1957 /// assert!(a <= b);
1958 /// assert!(b > a);
1959 /// assert!(b >= a);
1960 /// assert!(a != b);
1961 /// assert!(a == a);
1962 /// use core::cmp::Ordering;
1963 /// assert_eq!(a.cmp(&b), Ordering::Less);
1964 /// assert_eq!(a.partial_cmp(&b), Some(Ordering::Less));
1965 /// ```
1966 #[inline]
1967 fn cmp(&self, other: &Self) -> Ordering {
1968 // slow one by one: return self.iter().cmp(other.iter());
1969
1970 // fast by ranges:
1971 let mut a = self.ranges();
1972 let mut b = other.ranges();
1973 let mut a_rx = a.next();
1974 let mut b_rx = b.next();
1975 loop {
1976 match (a_rx, b_rx) {
1977 (Some(a_r), Some(b_r)) => {
1978 let cmp_start = a_r.start().cmp(b_r.start());
1979 if cmp_start != Ordering::Equal {
1980 return cmp_start;
1981 }
1982 let cmp_end = a_r.end().cmp(b_r.end());
1983 match cmp_end {
1984 Ordering::Equal => {
1985 a_rx = a.next();
1986 b_rx = b.next();
1987 }
1988 Ordering::Less => {
1989 a_rx = a.next();
1990 b_rx = Some((*a_r.end()).add_one()..=*b_r.end());
1991 }
1992 Ordering::Greater => {
1993 a_rx = Some((*b_r.end()).add_one()..=*a_r.end());
1994 b_rx = b.next();
1995 }
1996 }
1997 }
1998 (Some(_), None) => return Ordering::Greater,
1999 (None, Some(_)) => return Ordering::Less,
2000 (None, None) => return Ordering::Equal,
2001 }
2002 }
2003 }
2004}
2005
2006impl<T: Integer> PartialOrd for RangeSetBlaze<T> {
2007 #[inline]
2008 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2009 Some(self.cmp(other))
2010 }
2011}
2012
2013impl<T: Integer> Eq for RangeSetBlaze<T> {}
2014
2015/// Extracts the start and end of a range from a `RangeBounds`.
2016///
2017/// Empty ranges are allowed.
2018#[allow(clippy::redundant_pub_crate)]
2019pub(crate) fn extract_range<T: Integer, R>(range: R) -> (T, T)
2020where
2021 R: RangeBounds<T>,
2022{
2023 let start = match range.start_bound() {
2024 Bound::Included(n) => *n,
2025 Bound::Excluded(n) => {
2026 assert!(
2027 *n < T::max_value(),
2028 "inclusive start must be <= T::max_safe_value()"
2029 );
2030 n.add_one()
2031 }
2032 Bound::Unbounded => T::min_value(),
2033 };
2034 let end = match range.end_bound() {
2035 Bound::Included(n) => *n,
2036 Bound::Excluded(n) => {
2037 assert!(
2038 *n > T::min_value(),
2039 "inclusive end must be >= T::min_value()"
2040 );
2041 n.sub_one()
2042 }
2043 Bound::Unbounded => T::max_value(),
2044 };
2045 (start, end)
2046}