37
37
//! assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
38
38
//! ```
39
39
40
+ use option:: { Option , Some } ;
41
+ #[ cfg( stage0) ]
42
+ use option:: None ;
43
+
40
44
/// Trait for values that can be compared for equality and inequality.
41
45
///
42
46
/// This trait allows for partial equality, for types that do not have an
@@ -127,7 +131,9 @@ impl Ord for Ordering {
127
131
128
132
impl PartialOrd for Ordering {
129
133
#[ inline]
130
- fn lt ( & self , other : & Ordering ) -> bool { ( * self as int ) < ( * other as int ) }
134
+ fn partial_cmp ( & self , other : & Ordering ) -> Option < Ordering > {
135
+ ( * self as int ) . partial_cmp ( & ( * other as int ) )
136
+ }
131
137
}
132
138
133
139
/// Combine orderings, lexically.
@@ -145,7 +151,7 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
145
151
146
152
/// Trait for values that can be compared for a sort-order.
147
153
///
148
- /// PartialOrd only requires implementation of the `lt ` method,
154
+ /// PartialOrd only requires implementation of the `partial_cmp ` method,
149
155
/// with the others generated from default implementations.
150
156
///
151
157
/// However it remains possible to implement the others separately for types
@@ -154,20 +160,57 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
154
160
/// 5.11).
155
161
#[ lang="ord" ]
156
162
pub trait PartialOrd : PartialEq {
163
+ /// This method returns an ordering between `self` and `other` values
164
+ /// if one exists.
165
+ #[ cfg( stage0) ]
166
+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
167
+ match ( !self . lt ( other) , !other. lt ( self ) ) {
168
+ ( false , false ) => None ,
169
+ ( false , true ) => Some ( Less ) ,
170
+ ( true , false ) => Some ( Greater ) ,
171
+ ( true , true ) => Some ( Equal ) ,
172
+ }
173
+ }
174
+
175
+ /// This method returns an ordering between `self` and `other` values
176
+ /// if one exists.
177
+ #[ cfg( not( stage0) ) ]
178
+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > ;
179
+
157
180
/// This method tests less than (for `self` and `other`) and is used by the `<` operator.
158
- fn lt ( & self , other : & Self ) -> bool ;
181
+ fn lt ( & self , other : & Self ) -> bool {
182
+ match self . partial_cmp ( other) {
183
+ Some ( Less ) => true ,
184
+ _ => false ,
185
+ }
186
+ }
159
187
160
188
/// This method tests less than or equal to (`<=`).
161
189
#[ inline]
162
- fn le ( & self , other : & Self ) -> bool { !other. lt ( self ) }
190
+ fn le ( & self , other : & Self ) -> bool {
191
+ match self . partial_cmp ( other) {
192
+ Some ( Less ) | Some ( Equal ) => true ,
193
+ _ => false ,
194
+ }
195
+ }
163
196
164
197
/// This method tests greater than (`>`).
165
198
#[ inline]
166
- fn gt ( & self , other : & Self ) -> bool { other. lt ( self ) }
199
+ fn gt ( & self , other : & Self ) -> bool {
200
+ match self . partial_cmp ( other) {
201
+ Some ( Greater ) => true ,
202
+ _ => false ,
203
+ }
204
+ }
167
205
168
206
/// This method tests greater than or equal to (`>=`).
169
207
#[ inline]
170
- fn ge ( & self , other : & Self ) -> bool { !self . lt ( other) }
208
+ fn ge ( & self , other : & Self ) -> bool {
209
+ match self . partial_cmp ( other) {
210
+ Some ( Greater ) | Some ( Equal ) => true ,
211
+ _ => false ,
212
+ }
213
+ }
171
214
}
172
215
173
216
/// The equivalence relation. Two values may be equivalent even if they are
@@ -195,6 +238,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
195
238
mod impls {
196
239
use cmp:: { PartialOrd , Ord , PartialEq , Eq , Ordering ,
197
240
Less , Greater , Equal } ;
241
+ use option:: { Option , Some , None } ;
198
242
199
243
macro_rules! eq_impl(
200
244
( $( $t: ty) * ) => ( $(
@@ -227,6 +271,15 @@ mod impls {
227
271
macro_rules! ord_impl(
228
272
( $( $t: ty) * ) => ( $(
229
273
impl PartialOrd for $t {
274
+ #[ inline]
275
+ fn partial_cmp( & self , other: & $t) -> Option <Ordering > {
276
+ match ( self <= other, self >= other) {
277
+ ( false , false ) => None ,
278
+ ( false , true ) => Some ( Greater ) ,
279
+ ( true , false ) => Some ( Less ) ,
280
+ ( true , true ) => Some ( Equal ) ,
281
+ }
282
+ }
230
283
#[ inline]
231
284
fn lt( & self , other: & $t) -> bool { ( * self ) < ( * other) }
232
285
#[ inline]
@@ -241,13 +294,15 @@ mod impls {
241
294
242
295
impl PartialOrd for ( ) {
243
296
#[ inline]
244
- fn lt ( & self , _other : & ( ) ) -> bool { false }
297
+ fn partial_cmp ( & self , _: & ( ) ) -> Option < Ordering > {
298
+ Some ( Equal )
299
+ }
245
300
}
246
301
247
302
impl PartialOrd for bool {
248
303
#[ inline]
249
- fn lt ( & self , other : & bool ) -> bool {
250
- ( * self as u8 ) < ( * other as u8 )
304
+ fn partial_cmp ( & self , other : & bool ) -> Option < Ordering > {
305
+ ( * self as u8 ) . partial_cmp ( & ( * other as u8 ) )
251
306
}
252
307
}
253
308
@@ -288,6 +343,10 @@ mod impls {
288
343
fn ne ( & self , other : & & ' a T ) -> bool { * ( * self ) != * ( * other) }
289
344
}
290
345
impl < ' a , T : PartialOrd > PartialOrd for & ' a T {
346
+ #[ inline]
347
+ fn partial_cmp ( & self , other : & & ' a T ) -> Option < Ordering > {
348
+ ( * * self ) . partial_cmp ( * other)
349
+ }
291
350
#[ inline]
292
351
fn lt ( & self , other : & & ' a T ) -> bool { * ( * self ) < * ( * other) }
293
352
#[ inline]
@@ -311,6 +370,10 @@ mod impls {
311
370
fn ne ( & self , other : & & ' a mut T ) -> bool { * * self != * ( * other) }
312
371
}
313
372
impl < ' a , T : PartialOrd > PartialOrd for & ' a mut T {
373
+ #[ inline]
374
+ fn partial_cmp ( & self , other : & & ' a mut T ) -> Option < Ordering > {
375
+ ( * * self ) . partial_cmp ( * other)
376
+ }
314
377
#[ inline]
315
378
fn lt ( & self , other : & & ' a mut T ) -> bool { * * self < * * other }
316
379
#[ inline]
0 commit comments