10
10
11
11
/*!
12
12
13
- The `Ord` and `Eq` comparison traits
13
+ Defines the `Ord` and `Eq` comparison traits.
14
14
15
- This module contains the definition of both `Ord` and `Eq` which define
16
- the common interfaces for doing comparison. Both are language items
17
- that the compiler uses to implement the comparison operators. Rust code
18
- may implement `Ord` to overload the `<`, `<=`, `>`, and `>=` operators,
19
- and `Eq` to overload the `==` and `!=` operators.
15
+ This module defines both `Ord` and `Eq` traits which are used by the compiler
16
+ to implement comparison operators.
17
+ Rust programs may implement `Ord` to overload the `<`, `<=`, `>`, and `>=` operators,
18
+ and may implement `Eq` to overload the `==` and `!=` operators.
20
19
21
- */
20
+ For example, to define a type with a customized definition for the Eq operators,
21
+ you could do the following:
22
+
23
+ ```rust
24
+ // Our type.
25
+ struct SketchyNum {
26
+ num : int
27
+ }
28
+
29
+ // Our implementation of `Eq` to support `==` and `!=`.
30
+ impl Eq for SketchyNum {
31
+ // Our custom eq allows numbers which are near eachother to be equal! :D
32
+ fn eq(&self, other: &SketchyNum) -> bool {
33
+ (self.num - other.num).abs() < 5
34
+ }
35
+ }
36
+
37
+ // Now these binary operators will work when applied!
38
+ assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
39
+ assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
40
+ ```
22
41
23
- #! [ allow ( missing_doc ) ]
42
+ */
24
43
25
44
/**
26
45
* Trait for values that can be compared for equality and inequality.
@@ -35,8 +54,10 @@ and `Eq` to overload the `==` and `!=` operators.
35
54
*/
36
55
#[ lang="eq" ]
37
56
pub trait Eq {
57
+ /// This method tests for `self` and `other` values to be equal, and is used by `==`.
38
58
fn eq ( & self , other : & Self ) -> bool ;
39
59
60
+ /// This method tests for `!=`.
40
61
#[ inline]
41
62
fn ne ( & self , other : & Self ) -> bool { !self . eq ( other) }
42
63
}
@@ -55,6 +76,7 @@ pub trait TotalEq: Eq {
55
76
fn assert_receiver_is_total_eq ( & self ) { }
56
77
}
57
78
79
+ /// A macro which defines an implementation of TotalEq for a given type.
58
80
macro_rules! totaleq_impl(
59
81
( $t: ty) => {
60
82
impl TotalEq for $t { }
@@ -78,11 +100,29 @@ totaleq_impl!(uint)
78
100
79
101
totaleq_impl ! ( char )
80
102
103
+ /// An ordering is, e.g, a result of a comparison between two values.
81
104
#[ deriving( Clone , Eq , Show ) ]
82
- pub enum Ordering { Less = -1 , Equal = 0 , Greater = 1 }
105
+ pub enum Ordering {
106
+ /// An ordering where a compared value is less [than another].
107
+ Less = -1 ,
108
+ /// An ordering where a compared value is equal [to another].
109
+ Equal = 0 ,
110
+ /// An ordering where a compared value is greater [than another].
111
+ Greater = 1
112
+ }
83
113
84
- /// Trait for types that form a total order
114
+ /// Trait for types that form a total order.
85
115
pub trait TotalOrd : TotalEq + Ord {
116
+ /// This method returns an ordering between `self` and `other` values.
117
+ ///
118
+ /// By convention, `self.cmp(&other)` returns the ordering matching
119
+ /// the expression `self <operator> other` if true. For example:
120
+ ///
121
+ /// ```
122
+ /// assert_eq!( 5u.cmp(&10), Less); // because 5 < 10
123
+ /// assert_eq!(10u.cmp(&5), Greater); // because 10 > 5
124
+ /// assert_eq!( 5u.cmp(&5), Equal); // because 5 == 5
125
+ /// ```
86
126
fn cmp ( & self , other : & Self ) -> Ordering ;
87
127
}
88
128
@@ -99,6 +139,7 @@ impl Ord for Ordering {
99
139
fn lt ( & self , other : & Ordering ) -> bool { ( * self as int ) < ( * other as int ) }
100
140
}
101
141
142
+ /// A macro which defines an implementation of TotalOrd for a given type.
102
143
macro_rules! totalord_impl(
103
144
( $t: ty) => {
104
145
impl TotalOrd for $t {
@@ -128,8 +169,11 @@ totalord_impl!(uint)
128
169
totalord_impl ! ( char )
129
170
130
171
/**
131
- Return `o1` if it is not `Equal`, otherwise `o2`. Simulates the
132
- lexical ordering on a type `(int, int)`.
172
+ * Combine orderings, lexically.
173
+ *
174
+ * For example for a type `(int, int)`, two comparisons could be done.
175
+ * If the first ordering is different, the first ordering is all that must be returned.
176
+ * If the first ordering is equal, then second ordering is returned.
133
177
*/
134
178
#[ inline]
135
179
pub fn lexical_ordering ( o1 : Ordering , o2 : Ordering ) -> Ordering {
@@ -151,11 +195,18 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
151
195
*/
152
196
#[ lang="ord" ]
153
197
pub trait Ord : Eq {
198
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
154
199
fn lt ( & self , other : & Self ) -> bool ;
200
+
201
+ /// This method tests less than or equal to (`<=`).
155
202
#[ inline]
156
203
fn le ( & self , other : & Self ) -> bool { !other. lt ( self ) }
204
+
205
+ /// This method tests greater than (`>`).
157
206
#[ inline]
158
207
fn gt ( & self , other : & Self ) -> bool { other. lt ( self ) }
208
+
209
+ /// This method tests greater than or equal to (`>=`).
159
210
#[ inline]
160
211
fn ge ( & self , other : & Self ) -> bool { !self . lt ( other) }
161
212
}
@@ -165,14 +216,17 @@ pub trait Ord: Eq {
165
216
/// container types; e.g. it is often desirable to be able to use `&str`
166
217
/// values to look up entries in a container with `~str` keys.
167
218
pub trait Equiv < T > {
219
+ /// Implement this function to decide equivalent values.
168
220
fn equiv ( & self , other : & T ) -> bool ;
169
221
}
170
222
223
+ /// Compare and return the minimum of two values.
171
224
#[ inline]
172
225
pub fn min < T : TotalOrd > ( v1 : T , v2 : T ) -> T {
173
226
if v1 < v2 { v1 } else { v2 }
174
227
}
175
228
229
+ /// Compare and return the maximum of two values.
176
230
#[ inline]
177
231
pub fn max < T : TotalOrd > ( v1 : T , v2 : T ) -> T {
178
232
if v1 > v2 { v1 } else { v2 }
@@ -184,11 +238,11 @@ mod test {
184
238
185
239
#[ test]
186
240
fn test_int_totalord ( ) {
187
- assert_eq ! ( 5 . cmp( & 10 ) , Less ) ;
188
- assert_eq ! ( 10 . cmp( & 5 ) , Greater ) ;
189
- assert_eq ! ( 5 . cmp( & 5 ) , Equal ) ;
190
- assert_eq ! ( ( -5 ) . cmp( & 12 ) , Less ) ;
191
- assert_eq ! ( 12 . cmp( -5 ) , Greater ) ;
241
+ assert_eq ! ( 5 u . cmp( & 10 ) , Less ) ;
242
+ assert_eq ! ( 10 u . cmp( & 5 ) , Greater ) ;
243
+ assert_eq ! ( 5 u . cmp( & 5 ) , Equal ) ;
244
+ assert_eq ! ( ( -5 u ) . cmp( & 12 ) , Less ) ;
245
+ assert_eq ! ( 12 u . cmp( -5 ) , Greater ) ;
192
246
}
193
247
194
248
#[ test]
@@ -210,4 +264,24 @@ mod test {
210
264
t ( Greater , o, Greater ) ;
211
265
}
212
266
}
267
+
268
+ #[ test]
269
+ fn test_user_defined_eq ( ) {
270
+ // Our type.
271
+ struct SketchyNum {
272
+ num : int
273
+ }
274
+
275
+ // Our implementation of `Eq` to support `==` and `!=`.
276
+ impl Eq for SketchyNum {
277
+ // Our custom eq allows numbers which are near eachother to be equal! :D
278
+ fn eq ( & self , other : & SketchyNum ) -> bool {
279
+ ( self . num - other. num ) . abs ( ) < 5
280
+ }
281
+ }
282
+
283
+ // Now these binary operators will work when applied!
284
+ assert ! ( SketchyNum { num: 37 } == SketchyNum { num: 34 } ) ;
285
+ assert ! ( SketchyNum { num: 25 } != SketchyNum { num: 57 } ) ;
286
+ }
213
287
}
0 commit comments