(index<- )        ./libcore/cmp.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  //! Defines the `Ord` and `Eq` comparison traits.
  12  //!
  13  //! This module defines both `Ord` and `Eq` traits which are used by the
  14  //! compiler to implement comparison operators. Rust programs may implement
  15  //!`Ord` to overload the `<`, `<=`, `>`, and `>=` operators, and may implement
  16  //! `Eq` to overload the `==` and `!=` operators.
  17  //!
  18  //! For example, to define a type with a customized definition for the Eq
  19  //! operators, you could do the following:
  20  //!
  21  //! ```rust
  22  //! // Our type.
  23  //! struct SketchyNum {
  24  //!     num : int
  25  //! }
  26  //!
  27  //! // Our implementation of `Eq` to support `==` and `!=`.
  28  //! impl Eq for SketchyNum {
  29  //!     // Our custom eq allows numbers which are near each other to be equal! :D
  30  //!     fn eq(&self, other: &SketchyNum) -> bool {
  31  //!         (self.num - other.num).abs() < 5
  32  //!     }
  33  //! }
  34  //!
  35  //! // Now these binary operators will work when applied!
  36  //! assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
  37  //! assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
  38  //! ```
  39  
  40  /// Trait for values that can be compared for equality and inequality.
  41  ///
  42  /// This trait allows partial equality, where types can be unordered instead of
  43  /// strictly equal or unequal. For example, with the built-in floating-point
  44  /// types `a == b` and `a != b` will both evaluate to false if either `a` or
  45  /// `b` is NaN (cf. IEEE 754-2008 section 5.11).
  46  ///
  47  /// Eq only requires the `eq` method to be implemented; `ne` is its negation by
  48  /// default.
  49  ///
  50  /// Eventually, this will be implemented by default for types that implement
  51  /// `TotalEq`.
  52  #[lang="eq"]
  53  pub trait Eq {
  54      /// This method tests for `self` and `other` values to be equal, and is used by `==`.
  55      fn eq(&self, other: &Self) -> bool;
  56  
  57      /// This method tests for `!=`.
  58      #[inline]
  59      fn ne(&self, other&Self) -> bool { !self.eq(other) }
  60  }
  61  
  62  /// Trait for equality comparisons which are [equivalence relations](
  63  /// https://en.wikipedia.org/wiki/Equivalence_relation).
  64  ///
  65  /// This means, that in addition to `a == b` and `a != b` being strict
  66  /// inverses, the equality must be (for all `a`, `b` and `c`):
  67  ///
  68  /// - reflexive: `a == a`;
  69  /// - symmetric: `a == b` implies `b == a`; and
  70  /// - transitive: `a == b` and `b == c` implies `a == c`.
  71  pub trait TotalEq: Eq {
  72      // FIXME #13101: this method is used solely by #[deriving] to
  73      // assert that every component of a type implements #[deriving]
  74      // itself, the current deriving infrastructure means doing this
  75      // assertion without using a method on this trait is nearly
  76      // impossible.
  77      //
  78      // This should never be implemented by hand.
  79      #[doc(hidden)]
  80      #[inline(always)]
  81      fn assert_receiver_is_total_eq(&self) {}
  82  }
  83  
  84  /// An ordering is, e.g, a result of a comparison between two values.
  85  #[deriving(Clone, Eq)]
  86  pub enum Ordering {
  87     /// An ordering where a compared value is less [than another].
  88     Less = -1,
  89     /// An ordering where a compared value is equal [to another].
  90     Equal = 0,
  91     /// An ordering where a compared value is greater [than another].
  92     Greater = 1
  93  }
  94  
  95  /// Trait for types that form a [total order](
  96  /// https://en.wikipedia.org/wiki/Total_order).
  97  ///
  98  /// An order is a total order if it is (for all `a`, `b` and `c`):
  99  ///
 100  /// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is
 101  ///   true; and
 102  /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
 103  ///   both `==` and `>`.
 104  pub trait TotalOrd: TotalEq + Ord {
 105      /// This method returns an ordering between `self` and `other` values.
 106      ///
 107      /// By convention, `self.cmp(&other)` returns the ordering matching
 108      /// the expression `self <operator> other` if true.  For example:
 109      ///
 110      /// ```
 111      /// assert_eq!( 5u.cmp(&10), Less);     // because 5 < 10
 112      /// assert_eq!(10u.cmp(&5),  Greater);  // because 10 > 5
 113      /// assert_eq!( 5u.cmp(&5),  Equal);    // because 5 == 5
 114      /// ```
 115      fn cmp(&self, other: &Self) -> Ordering;
 116  }
 117  
 118  impl TotalEq for Ordering {}
 119  
 120  impl TotalOrd for Ordering {
 121      #[inline]
 122      fn cmp(&self, other&Ordering) -> Ordering {
 123          (*self as int).cmp(&(*other as int))
 124      }
 125  }
 126  
 127  impl Ord for Ordering {
 128      #[inline]
 129      fn lt(&self, other&Ordering) -> bool { (*self as int) < (*other as int) }
 130  }
 131  
 132  /// Combine orderings, lexically.
 133  ///
 134  /// For example for a type `(int, int)`, two comparisons could be done.
 135  /// If the first ordering is different, the first ordering is all that must be returned.
 136  /// If the first ordering is equal, then second ordering is returned.
 137  #[inline]
 138  pub fn lexical_ordering(o1Ordering, o2Ordering) -> Ordering {
 139      match o1 {
 140          Equal => o2,
 141          _ => o1
 142      }
 143  }
 144  
 145  /// Trait for values that can be compared for a sort-order.
 146  ///
 147  /// Ord only requires implementation of the `lt` method,
 148  /// with the others generated from default implementations.
 149  ///
 150  /// However it remains possible to implement the others separately,
 151  /// for compatibility with floating-point NaN semantics
 152  /// (cf. IEEE 754-2008 section 5.11).
 153  #[lang="ord"]
 154  pub trait Ord: Eq {
 155      /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
 156      fn lt(&self, other: &Self) -> bool;
 157  
 158      /// This method tests less than or equal to (`<=`).
 159      #[inline]
 160      fn le(&self, other&Self) -> bool { !other.lt(self) }
 161  
 162      /// This method tests greater than (`>`).
 163      #[inline]
 164      fn gt(&self, other&Self) -> bool {  other.lt(self) }
 165  
 166      /// This method tests greater than or equal to (`>=`).
 167      #[inline]
 168      fn ge(&self, other&Self) -> bool { !self.lt(other) }
 169  }
 170  
 171  /// The equivalence relation. Two values may be equivalent even if they are
 172  /// of different types. The most common use case for this relation is
 173  /// container types; e.g. it is often desirable to be able to use `&str`
 174  /// values to look up entries in a container with `~str` keys.
 175  pub trait Equiv<T> {
 176      /// Implement this function to decide equivalent values.
 177      fn equiv(&self, other: &T) -> bool;
 178  }
 179  
 180  /// Compare and return the minimum of two values.
 181  #[inline]
 182  pub fn min<T: TotalOrd>(v1T, v2T) -> T {
 183      if v1 < v2 { v1 } else { v2 }
 184  }
 185  
 186  /// Compare and return the maximum of two values.
 187  #[inline]
 188  pub fn max<T: TotalOrd>(v1T, v2T) -> T {
 189      if v1 > v2 { v1 } else { v2 }
 190  }
 191  
 192  // Implementation of Eq/TotalEq for some primitive types
 193  #[cfg(not(test))]
 194  mod impls {
 195      use cmp::{Ord, TotalOrd, Eq, TotalEq, Ordering};
 196      use owned::Box;
 197  
 198      // & pointers
 199      impl<'a, T: Eq> Eq for &'a T {
 200          #[inline]
 201          fn eq(&self, other& &'a T) -> bool { *(*self) == *(*other) }
 202          #[inline]
 203          fn ne(&self, other& &'a T) -> bool { *(*self) != *(*other) }
 204      }
 205      impl<'a, T: Ord> Ord for &'a T {
 206          #[inline]
 207          fn lt(&self, other& &'a T) -> bool { *(*self) < *(*other) }
 208          #[inline]
 209          fn le(&self, other& &'a T) -> bool { *(*self) <= *(*other) }
 210          #[inline]
 211          fn ge(&self, other& &'a T) -> bool { *(*self) >= *(*other) }
 212          #[inline]
 213          fn gt(&self, other& &'a T) -> bool { *(*self) > *(*other) }
 214      }
 215      impl<'a, T: TotalOrd> TotalOrd for &'a T {
 216          #[inline]
 217          fn cmp(&self, other& &'a T) -> Ordering { (**self).cmp(*other) }
 218      }
 219      impl<'a, T: TotalEq> TotalEq for &'a T {}
 220  
 221      // @ pointers
 222      impl<T:Eq> Eq for @T {
 223          #[inline]
 224          fn eq(&self, other&@T) -> bool { *(*self) == *(*other) }
 225          #[inline]
 226          fn ne(&self, other&@T) -> bool { *(*self) != *(*other) }
 227      }
 228      impl<T:Ord> Ord for @T {
 229          #[inline]
 230          fn lt(&self, other&@T) -> bool { *(*self) < *(*other) }
 231          #[inline]
 232          fn le(&self, other&@T) -> bool { *(*self) <= *(*other) }
 233          #[inline]
 234          fn ge(&self, other&@T) -> bool { *(*self) >= *(*other) }
 235          #[inline]
 236          fn gt(&self, other&@T) -> bool { *(*self) > *(*other) }
 237      }
 238      impl<T: TotalOrd> TotalOrd for @T {
 239          #[inline]
 240          fn cmp(&self, other&@T) -> Ordering { (**self).cmp(*other) }
 241      }
 242      impl<T: TotalEq> TotalEq for @T {}
 243  
 244      // box pointers
 245      impl<T:Eq> Eq for Box<T> {
 246          #[inline]
 247          fn eq(&self, other&Box<T>) -> bool { *(*self) == *(*other) }
 248          #[inline]
 249          fn ne(&self, other&Box<T>) -> bool { *(*self) != *(*other) }
 250      }
 251      impl<T:Ord> Ord for Box<T> {
 252          #[inline]
 253          fn lt(&self, other&Box<T>) -> bool { *(*self) < *(*other) }
 254          #[inline]
 255          fn le(&self, other&Box<T>) -> bool { *(*self) <= *(*other) }
 256          #[inline]
 257          fn ge(&self, other&Box<T>) -> bool { *(*self) >= *(*other) }
 258          #[inline]
 259          fn gt(&self, other&Box<T>) -> bool { *(*self) > *(*other) }
 260      }
 261      impl<T: TotalOrd> TotalOrd for Box<T> {
 262          #[inline]
 263          fn cmp(&self, other&Box<T>) -> Ordering { (**self).cmp(*other) }
 264      }
 265      impl<T: TotalEq> TotalEq for Box<T> {}
 266  }
 267  
 268  #[cfg(test)]
 269  mod test {
 270      use super::lexical_ordering;
 271  
 272      #[test]
 273      fn test_int_totalord() {
 274          assert_eq!(5u.cmp(&10), Less);
 275          assert_eq!(10u.cmp(&5), Greater);
 276          assert_eq!(5u.cmp(&5), Equal);
 277          assert_eq!((-5u).cmp(&12), Less);
 278          assert_eq!(12u.cmp(-5), Greater);
 279      }
 280  
 281      #[test]
 282      fn test_ordering_order() {
 283          assert!(Less < Equal);
 284          assert_eq!(Greater.cmp(&Less), Greater);
 285      }
 286  
 287      #[test]
 288      fn test_lexical_ordering() {
 289          fn t(o1: Ordering, o2: Ordering, e: Ordering) {
 290              assert_eq!(lexical_ordering(o1, o2), e);
 291          }
 292  
 293          let xs = [Less, Equal, Greater];
 294          for &o in xs.iter() {
 295              t(Less, o, Less);
 296              t(Equal, o, o);
 297              t(Greater, o, Greater);
 298           }
 299      }
 300  
 301      #[test]
 302      fn test_user_defined_eq() {
 303          // Our type.
 304          struct SketchyNum {
 305              num : int
 306          }
 307  
 308          // Our implementation of `Eq` to support `==` and `!=`.
 309          impl Eq for SketchyNum {
 310              // Our custom eq allows numbers which are near each other to be equal! :D
 311              fn eq(&self, other: &SketchyNum) -> bool {
 312                  (self.num - other.num).abs() < 5
 313              }
 314          }
 315  
 316          // Now these binary operators will work when applied!
 317          assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
 318          assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
 319      }
 320  }


libcore/cmp.rs:153:14-153:14 -trait- definition:
pub trait Ord: Eq {
    /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
    fn lt(&self, other: &Self) -> bool;
references:- 146
libcore/unit.rs:
libcore/bool.rs:
libcore/char.rs:
libcore/iter.rs:
libcore/option.rs:
libcore/result.rs:
libcore/slice.rs:
libcore/str.rs:
libcore/tuple.rs:
libcore/num/int_macros.rs:
libcore/num/uint_macros.rs:
libcore/num/f32.rs:
libcore/num/f64.rs:
libcore/num/mod.rs:
libcore/ptr.rs:
libcore/tuple.rs:


libcore/cmp.rs:85:23-85:23 -enum- definition:
pub enum Ordering {
   /// An ordering where a compared value is less [than another].
   Less = -1,
references:- 52
libcore/unit.rs:
libcore/bool.rs:
libcore/char.rs:
libcore/iter.rs:
libcore/option.rs:
libcore/result.rs:
libcore/slice.rs:
libcore/str.rs:
libcore/tuple.rs:
libcore/num/int_macros.rs:
libcore/num/uint_macros.rs:
libcore/cmp.rs:


libcore/cmp.rs:52:13-52:13 -trait- definition:
pub trait Eq {
    /// This method tests for `self` and `other` values to be equal, and is used by `==`.
    fn eq(&self, other: &Self) -> bool;
references:- 242
libcore/unit.rs:
libcore/bool.rs:
libcore/cell.rs:
libcore/char.rs:
libcore/iter.rs:
libcore/option.rs:
libcore/result.rs:
libcore/slice.rs:
libcore/str.rs:
libcore/tuple.rs:
libcore/num/int_macros.rs:
libcore/num/uint_macros.rs:
libcore/num/f32.rs:
libcore/num/f64.rs:
libcore/num/mod.rs:
libcore/intrinsics.rs:
libcore/ptr.rs:
libcore/kinds.rs:
libcore/tuple.rs:


libcore/cmp.rs:174:63-174:63 -trait- definition:
/// values to look up entries in a container with `~str` keys.
pub trait Equiv<T> {
    /// Implement this function to decide equivalent values.
references:- 6
libcore/slice.rs:
284:     impl<'a,T:Eq, V: Vector<T>> Equiv<V> for ~[T] {
285:         #[inline]
libcore/str.rs:
835:     impl<'a, S: Str> Equiv<S> for &'a str {
836:         #[inline]
--
840:     impl<'a, S: Str> Equiv<S> for ~str {
841:         #[inline]
libcore/ptr.rs:
430: impl<T> Equiv<*T> for *mut T {
431:     fn equiv(&self, other: &*T) -> bool {
libcore/slice.rs:
279:     impl<'a,T:Eq, V: Vector<T>> Equiv<V> for &'a [T] {
280:         #[inline]


libcore/cmp.rs:70:58-70:58 -trait- definition:
/// - transitive: `a == b` and `b == c` implies `a == c`.
pub trait TotalEq: Eq {
    // FIXME #13101: this method is used solely by #[deriving] to
references:- 127
libcore/unit.rs:
libcore/bool.rs:
libcore/char.rs:
libcore/iter.rs:
libcore/option.rs:
libcore/result.rs:
libcore/slice.rs:
libcore/str.rs:
libcore/tuple.rs:
libcore/num/int_macros.rs:
libcore/num/uint_macros.rs:
libcore/intrinsics.rs:
libcore/ptr.rs:
libcore/tuple.rs:


libcore/cmp.rs:181:10-181:10 -fn- definition:
pub fn min<T: TotalOrd>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}
references:- 10
libcore/iter.rs:
921:                 None    => Some(x),
922:                 Some(y) => Some(cmp::min(x, y))
923:             }
--
1181:         let lower = cmp::min(a_lower, b_lower);
--
1220:     fn indexable(&self) -> uint {
1221:         cmp::min(self.a.indexable(), self.b.indexable())
1222:     }
--
1649:     fn indexable(&self) -> uint {
1650:         cmp::min(self.iter.indexable(), self.n)
1651:     }
libcore/slice.rs:
134:         } else {
135:             (1, Some(cmp::min(self.count, self.iter.v.len()) + 1))
136:         }
--
189:         } else {
190:             let chunksz = cmp::min(self.v.len(), self.size);
191:             let (fst, snd) = (self.v.slice_to(chunksz),
--
1439:         } else {
1440:             let sz = cmp::min(self.v.len(), self.chunk_size);
1441:             let tmp = mem::replace(&mut self.v, &mut []);
libcore/iter.rs:
1636:         let lower = cmp::min(lower, self.n);


libcore/cmp.rs:103:25-103:25 -trait- definition:
///   both `==` and `>`.
pub trait TotalOrd: TotalEq + Ord {
    /// This method returns an ordering between `self` and `other` values.
references:- 130
libcore/unit.rs:
libcore/bool.rs:
libcore/char.rs:
libcore/iter.rs:
libcore/option.rs:
libcore/result.rs:
libcore/slice.rs:
libcore/str.rs:
libcore/tuple.rs:
libcore/num/int_macros.rs:
libcore/num/uint_macros.rs:
libcore/num/int_macros.rs: