OrdMask
ordmask is a library for efficient range-based set operations and membership checking. It represents a set of values as a collection of intervals and supports various set operations.
Features
- Efficient range membership checking
- Support for
union,intersection,minus,complement, andsymmetric_differenceoperations - Works with any type that implements
Ord,Clone, andWithMintraits - Zero-allocation operations where possible
- Optional
serdefeature for serialization/deserialization
Construction
use ;
// [0, 10), [20, 30) and [40, MAX]
let mask = ordmask!;
assert!;
assert!;
assert!;
// Create from `Vec<T>`
assert_eq!;
// Create from suspicious_points and a predicate
use BTreeSet;
assert_eq!;
// Create from suspicious_points_map
use BTreeMap;
let map = from;
assert_eq!;
// [MIN, 10)
let mask = ordmask!;
assert_eq!;
assert!;
assert!;
// [10, MAX]
let mask = ordmask!;
assert_eq!;
assert!;
assert!;
// [10, 20)
let mask = ordmask!;
assert_eq!;
assert!;
assert!;
assert!;
assert!;
// Universal
let mask = ordmask!;
assert_eq!;
assert!;
assert!;
// Empty
let mask = ordmask!;
assert_eq!;
assert!;
assert!;
Type Annotation
You can specify the type explicitly using the <T> syntax in the macro:
use ;
// Explicit type annotation with <T>
let mask = ordmask!; // Empty
let mask = ordmask!; // Universal
let mask = ordmask!; // [10, MAX]
let mask = ordmask!; // [10, 20)
let mask = ordmask!; // [MIN, 10)
Union
use ;
let a = ordmask!;
let b = ordmask!;
let c = ordmask!;
// &a | &b | &c: reference operators do not move (consume) the values
assert_eq!;
// a | b | c: non-reference operators move (consume) the values
assert_eq!;
Intersection
use ;
let a = ordmask!;
let b = ordmask!;
let c = ordmask!;
// &a & &b & &c: reference operators do not move (consume) the values
assert_eq!;
// a & b & c: non-reference operators move (consume) the values
assert_eq!;
Minus and Complement
use ;
let a = ordmask!;
let b = ordmask!;
let c = ordmask!;
// &a - &b - &c: reference operators do not move (consume) the values
assert_eq!;
// a - b - c: non-reference operators move (consume) the values
assert_eq!;
let a = ordmask!;
// !&a: reference operator and `a.complement()` do not move (consume) the value
assert_eq!;
// !a: non-reference operator and `a.to_complement()` move (consume) the value
assert_eq!;
Symmetric Difference
use ;
let a = ordmask!;
let b = ordmask!;
// &a ^ &b: reference operators do not move (consume) the values
assert_eq!;
// a ^ b: non-reference operators move (consume) the values
assert_eq!;
Spans
OrdMask provides methods to iterate over included spans. Each span is returned as a tuple (start, end) representing a half-open interval [start, end).
Note:
- Using spans requires type
Tto implement theWithMaxtrait (the library provides implementations for all standard integer types).- Since spans are half-open intervals
[start, end), whetherMAXis included can be confusing. Use.is_max_value_included()to check if the maximum value is in the mask.
Basic Iteration
Use .spans() to iterate over included spans.
use ordmask;
// Empty mask has no spans
assert_eq!;
// Universal mask has one span [MIN, MAX]
assert_eq!;
// Single span [1, 2)
assert_eq!;
// Multiple spans: [MIN, 1) and [2, MAX]
assert_eq!;
Owning Iteration
Use .into_spans() to consume the mask and return an owning iterator:
use ordmask;
assert_eq!;
Span Count and Values Count
Use .spans_count() to get the number of spans in O(1) time without consuming an iterator.
It's equivalent to .spans().count() but more efficient.
Use .values_count() to get the total count of included values.
It supports lazy comparison without computing the full count.
use ordmask;
// Span count
assert_eq!; // [MIN, 10)
assert_eq!; // [MIN, 10), [20, MAX]
assert_eq!;
assert_eq!;
// Values count (lazy comparison)
// [0, 10)
assert!;
// [0, 10), [20, MAX]
assert!;
// Empty mask has count 0
assert!;
Warning: Calling
.values_count().get()may panic due to overflow when called on a universal mask (becauseMAX - MIN + 1overflows). Use.is_universal()to check before calling.get(). However, lazy comparisons (e.g.,values_count() < value) are safe because they can stop early without computing the full count.
Value Iteration
Use .values() and .into_values() to iterate over individual included values (rather than spans).
Note: Value iteration requires type
Tto implementstd::ops::Add<Output = T>andWithOne(in addition toWithMinandWithMax). The library provides implementations for all standard integer types.
use ordmask;
// [1, 4) contains values 1, 2, 3
assert_eq!;
// Multiple spans: [1, 3) and [5, 7)
assert_eq!;
// Using into_iter() consumes the mask
assert_eq!;
// For loop support
let mask = ordmask!;
let mut sum = 0;
for v in mask.values
assert_eq!;
Warning: For large masks (e.g., universal mask), value iteration can produce a huge number of values. Use with caution.
Type Requirements
OrdMask<T> requires T to implement the WithMin trait, a trait for types that have a minimum value. The library provides implementations for all standard integer types:
use WithMin;
// Built-in implementations for:
// u8, u16, u32, u64, u128, usize
// i8, i16, i32, i64, i128, isize
assert_eq!;
assert_eq!;
To use custom types, at minimum, implement WithMin to use OrdMask. And then:
.spans_count()is already implemented- To use
.spans()or.into_spans(), also implementWithMax - To use
.values()or.into_values(), also implement:WithMaxWithOnestd::ops::Add
- To use
.values_count(), also implement:WithMaxOrderedSub<Target = COUNT>, andCOUNTshould implement:WithZeroWithOnestd::ops::Add- [Optionally]
PartialOrdto use comparison operators withCOUNT
use *;
;
// Required implementation. Enables `.spans_count()`.
assert!;
// Enables `.spans()` and `.into_spans()`.
assert_eq!;
// Enables `.values_count()` and comparison operators with `COUNT`.
assert!;
// Enables `.values()` and `.into_values()`.
assert_eq!;