inter_val/
interval.rs

1use crate::bound_type::{Left, Right};
2use crate::traits::{BoundaryOf, Flip, IntoGeneral};
3use crate::{Bound, Exclusive, Inclusive, LeftBounded, RightBounded};
4
5/// Return type of `Interval::union()`.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct IntervalUnion<T, L: Flip, R: Flip> {
8    pub span: Interval<T, L, R>,
9    pub gap: Option<Interval<T, R::Flip, L::Flip>>,
10}
11impl<T, L: Flip, R: Flip> IntervalUnion<T, L, R> {
12    pub fn into_vec(self) -> Vec<Interval<T, L, R>> {
13        self.into_iter().collect()
14    }
15}
16impl<T, L: Flip, R: Flip> IntoIterator for IntervalUnion<T, L, R> {
17    type Item = Interval<T, L, R>;
18    type IntoIter = std::vec::IntoIter<Self::Item>;
19    fn into_iter(self) -> Self::IntoIter {
20        if let Some(gap) = self.gap {
21            let first = Interval {
22                left: self.span.left,
23                right: gap.left.flip(),
24            };
25            let second = Interval {
26                left: gap.right.flip(),
27                right: self.span.right,
28            };
29            vec![first, second].into_iter()
30        } else {
31            vec![self.span].into_iter()
32        }
33    }
34}
35
36/// Return type of `Interval::difference()`.
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub struct IntervalDifference<T, L: Flip, R: Flip> {
39    pub lower: Option<Interval<T, L, L::Flip>>,
40    pub upper: Option<Interval<T, R::Flip, R>>,
41}
42impl<T, L: Flip<Flip = R>, R: Flip<Flip = L>> IntervalDifference<T, L, R> {
43    pub fn into_vec(self) -> Vec<Interval<T, L, R>> {
44        self.into_iter().collect()
45    }
46}
47impl<T, L: Flip<Flip = R>, R: Flip<Flip = L>> IntoIterator for IntervalDifference<T, L, R> {
48    type Item = Interval<T, L, R>;
49    type IntoIter =
50        std::iter::Chain<std::option::IntoIter<Self::Item>, std::option::IntoIter<Self::Item>>;
51    fn into_iter(self) -> Self::IntoIter {
52        self.lower.into_iter().chain(self.upper)
53    }
54}
55
56fn is_valid_interval<T, L, R>(left: &LeftBounded<T, L>, right: &RightBounded<T, R>) -> bool
57where
58    T: PartialOrd,
59    L: BoundaryOf<Left>,
60    R: BoundaryOf<Right>,
61{
62    left.contains(&right.limit) && right.contains(&left.limit)
63}
64
65/// Interval like *[a, b]*, *(a, b)*, *[a, b)*, and *(a, b]* for any `PartialOrd` type.
66///
67/// * `T`: Numeric type bounding real number line. `T` should implements `PartialOrd`. `NaN` safety is not guaranteed when `T` is floating point type.
68/// * `L`: Left boundary type. Specify one of [`Inclusive`], [`Exclusive`], or [`BoundType`](crate::BoundType).
69/// * `R`: Right boundary type. Specify one of [`Inclusive`] [`Exclusive`], or [`BoundType`](crate::BoundType).
70/// * `Interval<T>` (= `Interval<T, Inclusive, Inclusive>`) represents a closed interval, i.e., *[a, b]*.
71/// * `Interval<T, Exclusive>` (= `Interval<T, Exclusive, Exclusive>`) represents a open interval, i.e., *(a, b)*.
72/// * `Interval<T, Inclusive, Exclusive>` represents a right half-open interval, i.e., *[a, b)*.
73/// * `Interval<T, Exclusive, Inclusive>` represents a left half-open interval, i.e., *(a, b]*.
74/// * `Interval<T, BoundType>` represents any of the above.
75///
76/// This type is considered as an interval on ℝ (real number line), even if an integer type is specified for `T`.
77///
78/// # Memory cost
79/// ```
80/// use inter_val::{Interval, Exclusive, Inclusive, BoundType};
81/// use std::mem::size_of;
82///
83/// // When bound type is statically determined, the size of the interval is just the size of two `T`.
84/// assert_eq!(size_of::<Interval<i32, Inclusive>>(), size_of::<i32>() * 2);
85/// assert_eq!(size_of::<Interval<f64, Exclusive>>(), size_of::<f64>() * 2);
86///
87/// // Size is larger when bound type is not statically determined.
88/// assert!(size_of::<Interval<i32, BoundType>>() >= (size_of::<i32>() + size_of::<BoundType>()) * 2);
89/// ```
90///
91/// # Properties
92/// ```txt
93/// lower_bound     left              . center          right    upper_bound
94/// ...------------>|<------- self -------------------->|<------------ ...
95///                 inf                                 sup
96///                 [<------------ closure ------------>]
97///                  (<----------- interior ---------->)
98/// ```
99///
100/// # Set operations
101/// ```txt
102/// |<------------- a ----------------->|   . p           |<-------- c -------->|
103///        |<--------------- b ------------------->|
104///        |<--- a.intersection(&b) --->|
105///                                     |<-- a.gap(&c) -->|
106/// |<------------- a.hull(p) ------------->|
107/// |<---------------------------------- a.span(&c) --------------------------->|
108/// |<--------------------------------->|        +        |<------------------->| a.union(&c)
109/// |<---->| a.difference(&b)
110///                                                |<- δ -+---- c.dilate(δ) ----+- δ ->|
111/// ```
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub struct Interval<T, L = Inclusive, R = L> {
114    pub(crate) left: LeftBounded<T, L>,
115    pub(crate) right: RightBounded<T, R>,
116}
117
118impl<T, L, R> Interval<T, L, R> {
119    pub fn left(&self) -> &LeftBounded<T, L> {
120        &self.left
121    }
122    pub fn right(&self) -> &RightBounded<T, R> {
123        &self.right
124    }
125}
126impl<T: PartialOrd, L: BoundaryOf<Left>, R: BoundaryOf<Right>> Interval<T, L, R> {
127    fn new_(left: LeftBounded<T, L>, right: RightBounded<T, R>) -> Option<Self> {
128        is_valid_interval(&left, &right).then_some(Self { left, right })
129    }
130
131    /// Try to create a new interval. Return `None` if the interval is empty.
132    /// ```
133    /// use std::any::{Any, TypeId};
134    /// use inter_val::{Interval, BoundType, Exclusive, Inclusive};
135    ///
136    /// let a: Interval<i32, Inclusive, Exclusive> = Interval::try_new(0.into(), 3.into()).unwrap();
137    /// assert!(a.contains(&0));
138    /// assert!(a.contains(&2));
139    /// assert!(!a.contains(&3));
140    ///
141    /// let a = Interval::try_new(Exclusive.at(0), Inclusive.at(3)).unwrap();
142    /// assert_eq!(a.type_id(), TypeId::of::<Interval<i32, Exclusive, Inclusive>>());
143    ///
144    /// let a = Interval::try_new(BoundType::Exclusive.at(0), BoundType::Exclusive.at(3)).unwrap();
145    /// assert_eq!(a.type_id(), TypeId::of::<Interval<i32, BoundType, BoundType>>());
146    ///
147    /// assert!(Interval::try_new(Inclusive.at(3), Exclusive.at(0)).is_none()); // [3, 0) is empty.
148    /// assert!(Interval::try_new(Inclusive.at(3), Exclusive.at(3)).is_none()); // [3, 3) is empty.
149    /// assert!(Interval::try_new(Inclusive.at(3), Inclusive.at(3)).is_some()); // [3, 3] is not empty.
150    /// assert!(Interval::try_new(Exclusive.at(0), Exclusive.at(1)).is_some()); // (0, 1) is not empty.
151    /// ```
152    pub fn try_new(left: Bound<T, L>, right: Bound<T, R>) -> Option<Self> {
153        Self::new_(left.into(), right.into())
154    }
155
156    /// Create a new interval. Panics if the interval is empty.
157    /// ```
158    /// use std::any::{Any, TypeId};
159    /// use inter_val::{Interval, BoundType, Exclusive, Inclusive};
160    ///
161    /// let a: Interval<i32, Inclusive, Exclusive> = Interval::new(0.into(), 3.into());
162    /// assert!(a.contains(&0));
163    /// assert!(a.contains(&2));
164    /// assert!(!a.contains(&3));
165    ///
166    /// let a = Interval::new(Exclusive.at(0), Inclusive.at(3));
167    /// assert_eq!(a.type_id(), TypeId::of::<Interval<i32, Exclusive, Inclusive>>());
168    ///
169    /// let a = Interval::new(BoundType::Exclusive.at(0), BoundType::Exclusive.at(3));
170    /// assert_eq!(a.type_id(), TypeId::of::<Interval<i32, BoundType, BoundType>>());
171    /// ```
172    ///
173    /// # Panics
174    /// ```should_panic
175    /// # use inter_val::{Interval, Exclusive, Inclusive};
176    /// Interval::new(Inclusive.at(3), Exclusive.at(0)); // [3, 0) is empty.
177    /// ```
178    /// ```should_panic
179    /// # use inter_val::{Interval, Exclusive, Inclusive};
180    /// Interval::new(Inclusive.at(3), Exclusive.at(3)); // [3, 3) is empty.
181    /// ```
182    pub fn new(left: Bound<T, L>, right: Bound<T, R>) -> Self {
183        Self::try_new(left, right).expect("Invalid interval: left must be less than right.")
184    }
185
186    /// ```
187    /// use inter_val::{Interval, Exclusive, Inclusive};
188    /// let a: Interval<i32, Inclusive, Exclusive> = Interval::try_between(-2, 5).unwrap();
189    /// assert_eq!(a, Inclusive.at(-2).to(Exclusive.at(5)));
190    ///
191    /// let a: Interval<i32, Inclusive, Exclusive> = Interval::try_between(3, -1).unwrap();
192    /// assert_eq!(a, Inclusive.at(-1).to(Exclusive.at(3))); // Swaps left and right.
193    ///
194    /// assert!(Interval::<i32, Inclusive, Exclusive>::try_between(1, 1).is_none()); // [1, 1) is empty.
195    /// assert!(Interval::<i32, Inclusive, Inclusive>::try_between(1, 1).is_some()); // [1, 1] is not empty.
196    /// ```
197    pub fn try_between(a: T, b: T) -> Option<Self>
198    where
199        T: Into<Bound<T, L>> + Into<Bound<T, R>>,
200    {
201        if a < b {
202            Self::try_new(a.into(), b.into())
203        } else {
204            Self::try_new(b.into(), a.into())
205        }
206    }
207
208    /// ```
209    /// use inter_val::{Interval, Exclusive, Inclusive};
210    /// let a: Interval<i32, Inclusive, Exclusive> = Interval::between(-2, 5);
211    /// assert_eq!(a, Inclusive.at(-2).to(Exclusive.at(5)));
212    ///
213    /// let a: Interval<i32, Inclusive, Exclusive> = Interval::between(3, -1);
214    /// assert_eq!(a, Inclusive.at(-1).to(Exclusive.at(3))); // Swaps left and right.
215    ///
216    /// // Closed interval (bounded by `Inclusive`) never panics.
217    /// Interval::<i32, Inclusive, Inclusive>::between(1, 1); // Doesn't panic since [1, 1] is not empty.
218    /// ```
219    /// ```should_panic
220    /// # use inter_val::{Interval, Exclusive, Inclusive};
221    /// Interval::<i32, Inclusive, Exclusive>::between(1, 1); // Panics since [1, 1) is empty.
222    /// ```
223    pub fn between(a: T, b: T) -> Self
224    where
225        T: Into<Bound<T, L>> + Into<Bound<T, R>>,
226    {
227        Self::try_between(a, b).unwrap()
228    }
229
230    /// Shorthand of `.left().limit`
231    /// ```
232    /// use inter_val::{Interval, Exclusive, Inclusive};
233    /// let a = Interval::new(Exclusive.at(-1.0), Inclusive.at(1.0));
234    /// assert_eq!(a.inf(), &-1.0);
235    /// assert_eq!(a.inf(), &a.left().limit);
236    /// assert!(!a.contains(&-1.0));
237    /// ```
238    pub fn inf(&self) -> &T {
239        self.left.inf()
240    }
241
242    /// Shorthand of `.right().limit`
243    /// ```
244    /// use inter_val::{Interval, Exclusive, Inclusive};
245    /// let a = Interval::new(Inclusive.at(-1.0), Exclusive.at(1.0));
246    /// assert_eq!(a.sup(), &1.0);
247    /// assert_eq!(a.sup(), &a.right().limit);
248    /// assert!(!a.contains(&1.0));
249    /// ```
250    pub fn sup(&self) -> &T {
251        self.right.sup()
252    }
253
254    pub fn closure(self) -> Interval<T, Inclusive> {
255        Interval {
256            left: self.left.closure(),
257            right: self.right.closure(),
258        }
259    }
260
261    pub fn interior(self) -> Option<Interval<T, Exclusive>> {
262        Interval::<_, Exclusive>::new_(self.left.interior(), self.right.interior())
263    }
264
265    /// ```
266    /// use inter_val::{Interval, Inclusive, Exclusive};
267    /// let a = Inclusive.at(4).to(Exclusive.at(7));
268    /// let b = Exclusive.at(1.23).to(Inclusive.at(4.56));
269    /// assert!(a.contains(&4));
270    /// assert!(!a.contains(&7));
271    /// assert!(!b.contains(&1.23));
272    /// assert!(b.contains(&1.230000000001));
273    /// assert!(b.contains(&4.56));
274    /// ```
275    pub fn contains(&self, t: &T) -> bool {
276        self.left.contains(t) && self.right.contains(t)
277    }
278
279    /// ```
280    /// use inter_val::{Inclusive, Exclusive};
281    /// let a = Inclusive.at(4).to(Exclusive.at(7));    // [4, 7)
282    /// assert_eq!(a.dilate(2), Inclusive.at(2).to(Exclusive.at(9)));   // [4-2, 7+2) = [2, 9)
283    /// assert_eq!(a.dilate(-1), Inclusive.at(5).to(Exclusive.at(6)));  // [4+1, 7-1) = [5, 6)
284    /// ```
285    /// ```should_panic
286    /// use inter_val::{Inclusive, Exclusive};
287    /// let a = Inclusive.at(4).to(Exclusive.at(7));    // [4, 7)
288    /// a.dilate(-2);   // panic! [4+2, 7-2) = [6, 5) is empty.
289    /// ```
290    pub fn dilate(self, delta: T) -> Self
291    where
292        T: Clone + std::ops::Add<Output = T> + std::ops::Sub<Output = T>,
293    {
294        Self::new_(self.left.dilate(delta.clone()), self.right.dilate(delta)).unwrap()
295    }
296
297    /// ```
298    /// use inter_val::{Interval, Inclusive, Exclusive};
299    /// let a = Inclusive.at(0).to(Exclusive.at(3));
300    /// let b = Inclusive.at(0).to(Exclusive.at(4));
301    /// let c = Inclusive.at(1).to(Exclusive.at(4));
302    /// assert!(a.includes(&a));
303    /// assert!(!a.includes(&b) && b.includes(&a));
304    /// assert!(!a.includes(&c) && !c.includes(&a));
305    /// ```
306    pub fn includes(&self, other: &Self) -> bool {
307        self.left.includes(&other.left) && self.right.includes(&other.right)
308    }
309
310    /// ```
311    /// use inter_val::{Interval, Inclusive, Exclusive};
312    /// let a = Inclusive.at(0).to(Exclusive.at(3));
313    /// let b = Inclusive.at(1).to(Exclusive.at(4));
314    /// let c = Inclusive.at(3).to(Exclusive.at(5));
315    /// assert!(a.overlaps(&a));
316    /// assert!(a.overlaps(&b) && b.overlaps(&a));
317    /// assert!(!a.overlaps(&c) && !c.overlaps(&a));
318    /// ```
319    pub fn overlaps(&self, other: &Self) -> bool {
320        let left = crate::half::partial_max(&self.left, &other.left);
321        let right = crate::half::partial_min(&self.right, &other.right);
322        is_valid_interval(left, right)
323    }
324
325    /// ```
326    /// use inter_val::{Interval, Inclusive, Exclusive};
327    /// let a = Inclusive.at(0).to(Exclusive.at(3));
328    /// let b = Inclusive.at(1).to(Exclusive.at(4));
329    /// let c = Inclusive.at(3).to(Exclusive.at(5));
330    /// assert_eq!(a.intersection(&a), Some(a));
331    /// assert_eq!(a.intersection(&b), Some(Inclusive.at(1).to(Exclusive.at(3))));
332    /// assert_eq!(a.intersection(&c), None);
333    /// ```
334    pub fn intersection(&self, other: &Self) -> Option<Self>
335    where
336        T: Clone,
337    {
338        Self::new_(
339            self.left.intersection(&other.left).clone(),
340            self.right.intersection(&other.right).clone(),
341        )
342    }
343
344    /// ```
345    /// use inter_val::{Interval, Inclusive, Exclusive};
346    /// let a = Inclusive.at(0).to(Exclusive.at(3));
347    /// let b = Inclusive.at(5).to(Exclusive.at(8));
348    /// assert_eq!(a.span(&b), Inclusive.at(0).to(Exclusive.at(8)));
349    /// ```
350    pub fn span(&self, other: &Self) -> Self
351    where
352        T: Clone,
353    {
354        Self {
355            left: self.left.union(&other.left).clone(),
356            right: self.right.union(&other.right).clone(),
357        }
358    }
359
360    /// ```
361    /// use inter_val::{Interval, Inclusive, Exclusive};
362    /// let a = Inclusive.at(0).to(Exclusive.at(3));
363    /// assert_eq!(a.hull(-2), Inclusive.at(-2).to(Exclusive.at(3)));
364    /// assert_eq!(a.hull(5), Inclusive.at(0).to(Exclusive.at(5)));
365    /// ```
366    pub fn hull(self, t: T) -> Self
367    where
368        T: Clone,
369    {
370        Self {
371            left: self.left.hull(t.clone()),
372            right: self.right.hull(t),
373        }
374    }
375
376    /// ```
377    /// use inter_val::{Interval, Inclusive, Exclusive};
378    /// let a = Inclusive.at(0).to(Exclusive.at(3));
379    /// let b = Inclusive.at(5).to(Exclusive.at(8));
380    /// assert_eq!(a.gap(&b).unwrap(), Inclusive.at(3).to(Exclusive.at(5)));
381    /// ```
382    pub fn gap(&self, other: &Self) -> Option<Interval<T, R::Flip, L::Flip>>
383    where
384        T: Clone,
385        L::Flip: BoundaryOf<Right>,
386        R::Flip: BoundaryOf<Left>,
387    {
388        Interval::new_(self.right.clone().flip(), other.left.clone().flip())
389            .or_else(|| Interval::new_(other.right.clone().flip(), self.left.clone().flip()))
390    }
391
392    /// ```
393    /// use inter_val::{Interval, Inclusive, Exclusive};
394    /// let a = Inclusive.at(0).to(Exclusive.at(3));
395    /// let b = Inclusive.at(5).to(Exclusive.at(8));
396    /// let union = a.union(&b);
397    /// assert_eq!(union.span, a.span(&b));
398    /// assert_eq!(union.gap, a.gap(&b));
399    /// let union_ints: Vec<Interval<_, _, _>> = union.into_iter().collect();
400    /// assert_eq!(union_ints.len(), 2);
401    /// assert_eq!(union_ints[0], a);
402    /// assert_eq!(union_ints[1], b);
403    /// ```
404    pub fn union(&self, other: &Self) -> IntervalUnion<T, L, R>
405    where
406        T: Clone,
407        L::Flip: BoundaryOf<Right>,
408        R::Flip: BoundaryOf<Left>,
409    {
410        IntervalUnion {
411            gap: self.gap(other),
412            span: self.span(other),
413        }
414    }
415
416    pub fn lower_bound(&self) -> RightBounded<T, L::Flip>
417    where
418        T: Clone,
419    {
420        self.left.clone().flip()
421    }
422
423    pub fn upper_bound(&self) -> LeftBounded<T, R::Flip>
424    where
425        T: Clone,
426    {
427        self.right.clone().flip()
428    }
429
430    /// ```
431    /// use inter_val::{Interval, Inclusive, Exclusive};
432    /// let a = Inclusive.at(2.1).to(Inclusive.at(5.3));
433    /// assert_eq!(a.measure(), 5.3 - 2.1);
434    ///
435    /// let a = Exclusive.at(0).to(Exclusive.at(1));    // (0, 1)
436    /// assert_eq!(a.measure(), 1);
437    /// ```
438    pub fn measure(&self) -> T
439    where
440        T: Clone + std::ops::Sub<Output = T>,
441    {
442        self.sup().clone() - self.inf().clone()
443    }
444
445    /// ```
446    /// use inter_val::{Inclusive, Exclusive};
447    /// let a = Exclusive.at(10).to(Inclusive.at(20)); // (10, 20]
448    /// assert!(a.step_by(2).eq(vec![12, 14, 16, 18, 20]));
449    /// ```
450    pub fn step_by(&self, step: T) -> impl Iterator<Item = T> + '_
451    where
452        T: Clone,
453        for<'a> T: std::ops::AddAssign<&'a T>,
454    {
455        self.left
456            .step_by(step)
457            .take_while(|t| self.right.contains(t))
458    }
459
460    /// ```
461    /// use inter_val::{Inclusive, Exclusive};
462    /// let a = Exclusive.at(10).to(Inclusive.at(20)); // (10, 20]
463    /// assert!(a.step_rev_by(2).eq(vec![20, 18, 16, 14, 12]));
464    /// ```
465    pub fn step_rev_by(&self, step: T) -> impl Iterator<Item = T> + '_
466    where
467        T: Clone,
468        for<'a> T: std::ops::SubAssign<&'a T>,
469    {
470        self.right
471            .step_rev_by(step)
472            .take_while(|t| self.left.contains(t))
473    }
474
475    /// ```
476    /// use inter_val::{Interval, Inclusive, Exclusive, Nullable};
477    /// let a = Inclusive.at(0).to(Exclusive.at(3));  // [0, 3)
478    /// let b = Inclusive.at(1).to(Exclusive.at(5));  // [1, 5)
479    /// let c = Inclusive.at(8).to(Exclusive.at(10)); // [8, 10)
480    /// let span = Interval::span_many(vec![a, b, c]).unwrap(); // [0, 10)
481    /// assert_eq!(span.left().limit, 0);
482    /// assert_eq!(span.right().limit, 10);
483    ///
484    /// // Sum for Nullable<Interval> can be used as well.
485    /// let sum: Nullable<Interval<_, _, _>> = vec![a, b, c].into_iter().sum();
486    /// assert_eq!(sum.unwrap(), span);
487    /// ```
488    pub fn span_many<A: std::borrow::Borrow<Self>>(
489        items: impl IntoIterator<Item = A>,
490    ) -> Option<Self>
491    where
492        T: Clone,
493    {
494        let mut items = items.into_iter();
495        let first = items.next()?.borrow().clone();
496        Some(items.fold(first, |acc, item| acc.span(item.borrow())))
497    }
498
499    /// ```
500    /// use inter_val::{Interval, Nullable};
501    /// let hull = Interval::<_>::hull_many(vec![3, 9, 2, 5]).unwrap(); // [2, 9]
502    /// assert_eq!(hull.inf(), &2);
503    /// assert_eq!(hull.sup(), &9);
504    ///
505    /// let hull = Interval::<_>::hull_many(vec![3.1, 9.2, 2.3, 5.4]).unwrap(); // [2.3, 9.2]
506    /// assert_eq!(hull.inf(), &2.3);
507    /// assert_eq!(hull.sup(), &9.2);
508    ///
509    /// // Sum for Nullable<Interval> can be used as well.
510    /// let a: Nullable<Interval<i32>> = vec![1, 6, 2, 8, 3].into_iter().sum();
511    /// assert_eq!(a.unwrap(), Interval::between(1, 8));
512    /// ```
513    pub fn hull_many(items: impl IntoIterator<Item = T>) -> Option<Self>
514    where
515        T: Clone + Into<Bound<T, L>> + Into<Bound<T, R>>,
516    {
517        let mut items = items.into_iter();
518        let mut left = items.next()?;
519        let mut right = left.clone();
520        for x in items {
521            if x < left {
522                left = x;
523            } else if right < x {
524                right = x;
525            }
526        }
527        Self::try_new(left.into(), right.into())
528    }
529}
530
531impl<T: PartialOrd, L: BoundaryOf<Left, Flip = R>, R: BoundaryOf<Right, Flip = L>>
532    Interval<T, L, R>
533{
534    /// Difference is defined only for `Interval<T, Inclusive, Exclusive>`, `Interval<T, Exclusive, Inclusive>`, and `Interval<T, BoundType>`.
535    /// ```
536    /// use inter_val::{Interval, Inclusive, Exclusive};
537    /// let a = Inclusive.at(0).to(Exclusive.at(3));
538    /// let b = Inclusive.at(1).to(Exclusive.at(4));
539    /// let diff = a.difference(&b);
540    /// assert!(diff.lower.is_some() && diff.upper.is_none());
541    /// assert_eq!(diff.lower.unwrap(), Inclusive.at(0).to(Exclusive.at(1)));
542    /// assert_eq!(diff.into_iter().collect::<Vec<_>>().len(), 1);
543    /// ```
544    pub fn difference(&self, other: &Self) -> IntervalDifference<T, L, R>
545    where
546        T: Clone,
547    {
548        IntervalDifference {
549            lower: Self::new_(self.left.clone(), other.lower_bound()),
550            upper: Self::new_(other.upper_bound(), self.right.clone()),
551        }
552    }
553}
554
555impl<T: PartialOrd + Clone> Interval<T, Inclusive, Exclusive> {
556    /// ```
557    /// use inter_val::{Inclusive, Exclusive};
558    /// let a = Inclusive.at(0).to(Exclusive.at(3));    // [0, 3)
559    /// let (b, c) = a.try_split_at(1); // [0, 1) and [1, 3)
560    /// assert_eq!(b, Some(Inclusive.at(0).to(Exclusive.at(1))));
561    /// assert_eq!(c, Some(Inclusive.at(1).to(Exclusive.at(3))));
562    ///
563    /// let (b, c) = a.try_split_at(0);
564    /// assert_eq!(b, None);    // [0, 0) is empty.
565    /// assert_eq!(c, Some(a)); // [0, 3)
566    /// ```
567    pub fn try_split_at(&self, t: T) -> (Option<Self>, Option<Self>) {
568        if !self.left.contains(&t) {
569            return (None, Some(self.clone()));
570        }
571        if !self.right.contains(&t) {
572            return (Some(self.clone()), None);
573        }
574        let lower = Self::new_(self.left.clone(), Exclusive.at(t.clone()).into());
575        let upper = Self::new_(Inclusive.at(t).into(), self.right.clone());
576        (lower, upper)
577    }
578
579    /// ```
580    /// use inter_val::{Inclusive, Exclusive};
581    /// let a = Inclusive.at(0).to(Exclusive.at(3));    // [0, 3)
582    /// let (b, c) = a.split_at(1); // [0, 1) and [1, 3)
583    /// assert_eq!(b, Inclusive.at(0).to(Exclusive.at(1)));
584    /// assert_eq!(c, Inclusive.at(1).to(Exclusive.at(3)));
585    /// ```
586    /// ```should_panic
587    /// use inter_val::{Inclusive, Exclusive};
588    /// let a = Inclusive.at(0).to(Exclusive.at(3));    // [0, 3)
589    /// let (b, c) = a.split_at(0);
590    /// ```
591    pub fn split_at(&self, t: T) -> (Self, Self) {
592        assert!(self.contains(&t));
593        let lower = Self::new_(self.left.clone(), Exclusive.at(t.clone()).into());
594        let upper = Self::new_(Inclusive.at(t).into(), self.right.clone());
595        (lower.unwrap(), upper.unwrap())
596    }
597}
598
599impl<T: num::Float, L: BoundaryOf<Left>, R: BoundaryOf<Right>> Interval<T, L, R> {
600    /// ```
601    /// use inter_val::{Interval, Inclusive};
602    /// let a = Inclusive.at(2.1).to(Inclusive.at(5.3));
603    /// assert_eq!(a.center(), (2.1 + 5.3) / 2.0);
604    /// ```
605    pub fn center(&self) -> T {
606        (self.left.limit + self.right.limit) / (T::one() + T::one())
607    }
608
609    /// IoU - Intersection over Union.
610    /// ```
611    /// use inter_val::{Interval, Inclusive};
612    /// let a = Inclusive.at(0.0).to(Inclusive.at(1.0));
613    /// let b = Inclusive.at(0.0).to(Inclusive.at(2.0));
614    /// let c = Inclusive.at(1.0).to(Inclusive.at(2.0));
615    /// assert_eq!(a.iou(&a), 1.0);
616    /// assert_eq!(a.iou(&b), 0.5);
617    /// assert_eq!(a.iou(&c), 0.0);
618    /// ```
619    pub fn iou(&self, other: &Self) -> T {
620        self.intersection(other)
621            .map(|intersection| {
622                let union = self.span(other);
623                intersection.measure() / union.measure()
624            })
625            .unwrap_or(T::zero())
626    }
627
628    /// Linear interpolation.
629    /// ```
630    /// use inter_val::{Interval, Inclusive, Exclusive};
631    /// let a = Inclusive.at(2.0).to(Inclusive.at(4.0));    // [2, 4]
632    /// assert_eq!(a.lerp(0.0), 2.0);
633    /// assert_eq!(a.lerp(0.5), 3.0);
634    /// assert_eq!(a.lerp(1.0), 4.0);
635    /// assert_eq!(a.lerp(1.1), 4.2);
636    /// ```
637    pub fn lerp(&self, ratio: T) -> T {
638        (T::one() - ratio) * *self.inf() + ratio * *self.sup()
639    }
640
641    /// ```
642    /// use inter_val::{Interval, Inclusive, Exclusive};
643    /// let a = Inclusive.at(2.0).to(Inclusive.at(4.0));    // [2, 4]
644    /// let b = Inclusive.at(2.0).to(Exclusive.at(4.0));    // [2, 4)
645    /// let c = Exclusive.at(2.0).to(Inclusive.at(4.0));    // (2, 4]
646    /// assert!(a.step_uniform(4).eq(vec![2.0, 2.5, 3.0, 3.5, 4.0]));
647    /// assert!(b.step_uniform(4).eq(vec![2.0, 2.5, 3.0, 3.5]));
648    /// assert!(c.step_uniform(4).eq(vec![2.5, 3.0, 3.5, 4.0]));
649    /// ```
650    pub fn step_uniform(&self, n: usize) -> impl Iterator<Item = T> + '_ {
651        let step = self.measure() / T::from(n).unwrap();
652        let (mut i, mut t) = if self.left.bound_type.is_inclusive() {
653            (0, *self.inf())
654        } else {
655            (1, *self.inf() + step)
656        };
657        let last = if self.right.bound_type.is_inclusive() {
658            n
659        } else {
660            n - 1
661        };
662        std::iter::from_fn(move || {
663            let ret = (i <= last).then_some(t);
664            t = if i == n { *self.sup() } else { t + step };
665            i += 1;
666            ret
667        })
668    }
669}
670
671impl<T, L, R> Interval<T, L, R> {
672    /// Cast by `From<T>`.
673    /// ```
674    /// use inter_val::{Interval, Exclusive};
675    /// let src: Interval<i32, Exclusive> = Interval::between(0, 1);  // open interval (0, 1)
676    /// let dst = src.cast::<f64>();
677    /// assert!(dst.contains(&0.5));
678    /// ```
679    pub fn cast<U: From<T>>(self) -> Interval<U, L, R> {
680        Interval {
681            left: self.left.cast(),
682            right: self.right.cast(),
683        }
684    }
685}
686
687impl<T: num::NumCast, L, R> Interval<T, L, R> {
688    /// Cast by `num::NumCast`.
689    /// ```
690    /// use inter_val::{Interval, Exclusive};
691    /// let src: Interval<f64> = Interval::between(1.2, 7.8);  // closed interval [1.2, 7.8]
692    /// let dst = src.try_cast::<i32>().unwrap();
693    /// assert_eq!(dst.inf(), &1);
694    /// assert_eq!(dst.sup(), &7);
695    /// ```
696    pub fn try_cast<U: num::NumCast>(self) -> Option<Interval<U, L, R>> {
697        Some(Interval {
698            left: self.left.try_cast()?,
699            right: self.right.try_cast()?,
700        })
701    }
702}
703
704impl<T, L: IntoGeneral, R: IntoGeneral> IntoGeneral for Interval<T, L, R> {
705    type General = Interval<T, L::General, R::General>;
706    fn into_general(self) -> Self::General {
707        Interval {
708            left: self.left.into_general(),
709            right: self.right.into_general(),
710        }
711    }
712}
713
714/// ```
715/// use inter_val::{Interval, Exclusive, Inclusive, BoundType};
716///
717/// // Iterate Interval<i32, Exclusive, Inclusive>
718/// let items: Vec<_> = Exclusive.at(0).to(Inclusive.at(10)).into_iter().collect();
719/// assert_eq!(items.len(), 10);
720/// assert_eq!(items[0], 1);
721/// assert_eq!(items.last().unwrap(), &10);
722///
723/// // Iterate Interval<i32, BoundType, BoundType>
724/// let items: Vec<_> = (BoundType::Exclusive.at(0).to(BoundType::Inclusive.at(10)))
725///     .into_iter()
726///     .collect();
727/// assert_eq!(items.len(), 10);
728/// assert_eq!(items[0], 1);
729/// assert_eq!(items.last().unwrap(), &10);
730/// ```
731impl<T, L, R> IntoIterator for Interval<T, L, R>
732where
733    std::ops::RangeInclusive<T>: Iterator<Item = T>,
734    T: num::Integer + Clone,
735    L: BoundaryOf<Left>,
736    R: BoundaryOf<Right>,
737    for<'a> T: std::ops::AddAssign<&'a T> + std::ops::SubAssign<&'a T>,
738{
739    type Item = T;
740    type IntoIter = std::ops::RangeInclusive<T>;
741    fn into_iter(self) -> Self::IntoIter {
742        let first = self.left.step_by(T::one()).next().unwrap();
743        let last = self.right.step_rev_by(T::one()).next().unwrap();
744        first..=last
745    }
746}