diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index f990a27e52b..58b3db0ad39 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -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 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). diff --git a/src/libcoretest/cmp.rs b/src/libcoretest/cmp.rs index 051356cad16..94f66e4d151 100644 --- a/src/libcoretest/cmp.rs +++ b/src/libcoretest/cmp.rs @@ -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. diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 590bf478aa7..aad0d2fedaa 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -34,6 +34,7 @@ #![feature(unique)] #![feature(iter_max_by)] #![feature(iter_min_by)] +#![feature(ordering_chaining)] extern crate core; extern crate test;