Skip to content

Commit a5dd584

Browse files
committed
---
yaml --- r: 232818 b: refs/heads/try c: e9111e6 h: refs/heads/master v: v3
1 parent f21f6ab commit a5dd584

File tree

14 files changed

+336
-17
lines changed

14 files changed

+336
-17
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: edeb4f1c86cbf6af8ef9874d4b3af50f721ea1b8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 645d7ae739da255dbef79c48613acb9e25baac47
4+
refs/heads/try: e9111e6a0ee06f56625370b0116ac1246eb01de6
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ Read ["Installing Rust"] from [The Book].
6565
tools.
6666
6767
```sh
68+
# Update package mirrors (may be needed if you have a fresh install of MSYS2)
69+
$ pacman -Sy pacman-mirrors
70+
6871
# Choose one based on platform:
6972
$ pacman -S mingw-w64-i686-toolchain
7073
$ pacman -S mingw-w64-x86_64-toolchain

branches/try/src/doc/trpl/ffi.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -496,9 +496,11 @@ strings are not terminated with `\0`. If you need a NUL-terminated string for
496496
interoperability with C, you should use the `CString` type in the `std::ffi`
497497
module.
498498

499-
The standard library includes type aliases and function definitions for the C
500-
standard library in the `libc` module, and Rust links against `libc` and `libm`
501-
by default.
499+
The [`libc` crate on crates.io][libc] includes type aliases and function
500+
definitions for the C standard library in the `libc` module, and Rust links
501+
against `libc` and `libm` by default.
502+
503+
[libc]: https://crates.io/crates/libc
502504

503505
# The "nullable pointer optimization"
504506

branches/try/src/libcollections/btree/map.rs

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
459459
}
460460
});
461461
match result {
462-
Finished(ret) => return ret,
462+
Finished(ret) => return ret.map(|(_, v)| v),
463463
Continue(new_stack) => stack = new_stack
464464
}
465465
}
@@ -693,16 +693,16 @@ mod stack {
693693
impl<'a, K, V> SearchStack<'a, K, V, handle::KV, handle::Leaf> {
694694
/// Removes the key and value in the top element of the stack, then handles underflows as
695695
/// described in BTree's pop function.
696-
fn remove_leaf(mut self) -> V {
696+
fn remove_leaf(mut self) -> (K, V) {
697697
self.map.length -= 1;
698698

699699
// Remove the key-value pair from the leaf that this search stack points to.
700700
// Then, note if the leaf is underfull, and promptly forget the leaf and its ptr
701701
// to avoid ownership issues.
702-
let (value, mut underflow) = unsafe {
703-
let (_, value) = self.top.from_raw_mut().remove_as_leaf();
702+
let (key_val, mut underflow) = unsafe {
703+
let key_val = self.top.from_raw_mut().remove_as_leaf();
704704
let underflow = self.top.from_raw().node().is_underfull();
705-
(value, underflow)
705+
(key_val, underflow)
706706
};
707707

708708
loop {
@@ -717,7 +717,7 @@ mod stack {
717717
self.map.depth -= 1;
718718
self.map.root.hoist_lone_child();
719719
}
720-
return value;
720+
return key_val;
721721
}
722722
Some(mut handle) => {
723723
if underflow {
@@ -728,7 +728,7 @@ mod stack {
728728
}
729729
} else {
730730
// All done!
731-
return value;
731+
return key_val;
732732
}
733733
}
734734
}
@@ -739,7 +739,7 @@ mod stack {
739739
impl<'a, K, V> SearchStack<'a, K, V, handle::KV, handle::LeafOrInternal> {
740740
/// Removes the key and value in the top element of the stack, then handles underflows as
741741
/// described in BTree's pop function.
742-
pub fn remove(self) -> V {
742+
pub fn remove(self) -> (K, V) {
743743
// Ensure that the search stack goes to a leaf. This is necessary to perform deletion
744744
// in a BTree. Note that this may put the tree in an inconsistent state (further
745745
// described in into_leaf's comments), but this is immediately fixed by the
@@ -1208,7 +1208,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
12081208
/// Takes the value of the entry out of the map, and returns it.
12091209
#[stable(feature = "rust1", since = "1.0.0")]
12101210
pub fn remove(self) -> V {
1211-
self.stack.remove()
1211+
self.stack.remove().1
12121212
}
12131213
}
12141214

@@ -1609,3 +1609,86 @@ impl<K: Ord, V> BTreeMap<K, V> {
16091609
}
16101610
}
16111611
}
1612+
1613+
impl<K, Q: ?Sized> super::Recover<Q> for BTreeMap<K, ()> where K: Borrow<Q> + Ord, Q: Ord {
1614+
type Key = K;
1615+
1616+
fn get(&self, key: &Q) -> Option<&K> {
1617+
let mut cur_node = &self.root;
1618+
loop {
1619+
match Node::search(cur_node, key) {
1620+
Found(handle) => return Some(handle.into_kv().0),
1621+
GoDown(handle) => match handle.force() {
1622+
Leaf(_) => return None,
1623+
Internal(internal_handle) => {
1624+
cur_node = internal_handle.into_edge();
1625+
continue;
1626+
}
1627+
}
1628+
}
1629+
}
1630+
}
1631+
1632+
fn take(&mut self, key: &Q) -> Option<K> {
1633+
// See `remove` for an explanation of this.
1634+
1635+
let mut stack = stack::PartialSearchStack::new(self);
1636+
loop {
1637+
let result = stack.with(move |pusher, node| {
1638+
match Node::search(node, key) {
1639+
Found(handle) => {
1640+
// Perfect match. Terminate the stack here, and remove the entry
1641+
Finished(Some(pusher.seal(handle).remove()))
1642+
},
1643+
GoDown(handle) => {
1644+
// We need to keep searching, try to go down the next edge
1645+
match handle.force() {
1646+
// We're at a leaf; the key isn't in here
1647+
Leaf(_) => Finished(None),
1648+
Internal(internal_handle) => Continue(pusher.push(internal_handle))
1649+
}
1650+
}
1651+
}
1652+
});
1653+
match result {
1654+
Finished(ret) => return ret.map(|(k, _)| k),
1655+
Continue(new_stack) => stack = new_stack
1656+
}
1657+
}
1658+
}
1659+
1660+
fn replace(&mut self, mut key: K) -> Option<K> {
1661+
// See `insert` for an explanation of this.
1662+
1663+
let mut stack = stack::PartialSearchStack::new(self);
1664+
1665+
loop {
1666+
let result = stack.with(move |pusher, node| {
1667+
match Node::search::<K, _>(node, &key) {
1668+
Found(mut handle) => {
1669+
mem::swap(handle.key_mut(), &mut key);
1670+
Finished(Some(key))
1671+
},
1672+
GoDown(handle) => {
1673+
match handle.force() {
1674+
Leaf(leaf_handle) => {
1675+
pusher.seal(leaf_handle).insert(key, ());
1676+
Finished(None)
1677+
}
1678+
Internal(internal_handle) => {
1679+
Continue((pusher.push(internal_handle), key, ()))
1680+
}
1681+
}
1682+
}
1683+
}
1684+
});
1685+
match result {
1686+
Finished(ret) => return ret,
1687+
Continue((new_stack, renewed_key, _)) => {
1688+
stack = new_stack;
1689+
key = renewed_key;
1690+
}
1691+
}
1692+
}
1693+
}
1694+
}

branches/try/src/libcollections/btree/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,11 @@
1111
mod node;
1212
pub mod map;
1313
pub mod set;
14+
15+
trait Recover<Q: ?Sized> {
16+
type Key;
17+
18+
fn get(&self, key: &Q) -> Option<&Self::Key>;
19+
fn take(&mut self, key: &Q) -> Option<Self::Key>;
20+
fn replace(&mut self, key: Self::Key) -> Option<Self::Key>;
21+
}

branches/try/src/libcollections/btree/set.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use core::ops::{BitOr, BitAnd, BitXor, Sub};
1919

2020
use borrow::Borrow;
2121
use btree_map::{BTreeMap, Keys};
22+
use super::Recover;
2223
use Bound;
2324

2425
// FIXME(conventions): implement bounded iterators
@@ -329,6 +330,16 @@ impl<T: Ord> BTreeSet<T> {
329330
self.map.contains_key(value)
330331
}
331332

333+
/// Returns a reference to the value in the set, if any, that is equal to the given value.
334+
///
335+
/// The value may be any borrowed form of the set's value type,
336+
/// but the ordering on the borrowed form *must* match the
337+
/// ordering on the value type.
338+
#[unstable(feature = "set_recovery", issue = "28050")]
339+
pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T> where T: Borrow<Q>, Q: Ord {
340+
Recover::get(&self.map, value)
341+
}
342+
332343
/// Returns `true` if the set has no elements in common with `other`.
333344
/// This is equivalent to checking for an empty intersection.
334345
///
@@ -436,6 +447,13 @@ impl<T: Ord> BTreeSet<T> {
436447
self.map.insert(value, ()).is_none()
437448
}
438449

450+
/// Adds a value to the set, replacing the existing value, if any, that is equal to the given
451+
/// one. Returns the replaced value.
452+
#[unstable(feature = "set_recovery", issue = "28050")]
453+
pub fn replace(&mut self, value: T) -> Option<T> {
454+
Recover::replace(&mut self.map, value)
455+
}
456+
439457
/// Removes a value from the set. Returns `true` if the value was
440458
/// present in the set.
441459
///
@@ -458,6 +476,16 @@ impl<T: Ord> BTreeSet<T> {
458476
pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool where T: Borrow<Q>, Q: Ord {
459477
self.map.remove(value).is_some()
460478
}
479+
480+
/// Removes and returns the value in the set, if any, that is equal to the given one.
481+
///
482+
/// The value may be any borrowed form of the set's value type,
483+
/// but the ordering on the borrowed form *must* match the
484+
/// ordering on the value type.
485+
#[unstable(feature = "set_recovery", issue = "28050")]
486+
pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T> where T: Borrow<Q>, Q: Ord {
487+
Recover::take(&mut self.map, value)
488+
}
461489
}
462490

463491
#[stable(feature = "rust1", since = "1.0.0")]

branches/try/src/libcollections/fmt.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ pub use core::fmt::{LowerHex, UpperHex, Pointer};
481481
pub use core::fmt::{LowerExp, UpperExp};
482482
pub use core::fmt::Error;
483483
pub use core::fmt::{ArgumentV1, Arguments, write, radix, Radix, RadixFmt};
484+
pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
484485

485486
use string;
486487

branches/try/src/libcollectionstest/btree/set.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,52 @@ fn test_extend_ref() {
211211
assert!(a.contains(&5));
212212
assert!(a.contains(&6));
213213
}
214+
215+
#[test]
216+
fn test_recovery() {
217+
use std::cmp::Ordering;
218+
219+
#[derive(Debug)]
220+
struct Foo(&'static str, i32);
221+
222+
impl PartialEq for Foo {
223+
fn eq(&self, other: &Self) -> bool {
224+
self.0 == other.0
225+
}
226+
}
227+
228+
impl Eq for Foo {}
229+
230+
impl PartialOrd for Foo {
231+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
232+
self.0.partial_cmp(&other.0)
233+
}
234+
}
235+
236+
impl Ord for Foo {
237+
fn cmp(&self, other: &Self) -> Ordering {
238+
self.0.cmp(&other.0)
239+
}
240+
}
241+
242+
let mut s = BTreeSet::new();
243+
assert_eq!(s.replace(Foo("a", 1)), None);
244+
assert_eq!(s.len(), 1);
245+
assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
246+
assert_eq!(s.len(), 1);
247+
248+
{
249+
let mut it = s.iter();
250+
assert_eq!(it.next(), Some(&Foo("a", 2)));
251+
assert_eq!(it.next(), None);
252+
}
253+
254+
assert_eq!(s.get(&Foo("a", 1)), Some(&Foo("a", 2)));
255+
assert_eq!(s.take(&Foo("a", 1)), Some(Foo("a", 2)));
256+
assert_eq!(s.len(), 0);
257+
258+
assert_eq!(s.get(&Foo("a", 1)), None);
259+
assert_eq!(s.take(&Foo("a", 1)), None);
260+
261+
assert_eq!(s.iter().next(), None);
262+
}

branches/try/src/libcollectionstest/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#![feature(rand)]
2626
#![feature(range_inclusive)]
2727
#![feature(rustc_private)]
28+
#![feature(set_recovery)]
2829
#![feature(slice_bytes)]
2930
#![feature(slice_splits)]
3031
#![feature(split_off)]

branches/try/src/libcore/str/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,18 @@ impl<'a> DoubleEndedIterator for Chars<'a> {
292292
}
293293
}
294294

295+
impl<'a> Chars<'a> {
296+
/// View the underlying data as a subslice of the original data.
297+
///
298+
/// This has the same lifetime as the original slice, and so the
299+
/// iterator can continue to be used while this exists.
300+
#[unstable(feature = "iter_to_slice", issue = "27775")]
301+
#[inline]
302+
pub fn as_str(&self) -> &'a str {
303+
unsafe { from_utf8_unchecked(self.iter.as_slice()) }
304+
}
305+
}
306+
295307
/// Iterator for a string's characters and their byte offsets.
296308
#[derive(Clone)]
297309
#[stable(feature = "rust1", since = "1.0.0")]
@@ -339,6 +351,18 @@ impl<'a> DoubleEndedIterator for CharIndices<'a> {
339351
}
340352
}
341353

354+
impl<'a> CharIndices<'a> {
355+
/// View the underlying data as a subslice of the original data.
356+
///
357+
/// This has the same lifetime as the original slice, and so the
358+
/// iterator can continue to be used while this exists.
359+
#[unstable(feature = "iter_to_slice", issue = "27775")]
360+
#[inline]
361+
pub fn as_str(&self) -> &'a str {
362+
self.iter.as_str()
363+
}
364+
}
365+
342366
/// External iterator for a string's bytes.
343367
/// Use with the `std::iter` module.
344368
///

0 commit comments

Comments
 (0)