1#![cfg_attr(not(test), no_std)]
59#![forbid(unsafe_code)]
60#![warn(missing_docs)]
61
62use core::borrow::Borrow;
63use core::cmp::Ordering;
64use core::ops::{Bound, RangeBounds};
65
66#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
69pub enum RangeOrdering {
70 Below,
72 Inside,
74 Above,
76 Empty,
79}
80
81#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
88pub enum BoundOrdering {
89 Within,
91 Outside,
93 Incomparable,
96}
97
98#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
106pub struct RangePosition {
107 pub lower: BoundOrdering,
110 pub upper: BoundOrdering,
113}
114
115impl RangePosition {
116 pub fn is_inside(&self) -> bool {
124 self.lower == BoundOrdering::Within && self.upper == BoundOrdering::Within
125 }
126
127 pub fn ordering(&self) -> Option<RangeOrdering> {
138 match (self.lower, self.upper) {
139 (BoundOrdering::Within, BoundOrdering::Within) => Some(RangeOrdering::Inside),
140 (BoundOrdering::Outside, BoundOrdering::Within) => Some(RangeOrdering::Below),
141 (BoundOrdering::Within, BoundOrdering::Outside) => Some(RangeOrdering::Above),
142 (BoundOrdering::Outside, BoundOrdering::Outside) => Some(RangeOrdering::Empty),
143 _ => None,
144 }
145 }
146}
147
148fn lower_ordering<T: PartialOrd>(value: &T, bound: Bound<&T>) -> BoundOrdering {
150 match bound {
151 Bound::Unbounded => BoundOrdering::Within,
152 Bound::Included(key) => match value.partial_cmp(key) {
153 Some(Ordering::Less) => BoundOrdering::Outside,
154 Some(Ordering::Equal) | Some(Ordering::Greater) => BoundOrdering::Within,
155 None => BoundOrdering::Incomparable,
156 },
157 Bound::Excluded(key) => match value.partial_cmp(key) {
158 Some(Ordering::Less) | Some(Ordering::Equal) => BoundOrdering::Outside,
159 Some(Ordering::Greater) => BoundOrdering::Within,
160 None => BoundOrdering::Incomparable,
161 },
162 }
163}
164
165fn upper_ordering<T: PartialOrd>(value: &T, bound: Bound<&T>) -> BoundOrdering {
167 match bound {
168 Bound::Unbounded => BoundOrdering::Within,
169 Bound::Included(key) => match value.partial_cmp(key) {
170 Some(Ordering::Greater) => BoundOrdering::Outside,
171 Some(Ordering::Equal) | Some(Ordering::Less) => BoundOrdering::Within,
172 None => BoundOrdering::Incomparable,
173 },
174 Bound::Excluded(key) => match value.partial_cmp(key) {
175 Some(Ordering::Greater) | Some(Ordering::Equal) => BoundOrdering::Outside,
176 Some(Ordering::Less) => BoundOrdering::Within,
177 None => BoundOrdering::Incomparable,
178 },
179 }
180}
181
182fn position_in<T: PartialOrd, R: RangeBounds<T>>(value: &T, range: &R) -> RangePosition {
184 RangePosition {
185 lower: lower_ordering(value, range.start_bound()),
186 upper: upper_ordering(value, range.end_bound()),
187 }
188}
189
190fn range_is_empty<T: Ord, R: RangeBounds<T>>(range: &R) -> bool {
193 match (range.start_bound(), range.end_bound()) {
194 (Bound::Included(start), Bound::Included(end)) => start > end,
195 (Bound::Included(start), Bound::Excluded(end))
196 | (Bound::Excluded(start), Bound::Included(end))
197 | (Bound::Excluded(start), Bound::Excluded(end)) => start >= end,
198 _ => false,
199 }
200}
201
202pub trait BorrowRange<T: ?Sized, R>: Borrow<R> {}
253impl<T, R: RangeBounds<T>> BorrowRange<T, R> for R {}
254impl<T, R: RangeBounds<T>> BorrowRange<T, R> for &R {}
255
256pub trait RangeOrd {
260 fn rcmp<R: RangeBounds<Self>, B: BorrowRange<Self, R>>(&self, range: B) -> RangeOrdering;
271}
272
273impl<T: Ord> RangeOrd for T {
274 fn rcmp<R: RangeBounds<Self>, B: BorrowRange<Self, R>>(&self, range: B) -> RangeOrdering {
275 let range = range.borrow();
276 if range_is_empty(range) {
277 return RangeOrdering::Empty;
278 }
279 position_in(self, range)
282 .ordering()
283 .expect("a total order over a non-empty range always yields a verdict")
284 }
285}
286
287pub trait PartialRangeOrd {
291 fn partial_rcmp<R: RangeBounds<Self>, B: BorrowRange<Self, R>>(
306 &self,
307 range: B,
308 ) -> RangePosition;
309}
310
311impl<T: PartialOrd> PartialRangeOrd for T {
312 fn partial_rcmp<R: RangeBounds<Self>, B: BorrowRange<Self, R>>(
313 &self,
314 range: B,
315 ) -> RangePosition {
316 position_in(self, range.borrow())
317 }
318}
319
320#[cfg(test)]
321mod rcmp_tests {
322 use super::*;
323
324 #[test]
325 fn range_full() {
326 assert_eq!(1.rcmp(..), RangeOrdering::Inside);
328 }
329
330 #[test]
331 fn range_from() {
332 assert_eq!(1.rcmp(1..), RangeOrdering::Inside);
334 assert_eq!(1.rcmp(&1..), RangeOrdering::Inside);
335
336 assert_eq!(1.rcmp(2..), RangeOrdering::Below);
338 assert_eq!(1.rcmp(&2..), RangeOrdering::Below);
339 }
340
341 #[test]
342 fn range_to() {
343 assert_eq!(1.rcmp(..1), RangeOrdering::Above);
345 assert_eq!(1.rcmp(..&1), RangeOrdering::Above);
346
347 assert_eq!(1.rcmp(..2), RangeOrdering::Inside);
349 assert_eq!(1.rcmp(..&2), RangeOrdering::Inside);
350 }
351
352 #[test]
353 fn range() {
354 assert_eq!(1.rcmp(0..1), RangeOrdering::Above);
356 assert_eq!(1.rcmp(&0..&1), RangeOrdering::Above);
357
358 assert_eq!(1.rcmp(1..2), RangeOrdering::Inside);
360 assert_eq!(1.rcmp(&1..&2), RangeOrdering::Inside);
361
362 assert_eq!(1.rcmp(2..3), RangeOrdering::Below);
364 assert_eq!(1.rcmp(&2..&3), RangeOrdering::Below);
365 }
366
367 #[test]
368 fn range_inclusive() {
369 assert_eq!(1.rcmp(0..=0), RangeOrdering::Above);
371 assert_eq!(1.rcmp(&0..=&0), RangeOrdering::Above);
372
373 assert_eq!(1.rcmp(1..=1), RangeOrdering::Inside);
375 assert_eq!(1.rcmp(&1..=&1), RangeOrdering::Inside);
376
377 assert_eq!(1.rcmp(2..=2), RangeOrdering::Below);
379 assert_eq!(1.rcmp(&2..=&2), RangeOrdering::Below);
380 }
381
382 #[test]
383 fn range_to_inclusive() {
384 assert_eq!(1.rcmp(..=0), RangeOrdering::Above);
386 assert_eq!(1.rcmp(..=&0), RangeOrdering::Above);
387
388 assert_eq!(1.rcmp(..=1), RangeOrdering::Inside);
390 assert_eq!(1.rcmp(..=&1), RangeOrdering::Inside);
391 }
392
393 #[test]
394 fn bounds_full() {
395 let bounds: (Bound<i32>, Bound<i32>) = (Bound::Unbounded, Bound::Unbounded);
397 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
398 }
399
400 #[test]
401 fn bounds_from() {
402 let bounds = (Bound::Included(1), Bound::Unbounded);
404 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
405
406 let bounds = (Bound::Included(&1), Bound::Unbounded);
407 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
408
409 let bounds = (Bound::Included(2), Bound::Unbounded);
411 assert_eq!(1.rcmp(bounds), RangeOrdering::Below);
412
413 let bounds = (Bound::Included(&2), Bound::Unbounded);
414 assert_eq!(1.rcmp(bounds), RangeOrdering::Below);
415 }
416
417 #[test]
418 fn bounds_to() {
419 let bounds = (Bound::Unbounded, Bound::Excluded(1));
421 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
422
423 let bounds = (Bound::Unbounded, Bound::Excluded(&1));
424 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
425
426 let bounds = (Bound::Unbounded, Bound::Excluded(2));
428 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
429
430 let bounds = (Bound::Unbounded, Bound::Excluded(&2));
431 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
432 }
433
434 #[test]
435 fn bounds() {
436 let bounds = (Bound::Included(0), Bound::Excluded(1));
438 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
439
440 let bounds = (Bound::Included(&0), Bound::Excluded(&1));
441 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
442
443 let bounds = (Bound::Included(1), Bound::Excluded(2));
445 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
446
447 let bounds = (Bound::Included(&1), Bound::Excluded(&2));
448 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
449
450 let bounds = (Bound::Included(2), Bound::Excluded(3));
452 assert_eq!(1.rcmp(bounds), RangeOrdering::Below);
453
454 let bounds = (Bound::Included(&2), Bound::Excluded(&3));
455 assert_eq!(1.rcmp(bounds), RangeOrdering::Below);
456 }
457
458 #[test]
459 fn bounds_inclusive() {
460 let bounds = (Bound::Included(0), Bound::Included(0));
462 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
463
464 let bounds = (Bound::Included(&0), Bound::Included(&0));
465 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
466
467 let bounds = (Bound::Included(1), Bound::Included(1));
469 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
470
471 let bounds = (Bound::Included(&1), Bound::Included(&1));
472 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
473
474 let bounds = (Bound::Included(2), Bound::Included(2));
476 assert_eq!(1.rcmp(bounds), RangeOrdering::Below);
477
478 let bounds = (Bound::Included(&2), Bound::Included(&2));
479 assert_eq!(1.rcmp(bounds), RangeOrdering::Below);
480 }
481
482 #[test]
483 fn bounds_to_inclusive() {
484 let bounds = (Bound::Unbounded, Bound::Included(0));
486 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
487
488 let bounds = (Bound::Unbounded, Bound::Included(&0));
489 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
490
491 let bounds = (Bound::Unbounded, Bound::Included(1));
493 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
494
495 let bounds = (Bound::Unbounded, Bound::Included(&1));
496 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
497 }
498
499 #[test]
500 fn bounds_exclusive_inclusive() {
501 let bounds: (Bound<i32>, Bound<i32>) = (Bound::Excluded(-1), Bound::Included(0));
503 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
504
505 let bounds: (Bound<&i32>, Bound<&i32>) = (Bound::Excluded(&-1), Bound::Included(&0));
506 assert_eq!(1.rcmp(bounds), RangeOrdering::Above);
507
508 let bounds: (Bound<i32>, Bound<i32>) = (Bound::Excluded(0), Bound::Included(1));
510 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
511
512 let bounds: (Bound<&i32>, Bound<&i32>) = (Bound::Excluded(&0), Bound::Included(&1));
513 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
514
515 let bounds: (Bound<i32>, Bound<i32>) = (Bound::Excluded(1), Bound::Included(2));
517 assert_eq!(1.rcmp(bounds), RangeOrdering::Below);
518
519 let bounds: (Bound<&i32>, Bound<&i32>) = (Bound::Excluded(&1), Bound::Included(&2));
520 assert_eq!(1.rcmp(bounds), RangeOrdering::Below);
521 }
522
523 #[test]
524 fn bounds_as_reference() {
525 let bounds = 0..2;
526 assert_eq!(1.rcmp(&bounds), RangeOrdering::Inside);
527 assert_eq!(1.rcmp(bounds), RangeOrdering::Inside);
528 }
529
530 #[test]
531 #[allow(clippy::reversed_empty_ranges)] fn empty_ranges() {
533 assert_eq!(0.rcmp(0..0), RangeOrdering::Empty);
535 assert_eq!(0.rcmp(&0..&0), RangeOrdering::Empty);
536
537 assert_eq!(0.rcmp(..0u32), RangeOrdering::Above);
540 assert_eq!(0.rcmp(..&0u32), RangeOrdering::Above);
541
542 assert_eq!(30.rcmp(45..35), RangeOrdering::Empty);
544 assert_eq!(30.rcmp(&45..&35), RangeOrdering::Empty);
545
546 assert_eq!(30.rcmp(25..15), RangeOrdering::Empty);
548 assert_eq!(30.rcmp(&25..&15), RangeOrdering::Empty);
549
550 assert_eq!(0.rcmp(0..=0), RangeOrdering::Inside);
552 assert_eq!(1.rcmp(0..=0), RangeOrdering::Above);
553 }
554}
555
556#[cfg(test)]
557mod partial_rcmp_tests {
558 use super::*;
559
560 #[derive(Clone, Copy, Debug, PartialEq)]
564 struct Div(i32);
565
566 impl PartialOrd for Div {
567 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
568 let a_s = self.0.abs();
569 let a_o = other.0.abs();
570
571 match a_s.cmp(&a_o) {
572 Ordering::Less if a_o % a_s == 0 => Some(Ordering::Less),
573 Ordering::Greater if a_s % a_o == 0 => Some(Ordering::Greater),
574 Ordering::Equal => Some(Ordering::Equal),
575 _ => None,
576 }
577 }
578 }
579
580 const W: BoundOrdering = BoundOrdering::Within;
582 const O: BoundOrdering = BoundOrdering::Outside;
583 const I: BoundOrdering = BoundOrdering::Incomparable;
584
585 fn pos(lower: BoundOrdering, upper: BoundOrdering) -> RangePosition {
586 RangePosition { lower, upper }
587 }
588
589 #[test]
590 fn range_full() {
591 assert_eq!(Div(1).partial_rcmp(..), pos(W, W));
593 assert_eq!(
594 Div(1).partial_rcmp(..).ordering(),
595 Some(RangeOrdering::Inside)
596 );
597 }
598
599 #[test]
600 fn range_from() {
601 assert_eq!(Div(1).partial_rcmp(Div(1)..), pos(W, W));
603 assert_eq!(Div(1).partial_rcmp(&Div(1)..), pos(W, W));
604
605 assert_eq!(Div(1).partial_rcmp(Div(2)..), pos(O, W));
607 assert_eq!(Div(1).partial_rcmp(&Div(2)..), pos(O, W));
608
609 assert_eq!(Div(2).partial_rcmp(Div(3)..), pos(I, W));
611 assert_eq!(Div(2).partial_rcmp(&Div(3)..), pos(I, W));
612 assert_eq!(Div(2).partial_rcmp(Div(3)..).ordering(), None);
613 }
614
615 #[test]
616 fn range_to() {
617 assert_eq!(Div(4).partial_rcmp(..Div(2)), pos(W, O));
619 assert_eq!(Div(4).partial_rcmp(..&Div(2)), pos(W, O));
620
621 assert_eq!(Div(1).partial_rcmp(..Div(2)), pos(W, W));
623 assert_eq!(Div(1).partial_rcmp(..&Div(2)), pos(W, W));
624
625 assert_eq!(Div(3).partial_rcmp(..Div(10)), pos(W, I));
627 assert_eq!(Div(3).partial_rcmp(..&Div(10)), pos(W, I));
628 assert_eq!(Div(3).partial_rcmp(..Div(10)).ordering(), None);
629 }
630
631 #[test]
632 fn range() {
633 assert_eq!(Div(3).partial_rcmp(Div(1)..Div(3)), pos(W, O));
635 assert_eq!(Div(3).partial_rcmp(&Div(1)..&Div(3)), pos(W, O));
636
637 assert_eq!(Div(6).partial_rcmp(Div(2)..Div(12)), pos(W, W));
639 assert_eq!(Div(6).partial_rcmp(&Div(2)..&Div(12)), pos(W, W));
640
641 assert_eq!(Div(2).partial_rcmp(Div(4)..Div(8)), pos(O, W));
643 assert_eq!(Div(2).partial_rcmp(&Div(4)..&Div(8)), pos(O, W));
644
645 assert_eq!(Div(3).partial_rcmp(Div(4)..Div(12)), pos(I, W));
647 assert_eq!(Div(3).partial_rcmp(&Div(4)..&Div(12)), pos(I, W));
648 assert_eq!(Div(3).partial_rcmp(Div(4)..Div(12)).ordering(), None);
649 }
650
651 #[test]
652 fn range_inclusive() {
653 assert_eq!(Div(6).partial_rcmp(Div(1)..=Div(3)), pos(W, O));
655 assert_eq!(Div(6).partial_rcmp(&Div(1)..=&Div(3)), pos(W, O));
656
657 assert_eq!(Div(6).partial_rcmp(Div(6)..=Div(6)), pos(W, W));
659 assert_eq!(Div(6).partial_rcmp(&Div(6)..=&Div(6)), pos(W, W));
660
661 assert_eq!(Div(2).partial_rcmp(Div(4)..=Div(8)), pos(O, W));
663 assert_eq!(Div(2).partial_rcmp(&Div(4)..=&Div(8)), pos(O, W));
664
665 assert_eq!(Div(3).partial_rcmp(Div(4)..=Div(12)), pos(I, W));
667 assert_eq!(Div(3).partial_rcmp(&Div(4)..=&Div(12)), pos(I, W));
668 }
669
670 #[test]
671 fn range_to_inclusive() {
672 assert_eq!(Div(4).partial_rcmp(..=Div(2)), pos(W, O));
674 assert_eq!(Div(4).partial_rcmp(..=&Div(2)), pos(W, O));
675
676 assert_eq!(Div(1).partial_rcmp(..=Div(2)), pos(W, W));
678 assert_eq!(Div(1).partial_rcmp(..=&Div(2)), pos(W, W));
679
680 assert_eq!(Div(3).partial_rcmp(..=Div(10)), pos(W, I));
682 assert_eq!(Div(3).partial_rcmp(..=&Div(10)), pos(W, I));
683 }
684
685 #[test]
686 fn bounds_full() {
687 let bounds: (Bound<Div>, Bound<Div>) = (Bound::Unbounded, Bound::Unbounded);
688 assert_eq!(Div(1).partial_rcmp(bounds), pos(W, W));
689 }
690
691 #[test]
692 fn bounds_from() {
693 let bounds = (Bound::Included(Div(1)), Bound::Unbounded);
695 assert_eq!(Div(1).partial_rcmp(bounds), pos(W, W));
696
697 let bounds = (Bound::Included(&Div(1)), Bound::Unbounded);
698 assert_eq!(Div(1).partial_rcmp(bounds), pos(W, W));
699
700 let bounds = (Bound::Included(Div(2)), Bound::Unbounded);
702 assert_eq!(Div(1).partial_rcmp(bounds), pos(O, W));
703
704 let bounds = (Bound::Included(&Div(2)), Bound::Unbounded);
705 assert_eq!(Div(1).partial_rcmp(bounds), pos(O, W));
706
707 let bounds = (Bound::Included(Div(3)), Bound::Unbounded);
709 assert_eq!(Div(2).partial_rcmp(bounds), pos(I, W));
710
711 let bounds = (Bound::Included(&Div(3)), Bound::Unbounded);
712 assert_eq!(Div(2).partial_rcmp(bounds), pos(I, W));
713 }
714
715 #[test]
716 fn bounds_to() {
717 let bounds = (Bound::Unbounded, Bound::Excluded(Div(2)));
719 assert_eq!(Div(4).partial_rcmp(bounds), pos(W, O));
720
721 let bounds = (Bound::Unbounded, Bound::Excluded(Div(2)));
723 assert_eq!(Div(1).partial_rcmp(bounds), pos(W, W));
724
725 let bounds = (Bound::Unbounded, Bound::Excluded(&Div(10)));
727 assert_eq!(Div(3).partial_rcmp(bounds), pos(W, I));
728 }
729
730 #[test]
731 fn bounds() {
732 let bounds = (Bound::Included(Div(1)), Bound::Excluded(Div(3)));
734 assert_eq!(Div(3).partial_rcmp(bounds), pos(W, O));
735
736 let bounds = (Bound::Included(&Div(2)), Bound::Excluded(&Div(12)));
738 assert_eq!(Div(6).partial_rcmp(bounds), pos(W, W));
739
740 let bounds = (Bound::Included(Div(4)), Bound::Excluded(Div(8)));
742 assert_eq!(Div(2).partial_rcmp(bounds), pos(O, W));
743 }
744
745 #[test]
746 fn bounds_inclusive() {
747 let bounds = (Bound::Included(Div(1)), Bound::Included(Div(3)));
749 assert_eq!(Div(6).partial_rcmp(bounds), pos(W, O));
750
751 let bounds = (Bound::Included(&Div(6)), Bound::Included(&Div(6)));
753 assert_eq!(Div(6).partial_rcmp(bounds), pos(W, W));
754
755 let bounds = (Bound::Included(Div(4)), Bound::Included(Div(8)));
757 assert_eq!(Div(2).partial_rcmp(bounds), pos(O, W));
758 }
759
760 #[test]
761 fn bounds_to_inclusive() {
762 let bounds = (Bound::Unbounded, Bound::Included(Div(2)));
764 assert_eq!(Div(4).partial_rcmp(bounds), pos(W, O));
765
766 let bounds = (Bound::Unbounded, Bound::Included(&Div(2)));
768 assert_eq!(Div(1).partial_rcmp(bounds), pos(W, W));
769 }
770
771 #[test]
772 fn bounds_exclusive_inclusive() {
773 let bounds = (Bound::Excluded(Div(1)), Bound::Included(Div(3)));
775 assert_eq!(Div(6).partial_rcmp(bounds), pos(W, O));
776
777 let bounds = (Bound::Excluded(Div(1)), Bound::Included(Div(2)));
779 assert_eq!(Div(1).partial_rcmp(bounds), pos(O, W));
780 }
781
782 #[test]
783 fn bounds_as_reference() {
784 let bounds = Div(2)..Div(12);
785 assert_eq!(Div(6).partial_rcmp(&bounds), pos(W, W));
786 assert_eq!(Div(6).partial_rcmp(bounds), pos(W, W));
787 }
788
789 #[test]
792 fn comparable_to_one_bound_only() {
793 assert_eq!(Div(4).partial_rcmp(Div(2)..Div(9)), pos(W, I));
795 assert_eq!(Div(4).partial_rcmp(Div(2)..Div(9)).ordering(), None);
796
797 assert_eq!(Div(2).partial_rcmp(Div(4)..Div(9)), pos(O, I));
799 assert_eq!(Div(2).partial_rcmp(Div(4)..Div(9)).ordering(), None);
800
801 assert_eq!(Div(4).partial_rcmp(Div(3)..Div(12)), pos(I, W));
803 assert_eq!(Div(4).partial_rcmp(Div(3)..Div(12)).ordering(), None);
804 }
805
806 #[test]
807 fn empty_ranges() {
808 assert_eq!(Div(4).partial_rcmp(Div(8)..Div(2)), pos(O, O));
811 assert_eq!(
812 Div(4).partial_rcmp(Div(8)..Div(2)).ordering(),
813 Some(RangeOrdering::Empty)
814 );
815 }
816}