Skip to content

Commit

Permalink
Add or and or_else for ordering.
Browse files Browse the repository at this point in the history
  • Loading branch information
rednum committed Oct 9, 2016
1 parent c6673db commit d41c91c
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
70 changes: 70 additions & 0 deletions src/libcore/cmp.rs
Expand Up @@ -245,6 +245,76 @@ impl Ordering {
Greater => Less,
}
}

/// Chain two orderings.
///
/// Returns `self` when it's not `Equal`. Otherwise returns `other`.
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
/// let result = Ordering::Equal.or(Ordering::Less);
/// assert_eq!(result, Ordering::Less);
///
/// let result = Ordering::Less.or(Ordering::Equal);
/// assert_eq!(result, Ordering::Less);
///
/// let result = Ordering::Less.or(Ordering::Greater);
/// assert_eq!(result, Ordering::Less);
///
/// let result = Ordering::Equal.or(Ordering::Equal);
/// assert_eq!(result, Ordering::Equal);
///
/// let x = (1, 2, 7);
/// let y = (1, 5, 3);
/// let result = x.0.cmp(y.0).or(x.1.cmp(y.1)).or(x.2.cmp(y.2));
///
/// assert_eq!(result, Ordering::Less);
/// ```
#[unstable(feature = "ordering_chaining", issue = "37053")]
pub fn or(self, other: Ordering) -> Ordering {
match self {
Equal => other,
_ => self,
}
}

/// Chain the ordering with given function.
///
/// Returns `self` when it's not `Equal`. Otherwise calls `f` and returns
/// the result.
///
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
/// let result = Ordering::Equal.or_else(|| Ordering::Less);
/// assert_eq!(result, Ordering::Less);
///
/// let result = Ordering::Less.or_else(|| Ordering::Equal);
/// assert_eq!(result, Ordering::Less);
///
/// let result = Ordering::Less.or_else(|| Ordering::Greater);
/// assert_eq!(result, Ordering::Less);
///
/// let result = Ordering::Equal.or_else(|| Ordering::Equal);
/// assert_eq!(result, Ordering::Equal);
///
/// let x = (1, 2, 7);
/// let y = (1, 5, 3);
/// let result = x.0.cmp(&y.0).or_else(|| x.1.cmp(&y.1)).or_else(|| x.2.cmp(&y.2));
///
/// assert_eq!(result, Ordering::Less);
/// ```
#[unstable(feature = "ordering_chaining", issue = "37053")]
pub fn or_else<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
match self {
Equal => f(),
_ => self,
}
}
}

/// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
Expand Down
26 changes: 26 additions & 0 deletions src/libcoretest/cmp.rs
Expand Up @@ -41,6 +41,32 @@ fn test_ordering_order() {
assert_eq!(Greater.cmp(&Less), Greater);
}

#[test]
fn test_ordering_or() {
assert_eq!(Equal.or(Less), Less);
assert_eq!(Equal.or(Equal), Equal);
assert_eq!(Equal.or(Greater), Greater);
assert_eq!(Less.or(Less), Less);
assert_eq!(Less.or(Equal), Less);
assert_eq!(Less.or(Greater), Less);
assert_eq!(Greater.or(Less), Greater);
assert_eq!(Greater.or(Equal), Greater);
assert_eq!(Greater.or(Greater), Greater);
}

#[test]
fn test_ordering_or_else() {
assert_eq!(Equal.or_else(|| Less), Less);
assert_eq!(Equal.or_else(|| Equal), Equal);
assert_eq!(Equal.or_else(|| Greater), Greater);
assert_eq!(Less.or_else(|| Less), Less);
assert_eq!(Less.or_else(|| Equal), Less);
assert_eq!(Less.or_else(|| Greater), Less);
assert_eq!(Greater.or_else(|| Less), Greater);
assert_eq!(Greater.or_else(|| Equal), Greater);
assert_eq!(Greater.or_else(|| Greater), Greater);
}

#[test]
fn test_user_defined_eq() {
// Our type.
Expand Down
1 change: 1 addition & 0 deletions src/libcoretest/lib.rs
Expand Up @@ -34,6 +34,7 @@
#![feature(unique)]
#![feature(iter_max_by)]
#![feature(iter_min_by)]
#![feature(ordering_chaining)]

extern crate core;
extern crate test;
Expand Down

0 comments on commit d41c91c

Please sign in to comment.