diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 9c6fdc217dc4..2a81e7dcaf70 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -40,7 +40,7 @@ #![feature(fmt_internals)] #![feature(fmt_radix)] #![feature(heap_api)] -#![feature(iter_arith)] +#![feature(inclusive_range)] #![feature(iter_arith)] #![feature(lang_items)] #![feature(nonzero)] diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 62ae7938e15e..cae6520bdb28 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -59,7 +59,7 @@ use core::fmt; use core::hash; use core::iter::FromIterator; use core::mem; -use core::ops::{self, Add}; +use core::ops::{self, Add, Index, IndexMut}; use core::ptr; use core::slice; use core::str::pattern::Pattern; @@ -1606,6 +1606,24 @@ impl ops::Index for String { unsafe { str::from_utf8_unchecked(&self.vec) } } } +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::Index> for String { + type Output = str; + + #[inline] + fn index(&self, index: ops::RangeInclusive) -> &str { + Index::index(&**self, index) + } +} +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::Index> for String { + type Output = str; + + #[inline] + fn index(&self, index: ops::RangeToInclusive) -> &str { + Index::index(&**self, index) + } +} #[stable(feature = "derefmut_for_string", since = "1.2.0")] impl ops::IndexMut> for String { @@ -1635,6 +1653,20 @@ impl ops::IndexMut for String { unsafe { mem::transmute(&mut *self.vec) } } } +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::IndexMut> for String { + #[inline] + fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut str { + IndexMut::index_mut(&mut **self, index) + } +} +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::IndexMut> for String { + #[inline] + fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut str { + IndexMut::index_mut(&mut **self, index) + } +} #[stable(feature = "rust1", since = "1.0.0")] impl ops::Deref for String { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index ae442e155c0d..841748f38812 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1225,6 +1225,24 @@ impl ops::Index for Vec { self } } +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::Index> for Vec { + type Output = [T]; + + #[inline] + fn index(&self, index: ops::RangeInclusive) -> &[T] { + Index::index(&**self, index) + } +} +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::Index> for Vec { + type Output = [T]; + + #[inline] + fn index(&self, index: ops::RangeToInclusive) -> &[T] { + Index::index(&**self, index) + } +} #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut> for Vec { @@ -1254,6 +1272,20 @@ impl ops::IndexMut for Vec { self } } +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::IndexMut> for Vec { + #[inline] + fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut [T] { + IndexMut::index_mut(&mut **self, index) + } +} +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::IndexMut> for Vec { + #[inline] + fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut [T] { + IndexMut::index_mut(&mut **self, index) + } +} #[stable(feature = "rust1", since = "1.0.0")] impl ops::Deref for Vec { diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 73466a849dc8..2293e93eea72 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -560,7 +560,7 @@ impl ops::Index> for [T] { #[inline] fn index(&self, index: ops::RangeTo) -> &[T] { - self.index(ops::Range{ start: 0, end: index.end }) + self.index(0 .. index.end) } } #[stable(feature = "rust1", since = "1.0.0")] @@ -569,7 +569,7 @@ impl ops::Index> for [T] { #[inline] fn index(&self, index: ops::RangeFrom) -> &[T] { - self.index(ops::Range{ start: index.start, end: self.len() }) + self.index(index.start .. self.len()) } } #[stable(feature = "rust1", since = "1.0.0")] @@ -582,6 +582,32 @@ impl ops::Index for [T] { } } +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::Index> for [T] { + type Output = [T]; + + #[inline] + fn index(&self, index: ops::RangeInclusive) -> &[T] { + match index { + ops::RangeInclusive::Empty { .. } => &[], + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => + panic!("attempted to index slice up to maximum usize"), + ops::RangeInclusive::NonEmpty { start, end } => + self.index(start .. end+1) + } + } +} +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::Index> for [T] { + type Output = [T]; + + #[inline] + fn index(&self, index: ops::RangeToInclusive) -> &[T] { + // SNAP 3391630 change this to `0...index.end` + self.index(ops::RangeInclusive::NonEmpty { start: 0, end: index.end }) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut> for [T] { #[inline] @@ -603,7 +629,7 @@ impl ops::IndexMut> for [T] { impl ops::IndexMut> for [T] { #[inline] fn index_mut(&mut self, index: ops::RangeTo) -> &mut [T] { - self.index_mut(ops::Range{ start: 0, end: index.end }) + self.index_mut(0 .. index.end) } } #[stable(feature = "rust1", since = "1.0.0")] @@ -611,7 +637,7 @@ impl ops::IndexMut> for [T] { #[inline] fn index_mut(&mut self, index: ops::RangeFrom) -> &mut [T] { let len = self.len(); - self.index_mut(ops::Range{ start: index.start, end: len }) + self.index_mut(index.start .. len) } } #[stable(feature = "rust1", since = "1.0.0")] @@ -622,6 +648,27 @@ impl ops::IndexMut for [T] { } } +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::IndexMut> for [T] { + #[inline] + fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut [T] { + match index { + ops::RangeInclusive::Empty { .. } => &mut [], + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => + panic!("attempted to index slice up to maximum usize"), + ops::RangeInclusive::NonEmpty { start, end } => + self.index_mut(start .. end+1) + } + } +} +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl ops::IndexMut> for [T] { + #[inline] + fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut [T] { + // SNAP 3391630 change this to `0...index.end` + self.index_mut(ops::RangeInclusive::NonEmpty { start: 0, end: index.end }) + } +} //////////////////////////////////////////////////////////////////////////////// // Common traits diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 4d367cfd432f..1c77ea84537c 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1462,6 +1462,62 @@ mod traits { self } } + + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ops::Index> for str { + type Output = str; + + #[inline] + fn index(&self, index: ops::RangeInclusive) -> &str { + match index { + ops::RangeInclusive::Empty { .. } => "", + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => + panic!("attempted to index slice up to maximum usize"), + ops::RangeInclusive::NonEmpty { start, end } => + self.index(start .. end+1) + } + } + } + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ops::Index> for str { + type Output = str; + + #[inline] + fn index(&self, index: ops::RangeToInclusive) -> &str { + // SNAP 3391630 change this to `0...index.end` + self.index(ops::RangeInclusive::NonEmpty { start: 0, end: index.end }) + } + } + + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ops::IndexMut> for str { + #[inline] + fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut str { + match index { + ops::RangeInclusive::Empty { .. } => &mut self[0..0], // `&mut ""` doesn't work + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => + panic!("attempted to index str up to maximum usize"), + ops::RangeInclusive::NonEmpty { start, end } => + self.index_mut(start .. end+1) + } + } + } + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ops::IndexMut> for str { + #[inline] + fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut str { + // SNAP 3391630 change this to `0...index.end` + self.index_mut(ops::RangeInclusive::NonEmpty { start: 0, end: index.end }) + } + } } /// Methods for string slices diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index dd84cba370c2..6ecf5c32bdbd 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -233,6 +233,7 @@ #![feature(fnbox)] #![feature(heap_api)] #![feature(hashmap_hasher)] +#![feature(inclusive_range)] #![feature(int_error_internals)] #![feature(into_cow)] #![feature(lang_items)] diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs index c1bc6adf7b8a..52c8353d00e9 100644 --- a/src/test/run-pass/range_inclusive.rs +++ b/src/test/run-pass/range_inclusive.rs @@ -55,6 +55,24 @@ pub fn main() { let _ = x...&y; } + // test collection indexing + let vec = (0...10).collect::>(); + let slice: &[_] = &*vec; + let string = String::from("hello world"); + let stir = "hello world"; + + assert_eq!(&vec[3...6], &[3, 4, 5, 6]); + assert_eq!(&vec[ ...6], &[0, 1, 2, 3, 4, 5, 6]); + + assert_eq!(&slice[3...6], &[3, 4, 5, 6]); + assert_eq!(&slice[ ...6], &[0, 1, 2, 3, 4, 5, 6]); + + assert_eq!(&string[3...6], "lo w"); + assert_eq!(&string[ ...6], "hello w"); + + assert_eq!(&stir[3...6], "lo w"); + assert_eq!(&stir[ ...6], "hello w"); + // test the size hints and emptying let mut long = 0...255u8; let mut short = 42...42;