Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
429c23d5
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
429c23d5
编写于
1月 13, 2015
作者:
P
Piotr Czarnecki
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement range and range_mut for BTree
Simplify BTree's iterators, too.
上级
135cac85
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
605 addition
and
194 deletion
+605
-194
src/libcollections/btree/map.rs
src/libcollections/btree/map.rs
+333
-118
src/libcollections/btree/node.rs
src/libcollections/btree/node.rs
+215
-75
src/libcollections/btree/set.rs
src/libcollections/btree/set.rs
+46
-0
src/libcollections/lib.rs
src/libcollections/lib.rs
+10
-1
src/libstd/collections/mod.rs
src/libstd/collections/mod.rs
+1
-0
未找到文件。
src/libcollections/btree/map.rs
浏览文件 @
429c23d5
...
...
@@ -27,6 +27,7 @@
use
core
::
iter
::{
Map
,
FromIterator
};
use
core
::
ops
::{
Index
,
IndexMut
};
use
core
::{
iter
,
fmt
,
mem
};
use
Bound
::{
self
,
Included
,
Excluded
,
Unbounded
};
use
ring_buf
::
RingBuf
;
...
...
@@ -37,8 +38,6 @@
use
super
::
node
::{
Traversal
,
MutTraversal
,
MoveTraversal
};
use
super
::
node
::{
self
,
Node
,
Found
,
GoDown
};
// FIXME(conventions): implement bounded iterators
/// A map based on a B-Tree.
///
/// B-Trees represent a fundamental compromise between cache-efficiency and actually minimizing
...
...
@@ -92,9 +91,7 @@ pub struct BTreeMap<K, V> {
/// An abstract base over-which all other BTree iterators are built.
struct
AbsIter
<
T
>
{
lca
:
T
,
left
:
RingBuf
<
T
>
,
right
:
RingBuf
<
T
>
,
traversals
:
RingBuf
<
T
>
,
size
:
uint
,
}
...
...
@@ -128,6 +125,16 @@ pub struct Values<'a, K: 'a, V: 'a> {
inner
:
Map
<
(
&
'a
K
,
&
'a
V
),
&
'a
V
,
Iter
<
'a
,
K
,
V
>
,
fn
((
&
'a
K
,
&
'a
V
))
->
&
'a
V
>
}
/// An iterator over a sub-range of BTreeMap's entries.
pub
struct
Range
<
'a
,
K
:
'a
,
V
:
'a
>
{
inner
:
AbsIter
<
Traversal
<
'a
,
K
,
V
>>
}
/// A mutable iterator over a sub-range of BTreeMap's entries.
pub
struct
RangeMut
<
'a
,
K
:
'a
,
V
:
'a
>
{
inner
:
AbsIter
<
MutTraversal
<
'a
,
K
,
V
>>
}
/// A view into a single entry in a map, which may either be vacant or occupied.
#[unstable
=
"precise API still under development"
]
pub
enum
Entry
<
'a
,
K
:
'a
,
V
:
'a
>
{
...
...
@@ -924,74 +931,45 @@ fn traverse(node: Node<K, V>) -> MoveTraversal<K, V> {
}
/// Represents an operation to perform inside the following iterator methods.
/// This is necessary to use in `next` because we want to modify
self.left
inside
/// a match that borrows it. Similarly
, in `next_back` for self.right. Instead, we use this
///
enum to note
what we want to do, and do it after the match.
/// This is necessary to use in `next` because we want to modify
`self.traversals`
inside
/// a match that borrows it. Similarly
in `next_back`. Instead, we use this enum to note
/// what we want to do, and do it after the match.
enum
StackOp
<
T
>
{
Push
(
T
),
Pop
,
}
impl
<
K
,
V
,
E
,
T
>
Iterator
for
AbsIter
<
T
>
where
T
:
DoubleEndedIterator
<
Item
=
TraversalItem
<
K
,
V
,
E
>>
+
Traverse
<
E
>
,
{
type
Item
=
(
K
,
V
);
// This function is pretty long, but only because there's a lot of cases to consider.
// Our iterator represents two search paths, left and right, to the smallest and largest
// elements we have yet to yield. lca represents the least common ancestor of these two paths,
// above-which we never walk, since everything outside it has already been consumed (or was
// never in the range to iterate).
//
// Note that the design of these iterators permits an *arbitrary* initial pair of min and max,
// making these arbitrary sub-range iterators. However the logic to construct these paths
// efficiently is fairly involved, so this is a FIXME. The sub-range iterators also wouldn't be
// able to accurately predict size, so those iterators can't implement ExactSizeIterator.
// Our iterator represents a queue of all ancestors of elements we have
// yet to yield, from smallest to largest. Note that the design of these
// iterators permits an *arbitrary* initial pair of min and max, making
// these arbitrary sub-range iterators.
fn
next
(
&
mut
self
)
->
Option
<
(
K
,
V
)
>
{
loop
{
// We want the smallest element, so try to get the top of the left stack
let
op
=
match
self
.left
.back_mut
()
{
// The left stack is empty, so try to get the next element of the two paths
// LCAs (the left search path is currently a subpath of the right one)
None
=>
match
self
.lca
.next
()
{
// The lca has been exhausted, walk further down the right path
None
=>
match
self
.right
.pop_front
()
{
// The right path is exhausted, so we're done
None
=>
return
None
,
// The right path had something, make that the new LCA
// and restart the whole process
Some
(
right
)
=>
{
self
.lca
=
right
;
continue
;
}
},
// The lca yielded an edge, make that the new head of the left path
Some
(
Edge
(
next
))
=>
Push
(
Traverse
::
traverse
(
next
)),
// The lca yielded an entry, so yield that
Some
(
Elem
(
k
,
v
))
=>
{
self
.size
-=
1
;
return
Some
((
k
,
v
))
}
},
// The left stack wasn't empty, so continue along the node in its head
// We want the smallest element, so try to get the back of the queue
let
op
=
match
self
.traversals
.back_mut
()
{
None
=>
return
None
,
// The queue wasn't empty, so continue along the node in its head
Some
(
iter
)
=>
match
iter
.next
()
{
// The head
of the left path is empty, so Pop it off and restart
the process
// The head
is empty, so Pop it off and continue
the process
None
=>
Pop
,
// The head of the left path yielded an edge, so make that the new head
// of the left path
// The head yielded an edge, so make that the new head
Some
(
Edge
(
next
))
=>
Push
(
Traverse
::
traverse
(
next
)),
// The head
of the left path yielded
entry, so yield that
Some
(
Elem
(
k
,
v
))
=>
{
// The head
yielded an
entry, so yield that
Some
(
Elem
(
kv
))
=>
{
self
.size
-=
1
;
return
Some
(
(
k
,
v
)
)
return
Some
(
kv
)
}
}
};
// Handle any operation
on the left stack as necessary
// Handle any operation
as necessary, without a conflicting borrow of the queue
match
op
{
Push
(
item
)
=>
{
self
.
left
.push_back
(
item
);
},
Pop
=>
{
self
.
left
.pop_back
();
},
Push
(
item
)
=>
{
self
.
traversals
.push_back
(
item
);
},
Pop
=>
{
self
.
traversals
.pop_back
();
},
}
}
}
...
...
@@ -1005,36 +983,24 @@ impl<K, V, E, T> DoubleEndedIterator for AbsIter<T> where
T
:
DoubleEndedIterator
<
Item
=
TraversalItem
<
K
,
V
,
E
>>
+
Traverse
<
E
>
,
{
// next_back is totally symmetric to next
#[inline]
fn
next_back
(
&
mut
self
)
->
Option
<
(
K
,
V
)
>
{
loop
{
let
op
=
match
self
.right
.back_mut
()
{
None
=>
match
self
.lca
.next_back
()
{
None
=>
match
self
.left
.pop_front
()
{
None
=>
return
None
,
Some
(
left
)
=>
{
self
.lca
=
left
;
continue
;
}
},
Some
(
Edge
(
next
))
=>
Push
(
Traverse
::
traverse
(
next
)),
Some
(
Elem
(
k
,
v
))
=>
{
self
.size
-=
1
;
return
Some
((
k
,
v
))
}
},
let
op
=
match
self
.traversals
.front_mut
()
{
None
=>
return
None
,
Some
(
iter
)
=>
match
iter
.next_back
()
{
None
=>
Pop
,
Some
(
Edge
(
next
))
=>
Push
(
Traverse
::
traverse
(
next
)),
Some
(
Elem
(
k
,
v
))
=>
{
Some
(
Elem
(
kv
))
=>
{
self
.size
-=
1
;
return
Some
(
(
k
,
v
)
)
return
Some
(
kv
)
}
}
};
match
op
{
Push
(
item
)
=>
{
self
.
right
.push_back
(
item
);
},
Pop
=>
{
self
.
right
.pop_back
();
}
Push
(
item
)
=>
{
self
.
traversals
.push_front
(
item
);
},
Pop
=>
{
self
.
traversals
.pop_front
();
}
}
}
}
...
...
@@ -1111,6 +1077,24 @@ fn next_back(&mut self) -> Option<(&'a V)> { self.inner.next_back() }
#[stable]
impl
<
'a
,
K
,
V
>
ExactSizeIterator
for
Values
<
'a
,
K
,
V
>
{}
impl
<
'a
,
K
,
V
>
Iterator
for
Range
<
'a
,
K
,
V
>
{
type
Item
=
(
&
'a
K
,
&
'a
V
);
fn
next
(
&
mut
self
)
->
Option
<
(
&
'a
K
,
&
'a
V
)
>
{
self
.inner
.next
()
}
}
impl
<
'a
,
K
,
V
>
DoubleEndedIterator
for
Range
<
'a
,
K
,
V
>
{
fn
next_back
(
&
mut
self
)
->
Option
<
(
&
'a
K
,
&
'a
V
)
>
{
self
.inner
.next_back
()
}
}
impl
<
'a
,
K
,
V
>
Iterator
for
RangeMut
<
'a
,
K
,
V
>
{
type
Item
=
(
&
'a
K
,
&
'a
mut
V
);
fn
next
(
&
mut
self
)
->
Option
<
(
&
'a
K
,
&
'a
mut
V
)
>
{
self
.inner
.next
()
}
}
impl
<
'a
,
K
,
V
>
DoubleEndedIterator
for
RangeMut
<
'a
,
K
,
V
>
{
fn
next_back
(
&
mut
self
)
->
Option
<
(
&
'a
K
,
&
'a
mut
V
)
>
{
self
.inner
.next_back
()
}
}
impl
<
'a
,
K
:
Ord
,
V
>
Entry
<
'a
,
K
,
V
>
{
#[unstable
=
"matches collection reform v2 specification, waiting for dust to settle"
]
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
...
...
@@ -1188,11 +1172,12 @@ impl<K, V> BTreeMap<K, V> {
#[stable]
pub
fn
iter
(
&
self
)
->
Iter
<
K
,
V
>
{
let
len
=
self
.len
();
// NB. The initial capacity for ringbuf is large enough to avoid reallocs in many cases.
let
mut
lca
=
RingBuf
::
new
();
lca
.push_back
(
Traverse
::
traverse
(
&
self
.root
));
Iter
{
inner
:
AbsIter
{
lca
:
Traverse
::
traverse
(
&
self
.root
),
left
:
RingBuf
::
new
(),
right
:
RingBuf
::
new
(),
traversals
:
lca
,
size
:
len
,
}
}
...
...
@@ -1220,11 +1205,11 @@ pub fn iter(&self) -> Iter<K, V> {
#[stable]
pub
fn
iter_mut
(
&
mut
self
)
->
IterMut
<
K
,
V
>
{
let
len
=
self
.len
();
let
mut
lca
=
RingBuf
::
new
();
lca
.push_back
(
Traverse
::
traverse
(
&
mut
self
.root
));
IterMut
{
inner
:
AbsIter
{
lca
:
Traverse
::
traverse
(
&
mut
self
.root
),
left
:
RingBuf
::
new
(),
right
:
RingBuf
::
new
(),
traversals
:
lca
,
size
:
len
,
}
}
...
...
@@ -1249,11 +1234,11 @@ pub fn iter_mut(&mut self) -> IterMut<K, V> {
#[stable]
pub
fn
into_iter
(
self
)
->
IntoIter
<
K
,
V
>
{
let
len
=
self
.len
();
let
mut
lca
=
RingBuf
::
new
();
lca
.push_back
(
Traverse
::
traverse
(
self
.root
));
IntoIter
{
inner
:
AbsIter
{
lca
:
Traverse
::
traverse
(
self
.root
),
left
:
RingBuf
::
new
(),
right
:
RingBuf
::
new
(),
traversals
:
lca
,
size
:
len
,
}
}
...
...
@@ -1334,7 +1319,189 @@ pub fn len(&self) -> uint { self.length }
pub
fn
is_empty
(
&
self
)
->
bool
{
self
.len
()
==
0
}
}
macro_rules!
range_impl
{
(
$root:expr
,
$min:expr
,
$max:expr
,
$as_slices_internal:ident
,
$iter:ident
,
$Range:ident
,
$edges:ident
,
[
$
(
$mutability:ident
)
*
])
=>
(
{
// A deque that encodes two search paths containing (left-to-right):
// a series of truncated-from-the-left iterators, the LCA's doubly-truncated iterator,
// and a series of truncated-from-the-right iterators.
let
mut
traversals
=
RingBuf
::
new
();
let
(
root
,
min
,
max
)
=
(
$root
,
$min
,
$max
);
let
mut
leftmost
=
None
;
let
mut
rightmost
=
None
;
match
(
&
min
,
&
max
)
{
(
&
Unbounded
,
&
Unbounded
)
=>
{
traversals
.push_back
(
Traverse
::
traverse
(
root
))
}
(
&
Unbounded
,
&
Included
(
_
))
|
(
&
Unbounded
,
&
Excluded
(
_
))
=>
{
rightmost
=
Some
(
root
);
}
(
&
Included
(
_
),
&
Unbounded
)
|
(
&
Excluded
(
_
),
&
Unbounded
)
=>
{
leftmost
=
Some
(
root
);
}
(
&
Included
(
min_key
),
&
Included
(
max_key
))
|
(
&
Included
(
min_key
),
&
Excluded
(
max_key
))
|
(
&
Excluded
(
min_key
),
&
Included
(
max_key
))
|
(
&
Excluded
(
min_key
),
&
Excluded
(
max_key
))
=>
{
// lca represents the Lowest Common Ancestor, above which we never
// walk, since everything else is outside the range to iterate.
// ___________________
// |__0_|_80_|_85_|_90_| (root)
// | | | | |
// |
// v
// ___________________
// |__5_|_15_|_30_|_73_|
// | | | | |
// |
// v
// ___________________
// |_33_|_58_|_63_|_68_| lca for the range [41, 65]
// | |\___|___/| | iterator at traversals[2]
// | |
// | v
// v rightmost
// leftmost
let
mut
is_leaf
=
root
.is_leaf
();
let
mut
lca
=
root
.
$as_slices_internal
();
loop
{
let
slice
=
lca
.slice_from
(
min_key
)
.slice_to
(
max_key
);
if
let
[
ref
$
(
$mutability
)
*
edge
]
=
slice
.edges
{
// Follow the only edge that leads the node that covers the range.
is_leaf
=
edge
.is_leaf
();
lca
=
edge
.
$as_slices_internal
();
}
else
{
let
mut
iter
=
slice
.
$iter
();
if
is_leaf
{
leftmost
=
None
;
rightmost
=
None
;
}
else
{
// Only change the state of nodes with edges.
leftmost
=
iter
.next_edge_item
();
rightmost
=
iter
.next_edge_item_back
();
}
traversals
.push_back
(
iter
);
break
;
}
}
}
}
// Keep narrowing the range by going down.
// ___________________
// |_38_|_43_|_48_|_53_|
// | |____|____|____/ iterator at traversals[1]
// |
// v
// ___________________
// |_39_|_40_|_41_|_42_| (leaf, the last leftmost)
// \_________| iterator at traversals[0]
match
min
{
Included
(
key
)
|
Excluded
(
key
)
=>
while
let
Some
(
left
)
=
leftmost
{
let
is_leaf
=
left
.is_leaf
();
let
mut
iter
=
left
.
$as_slices_internal
()
.slice_from
(
key
)
.
$iter
();
leftmost
=
if
is_leaf
{
None
}
else
{
// Only change the state of nodes with edges.
iter
.next_edge_item
()
};
traversals
.push_back
(
iter
);
},
_
=>
{}
}
// If the leftmost iterator starts with an element, then it was an exact match.
if
let
(
Excluded
(
_
),
Some
(
leftmost_iter
))
=
(
min
,
traversals
.back_mut
())
{
// Drop this excluded element. `next_kv_item` has no effect when
// the next item is an edge.
leftmost_iter
.next_kv_item
();
}
// The code for the right side is similar.
match
max
{
Included
(
key
)
|
Excluded
(
key
)
=>
while
let
Some
(
right
)
=
rightmost
{
let
is_leaf
=
right
.is_leaf
();
let
mut
iter
=
right
.
$as_slices_internal
()
.slice_to
(
key
)
.
$iter
();
rightmost
=
if
is_leaf
{
None
}
else
{
iter
.next_edge_item_back
()
};
traversals
.push_front
(
iter
);
},
_
=>
{}
}
if
let
(
Excluded
(
_
),
Some
(
rightmost_iter
))
=
(
max
,
traversals
.front_mut
())
{
rightmost_iter
.next_kv_item_back
();
}
$Range
{
inner
:
AbsIter
{
traversals
:
traversals
,
size
:
0
,
// unused
}
}
}
)
}
impl
<
K
:
Ord
,
V
>
BTreeMap
<
K
,
V
>
{
/// Constructs a double-ended iterator over a sub-range of elements in the map, starting
/// at min, and ending at max. If min is `Unbounded`, then it will be treated as "negative
/// infinity", and if max is `Unbounded`, then it will be treated as "positive infinity".
/// Thus range(Unbounded, Unbounded) will yield the whole collection.
///
/// # Examples
///
/// ```
/// use std::collections::BTreeMap;
/// use std::collections::Bound::{Included, Unbounded};
///
/// let mut map = BTreeMap::new();
/// map.insert(3u, "a");
/// map.insert(5u, "b");
/// map.insert(8u, "c");
/// for (&key, &value) in map.range(Included(&4), Included(&8)) {
/// println!("{}: {}", key, value);
/// }
/// assert_eq!(Some((&5u, &"b")), map.range(Included(&4), Unbounded).next());
/// ```
#[unstable
=
"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
>
{
range_impl!
(
&
self
.root
,
min
,
max
,
as_slices_internal
,
iter
,
Range
,
edges
,
[])
}
/// Constructs a mutable double-ended iterator over a sub-range of elements in the map, starting
/// at min, and ending at max. If min is `Unbounded`, then it will be treated as "negative
/// infinity", and if max is `Unbounded`, then it will be treated as "positive infinity".
/// Thus range(Unbounded, Unbounded) will yield the whole collection.
///
/// # Examples
///
/// ```
/// use std::collections::BTreeMap;
/// use std::collections::Bound::{Included, Excluded};
///
/// 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")) {
/// *balance += 100;
/// }
/// for (name, balance) in map.iter() {
/// println!("{} => {}", name, balance);
/// }
/// ```
#[unstable
=
"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
>
{
range_impl!
(
&
mut
self
.root
,
min
,
max
,
as_slices_internal_mut
,
iter_mut
,
RangeMut
,
edges_mut
,
[
mut
])
}
/// Gets the given key's corresponding entry in the map for in-place manipulation.
///
/// # Examples
...
...
@@ -1410,8 +1577,10 @@ pub fn entry<'a>(&'a mut self, mut key: K) -> Entry<'a, K, V> {
#[cfg(test)]
mod
test
{
use
prelude
::
*
;
use
std
::
iter
::
range_inclusive
;
use
super
::{
BTreeMap
,
Occupied
,
Vacant
};
use
Bound
::{
self
,
Included
,
Excluded
,
Unbounded
};
#[test]
fn
test_basic_large
()
{
...
...
@@ -1481,75 +1650,121 @@ fn test_iter() {
// Forwards
let
mut
map
:
BTreeMap
<
uint
,
uint
>
=
range
(
0
,
size
)
.map
(|
i
|
(
i
,
i
))
.collect
();
{
let
mut
iter
=
map
.iter
();
fn
test
<
T
>
(
size
:
uint
,
mut
iter
:
T
)
where
T
:
Iterator
<
Item
=
(
uint
,
uint
)
>
{
for
i
in
range
(
0
,
size
)
{
assert_eq!
(
iter
.size_hint
(),
(
size
-
i
,
Some
(
size
-
i
)));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
&
i
,
&
i
));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
i
,
i
));
}
assert_eq!
(
iter
.size_hint
(),
(
0
,
Some
(
0
)));
assert_eq!
(
iter
.next
(),
None
);
}
test
(
size
,
map
.iter
()
.map
(|(
&
k
,
&
v
)|
(
k
,
v
)));
test
(
size
,
map
.iter_mut
()
.map
(|(
&
k
,
&
mut
v
)|
(
k
,
v
)));
test
(
size
,
map
.into_iter
());
}
{
let
mut
iter
=
map
.iter_mut
();
for
i
in
range
(
0
,
size
)
{
assert_eq!
(
iter
.size_hint
(),
(
size
-
i
,
Some
(
size
-
i
)));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
&
i
,
&
mut
(
i
+
0
)));
}
assert_eq!
(
iter
.size_hint
(),
(
0
,
Some
(
0
)));
assert_eq!
(
iter
.next
(),
None
);
}
#[test]
fn
test_iter_rev
()
{
let
size
=
10000u
;
{
let
mut
iter
=
map
.into_iter
();
// Forwards
let
mut
map
:
BTreeMap
<
uint
,
uint
>
=
range
(
0
,
size
)
.map
(|
i
|
(
i
,
i
))
.collect
();
fn
test
<
T
>
(
size
:
uint
,
mut
iter
:
T
)
where
T
:
Iterator
<
Item
=
(
uint
,
uint
)
>
{
for
i
in
range
(
0
,
size
)
{
assert_eq!
(
iter
.size_hint
(),
(
size
-
i
,
Some
(
size
-
i
)));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
i
,
i
));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
size
-
i
-
1
,
size
-
i
-
1
));
}
assert_eq!
(
iter
.size_hint
(),
(
0
,
Some
(
0
)));
assert_eq!
(
iter
.next
(),
None
);
}
test
(
size
,
map
.iter
()
.rev
()
.map
(|(
&
k
,
&
v
)|
(
k
,
v
)));
test
(
size
,
map
.iter_mut
()
.rev
()
.map
(|(
&
k
,
&
mut
v
)|
(
k
,
v
)));
test
(
size
,
map
.into_iter
()
.rev
());
}
#[test]
fn
test_iter_
rev
()
{
fn
test_iter_
mixed
()
{
let
size
=
10000u
;
// Forwards
let
mut
map
:
BTreeMap
<
uint
,
uint
>
=
range
(
0
,
size
)
.map
(|
i
|
(
i
,
i
))
.collect
();
{
let
mut
iter
=
map
.iter
()
.rev
();
for
i
in
range
(
0
,
size
)
{
assert_eq!
(
iter
.size_hint
(),
(
size
-
i
,
Some
(
size
-
i
)));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
&
(
size
-
i
-
1
),
&
(
size
-
i
-
1
)));
fn
test
<
T
>
(
size
:
uint
,
mut
iter
:
T
)
where
T
:
Iterator
<
Item
=
(
uint
,
uint
)
>
+
DoubleEndedIterator
{
for
i
in
range
(
0
,
size
/
4
)
{
assert_eq!
(
iter
.size_hint
(),
(
size
-
i
*
2
,
Some
(
size
-
i
*
2
)));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
i
,
i
));
assert_eq!
(
iter
.next_back
()
.unwrap
(),
(
size
-
i
-
1
,
size
-
i
-
1
));
}
for
i
in
range
(
size
/
4
,
size
*
3
/
4
)
{
assert_eq!
(
iter
.size_hint
(),
(
size
*
3
/
4
-
i
,
Some
(
size
*
3
/
4
-
i
)));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
i
,
i
));
}
assert_eq!
(
iter
.size_hint
(),
(
0
,
Some
(
0
)));
assert_eq!
(
iter
.next
(),
None
);
}
test
(
size
,
map
.iter
()
.map
(|(
&
k
,
&
v
)|
(
k
,
v
)));
test
(
size
,
map
.iter_mut
()
.map
(|(
&
k
,
&
mut
v
)|
(
k
,
v
)));
test
(
size
,
map
.into_iter
());
}
{
let
mut
iter
=
map
.iter_mut
()
.rev
();
for
i
in
range
(
0
,
size
)
{
assert_eq!
(
iter
.size_hint
(),
(
size
-
i
,
Some
(
size
-
i
)));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
&
(
size
-
i
-
1
),
&
mut
(
size
-
i
-
1
)));
}
assert_eq!
(
iter
.size_hint
(),
(
0
,
Some
(
0
)));
assert_eq!
(
iter
.next
(),
None
);
#[test]
fn
test_range_small
()
{
let
size
=
5u
;
// Forwards
let
map
:
BTreeMap
<
uint
,
uint
>
=
range
(
0
,
size
)
.map
(|
i
|
(
i
,
i
))
.collect
();
let
mut
j
=
0u
;
for
((
&
k
,
&
v
),
i
)
in
map
.range
(
Included
(
&
2
),
Unbounded
)
.zip
(
range
(
2u
,
size
))
{
assert_eq!
(
k
,
i
);
assert_eq!
(
v
,
i
);
j
+=
1
;
}
assert_eq!
(
j
,
size
-
2
);
}
{
let
mut
iter
=
map
.into_iter
()
.rev
();
for
i
in
range
(
0
,
size
)
{
assert_eq!
(
iter
.size_hint
(),
(
size
-
i
,
Some
(
size
-
i
)));
assert_eq!
(
iter
.next
()
.unwrap
(),
(
size
-
i
-
1
,
size
-
i
-
1
));
#[test]
fn
test_range_1000
()
{
let
size
=
1000u
;
let
map
:
BTreeMap
<
uint
,
uint
>
=
range
(
0
,
size
)
.map
(|
i
|
(
i
,
i
))
.collect
();
fn
test
(
map
:
&
BTreeMap
<
uint
,
uint
>
,
size
:
uint
,
min
:
Bound
<&
uint
>
,
max
:
Bound
<&
uint
>
)
{
let
mut
kvs
=
map
.range
(
min
,
max
)
.map
(|(
&
k
,
&
v
)|
(
k
,
v
));
let
mut
pairs
=
range
(
0
,
size
)
.map
(|
i
|
(
i
,
i
));
for
(
kv
,
pair
)
in
kvs
.by_ref
()
.zip
(
pairs
.by_ref
())
{
assert_eq!
(
kv
,
pair
);
}
assert_eq!
(
iter
.size_hint
(),
(
0
,
Some
(
0
))
);
assert_eq!
(
iter
.next
(),
None
);
assert_eq!
(
kvs
.next
(),
None
);
assert_eq!
(
pairs
.next
(),
None
);
}
test
(
&
map
,
size
,
Included
(
&
0
),
Excluded
(
&
size
));
test
(
&
map
,
size
,
Unbounded
,
Excluded
(
&
size
));
test
(
&
map
,
size
,
Included
(
&
0
),
Included
(
&
(
size
-
1
)));
test
(
&
map
,
size
,
Unbounded
,
Included
(
&
(
size
-
1
)));
test
(
&
map
,
size
,
Included
(
&
0
),
Unbounded
);
test
(
&
map
,
size
,
Unbounded
,
Unbounded
);
}
#[test]
fn
test_range
()
{
let
size
=
200u
;
let
map
:
BTreeMap
<
uint
,
uint
>
=
range
(
0
,
size
)
.map
(|
i
|
(
i
,
i
))
.collect
();
for
i
in
range
(
0
,
size
)
{
for
j
in
range
(
i
,
size
)
{
let
mut
kvs
=
map
.range
(
Included
(
&
i
),
Included
(
&
j
))
.map
(|(
&
k
,
&
v
)|
(
k
,
v
));
let
mut
pairs
=
range_inclusive
(
i
,
j
)
.map
(|
i
|
(
i
,
i
));
for
(
kv
,
pair
)
in
kvs
.by_ref
()
.zip
(
pairs
.by_ref
())
{
assert_eq!
(
kv
,
pair
);
}
assert_eq!
(
kvs
.next
(),
None
);
assert_eq!
(
pairs
.next
(),
None
);
}
}
}
#[test]
...
...
src/libcollections/btree/node.rs
浏览文件 @
429c23d5
...
...
@@ -77,6 +77,24 @@ pub struct Node<K, V> {
_
capacity
:
uint
,
}
struct
NodeSlice
<
'a
,
K
:
'a
,
V
:
'a
>
{
keys
:
&
'a
[
K
],
vals
:
&
'a
[
V
],
pub
edges
:
&
'a
[
Node
<
K
,
V
>
],
head_is_edge
:
bool
,
tail_is_edge
:
bool
,
has_edges
:
bool
,
}
struct
MutNodeSlice
<
'a
,
K
:
'a
,
V
:
'a
>
{
keys
:
&
'a
[
K
],
vals
:
&
'a
mut
[
V
],
pub
edges
:
&
'a
mut
[
Node
<
K
,
V
>
],
head_is_edge
:
bool
,
tail_is_edge
:
bool
,
has_edges
:
bool
,
}
/// Rounds up to a multiple of a power of two. Returns the closest multiple
/// of `target_alignment` that is higher or equal to `unrounded`.
///
...
...
@@ -342,7 +360,8 @@ pub fn as_slices_mut<'a>(&'a mut self) -> (&'a mut [K], &'a mut [V]) {
}
#[inline]
pub
fn
as_slices_internal
<
'a
>
(
&
'a
self
)
->
(
&
'a
[
K
],
&
'a
[
V
],
&
'a
[
Node
<
K
,
V
>
])
{
pub
fn
as_slices_internal
<
'b
>
(
&
'b
self
)
->
NodeSlice
<
'b
,
K
,
V
>
{
let
is_leaf
=
self
.is_leaf
();
let
(
keys
,
vals
)
=
self
.as_slices
();
let
edges
:
&
[
_
]
=
if
self
.is_leaf
()
{
&
[]
...
...
@@ -354,12 +373,18 @@ pub fn as_slices_internal<'a>(&'a self) -> (&'a [K], &'a [V], &'a [Node<K, V>])
})
}
};
(
keys
,
vals
,
edges
)
NodeSlice
{
keys
:
keys
,
vals
:
vals
,
edges
:
edges
,
head_is_edge
:
true
,
tail_is_edge
:
true
,
has_edges
:
!
is_leaf
,
}
}
#[inline]
pub
fn
as_slices_internal_mut
<
'a
>
(
&
'a
mut
self
)
->
(
&
'a
mut
[
K
],
&
'a
mut
[
V
],
&
'a
mut
[
Node
<
K
,
V
>
])
{
pub
fn
as_slices_internal_mut
<
'b
>
(
&
'b
mut
self
)
->
MutNodeSlice
<
'b
,
K
,
V
>
{
unsafe
{
mem
::
transmute
(
self
.as_slices_internal
())
}
}
...
...
@@ -385,12 +410,12 @@ pub fn vals_mut<'a>(&'a mut self) -> &'a mut [V] {
#[inline]
pub
fn
edges
<
'a
>
(
&
'a
self
)
->
&
'a
[
Node
<
K
,
V
>
]
{
self
.as_slices_internal
()
.
2
self
.as_slices_internal
()
.
edges
}
#[inline]
pub
fn
edges_mut
<
'a
>
(
&
'a
mut
self
)
->
&
'a
mut
[
Node
<
K
,
V
>
]
{
self
.as_slices_internal_mut
()
.
2
self
.as_slices_internal_mut
()
.
edges
}
}
...
...
@@ -522,30 +547,11 @@ pub fn search<Q: ?Sized, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key:
// FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V).
// For the B configured as of this writing (B = 6), binary search was *significantly*
// worse for uints.
let
(
found
,
index
)
=
node
.search_linear
(
key
);
if
found
{
Found
(
Handle
{
node
:
node
,
index
:
index
})
}
else
{
GoDown
(
Handle
{
node
:
node
,
index
:
index
})
match
node
.as_slices_internal
()
.search_linear
(
key
)
{
(
index
,
true
)
=>
Found
(
Handle
{
node
:
node
,
index
:
index
}),
(
index
,
false
)
=>
GoDown
(
Handle
{
node
:
node
,
index
:
index
}),
}
}
fn
search_linear
<
Q
:
?
Sized
>
(
&
self
,
key
:
&
Q
)
->
(
bool
,
uint
)
where
Q
:
BorrowFrom
<
K
>
+
Ord
{
for
(
i
,
k
)
in
self
.keys
()
.iter
()
.enumerate
()
{
match
key
.cmp
(
BorrowFrom
::
borrow_from
(
k
))
{
Greater
=>
{},
Equal
=>
return
(
true
,
i
),
Less
=>
return
(
false
,
i
),
}
}
(
false
,
self
.len
())
}
}
// Public interface
...
...
@@ -1043,31 +1049,11 @@ pub fn kv_handle(&mut self, index: uint) -> Handle<&mut Node<K, V>, handle::KV,
}
pub
fn
iter
<
'a
>
(
&
'a
self
)
->
Traversal
<
'a
,
K
,
V
>
{
let
is_leaf
=
self
.is_leaf
();
let
(
keys
,
vals
,
edges
)
=
self
.as_slices_internal
();
Traversal
{
inner
:
ElemsAndEdges
(
keys
.iter
()
.zip
(
vals
.iter
()),
edges
.iter
()
),
head_is_edge
:
true
,
tail_is_edge
:
true
,
has_edges
:
!
is_leaf
,
}
self
.as_slices_internal
()
.iter
()
}
pub
fn
iter_mut
<
'a
>
(
&
'a
mut
self
)
->
MutTraversal
<
'a
,
K
,
V
>
{
let
is_leaf
=
self
.is_leaf
();
let
(
keys
,
vals
,
edges
)
=
self
.as_slices_internal_mut
();
MutTraversal
{
inner
:
ElemsAndEdges
(
keys
.iter
()
.zip
(
vals
.iter_mut
()),
edges
.iter_mut
()
),
head_is_edge
:
true
,
tail_is_edge
:
true
,
has_edges
:
!
is_leaf
,
}
self
.as_slices_internal_mut
()
.iter_mut
()
}
pub
fn
into_iter
(
self
)
->
MoveTraversal
<
K
,
V
>
{
...
...
@@ -1311,12 +1297,15 @@ fn min_load_from_capacity(cap: uint) -> uint {
/// A trait for pairs of `Iterator`s, one over edges and the other over key/value pairs. This is
/// necessary, as the `MoveTraversalImpl` needs to have a destructor that deallocates the `Node`,
/// and a pair of `Iterator`s would require two independent destructors.
trait
TraversalImpl
<
K
,
V
,
E
>
{
fn
next_kv
(
&
mut
self
)
->
Option
<
(
K
,
V
)
>
;
fn
next_kv_back
(
&
mut
self
)
->
Option
<
(
K
,
V
)
>
;
trait
TraversalImpl
{
type
Item
;
type
Edge
;
fn
next_kv
(
&
mut
self
)
->
Option
<
Self
::
Item
>
;
fn
next_kv_back
(
&
mut
self
)
->
Option
<
Self
::
Item
>
;
fn
next_edge
(
&
mut
self
)
->
Option
<
E
>
;
fn
next_edge_back
(
&
mut
self
)
->
Option
<
E
>
;
fn
next_edge
(
&
mut
self
)
->
Option
<
Self
::
Edge
>
;
fn
next_edge_back
(
&
mut
self
)
->
Option
<
Self
::
Edge
>
;
}
/// A `TraversalImpl` that actually is backed by two iterators. This works in the non-moving case,
...
...
@@ -1324,9 +1313,11 @@ trait TraversalImpl<K, V, E> {
struct
ElemsAndEdges
<
Elems
,
Edges
>
(
Elems
,
Edges
);
impl
<
K
,
V
,
E
,
Elems
:
DoubleEndedIterator
,
Edges
:
DoubleEndedIterator
>
TraversalImpl
<
K
,
V
,
E
>
for
ElemsAndEdges
<
Elems
,
Edges
>
TraversalImpl
for
ElemsAndEdges
<
Elems
,
Edges
>
where
Elems
:
Iterator
<
Item
=
(
K
,
V
)
>
,
Edges
:
Iterator
<
Item
=
E
>
{
type
Item
=
(
K
,
V
);
type
Edge
=
E
;
fn
next_kv
(
&
mut
self
)
->
Option
<
(
K
,
V
)
>
{
self
.0
.next
()
}
fn
next_kv_back
(
&
mut
self
)
->
Option
<
(
K
,
V
)
>
{
self
.0
.next_back
()
}
...
...
@@ -1347,7 +1338,10 @@ struct MoveTraversalImpl<K, V> {
is_leaf
:
bool
}
impl
<
K
,
V
>
TraversalImpl
<
K
,
V
,
Node
<
K
,
V
>>
for
MoveTraversalImpl
<
K
,
V
>
{
impl
<
K
,
V
>
TraversalImpl
for
MoveTraversalImpl
<
K
,
V
>
{
type
Item
=
(
K
,
V
);
type
Edge
=
Node
<
K
,
V
>
;
fn
next_kv
(
&
mut
self
)
->
Option
<
(
K
,
V
)
>
{
match
(
self
.keys
.next
(),
self
.vals
.next
())
{
(
Some
(
k
),
Some
(
v
))
=>
Some
((
k
,
v
)),
...
...
@@ -1398,9 +1392,12 @@ struct AbsTraversal<Impl> {
has_edges
:
bool
,
}
/// A single atomic step in a traversal.
Either an element is visited, or an edge is followed
/// A single atomic step in a traversal.
pub
enum
TraversalItem
<
K
,
V
,
E
>
{
Elem
(
K
,
V
),
/// An element is visited. This isn't written as `Elem(K, V)` just because `opt.map(Elem)`
/// requires the function to take a single argument. (Enum constructors are functions.)
Elem
((
K
,
V
)),
/// An edge is followed.
Edge
(
E
),
}
...
...
@@ -1417,32 +1414,175 @@ pub enum TraversalItem<K, V, E> {
/// An owning traversal over a node's entries and edges
pub
type
MoveTraversal
<
K
,
V
>
=
AbsTraversal
<
MoveTraversalImpl
<
K
,
V
>>
;
#[old_impl_check]
impl
<
K
,
V
,
E
,
Impl
:
TraversalImpl
<
K
,
V
,
E
>>
Iterator
for
AbsTraversal
<
Impl
>
{
impl
<
K
,
V
,
E
,
Impl
>
Iterator
for
AbsTraversal
<
Impl
>
where
Impl
:
TraversalImpl
<
Item
=
(
K
,
V
),
Edge
=
E
>
{
type
Item
=
TraversalItem
<
K
,
V
,
E
>
;
fn
next
(
&
mut
self
)
->
Option
<
TraversalItem
<
K
,
V
,
E
>>
{
let
head_is_edge
=
self
.head_is_edge
;
self
.head_is_edge
=
!
head_is_edge
;
self
.next_edge_item
()
.map
(
Edge
)
.or_else
(||
self
.next_kv_item
()
.map
(
Elem
)
)
}
}
if
head_is_edge
&&
self
.has_edges
{
self
.inner
.next_edge
()
.map
(|
node
|
Edge
(
node
))
impl
<
K
,
V
,
E
,
Impl
>
DoubleEndedIterator
for
AbsTraversal
<
Impl
>
where
Impl
:
TraversalImpl
<
Item
=
(
K
,
V
),
Edge
=
E
>
{
fn
next_back
(
&
mut
self
)
->
Option
<
TraversalItem
<
K
,
V
,
E
>>
{
self
.next_edge_item_back
()
.map
(
Edge
)
.or_else
(||
self
.next_kv_item_back
()
.map
(
Elem
)
)
}
}
impl
<
K
,
V
,
E
,
Impl
>
AbsTraversal
<
Impl
>
where
Impl
:
TraversalImpl
<
Item
=
(
K
,
V
),
Edge
=
E
>
{
/// Advances the iterator and returns the item if it's an edge. Returns None
/// and does nothing if the first item is not an edge.
pub
fn
next_edge_item
(
&
mut
self
)
->
Option
<
E
>
{
// NB. `&& self.has_edges` might be redundant in this condition.
let
edge
=
if
self
.head_is_edge
&&
self
.has_edges
{
self
.inner
.next_edge
()
}
else
{
None
};
self
.head_is_edge
=
false
;
edge
}
/// Advances the iterator and returns the item if it's an edge. Returns None
/// and does nothing if the last item is not an edge.
pub
fn
next_edge_item_back
(
&
mut
self
)
->
Option
<
E
>
{
let
edge
=
if
self
.tail_is_edge
&&
self
.has_edges
{
self
.inner
.next_edge_back
()
}
else
{
None
};
self
.tail_is_edge
=
false
;
edge
}
/// Advances the iterator and returns the item if it's a key-value pair. Returns None
/// and does nothing if the first item is not a key-value pair.
pub
fn
next_kv_item
(
&
mut
self
)
->
Option
<
(
K
,
V
)
>
{
if
!
self
.head_is_edge
{
self
.head_is_edge
=
true
;
self
.inner
.next_kv
()
}
else
{
None
}
}
/// Advances the iterator and returns the item if it's a key-value pair. Returns None
/// and does nothing if the last item is not a key-value pair.
pub
fn
next_kv_item_back
(
&
mut
self
)
->
Option
<
(
K
,
V
)
>
{
if
!
self
.tail_is_edge
{
self
.tail_is_edge
=
true
;
self
.inner
.next_kv_back
()
}
else
{
self
.inner
.next_kv
()
.map
(|(
k
,
v
)|
Elem
(
k
,
v
))
None
}
}
}
#[old_impl_check]
impl
<
K
,
V
,
E
,
Impl
:
TraversalImpl
<
K
,
V
,
E
>>
DoubleEndedIterator
for
AbsTraversal
<
Impl
>
{
fn
next_back
(
&
mut
self
)
->
Option
<
TraversalItem
<
K
,
V
,
E
>>
{
let
tail_is_edge
=
self
.tail_is_edge
;
self
.tail_is_edge
=
!
tail_is_edge
;
macro_rules!
node_slice_impl
{
(
$NodeSlice:ident
,
$Traversal:ident
,
$as_slices_internal:ident
,
$slice_from:ident
,
$slice_to:ident
,
$iter:ident
)
=>
{
impl
<
'a
,
K
:
Ord
+
'a
,
V
:
'a
>
$NodeSlice
<
'a
,
K
,
V
>
{
/// Performs linear search in a slice. Returns a tuple of (index, is_exact_match).
fn
search_linear
<
Q
:
?
Sized
>
(
&
self
,
key
:
&
Q
)
->
(
uint
,
bool
)
where
Q
:
BorrowFrom
<
K
>
+
Ord
{
for
(
i
,
k
)
in
self
.keys
.iter
()
.enumerate
()
{
match
key
.cmp
(
BorrowFrom
::
borrow_from
(
k
))
{
Greater
=>
{},
Equal
=>
return
(
i
,
true
),
Less
=>
return
(
i
,
false
),
}
}
(
self
.keys
.len
(),
false
)
}
if
tail_is_edge
&&
self
.has_edges
{
self
.inner
.next_edge_back
()
.map
(|
node
|
Edge
(
node
))
}
else
{
self
.inner
.next_kv_back
()
.map
(|(
k
,
v
)|
Elem
(
k
,
v
))
/// Returns a sub-slice with elements starting with `min_key`.
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
.
$slice_from
(
pos
)
},
keys
:
self
.keys
.slice_from
(
pos
),
vals
:
self
.vals
.
$slice_from
(
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`.
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
.
$slice_to
(
pos
+
1
)
},
keys
:
self
.keys
.slice_to
(
pos
),
vals
:
self
.vals
.
$slice_to
(
pos
),
head_is_edge
:
self
.head_is_edge
,
tail_is_edge
:
!
pos_is_kv
,
}
}
}
impl
<
'a
,
K
:
'a
,
V
:
'a
>
$NodeSlice
<
'a
,
K
,
V
>
{
/// Returns an iterator over key/value pairs and edges in a slice.
#[inline]
pub
fn
$iter
(
self
)
->
$Traversal
<
'a
,
K
,
V
>
{
let
mut
edges
=
self
.edges
.
$iter
();
// Skip edges at both ends, if excluded.
if
!
self
.head_is_edge
{
edges
.next
();
}
if
!
self
.tail_is_edge
{
edges
.next_back
();
}
// The key iterator is always immutable.
$Traversal
{
inner
:
ElemsAndEdges
(
self
.keys
.iter
()
.zip
(
self
.vals
.
$iter
()),
edges
),
head_is_edge
:
self
.head_is_edge
,
tail_is_edge
:
self
.tail_is_edge
,
has_edges
:
self
.has_edges
,
}
}
}
}
}
node_slice_impl!
(
NodeSlice
,
Traversal
,
as_slices_internal
,
slice_from
,
slice_to
,
iter
);
node_slice_impl!
(
MutNodeSlice
,
MutTraversal
,
as_slices_internal_mut
,
slice_from_mut
,
slice_to_mut
,
iter_mut
);
src/libcollections/btree/set.rs
浏览文件 @
429c23d5
...
...
@@ -25,6 +25,7 @@
use
core
::
ops
::{
BitOr
,
BitAnd
,
BitXor
,
Sub
};
use
btree_map
::{
BTreeMap
,
Keys
};
use
Bound
;
// FIXME(conventions): implement bounded iterators
...
...
@@ -50,6 +51,11 @@ pub struct IntoIter<T> {
iter
:
Map
<
(
T
,
()),
T
,
::
btree_map
::
IntoIter
<
T
,
()
>
,
fn
((
T
,
()))
->
T
>
}
/// An iterator over a sub-range of BTreeSet's items.
pub
struct
Range
<
'a
,
T
:
'a
>
{
iter
:
Map
<
(
&
'a
T
,
&
'a
()),
&
'a
T
,
::
btree_map
::
Range
<
'a
,
T
,
()
>
,
fn
((
&
'a
T
,
&
'a
()))
->
&
'a
T
>
}
/// A lazy iterator producing elements in the set difference (in-order).
#[stable]
pub
struct
Difference
<
'a
,
T
:
'a
>
{
...
...
@@ -145,6 +151,36 @@ fn first<A, B>((a, _): (A, B)) -> A { a }
}
}
impl
<
T
:
Ord
>
BTreeSet
<
T
>
{
/// Constructs a double-ended iterator over a sub-range of elements in the set, starting
/// at min, and ending at max. If min is `Unbounded`, then it will be treated as "negative
/// infinity", and if max is `Unbounded`, then it will be treated as "positive infinity".
/// Thus range(Unbounded, Unbounded) will yield the whole collection.
///
/// # Examples
///
/// ```
/// use std::collections::BTreeSet;
/// use std::collections::Bound::{Included, Unbounded};
///
/// let mut set = BTreeSet::new();
/// set.insert(3u);
/// set.insert(5u);
/// set.insert(8u);
/// for &elem in set.range(Included(&4), Included(&8)) {
/// println!("{}", elem);
/// }
/// assert_eq!(Some(&5u), set.range(Included(&4), Unbounded).next());
/// ```
#[unstable
=
"matches collection reform specification, waiting for dust to settle"
]
pub
fn
range
<
'a
>
(
&
'a
self
,
min
:
Bound
<&
T
>
,
max
:
Bound
<&
T
>
)
->
Range
<
'a
,
T
>
{
fn
first
<
A
,
B
>
((
a
,
_
):
(
A
,
B
))
->
A
{
a
}
let
first
:
fn
((
&
'a
T
,
&
'a
()))
->
&
'a
T
=
first
;
// coerce to fn pointer
Range
{
iter
:
self
.map
.range
(
min
,
max
)
.map
(
first
)
}
}
}
impl
<
T
:
Ord
>
BTreeSet
<
T
>
{
/// Visits the values representing the difference, in ascending order.
///
...
...
@@ -598,6 +634,16 @@ fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
#[stable]
impl
<
T
>
ExactSizeIterator
for
IntoIter
<
T
>
{}
impl
<
'a
,
T
>
Iterator
for
Range
<
'a
,
T
>
{
type
Item
=
&
'a
T
;
fn
next
(
&
mut
self
)
->
Option
<&
'a
T
>
{
self
.iter
.next
()
}
}
impl
<
'a
,
T
>
DoubleEndedIterator
for
Range
<
'a
,
T
>
{
fn
next_back
(
&
mut
self
)
->
Option
<&
'a
T
>
{
self
.iter
.next_back
()
}
}
/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
fn
cmp_opt
<
T
:
Ord
>
(
x
:
Option
<&
T
>
,
y
:
Option
<&
T
>
,
short
:
Ordering
,
long
:
Ordering
)
->
Ordering
{
...
...
src/libcollections/lib.rs
浏览文件 @
429c23d5
...
...
@@ -26,7 +26,6 @@
#![feature(unsafe_destructor,
slicing_syntax)]
#![feature(box_syntax)]
#![feature(unboxed_closures)]
#![feature(old_impl_check)]
#![allow(unknown_features)]
#![feature(int_uint)]
#![allow(unstable)]
#![no_std]
...
...
@@ -142,3 +141,13 @@ mod prelude {
pub
use
string
::{
String
,
ToString
};
pub
use
vec
::
Vec
;
}
/// An endpoint of a range of keys.
pub
enum
Bound
<
T
>
{
/// An inclusive bound.
Included
(
T
),
/// An exclusive bound.
Excluded
(
T
),
/// An infinite endpoint. Indicates that there is no bound in this direction.
Unbounded
,
}
src/libstd/collections/mod.rs
浏览文件 @
429c23d5
...
...
@@ -311,6 +311,7 @@
#![stable]
pub
use
core_collections
::
Bound
;
pub
use
core_collections
::{
BinaryHeap
,
Bitv
,
BitvSet
,
BTreeMap
,
BTreeSet
};
pub
use
core_collections
::{
DList
,
RingBuf
,
VecMap
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录