3737//! assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
3838//! ```
3939
40+ use option:: { Option , Some } ;
41+ #[ cfg( stage0) ]
42+ use option:: None ;
43+
4044/// Trait for values that can be compared for equality and inequality.
4145///
4246/// This trait allows for partial equality, for types that do not have an
@@ -127,7 +131,9 @@ impl Ord for Ordering {
127131
128132impl PartialOrd for Ordering {
129133 #[ 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+ }
131137}
132138
133139/// Combine orderings, lexically.
@@ -145,7 +151,7 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
145151
146152/// Trait for values that can be compared for a sort-order.
147153///
148- /// PartialOrd only requires implementation of the `lt ` method,
154+ /// PartialOrd only requires implementation of the `partial_cmp ` method,
149155/// with the others generated from default implementations.
150156///
151157/// However it remains possible to implement the others separately for types
@@ -154,20 +160,57 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
154160/// 5.11).
155161#[ lang="ord" ]
156162pub 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+
157180 /// 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+ }
159187
160188 /// This method tests less than or equal to (`<=`).
161189 #[ 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+ }
163196
164197 /// This method tests greater than (`>`).
165198 #[ 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+ }
167205
168206 /// This method tests greater than or equal to (`>=`).
169207 #[ 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+ }
171214}
172215
173216/// 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 {
195238mod impls {
196239 use cmp:: { PartialOrd , Ord , PartialEq , Eq , Ordering ,
197240 Less , Greater , Equal } ;
241+ use option:: { Option , Some , None } ;
198242
199243 macro_rules! eq_impl(
200244 ( $( $t: ty) * ) => ( $(
@@ -227,6 +271,15 @@ mod impls {
227271 macro_rules! ord_impl(
228272 ( $( $t: ty) * ) => ( $(
229273 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+ }
230283 #[ inline]
231284 fn lt( & self , other: & $t) -> bool { ( * self ) < ( * other) }
232285 #[ inline]
@@ -241,13 +294,15 @@ mod impls {
241294
242295 impl PartialOrd for ( ) {
243296 #[ inline]
244- fn lt ( & self , _other : & ( ) ) -> bool { false }
297+ fn partial_cmp ( & self , _: & ( ) ) -> Option < Ordering > {
298+ Some ( Equal )
299+ }
245300 }
246301
247302 impl PartialOrd for bool {
248303 #[ 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 ) )
251306 }
252307 }
253308
@@ -288,6 +343,10 @@ mod impls {
288343 fn ne ( & self , other : & & ' a T ) -> bool { * ( * self ) != * ( * other) }
289344 }
290345 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+ }
291350 #[ inline]
292351 fn lt ( & self , other : & & ' a T ) -> bool { * ( * self ) < * ( * other) }
293352 #[ inline]
@@ -311,6 +370,10 @@ mod impls {
311370 fn ne ( & self , other : & & ' a mut T ) -> bool { * * self != * ( * other) }
312371 }
313372 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+ }
314377 #[ inline]
315378 fn lt ( & self , other : & & ' a mut T ) -> bool { * * self < * * other }
316379 #[ inline]
0 commit comments