]> git.lizzy.rs Git - rust.git/blob - src/libcore/cmp.rs
Auto merge of #42264 - GuillaumeGomez:new-error-codes, r=Susurrus
[rust.git] / src / libcore / cmp.rs
1 // Copyright 2012-2014 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 //! Functionality for ordering and comparison.
12 //!
13 //! This module defines both [`PartialOrd`] and [`PartialEq`] traits which are used
14 //! by the compiler to implement comparison operators. Rust programs may
15 //! implement [`PartialOrd`] to overload the `<`, `<=`, `>`, and `>=` operators,
16 //! and may implement [`PartialEq`] to overload the `==` and `!=` operators.
17 //!
18 //! [`PartialOrd`]: trait.PartialOrd.html
19 //! [`PartialEq`]: trait.PartialEq.html
20 //!
21 //! # Examples
22 //!
23 //! ```
24 //! let x: u32 = 0;
25 //! let y: u32 = 1;
26 //!
27 //! // these two lines are equivalent
28 //! assert_eq!(x < y, true);
29 //! assert_eq!(x.lt(&y), true);
30 //!
31 //! // these two lines are also equivalent
32 //! assert_eq!(x == y, false);
33 //! assert_eq!(x.eq(&y), false);
34 //! ```
35
36 #![stable(feature = "rust1", since = "1.0.0")]
37
38 use self::Ordering::*;
39
40 /// Trait for equality comparisons which are [partial equivalence
41 /// relations](http://en.wikipedia.org/wiki/Partial_equivalence_relation).
42 ///
43 /// This trait allows for partial equality, for types that do not have a full
44 /// equivalence relation.  For example, in floating point numbers `NaN != NaN`,
45 /// so floating point types implement `PartialEq` but not `Eq`.
46 ///
47 /// Formally, the equality must be (for all `a`, `b` and `c`):
48 ///
49 /// - symmetric: `a == b` implies `b == a`; and
50 /// - transitive: `a == b` and `b == c` implies `a == c`.
51 ///
52 /// Note that these requirements mean that the trait itself must be implemented
53 /// symmetrically and transitively: if `T: PartialEq<U>` and `U: PartialEq<V>`
54 /// then `U: PartialEq<T>` and `T: PartialEq<V>`.
55 ///
56 /// ## Derivable
57 ///
58 /// This trait can be used with `#[derive]`. When `derive`d on structs, two
59 /// instances are equal if all fields are equal, and not equal if any fields
60 /// are not equal. When `derive`d on enums, each variant is equal to itself
61 /// and not equal to the other variants.
62 ///
63 /// ## How can I implement `PartialEq`?
64 ///
65 /// PartialEq only requires the `eq` method to be implemented; `ne` is defined
66 /// in terms of it by default. Any manual implementation of `ne` *must* respect
67 /// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
68 /// only if `a != b`.
69 ///
70 /// Implementations of `PartialEq`, `PartialOrd`, and `Ord` *must* agree with
71 /// each other. It's easy to accidentally make them disagree by deriving some
72 /// of the traits and manually implementing others.
73 ///
74 /// An example implementation for a domain in which two books are considered
75 /// the same book if their ISBN matches, even if the formats differ:
76 ///
77 /// ```
78 /// enum BookFormat { Paperback, Hardback, Ebook }
79 /// struct Book {
80 ///     isbn: i32,
81 ///     format: BookFormat,
82 /// }
83 ///
84 /// impl PartialEq for Book {
85 ///     fn eq(&self, other: &Book) -> bool {
86 ///         self.isbn == other.isbn
87 ///     }
88 /// }
89 ///
90 /// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
91 /// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
92 /// let b3 = Book { isbn: 10, format: BookFormat::Paperback };
93 ///
94 /// assert!(b1 == b2);
95 /// assert!(b1 != b3);
96 /// ```
97 ///
98 /// # Examples
99 ///
100 /// ```
101 /// let x: u32 = 0;
102 /// let y: u32 = 1;
103 ///
104 /// assert_eq!(x == y, false);
105 /// assert_eq!(x.eq(&y), false);
106 /// ```
107 #[lang = "eq"]
108 #[stable(feature = "rust1", since = "1.0.0")]
109 #[rustc_on_unimplemented = "can't compare `{Self}` with `{Rhs}`"]
110 pub trait PartialEq<Rhs: ?Sized = Self> {
111     /// This method tests for `self` and `other` values to be equal, and is used
112     /// by `==`.
113     #[stable(feature = "rust1", since = "1.0.0")]
114     fn eq(&self, other: &Rhs) -> bool;
115
116     /// This method tests for `!=`.
117     #[inline]
118     #[stable(feature = "rust1", since = "1.0.0")]
119     fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
120 }
121
122 /// Trait for equality comparisons which are [equivalence relations](
123 /// https://en.wikipedia.org/wiki/Equivalence_relation).
124 ///
125 /// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must
126 /// be (for all `a`, `b` and `c`):
127 ///
128 /// - reflexive: `a == a`;
129 /// - symmetric: `a == b` implies `b == a`; and
130 /// - transitive: `a == b` and `b == c` implies `a == c`.
131 ///
132 /// This property cannot be checked by the compiler, and therefore `Eq` implies
133 /// `PartialEq`, and has no extra methods.
134 ///
135 /// ## Derivable
136 ///
137 /// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
138 /// no extra methods, it is only informing the compiler that this is an
139 /// equivalence relation rather than a partial equivalence relation. Note that
140 /// the `derive` strategy requires all fields are `Eq`, which isn't
141 /// always desired.
142 ///
143 /// ## How can I implement `Eq`?
144 ///
145 /// If you cannot use the `derive` strategy, specify that your type implements
146 /// `Eq`, which has no methods:
147 ///
148 /// ```
149 /// enum BookFormat { Paperback, Hardback, Ebook }
150 /// struct Book {
151 ///     isbn: i32,
152 ///     format: BookFormat,
153 /// }
154 /// impl PartialEq for Book {
155 ///     fn eq(&self, other: &Book) -> bool {
156 ///         self.isbn == other.isbn
157 ///     }
158 /// }
159 /// impl Eq for Book {}
160 /// ```
161 #[stable(feature = "rust1", since = "1.0.0")]
162 pub trait Eq: PartialEq<Self> {
163     // FIXME #13101: this method is used solely by #[deriving] to
164     // assert that every component of a type implements #[deriving]
165     // itself, the current deriving infrastructure means doing this
166     // assertion without using a method on this trait is nearly
167     // impossible.
168     //
169     // This should never be implemented by hand.
170     #[doc(hidden)]
171     #[inline(always)]
172     #[stable(feature = "rust1", since = "1.0.0")]
173     fn assert_receiver_is_total_eq(&self) {}
174 }
175
176 // FIXME: this struct is used solely by #[derive] to
177 // assert that every component of a type implements Eq.
178 //
179 // This struct should never appear in user code.
180 #[doc(hidden)]
181 #[allow(missing_debug_implementations)]
182 #[unstable(feature = "derive_eq",
183            reason = "deriving hack, should not be public",
184            issue = "0")]
185 pub struct AssertParamIsEq<T: Eq + ?Sized> { _field: ::marker::PhantomData<T> }
186
187 /// An `Ordering` is the result of a comparison between two values.
188 ///
189 /// # Examples
190 ///
191 /// ```
192 /// use std::cmp::Ordering;
193 ///
194 /// let result = 1.cmp(&2);
195 /// assert_eq!(Ordering::Less, result);
196 ///
197 /// let result = 1.cmp(&1);
198 /// assert_eq!(Ordering::Equal, result);
199 ///
200 /// let result = 2.cmp(&1);
201 /// assert_eq!(Ordering::Greater, result);
202 /// ```
203 #[derive(Clone, Copy, PartialEq, Debug, Hash)]
204 #[stable(feature = "rust1", since = "1.0.0")]
205 pub enum Ordering {
206     /// An ordering where a compared value is less [than another].
207     #[stable(feature = "rust1", since = "1.0.0")]
208     Less = -1,
209     /// An ordering where a compared value is equal [to another].
210     #[stable(feature = "rust1", since = "1.0.0")]
211     Equal = 0,
212     /// An ordering where a compared value is greater [than another].
213     #[stable(feature = "rust1", since = "1.0.0")]
214     Greater = 1,
215 }
216
217 impl Ordering {
218     /// Reverses the `Ordering`.
219     ///
220     /// * `Less` becomes `Greater`.
221     /// * `Greater` becomes `Less`.
222     /// * `Equal` becomes `Equal`.
223     ///
224     /// # Examples
225     ///
226     /// Basic behavior:
227     ///
228     /// ```
229     /// use std::cmp::Ordering;
230     ///
231     /// assert_eq!(Ordering::Less.reverse(), Ordering::Greater);
232     /// assert_eq!(Ordering::Equal.reverse(), Ordering::Equal);
233     /// assert_eq!(Ordering::Greater.reverse(), Ordering::Less);
234     /// ```
235     ///
236     /// This method can be used to reverse a comparison:
237     ///
238     /// ```
239     /// let mut data: &mut [_] = &mut [2, 10, 5, 8];
240     ///
241     /// // sort the array from largest to smallest.
242     /// data.sort_by(|a, b| a.cmp(b).reverse());
243     ///
244     /// let b: &mut [_] = &mut [10, 8, 5, 2];
245     /// assert!(data == b);
246     /// ```
247     #[inline]
248     #[stable(feature = "rust1", since = "1.0.0")]
249     pub fn reverse(self) -> Ordering {
250         match self {
251             Less => Greater,
252             Equal => Equal,
253             Greater => Less,
254         }
255     }
256
257     /// Chains two orderings.
258     ///
259     /// Returns `self` when it's not `Equal`. Otherwise returns `other`.
260     /// # Examples
261     ///
262     /// ```
263     /// use std::cmp::Ordering;
264     ///
265     /// let result = Ordering::Equal.then(Ordering::Less);
266     /// assert_eq!(result, Ordering::Less);
267     ///
268     /// let result = Ordering::Less.then(Ordering::Equal);
269     /// assert_eq!(result, Ordering::Less);
270     ///
271     /// let result = Ordering::Less.then(Ordering::Greater);
272     /// assert_eq!(result, Ordering::Less);
273     ///
274     /// let result = Ordering::Equal.then(Ordering::Equal);
275     /// assert_eq!(result, Ordering::Equal);
276     ///
277     /// let x: (i64, i64, i64) = (1, 2, 7);
278     /// let y: (i64, i64, i64) = (1, 5, 3);
279     /// let result = x.0.cmp(&y.0).then(x.1.cmp(&y.1)).then(x.2.cmp(&y.2));
280     ///
281     /// assert_eq!(result, Ordering::Less);
282     /// ```
283     #[inline]
284     #[stable(feature = "ordering_chaining", since = "1.17.0")]
285     pub fn then(self, other: Ordering) -> Ordering {
286         match self {
287             Equal => other,
288             _ => self,
289         }
290     }
291
292     /// Chains the ordering with the given function.
293     ///
294     /// Returns `self` when it's not `Equal`. Otherwise calls `f` and returns
295     /// the result.
296     ///
297     /// # Examples
298     ///
299     /// ```
300     /// use std::cmp::Ordering;
301     ///
302     /// let result = Ordering::Equal.then_with(|| Ordering::Less);
303     /// assert_eq!(result, Ordering::Less);
304     ///
305     /// let result = Ordering::Less.then_with(|| Ordering::Equal);
306     /// assert_eq!(result, Ordering::Less);
307     ///
308     /// let result = Ordering::Less.then_with(|| Ordering::Greater);
309     /// assert_eq!(result, Ordering::Less);
310     ///
311     /// let result = Ordering::Equal.then_with(|| Ordering::Equal);
312     /// assert_eq!(result, Ordering::Equal);
313     ///
314     /// let x: (i64, i64, i64) = (1, 2, 7);
315     /// let y: (i64, i64, i64)  = (1, 5, 3);
316     /// let result = x.0.cmp(&y.0).then_with(|| x.1.cmp(&y.1)).then_with(|| x.2.cmp(&y.2));
317     ///
318     /// assert_eq!(result, Ordering::Less);
319     /// ```
320     #[inline]
321     #[stable(feature = "ordering_chaining", since = "1.17.0")]
322     pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
323         match self {
324             Equal => f(),
325             _ => self,
326         }
327     }
328 }
329
330 /// A helper struct for reverse ordering.
331 ///
332 /// This struct is a helper to be used with functions like `Vec::sort_by_key` and
333 /// can be used to reverse order a part of a key.
334 ///
335 /// Example usage:
336 ///
337 /// ```
338 /// #![feature(reverse_cmp_key)]
339 /// use std::cmp::Reverse;
340 ///
341 /// let mut v = vec![1, 2, 3, 4, 5, 6];
342 /// v.sort_by_key(|&num| (num > 3, Reverse(num)));
343 /// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
344 /// ```
345 #[derive(PartialEq, Eq, Debug)]
346 #[unstable(feature = "reverse_cmp_key", issue = "40893")]
347 pub struct Reverse<T>(pub T);
348
349 #[unstable(feature = "reverse_cmp_key", issue = "40893")]
350 impl<T: PartialOrd> PartialOrd for Reverse<T> {
351     #[inline]
352     fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
353         other.0.partial_cmp(&self.0)
354     }
355
356     #[inline]
357     fn lt(&self, other: &Self) -> bool { other.0 < self.0 }
358     #[inline]
359     fn le(&self, other: &Self) -> bool { other.0 <= self.0 }
360     #[inline]
361     fn ge(&self, other: &Self) -> bool { other.0 >= self.0 }
362     #[inline]
363     fn gt(&self, other: &Self) -> bool { other.0 > self.0 }
364 }
365
366 #[unstable(feature = "reverse_cmp_key", issue = "40893")]
367 impl<T: Ord> Ord for Reverse<T> {
368     #[inline]
369     fn cmp(&self, other: &Reverse<T>) -> Ordering {
370         other.0.cmp(&self.0)
371     }
372 }
373
374 /// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
375 ///
376 /// An order is a total order if it is (for all `a`, `b` and `c`):
377 ///
378 /// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and
379 /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
380 ///
381 /// ## Derivable
382 ///
383 /// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
384 /// ordering based on the top-to-bottom declaration order of the struct's members.
385 ///
386 /// ## How can I implement `Ord`?
387 ///
388 /// `Ord` requires that the type also be `PartialOrd` and `Eq` (which requires `PartialEq`).
389 ///
390 /// Then you must define an implementation for `cmp()`. You may find it useful to use
391 /// `cmp()` on your type's fields.
392 ///
393 /// Implementations of `PartialEq`, `PartialOrd`, and `Ord` *must* agree with each other. It's
394 /// easy to accidentally make them disagree by deriving some of the traits and manually
395 /// implementing others.
396 ///
397 /// Here's an example where you want to sort people by height only, disregarding `id`
398 /// and `name`:
399 ///
400 /// ```
401 /// use std::cmp::Ordering;
402 ///
403 /// #[derive(Eq)]
404 /// struct Person {
405 ///     id: u32,
406 ///     name: String,
407 ///     height: u32,
408 /// }
409 ///
410 /// impl Ord for Person {
411 ///     fn cmp(&self, other: &Person) -> Ordering {
412 ///         self.height.cmp(&other.height)
413 ///     }
414 /// }
415 ///
416 /// impl PartialOrd for Person {
417 ///     fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
418 ///         Some(self.cmp(other))
419 ///     }
420 /// }
421 ///
422 /// impl PartialEq for Person {
423 ///     fn eq(&self, other: &Person) -> bool {
424 ///         self.height == other.height
425 ///     }
426 /// }
427 /// ```
428 #[stable(feature = "rust1", since = "1.0.0")]
429 pub trait Ord: Eq + PartialOrd<Self> {
430     /// This method returns an `Ordering` between `self` and `other`.
431     ///
432     /// By convention, `self.cmp(&other)` returns the ordering matching the expression
433     /// `self <operator> other` if true.
434     ///
435     /// # Examples
436     ///
437     /// ```
438     /// use std::cmp::Ordering;
439     ///
440     /// assert_eq!(5.cmp(&10), Ordering::Less);
441     /// assert_eq!(10.cmp(&5), Ordering::Greater);
442     /// assert_eq!(5.cmp(&5), Ordering::Equal);
443     /// ```
444     #[stable(feature = "rust1", since = "1.0.0")]
445     fn cmp(&self, other: &Self) -> Ordering;
446 }
447
448 #[stable(feature = "rust1", since = "1.0.0")]
449 impl Eq for Ordering {}
450
451 #[stable(feature = "rust1", since = "1.0.0")]
452 impl Ord for Ordering {
453     #[inline]
454     fn cmp(&self, other: &Ordering) -> Ordering {
455         (*self as i32).cmp(&(*other as i32))
456     }
457 }
458
459 #[stable(feature = "rust1", since = "1.0.0")]
460 impl PartialOrd for Ordering {
461     #[inline]
462     fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
463         (*self as i32).partial_cmp(&(*other as i32))
464     }
465 }
466
467 /// Trait for values that can be compared for a sort-order.
468 ///
469 /// The comparison must satisfy, for all `a`, `b` and `c`:
470 ///
471 /// - antisymmetry: if `a < b` then `!(a > b)`, as well as `a > b` implying `!(a < b)`; and
472 /// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
473 ///
474 /// Note that these requirements mean that the trait itself must be implemented symmetrically and
475 /// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
476 /// PartialOrd<V>`.
477 ///
478 /// ## Derivable
479 ///
480 /// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
481 /// ordering based on the top-to-bottom declaration order of the struct's members.
482 ///
483 /// ## How can I implement `PartialOrd`?
484 ///
485 /// `PartialOrd` only requires implementation of the `partial_cmp` method, with the others
486 /// generated from default implementations.
487 ///
488 /// However it remains possible to implement the others separately for types which do not have a
489 /// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
490 /// false` (cf. IEEE 754-2008 section 5.11).
491 ///
492 /// `PartialOrd` requires your type to be `PartialEq`.
493 ///
494 /// Implementations of `PartialEq`, `PartialOrd`, and `Ord` *must* agree with each other. It's
495 /// easy to accidentally make them disagree by deriving some of the traits and manually
496 /// implementing others.
497 ///
498 /// If your type is `Ord`, you can implement `partial_cmp()` by using `cmp()`:
499 ///
500 /// ```
501 /// use std::cmp::Ordering;
502 ///
503 /// #[derive(Eq)]
504 /// struct Person {
505 ///     id: u32,
506 ///     name: String,
507 ///     height: u32,
508 /// }
509 ///
510 /// impl PartialOrd for Person {
511 ///     fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
512 ///         Some(self.cmp(other))
513 ///     }
514 /// }
515 ///
516 /// impl Ord for Person {
517 ///     fn cmp(&self, other: &Person) -> Ordering {
518 ///         self.height.cmp(&other.height)
519 ///     }
520 /// }
521 ///
522 /// impl PartialEq for Person {
523 ///     fn eq(&self, other: &Person) -> bool {
524 ///         self.height == other.height
525 ///     }
526 /// }
527 /// ```
528 ///
529 /// You may also find it useful to use `partial_cmp()` on your type's fields. Here
530 /// is an example of `Person` types who have a floating-point `height` field that
531 /// is the only field to be used for sorting:
532 ///
533 /// ```
534 /// use std::cmp::Ordering;
535 ///
536 /// struct Person {
537 ///     id: u32,
538 ///     name: String,
539 ///     height: f64,
540 /// }
541 ///
542 /// impl PartialOrd for Person {
543 ///     fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
544 ///         self.height.partial_cmp(&other.height)
545 ///     }
546 /// }
547 ///
548 /// impl PartialEq for Person {
549 ///     fn eq(&self, other: &Person) -> bool {
550 ///         self.height == other.height
551 ///     }
552 /// }
553 /// ```
554 ///
555 /// # Examples
556 ///
557 /// ```
558 /// let x : u32 = 0;
559 /// let y : u32 = 1;
560 ///
561 /// assert_eq!(x < y, true);
562 /// assert_eq!(x.lt(&y), true);
563 /// ```
564 #[lang = "ord"]
565 #[stable(feature = "rust1", since = "1.0.0")]
566 #[rustc_on_unimplemented = "can't compare `{Self}` with `{Rhs}`"]
567 pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
568     /// This method returns an ordering between `self` and `other` values if one exists.
569     ///
570     /// # Examples
571     ///
572     /// ```
573     /// use std::cmp::Ordering;
574     ///
575     /// let result = 1.0.partial_cmp(&2.0);
576     /// assert_eq!(result, Some(Ordering::Less));
577     ///
578     /// let result = 1.0.partial_cmp(&1.0);
579     /// assert_eq!(result, Some(Ordering::Equal));
580     ///
581     /// let result = 2.0.partial_cmp(&1.0);
582     /// assert_eq!(result, Some(Ordering::Greater));
583     /// ```
584     ///
585     /// When comparison is impossible:
586     ///
587     /// ```
588     /// let result = std::f64::NAN.partial_cmp(&1.0);
589     /// assert_eq!(result, None);
590     /// ```
591     #[stable(feature = "rust1", since = "1.0.0")]
592     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
593
594     /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
595     ///
596     /// # Examples
597     ///
598     /// ```
599     /// let result = 1.0 < 2.0;
600     /// assert_eq!(result, true);
601     ///
602     /// let result = 2.0 < 1.0;
603     /// assert_eq!(result, false);
604     /// ```
605     #[inline]
606     #[stable(feature = "rust1", since = "1.0.0")]
607     fn lt(&self, other: &Rhs) -> bool {
608         match self.partial_cmp(other) {
609             Some(Less) => true,
610             _ => false,
611         }
612     }
613
614     /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
615     /// operator.
616     ///
617     /// # Examples
618     ///
619     /// ```
620     /// let result = 1.0 <= 2.0;
621     /// assert_eq!(result, true);
622     ///
623     /// let result = 2.0 <= 2.0;
624     /// assert_eq!(result, true);
625     /// ```
626     #[inline]
627     #[stable(feature = "rust1", since = "1.0.0")]
628     fn le(&self, other: &Rhs) -> bool {
629         match self.partial_cmp(other) {
630             Some(Less) | Some(Equal) => true,
631             _ => false,
632         }
633     }
634
635     /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
636     ///
637     /// # Examples
638     ///
639     /// ```
640     /// let result = 1.0 > 2.0;
641     /// assert_eq!(result, false);
642     ///
643     /// let result = 2.0 > 2.0;
644     /// assert_eq!(result, false);
645     /// ```
646     #[inline]
647     #[stable(feature = "rust1", since = "1.0.0")]
648     fn gt(&self, other: &Rhs) -> bool {
649         match self.partial_cmp(other) {
650             Some(Greater) => true,
651             _ => false,
652         }
653     }
654
655     /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
656     /// operator.
657     ///
658     /// # Examples
659     ///
660     /// ```
661     /// let result = 2.0 >= 1.0;
662     /// assert_eq!(result, true);
663     ///
664     /// let result = 2.0 >= 2.0;
665     /// assert_eq!(result, true);
666     /// ```
667     #[inline]
668     #[stable(feature = "rust1", since = "1.0.0")]
669     fn ge(&self, other: &Rhs) -> bool {
670         match self.partial_cmp(other) {
671             Some(Greater) | Some(Equal) => true,
672             _ => false,
673         }
674     }
675 }
676
677 /// Compares and returns the minimum of two values.
678 ///
679 /// Returns the first argument if the comparison determines them to be equal.
680 ///
681 /// # Examples
682 ///
683 /// ```
684 /// use std::cmp;
685 ///
686 /// assert_eq!(1, cmp::min(1, 2));
687 /// assert_eq!(2, cmp::min(2, 2));
688 /// ```
689 #[inline]
690 #[stable(feature = "rust1", since = "1.0.0")]
691 pub fn min<T: Ord>(v1: T, v2: T) -> T {
692     if v1 <= v2 { v1 } else { v2 }
693 }
694
695 /// Compares and returns the maximum of two values.
696 ///
697 /// Returns the second argument if the comparison determines them to be equal.
698 ///
699 /// # Examples
700 ///
701 /// ```
702 /// use std::cmp;
703 ///
704 /// assert_eq!(2, cmp::max(1, 2));
705 /// assert_eq!(2, cmp::max(2, 2));
706 /// ```
707 #[inline]
708 #[stable(feature = "rust1", since = "1.0.0")]
709 pub fn max<T: Ord>(v1: T, v2: T) -> T {
710     if v2 >= v1 { v2 } else { v1 }
711 }
712
713 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
714 mod impls {
715     use cmp::Ordering::{self, Less, Greater, Equal};
716
717     macro_rules! partial_eq_impl {
718         ($($t:ty)*) => ($(
719             #[stable(feature = "rust1", since = "1.0.0")]
720             impl PartialEq for $t {
721                 #[inline]
722                 fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
723                 #[inline]
724                 fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
725             }
726         )*)
727     }
728
729     #[stable(feature = "rust1", since = "1.0.0")]
730     impl PartialEq for () {
731         #[inline]
732         fn eq(&self, _other: &()) -> bool { true }
733         #[inline]
734         fn ne(&self, _other: &()) -> bool { false }
735     }
736
737     partial_eq_impl! {
738         bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
739     }
740
741     macro_rules! eq_impl {
742         ($($t:ty)*) => ($(
743             #[stable(feature = "rust1", since = "1.0.0")]
744             impl Eq for $t {}
745         )*)
746     }
747
748     eq_impl! { () bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
749
750     macro_rules! partial_ord_impl {
751         ($($t:ty)*) => ($(
752             #[stable(feature = "rust1", since = "1.0.0")]
753             impl PartialOrd for $t {
754                 #[inline]
755                 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
756                     match (self <= other, self >= other) {
757                         (false, false) => None,
758                         (false, true) => Some(Greater),
759                         (true, false) => Some(Less),
760                         (true, true) => Some(Equal),
761                     }
762                 }
763                 #[inline]
764                 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
765                 #[inline]
766                 fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
767                 #[inline]
768                 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
769                 #[inline]
770                 fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
771             }
772         )*)
773     }
774
775     #[stable(feature = "rust1", since = "1.0.0")]
776     impl PartialOrd for () {
777         #[inline]
778         fn partial_cmp(&self, _: &()) -> Option<Ordering> {
779             Some(Equal)
780         }
781     }
782
783     #[stable(feature = "rust1", since = "1.0.0")]
784     impl PartialOrd for bool {
785         #[inline]
786         fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
787             (*self as u8).partial_cmp(&(*other as u8))
788         }
789     }
790
791     partial_ord_impl! { f32 f64 }
792
793     macro_rules! ord_impl {
794         ($($t:ty)*) => ($(
795             #[stable(feature = "rust1", since = "1.0.0")]
796             impl PartialOrd for $t {
797                 #[inline]
798                 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
799                     Some(self.cmp(other))
800                 }
801                 #[inline]
802                 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
803                 #[inline]
804                 fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
805                 #[inline]
806                 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
807                 #[inline]
808                 fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
809             }
810
811             #[stable(feature = "rust1", since = "1.0.0")]
812             impl Ord for $t {
813                 #[inline]
814                 fn cmp(&self, other: &$t) -> Ordering {
815                     if *self == *other { Equal }
816                     else if *self < *other { Less }
817                     else { Greater }
818                 }
819             }
820         )*)
821     }
822
823     #[stable(feature = "rust1", since = "1.0.0")]
824     impl Ord for () {
825         #[inline]
826         fn cmp(&self, _other: &()) -> Ordering { Equal }
827     }
828
829     #[stable(feature = "rust1", since = "1.0.0")]
830     impl Ord for bool {
831         #[inline]
832         fn cmp(&self, other: &bool) -> Ordering {
833             (*self as u8).cmp(&(*other as u8))
834         }
835     }
836
837     ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
838
839     #[unstable(feature = "never_type_impls", issue = "35121")]
840     impl PartialEq for ! {
841         fn eq(&self, _: &!) -> bool {
842             *self
843         }
844     }
845
846     #[unstable(feature = "never_type_impls", issue = "35121")]
847     impl Eq for ! {}
848
849     #[unstable(feature = "never_type_impls", issue = "35121")]
850     impl PartialOrd for ! {
851         fn partial_cmp(&self, _: &!) -> Option<Ordering> {
852             *self
853         }
854     }
855
856     #[unstable(feature = "never_type_impls", issue = "35121")]
857     impl Ord for ! {
858         fn cmp(&self, _: &!) -> Ordering {
859             *self
860         }
861     }
862
863     // & pointers
864
865     #[stable(feature = "rust1", since = "1.0.0")]
866     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a A where A: PartialEq<B> {
867         #[inline]
868         fn eq(&self, other: & &'b B) -> bool { PartialEq::eq(*self, *other) }
869         #[inline]
870         fn ne(&self, other: & &'b B) -> bool { PartialEq::ne(*self, *other) }
871     }
872     #[stable(feature = "rust1", since = "1.0.0")]
873     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> {
874         #[inline]
875         fn partial_cmp(&self, other: &&'b B) -> Option<Ordering> {
876             PartialOrd::partial_cmp(*self, *other)
877         }
878         #[inline]
879         fn lt(&self, other: & &'b B) -> bool { PartialOrd::lt(*self, *other) }
880         #[inline]
881         fn le(&self, other: & &'b B) -> bool { PartialOrd::le(*self, *other) }
882         #[inline]
883         fn ge(&self, other: & &'b B) -> bool { PartialOrd::ge(*self, *other) }
884         #[inline]
885         fn gt(&self, other: & &'b B) -> bool { PartialOrd::gt(*self, *other) }
886     }
887     #[stable(feature = "rust1", since = "1.0.0")]
888     impl<'a, A: ?Sized> Ord for &'a A where A: Ord {
889         #[inline]
890         fn cmp(&self, other: & &'a A) -> Ordering { Ord::cmp(*self, *other) }
891     }
892     #[stable(feature = "rust1", since = "1.0.0")]
893     impl<'a, A: ?Sized> Eq for &'a A where A: Eq {}
894
895     // &mut pointers
896
897     #[stable(feature = "rust1", since = "1.0.0")]
898     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> {
899         #[inline]
900         fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
901         #[inline]
902         fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
903     }
904     #[stable(feature = "rust1", since = "1.0.0")]
905     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> {
906         #[inline]
907         fn partial_cmp(&self, other: &&'b mut B) -> Option<Ordering> {
908             PartialOrd::partial_cmp(*self, *other)
909         }
910         #[inline]
911         fn lt(&self, other: &&'b mut B) -> bool { PartialOrd::lt(*self, *other) }
912         #[inline]
913         fn le(&self, other: &&'b mut B) -> bool { PartialOrd::le(*self, *other) }
914         #[inline]
915         fn ge(&self, other: &&'b mut B) -> bool { PartialOrd::ge(*self, *other) }
916         #[inline]
917         fn gt(&self, other: &&'b mut B) -> bool { PartialOrd::gt(*self, *other) }
918     }
919     #[stable(feature = "rust1", since = "1.0.0")]
920     impl<'a, A: ?Sized> Ord for &'a mut A where A: Ord {
921         #[inline]
922         fn cmp(&self, other: &&'a mut A) -> Ordering { Ord::cmp(*self, *other) }
923     }
924     #[stable(feature = "rust1", since = "1.0.0")]
925     impl<'a, A: ?Sized> Eq for &'a mut A where A: Eq {}
926
927     #[stable(feature = "rust1", since = "1.0.0")]
928     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> {
929         #[inline]
930         fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
931         #[inline]
932         fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
933     }
934
935     #[stable(feature = "rust1", since = "1.0.0")]
936     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> {
937         #[inline]
938         fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) }
939         #[inline]
940         fn ne(&self, other: &&'b B) -> bool { PartialEq::ne(*self, *other) }
941     }
942 }