Skip to content

Commit b7ff256

Browse files
committed
---
yaml --- r: 123864 b: refs/heads/snap-stage3 c: be7a170 h: refs/heads/master v: v3
1 parent 6a9e592 commit b7ff256

File tree

3 files changed

+143
-83
lines changed

3 files changed

+143
-83
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: 4e2da7cb79143b0e7206a684629ed942599ec8e9
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 3f3291e0c7d9d189553b16c52dda3851423534a5
4+
refs/heads/snap-stage3: be7a17062b103b31798afcd525c51a9642038465
55
refs/heads/try: 296eb104620b346d88bc4a2c2ab7693e6d3db019
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libcollections/treemap.rs

Lines changed: 136 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -88,40 +88,18 @@ impl<K: Ord, V> Mutable for TreeMap<K, V> {
8888
}
8989

9090
impl<K: Ord, V> Map<K, V> for TreeMap<K, V> {
91+
// See comments on tree_find_with
92+
#[inline]
9193
fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
92-
let mut current = &self.root;
93-
loop {
94-
match *current {
95-
Some(ref r) => {
96-
match key.cmp(&r.key) {
97-
Less => current = &r.left,
98-
Greater => current = &r.right,
99-
Equal => return Some(&r.value)
100-
}
101-
}
102-
None => return None
103-
}
104-
}
94+
tree_find_with(&self.root, |k2| key.cmp(k2))
10595
}
10696
}
10797

10898
impl<K: Ord, V> MutableMap<K, V> for TreeMap<K, V> {
99+
// See comments on def_tree_find_mut_with
109100
#[inline]
110101
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
111-
let mut current = &mut self.root;
112-
loop {
113-
let temp = current; // hack to appease borrowck
114-
match *temp {
115-
Some(ref mut r) => {
116-
match key.cmp(&r.key) {
117-
Less => current = &mut r.left,
118-
Greater => current = &mut r.right,
119-
Equal => return Some(&mut r.value)
120-
}
121-
}
122-
None => return None
123-
}
124-
}
102+
tree_find_mut_with(&mut self.root, |x| key.cmp(x))
125103
}
126104

127105
fn swap(&mut self, key: K, value: V) -> Option<V> {
@@ -194,6 +172,55 @@ impl<K: Ord, V> TreeMap<K, V> {
194172
}
195173
}
196174

175+
impl<K, V> TreeMap<K, V> {
176+
/// Return the value for which f(key) returns Equal. f is invoked
177+
/// with current key and helps to navigate the tree
178+
///
179+
/// # Example
180+
///
181+
/// ```
182+
/// use std::ascii::StrAsciiExt;
183+
///
184+
/// let mut t = collections::treemap::TreeMap::new();
185+
/// t.insert("Content-Type", "application/xml");
186+
/// t.insert("User-Agent", "Curl-Rust/0.1");
187+
///
188+
/// let ua_key = "user-agent";
189+
/// let ua = t.find_with(|&k| {
190+
/// ua_key.cmp(&k.to_ascii_lower().as_slice())
191+
/// });
192+
///
193+
/// assert_eq!(*ua.unwrap(), "Curl-Rust/0.1");
194+
/// ```
195+
#[inline]
196+
pub fn find_with<'a>(&'a self, f:|&K| -> Ordering) -> Option<&'a V> {
197+
tree_find_with(&self.root, f)
198+
}
199+
200+
/// Return the value for which f(key) returns Equal. f is invoked
201+
/// with current key and helps to navigate the tree
202+
///
203+
/// # Example
204+
///
205+
/// ```
206+
/// let mut t = collections::treemap::TreeMap::new();
207+
/// t.insert("Content-Type", "application/xml");
208+
/// t.insert("User-Agent", "Curl-Rust/0.1");
209+
///
210+
/// let new_ua = "Safari/156.0";
211+
/// match t.find_mut_with(|k| "User-Agent".cmp(k)) {
212+
/// Some(x) => *x = new_ua,
213+
/// None => fail!(),
214+
/// }
215+
///
216+
/// assert_eq!(t.find(&"User-Agent"), Some(&new_ua));
217+
/// ```
218+
#[inline]
219+
pub fn find_mut_with<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
220+
tree_find_mut_with(&mut self.root, f)
221+
}
222+
}
223+
197224
// range iterators.
198225

199226
macro_rules! bound_setup {
@@ -853,6 +880,51 @@ fn split<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
853880
}
854881
}
855882

