From 5eec666c8c4be3706a79755e6cb1119990390c79 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Wed, 12 Nov 2014 14:55:44 -0800 Subject: [PATCH] libcollections: use BorrowFrom in TreeSet, Map This commit generalizes methods like `get` and `remove` for `TreeMap` and `TreeSet` to use the new `std::borrow` infrastructure. [breaking-change] --- src/libcollections/tree/map.rs | 54 ++++++++++++++++++++++++---------- src/libcollections/tree/set.rs | 19 ++++++++++-- 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs index 50bfeafc43e..119268c27ee 100644 --- a/src/libcollections/tree/map.rs +++ b/src/libcollections/tree/map.rs @@ -11,6 +11,8 @@ use core::prelude::*; use alloc::boxed::Box; + +use core::borrow::BorrowFrom; use core::default::Default; use core::fmt; use core::fmt::Show; @@ -188,16 +190,16 @@ impl Default for TreeMap { fn default() -> TreeMap { TreeMap::new() } } -impl Index for TreeMap { +impl Index for TreeMap where Q: BorrowFrom + Ord { #[inline] - fn index<'a>(&'a self, i: &K) -> &'a V { + fn index<'a>(&'a self, i: &Q) -> &'a V { self.get(i).expect("no entry found for key") } } -impl IndexMut for TreeMap { +impl IndexMut for TreeMap where Q: BorrowFrom + Ord { #[inline] - fn index_mut<'a>(&'a mut self, i: &K) -> &'a mut V { + fn index_mut<'a>(&'a mut self, i: &Q) -> &'a mut V { self.get_mut(i).expect("no entry found for key") } } @@ -446,6 +448,9 @@ pub fn find(&self, key: &K) -> Option<&V> { /// Returns a reference to the value corresponding to the key. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -458,12 +463,17 @@ pub fn find(&self, key: &K) -> Option<&V> { /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get(&self, key: &K) -> Option<&V> { - tree_find_with(&self.root, |k2| key.cmp(k2)) + pub fn get(&self, key: &Q) -> Option<&V> + where Q: BorrowFrom + Ord + { + tree_find_with(&self.root, |k2| key.cmp(BorrowFrom::borrow_from(k2))) } /// Returns true if the map contains a value for the specified key. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -476,7 +486,9 @@ pub fn get(&self, key: &K) -> Option<&V> { /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains_key(&self, key: &K) -> bool { + pub fn contains_key(&self, key: &Q) -> bool + where Q: BorrowFrom + Ord + { self.get(key).is_some() } @@ -488,6 +500,9 @@ pub fn find_mut(&mut self, key: &K) -> Option<&mut V> { /// Returns a mutable reference to the value corresponding to the key. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -503,8 +518,10 @@ pub fn find_mut(&mut self, key: &K) -> Option<&mut V> { /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { - tree_find_with_mut(&mut self.root, |x| key.cmp(x)) + pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> + where Q: BorrowFrom + Ord + { + tree_find_with_mut(&mut self.root, |x| key.cmp(BorrowFrom::borrow_from(x))) } /// Deprecated: Renamed to `insert`. @@ -545,6 +562,9 @@ pub fn pop(&mut self, key: &K) -> Option { /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -556,7 +576,9 @@ pub fn pop(&mut self, key: &K) -> Option { /// assert_eq!(map.remove(&1), None); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, key: &K) -> Option { + pub fn remove(&mut self, key: &Q) -> Option + where Q: BorrowFrom + Ord + { let ret = remove(&mut self.root, key); if ret.is_some() { self.length -= 1 } ret @@ -589,6 +611,7 @@ impl TreeMap { /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1"); /// ``` #[inline] + #[experimental = "likely to be renamed, may be removed"] pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> { tree_find_with(&self.root, f) } @@ -613,6 +636,7 @@ pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> { /// assert_eq!(t.get(&"User-Agent"), Some(&new_ua)); /// ``` #[inline] + #[experimental = "likely to be renamed, may be removed"] pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> { tree_find_with_mut(&mut self.root, f) } @@ -1168,10 +1192,11 @@ fn insert(node: &mut Option>>, } } -fn remove(node: &mut Option>>, - key: &K) -> Option { +fn remove(node: &mut Option>>, key: &Q) -> Option + where K: Ord, Q: BorrowFrom + Ord +{ fn heir_swap(node: &mut Box>, - child: &mut Option>>) { + child: &mut Option>>) { // *could* be done without recursion, but it won't borrow check for x in child.iter_mut() { if x.right.is_some() { @@ -1188,7 +1213,7 @@ fn heir_swap(node: &mut Box>, return None; // bottom of tree } Some(ref mut save) => { - let (ret, rebalance) = match key.cmp(&save.key) { + let (ret, rebalance) = match key.cmp(BorrowFrom::borrow_from(&save.key)) { Less => (remove(&mut save.left, key), true), Greater => (remove(&mut save.right, key), true), Equal => { @@ -1918,4 +1943,3 @@ pub fn iter_100000(b: &mut Bencher) { bench_iter(b, 100000); } } - diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs index abfaeed7e7e..6988b929df6 100644 --- a/src/libcollections/tree/set.rs +++ b/src/libcollections/tree/set.rs @@ -10,6 +10,7 @@ use core::prelude::*; +use core::borrow::BorrowFrom; use core::default::Default; use core::fmt; use core::fmt::Show; @@ -396,6 +397,10 @@ pub fn clear(&mut self) { self.map.clear() } /// Returns `true` if the set contains a value. /// + /// The value may be any borrowed form of the set's value type, + /// but the ordering on the borrowed form *must* match the + /// ordering on the value type. + /// /// # Example /// /// ``` @@ -407,7 +412,9 @@ pub fn clear(&mut self) { self.map.clear() } /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains(&self, value: &T) -> bool { + pub fn contains(&self, value: &Q) -> bool + where Q: Ord + BorrowFrom + { self.map.contains_key(value) } @@ -519,6 +526,10 @@ pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none( /// Removes a value from the set. Returns `true` if the value was /// present in the set. /// + /// The value may be any borrowed form of the set's value type, + /// but the ordering on the borrowed form *must* match the + /// ordering on the value type. + /// /// # Example /// /// ``` @@ -532,7 +543,11 @@ pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none( /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value).is_some() } + pub fn remove(&mut self, value: &Q) -> bool + where Q: Ord + BorrowFrom + { + self.map.remove(value).is_some() + } } /// A lazy forward iterator over a set. -- GitLab