|
146 | 146 | #![stable(feature = "rust1", since = "1.0.0")]
|
147 | 147 |
|
148 | 148 | use iter::{FromIterator, FusedIterator, TrustedLen};
|
149 |
| -use {mem, ops}; |
| 149 | +use {cmp, intrinsics, mem, ops}; |
150 | 150 |
|
151 | 151 | // Note that this is not a lang item per se, but it has a hidden dependency on
|
152 | 152 | // `Iterator`, which is one. The compiler assumes that the `next` method of
|
153 | 153 | // `Iterator` is an enumeration with one type parameter and two variants,
|
154 | 154 | // which basically means it must be `Option`.
|
155 | 155 |
|
156 | 156 | /// The `Option` type. See [the module level documentation](index.html) for more.
|
157 |
| -#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] |
| 157 | +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] // PartialOrd and Ord by hand below. |
158 | 158 | #[stable(feature = "rust1", since = "1.0.0")]
|
159 | 159 | pub enum Option<T> {
|
160 |
| - /// No value |
161 |
| - #[stable(feature = "rust1", since = "1.0.0")] |
162 |
| - None, |
163 | 160 | /// Some value `T`
|
164 | 161 | #[stable(feature = "rust1", since = "1.0.0")]
|
165 | 162 | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
|
| 163 | + /// No value |
| 164 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 165 | + None, |
166 | 166 | }
|
167 | 167 |
|
168 | 168 | /////////////////////////////////////////////////////////////////////////////
|
@@ -981,6 +981,107 @@ impl<T> From<T> for Option<T> {
|
981 | 981 | }
|
982 | 982 | }
|
983 | 983 |
|
| 984 | +// The Option<T> type used to be defined as { None, Some(T) }, but for codegen |
| 985 | +// reasons we reversed it in #49499 to reduce the amount of work that needs |
| 986 | +// to be done for Result<T, ()> <-> Option<T> conversions. Keeping the derived |
| 987 | +// Ord and PartialOrd implementations would make that swap a breaking change. |
| 988 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 989 | +impl<T> Ord for Option<T> |
| 990 | +where |
| 991 | + T: Ord, |
| 992 | +{ |
| 993 | + #[inline] |
| 994 | + fn cmp(&self, other: &Self) -> cmp::Ordering { |
| 995 | + let self_discr = unsafe { intrinsics::discriminant_value(self) } as isize; |
| 996 | + let other_discr = unsafe { intrinsics::discriminant_value(other) } as isize; |
| 997 | + if self_discr == other_discr { |
| 998 | + match (self, other) { |
| 999 | + (&Some(ref this), &Some(ref other)) => this.cmp(other), |
| 1000 | + _ => cmp::Ordering::Equal, |
| 1001 | + } |
| 1002 | + } else { |
| 1003 | + other_discr.cmp(&self_discr) |
| 1004 | + } |
| 1005 | + } |
| 1006 | +} |
| 1007 | + |
| 1008 | +// See comment on the Ord impl above. |
| 1009 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 1010 | +impl<T> PartialOrd for Option<T> |
| 1011 | +where |
| 1012 | + T: PartialOrd, |
| 1013 | +{ |
| 1014 | + #[inline] |
| 1015 | + fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { |
| 1016 | + let self_discr = unsafe { intrinsics::discriminant_value(self) } as isize; |
| 1017 | + let other_discr = unsafe { intrinsics::discriminant_value(other) } as isize; |
| 1018 | + if self_discr == other_discr { |
| 1019 | + match (self, other) { |
| 1020 | + (&Some(ref this), &Some(ref other)) => this.partial_cmp(other), |
| 1021 | + _ => Some(cmp::Ordering::Equal), |
| 1022 | + } |
| 1023 | + } else { |
| 1024 | + other_discr.partial_cmp(&self_discr) |
| 1025 | + } |
| 1026 | + } |
| 1027 | + |
| 1028 | + #[inline] |
| 1029 | + fn lt(&self, other: &Self) -> bool { |
| 1030 | + let self_discr = unsafe { intrinsics::discriminant_value(self) } as isize; |
| 1031 | + let other_discr = unsafe { intrinsics::discriminant_value(other) } as isize; |
| 1032 | + if self_discr == other_discr { |
| 1033 | + match (self, other) { |
| 1034 | + (&Some(ref this), &Some(ref other)) => this < other, |
| 1035 | + _ => false, |
| 1036 | + } |
| 1037 | + } else { |
| 1038 | + other_discr < self_discr |
| 1039 | + } |
| 1040 | + } |
| 1041 | + |
| 1042 | + #[inline] |
| 1043 | + fn le(&self, other: &Self) -> bool { |
| 1044 | + let self_discr = unsafe { intrinsics::discriminant_value(self) } as isize; |
| 1045 | + let other_discr = unsafe { intrinsics::discriminant_value(other) } as isize; |
| 1046 | + if self_discr == other_discr { |
| 1047 | + match (self, other) { |
| 1048 | + (&Some(ref this), &Some(ref other)) => this <= other, |
| 1049 | + _ => true, |
| 1050 | + } |
| 1051 | + } else { |
| 1052 | + other_discr <= self_discr |
| 1053 | + } |
| 1054 | + } |
| 1055 | + |
| 1056 | + #[inline] |
| 1057 | + fn gt(&self, other: &Self) -> bool { |
| 1058 | + let self_discr = unsafe { intrinsics::discriminant_value(self) } as isize; |
| 1059 | + let other_discr = unsafe { intrinsics::discriminant_value(other) } as isize; |
| 1060 | + if self_discr == other_discr { |
| 1061 | + match (self, other) { |
| 1062 | + (&Some(ref this), &Some(ref other)) => this > other, |
| 1063 | + _ => false, |
| 1064 | + } |
| 1065 | + } else { |
| 1066 | + other_discr > self_discr |
| 1067 | + } |
| 1068 | + } |
| 1069 | + |
| 1070 | + #[inline] |
| 1071 | + fn ge(&self, other: &Self) -> bool { |
| 1072 | + let self_discr = unsafe { intrinsics::discriminant_value(self) } as isize; |
| 1073 | + let other_discr = unsafe { intrinsics::discriminant_value(other) } as isize; |
| 1074 | + if self_discr == other_discr { |
| 1075 | + match (self, other) { |
| 1076 | + (&Some(ref this), &Some(ref other)) => this >= other, |
| 1077 | + _ => true, |
| 1078 | + } |
| 1079 | + } else { |
| 1080 | + other_discr >= self_discr |
| 1081 | + } |
| 1082 | + } |
| 1083 | +} |
| 1084 | + |
984 | 1085 | /////////////////////////////////////////////////////////////////////////////
|
985 | 1086 | // The Option Iterators
|
986 | 1087 | /////////////////////////////////////////////////////////////////////////////
|
|
0 commit comments