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

    git branch:    * master           c7553ea auto merge of #13609 : richo/rust/str-type-vim, r=alexcrichton
    modified:    Wed Apr  9 17:27:02 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 eachother 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  /// A macro which defines an implementation of TotalEq for a given type.
  85  macro_rules! totaleq_impl(
  86      ($t:ty) => {
  87          impl TotalEq for $t {}
  88      }
  89  )
  90  
  91  totaleq_impl!(bool)
  92  
  93  totaleq_impl!(u8)
  94  totaleq_impl!(u16)
  95  totaleq_impl!(u32)
  96  totaleq_impl!(u64)
  97  
  98  totaleq_impl!(i8)
  99  totaleq_impl!(i16)
 100  totaleq_impl!(i32)
 101  totaleq_impl!(i64)
 102  
 103  totaleq_impl!(int)
 104  totaleq_impl!(uint)
 105  
 106  totaleq_impl!(char)
 107  
 108  /// An ordering is, e.g, a result of a comparison between two values.
 109  #[deriving(Clone, Eq, Show)]
 110  pub enum Ordering {
 111     /// An ordering where a compared value is less [than another].
 112     Less = -1,
 113     /// An ordering where a compared value is equal [to another].
 114     Equal = 0,
 115     /// An ordering where a compared value is greater [than another].
 116     Greater = 1
 117  }
 118  
 119  /// Trait for types that form a [total order](
 120  /// https://en.wikipedia.org/wiki/Total_order).
 121  ///
 122  /// An order is a total order if it is (for all `a`, `b` and `c`):
 123  ///
 124  /// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is
 125  ///   true; and
 126  /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
 127  ///   both `==` and `>`.
 128  pub trait TotalOrd: TotalEq + Ord {
 129      /// This method returns an ordering between `self` and `other` values.
 130      ///
 131      /// By convention, `self.cmp(&other)` returns the ordering matching
 132      /// the expression `self <operator> other` if true.  For example:
 133      ///
 134      /// ```
 135      /// assert_eq!( 5u.cmp(&10), Less);     // because 5 < 10
 136      /// assert_eq!(10u.cmp(&5),  Greater);  // because 10 > 5
 137      /// assert_eq!( 5u.cmp(&5),  Equal);    // because 5 == 5
 138      /// ```
 139      fn cmp(&self, other: &Self) -> Ordering;
 140  }
 141  
 142  impl TotalEq for Ordering {}
 143  impl TotalOrd for Ordering {
 144      #[inline]
 145      fn cmp(&self, other&Ordering) -> Ordering {
 146          (*self as int).cmp(&(*other as int))
 147      }
 148  }
 149  
 150  impl Ord for Ordering {
 151      #[inline]
 152      fn lt(&self, other&Ordering) -> bool { (*self as int) < (*other as int) }
 153  }
 154  
 155  /// A macro which defines an implementation of TotalOrd for a given type.
 156  macro_rules! totalord_impl(
 157      ($t:ty) => {
 158          impl TotalOrd for $t {
 159              #[inline]
 160              fn cmp(&self, other&$t) -> Ordering {
 161                  if *self < *other { Less }
 162                  else if *self > *other { Greater }
 163                  else { Equal }
 164              }
 165          }
 166      }
 167  )
 168  
 169  totalord_impl!(u8)
 170  totalord_impl!(u16)
 171  totalord_impl!(u32)
 172  totalord_impl!(u64)
 173  
 174  totalord_impl!(i8)
 175  totalord_impl!(i16)
 176  totalord_impl!(i32)
 177  totalord_impl!(i64)
 178  
 179  totalord_impl!(int)
 180  totalord_impl!(uint)
 181  
 182  totalord_impl!(char)
 183  
 184  /// Combine orderings, lexically.
 185  ///
 186  /// For example for a type `(int, int)`, two comparisons could be done.
 187  /// If the first ordering is different, the first ordering is all that must be returned.
 188  /// If the first ordering is equal, then second ordering is returned.
 189  #[inline]
 190  pub fn lexical_ordering(o1Ordering, o2Ordering) -> Ordering {
 191      match o1 {
 192          Equal => o2,
 193          _ => o1
 194      }
 195  }
 196  
 197  /// Trait for values that can be compared for a sort-order.
 198  ///
 199  /// Ord only requires implementation of the `lt` method,
 200  /// with the others generated from default implementations.
 201  ///
 202  /// However it remains possible to implement the others separately,
 203  /// for compatibility with floating-point NaN semantics
 204  /// (cf. IEEE 754-2008 section 5.11).
 205  #[lang="ord"]
 206  pub trait Ord: Eq {
 207      /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
 208      fn lt(&self, other: &Self) -> bool;
 209  
 210      /// This method tests less than or equal to (`<=`).
 211      #[inline]
 212      fn le(&self, other&Self) -> bool { !other.lt(self) }
 213  
 214      /// This method tests greater than (`>`).
 215      #[inline]
 216      fn gt(&self, other&Self) -> bool {  other.lt(self) }
 217  
 218      /// This method tests greater than or equal to (`>=`).
 219      #[inline]
 220      fn ge(&self, other&Self) -> bool { !self.lt(other) }
 221  }
 222  
 223  /// The equivalence relation. Two values may be equivalent even if they are
 224  /// of different types. The most common use case for this relation is
 225  /// container types; e.g. it is often desirable to be able to use `&str`
 226  /// values to look up entries in a container with `~str` keys.
 227  pub trait Equiv<T> {
 228      /// Implement this function to decide equivalent values.
 229      fn equiv(&self, other: &T) -> bool;
 230  }
 231  
 232  /// Compare and return the minimum of two values.
 233  #[inline]
 234  pub fn min<T: TotalOrd>(v1T, v2T) -> T {
 235      if v1 < v2 { v1 } else { v2 }
 236  }
 237  
 238  /// Compare and return the maximum of two values.
 239  #[inline]
 240  pub fn max<T: TotalOrd>(v1T, v2T) -> T {
 241      if v1 > v2 { v1 } else { v2 }
 242  }
 243  
 244  #[cfg(test)]
 245  mod test {
 246      use super::lexical_ordering;
 247  
 248      #[test]
 249      fn test_int_totalord() {
 250          assert_eq!(5u.cmp(&10), Less);
 251          assert_eq!(10u.cmp(&5), Greater);
 252          assert_eq!(5u.cmp(&5), Equal);
 253          assert_eq!((-5u).cmp(&12), Less);
 254          assert_eq!(12u.cmp(-5), Greater);
 255      }
 256  
 257      #[test]
 258      fn test_ordering_order() {
 259          assert!(Less < Equal);
 260          assert_eq!(Greater.cmp(&Less), Greater);
 261      }
 262  
 263      #[test]
 264      fn test_lexical_ordering() {
 265          fn t(o1: Ordering, o2: Ordering, e: Ordering) {
 266              assert_eq!(lexical_ordering(o1, o2), e);
 267          }
 268  
 269          let xs = [Less, Equal, Greater];
 270          for &o in xs.iter() {
 271              t(Less, o, Less);
 272              t(Equal, o, o);
 273              t(Greater, o, Greater);
 274           }
 275      }
 276  
 277      #[test]
 278      fn test_user_defined_eq() {
 279          // Our type.
 280          struct SketchyNum {
 281              num : int
 282          }
 283  
 284          // Our implementation of `Eq` to support `==` and `!=`.
 285          impl Eq for SketchyNum {
 286              // Our custom eq allows numbers which are near eachother to be equal! :D
 287              fn eq(&self, other: &SketchyNum) -> bool {
 288                  (self.num - other.num).abs() < 5
 289              }
 290          }
 291  
 292          // Now these binary operators will work when applied!
 293          assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
 294          assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
 295      }
 296  }


