Skip to content

Commit 0d87259

Browse files
author
blake2-ppc
committed
---
yaml --- r: 64210 b: refs/heads/snap-stage3 c: 7b1c577 h: refs/heads/master v: v3
1 parent 1f77e09 commit 0d87259

File tree

2 files changed

+74
-63
lines changed

2 files changed

+74
-63
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: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: f97e64083b10e06286eb621f9dff918362e03fc1
4+
refs/heads/snap-stage3: 7b1c57713d331266d632c4fa11d4cdfaaa895ac7
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libextra/dlist.rs

Lines changed: 73 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,23 @@
1313

1414
use std::cast;
1515
use std::cmp;
16+
use std::ptr;
1617
use std::util;
1718
use std::iterator::FromIterator;
1819

1920
/// A doubly-linked list
2021
pub struct List<T> {
2122
priv length: uint,
2223
priv list_head: Link<T>,
23-
priv list_tail: Rawlink<T>,
24+
priv list_tail: Rawlink<Node<T>>,
2425
}
2526

2627
type Link<T> = Option<~Node<T>>;
27-
type Rawlink<T> = Option<&'static Node<T>>;
28-
// Rawlink uses &'static to have a small Option<&'> represenation.
29-
// FIXME: Use a raw pointer like *mut Node if possible.
30-
// FIXME: Causes infinite recursion in %? repr
28+
struct Rawlink<T> { priv p: *mut T }
3129

3230
struct Node<T> {
3331
priv next: Link<T>,
34-
priv prev: Rawlink<T>,
32+
priv prev: Rawlink<Node<T>>,
3533
priv value: T,
3634
}
3735

@@ -45,21 +43,21 @@ pub struct ForwardIterator<'self, T> {
4543
/// List reverse iterator
4644
pub struct ReverseIterator<'self, T> {
4745
priv list: &'self List<T>,
48-
priv next: Rawlink<T>,
46+
priv next: Rawlink<Node<T>>,
4947
priv nelem: uint,
5048
}
5149

5250
/// List mutable iterator
5351
pub struct MutForwardIterator<'self, T> {
5452
priv list: &'self mut List<T>,
55-
priv curs: Rawlink<T>,
53+
priv curs: Rawlink<Node<T>>,
5654
priv nelem: uint,
5755
}
5856

5957
/// List mutable reverse iterator
6058
pub struct MutReverseIterator<'self, T> {
6159
priv list: &'self mut List<T>,
62-
priv next: Rawlink<T>,
60+
priv next: Rawlink<Node<T>>,
6361
priv nelem: uint,
6462
}
6563

@@ -73,6 +71,33 @@ pub struct ConsumeRevIterator<T> {
7371
priv list: List<T>
7472
}
7573

