Skip to content

Commit fba0bf6

Browse files
committed
Stabilize Index traits and most range notation
This commit marks as `#[stable]`: * The `Index` and `IndexMut` traits. These are stabilized as taking the index itself *by reference*; after extensive discussion it was determined that this is a better match with our choices elsewhere (e.g. making comparison operators auto-reference), and that the use cases for by-value indices are better handled through `IndexSet`. * The `Range`, `RangeFrom` and `RangeTo` structs, introduced for range notation. * Various impls of `Index` and `IndexMut`. The `FullRange` struct is left unstable as we may wish to rename it to `RangeFull` in the future. This commit also *removes* the `Step` trait in favor of direct implementation of iterator traits on ranges for integers. The `Step` trait was not a terribly useful factoring internally, and it is likely that external integer types are best off implementing range iterators directly. It was removed to simplify the API surface. We can always reintroduce `Step` later if it turns out to be useful. Due to this removal, this is a: [breaking-change]
1 parent 6869645 commit fba0bf6

File tree

3 files changed

+89
-102
lines changed

3 files changed

+89
-102
lines changed

src/libcollections/vec.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,7 @@ impl<S: hash::Writer + hash::Hasher, T: Hash<S>> Hash<S> for Vec<T> {
12291229
}
12301230
}
12311231

1232-
#[unstable = "waiting on Index stability"]
1232+
#[stable]
12331233
impl<T> Index<uint> for Vec<T> {
12341234
type Output = T;
12351235

@@ -1239,6 +1239,7 @@ impl<T> Index<uint> for Vec<T> {
12391239
}
12401240
}
12411241