libstd/cmp.rs:205:14-205: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:- 157
libstd/num/mod.rs:
libstd/num/strconv.rs:
libstd/iter.rs:
libstd/option.rs:
libstd/result.rs:
libstd/num/int_macros.rs:
libstd/num/uint_macros.rs:
libstd/num/f32.rs:
libstd/num/f64.rs:
libstd/unit.rs:
libstd/bool.rs:
libstd/char.rs:
libstd/tuple.rs:
libstd/slice.rs:
libstd/vec.rs:
libstd/str.rs:
libstd/strbuf.rs:
libstd/ascii.rs:
libstd/ptr.rs:
libstd/owned.rs:
libstd/managed.rs:
libstd/reference.rs:
libstd/rc.rs:
libstd/iter.rs:


libstd/cmp.rs:239:10-239:10 -fn- definition:
pub fn max<T: TotalOrd>(v1: T, v2: T) -> T {
    if v1 > v2 { v1 } else { v2 }
}
references:- 2
libstd/rt/thread.rs:
233:         // Reserve room for the red zone, the runtime's stack of last resort.
234:         let stack_size = cmp::max(stack, RED_ZONE + min_stack_size(&attr) as uint);
235:         match pthread_attr_setstacksize(&mut attr, stack_size as libc::size_t) {
libstd/iter.rs:
910:                 None    => Some(x),
911:                 Some(y) => Some(cmp::max(x, y))
912:             }


