From 4fdeb353ceecd17fd7894bd7968d266a437d652e Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Wed, 5 Aug 2015 15:12:10 -0400 Subject: [PATCH] Fully generalize `BTree{Map, Set}` range iterators This permits collections with `String` keys to be ranged over with `&str` bounds. The `K` defaults for `Min` and `Max` permit the default type parameter fallback to work with things like ```rust use std::collections::{BTreeSet, Bound}; let set = BTreeSet::::new(); set.range(Bound::Included("a"), Bound::Unbounded); ``` Without the defaults, the type of the maximum bound would be unconstrained. --- src/libcollections/btree/map.rs | 14 +++++++++++--- src/libcollections/btree/node.rs | 8 ++++++-- src/libcollections/btree/set.rs | 6 +++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 9fa54c6ca2f..f5d1d44b404 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -1522,7 +1522,11 @@ impl BTreeMap { /// ``` #[unstable(feature = "btree_range", reason = "matches collection reform specification, waiting for dust to settle")] - pub fn range<'a>(&'a self, min: Bound<&K>, max: Bound<&K>) -> Range<'a, K, V> { + pub fn range(&self, min: Bound<&Min>, + max: Bound<&Max>) + -> Range where + K: Borrow + Borrow, + { range_impl!(&self.root, min, max, as_slices_internal, iter, Range, edges, []) } @@ -1542,7 +1546,7 @@ impl BTreeMap { /// let mut map: BTreeMap<&str, i32> = ["Alice", "Bob", "Carol", "Cheryl"].iter() /// .map(|&s| (s, 0)) /// .collect(); - /// for (_, balance) in map.range_mut(Included(&"B"), Excluded(&"Cheryl")) { + /// for (_, balance) in map.range_mut(Included("B"), Excluded("Cheryl")) { /// *balance += 100; /// } /// for (name, balance) in &map { @@ -1551,7 +1555,11 @@ impl BTreeMap { /// ``` #[unstable(feature = "btree_range", reason = "matches collection reform specification, waiting for dust to settle")] - pub fn range_mut<'a>(&'a mut self, min: Bound<&K>, max: Bound<&K>) -> RangeMut<'a, K, V> { + pub fn range_mut(&mut self, min: Bound<&Min>, + max: Bound<&Max>) + -> RangeMut where + K: Borrow + Borrow, + { range_impl!(&mut self.root, min, max, as_slices_internal_mut, iter_mut, RangeMut, edges_mut, [mut]) } diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index b9cd73470b6..9f2e1db42c9 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -1528,7 +1528,9 @@ macro_rules! node_slice_impl { } /// Returns a sub-slice with elements starting with `min_key`. - pub fn slice_from(self, min_key: &K) -> $NodeSlice<'a, K, V> { + pub fn slice_from(self, min_key: &Q) -> $NodeSlice<'a, K, V> where + K: Borrow, + { // _______________ // |_1_|_3_|_5_|_7_| // | | | | | @@ -1556,7 +1558,9 @@ macro_rules! node_slice_impl { } /// Returns a sub-slice with elements up to and including `max_key`. - pub fn slice_to(self, max_key: &K) -> $NodeSlice<'a, K, V> { + pub fn slice_to(self, max_key: &Q) -> $NodeSlice<'a, K, V> where + K: Borrow, + { // _______________ // |_1_|_3_|_5_|_7_| // | | | | | diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index b9430b2d003..e31147b7308 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -158,7 +158,11 @@ impl BTreeSet { /// ``` #[unstable(feature = "btree_range", reason = "matches collection reform specification, waiting for dust to settle")] - pub fn range<'a>(&'a self, min: Bound<&T>, max: Bound<&T>) -> Range<'a, T> { + pub fn range<'a, Min: ?Sized + Ord = T, Max: ?Sized + Ord = T>(&'a self, min: Bound<&Min>, + max: Bound<&Max>) + -> Range<'a, T> where + T: Borrow + Borrow, + { fn first((a, _): (A, B)) -> A { a } let first: fn((&'a T, &'a ())) -> &'a T = first; // coerce to fn pointer