]> git.lizzy.rs Git - rust.git/blob - src/libcore/cmp.rs
auto merge of #15421 : catharsis/rust/doc-ffi-minor-fixes, r=alexcrichton
[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 //! Defines the `PartialOrd` and `PartialEq` comparison traits.
12 //!
13 //! This module defines both `PartialOrd` and `PartialEq` traits which are used by the
14 //! compiler to implement comparison operators. Rust programs may implement
15 //!`PartialOrd` to overload the `<`, `<=`, `>`, and `>=` operators, and may implement
16 //! `PartialEq` to overload the `==` and `!=` operators.
17 //!
18 //! For example, to define a type with a customized definition for the PartialEq
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 `PartialEq` to support `==` and `!=`.
28 //! impl PartialEq 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 use option::{Option, Some};
41
42 /// Trait for values that can be compared for equality and inequality.
43 ///
44 /// This trait allows for partial equality, for types that do not have an
45 /// equivalence relation. For example, in floating point numbers `NaN != NaN`,
46 /// so floating point types implement `PartialEq` but not `Eq`.
47 ///
48 /// PartialEq only requires the `eq` method to be implemented; `ne` is defined
49 /// in terms of it by default. Any manual implementation of `ne` *must* respect
50 /// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
51 /// only if `a != b`.
52 ///
53 /// Eventually, this will be implemented by default for types that implement
54 /// `Eq`.
55 #[lang="eq"]
56 pub trait PartialEq {
57     /// This method tests for `self` and `other` values to be equal, and is used by `==`.
58     fn eq(&self, other: &Self) -> bool;
59
60     /// This method tests for `!=`.
61     #[inline]
62     fn ne(&self, other: &Self) -> bool { !self.eq(other) }
63 }
64
65 /// Trait for equality comparisons which are [equivalence relations](
66 /// https://en.wikipedia.org/wiki/Equivalence_relation).
67 ///
68 /// This means, that in addition to `a == b` and `a != b` being strict
69 /// inverses, the equality must be (for all `a`, `b` and `c`):
70 ///
71 /// - reflexive: `a == a`;
72 /// - symmetric: `a == b` implies `b == a`; and
73 /// - transitive: `a == b` and `b == c` implies `a == c`.
74 pub trait Eq: PartialEq {
75     // FIXME #13101: this method is used solely by #[deriving] to
76     // assert that every component of a type implements #[deriving]
77     // itself, the current deriving infrastructure means doing this
78     // assertion without using a method on this trait is nearly
79     // impossible.
80     //
81     // This should never be implemented by hand.
82     #[doc(hidden)]
83     #[inline(always)]
84     fn assert_receiver_is_total_eq(&self) {}
85 }
86
87 /// An ordering is, e.g, a result of a comparison between two values.
88 #[deriving(Clone, PartialEq, Show)]
89 pub enum Ordering {
90    /// An ordering where a compared value is less [than another].
91    Less = -1i,
92    /// An ordering where a compared value is equal [to another].
93    Equal = 0i,
94    /// An ordering where a compared value is greater [than another].
95    Greater = 1i,
96 }
97
98 /// Trait for types that form a [total order](
99 /// https://en.wikipedia.org/wiki/Total_order).
100 ///
101 /// An order is a total order if it is (for all `a`, `b` and `c`):
102 ///
103 /// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is
104 ///   true; and
105 /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
106 ///   both `==` and `>`.
107 pub trait Ord: Eq + PartialOrd {
108     /// This method returns an ordering between `self` and `other` values.
109     ///
110     /// By convention, `self.cmp(&other)` returns the ordering matching
111     /// the expression `self <operator> other` if true.  For example:
112     ///
113     /// ```
114     /// assert_eq!( 5u.cmp(&10), Less);     // because 5 < 10
115     /// assert_eq!(10u.cmp(&5),  Greater);  // because 10 > 5
116     /// assert_eq!( 5u.cmp(&5),  Equal);    // because 5 == 5
117     /// ```
118     fn cmp(&self, other: &Self) -> Ordering;
119 }
120
121 impl Eq for Ordering {}
122
123 impl Ord for Ordering {
124     #[inline]
125     fn cmp(&self, other: &Ordering) -> Ordering {
126         (*self as int).cmp(&(*other as int))
127     }
128 }
129
130 impl PartialOrd for Ordering {
131     #[inline]
132     fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
133         (*self as int).partial_cmp(&(*other as int))
134     }
135 }
136
137 /// Combine orderings, lexically.
138 ///
139 /// For example for a type `(int, int)`, two comparisons could be done.
140 /// If the first ordering is different, the first ordering is all that must be returned.
141 /// If the first ordering is equal, then second ordering is returned.
142 #[inline]
143 pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
144     match o1 {
145         Equal => o2,
146         _ => o1
147     }
148 }
149
150 /// Trait for values that can be compared for a sort-order.
151 ///
152 /// PartialOrd only requires implementation of the `partial_cmp` method,
153 /// with the others generated from default implementations.
154 ///
155 /// However it remains possible to implement the others separately for types
156 /// which do not have a total order. For example, for floating point numbers,
157 /// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
158 /// 5.11).
159 #[lang="ord"]
160 pub trait PartialOrd: PartialEq {
161     /// This method returns an ordering between `self` and `other` values
162     /// if one exists.
163     fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
164
165     /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
166     fn lt(&self, other: &Self) -> bool {
167         match self.partial_cmp(other) {
168             Some(Less) => true,
169             _ => false,
170         }
171     }
172
173     /// This method tests less than or equal to (`<=`).
174     #[inline]
175     fn le(&self, other: &Self) -> bool {
176         match self.partial_cmp(other) {
177             Some(Less) | Some(Equal) => true,
178             _ => false,
179         }
180     }
181
182     /// This method tests greater than (`>`).
183     #[inline]
184     fn gt(&self, other: &Self) -> bool {
185         match self.partial_cmp(other) {
186             Some(Greater) => true,
187             _ => false,
188         }
189     }
190
191     /// This method tests greater than or equal to (`>=`).
192     #[inline]
193     fn ge(&self, other: &Self) -> bool {
194         match self.partial_cmp(other) {
195             Some(Greater) | Some(Equal) => true,
196             _ => false,
197         }
198     }
199 }
200
201 /// The equivalence relation. Two values may be equivalent even if they are
202 /// of different types. The most common use case for this relation is
203 /// container types; e.g. it is often desirable to be able to use `&str`
204 /// values to look up entries in a container with `String` keys.
205 pub trait Equiv<T> {
206     /// Implement this function to decide equivalent values.
207     fn equiv(&self, other: &T) -> bool;
208 }
209
210 /// Compare and return the minimum of two values.
211 #[inline]
212 pub fn min<T: Ord>(v1: T, v2: T) -> T {
213     if v1 < v2 { v1 } else { v2 }
214 }
215
216 /// Compare and return the maximum of two values.
217 #[inline]
218 pub fn max<T: Ord>(v1: T, v2: T) -> T {
219     if v1 > v2 { v1 } else { v2 }
220 }
221
222 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
223 mod impls {
224     use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering,
225               Less, Greater, Equal};
226     use option::{Option, Some, None};
227
228     macro_rules! eq_impl(
229         ($($t:ty)*) => ($(
230             impl PartialEq for $t {
231                 #[inline]
232                 fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
233                 #[inline]
234                 fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
235             }
236         )*)
237     )
238
239     impl PartialEq for () {
240         #[inline]
241         fn eq(&self, _other: &()) -> bool { true }
242         #[inline]
243         fn ne(&self, _other: &()) -> bool { false }
244     }
245
246     eq_impl!(bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
247
248     macro_rules! totaleq_impl(
249         ($($t:ty)*) => ($(
250             impl Eq for $t {}
251         )*)
252     )
253
254     totaleq_impl!(() bool char uint u8 u16 u32 u64 int i8 i16 i32 i64)
255
256     macro_rules! ord_impl(
257         ($($t:ty)*) => ($(
258             impl PartialOrd for $t {
259                 #[inline]
260                 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
261                     match (self <= other, self >= other) {
262                         (false, false) => None,
263                         (false, true) => Some(Greater),
264                         (true, false) => Some(Less),
265                         (true, true) => Some(Equal),
266                     }
267                 }
268                 #[inline]
269                 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
270                 #[inline]
271                 fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
272                 #[inline]
273                 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
274                 #[inline]
275                 fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
276             }
277         )*)
278     )
279
280     impl PartialOrd for () {
281         #[inline]
282         fn partial_cmp(&self, _: &()) -> Option<Ordering> {
283             Some(Equal)
284         }
285     }
286
287     impl PartialOrd for bool {
288         #[inline]
289         fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
290             (*self as u8).partial_cmp(&(*other as u8))
291         }
292     }
293
294     ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
295
296     macro_rules! totalord_impl(
297         ($($t:ty)*) => ($(
298             impl Ord for $t {
299                 #[inline]
300                 fn cmp(&self, other: &$t) -> Ordering {
301                     if *self < *other { Less }
302                     else if *self > *other { Greater }
303                     else { Equal }
304                 }
305             }
306         )*)
307     )
308
309     impl Ord for () {
310         #[inline]
311         fn cmp(&self, _other: &()) -> Ordering { Equal }
312     }
313
314     impl Ord for bool {
315         #[inline]
316         fn cmp(&self, other: &bool) -> Ordering {
317             (*self as u8).cmp(&(*other as u8))
318         }
319     }
320
321     totalord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64)
322
323     // & pointers
324     impl<'a, T: PartialEq> PartialEq for &'a T {
325         #[inline]
326         fn eq(&self, other: & &'a T) -> bool { *(*self) == *(*other) }
327         #[inline]
328         fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) }
329     }
330     impl<'a, T: PartialOrd> PartialOrd for &'a T {
331         #[inline]
332         fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
333             (**self).partial_cmp(*other)
334         }
335         #[inline]
336         fn lt(&self, other: & &'a T) -> bool { *(*self) < *(*other) }
337         #[inline]
338         fn le(&self, other: & &'a T) -> bool { *(*self) <= *(*other) }
339         #[inline]
340         fn ge(&self, other: & &'a T) -> bool { *(*self) >= *(*other) }
341         #[inline]
342         fn gt(&self, other: & &'a T) -> bool { *(*self) > *(*other) }
343     }
344     impl<'a, T: Ord> Ord for &'a T {
345         #[inline]
346         fn cmp(&self, other: & &'a T) -> Ordering { (**self).cmp(*other) }
347     }
348     impl<'a, T: Eq> Eq for &'a T {}
349
350     // &mut pointers
351     impl<'a, T: PartialEq> PartialEq for &'a mut T {
352         #[inline]
353         fn eq(&self, other: &&'a mut T) -> bool { **self == *(*other) }
354         #[inline]
355         fn ne(&self, other: &&'a mut T) -> bool { **self != *(*other) }
356     }
357     impl<'a, T: PartialOrd> PartialOrd for &'a mut T {
358         #[inline]
359         fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
360             (**self).partial_cmp(*other)
361         }
362         #[inline]
363         fn lt(&self, other: &&'a mut T) -> bool { **self < **other }
364         #[inline]
365         fn le(&self, other: &&'a mut T) -> bool { **self <= **other }
366         #[inline]
367         fn ge(&self, other: &&'a mut T) -> bool { **self >= **other }
368         #[inline]
369         fn gt(&self, other: &&'a mut T) -> bool { **self > **other }
370     }
371     impl<'a, T: Ord> Ord for &'a mut T {
372         #[inline]
373         fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) }
374     }
375     impl<'a, T: Eq> Eq for &'a mut T {}
376 }