74+
/// Rawlink is a type like Option<T> but for holding a raw pointer
75+
impl<T> Rawlink<T> {
76+
/// Like Option::None for Rawlink
77+
fn none() -> Rawlink<T> {
78+
Rawlink{p: ptr::mut_null()}
79+
}
80+
81+
/// Like Option::Some for Rawlink
82+
fn some(n: &mut T) -> Rawlink<T> {
83+
Rawlink{p: ptr::to_mut_unsafe_ptr(n)}
84+
}
85+
86+
/// Convert the `Rawlink` into an Option value
87+
fn resolve_immut(&self) -> Option<&T> {
88+
unsafe { self.p.to_option() }
89+
}
90+
91+
/// Convert the `Rawlink` into an Option value
92+
fn resolve(&mut self) -> Option<&mut T> {
93+
if self.p.is_null() {
94+
None
95+
} else {
96+
Some(unsafe { cast::transmute(self.p) })
97+
}
98+
}
99+
}
100+
76101
impl<T> Container for List<T> {
77102
/// O(1)
78103
fn is_empty(&self) -> bool {
@@ -93,19 +118,11 @@ impl<T> Mutable for List<T> {
93118
}
94119
}
95120

96-
/// Cast the raw link into a borrowed ref
97-
fn resolve_rawlink<T>(lnk: &'static Node<T>) -> &mut Node<T> {
98-
unsafe { cast::transmute_mut(lnk) }
99-
}
100-
fn rawlink<T>(n: &mut Node<T>) -> Rawlink<T> {
101-
Some(unsafe { cast::transmute(n) })
102-
}
103-
104121
impl<T> List<T> {
105122
/// Create an empty List
106123
#[inline]
107124
pub fn new() -> List<T> {
108-
List{list_head: None, list_tail: None, length: 0}
125+
List{list_head: None, list_tail: Rawlink::none(), length: 0}
109126
}
110127

111128
/// Provide a reference to the front element, or None if the list is empty
@@ -123,30 +140,29 @@ impl<T> List<T> {
123140

124141
/// Provide a reference to the back element, or None if the list is empty
125142
pub fn peek_back<'a>(&'a self) -> Option<&'a T> {
126-
match self.list_tail {
143+
match self.list_tail.resolve_immut() {
127144
None => None,
128-
Some(tail) => Some(&resolve_rawlink(tail).value),
145+
Some(tail) => Some(&tail.value),
129146
}
130147
}
131148

132149
/// Provide a mutable reference to the back element, or None if the list is empty
133150
pub fn peek_back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
134-
match self.list_tail {
151+
match self.list_tail.resolve() {
135152
None => None,
136-
Some(tail) => Some(&mut resolve_rawlink(tail).value),
153+
Some(tail) => Some(&mut tail.value),
137154
}
138155
}
139156

140157
/// Add an element last in the list
141158
///
142159
/// O(1)
143160
pub fn push_back(&mut self, elt: T) {
144-
match self.list_tail {
161+
match self.list_tail.resolve() {
145162
None => return self.push_front(elt),
146-
Some(rtail) => {
163+
Some(tail) => {
147164
let mut new_tail = ~Node{value: elt, next: None, prev: self.list_tail};
148-
self.list_tail = rawlink(new_tail);
149-
let tail = resolve_rawlink(rtail);
165+
self.list_tail = Rawlink::some(new_tail);
150166
tail.next = Some(new_tail);
151167
}
152168
}
@@ -158,19 +174,18 @@ impl<T> List<T> {
158174
/// O(1)
159175
#[inline]
160176
pub fn pop_back(&mut self) -> Option<T> {
161-
match self.list_tail {
177+
match self.list_tail.resolve() {
162178
None => None,
163-
Some(rtail) => {
179+
Some(tail) => {
164180
self.length -= 1;
165-
let tail = resolve_rawlink(rtail);
166-
let tail_own = match tail.prev {
181+
let tail_own = match tail.prev.resolve() {
167182
None => {
168-
self.list_tail = None;
183+
self.list_tail = Rawlink::none();
169184
self.list_head.swap_unwrap()
170185
},
171-
Some(rtail_prev) => {
186+
Some(tail_prev) => {
172187
self.list_tail = tail.prev;
173-
resolve_rawlink(rtail_prev).next.swap_unwrap()
188+
tail_prev.next.swap_unwrap()
174189
}
175190
};
176191
Some(tail_own.value)
@@ -182,14 +197,14 @@ impl<T> List<T> {
182197
///
183198
/// O(1)
184199
pub fn push_front(&mut self, elt: T) {
185-
let mut new_head = ~Node{value: elt, next: None, prev: None};
200+
let mut new_head = ~Node{value: elt, next: None, prev: Rawlink::none()};
186201
match self.list_head {
187202
None => {
188-
self.list_tail = rawlink(new_head);
203+
self.list_tail = Rawlink::some(new_head);
189204
self.list_head = Some(new_head);
190205
}
191206
Some(ref mut head) => {
192-
head.prev = rawlink(new_head);
207+
head.prev = Rawlink::some(new_head);
193208
util::swap(head, &mut new_head);
194209
head.next = Some(new_head);
195210
}
@@ -208,12 +223,12 @@ impl<T> List<T> {
208223
match *head.swap_unwrap() {
209224
Node{value: value, next: Some(next), prev: _} => {
210225
let mut mnext = next;
211-
mnext.prev = None;
226+
mnext.prev = Rawlink::none();
212227
*head = Some(mnext);
213228
Some(value)
214229
}
215230
Node{value: value, next: None, prev: _} => {
216-
self.list_tail = None;
231+
self.list_tail = Rawlink::none();
217232
*head = None;
218233
Some(value)
219234
}
@@ -226,14 +241,13 @@ impl<T> List<T> {
226241
///
227242
/// O(1)
228243
pub fn append(&mut self, other: List<T>) {
229-
match self.list_tail {
244+
match self.list_tail.resolve() {
230245
None => *self = other,
231-
Some(rtail) => {
246+
Some(tail) => {
232247
match other {
233248
List{list_head: None, list_tail: _, length: _} => return,
234249
List{list_head: Some(node), list_tail: o_tail, length: o_length} => {
235250
let mut lnk_node = node;
236-
let tail = resolve_rawlink(rtail);
237251
lnk_node.prev = self.list_tail;
238252
tail.next = Some(lnk_node);
239253
self.list_tail = o_tail;
@@ -301,7 +315,7 @@ impl<T> List<T> {
301315

302316
/// Provide a forward iterator with mutable references
303317
pub fn mut_iter<'a>(&'a mut self) -> MutForwardIterator<'a, T> {
304-
MutForwardIterator{nelem: self.len(), list: self, curs: None}
318+
MutForwardIterator{nelem: self.len(), list: self, curs: Rawlink::none()}
305319
}
306320

307321
/// Provide a reverse iterator with mutable references
@@ -353,23 +367,23 @@ impl<'self, A> Iterator<&'self A> for ForwardIterator<'self, A> {
353367
impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
354368
#[inline]
355369
fn next(&mut self) -> Option<&'self mut A> {
356-
match self.curs {
370+
match self.curs.resolve() {
357371
None => {
358372
match self.list.list_head {
359373
None => None,
360374
Some(ref mut head) => {
361375
self.nelem -= 1;
362-
self.curs = rawlink(&mut **head);
376+
self.curs = Rawlink::some(*head);
363377
Some(&mut head.value)
364378
}
365379
}
366380
}
367-
Some(rcurs) => {
368-
match resolve_rawlink(rcurs).next {
381+
Some(curs) => {
382+
match curs.next {
369383
None => None,
370384
Some(ref mut head) => {
371385
self.nelem -= 1;
372-
self.curs = rawlink(&mut **head);
386+
self.curs = Rawlink::some(*head);
373387
Some(&mut head.value)
374388
}
375389
}
@@ -385,11 +399,10 @@ impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
385399
impl<'self, A> Iterator<&'self A> for ReverseIterator<'self, A> {
386400
#[inline]
387401
fn next(&mut self) -> Option<&'self A> {
388-
match self.next {
402+
match self.next.resolve() {
389403
None => None,
390-
Some(rnext) => {
404+
Some(prev) => {
391405
self.nelem -= 1;
392-
let prev = resolve_rawlink(rnext);
393406
self.next = prev.prev;
394407
Some(&prev.value)
395408
}
@@ -404,11 +417,10 @@ impl<'self, A> Iterator<&'self A> for ReverseIterator<'self, A> {
404417
impl<'self, A> Iterator<&'self mut A> for MutReverseIterator<'self, A> {
405418
#[inline]
406419
fn next(&mut self) -> Option<&'self mut A> {
407-
match self.next {
420+
match self.next.resolve() {
408421
None => None,
409-
Some(rnext) => {
422+
Some(prev) => {
410423
self.nelem -= 1;
411-
let prev = resolve_rawlink(rnext);
412424
self.next = prev.prev;
413425
Some(&mut prev.value)
414426
}
@@ -428,19 +440,18 @@ trait ListInsertCursor<A> {
428440

429441
impl<'self, A> ListInsertCursor<A> for MutForwardIterator<'self, A> {
430442
fn insert_before(&mut self, elt: A) {
431-
match self.curs {
443+
match self.curs.resolve() {
432444
None => self.list.push_front(elt),
433-
Some(rcurs) => {
434-
let node = resolve_rawlink(rcurs);
435-
let prev_node = match node.prev {
445+
Some(node) => {
446+
let prev_node = match node.prev.resolve() {
436447
None => return self.list.push_front(elt), // at head
437-
Some(rprev) => resolve_rawlink(rprev),
448+
Some(prev) => prev,
438449
};
439450
let mut node_own = prev_node.next.swap_unwrap();
440451
let mut ins_node = ~Node{value: elt,
441452
next: None,
442-
prev: rawlink(prev_node)};
443-
node_own.prev = rawlink(ins_node);
453+
prev: Rawlink::some(prev_node)};
454+
node_own.prev = Rawlink::some(ins_node);
444455
ins_node.next = Some(node_own);
445456
prev_node.next = Some(ins_node);
446457
self.list.length += 1;
@@ -497,11 +508,11 @@ fn check_links<T>(list: &List<T>) {
497508
Some(ref node) => node_ptr = &**node,
498509
}
499510
loop {
500-
match (last_ptr, node_ptr.prev) {
511+
match (last_ptr, node_ptr.prev.resolve_immut()) {
501512
(None , None ) => {}
502513
(None , _ ) => fail!("prev link for list_head"),
503514
(Some(p), Some(pptr)) => {
504-
assert_eq!((p as *Node<T>) as uint, pptr as *Node<T> as uint);
515+
assert_eq!(p as *Node<T>, pptr as *Node<T>);
505516
}
506517
_ => fail!("prev link is none, not good"),
507518
}

0 commit comments

Comments
 (0)