From b47e1e9eda303e42896821cbc8d9bbc127890abb Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 17:55:55 -0500 Subject: [PATCH 01/10] modernize std::deque * use a proper exported data type with private fields * implement core::container::Container * use the current constructor convention * use explicit self * get rid of DVec and the mutable fields Closes #2343 --- src/libstd/deque.rs | 247 +++++++++++++++----------------- src/test/bench/graph500-bfs.rs | 11 +- src/test/run-pass/issue-2383.rs | 5 +- 3 files changed, 119 insertions(+), 144 deletions(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 6d01a441843..86b904be3cb 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,145 +8,122 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! A deque. Untested as of yet. Likely buggy -#[forbid(non_camel_case_types)]; - +use core::container::{Container, Mutable}; use core::cmp::Eq; -use core::dvec::DVec; -use core::dvec; use core::prelude::*; use core::uint; use core::vec; -pub trait Deque { - fn size() -> uint; - fn add_front(v: T); - fn add_back(v: T); - fn pop_front() -> T; - fn pop_back() -> T; - fn peek_front() -> T; - fn peek_back() -> T; - fn get(int) -> T; +const initial_capacity: uint = 32u; // 2^5 + +pub struct Deque { + priv nelts: uint, + priv lo: uint, + priv hi: uint, + priv elts: ~[Option] } -// FIXME (#2343) eventually, a proper datatype plus an exported impl would -// be preferrable. -pub fn create() -> Deque { - type Cell = Option; +impl Container for Deque { + pure fn len(&self) -> uint { self.nelts } + pure fn is_empty(&self) -> bool { self.len() == 0 } +} - let initial_capacity: uint = 32u; // 2^5 - /** - * Grow is only called on full elts, so nelts is also len(elts), unlike - * elsewhere. - */ - fn grow(nelts: uint, lo: uint, elts: ~[Cell]) - -> ~[Cell] { - let mut elts = elts; - assert (nelts == vec::len(elts)); - let mut rv = ~[]; - - let mut i = 0u; - let nalloc = uint::next_power_of_two(nelts + 1u); - while i < nalloc { - if i < nelts { - rv.push(elts[(lo + i) % nelts]); - } else { rv.push(None); } - i += 1u; - } - - rv - } - fn get(elts: &DVec>, i: uint) -> T { - match (*elts).get_elt(i) { Some(t) => t, _ => fail!() } +impl Deque { + static pure fn new() -> Deque { + Deque{nelts: 0, lo: 0, hi: 0, + elts: vec::from_fn(initial_capacity, |_| None)} } - struct Repr { - mut nelts: uint, - mut lo: uint, - mut hi: uint, - elts: DVec>, + fn add_front(&mut self, t: T) { + let oldlo: uint = self.lo; + if self.lo == 0u { + self.lo = self.elts.len() - 1u; + } else { self.lo -= 1u; } + if self.lo == self.hi { + self.elts = grow(self.nelts, oldlo, self.elts); + self.lo = self.elts.len() - 1u; + self.hi = self.nelts; + } + self.elts[self.lo] = Some(t); + self.nelts += 1u; } - impl Deque for Repr { - fn size() -> uint { return self.nelts; } - fn add_front(t: T) { - let oldlo: uint = self.lo; - if self.lo == 0u { - self.lo = self.elts.len() - 1u; - } else { self.lo -= 1u; } - if self.lo == self.hi { - self.elts.swap(|v| grow(self.nelts, oldlo, v)); - self.lo = self.elts.len() - 1u; - self.hi = self.nelts; - } - self.elts.set_elt(self.lo, Some(t)); - self.nelts += 1u; - } - fn add_back(t: T) { - if self.lo == self.hi && self.nelts != 0u { - self.elts.swap(|v| grow(self.nelts, self.lo, v)); - self.lo = 0u; - self.hi = self.nelts; - } - self.elts.set_elt(self.hi, Some(t)); - self.hi = (self.hi + 1u) % self.elts.len(); - self.nelts += 1u; - } - /** - * We actually release (turn to none()) the T we're popping so - * that we don't keep anyone's refcount up unexpectedly. - */ - fn pop_front() -> T { - let t: T = get(&self.elts, self.lo); - self.elts.set_elt(self.lo, None); - self.lo = (self.lo + 1u) % self.elts.len(); - self.nelts -= 1u; - return t; - } - fn pop_back() -> T { - if self.hi == 0u { - self.hi = self.elts.len() - 1u; - } else { self.hi -= 1u; } - let t: T = get(&self.elts, self.hi); - self.elts.set_elt(self.hi, None); - self.nelts -= 1u; - return t; - } - fn peek_front() -> T { return get(&self.elts, self.lo); } - fn peek_back() -> T { return get(&self.elts, self.hi - 1u); } - fn get(i: int) -> T { - let idx = (self.lo + (i as uint)) % self.elts.len(); - return get(&self.elts, idx); + fn add_back(&mut self, t: T) { + if self.lo == self.hi && self.nelts != 0u { + self.elts = grow(self.nelts, self.lo, self.elts); + self.lo = 0u; + self.hi = self.nelts; } + self.elts[self.hi] = Some(t); + self.hi = (self.hi + 1u) % self.elts.len(); + self.nelts += 1u; } - let repr: Repr = Repr { - nelts: 0u, - lo: 0u, - hi: 0u, - elts: dvec::from_vec(vec::from_elem(initial_capacity, None)), - }; + fn pop_front(&mut self) -> T { + let t: T = get(self.elts, self.lo); + self.elts[self.lo] = None; + self.lo = (self.lo + 1u) % self.elts.len(); + self.nelts -= 1u; + return t; + } - repr as Deque:: + fn pop_back(&mut self) -> T { + if self.hi == 0u { + self.hi = self.elts.len() - 1u; + } else { self.hi -= 1u; } + let t: T = get(self.elts, self.hi); + self.elts[self.hi] = None; + self.nelts -= 1u; + return t; + } + + fn peek_front(&self) -> T { return get(self.elts, self.lo); } + + fn peek_back(&self) -> T { return get(self.elts, self.hi - 1u); } + + fn get(&self, i: int) -> T { + let idx = (self.lo + (i as uint)) % self.elts.len(); + return get(self.elts, idx); + } +} + +/// Grow is only called on full elts, so nelts is also len(elts), unlike +/// elsewhere. +fn grow(nelts: uint, lo: uint, elts: &[Option]) -> ~[Option] { + assert nelts == elts.len(); + let mut rv = ~[]; + + let mut i = 0u; + let nalloc = uint::next_power_of_two(nelts + 1u); + while i < nalloc { + if i < nelts { + rv.push(elts[(lo + i) % nelts]); + } else { rv.push(None); } + i += 1u; + } + + rv +} + +fn get(elts: &[Option], i: uint) -> T { + match elts[i] { Some(t) => t, _ => fail!() } } #[cfg(test)] mod tests { use core::prelude::*; - - use deque::*; - use deque; + use super::*; #[test] fn test_simple() { - let d: deque::Deque = deque::create::(); - assert (d.size() == 0u); + let mut d = Deque::new(); + assert (d.len() == 0u); d.add_front(17); d.add_front(42); d.add_back(137); - assert (d.size() == 3u); + assert (d.len() == 3u); d.add_back(137); - assert (d.size() == 4u); + assert (d.len() == 4u); log(debug, d.peek_front()); assert (d.peek_front() == 42); log(debug, d.peek_back()); @@ -163,15 +140,15 @@ mod tests { i = d.pop_back(); log(debug, i); assert (i == 17); - assert (d.size() == 0u); + assert (d.len() == 0u); d.add_back(3); - assert (d.size() == 1u); + assert (d.len() == 1u); d.add_front(2); - assert (d.size() == 2u); + assert (d.len() == 2u); d.add_back(4); - assert (d.size() == 3u); + assert (d.len() == 3u); d.add_front(1); - assert (d.size() == 4u); + assert (d.len() == 4u); log(debug, d.get(0)); log(debug, d.get(1)); log(debug, d.get(2)); @@ -189,29 +166,29 @@ mod tests { let c: @int = @64; let d: @int = @175; - let deq: deque::Deque<@int> = deque::create::<@int>(); - assert (deq.size() == 0u); + let mut deq = Deque::new(); + assert (deq.len() == 0u); deq.add_front(a); deq.add_front(b); deq.add_back(c); - assert (deq.size() == 3u); + assert (deq.len() == 3u); deq.add_back(d); - assert (deq.size() == 4u); + assert (deq.len() == 4u); assert (deq.peek_front() == b); assert (deq.peek_back() == d); assert (deq.pop_front() == b); assert (deq.pop_back() == d); assert (deq.pop_back() == c); assert (deq.pop_back() == a); - assert (deq.size() == 0u); + assert (deq.len() == 0u); deq.add_back(c); - assert (deq.size() == 1u); + assert (deq.len() == 1u); deq.add_front(b); - assert (deq.size() == 2u); + assert (deq.len() == 2u); deq.add_back(d); - assert (deq.size() == 3u); + assert (deq.len() == 3u); deq.add_front(a); - assert (deq.size() == 4u); + assert (deq.len() == 4u); assert (deq.get(0) == a); assert (deq.get(1) == b); assert (deq.get(2) == c); @@ -219,29 +196,29 @@ mod tests { } fn test_parameterized(a: T, b: T, c: T, d: T) { - let deq: deque::Deque = deque::create::(); - assert (deq.size() == 0u); + let mut deq = Deque::new(); + assert (deq.len() == 0u); deq.add_front(a); deq.add_front(b); deq.add_back(c); - assert (deq.size() == 3u); + assert (deq.len() == 3u); deq.add_back(d); - assert (deq.size() == 4u); + assert (deq.len() == 4u); assert deq.peek_front() == b; assert deq.peek_back() == d; assert deq.pop_front() == b; assert deq.pop_back() == d; assert deq.pop_back() == c; assert deq.pop_back() == a; - assert (deq.size() == 0u); + assert (deq.len() == 0u); deq.add_back(c); - assert (deq.size() == 1u); + assert (deq.len() == 1u); deq.add_front(b); - assert (deq.size() == 2u); + assert (deq.len() == 2u); deq.add_back(d); - assert (deq.size() == 3u); + assert (deq.len() == 3u); deq.add_front(a); - assert (deq.size() == 4u); + assert (deq.len() == 4u); assert deq.get(0) == a; assert deq.get(1) == b; assert deq.get(2) == c; diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index 5910ade013e..f1d5749e840 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -23,7 +23,6 @@ use std::time; use std::oldmap; use std::oldmap::Map; use std::oldmap::HashMap; -use std::deque; use std::deque::Deque; use std::par; use core::io::WriterUtil; @@ -124,18 +123,18 @@ fn bfs(graph: graph, key: node_id) -> bfs_result { let mut marks : ~[node_id] = vec::from_elem(vec::len(graph), -1i64); - let Q = deque::create(); + let mut q = Deque::new(); - Q.add_back(key); + q.add_back(key); marks[key] = key; - while Q.size() > 0 { - let t = Q.pop_front(); + while !q.is_empty() { + let t = q.pop_front(); do graph[t].each() |k| { if marks[*k] == -1i64 { marks[*k] = t; - Q.add_back(*k); + q.add_back(*k); } true }; diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs index e45d9d60555..a7afa1d6f34 100644 --- a/src/test/run-pass/issue-2383.rs +++ b/src/test/run-pass/issue-2383.rs @@ -11,10 +11,9 @@ // except according to those terms. extern mod std; -use std::deque; use std::deque::Deque; pub fn main() { - let Q = deque::create(); - Q.add_back(10); + let mut q = Deque::new(); + q.add_back(10); } From ed7c9c4e2a248c33f12c4a14d23dfe1b347a6310 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 18:55:25 -0500 Subject: [PATCH 02/10] add a Mutable implementation (clear) to std::deque --- src/libstd/deque.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 86b904be3cb..d8fca5c8532 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -28,6 +28,15 @@ impl Container for Deque { pure fn is_empty(&self) -> bool { self.len() == 0 } } +impl Mutable for Deque { + fn clear(&mut self) { + for vec::each_mut(self.elts) |x| { *x = None } + self.nelts = 0; + self.lo = 0; + self.hi = 0; + } +} + impl Deque { static pure fn new() -> Deque { Deque{nelts: 0, lo: 0, hi: 0, From 15879d3f74411093ecea3481a2664fa11c6f01b4 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 18:57:45 -0500 Subject: [PATCH 03/10] deque: rm old return statements --- src/libstd/deque.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index d8fca5c8532..d5d2985a031 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -73,7 +73,7 @@ impl Deque { self.elts[self.lo] = None; self.lo = (self.lo + 1u) % self.elts.len(); self.nelts -= 1u; - return t; + t } fn pop_back(&mut self) -> T { @@ -83,16 +83,16 @@ impl Deque { let t: T = get(self.elts, self.hi); self.elts[self.hi] = None; self.nelts -= 1u; - return t; + t } - fn peek_front(&self) -> T { return get(self.elts, self.lo); } + fn peek_front(&self) -> T { get(self.elts, self.lo) } - fn peek_back(&self) -> T { return get(self.elts, self.hi - 1u); } + fn peek_back(&self) -> T { get(self.elts, self.hi - 1u) } fn get(&self, i: int) -> T { let idx = (self.lo + (i as uint)) % self.elts.len(); - return get(self.elts, idx); + get(self.elts, idx) } } From 5832fe968f08435be86cf6b900ac792445f3100d Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 19:00:51 -0500 Subject: [PATCH 04/10] deque: separate the methods that need Copy --- src/libstd/deque.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index d5d2985a031..7ad93f58050 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -37,12 +37,14 @@ impl Mutable for Deque { } } -impl Deque { +impl Deque { static pure fn new() -> Deque { Deque{nelts: 0, lo: 0, hi: 0, elts: vec::from_fn(initial_capacity, |_| None)} } +} +impl Deque { fn add_front(&mut self, t: T) { let oldlo: uint = self.lo; if self.lo == 0u { From 5929f159999b1d9712b8c1dd9fe92ce28c64a741 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 19:03:27 -0500 Subject: [PATCH 05/10] deque: avoid Copy in the get function --- src/libstd/deque.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 7ad93f58050..9f512d2b776 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -71,7 +71,7 @@ impl Deque { } fn pop_front(&mut self) -> T { - let t: T = get(self.elts, self.lo); + let t = { *get(self.elts, self.lo) }; self.elts[self.lo] = None; self.lo = (self.lo + 1u) % self.elts.len(); self.nelts -= 1u; @@ -82,19 +82,19 @@ impl Deque { if self.hi == 0u { self.hi = self.elts.len() - 1u; } else { self.hi -= 1u; } - let t: T = get(self.elts, self.hi); + let t = { *get(self.elts, self.hi) }; self.elts[self.hi] = None; self.nelts -= 1u; t } - fn peek_front(&self) -> T { get(self.elts, self.lo) } + fn peek_front(&self) -> T { *get(self.elts, self.lo) } - fn peek_back(&self) -> T { get(self.elts, self.hi - 1u) } + fn peek_back(&self) -> T { *get(self.elts, self.hi - 1u) } fn get(&self, i: int) -> T { let idx = (self.lo + (i as uint)) % self.elts.len(); - get(self.elts, idx) + *get(self.elts, idx) } } @@ -116,8 +116,8 @@ fn grow(nelts: uint, lo: uint, elts: &[Option]) -> ~[Option] { rv } -fn get(elts: &[Option], i: uint) -> T { - match elts[i] { Some(t) => t, _ => fail!() } +fn get(elts: &r/[Option], i: uint) -> &r/T { + match elts[i] { Some(ref t) => t, _ => fail!() } } #[cfg(test)] From 373c072e838dd663b2b164bcb6585d3c2bef0357 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 19:10:10 -0500 Subject: [PATCH 06/10] deque: avoid Copy in peek_{front,back} --- src/libstd/deque.rs | 126 ++++++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 64 deletions(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 9f512d2b776..b548623ba7c 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -42,11 +42,14 @@ impl Deque { Deque{nelts: 0, lo: 0, hi: 0, elts: vec::from_fn(initial_capacity, |_| None)} } + + fn peek_front(&self) -> &self/T { get(self.elts, self.lo) } + fn peek_back(&self) -> &self/T { get(self.elts, self.hi - 1u) } } impl Deque { fn add_front(&mut self, t: T) { - let oldlo: uint = self.lo; + let oldlo = self.lo; if self.lo == 0u { self.lo = self.elts.len() - 1u; } else { self.lo -= 1u; } @@ -88,10 +91,6 @@ impl Deque { t } - fn peek_front(&self) -> T { *get(self.elts, self.lo) } - - fn peek_back(&self) -> T { *get(self.elts, self.hi - 1u) } - fn get(&self, i: int) -> T { let idx = (self.lo + (i as uint)) % self.elts.len(); *get(self.elts, idx) @@ -122,52 +121,51 @@ fn get(elts: &r/[Option], i: uint) -> &r/T { #[cfg(test)] mod tests { - use core::prelude::*; use super::*; #[test] fn test_simple() { let mut d = Deque::new(); - assert (d.len() == 0u); + assert d.len() == 0u; d.add_front(17); d.add_front(42); d.add_back(137); - assert (d.len() == 3u); + assert d.len() == 3u; d.add_back(137); - assert (d.len() == 4u); + assert d.len() == 4u; log(debug, d.peek_front()); - assert (d.peek_front() == 42); + assert *d.peek_front() == 42; log(debug, d.peek_back()); - assert (d.peek_back() == 137); + assert *d.peek_back() == 137; let mut i: int = d.pop_front(); log(debug, i); - assert (i == 42); + assert i == 42; i = d.pop_back(); log(debug, i); - assert (i == 137); + assert i == 137; i = d.pop_back(); log(debug, i); - assert (i == 137); + assert i == 137; i = d.pop_back(); log(debug, i); - assert (i == 17); - assert (d.len() == 0u); + assert i == 17; + assert d.len() == 0u; d.add_back(3); - assert (d.len() == 1u); + assert d.len() == 1u; d.add_front(2); - assert (d.len() == 2u); + assert d.len() == 2u; d.add_back(4); - assert (d.len() == 3u); + assert d.len() == 3u; d.add_front(1); - assert (d.len() == 4u); + assert d.len() == 4u; log(debug, d.get(0)); log(debug, d.get(1)); log(debug, d.get(2)); log(debug, d.get(3)); - assert (d.get(0) == 1); - assert (d.get(1) == 2); - assert (d.get(2) == 3); - assert (d.get(3) == 4); + assert d.get(0) == 1; + assert d.get(1) == 2; + assert d.get(2) == 3; + assert d.get(3) == 4; } #[test] @@ -178,58 +176,58 @@ mod tests { let d: @int = @175; let mut deq = Deque::new(); - assert (deq.len() == 0u); + assert deq.len() == 0; deq.add_front(a); deq.add_front(b); deq.add_back(c); - assert (deq.len() == 3u); + assert deq.len() == 3; deq.add_back(d); - assert (deq.len() == 4u); - assert (deq.peek_front() == b); - assert (deq.peek_back() == d); - assert (deq.pop_front() == b); - assert (deq.pop_back() == d); - assert (deq.pop_back() == c); - assert (deq.pop_back() == a); - assert (deq.len() == 0u); - deq.add_back(c); - assert (deq.len() == 1u); - deq.add_front(b); - assert (deq.len() == 2u); - deq.add_back(d); - assert (deq.len() == 3u); - deq.add_front(a); - assert (deq.len() == 4u); - assert (deq.get(0) == a); - assert (deq.get(1) == b); - assert (deq.get(2) == c); - assert (deq.get(3) == d); - } - - fn test_parameterized(a: T, b: T, c: T, d: T) { - let mut deq = Deque::new(); - assert (deq.len() == 0u); - deq.add_front(a); - deq.add_front(b); - deq.add_back(c); - assert (deq.len() == 3u); - deq.add_back(d); - assert (deq.len() == 4u); - assert deq.peek_front() == b; - assert deq.peek_back() == d; + assert deq.len() == 4; + assert *deq.peek_front() == b; + assert *deq.peek_back() == d; assert deq.pop_front() == b; assert deq.pop_back() == d; assert deq.pop_back() == c; assert deq.pop_back() == a; - assert (deq.len() == 0u); + assert deq.len() == 0; deq.add_back(c); - assert (deq.len() == 1u); + assert deq.len() == 1; deq.add_front(b); - assert (deq.len() == 2u); + assert deq.len() == 2; deq.add_back(d); - assert (deq.len() == 3u); + assert deq.len() == 3; deq.add_front(a); - assert (deq.len() == 4u); + assert deq.len() == 4; + assert deq.get(0) == a; + assert deq.get(1) == b; + assert deq.get(2) == c; + assert deq.get(3) == d; + } + + fn test_parameterized(a: T, b: T, c: T, d: T) { + let mut deq = Deque::new(); + assert deq.len() == 0; + deq.add_front(a); + deq.add_front(b); + deq.add_back(c); + assert deq.len() == 3; + deq.add_back(d); + assert deq.len() == 4; + assert *deq.peek_front() == b; + assert *deq.peek_back() == d; + assert deq.pop_front() == b; + assert deq.pop_back() == d; + assert deq.pop_back() == c; + assert deq.pop_back() == a; + assert deq.len() == 0; + deq.add_back(c); + assert deq.len() == 1; + deq.add_front(b); + assert deq.len() == 2; + deq.add_back(d); + assert deq.len() == 3; + deq.add_front(a); + assert deq.len() == 4; assert deq.get(0) == a; assert deq.get(1) == b; assert deq.get(2) == c; From 6190661018b7a62613b7f02d2bc1c1d31cd2470d Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 19:43:29 -0500 Subject: [PATCH 07/10] deque: avoid Copy in pop_{front,back} --- src/libstd/deque.rs | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index b548623ba7c..7f8732d187f 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -45,6 +45,23 @@ impl Deque { fn peek_front(&self) -> &self/T { get(self.elts, self.lo) } fn peek_back(&self) -> &self/T { get(self.elts, self.hi - 1u) } + + fn pop_front(&mut self) -> T { + let mut result = self.elts[self.lo].swap_unwrap(); + self.lo = (self.lo + 1u) % self.elts.len(); + self.nelts -= 1u; + result + } + + fn pop_back(&mut self) -> T { + if self.hi == 0u { + self.hi = self.elts.len() - 1u; + } else { self.hi -= 1u; } + let mut result = self.elts[self.hi].swap_unwrap(); + self.elts[self.hi] = None; + self.nelts -= 1u; + result + } } impl Deque { @@ -73,24 +90,6 @@ impl Deque { self.nelts += 1u; } - fn pop_front(&mut self) -> T { - let t = { *get(self.elts, self.lo) }; - self.elts[self.lo] = None; - self.lo = (self.lo + 1u) % self.elts.len(); - self.nelts -= 1u; - t - } - - fn pop_back(&mut self) -> T { - if self.hi == 0u { - self.hi = self.elts.len() - 1u; - } else { self.hi -= 1u; } - let t = { *get(self.elts, self.hi) }; - self.elts[self.hi] = None; - self.nelts -= 1u; - t - } - fn get(&self, i: int) -> T { let idx = (self.lo + (i as uint)) % self.elts.len(); *get(self.elts, idx) From a2573290710f4b3f14be475f4ef2af773de7b4c7 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 20:50:14 -0500 Subject: [PATCH 08/10] deque: avoid Copy for get --- src/libstd/deque.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 7f8732d187f..1857d5eeaf9 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -46,6 +46,11 @@ impl Deque { fn peek_front(&self) -> &self/T { get(self.elts, self.lo) } fn peek_back(&self) -> &self/T { get(self.elts, self.hi - 1u) } + fn get(&self, i: int) -> &self/T { + let idx = (self.lo + (i as uint)) % self.elts.len(); + get(self.elts, idx) + } + fn pop_front(&mut self) -> T { let mut result = self.elts[self.lo].swap_unwrap(); self.lo = (self.lo + 1u) % self.elts.len(); @@ -89,11 +94,6 @@ impl Deque { self.hi = (self.hi + 1u) % self.elts.len(); self.nelts += 1u; } - - fn get(&self, i: int) -> T { - let idx = (self.lo + (i as uint)) % self.elts.len(); - *get(self.elts, idx) - } } /// Grow is only called on full elts, so nelts is also len(elts), unlike @@ -161,10 +161,10 @@ mod tests { log(debug, d.get(1)); log(debug, d.get(2)); log(debug, d.get(3)); - assert d.get(0) == 1; - assert d.get(1) == 2; - assert d.get(2) == 3; - assert d.get(3) == 4; + assert *d.get(0) == 1; + assert *d.get(1) == 2; + assert *d.get(2) == 3; + assert *d.get(3) == 4; } #[test] @@ -197,10 +197,10 @@ mod tests { assert deq.len() == 3; deq.add_front(a); assert deq.len() == 4; - assert deq.get(0) == a; - assert deq.get(1) == b; - assert deq.get(2) == c; - assert deq.get(3) == d; + assert *deq.get(0) == a; + assert *deq.get(1) == b; + assert *deq.get(2) == c; + assert *deq.get(3) == d; } fn test_parameterized(a: T, b: T, c: T, d: T) { @@ -227,10 +227,10 @@ mod tests { assert deq.len() == 3; deq.add_front(a); assert deq.len() == 4; - assert deq.get(0) == a; - assert deq.get(1) == b; - assert deq.get(2) == c; - assert deq.get(3) == d; + assert *deq.get(0) == a; + assert *deq.get(1) == b; + assert *deq.get(2) == c; + assert *deq.get(3) == d; } #[deriving_eq] From 5aa04635647287481ceca44cf557b698666fa939 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 21:34:09 -0500 Subject: [PATCH 09/10] deque: avoid Copy in grow --- src/libstd/deque.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 1857d5eeaf9..c182aa8caa0 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -98,17 +98,14 @@ impl Deque { /// Grow is only called on full elts, so nelts is also len(elts), unlike /// elsewhere. -fn grow(nelts: uint, lo: uint, elts: &[Option]) -> ~[Option] { +fn grow(nelts: uint, lo: uint, elts: &mut [Option]) -> ~[Option] { assert nelts == elts.len(); let mut rv = ~[]; - let mut i = 0u; - let nalloc = uint::next_power_of_two(nelts + 1u); - while i < nalloc { - if i < nelts { - rv.push(elts[(lo + i) % nelts]); - } else { rv.push(None); } - i += 1u; + do vec::grow_fn(&mut rv, nelts + 1) |i| { + let mut element = None; + element <-> elts[(lo + i) % nelts]; + element } rv From 8b38e07f24c5aeb817a2c83d8207016308550fa6 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 16 Feb 2013 21:34:38 -0500 Subject: [PATCH 10/10] deque: get rid of Copy requirement Closes #3748 --- src/libstd/deque.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index c182aa8caa0..2c90100a6f6 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -67,9 +67,7 @@ impl Deque { self.nelts -= 1u; result } -} -impl Deque { fn add_front(&mut self, t: T) { let oldlo = self.lo; if self.lo == 0u {