1242+
#[stable]
12421243
impl<T> IndexMut<uint> for Vec<T> {
12431244
type Output = T;
12441245

@@ -1249,27 +1250,31 @@ impl<T> IndexMut<uint> for Vec<T> {
12491250
}
12501251

12511252

1253+
#[stable]
12521254
impl<T> ops::Index<ops::Range<uint>> for Vec<T> {
12531255
type Output = [T];
12541256
#[inline]
12551257
fn index(&self, index: &ops::Range<uint>) -> &[T] {
12561258
self.as_slice().index(index)
12571259
}
12581260
}
1261+
#[stable]
12591262
impl<T> ops::Index<ops::RangeTo<uint>> for Vec<T> {
12601263
type Output = [T];
12611264
#[inline]
12621265
fn index(&self, index: &ops::RangeTo<uint>) -> &[T] {
12631266
self.as_slice().index(index)
12641267
}
12651268
}
1269+
#[stable]
12661270
impl<T> ops::Index<ops::RangeFrom<uint>> for Vec<T> {
12671271
type Output = [T];
12681272
#[inline]
12691273
fn index(&self, index: &ops::RangeFrom<uint>) -> &[T] {
12701274
self.as_slice().index(index)
12711275
}
12721276
}
1277+
#[stable]
12731278
impl<T> ops::Index<ops::FullRange> for Vec<T> {
12741279
type Output = [T];
12751280
#[inline]
@@ -1278,27 +1283,31 @@ impl<T> ops::Index<ops::FullRange> for Vec<T> {
12781283
}
12791284
}
12801285

1286+
#[stable]
12811287
impl<T> ops::IndexMut<ops::Range<uint>> for Vec<T> {
12821288
type Output = [T];
12831289
#[inline]
12841290
fn index_mut(&mut self, index: &ops::Range<uint>) -> &mut [T] {
12851291
self.as_mut_slice().index_mut(index)
12861292
}
12871293
}
1294+
#[stable]
12881295
impl<T> ops::IndexMut<ops::RangeTo<uint>> for Vec<T> {
12891296
type Output = [T];
12901297
#[inline]
12911298
fn index_mut(&mut self, index: &ops::RangeTo<uint>) -> &mut [T] {
12921299
self.as_mut_slice().index_mut(index)
12931300
}
12941301
}
1302+
#[stable]
12951303
impl<T> ops::IndexMut<ops::RangeFrom<uint>> for Vec<T> {
12961304
type Output = [T];
12971305
#[inline]
12981306
fn index_mut(&mut self, index: &ops::RangeFrom<uint>) -> &mut [T] {
12991307
self.as_mut_slice().index_mut(index)
13001308
}
13011309
}
1310+
#[stable]
13021311
impl<T> ops::IndexMut<ops::FullRange> for Vec<T> {
13031312
type Output = [T];
13041313
#[inline]
@@ -1307,7 +1316,6 @@ impl<T> ops::IndexMut<ops::FullRange> for Vec<T> {
13071316
}
13081317
}
13091318

1310-
13111319
#[stable]
13121320
impl<T> ops::Deref for Vec<T> {
13131321
type Target = [T];

src/libcore/iter.rs

+67-37
Original file line numberDiff line numberDiff line change
@@ -2701,63 +2701,93 @@ impl<A: Int> Iterator for RangeStepInclusive<A> {
27012701
}
27022702
}
27032703

2704-
2705-
/// The `Step` trait identifies objects which can be stepped over in both
2706-
/// directions. The `steps_between` function provides a way to
2707-
/// compare two Step objects (it could be provided using `step()` and `Ord`,
2708-
/// but the implementation would be so inefficient as to be useless).
2709-
#[unstable = "design of range notation/iteration is in flux"]
2710-
pub trait Step: Ord {
2711-
/// Change self to the next object.
2712-
fn step(&mut self);
2713-
/// Change self to the previous object.
2714-
fn step_back(&mut self);
2715-
/// The steps_between two step objects.
2716-
/// start should always be less than end, so the result should never be negative.
2717-
/// Return None if it is not possible to calculate steps_between without
2718-
/// overflow.
2719-
fn steps_between(start: &Self, end: &Self) -> Option<uint>;
2720-
}
2721-
2722-
macro_rules! step_impl {
2704+
macro_rules! range_impl {
27232705
($($t:ty)*) => ($(
2724-
#[unstable = "Trait is unstable."]
2725-
impl Step for $t {
2726-
#[inline]
2727-
fn step(&mut self) { *self += 1; }
2706+
#[stable]
2707+
impl Iterator for ::ops::Range<$t> {
2708+
type Item = $t;
2709+
27282710
#[inline]
2729-
fn step_back(&mut self) { *self -= 1; }
2711+
fn next(&mut self) -> Option<$t> {
2712+
if self.start < self.end {
2713+
let result = self.start;
2714+
self.start += 1;
2715+
return Some(result);
2716+
}
2717+
2718+
return None;
2719+
}
2720+
27302721
#[inline]
2731-
fn steps_between(start: &$t, end: &$t) -> Option<uint> {
2732-
debug_assert!(end >= start);
2733-
Some((*end - *start) as uint)
2722+
fn size_hint(&self) -> (uint, Option<uint>) {
2723+
debug_assert!(self.end >= self.start);
2724+
let hint = (self.end - self.start) as uint;
2725+
(hint, Some(hint))
27342726
}
27352727
}
2728+
2729+
#[stable]
2730+
impl ExactSizeIterator for ::ops::Range<$t> {}
27362731
)*)
27372732
}
27382733

2739-
macro_rules! step_impl_no_between {
2734+
macro_rules! range_impl_no_hint {
27402735
($($t:ty)*) => ($(
2741-
#[unstable = "Trait is unstable."]
2742-
impl Step for $t {
2736+
#[stable]
2737+
impl Iterator for ::ops::Range<$t> {
2738+
type Item = $t;
2739+
27432740
#[inline]
2744-
fn step(&mut self) { *self += 1; }
2741+
fn next(&mut self) -> Option<$t> {
2742+
if self.start < self.end {
2743+
let result = self.start;
2744+
self.start += 1;
2745+
return Some(result);
2746+
}
2747+
2748+
return None;
2749+
}
2750+
}
2751+
)*)
2752+
}
2753+
2754+
macro_rules! range_other_impls {
2755+
($($t:ty)*) => ($(
2756+
#[stable]
2757+
impl DoubleEndedIterator for ::ops::Range<$t> {
27452758
#[inline]
2746-
fn step_back(&mut self) { *self -= 1; }
2759+
fn next_back(&mut self) -> Option<$t> {
2760+
if self.start < self.end {
2761+
self.end -= 1;
2762+
return Some(self.end);
2763+
}
2764+
2765+
return None;
2766+
}
2767+
}
2768+
2769+
#[stable]
2770+
impl Iterator for ::ops::RangeFrom<$t> {
2771+
type Item = $t;
2772+
27472773
#[inline]
2748-
fn steps_between(_start: &$t, _end: &$t) -> Option<uint> {
2749-
None
2774+
fn next(&mut self) -> Option<$t> {
2775+
let result = self.start;
2776+
self.start += 1;
2777+
debug_assert!(result < self.start);
2778+
return Some(result);
27502779
}
27512780
}
27522781
)*)
27532782
}
27542783

2755-
step_impl!(uint u8 u16 u32 int i8 i16 i32);
2784+
range_impl!(uint u8 u16 u32 int i8 i16 i32);
27562785
#[cfg(target_pointer_width = "64")]
2757-
step_impl!(u64 i64);
2786+
range_impl!(u64 i64);
27582787
#[cfg(target_pointer_width = "32")]
2759-
step_impl_no_between!(u64 i64);
2788+
range_impl_no_hint!(u64 i64);
27602789

2790+
range_other_impls!(uint u8 u16 u32 u64 int i8 i16 i32 i64);
27612791

27622792
/// An iterator that repeats an element endlessly
27632793
#[derive(Clone)]

src/libcore/ops.rs

+12-63
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,7 @@
6969
7070
#![stable]
7171

72-
use clone::Clone;
73-
use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator};
7472
use marker::Sized;
75-
use option::Option::{self, Some, None};
7673
use fmt;
7774

7875
/// The `Drop` trait is used to run some code when a value goes out of scope. This
@@ -924,10 +921,12 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
924921
/// }
925922
/// ```
926923
#[lang="index"]
924+
#[stable]
927925
pub trait Index<Index: ?Sized> {
928926
type Output: ?Sized;
929927

930928
/// The method for the indexing (`Foo[Bar]`) operation
929+
#[stable]
931930
fn index<'a>(&'a self, index: &Index) -> &'a Self::Output;
932931
}
933932

@@ -960,20 +959,22 @@ pub trait Index<Index: ?Sized> {
960959
/// }
961960
/// ```
962961
#[lang="index_mut"]
962+
#[stable]
963963
pub trait IndexMut<Index: ?Sized> {
964964
type Output: ?Sized;
965965

966966
/// The method for the indexing (`Foo[Bar]`) operation
967+
#[stable]
967968
fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output;
968969
}
969970

970971
/// An unbounded range.
971972
#[derive(Copy, Clone, PartialEq, Eq)]
972973
#[lang="full_range"]
973-
#[unstable = "API still in development"]
974+
#[unstable = "may be renamed to RangeFull"]
974975
pub struct FullRange;
975976

976-
#[unstable = "API still in development"]
977+
#[stable]
977978
impl fmt::Show for FullRange {
978979
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
979980
fmt::Show::fmt("..", fmt)
@@ -983,56 +984,15 @@ impl fmt::Show for FullRange {
983984
/// A (half-open) range which is bounded at both ends.
984985
#[derive(Copy, Clone, PartialEq, Eq)]
985986
#[lang="range"]
986-
#[unstable = "API still in development"]
987+
#[stable]
987988
pub struct Range<Idx> {
988989
/// The lower bound of the range (inclusive).
989990
pub start: Idx,
990991
/// The upper bound of the range (exclusive).
991992
pub end: Idx,
992993
}
993994

994-
#[unstable = "API still in development"]
995-
impl<Idx: Clone + Step> Iterator for Range<Idx> {
996-
type Item = Idx;
997-
998-
#[inline]
999-
fn next(&mut self) -> Option<Idx> {
1000-
if self.start < self.end {
1001-
let result = self.start.clone();
1002-
self.start.step();
1003-
return Some(result);
1004-
}
1005-
1006-
return None;
1007-
}
1008-
1009-
#[inline]
1010-
fn size_hint(&self) -> (uint, Option<uint>) {
1011-
if let Some(hint) = Step::steps_between(&self.start, &self.end) {
1012-
(hint, Some(hint))
1013-
} else {
1014-
(0, None)
1015-
}
1016-
}
1017-
}
1018-
1019-
#[unstable = "API still in development"]
1020-
impl<Idx: Clone + Step> DoubleEndedIterator for Range<Idx> {
1021-
#[inline]
1022-
fn next_back(&mut self) -> Option<Idx> {
1023-
if self.start < self.end {
1024-
self.end.step_back();
1025-
return Some(self.end.clone());
1026-
}
1027-
1028-
return None;
1029-
}
1030-
}
1031-
1032-
#[unstable = "API still in development"]
1033-
impl<Idx: Clone + Step> ExactSizeIterator for Range<Idx> {}
1034-
1035-
#[unstable = "API still in development"]
995+
#[stable]
1036996
impl<Idx: fmt::Show> fmt::Show for Range<Idx> {
1037997
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1038998
write!(fmt, "{:?}..{:?}", self.start, self.end)
@@ -1042,26 +1002,15 @@ impl<Idx: fmt::Show> fmt::Show for Range<Idx> {
10421002
/// A range which is only bounded below.
10431003
#[derive(Copy, Clone, PartialEq, Eq)]
10441004
#[lang="range_from"]
1045-
#[unstable = "API still in development"]
1005+
#[stable]
10461006
pub struct RangeFrom<Idx> {
10471007
/// The lower bound of the range (inclusive).
10481008
pub start: Idx,
10491009
}
10501010

1051-
#[unstable = "API still in development"]
1052-
impl<Idx: Clone + Step> Iterator for RangeFrom<Idx> {
1053-
type Item = Idx;
10541011

1055-
#[inline]
1056-
fn next(&mut self) -> Option<Idx> {
1057-
// Deliberately overflow so we loop forever.
1058-
let result = self.start.clone();
1059-
self.start.step();
1060-
return Some(result);
1061-
}
1062-
}
10631012

1064-
#[unstable = "API still in development"]
1013+
#[stable]
10651014
impl<Idx: fmt::Show> fmt::Show for RangeFrom<Idx> {
10661015
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
10671016
write!(fmt, "{:?}..", self.start)
@@ -1071,13 +1020,13 @@ impl<Idx: fmt::Show> fmt::Show for RangeFrom<Idx> {
10711020
/// A range which is only bounded above.
10721021
#[derive(Copy, Clone, PartialEq, Eq)]
10731022
#[lang="range_to"]
1074-
#[unstable = "API still in development"]
1023+
#[stable]
10751024
pub struct RangeTo<Idx> {
10761025
/// The upper bound of the range (exclusive).
10771026
pub end: Idx,
10781027
}
10791028

1080-
#[unstable = "API still in development"]
1029+
#[stable]
10811030
impl<Idx: fmt::Show> fmt::Show for RangeTo<Idx> {
10821031
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
10831032
write!(fmt, "..{:?}", self.end)

0 commit comments

Comments
 (0)