883+
// Next 2 functions have the same conventions
884+
//
885+
// The only difference is that non-mutable version uses loop instead
886+
// of recursion (performance considerations)
887+
// It seems to be impossible to avoid recursion with mutability
888+
//
889+
// So convention is that comparator is gets at input current key
890+
// and returns search_key cmp cur_key (i.e. search_key.cmp(cur_key))
891+
fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
892+
f: |&K| -> Ordering) -> Option<&'r V> {
893+
let mut current: &'r Option<Box<TreeNode<K, V>>> = node;
894+
loop {
895+
match *current {
896+
Some(ref r) => {
897+
match f(&r.key) {
898+
Less => current = &r.left,
899+
Greater => current = &r.right,
900+
Equal => return Some(&r.value)
901+
}
902+
}
903+
None => return None
904+
}
905+
}
906+
}
907+
908+
// See comments above tree_find_with
909+
fn tree_find_mut_with<'r, K, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
910+
f: |&K| -> Ordering) -> Option<&'r mut V> {
911+
912+
let mut current = node;
913+
loop {
914+
let temp = current; // hack to appease borrowck
915+
match *temp {
916+
Some(ref mut r) => {
917+
match f(&r.key) {
918+
Less => current = &mut r.left,
919+
Greater => current = &mut r.right,
920+
Equal => return Some(&mut r.value)
921+
}
922+
}
923+
None => return None
924+
}
925+
}
926+
}
927+
856928
fn insert<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
857929
key: K, value: V) -> Option<V> {
858930
match *node {
@@ -1024,6 +1096,30 @@ mod test_treemap {
10241096
assert_eq!(m.find(&2), None);
10251097
}
10261098

1099+
#[test]
1100+
fn find_with_empty() {
1101+
let m: TreeMap<&'static str,int> = TreeMap::new();
1102+
assert!(m.find_with(|k| "test".cmp(k)) == None);
1103+
}
1104+
1105+
#[test]
1106+
fn find_with_not_found() {
1107+
let mut m = TreeMap::new();
1108+
assert!(m.insert("test1", 2i));
1109+
assert!(m.insert("test2", 3i));
1110+
assert!(m.insert("test3", 3i));
1111+
assert_eq!(m.find_with(|k| "test4".cmp(k)), None);
1112+
}
1113+
1114+
#[test]
1115+
fn find_with_found() {
1116+
let mut m = TreeMap::new();
1117+
assert!(m.insert("test1", 2i));
1118+
assert!(m.insert("test2", 3i));
1119+
assert!(m.insert("test3", 4i));
1120+
assert_eq!(m.find_with(|k| "test2".cmp(k)), Some(&3i));
1121+
}
1122+
10271123
#[test]
10281124
fn test_find_mut() {
10291125
let mut m = TreeMap::new();
@@ -1037,6 +1133,19 @@ mod test_treemap {
10371133
assert_eq!(m.find(&5), Some(&new));
10381134
}
10391135

1136+
#[test]
1137+
fn test_find_with_mut() {
1138+
let mut m = TreeMap::new();
1139+
assert!(m.insert("t1", 12i));
1140+
assert!(m.insert("t2", 8));
1141+
assert!(m.insert("t5", 14));
1142+
let new = 100;
1143+
match m.find_mut_with(|k| "t5".cmp(k)) {
1144+
None => fail!(), Some(x) => *x = new
1145+
}
1146+
assert_eq!(m.find_with(|k| "t5".cmp(k)), Some(&new));
1147+
}
1148+
10401149
#[test]
10411150
fn insert_replace() {
10421151
let mut m = TreeMap::new();

branches/snap-stage3/src/libcore/any.rs

Lines changed: 6 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -13,61 +13,12 @@
1313
//! This module implements the `Any` trait, which enables dynamic typing
1414
//! of any `'static` type through runtime reflection.
1515
//!
16-
//! `Any` itself can be used to get a `TypeId`, and has more features when used
17-
//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
18-
//! `as_ref` methods, to test if the contained value is of a given type, and to
19-
//! get a reference to the inner value as a type. As`&mut Any`, there is also
20-
//! the `as_mut` method, for getting a mutable reference to the inner value.
21-
//! `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the
22-
//! object. See the extension traits (`*Ext`) for the full details.
23-
//!
24-
//! Note that &Any is limited to testing whether a value is of a specified
25-
//! concrete type, and cannot be used to test whether a type implements a trait.
26-
//!
27-
//! # Examples
28-
//!
29-
//! Consider a situation where we want to log out a value passed to a function.
30-
//! We know the value we're working on implements Show, but we don't know its
31-
//! concrete type. We want to give special treatment to certain types: in this
32-
//! case printing out the length of String values prior to their value.
33-
//! We don't know the concrete type of our value at compile time, so we need to
34-
//! use runtime reflection instead.
35-
//!
36-
//! ```rust
37-
//! use std::fmt::Show;
38-
//! use std::any::{Any, AnyRefExt};
39-
//!
40-
//! // Logger function for any type that implements Show.
41-
//! fn log<T: Any+Show>(value: &T) {
42-
//! let value_any = value as &Any;
43-
//!
44-
//! // try to convert our value to a String. If successful, we want to
45-
//! // output the String's length as well as its value. If not, it's a
46-
//! // different type: just print it out unadorned.
47-
//! match value_any.as_ref::<String>() {
48-
//! Some(as_string) => {
49-
//! println!("String ({}): {}", as_string.len(), as_string);
50-
//! }
51-
//! None => {
52-
//! println!("{}", value);
53-
//! }
54-
//! }
55-
//! }
56-
//!
57-
//! // This function wants to log its parameter out prior to doing work with it.
58-
//! fn do_work<T: Show>(value: &T) {
59-
//! log(value);
60-
//! // ...do some other work
61-
//! }
62-
//!
63-
//! fn main() {
64-
//! let my_string = "Hello World".to_string();
65-
//! do_work(&my_string);
66-
//!
67-
//! let my_i8: i8 = 100;
68-
//! do_work(&my_i8);
69-
//! }
70-
//! ```
16+
//! `Any` itself can be used to get a `TypeId`, and has more features when used as a trait object.
17+
//! As `&Any` (a borrowed trait object), it has the `is` and `as_ref` methods, to test if the
18+
//! contained value is of a given type, and to get a reference to the inner value as a type. As
19+
//! `&mut Any`, there is also the `as_mut` method, for getting a mutable reference to the inner
20+
//! value. `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the object. See
21+
//! the extension traits (`*Ext`) for the full details.
7122
7223
use mem::{transmute, transmute_copy};
7324
use option::{Option, Some, None};

0 commit comments

Comments
 (0)