Skip to content

Commit 2896278

Browse files
author
Jorge Aparicio
committed
DSTify PartialEq, PartialOrd, Eq, Ord
1 parent 1a94375 commit 2896278

File tree

3 files changed

+329
-0
lines changed

3 files changed

+329
-0
lines changed

src/libcore/cmp.rs

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ use option::{Option, Some, None};
5555
///
5656
/// Eventually, this will be implemented by default for types that implement
5757
/// `Eq`.
58+
// NOTE(stage0): remove trait after a snapshot
59+
#[cfg(stage0)]
5860
#[lang="eq"]
5961
#[unstable = "Definition may change slightly after trait reform"]
6062
pub trait PartialEq {
@@ -66,6 +68,31 @@ pub trait PartialEq {
6668
fn ne(&self, other: &Self) -> bool { !self.eq(other) }
6769
}
6870

71+
/// Trait for values that can be compared for equality and inequality.
72+
///
73+
/// This trait allows for partial equality, for types that do not have an
74+
/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
75+
/// so floating point types implement `PartialEq` but not `Eq`.
76+
///
77+
/// PartialEq only requires the `eq` method to be implemented; `ne` is defined
78+
/// in terms of it by default. Any manual implementation of `ne` *must* respect
79+
/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
80+
/// only if `a != b`.
81+
///
82+
/// Eventually, this will be implemented by default for types that implement
83+
/// `Eq`.
84+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
85+
#[lang="eq"]
86+
#[unstable = "Definition may change slightly after trait reform"]
87+
pub trait PartialEq for Sized? {
88+
/// This method tests for `self` and `other` values to be equal, and is used by `==`.
89+
fn eq(&self, other: &Self) -> bool;
90+
91+
/// This method tests for `!=`.
92+
#[inline]
93+
fn ne(&self, other: &Self) -> bool { !self.eq(other) }
94+
}
95+
6996
/// Trait for equality comparisons which are [equivalence relations](
7097
/// https://en.wikipedia.org/wiki/Equivalence_relation).
7198
///
@@ -75,6 +102,8 @@ pub trait PartialEq {
75102
/// - reflexive: `a == a`;
76103
/// - symmetric: `a == b` implies `b == a`; and
77104
/// - transitive: `a == b` and `b == c` implies `a == c`.
105+
// NOTE(stage0): remove trait after a snapshot
106+
#[cfg(stage0)]
78107
#[unstable = "Definition may change slightly after trait reform"]
79108
pub trait Eq: PartialEq {
80109
// FIXME #13101: this method is used solely by #[deriving] to
@@ -89,6 +118,30 @@ pub trait Eq: PartialEq {
89118
fn assert_receiver_is_total_eq(&self) {}
90119
}
91120

121+
/// Trait for equality comparisons which are [equivalence relations](
122+
/// https://en.wikipedia.org/wiki/Equivalence_relation).
123+
///
124+
/// This means, that in addition to `a == b` and `a != b` being strict
125+
/// inverses, the equality must be (for all `a`, `b` and `c`):
126+
///
127+
/// - reflexive: `a == a`;
128+
/// - symmetric: `a == b` implies `b == a`; and
129+
/// - transitive: `a == b` and `b == c` implies `a == c`.
130+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
131+
#[unstable = "Definition may change slightly after trait reform"]
132+
pub trait Eq for Sized?: PartialEq {
133+
// FIXME #13101: this method is used solely by #[deriving] to
134+
// assert that every component of a type implements #[deriving]
135+
// itself, the current deriving infrastructure means doing this
136+
// assertion without using a method on this trait is nearly
137+
// impossible.
138+
//
139+
// This should never be implemented by hand.
140+
#[doc(hidden)]
141+
#[inline(always)]
142+
fn assert_receiver_is_total_eq(&self) {}
143+
}
144+
92145
/// An ordering is, e.g, a result of a comparison between two values.
93146
#[deriving(Clone, PartialEq, Show)]
94147
#[stable]
@@ -145,6 +198,8 @@ impl Ordering {
145198
/// true; and
146199
/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
147200
/// both `==` and `>`.
201+
// NOTE(stage0): remove trait after a snapshot
202+
#[cfg(stage0)]
148203
#[unstable = "Definition may change slightly after trait reform"]
149204
pub trait Ord: Eq + PartialOrd {
150205
/// This method returns an ordering between `self` and `other` values.
@@ -160,6 +215,31 @@ pub trait Ord: Eq + PartialOrd {
160215
fn cmp(&self, other: &Self) -> Ordering;
161216
}
162217

218+
/// Trait for types that form a [total order](
219+
/// https://en.wikipedia.org/wiki/Total_order).
220+
///
221+
/// An order is a total order if it is (for all `a`, `b` and `c`):
222+
///
223+
/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is
224+
/// true; and
225+
/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
226+
/// both `==` and `>`.
227+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
228+
#[unstable = "Definition may change slightly after trait reform"]
229+
pub trait Ord for Sized?: Eq + PartialOrd {
230+
/// This method returns an ordering between `self` and `other` values.
231+
///
232+
/// By convention, `self.cmp(&other)` returns the ordering matching
233+
/// the expression `self <operator> other` if true. For example:
234+
///
235+
/// ```
236+
/// assert_eq!( 5u.cmp(&10), Less); // because 5 < 10
237+
/// assert_eq!(10u.cmp(&5), Greater); // because 10 > 5
238+
/// assert_eq!( 5u.cmp(&5), Equal); // because 5 == 5
239+
/// ```
240+
fn cmp(&self, other: &Self) -> Ordering;
241+
}
242+
163243
#[unstable = "Trait is unstable."]
164244
impl Eq for Ordering {}
165245

@@ -188,6 +268,8 @@ impl PartialOrd for Ordering {
188268
/// which do not have a total order. For example, for floating point numbers,
189269
/// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
190270
/// 5.11).
271+
// NOTE(stage0): remove trait after a snapshot
272+
#[cfg(stage0)]
191273
#[lang="ord"]
192274
#[unstable = "Definition may change slightly after trait reform"]
193275
pub trait PartialOrd: PartialEq {
@@ -232,6 +314,60 @@ pub trait PartialOrd: PartialEq {
232314
}
233315
}
234316

317+
/// Trait for values that can be compared for a sort-order.
318+
///
319+
/// PartialOrd only requires implementation of the `partial_cmp` method,
320+
/// with the others generated from default implementations.
321+
///
322+
/// However it remains possible to implement the others separately for types
323+
/// which do not have a total order. For example, for floating point numbers,
324+
/// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
325+
/// 5.11).
326+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
327+
#[lang="ord"]
328+
#[unstable = "Definition may change slightly after trait reform"]
329+
pub trait PartialOrd for Sized?: PartialEq {
330+
/// This method returns an ordering between `self` and `other` values
331+
/// if one exists.
332+
fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
333+
334+
/// This method tests less than (for `self` and `other`) and is used by the `<` operator.
335+
#[inline]
336+
fn lt(&self, other: &Self) -> bool {
337+
match self.partial_cmp(other) {
338+
Some(Less) => true,
339+
_ => false,
340+
}
341+
}
342+
343+
/// This method tests less than or equal to (`<=`).
344+
#[inline]
345+
fn le(&self, other: &Self) -> bool {
346+
match self.partial_cmp(other) {
347+
Some(Less) | Some(Equal) => true,
348+
_ => false,
349+
}
350+
}
351+
352+
/// This method tests greater than (`>`).
353+
#[inline]
354+
fn gt(&self, other: &Self) -> bool {
355+
match self.partial_cmp(other) {
356+
Some(Greater) => true,
357+
_ => false,
358+
}
359+
}
360+
361+
/// This method tests greater than or equal to (`>=`).
362+
#[inline]
363+
fn ge(&self, other: &Self) -> bool {
364+
match self.partial_cmp(other) {
365+
Some(Greater) | Some(Equal) => true,
366+
_ => false,
367+
}
368+
}
369+
}
370+
235371
/// The equivalence relation. Two values may be equivalent even if they are
236372
/// of different types. The most common use case for this relation is
237373
/// container types; e.g. it is often desirable to be able to use `&str`
@@ -286,6 +422,8 @@ pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
286422
mod impls {
287423
use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering,
288424
Less, Greater, Equal};
425+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
426+
use kinds::Sized;
289427
use option::{Option, Some, None};
290428

291429
macro_rules! partial_eq_impl(
@@ -393,13 +531,17 @@ mod impls {
393531
ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64)
394532

395533
// & pointers
534+
// NOTE(stage0): remove impl after a snapshot
535+
#[cfg(stage0)]
396536
#[unstable = "Trait is unstable."]
397537
impl<'a, T: PartialEq> PartialEq for &'a T {
398538
#[inline]
399539
fn eq(&self, other: & &'a T) -> bool { *(*self) == *(*other) }
400540
#[inline]
401541
fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) }
402542
}
543+
// NOTE(stage0): remove impl after a snapshot
544+
#[cfg(stage0)]
403545
#[unstable = "Trait is unstable."]
404546
impl<'a, T: PartialOrd> PartialOrd for &'a T {
405547
#[inline]
@@ -415,22 +557,64 @@ mod impls {
415557
#[inline]
416558
fn gt(&self, other: & &'a T) -> bool { *(*self) > *(*other) }
417559
}
560+
// NOTE(stage0): remove impl after a snapshot
561+
#[cfg(stage0)]
418562
#[unstable = "Trait is unstable."]
419563
impl<'a, T: Ord> Ord for &'a T {
420564
#[inline]
421565
fn cmp(&self, other: & &'a T) -> Ordering { (**self).cmp(*other) }
422566
}
567+
// NOTE(stage0): remove impl after a snapshot
568+
#[cfg(stage0)]
423569
#[unstable = "Trait is unstable."]
424570
impl<'a, T: Eq> Eq for &'a T {}
425571

572+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
573+
#[unstable = "Trait is unstable."]
574+
impl<'a, Sized? T: PartialEq> PartialEq for &'a T {
575+
#[inline]
576+
fn eq(&self, other: & &'a T) -> bool { PartialEq::eq(*self, *other) }
577+
#[inline]
578+
fn ne(&self, other: & &'a T) -> bool { PartialEq::ne(*self, *other) }
579+
}
580+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
581+
#[unstable = "Trait is unstable."]
582+
impl<'a, Sized? T: PartialOrd> PartialOrd for &'a T {
583+
#[inline]
584+
fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
585+
PartialOrd::partial_cmp(*self, *other)
586+
}
587+
#[inline]
588+
fn lt(&self, other: & &'a T) -> bool { PartialOrd::lt(*self, *other) }
589+
#[inline]
590+
fn le(&self, other: & &'a T) -> bool { PartialOrd::le(*self, *other) }
591+
#[inline]
592+
fn ge(&self, other: & &'a T) -> bool { PartialOrd::ge(*self, *other) }
593+
#[inline]
594+
fn gt(&self, other: & &'a T) -> bool { PartialOrd::gt(*self, *other) }
595+
}
596+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
597+
#[unstable = "Trait is unstable."]
598+
impl<'a, Sized? T: Ord> Ord for &'a T {
599+
#[inline]
600+
fn cmp(&self, other: & &'a T) -> Ordering { Ord::cmp(*self, *other) }
601+
}
602+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
603+
#[unstable = "Trait is unstable."]
604+
impl<'a, Sized? T: Eq> Eq for &'a T {}
605+
426606
// &mut pointers
607+
// NOTE(stage0): remove impl after a snapshot
608+
#[cfg(stage0)]
427609
#[unstable = "Trait is unstable."]
428610
impl<'a, T: PartialEq> PartialEq for &'a mut T {
429611
#[inline]
430612
fn eq(&self, other: &&'a mut T) -> bool { **self == *(*other) }
431613
#[inline]
432614
fn ne(&self, other: &&'a mut T) -> bool { **self != *(*other) }
433615
}
616+
// NOTE(stage0): remove impl after a snapshot
617+
#[cfg(stage0)]
434618
#[unstable = "Trait is unstable."]
435619
impl<'a, T: PartialOrd> PartialOrd for &'a mut T {
436620
#[inline]
@@ -446,11 +630,49 @@ mod impls {
446630
#[inline]
447631
fn gt(&self, other: &&'a mut T) -> bool { **self > **other }
448632
}
633+
// NOTE(stage0): remove impl after a snapshot
634+
#[cfg(stage0)]
449635
#[unstable = "Trait is unstable."]
450636
impl<'a, T: Ord> Ord for &'a mut T {
451637
#[inline]
452638
fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) }
453639
}
640+
// NOTE(stage0): remove impl after a snapshot
641+
#[cfg(stage0)]
454642
#[unstable = "Trait is unstable."]
455643
impl<'a, T: Eq> Eq for &'a mut T {}
644+
645+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
646+
#[unstable = "Trait is unstable."]
647+
impl<'a, Sized? T: PartialEq> PartialEq for &'a mut T {
648+
#[inline]
649+
fn eq(&self, other: &&'a mut T) -> bool { PartialEq::eq(*self, *other) }
650+
#[inline]
651+
fn ne(&self, other: &&'a mut T) -> bool { PartialEq::ne(*self, *other) }
652+
}
653+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
654+
#[unstable = "Trait is unstable."]
655+
impl<'a, Sized? T: PartialOrd> PartialOrd for &'a mut T {
656+
#[inline]
657+
fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
658+
PartialOrd::partial_cmp(*self, *other)
659+
}
660+
#[inline]
661+
fn lt(&self, other: &&'a mut T) -> bool { PartialOrd::lt(*self, *other) }
662+
#[inline]
663+
fn le(&self, other: &&'a mut T) -> bool { PartialOrd::le(*self, *other) }
664+
#[inline]
665+
fn ge(&self, other: &&'a mut T) -> bool { PartialOrd::ge(*self, *other) }
666+
#[inline]
667+
fn gt(&self, other: &&'a mut T) -> bool { PartialOrd::gt(*self, *other) }
668+
}
669+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
670+
#[unstable = "Trait is unstable."]
671+
impl<'a, Sized? T: Ord> Ord for &'a mut T {
672+
#[inline]
673+
fn cmp(&self, other: &&'a mut T) -> Ordering { Ord::cmp(*self, *other) }
674+
}
675+
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
676+
#[unstable = "Trait is unstable."]
677+
impl<'a, Sized? T: Eq> Eq for &'a mut T {}
456678
}

0 commit comments

Comments
 (0)