Skip to content

Commit

Permalink
Auto merge of #23601 - nikomatsakis:by-value-index, r=japaric
Browse files Browse the repository at this point in the history
This is a [breaking-change]. When indexing a generic map (hashmap, etc) using the `[]` operator, it is now necessary to borrow explicitly, so change `map[key]` to `map[&key]` (consistent with the `get` routine). However, indexing of string-valued maps with constant strings can now be written `map["abc"]`.

r? @japaric
cc @aturon @gankro
  • Loading branch information
bors committed Mar 23, 2015
2 parents b0aad7d + b760c56 commit 2aa6858
Show file tree
Hide file tree
Showing 74 changed files with 983 additions and 180 deletions.
12 changes: 12 additions & 0 deletions src/libcollections/bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ pub struct BitVec {
impl Index<usize> for BitVec {
type Output = bool;


#[cfg(stage0)]
#[inline]
fn index(&self, i: &usize) -> &bool {
if self.get(*i).expect("index out of bounds") {
Expand All @@ -177,6 +179,16 @@ impl Index<usize> for BitVec {
&FALSE
}
}

#[cfg(not(stage0))]
#[inline]
fn index(&self, i: usize) -> &bool {
if self.get(i).expect("index out of bounds") {
&TRUE
} else {
&FALSE
}
}
}

/// Computes how many blocks are needed to store that many bits
Expand Down
32 changes: 30 additions & 2 deletions src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// Some(x) => *x = "b",
/// None => (),
/// }
/// assert_eq!(map[1], "b");
/// assert_eq!(map[&1], "b");
/// ```
// See `get` for implementation notes, this is basically a copy-paste with mut's added
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -326,7 +326,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
///
/// map.insert(37, "b");
/// assert_eq!(map.insert(37, "c"), Some("b"));
/// assert_eq!(map[37], "c");
/// assert_eq!(map[&37], "c");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn insert(&mut self, mut key: K, mut value: V) -> Option<V> {
Expand Down Expand Up @@ -914,21 +914,49 @@ impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
where K: Borrow<Q>, Q: Ord
{
type Output = V;

#[inline]
fn index(&self, key: &Q) -> &V {
self.get(key).expect("no entry found for key")
}
}

#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K: Ord, Q: ?Sized, V> Index<&'a Q> for BTreeMap<K, V>
where K: Borrow<Q>, Q: Ord
{
type Output = V;

#[inline]
fn index(&self, key: &Q) -> &V {
self.get(key).expect("no entry found for key")
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<K: Ord, Q: ?Sized, V> IndexMut<Q> for BTreeMap<K, V>
where K: Borrow<Q>, Q: Ord
{
#[inline]
fn index_mut(&mut self, key: &Q) -> &mut V {
self.get_mut(key).expect("no entry found for key")
}
}

#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K: Ord, Q: ?Sized, V> IndexMut<&'a Q> for BTreeMap<K, V>
where K: Borrow<Q>, Q: Ord
{
#[inline]
fn index_mut(&mut self, key: &Q) -> &mut V {
self.get_mut(key).expect("no entry found for key")
}
Expand Down
61 changes: 61 additions & 0 deletions src/libcollections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,7 @@ macro_rules! node_slice_impl {
}

/// Returns a sub-slice with elements starting with `min_key`.
#[cfg(stage0)]
pub fn slice_from(self, min_key: &K) -> $NodeSlice<'a, K, V> {
// _______________
// |_1_|_3_|_5_|_7_|
Expand Down Expand Up @@ -1549,7 +1550,37 @@ macro_rules! node_slice_impl {
}
}

/// Returns a sub-slice with elements starting with `min_key`.
#[cfg(not(stage0))]
pub fn slice_from(self, min_key: &K) -> $NodeSlice<'a, K, V> {
// _______________
// |_1_|_3_|_5_|_7_|
// | | | | |
// 0 0 1 1 2 2 3 3 4 index
// | | | | |
// \___|___|___|___/ slice_from(&0); pos = 0
// \___|___|___/ slice_from(&2); pos = 1
// |___|___|___/ slice_from(&3); pos = 1; result.head_is_edge = false
// \___|___/ slice_from(&4); pos = 2
// \___/ slice_from(&6); pos = 3
// \|/ slice_from(&999); pos = 4
let (pos, pos_is_kv) = self.search_linear(min_key);
$NodeSlice {
has_edges: self.has_edges,
edges: if !self.has_edges {
self.edges
} else {
self.edges.$index(pos ..)
},
keys: &self.keys[pos ..],
vals: self.vals.$index(pos ..),
head_is_edge: !pos_is_kv,
tail_is_edge: self.tail_is_edge,
}
}

/// Returns a sub-slice with elements up to and including `max_key`.
#[cfg(stage0)]
pub fn slice_to(self, max_key: &K) -> $NodeSlice<'a, K, V> {
// _______________
// |_1_|_3_|_5_|_7_|
Expand Down Expand Up @@ -1577,6 +1608,36 @@ macro_rules! node_slice_impl {
tail_is_edge: !pos_is_kv,
}
}

/// Returns a sub-slice with elements up to and including `max_key`.
#[cfg(not(stage0))]
pub fn slice_to(self, max_key: &K) -> $NodeSlice<'a, K, V> {
// _______________
// |_1_|_3_|_5_|_7_|
// | | | | |
// 0 0 1 1 2 2 3 3 4 index
// | | | | |
//\|/ | | | | slice_to(&0); pos = 0
// \___/ | | | slice_to(&2); pos = 1
// \___|___| | | slice_to(&3); pos = 1; result.tail_is_edge = false
// \___|___/ | | slice_to(&4); pos = 2
// \___|___|___/ | slice_to(&6); pos = 3
// \___|___|___|___/ slice_to(&999); pos = 4
let (pos, pos_is_kv) = self.search_linear(max_key);
let pos = pos + if pos_is_kv { 1 } else { 0 };
$NodeSlice {
has_edges: self.has_edges,
edges: if !self.has_edges {
self.edges
} else {
self.edges.$index(.. (pos + 1))
},
keys: &self.keys[..pos],
vals: self.vals.$index(.. pos),
head_is_edge: self.head_is_edge,
tail_is_edge: !pos_is_kv,
}
}
}

impl<'a, K: 'a, V: 'a> $NodeSlice<'a, K, V> {
Expand Down
32 changes: 32 additions & 0 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,34 +870,66 @@ impl<'a> Add<&'a str> for String {
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::Range<usize>> for String {
type Output = str;

#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::Range<usize>) -> &str {
&self[..][*index]
}

#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::Range<usize>) -> &str {
&self[..][index]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeTo<usize>> for String {
type Output = str;

#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeTo<usize>) -> &str {
&self[..][*index]
}

#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &str {
&self[..][index]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFrom<usize>> for String {
type Output = str;

#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
&self[..][*index]
}

#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &str {
&self[..][index]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for String {
type Output = str;

#[cfg(stage0)]
#[inline]
fn index(&self, _index: &ops::RangeFull) -> &str {
unsafe { mem::transmute(&*self.vec) }
}

#[cfg(not(stage0))]
#[inline]
fn index(&self, _index: ops::RangeFull) -> &str {
unsafe { mem::transmute(&*self.vec) }
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
Loading

0 comments on commit 2aa6858

Please sign in to comment.