Skip to content

Commit 7eb7c56

Browse files
committed
add indexing with RangeInclusive in libcore and libcollections
1 parent b1b4f50 commit 7eb7c56

File tree

7 files changed

+192
-6
lines changed

7 files changed

+192
-6
lines changed

src/libcollections/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#![feature(fmt_internals)]
4141
#![feature(fmt_radix)]
4242
#![feature(heap_api)]
43-
#![feature(iter_arith)]
43+
#![feature(inclusive_range)]
4444
#![feature(iter_arith)]
4545
#![feature(lang_items)]
4646
#![feature(nonzero)]

src/libcollections/string.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use core::fmt;
5959
use core::hash;
6060
use core::iter::FromIterator;
6161
use core::mem;
62-
use core::ops::{self, Add};
62+
use core::ops::{self, Add, Index, IndexMut};
6363
use core::ptr;
6464
use core::slice;
6565
use core::str::pattern::Pattern;
@@ -1606,6 +1606,24 @@ impl ops::Index<ops::RangeFull> for String {
16061606
unsafe { str::from_utf8_unchecked(&self.vec) }
16071607
}
16081608
}
1609+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1610+
impl ops::Index<ops::RangeInclusive<usize>> for String {
1611+
type Output = str;
1612+
1613+
#[inline]
1614+
fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
1615+
Index::index(&**self, index)
1616+
}
1617+
}
1618+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1619+
impl ops::Index<ops::RangeToInclusive<usize>> for String {
1620+
type Output = str;
1621+
1622+
#[inline]
1623+
fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
1624+
Index::index(&**self, index)
1625+
}
1626+
}
16091627

16101628
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
16111629
impl ops::IndexMut<ops::Range<usize>> for String {
@@ -1635,6 +1653,20 @@ impl ops::IndexMut<ops::RangeFull> for String {
16351653
unsafe { mem::transmute(&mut *self.vec) }
16361654
}
16371655
}
1656+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1657+
impl ops::IndexMut<ops::RangeInclusive<usize>> for String {
1658+
#[inline]
1659+
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
1660+
IndexMut::index_mut(&mut **self, index)
1661+
}
1662+
}
1663+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1664+
impl ops::IndexMut<ops::RangeToInclusive<usize>> for String {
1665+
#[inline]
1666+
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
1667+
IndexMut::index_mut(&mut **self, index)
1668+
}
1669+
}
16381670

16391671
#[stable(feature = "rust1", since = "1.0.0")]
16401672
impl ops::Deref for String {

src/libcollections/vec.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,24 @@ impl<T> ops::Index<ops::RangeFull> for Vec<T> {
12251225
self
12261226
}
12271227
}
1228+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1229+
impl<T> ops::Index<ops::RangeInclusive<usize>> for Vec<T> {
1230+
type Output = [T];
1231+
1232+
#[inline]
1233+
fn index(&self, index: ops::RangeInclusive<usize>) -> &[T] {
1234+
Index::index(&**self, index)
1235+
}
1236+
}
1237+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1238+
impl<T> ops::Index<ops::RangeToInclusive<usize>> for Vec<T> {
1239+
type Output = [T];
1240+
1241+
#[inline]
1242+
fn index(&self, index: ops::RangeToInclusive<usize>) -> &[T] {
1243+
Index::index(&**self, index)
1244+
}
1245+
}
12281246

12291247
#[stable(feature = "rust1", since = "1.0.0")]
12301248
impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
@@ -1254,6 +1272,20 @@ impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
12541272
self
12551273
}
12561274
}
1275+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1276+
impl<T> ops::IndexMut<ops::RangeInclusive<usize>> for Vec<T> {
1277+
#[inline]
1278+
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut [T] {
1279+
IndexMut::index_mut(&mut **self, index)
1280+
}
1281+
}
1282+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1283+
impl<T> ops::IndexMut<ops::RangeToInclusive<usize>> for Vec<T> {
1284+
#[inline]
1285+
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut [T] {
1286+
IndexMut::index_mut(&mut **self, index)
1287+
}
1288+
}
12571289

12581290
#[stable(feature = "rust1", since = "1.0.0")]
12591291
impl<T> ops::Deref for Vec<T> {

src/libcore/slice.rs

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ impl<T> ops::Index<ops::RangeTo<usize>> for [T] {
560560

561561
#[inline]
562562
fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
563-
self.index(ops::Range{ start: 0, end: index.end })
563+
self.index(0 .. index.end)
564564
}
565565
}
566566
#[stable(feature = "rust1", since = "1.0.0")]
@@ -569,7 +569,7 @@ impl<T> ops::Index<ops::RangeFrom<usize>> for [T] {
569569

570570
#[inline]
571571
fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
572-
self.index(ops::Range{ start: index.start, end: self.len() })
572+
self.index(index.start .. self.len())
573573
}
574574
}
575575
#[stable(feature = "rust1", since = "1.0.0")]
@@ -582,6 +582,32 @@ impl<T> ops::Index<RangeFull> for [T] {
582582
}
583583
}
584584

585+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
586+
impl<T> ops::Index<ops::RangeInclusive<usize>> for [T] {
587+
type Output = [T];
588+
589+
#[inline]
590+
fn index(&self, index: ops::RangeInclusive<usize>) -> &[T] {
591+
match index {
592+
ops::RangeInclusive::Empty { .. } => &[],
593+
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
594+
panic!("attempted to index slice up to maximum usize"),
595+
ops::RangeInclusive::NonEmpty { start, end } =>
596+
self.index(start .. end+1)
597+
}
598+
}
599+
}
600+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
601+
impl<T> ops::Index<ops::RangeToInclusive<usize>> for [T] {
602+
type Output = [T];
603+
604+
#[inline]
605+
fn index(&self, index: ops::RangeToInclusive<usize>) -> &[T] {
606+
// SNAP 3391630 change this to `0...index.end`
607+
self.index(ops::RangeInclusive::NonEmpty { start: 0, end: index.end })
608+
}
609+
}
610+
585611
#[stable(feature = "rust1", since = "1.0.0")]
586612
impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
587613
#[inline]
@@ -603,15 +629,15 @@ impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
603629
impl<T> ops::IndexMut<ops::RangeTo<usize>> for [T] {
604630
#[inline]
605631
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
606-
self.index_mut(ops::Range{ start: 0, end: index.end })
632+
self.index_mut(0 .. index.end)
607633
}
608634
}
609635
#[stable(feature = "rust1", since = "1.0.0")]
610636
impl<T> ops::IndexMut<ops::RangeFrom<usize>> for [T] {
611637
#[inline]
612638
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
613639
let len = self.len();
614-
self.index_mut(ops::Range{ start: index.start, end: len })
640+
self.index_mut(index.start .. len)
615641
}
616642
}
617643
#[stable(feature = "rust1", since = "1.0.0")]
@@ -622,6 +648,27 @@ impl<T> ops::IndexMut<RangeFull> for [T] {
622648
}
623649
}
624650

651+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
652+
impl<T> ops::IndexMut<ops::RangeInclusive<usize>> for [T] {
653+
#[inline]
654+
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut [T] {
655+
match index {
656+
ops::RangeInclusive::Empty { .. } => &mut [],
657+
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
658+
panic!("attempted to index slice up to maximum usize"),
659+
ops::RangeInclusive::NonEmpty { start, end } =>
660+
self.index_mut(start .. end+1)
661+
}
662+
}
663+
}
664+
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
665+
impl<T> ops::IndexMut<ops::RangeToInclusive<usize>> for [T] {
666+
#[inline]
667+
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut [T] {
668+
// SNAP 3391630 change this to `0...index.end`
669+
self.index_mut(ops::RangeInclusive::NonEmpty { start: 0, end: index.end })
670+
}
671+
}
625672