libstd/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:- 141
libstd/iter.rs:
libstd/option.rs:
libstd/result.rs:
libstd/io/net/ip.rs:
libstd/io/process.rs:
libstd/path/posix.rs:
libstd/path/windows.rs:
libstd/fmt/parse.rs:
libstd/intrinsics.rs:
libstd/unit.rs:
libstd/tuple.rs:
libstd/slice.rs:
libstd/vec.rs:
libstd/str.rs:
libstd/strbuf.rs:
libstd/ascii.rs:
libstd/ptr.rs:
libstd/owned.rs:
libstd/managed.rs:
libstd/reference.rs:
libstd/rc.rs:
libstd/tuple.rs:


libstd/cmp.rs:233:10-233:10 -fn- definition:
pub fn min<T: TotalOrd>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}
references:- 25
libstd/iter.rs:
920:                 None    => Some(x),
921:                 Some(y) => Some(cmp::min(x, y))
922:             }
--
1634:         let lower = cmp::min(lower, self.n);
--
1647:     fn indexable(&self) -> uint {
1648:         cmp::min(self.iter.indexable(), self.n)
1649:     }
libstd/comm/stream.rs:
222:                         n => {
223:                             let m = cmp::min(n, self.steals);
224:                             self.steals -= m;
libstd/comm/shared.rs:
312:                         n => {
313:                             let m = cmp::min(n, self.steals);
314:                             self.steals -= m;
libstd/io/buffered.rs:
106:             let available = try!(self.fill_buf());
107:             let nread = cmp::min(available.len(), buf.len());
108:             slice::bytes::copy_memory(buf, available.slice_to(nread));
libstd/io/comm_adapters.rs:
65:                     let src = prev.slice_from(self.pos);
66:                     let count = cmp::min(dst.len(), src.len());
67:                     bytes::copy_memory(dst, src.slice_to(count));
libstd/io/mem.rs:
302:         let write_len = min(buf.len(), self.buf.len() - self.pos);
303:         {
libstd/io/util.rs:
49:         let len = cmp::min(self.limit, buf.len());
50:         self.inner.read(buf.mut_slice_to(len)).map(|len| {
libstd/fmt/mod.rs:
1026:                 if char_len >= max {
1027:                     let nchars = ::cmp::min(max, char_len);
1028:                     return self.buf.write(s.slice_chars(0, nchars).as_bytes());
libstd/slice.rs:
448:         } else {
449:             let chunksz = cmp::min(self.v.len(), self.size);
450:             let (fst, snd) = (self.v.slice_to(chunksz),
--
1279:         // start <= i < len;
1280:         for i in range(start, cmp::min(start + insertion, len)) {
1281:             // j satisfies: start <= j <= i;
--
1760:         }
1761:         cmp::min(self.len(), end-start)
1762:     }
--
2199:         } else {
2200:             let sz = cmp::min(self.v.len(), self.chunk_size);
2201:             let tmp = mem::replace(&mut self.v, &mut []);
libstd/str.rs:
2701:                 } else {
2702:                     *dcol.get_mut(j + 1) = ::cmp::min(current, next);
2703:                     *dcol.get_mut(j + 1) = ::cmp::min(*dcol.get(j + 1),
2704:                                                       *dcol.get(j)) + 1;
libstd/iter.rs:
1182:         let upper = match (a_upper, b_upper) {
1183:             (Some(x), Some(y)) => Some(cmp::min(x,y)),
1184:             (Some(x), None) => Some(x),


libstd/cmp.rs:127:25-127:25 -trait- definition:
///   both `==` and `>`.
pub trait TotalOrd: TotalEq + Ord {
    /// This method returns an ordering between `self` and `other` values.
references:- 139
libstd/iter.rs:
libstd/option.rs:
libstd/result.rs:
libstd/unit.rs:
libstd/bool.rs:
libstd/tuple.rs:
libstd/slice.rs:
libstd/vec.rs:
libstd/str.rs:
libstd/strbuf.rs:
libstd/ascii.rs:
libstd/owned.rs:
libstd/managed.rs:
libstd/reference.rs:
libstd/rc.rs:
libstd/managed.rs:


libstd/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:- 290
libstd/num/mod.rs:
libstd/num/strconv.rs:
libstd/iter.rs:
libstd/option.rs:
libstd/result.rs:
libstd/cell.rs:
libstd/comm/mod.rs:
libstd/local_data.rs:
libstd/sync/deque.rs:
libstd/c_str.rs:
libstd/io/mod.rs:
libstd/io/net/ip.rs:
libstd/io/process.rs:
libstd/io/signal.rs:
libstd/path/posix.rs:
libstd/path/windows.rs:
libstd/fmt/num.rs:
libstd/fmt/parse.rs:
libstd/intrinsics.rs:
libstd/num/int_macros.rs:
libstd/num/uint_macros.rs:
libstd/num/f32.rs:
libstd/num/f64.rs:
libstd/unit.rs:
libstd/bool.rs:
libstd/char.rs:
libstd/tuple.rs:
libstd/slice.rs:
libstd/vec.rs:
libstd/str.rs:
libstd/strbuf.rs:
libstd/ascii.rs:
libstd/ptr.rs:
libstd/owned.rs:
libstd/managed.rs:
libstd/reference.rs:
libstd/rc.rs:
libstd/kinds.rs:
libstd/tuple.rs:


libstd/cmp.rs:109:29-109:29 -enum- definition:
pub enum Ordering {
   /// An ordering where a compared value is less [than another].
   Less = -1,
references:- 63
libstd/iter.rs:
libstd/option.rs:
libstd/result.rs:
libstd/unit.rs:
libstd/bool.rs:
libstd/tuple.rs:
libstd/slice.rs:
libstd/vec.rs:
libstd/str.rs:
libstd/strbuf.rs:
libstd/ascii.rs:
libstd/owned.rs:
libstd/managed.rs:
libstd/reference.rs:
libstd/rc.rs:
libstd/cmp.rs:


libstd/cmp.rs:226:63-226: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:- 7
libstd/slice.rs:
546:     impl<'a,T:Eq, V: Vector<T>> Equiv<V> for ~[T] {
547:         #[inline]
libstd/str.rs:
1538:     impl<'a, S: Str> Equiv<S> for ~str {
1539:         #[inline]
libstd/ptr.rs:
428: impl<T> Equiv<*T> for *mut T {
429:     fn equiv(&self, other: &*T) -> bool {
libstd/str.rs:
1270: impl<'a, S: Str> Equiv<S> for MaybeOwned<'a> {
1271:     #[inline]