Skip to content

Commit 7c57420

Browse files
committed
impl ops::Try for Ordering
1 parent c133aac commit 7c57420

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

library/core/src/cmp.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#![stable(feature = "rust1", since = "1.0.0")]
2424

2525
use self::Ordering::*;
26+
use crate::ops;
2627

2728
/// Trait for equality comparisons which are [partial equivalence
2829
/// relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
@@ -679,6 +680,30 @@ impl PartialOrd for Ordering {
679680
}
680681
}
681682

683+
#[unstable(feature = "try_trait", issue = "42327")]
684+
impl ops::Try for Ordering {
685+
type Ok = ();
686+
type Error = Self;
687+
688+
#[inline]
689+
fn into_result(self) -> Result<(), Self> {
690+
match self {
691+
Equal => Ok(()),
692+
_ => Err(self),
693+
}
694+
}
695+
696+
#[inline]
697+
fn from_ok(_: ()) -> Self {
698+
Equal
699+
}
700+
701+
#[inline]
702+
fn from_error(v: Self) -> Self {
703+
v
704+
}
705+
}
706+
682707
/// Trait for values that can be compared for a sort-order.
683708
///
684709
/// The comparison must satisfy, for all `a`, `b` and `c`:

src/test/ui/ordering-try.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// run-pass
2+
3+
use std::cmp::Ordering;
4+
use std::iter;
5+
6+
#[derive(Eq, PartialEq)]
7+
struct Test(bool, u8, &'static str);
8+
9+
const BOOL_VALUES: [bool; 2] = [true, false];
10+
const U8_VALUES: [u8; 3] = [1, 2, 3];
11+
const STR_VALUES: [&str; 3] = ["a", "ab", "c"];
12+
13+
fn test_values() -> impl Iterator<Item = Test> {
14+
BOOL_VALUES.iter().flat_map(|&a| {
15+
U8_VALUES.iter().flat_map(move |&b| {
16+
STR_VALUES.iter().map(move |&c| Test(a, b, c))
17+
})
18+
})
19+
}
20+
21+
// This Ord implementation should behave the same as #[derive(Ord)],
22+
// but uses the Try operator on Ordering values
23+
impl Ord for Test {
24+
fn cmp(&self, other: &Self) -> Ordering {
25+
self.0.cmp(&other.0)?;
26+
self.1.cmp(&other.1)?;
27+
self.2.cmp(&other.2)
28+
}
29+
}
30+
31+
impl PartialOrd for Test {
32+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
33+
Some(self.cmp(other))
34+
}
35+
}
36+
37+
fn test_struct_cmp() {
38+
for test1 in test_values() {
39+
let test1_alt = (test1.0, test1.1, test1.2);
40+
for test2 in test_values() {
41+
let test2_alt = (test2.0, test2.1, test2.2);
42+
assert_eq!(test1.cmp(&test2), test1_alt.cmp(&test2_alt));
43+
}
44+
}
45+
}
46+
47+
// Implement Iterator::cmp() using the Try operator
48+
fn cmp<A, I1, I2>(mut iter1: I1, mut iter2: I2) -> Ordering
49+
where
50+
A: Ord,
51+
I1: Iterator<Item = A>,
52+
I2: Iterator<Item = A>,
53+
{
54+
loop {
55+
match (iter1.next(), iter2.next()) {
56+
(Some(x), Some(y)) => x.cmp(&y)?,
57+
(x, y) => return x.cmp(&y),
58+
}
59+
}
60+
}
61+
62+
fn u8_sequences() -> impl Iterator<Item = Vec<u8>> {
63+
iter::once(vec![])
64+
.chain(U8_VALUES.iter().map(|&a| vec![a]))
65+
.chain(U8_VALUES.iter().flat_map(|&a| {
66+
U8_VALUES.iter().map(move |&b| vec![a, b])
67+
}))
68+
.chain(U8_VALUES.iter().flat_map(|&a| {
69+
U8_VALUES.iter().flat_map(move |&b| {
70+
U8_VALUES.iter().map(move |&c| vec![a, b, c])
71+
})
72+
}))
73+
}
74+
75+
fn test_slice_cmp() {
76+
for sequence1 in u8_sequences() {
77+
for sequence2 in u8_sequences() {
78+
assert_eq!(
79+
cmp(sequence1.iter().copied(), sequence2.iter().copied()),
80+
sequence1.iter().copied().cmp(sequence2.iter().copied()),
81+
);
82+
}
83+
}
84+
}
85+
86+
fn main() {
87+
test_struct_cmp();
88+
test_slice_cmp();
89+
}

0 commit comments

Comments
 (0)