626673
////////////////////////////////////////////////////////////////////////////////
627674
// Common traits

src/libcore/str/mod.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,62 @@ mod traits {
14621462
self
14631463
}
14641464
}
1465+
1466+
#[unstable(feature = "inclusive_range",
1467+
reason = "recently added, follows RFC",
1468+
issue = "28237")]
1469+
impl ops::Index<ops::RangeInclusive<usize>> for str {
1470+
type Output = str;
1471+
1472+
#[inline]
1473+
fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
1474+
match index {
1475+
ops::RangeInclusive::Empty { .. } => "",
1476+
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
1477+
panic!("attempted to index slice up to maximum usize"),
1478+
ops::RangeInclusive::NonEmpty { start, end } =>
1479+
self.index(start .. end+1)
1480+
}
1481+
}
1482+
}
1483+
#[unstable(feature = "inclusive_range",
1484+
reason = "recently added, follows RFC",
1485+
issue = "28237")]
1486+
impl ops::Index<ops::RangeToInclusive<usize>> for str {
1487+
type Output = str;
1488+
1489+
#[inline]
1490+
fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
1491+
// SNAP 3391630 change this to `0...index.end`
1492+
self.index(ops::RangeInclusive::NonEmpty { start: 0, end: index.end })
1493+
}
1494+
}
1495+
1496+
#[unstable(feature = "inclusive_range",
1497+
reason = "recently added, follows RFC",
1498+
issue = "28237")]
1499+
impl ops::IndexMut<ops::RangeInclusive<usize>> for str {
1500+
#[inline]
1501+
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
1502+
match index {
1503+
ops::RangeInclusive::Empty { .. } => &mut self[0..0], // `&mut ""` doesn't work
1504+
ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
1505+
panic!("attempted to index str up to maximum usize"),
1506+
ops::RangeInclusive::NonEmpty { start, end } =>
1507+
self.index_mut(start .. end+1)
1508+
}
1509+
}
1510+
}
1511+
#[unstable(feature = "inclusive_range",
1512+
reason = "recently added, follows RFC",
1513+
issue = "28237")]
1514+
impl ops::IndexMut<ops::RangeToInclusive<usize>> for str {
1515+
#[inline]
1516+
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
1517+
// SNAP 3391630 change this to `0...index.end`
1518+
self.index_mut(ops::RangeInclusive::NonEmpty { start: 0, end: index.end })
1519+
}
1520+
}
14651521
}
14661522

14671523
/// Methods for string slices

src/libstd/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@
233233
#![feature(fnbox)]
234234
#![feature(heap_api)]
235235
#![feature(hashmap_hasher)]
236+
#![feature(inclusive_range)]
236237
#![feature(int_error_internals)]
237238
#![feature(into_cow)]
238239
#![feature(lang_items)]

src/test/run-pass/range_inclusive.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,24 @@ pub fn main() {
5555
let _ = x...&y;
5656
}
5757

58+
// test collection indexing
59+
let vec = (0...10).collect::<Vec<_>>();
60+
let slice: &[_] = &*vec;
61+
let string = String::from("hello world");
62+
let stir = "hello world";
63+
64+
assert_eq!(&vec[3...6], &[3, 4, 5, 6]);
65+
assert_eq!(&vec[ ...6], &[0, 1, 2, 3, 4, 5, 6]);
66+
67+
assert_eq!(&slice[3...6], &[3, 4, 5, 6]);
68+
assert_eq!(&slice[ ...6], &[0, 1, 2, 3, 4, 5, 6]);
69+
70+
assert_eq!(&string[3...6], "lo w");
71+
assert_eq!(&string[ ...6], "hello w");
72+
73+
assert_eq!(&stir[3...6], "lo w");
74+
assert_eq!(&stir[ ...6], "hello w");
75+
5876
// test the size hints and emptying
5977
let mut long = 0...255u8;
6078
let mut short = 42...42;

0 commit comments

Comments
 (0)