diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-05-19 19:46:54 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-05-19 23:34:32 -0700 |
| commit | 66319b027888ceddf024a5919e007caceaf369f3 (patch) | |
| tree | d210e635c950974972a086f7caa4268be6f33c93 /src/libstd | |
| parent | 3a481c0f88025318eba7c48907a5c1d966e01d27 (diff) | |
| download | rust-66319b027888ceddf024a5919e007caceaf369f3.tar.gz rust-66319b027888ceddf024a5919e007caceaf369f3.zip | |
Register snapshots
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/bitv.rs | 47 | ||||
| -rw-r--r-- | src/libstd/deque.rs | 12 | ||||
| -rw-r--r-- | src/libstd/dlist.rs | 47 | ||||
| -rw-r--r-- | src/libstd/ebml.rs | 41 | ||||
| -rw-r--r-- | src/libstd/fileinput.rs | 56 | ||||
| -rw-r--r-- | src/libstd/list.rs | 33 | ||||
| -rw-r--r-- | src/libstd/net_url.rs | 7 | ||||
| -rw-r--r-- | src/libstd/priority_queue.rs | 6 | ||||
| -rw-r--r-- | src/libstd/rc.rs | 32 | ||||
| -rw-r--r-- | src/libstd/smallintmap.rs | 48 | ||||
| -rw-r--r-- | src/libstd/sort.rs | 20 | ||||
| -rw-r--r-- | src/libstd/sort_stage0.rs | 1240 | ||||
| -rw-r--r-- | src/libstd/std.rc | 6 | ||||
| -rw-r--r-- | src/libstd/treemap.rs | 208 | ||||
| -rw-r--r-- | src/libstd/workcache.rs | 11 |
15 files changed, 0 insertions, 1814 deletions
diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index f0632e550fa..9d22107931e 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -143,17 +143,6 @@ pub impl BigBitv { } #[inline(always)] - #[cfg(stage0)] - fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) { - for uint::range(0, self.storage.len()) |i| { - let mut w = self.storage[i]; - let b = op(&mut w); - self.storage[i] = w; - if !b { break; } - } - } - #[inline(always)] - #[cfg(not(stage0))] fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) -> bool { uint::range(0, self.storage.len(), |i| op(&mut self.storage[i])) } @@ -199,19 +188,6 @@ pub impl BigBitv { } #[inline(always)] - #[cfg(stage0)] - fn equals(&self, b: &BigBitv, nbits: uint) -> bool { - let len = b.storage.len(); - for uint::iterate(0, len) |i| { - let mask = big_mask(nbits, i); - if mask & self.storage[i] != mask & b.storage[i] { - return false; - } - } - } - - #[inline(always)] - #[cfg(not(stage0))] fn equals(&self, b: &BigBitv, nbits: uint) -> bool { let len = b.storage.len(); for uint::iterate(0, len) |i| { @@ -407,16 +383,6 @@ pub impl Bitv { } #[inline(always)] - #[cfg(stage0)] - fn each(&self, f: &fn(bool) -> bool) { - let mut i = 0; - while i < self.nbits { - if !f(self.get(i)) { break; } - i += 1; - } - } - #[inline(always)] - #[cfg(not(stage0))] fn each(&self, f: &fn(bool) -> bool) -> bool { let mut i = 0; while i < self.nbits { @@ -519,15 +485,6 @@ pub impl Bitv { true } - #[cfg(stage0)] - fn ones(&self, f: &fn(uint) -> bool) { - for uint::range(0, self.nbits) |i| { - if self.get(i) { - if !f(i) { break } - } - } - } - #[cfg(not(stage0))] fn ones(&self, f: &fn(uint) -> bool) -> bool { uint::range(0, self.nbits, |i| !self.get(i) || f(i)) } @@ -697,7 +654,6 @@ pub impl BitvSet { } } -#[cfg(not(stage0))] impl BaseIter<uint> for BitvSet { fn size_hint(&self) -> Option<uint> { Some(self.len()) } @@ -711,7 +667,6 @@ impl BaseIter<uint> for BitvSet { } } -#[cfg(not(stage0))] impl cmp::Eq for BitvSet { fn eq(&self, other: &BitvSet) -> bool { if self.size != other.size { @@ -745,7 +700,6 @@ impl Mutable for BitvSet { } } -#[cfg(not(stage0))] impl Set<uint> for BitvSet { fn contains(&self, value: &uint) -> bool { *value < self.bitv.storage.len() * uint::bits && self.bitv.get(*value) @@ -849,7 +803,6 @@ impl Set<uint> for BitvSet { } } -#[cfg(not(stage0))] priv impl BitvSet { /// Visits each of the words that the two bit vectors (self and other) /// both have in common. The three yielded arguments are (bit location, diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index eac765de006..60f16074177 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -65,23 +65,11 @@ pub impl<T> Deque<T> { } /// Iterate over the elements in the deque - #[cfg(stage0)] - fn each(&self, f: &fn(&T) -> bool) { - self.eachi(|_i, e| f(e)) - } - /// Iterate over the elements in the deque - #[cfg(not(stage0))] fn each(&self, f: &fn(&T) -> bool) -> bool { self.eachi(|_i, e| f(e)) } /// Iterate over the elements in the deque by index - #[cfg(stage0)] - fn eachi(&self, f: &fn(uint, &T) -> bool) { - uint::range(0, self.nelts, |i| f(i, self.get(i as int))) - } - /// Iterate over the elements in the deque by index - #[cfg(not(stage0))] fn eachi(&self, f: &fn(uint, &T) -> bool) -> bool { uint::range(0, self.nelts, |i| f(i, self.get(i as int))) } diff --git a/src/libstd/dlist.rs b/src/libstd/dlist.rs index e0b4d746d53..100543d7d98 100644 --- a/src/libstd/dlist.rs +++ b/src/libstd/dlist.rs @@ -391,17 +391,6 @@ pub impl<T> DList<T> { } /// Iterate over nodes. - #[cfg(stage0)] - fn each_node(@mut self, f: &fn(@mut DListNode<T>) -> bool) { - let mut link = self.peek_n(); - while link.is_some() { - let nobe = link.get(); - if !f(nobe) { break; } - link = nobe.next_link(); - } - } - /// Iterate over nodes. - #[cfg(not(stage0))] fn each_node(@mut self, f: &fn(@mut DListNode<T>) -> bool) -> bool { let mut link = self.peek_n(); while link.is_some() { @@ -508,42 +497,6 @@ impl<T> BaseIter<T> for @mut DList<T> { * allow for e.g. breadth-first search with in-place enqueues), but * removing the current node is forbidden. */ - #[cfg(stage0)] - fn each(&self, f: &fn(v: &T) -> bool) { - let mut link = self.peek_n(); - while link.is_some() { - let nobe = link.get(); - assert!(nobe.linked); - - { - let frozen_nobe = &*nobe; - if !f(&frozen_nobe.data) { break; } - } - - // Check (weakly) that the user didn't do a remove. - if self.size == 0 { - fail!("The dlist became empty during iteration??") - } - if !nobe.linked || - (!((nobe.prev.is_some() - || managed::mut_ptr_eq(self.hd.expect(~"headless dlist?"), - nobe)) - && (nobe.next.is_some() - || managed::mut_ptr_eq(self.tl.expect(~"tailless dlist?"), - nobe)))) { - fail!("Removing a dlist node during iteration is forbidden!") - } - link = nobe.next_link(); - } - } - /** - * Iterates through the current contents. - * - * Attempts to access this dlist during iteration are allowed (to - * allow for e.g. breadth-first search with in-place enqueues), but - * removing the current node is forbidden. - */ - #[cfg(not(stage0))] fn each(&self, f: &fn(v: &T) -> bool) -> bool { let mut link = self.peek_n(); while link.is_some() { diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 8d550081d1e..a7c18ebf5cd 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -200,20 +200,6 @@ pub mod reader { } } - #[cfg(stage0)] - pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(*d.data, pos); - let elt_size = vuint_at(*d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - let doc = Doc { data: d.data, start: elt_size.next, end: pos }; - if !it(elt_tag.val, doc) { - break; - } - } - } - #[cfg(not(stage0))] pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) -> bool { let mut pos = d.start; while pos < d.end { @@ -228,23 +214,6 @@ pub mod reader { return true; } - #[cfg(stage0)] - pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(*d.data, pos); - let elt_size = vuint_at(*d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - let doc = Doc { data: d.data, start: elt_size.next, - end: pos }; - if !it(doc) { - break; - } - } - } - } - #[cfg(not(stage0))] pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) -> bool { let mut pos = d.start; while pos < d.end { @@ -655,16 +624,6 @@ pub mod writer { fail!("vint to write too big: %?", n); } - #[cfg(stage0)] - pub fn Encoder(w: @io::Writer) -> Encoder { - let size_positions: ~[uint] = ~[]; - Encoder { - writer: w, - mut size_positions: size_positions - } - } - - #[cfg(not(stage0))] pub fn Encoder(w: @io::Writer) -> Encoder { let size_positions: ~[uint] = ~[]; Encoder { diff --git a/src/libstd/fileinput.rs b/src/libstd/fileinput.rs index a31827f95d1..25e248414cd 100644 --- a/src/libstd/fileinput.rs +++ b/src/libstd/fileinput.rs @@ -254,17 +254,6 @@ impl FileInput { (line numbers and file names, see documentation for `FileInputState`). Otherwise identical to `lines_each`. */ - #[cfg(stage0)] - pub fn each_line_state(&self, - f: &fn(&str, FileInputState) -> bool) { - self.each_line(|line| f(line, copy self.fi.state)); - } - /** - Apply `f` to each line successively, along with some state - (line numbers and file names, see documentation for - `FileInputState`). Otherwise identical to `lines_each`. - */ - #[cfg(not(stage0))] pub fn each_line_state(&self, f: &fn(&str, FileInputState) -> bool) -> bool { self.each_line(|line| f(line, copy self.fi.state)) @@ -377,17 +366,6 @@ reading from `stdin`). Fails when attempting to read from a file that can't be opened. */ -#[cfg(stage0)] -pub fn input(f: &fn(&str) -> bool) { - FileInput::from_args().each_line(f); -} -/** -Iterate directly over the command line arguments (no arguments implies -reading from `stdin`). - -Fails when attempting to read from a file that can't be opened. -*/ -#[cfg(not(stage0))] pub fn input(f: &fn(&str) -> bool) -> bool { let i = FileInput::from_args(); i.each_line(f) @@ -400,18 +378,6 @@ provided at each call. Fails when attempting to read from a file that can't be opened. */ -#[cfg(stage0)] -pub fn input_state(f: &fn(&str, FileInputState) -> bool) { - FileInput::from_args().each_line_state(f); -} -/** -Iterate directly over the command line arguments (no arguments -implies reading from `stdin`) with the current state of the iteration -provided at each call. - -Fails when attempting to read from a file that can't be opened. -*/ -#[cfg(not(stage0))] pub fn input_state(f: &fn(&str, FileInputState) -> bool) -> bool { let i = FileInput::from_args(); i.each_line_state(f) @@ -422,16 +388,6 @@ Iterate over a vector of files (an empty vector implies just `stdin`). Fails when attempting to read from a file that can't be opened. */ -#[cfg(stage0)] -pub fn input_vec(files: ~[Option<Path>], f: &fn(&str) -> bool) { - FileInput::from_vec(files).each_line(f); -} -/** -Iterate over a vector of files (an empty vector implies just `stdin`). - -Fails when attempting to read from a file that can't be opened. -*/ -#[cfg(not(stage0))] pub fn input_vec(files: ~[Option<Path>], f: &fn(&str) -> bool) -> bool { let i = FileInput::from_vec(files); i.each_line(f) @@ -443,18 +399,6 @@ with the current state of the iteration provided at each call. Fails when attempting to read from a file that can't be opened. */ -#[cfg(stage0)] -pub fn input_vec_state(files: ~[Option<Path>], - f: &fn(&str, FileInputState) -> bool) { - FileInput::from_vec(files).each_line_state(f); -} -/** -Iterate over a vector of files (an empty vector implies just `stdin`) -with the current state of the iteration provided at each call. - -Fails when attempting to read from a file that can't be opened. -*/ -#[cfg(not(stage0))] pub fn input_vec_state(files: ~[Option<Path>], f: &fn(&str, FileInputState) -> bool) -> bool { let i = FileInput::from_vec(files); diff --git a/src/libstd/list.rs b/src/libstd/list.rs index ae3251b961c..3a916233db8 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -140,21 +140,6 @@ pub fn iter<T>(l: @List<T>, f: &fn(&T)) { } /// Iterate over a list -#[cfg(stage0)] -pub fn each<T>(l: @List<T>, f: &fn(&T) -> bool) { - let mut cur = l; - loop { - cur = match *cur { - Cons(ref hd, tl) => { - if !f(hd) { return; } - tl - } - Nil => break - } - } -} -/// Iterate over a list -#[cfg(not(stage0))] pub fn each<T>(l: @List<T>, f: &fn(&T) -> bool) -> bool { let mut cur = l; loop { @@ -170,24 +155,6 @@ pub fn each<T>(l: @List<T>, f: &fn(&T) -> bool) -> bool { impl<T> MutList<T> { /// Iterate over a mutable list - #[cfg(stage0)] - pub fn each(@mut self, f: &fn(&mut T) -> bool) { - let mut cur = self; - loop { - let borrowed = &mut *cur; - cur = match *borrowed { - MutCons(ref mut hd, tl) => { - if !f(hd) { - return; - } - tl - } - MutNil => break - } - } - } - /// Iterate over a mutable list - #[cfg(not(stage0))] pub fn each(@mut self, f: &fn(&mut T) -> bool) -> bool { let mut cur = self; loop { diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index ef503817b55..19e0dc14412 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -703,13 +703,6 @@ impl ToStr for Url { } } -#[cfg(stage0)] -impl IterBytes for Url { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { - self.to_str().iter_bytes(lsb0, f) - } -} -#[cfg(not(stage0))] impl IterBytes for Url { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { self.to_str().iter_bytes(lsb0, f) diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index b54fc81aac1..2f5d12d0807 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -22,12 +22,6 @@ impl<T:Ord> BaseIter<T> for PriorityQueue<T> { /// Visit all values in the underlying vector. /// /// The values are **not** visited in order. - #[cfg(stage0)] - fn each(&self, f: &fn(&T) -> bool) { self.data.each(f) } - /// Visit all values in the underlying vector. - /// - /// The values are **not** visited in order. - #[cfg(not(stage0))] fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.each(f) } fn size_hint(&self) -> Option<uint> { self.data.size_hint() } diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs index cc1492ba448..02f824b9113 100644 --- a/src/libstd/rc.rs +++ b/src/libstd/rc.rs @@ -61,7 +61,6 @@ pub impl<T> Rc<T> { } #[unsafe_destructor] -#[cfg(not(stage0))] impl<T> Drop for Rc<T> { fn finalize(&self) { unsafe { @@ -74,21 +73,6 @@ impl<T> Drop for Rc<T> { } } -#[unsafe_destructor] -#[cfg(stage0)] -impl<T> Drop for Rc<T> { - fn finalize(&self) { - unsafe { - (*self.ptr).count -= 1; - if (*self.ptr).count == 0 { - util::replace_ptr(self.ptr, intrinsics::init()); - free(self.ptr as *c_void) - } - } - } -} - - impl<T> Clone for Rc<T> { /// Return a shallow copy of the reference counted pointer. #[inline] @@ -157,7 +141,6 @@ mod test_rc { #[abi = "rust-intrinsic"] extern "rust-intrinsic" { fn init<T>() -> T; - #[cfg(not(stage0))] fn uninit<T>() -> T; } @@ -228,7 +211,6 @@ pub impl<T> RcMut<T> { } #[unsafe_destructor] -#[cfg(not(stage0))] impl<T> Drop for RcMut<T> { fn finalize(&self) { unsafe { @@ -241,20 +223,6 @@ impl<T> Drop for RcMut<T> { } } -#[unsafe_destructor] -#[cfg(stage0)] -impl<T> Drop for RcMut<T> { - fn finalize(&self) { - unsafe { - (*self.ptr).count -= 1; - if (*self.ptr).count == 0 { - util::replace_ptr(self.ptr, init()); - free(self.ptr as *c_void) - } - } - } -} - impl<T> Clone for RcMut<T> { /// Return a shallow copy of the reference counted pointer. #[inline] diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index a336bd54a61..3c1f53b25f7 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -51,18 +51,6 @@ impl<V> Map<uint, V> for SmallIntMap<V> { } /// Visit all key-value pairs in order - #[cfg(stage0)] - fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) { - for uint::range(0, self.v.len()) |i| { - match self.v[i] { - Some(ref elt) => if !it(&i, elt) { break }, - None => () - } - } - } - - /// Visit all key-value pairs in order - #[cfg(not(stage0))] fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool { for uint::range(0, self.v.len()) |i| { match self.v[i] { @@ -74,40 +62,16 @@ impl<V> Map<uint, V> for SmallIntMap<V> { } /// Visit all keys in order - #[cfg(stage0)] - fn each_key(&self, blk: &fn(key: &uint) -> bool) { - self.each(|k, _| blk(k)) - } - #[cfg(not(stage0))] - /// Visit all keys in order fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool { self.each(|k, _| blk(k)) } /// Visit all values in order - #[cfg(stage0)] - fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) { - self.each(|_, v| blk(v)) - } - - /// Visit all values in order - #[cfg(not(stage0))] fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool { self.each(|_, v| blk(v)) } /// Iterate over the map and mutate the contained values - #[cfg(stage0)] - fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) { - for uint::range(0, self.v.len()) |i| { - match self.v[i] { - Some(ref mut elt) => if !it(&i, elt) { return; }, - None => () - } - } - } - /// Iterate over the map and mutate the contained values - #[cfg(not(stage0))] fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool { for uint::range(0, self.v.len()) |i| { match self.v[i] { @@ -187,18 +151,6 @@ pub impl<V> SmallIntMap<V> { fn new() -> SmallIntMap<V> { SmallIntMap{v: ~[]} } /// Visit all key-value pairs in reverse order - #[cfg(stage0)] - fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) { - for uint::range_rev(self.v.len(), 0) |i| { - match self.v[i - 1] { - Some(ref elt) => if !it(i - 1, elt) { break }, - None => () - } - } - } - - /// Visit all key-value pairs in reverse order - #[cfg(not(stage0))] fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool { for uint::range_rev(self.v.len(), 0) |i| { match self.v[i - 1] { diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index ca752a48298..d896fa8c096 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -61,26 +61,6 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] { } } -#[cfg(stage0)] -fn part<T>(arr: &mut [T], left: uint, - right: uint, pivot: uint, compare_func: Le<T>) -> uint { - swap(&mut arr[pivot], &mut arr[right]); - let mut storage_index: uint = left; - let mut i: uint = left; - while i < right { - let a: &mut T = &mut arr[i]; - let b: &mut T = &mut arr[right]; - if compare_func(a, b) { - swap(&mut arr[i], &mut arr[storage_index]); - storage_index += 1; - } - i += 1; - } - swap(&mut arr[storage_index], &mut arr[right]); - return storage_index; -} - -#[cfg(not(stage0))] fn part<T>(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le<T>) -> uint { vec::swap(arr, pivot, right); diff --git a/src/libstd/sort_stage0.rs b/src/libstd/sort_stage0.rs deleted file mode 100644 index cdef8e220ce..00000000000 --- a/src/libstd/sort_stage0.rs +++ /dev/null @@ -1,1240 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Sorting methods - -use core::cmp::{Eq, Ord}; -use core::vec::len; -use core::vec; -use core::util; - -type Le<'self, T> = &'self fn(v1: &T, v2: &T) -> bool; - -/** - * Merge sort. Returns a new vector containing the sorted list. - * - * Has worst case O(n log n) performance, best case O(n), but - * is not space efficient. This is a stable sort. - */ -pub fn merge_sort<T:Copy>(v: &const [T], le: Le<T>) -> ~[T] { - type Slice = (uint, uint); - - return merge_sort_(v, (0u, len(v)), le); - - fn merge_sort_<T:Copy>(v: &const [T], slice: Slice, le: Le<T>) - -> ~[T] { - let begin = slice.first(); - let end = slice.second(); - - let v_len = end - begin; - if v_len == 0 { return ~[]; } - if v_len == 1 { return ~[v[begin]]; } - - let mid = v_len / 2 + begin; - let a = (begin, mid); - let b = (mid, end); - return merge(le, merge_sort_(v, a, le), merge_sort_(v, b, le)); - } - - fn merge<T:Copy>(le: Le<T>, a: &[T], b: &[T]) -> ~[T] { - let mut rs = vec::with_capacity(len(a) + len(b)); - let a_len = len(a); - let mut a_ix = 0; - let b_len = len(b); - let mut b_ix = 0; - while a_ix < a_len && b_ix < b_len { - if le(&a[a_ix], &b[b_ix]) { - rs.push(a[a_ix]); - a_ix += 1; - } else { rs.push(b[b_ix]); b_ix += 1; } - } - rs.push_all(vec::slice(a, a_ix, a_len)); - rs.push_all(vec::slice(b, b_ix, b_len)); - rs - } -} - -#[cfg(stage0)] -fn part<T>(arr: &mut [T], left: uint, - right: uint, pivot: uint, compare_func: Le<T>) -> uint { - vec::swap(arr, pivot, right); - let mut storage_index: uint = left; - let mut i: uint = left; - while i < right { - let a: &mut T = &mut arr[i]; - let b: &mut T = &mut arr[right]; - if compare_func(a, b) { - vec::swap(arr, i, storage_index); - storage_index += 1; - } - i += 1; - } - vec::swap(arr, storage_index, right); - return storage_index; -} - -#[cfg(not(stage0))] -fn part<T>(arr: &mut [T], left: uint, - right: uint, pivot: uint, compare_func: Le<T>) -> uint { - vec::swap(arr, pivot, right); - let mut storage_index: uint = left; - let mut i: uint = left; - while i < right { - if compare_func(&arr[i], &arr[right]) { - vec::swap(arr, i, storage_index); - storage_index += 1; - } - i += 1; - } - vec::swap(arr, storage_index, right); - return storage_index; -} - -fn qsort<T>(arr: &mut [T], left: uint, - right: uint, compare_func: Le<T>) { - if right > left { - let pivot = (left + right) / 2u; - let new_pivot = part::<T>(arr, left, right, pivot, compare_func); - if new_pivot != 0u { - // Need to do this check before recursing due to overflow - qsort::<T>(arr, left, new_pivot - 1u, compare_func); - } - qsort::<T>(arr, new_pivot + 1u, right, compare_func); - } -} - -/** - * Quicksort. Sorts a mut vector in place. - * - * Has worst case O(n^2) performance, average case O(n log n). - * This is an unstable sort. - */ -pub fn quick_sort<T>(arr: &mut [T], compare_func: Le<T>) { - if len::<T>(arr) == 0u { return; } - qsort::<T>(arr, 0u, len::<T>(arr) - 1u, compare_func); -} - -fn qsort3<T:Copy + Ord + Eq>(arr: &mut [T], left: int, right: int) { - if right <= left { return; } - let v: T = arr[right]; - let mut i: int = left - 1; - let mut j: int = right; - let mut p: int = i; - let mut q: int = j; - loop { - i += 1; - while arr[i] < v { i += 1; } - j -= 1; - while v < arr[j] { - if j == left { break; } - j -= 1; - } - if i >= j { break; } - vec::swap(arr, i as uint, j as uint); - if arr[i] == v { - p += 1; - vec::swap(arr, p as uint, i as uint); - } - if v == arr[j] { - q -= 1; - vec::swap(arr, j as uint, q as uint); - } - } - vec::swap(arr, i as uint, right as uint); - j = i - 1; - i += 1; - let mut k: int = left; - while k < p { - vec::swap(arr, k as uint, j as uint); - k += 1; - j -= 1; - if k == len::<T>(arr) as int { break; } - } - k = right - 1; - while k > q { - vec::swap(arr, i as uint, k as uint); - k -= 1; - i += 1; - if k == 0 { break; } - } - qsort3::<T>(arr, left, j); - qsort3::<T>(arr, i, right); -} - -/** - * Fancy quicksort. Sorts a mut vector in place. - * - * Based on algorithm presented by ~[Sedgewick and Bentley] - * (http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf). - * According to these slides this is the algorithm of choice for - * 'randomly ordered keys, abstract compare' & 'small number of key values'. - * - * This is an unstable sort. - */ -pub fn quick_sort3<T:Copy + Ord + Eq>(arr: &mut [T]) { - if arr.len() <= 1 { return; } - let len = arr.len() - 1; // FIXME(#5074) nested calls - qsort3(arr, 0, (len - 1) as int); -} - -pub trait Sort { - fn qsort(self); -} - -impl<'self, T:Copy + Ord + Eq> Sort for &'self mut [T] { - fn qsort(self) { quick_sort3(self); } -} - -static MIN_MERGE: uint = 64; -static MIN_GALLOP: uint = 7; -static INITIAL_TMP_STORAGE: uint = 128; - -pub fn tim_sort<T:Copy + Ord>(array: &mut [T]) { - let size = array.len(); - if size < 2 { - return; - } - - if size < MIN_MERGE { - let init_run_len = count_run_ascending(array); - binarysort(array, init_run_len); - return; - } - - let mut ms = MergeState(); - let min_run = min_run_length(size); - - let mut idx = 0; - let mut remaining = size; - loop { - let run_len: uint = { - // This scope contains the slice `arr` here: - let arr = vec::mut_slice(array, idx, size); - let mut run_len: uint = count_run_ascending(arr); - - if run_len < min_run { - let force = if remaining <= min_run {remaining} else {min_run}; - let slice = vec::mut_slice(arr, 0, force); - binarysort(slice, run_len); - run_len = force; - } - - run_len - }; - - ms.push_run(idx, run_len); - ms.merge_collapse(array); - - idx += run_len; - remaining -= run_len; - if remaining == 0 { break; } - } - - ms.merge_force_collapse(array); -} - -fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) { - let size = array.len(); - let mut start = start; - assert!(start <= size); - - if start == 0 { start += 1; } - - while start < size { - let pivot = array[start]; - let mut left = 0; - let mut right = start; - assert!(left <= right); - - while left < right { - let mid = (left + right) >> 1; - if pivot < array[mid] { - right = mid; - } else { - left = mid+1; - } - } - assert_eq!(left, right); - let n = start-left; - - copy_vec(array, left+1, array, left, n); - array[left] = pivot; - start += 1; - } -} - -// Reverse the order of elements in a slice, in place -fn reverse_slice<T>(v: &mut [T], start: uint, end:uint) { - let mut i = start; - while i < end / 2 { - vec::swap(v, i, end - i - 1); - i += 1; - } -} - -fn min_run_length(n: uint) -> uint { - let mut n = n; - let mut r = 0; // becomes 1 if any 1 bits are shifted off - - while n >= MIN_MERGE { - r |= n & 1; - n >>= 1; - } - return n + r; -} - -fn count_run_ascending<T:Copy + Ord>(array: &mut [T]) -> uint { - let size = array.len(); - assert!(size > 0); - if size == 1 { return 1; } - - let mut run = 2; - if array[1] < array[0] { - while run < size && array[run] < array[run-1] { - run += 1; - } - reverse_slice(array, 0, run); - } else { - while run < size && array[run] >= array[run-1] { - run += 1; - } - } - - return run; -} - -fn gallop_left<T:Copy + Ord>(key: &const T, - array: &const [T], - hint: uint) - -> uint { - let size = array.len(); - assert!(size != 0 && hint < size); - - let mut last_ofs = 0; - let mut ofs = 1; - - if *key > array[hint] { - // Gallop right until array[hint+last_ofs] < key <= array[hint+ofs] - let max_ofs = size - hint; - while ofs < max_ofs && *key > array[hint+ofs] { - last_ofs = ofs; - ofs = (ofs << 1) + 1; - if ofs < last_ofs { ofs = max_ofs; } // uint overflow guard - } - if ofs > max_ofs { ofs = max_ofs; } - - last_ofs += hint; - ofs += hint; - } else { - let max_ofs = hint + 1; - while ofs < max_ofs && *key <= array[hint-ofs] { - last_ofs = ofs; - ofs = (ofs << 1) + 1; - if ofs < last_ofs { ofs = max_ofs; } // uint overflow guard - } - - if ofs > max_ofs { ofs = max_ofs; } - - let tmp = last_ofs; - last_ofs = hint - ofs; - ofs = hint - tmp; - } - assert!((last_ofs < ofs || last_ofs+1 < ofs+1) && ofs <= size); - - last_ofs += 1; - while last_ofs < ofs { - let m = last_ofs + ((ofs - last_ofs) >> 1); - if *key > array[m] { - last_ofs = m+1; - } else { - ofs = m; - } - } - assert_eq!(last_ofs, ofs); - return ofs; -} - -fn gallop_right<T:Copy + Ord>(key: &const T, - array: &const [T], - hint: uint) - -> uint { - let size = array.len(); - assert!(size != 0 && hint < size); - - let mut last_ofs = 0; - let mut ofs = 1; - - if *key >= array[hint] { - // Gallop right until array[hint+last_ofs] <= key < array[hint+ofs] - let max_ofs = size - hint; - while ofs < max_ofs && *key >= array[hint+ofs] { - last_ofs = ofs; - ofs = (ofs << 1) + 1; - if ofs < last_ofs { ofs = max_ofs; } - } - if ofs > max_ofs { ofs = max_ofs; } - - last_ofs += hint; - ofs += hint; - } else { - // Gallop left until array[hint-ofs] <= key < array[hint-last_ofs] - let max_ofs = hint + 1; - while ofs < max_ofs && *key < array[hint-ofs] { - last_ofs = ofs; - ofs = (ofs << 1) + 1; - if ofs < last_ofs { ofs = max_ofs; } - } - if ofs > max_ofs { ofs = max_ofs; } - - let tmp = last_ofs; - last_ofs = hint - ofs; - ofs = hint - tmp; - } - - assert!((last_ofs < ofs || last_ofs+1 < ofs+1) && ofs <= size); - - last_ofs += 1; - while last_ofs < ofs { - let m = last_ofs + ((ofs - last_ofs) >> 1); - - if *key >= array[m] { - last_ofs = m + 1; - } else { - ofs = m; - } - } - assert_eq!(last_ofs, ofs); - return ofs; -} - -struct RunState { - base: uint, - len: uint, -} - -struct MergeState<T> { - min_gallop: uint, - runs: ~[RunState], -} - -// Fixme (#3853) Move into MergeState -fn MergeState<T>() -> MergeState<T> { - MergeState { - min_gallop: MIN_GALLOP, - runs: ~[], - } -} - -impl<T:Copy + Ord> MergeState<T> { - fn push_run(&mut self, run_base: uint, run_len: uint) { - let tmp = RunState{base: run_base, len: run_len}; - self.runs.push(tmp); - } - - fn merge_at(&mut self, n: uint, array: &mut [T]) { - let size = self.runs.len(); - assert!(size >= 2); - assert!(n == size-2 || n == size-3); - - let mut b1 = self.runs[n].base; - let mut l1 = self.runs[n].len; - let b2 = self.runs[n+1].base; - let l2 = self.runs[n+1].len; - - assert!(l1 > 0 && l2 > 0); - assert_eq!(b1 + l1, b2); - - self.runs[n].len = l1 + l2; - if n == size-3 { - self.runs[n+1].base = self.runs[n+2].base; - self.runs[n+1].len = self.runs[n+2].len; - } - - let k = { // constrain lifetime of slice below - let slice = vec::mut_slice(array, b1, b1+l1); - gallop_right(&const array[b2], slice, 0) - }; - b1 += k; - l1 -= k; - if l1 != 0 { - let l2 = { // constrain lifetime of slice below - let slice = vec::mut_slice(array, b2, b2+l2); - gallop_left(&const array[b1+l1-1],slice,l2-1) - }; - if l2 > 0 { - if l1 <= l2 { - self.merge_lo(array, b1, l1, b2, l2); - } else { - self.merge_hi(array, b1, l1, b2, l2); - } - } - } - self.runs.pop(); - } - - fn merge_lo(&mut self, array: &mut [T], base1: uint, len1: uint, - base2: uint, len2: uint) { - assert!(len1 != 0 && len2 != 0 && base1+len1 == base2); - - let mut tmp = ~[]; - for uint::range(base1, base1+len1) |i| { - tmp.push(array[i]); - } - - let mut c1 = 0; - let mut c2 = base2; - let mut dest = base1; - let mut len1 = len1; - let mut len2 = len2; - - vec::swap(array, dest, c2); - dest += 1; c2 += 1; len2 -= 1; - - if len2 == 0 { - copy_vec(array, dest, tmp, 0, len1); - return; - } - if len1 == 1 { - copy_vec(array, dest, array, c2, len2); - util::swap(&mut array[dest+len2], &mut tmp[c1]); - return; - } - - let mut min_gallop = self.min_gallop; - loop { - let mut count1 = 0; - let mut count2 = 0; - let mut break_outer = false; - - loop { - assert!(len1 > 1 && len2 != 0); - if array[c2] < tmp[c1] { - vec::swap(array, dest, c2); - dest += 1; c2 += 1; len2 -= 1; - count2 += 1; count1 = 0; - if len2 == 0 { - break_outer = true; - } - } else { - util::swap(&mut array[dest], &mut tmp[c1]); - dest += 1; c1 += 1; len1 -= 1; - count1 += 1; count2 = 0; - if len1 == 1 { - break_outer = true; - } - } - if break_outer || ((count1 | count2) >= min_gallop) { - break; - } - } - if break_outer { break; } - - // Start to gallop - loop { - assert!(len1 > 1 && len2 != 0); - - let tmp_view = vec::const_slice(tmp, c1, c1+len1); - count1 = gallop_right(&const array[c2], tmp_view, 0); - if count1 != 0 { - copy_vec(array, dest, tmp, c1, count1); - dest += count1; c1 += count1; len1 -= count1; - if len1 <= 1 { break_outer = true; break; } - } - vec::swap(array, dest, c2); - dest += 1; c2 += 1; len2 -= 1; - if len2 == 0 { break_outer = true; break; } - - let tmp_view = vec::const_slice(array, c2, c2+len2); - count2 = gallop_left(&const tmp[c1], tmp_view, 0); - if count2 != 0 { - copy_vec(array, dest, array, c2, count2); - dest += count2; c2 += count2; len2 -= count2; - if len2 == 0 { break_outer = true; break; } - } - util::swap(&mut array[dest], &mut tmp[c1]); - dest += 1; c1 += 1; len1 -= 1; - if len1 == 1 { break_outer = true; break; } - min_gallop -= 1; - if !(count1 >= MIN_GALLOP || count2 >= MIN_GALLOP) { - break; - } - } - if break_outer { break; } - if min_gallop < 0 { min_gallop = 0; } - min_gallop += 2; // Penalize for leaving gallop - } - self.min_gallop = if min_gallop < 1 { 1 } else { min_gallop }; - - if len1 == 1 { - assert!(len2 > 0); - copy_vec(array, dest, array, c2, len2); - util::swap(&mut array[dest+len2], &mut tmp[c1]); - } else if len1 == 0 { - fail!("Comparison violates its contract!"); - } else { - assert_eq!(len2, 0); - assert!(len1 > 1); - copy_vec(array, dest, tmp, c1, len1); - } - } - - fn merge_hi(&mut self, array: &mut [T], base1: uint, len1: uint, - base2: uint, len2: uint) { - assert!(len1 != 1 && len2 != 0 && base1+len1 == base2); - - let mut tmp = ~[]; - for uint::range(base2, base2+len2) |i| { - tmp.push(array[i]); - } - - let mut c1 = base1 + len1 - 1; - let mut c2 = len2 - 1; - let mut dest = base2 + len2 - 1; - let mut len1 = len1; - let mut len2 = len2; - - vec::swap(array, dest, c1); - dest -= 1; c1 -= 1; len1 -= 1; - - if len1 == 0 { - copy_vec(array, dest-(len2-1), tmp, 0, len2); - return; - } - if len2 == 1 { - dest -= len1; - c1 -= len1; - copy_vec(array, dest+1, array, c1+1, len1); - util::swap(&mut array[dest], &mut tmp[c2]); - return; - } - - let mut min_gallop = self.min_gallop; - loop { - let mut count1 = 0; - let mut count2 = 0; - let mut break_outer = false; - - loop { - assert!(len1 != 0 && len2 > 1); - if tmp[c2] < array[c1] { - vec::swap(array, dest, c1); - dest -= 1; c1 -= 1; len1 -= 1; - count1 += 1; count2 = 0; - if len1 == 0 { - break_outer = true; - } - } else { - util::swap(&mut array[dest], &mut tmp[c2]); - dest -= 1; c2 -= 1; len2 -= 1; - count2 += 1; count1 = 0; - if len2 == 1 { - break_outer = true; - } - } - if break_outer || ((count1 | count2) >= min_gallop) { - break; - } - } - if break_outer { break; } - - // Start to gallop - loop { - assert!(len2 > 1 && len1 != 0); - - { // constrain scope of tmp_view: - let tmp_view = vec::mut_slice (array, base1, base1+len1); - count1 = len1 - gallop_right( - &const tmp[c2], tmp_view, len1-1); - } - - if count1 != 0 { - dest -= count1; c1 -= count1; len1 -= count1; - copy_vec(array, dest+1, array, c1+1, count1); - if len1 == 0 { break_outer = true; break; } - } - - util::swap(&mut array[dest], &mut tmp[c2]); - dest -= 1; c2 -= 1; len2 -= 1; - if len2 == 1 { break_outer = true; break; } - - let count2; - { // constrain scope of tmp_view - let tmp_view = vec::mut_slice(tmp, 0, len2); - count2 = len2 - gallop_left(&const array[c1], - tmp_view, - len2-1); - } - - if count2 != 0 { - dest -= count2; c2 -= count2; len2 -= count2; - copy_vec(array, dest+1, tmp, c2+1, count2); - if len2 <= 1 { break_outer = true; break; } - } - vec::swap(array, dest, c1); - dest -= 1; c1 -= 1; len1 -= 1; - if len1 == 0 { break_outer = true; break; } - min_gallop -= 1; - if !(count1 >= MIN_GALLOP || count2 >= MIN_GALLOP) { - break; - } - } - - if break_outer { break; } - if min_gallop < 0 { min_gallop = 0; } - min_gallop += 2; // Penalize for leaving gallop - } - self.min_gallop = if min_gallop < 1 { 1 } else { min_gallop }; - - if len2 == 1 { - assert!(len1 > 0); - dest -= len1; - c1 -= len1; - copy_vec(array, dest+1, array, c1+1, len1); - util::swap(&mut array[dest], &mut tmp[c2]); - } else if len2 == 0 { - fail!("Comparison violates its contract!"); - } else { - assert_eq!(len1, 0); - assert!(len2 != 0); - copy_vec(array, dest-(len2-1), tmp, 0, len2); - } - } - - fn merge_collapse(&mut self, array: &mut [T]) { - while self.runs.len() > 1 { - let mut n = self.runs.len()-2; - if n > 0 && - self.runs[n-1].len <= self.runs[n].len + self.runs[n+1].len - { - if self.runs[n-1].len < self.runs[n+1].len { n -= 1; } - } else if self.runs[n].len <= self.runs[n+1].len { - /* keep going */ - } else { - break; - } - self.merge_at(n, array); - } - } - - fn merge_force_collapse(&mut self, array: &mut [T]) { - while self.runs.len() > 1 { - let mut n = self.runs.len()-2; - if n > 0 { - if self.runs[n-1].len < self.runs[n+1].len { - n -= 1; - } - } - self.merge_at(n, array); - } - } -} - -#[inline(always)] -fn copy_vec<T:Copy>(dest: &mut [T], - s1: uint, - from: &const [T], - s2: uint, - len: uint) { - assert!(s1+len <= dest.len() && s2+len <= from.len()); - - let mut slice = ~[]; - for uint::range(s2, s2+len) |i| { - slice.push(from[i]); - } - - for slice.eachi |i, v| { - dest[s1+i] = *v; - } -} - -#[cfg(test)] -mod test_qsort3 { - use sort::*; - - use core::vec; - - fn check_sort(v1: &mut [int], v2: &mut [int]) { - let len = vec::len::<int>(v1); - quick_sort3::<int>(v1); - let mut i = 0; - while i < len { - // debug!(v2[i]); - assert_eq!(v2[i], v1[i]); - i += 1; - } - } - - #[test] - fn test() { - { - let mut v1 = ~[3, 7, 4, 5, 2, 9, 5, 8]; - let mut v2 = ~[2, 3, 4, 5, 5, 7, 8, 9]; - check_sort(v1, v2); - } - { - let mut v1 = ~[1, 1, 1]; - let mut v2 = ~[1, 1, 1]; - check_sort(v1, v2); - } - { - let mut v1: ~[int] = ~[]; - let mut v2: ~[int] = ~[]; - check_sort(v1, v2); - } - { let mut v1 = ~[9]; let mut v2 = ~[9]; check_sort(v1, v2); } - { - let mut v1 = ~[9, 3, 3, 3, 9]; - let mut v2 = ~[3, 3, 3, 9, 9]; - check_sort(v1, v2); - } - } -} - -#[cfg(test)] -mod test_qsort { - use sort::*; - - use core::int; - use core::vec; - - fn check_sort(v1: &mut [int], v2: &mut [int]) { - let len = vec::len::<int>(v1); - fn leual(a: &int, b: &int) -> bool { *a <= *b } - quick_sort::<int>(v1, leual); - let mut i = 0u; - while i < len { - // debug!(v2[i]); - assert_eq!(v2[i], v1[i]); - i += 1; - } - } - - #[test] - fn test() { - { - let mut v1 = ~[3, 7, 4, 5, 2, 9, 5, 8]; - let mut v2 = ~[2, 3, 4, 5, 5, 7, 8, 9]; - check_sort(v1, v2); - } - { - let mut v1 = ~[1, 1, 1]; - let mut v2 = ~[1, 1, 1]; - check_sort(v1, v2); - } - { - let mut v1: ~[int] = ~[]; - let mut v2: ~[int] = ~[]; - check_sort(v1, v2); - } - { let mut v1 = ~[9]; let mut v2 = ~[9]; check_sort(v1, v2); } - { - let mut v1 = ~[9, 3, 3, 3, 9]; - let mut v2 = ~[3, 3, 3, 9, 9]; - check_sort(v1, v2); - } - } - - // Regression test for #750 - #[test] - fn test_simple() { - let mut names = ~[2, 1, 3]; - - let expected = ~[1, 2, 3]; - - do quick_sort(names) |x, y| { int::le(*x, *y) }; - - let immut_names = names; - - let pairs = vec::zip_slice(expected, immut_names); - for pairs.each |p| { - let (a, b) = *p; - debug!("%d %d", a, b); - assert_eq!(a, b); - } - } -} - -#[cfg(test)] -mod tests { - - use sort::*; - - use core::vec; - - fn check_sort(v1: &[int], v2: &[int]) { - let len = vec::len::<int>(v1); - pub fn le(a: &int, b: &int) -> bool { *a <= *b } - let f = le; - let v3 = merge_sort::<int>(v1, f); - let mut i = 0u; - while i < len { - debug!(v3[i]); - assert_eq!(v3[i], v2[i]); - i += 1; - } - } - - #[test] - fn test() { - { - let v1 = ~[3, 7, 4, 5, 2, 9, 5, 8]; - let v2 = ~[2, 3, 4, 5, 5, 7, 8, 9]; - check_sort(v1, v2); - } - { let v1 = ~[1, 1, 1]; let v2 = ~[1, 1, 1]; check_sort(v1, v2); } - { let v1:~[int] = ~[]; let v2:~[int] = ~[]; check_sort(v1, v2); } - { let v1 = ~[9]; let v2 = ~[9]; check_sort(v1, v2); } - { - let v1 = ~[9, 3, 3, 3, 9]; - let v2 = ~[3, 3, 3, 9, 9]; - check_sort(v1, v2); - } - } - - #[test] - fn test_merge_sort_mutable() { - pub fn le(a: &int, b: &int) -> bool { *a <= *b } - let mut v1 = ~[3, 2, 1]; - let v2 = merge_sort(v1, le); - assert_eq!(v2, ~[1, 2, 3]); - } - - #[test] - fn test_merge_sort_stability() { - // tjc: funny that we have to use parens - fn ile(x: &(&'static str), y: &(&'static str)) -> bool - { - // FIXME: #4318 Instead of to_ascii and to_str_ascii, could use - // to_ascii_consume and to_str_consume to not do a unnecessary copy. - // (Actually, could just remove the to_str_* call, but needs an deriving(Ord) on - // Ascii) - let x = x.to_ascii().to_lower().to_str_ascii(); - let y = y.to_ascii().to_lower().to_str_ascii(); - x <= y - } - - let names1 = ~["joe bob", "Joe Bob", "Jack Brown", "JOE Bob", - "Sally Mae", "JOE BOB", "Alex Andy"]; - let names2 = ~["Alex Andy", "Jack Brown", "joe bob", "Joe Bob", - "JOE Bob", "JOE BOB", "Sally Mae"]; - let names3 = merge_sort(names1, ile); - assert_eq!(names3, names2); - } -} - -#[cfg(test)] -mod test_tim_sort { - use sort::tim_sort; - use core::rand::RngUtil; - - struct CVal { - val: float, - } - - impl Ord for CVal { - fn lt(&self, other: &CVal) -> bool { - let rng = rand::rng(); - if rng.gen::<float>() > 0.995 { fail!("It's happening!!!"); } - (*self).val < other.val - } - fn le(&self, other: &CVal) -> bool { (*self).val <= other.val } - fn gt(&self, other: &CVal) -> bool { (*self).val > other.val } - fn ge(&self, other: &CVal) -> bool { (*self).val >= other.val } - } - - fn check_sort(v1: &mut [int], v2: &mut [int]) { - let len = vec::len::<int>(v1); - tim_sort::<int>(v1); - let mut i = 0u; - while i < len { - // debug!(v2[i]); - assert_eq!(v2[i], v1[i]); - i += 1u; - } - } - - #[test] - fn test() { - { - let mut v1 = ~[3, 7, 4, 5, 2, 9, 5, 8]; - let mut v2 = ~[2, 3, 4, 5, 5, 7, 8, 9]; - check_sort(v1, v2); - } - { - let mut v1 = ~[1, 1, 1]; - let mut v2 = ~[1, 1, 1]; - check_sort(v1, v2); - } - { - let mut v1: ~[int] = ~[]; - let mut v2: ~[int] = ~[]; - check_sort(v1, v2); - } - { let mut v1 = ~[9]; let mut v2 = ~[9]; check_sort(v1, v2); } - { - let mut v1 = ~[9, 3, 3, 3, 9]; - let mut v2 = ~[3, 3, 3, 9, 9]; - check_sort(v1, v2); - } - } - - #[test] - #[should_fail] - #[cfg(unix)] - fn crash_test() { - let rng = rand::rng(); - let mut arr = do vec::from_fn(1000) |_i| { - CVal { val: rng.gen() } - }; - - tim_sort(arr); - fail!("Guarantee the fail"); - } - - struct DVal { val: uint } - - impl Ord for DVal { - fn lt(&self, _x: &DVal) -> bool { true } - fn le(&self, _x: &DVal) -> bool { true } - fn gt(&self, _x: &DVal) -> bool { true } - fn ge(&self, _x: &DVal) -> bool { true } - } - - #[test] - fn test_bad_Ord_impl() { - let rng = rand::rng(); - let mut arr = do vec::from_fn(500) |_i| { - DVal { val: rng.gen() } - }; - - tim_sort(arr); - } -} - -#[cfg(test)] -mod big_tests { - use sort::*; - use core::rand::RngUtil; - - #[test] - fn test_unique() { - let low = 5; - let high = 10; - tabulate_unique(low, high); - } - - #[test] - fn test_managed() { - let low = 5; - let high = 10; - tabulate_managed(low, high); - } - - fn multiplyVec<T:Copy>(arr: &const [T], num: uint) -> ~[T] { - let size = arr.len(); - let res = do vec::from_fn(num) |i| { - arr[i % size] - }; - res - } - - fn makeRange(n: uint) -> ~[uint] { - let one = do vec::from_fn(n) |i| { i }; - let mut two = copy one; - vec::reverse(two); - vec::append(two, one) - } - - fn tabulate_unique(lo: uint, hi: uint) { - fn isSorted<T:Ord>(arr: &const [T]) { - for uint::range(0, arr.len()-1) |i| { - if arr[i] > arr[i+1] { - fail!("Array not sorted"); - } - } - } - - let rng = rand::rng(); - - for uint::range(lo, hi) |i| { - let n = 1 << i; - let mut arr: ~[float] = do vec::from_fn(n) |_i| { - rng.gen() - }; - - tim_sort(arr); // *sort - isSorted(arr); - - vec::reverse(arr); - tim_sort(arr); // \sort - isSorted(arr); - - tim_sort(arr); // /sort - isSorted(arr); - - for 3.times { - let i1 = rng.gen_uint_range(0, n); - let i2 = rng.gen_uint_range(0, n); - vec::swap(arr, i1, i2); - } - tim_sort(arr); // 3sort - isSorted(arr); - - if n >= 10 { - let size = arr.len(); - let mut idx = 1; - while idx <= 10 { - arr[size-idx] = rng.gen(); - idx += 1; - } - } - tim_sort(arr); // +sort - isSorted(arr); - - for (n/100).times { - let idx = rng.gen_uint_range(0, n); - arr[idx] = rng.gen(); - } - tim_sort(arr); - isSorted(arr); - - let mut arr = if n > 4 { - let part = vec::slice(arr, 0, 4); - multiplyVec(part, n) - } else { arr }; - tim_sort(arr); // ~sort - isSorted(arr); - - let mut arr = vec::from_elem(n, -0.5); - tim_sort(arr); // =sort - isSorted(arr); - - let half = n / 2; - let mut arr = makeRange(half).map(|i| *i as float); - tim_sort(arr); // !sort - isSorted(arr); - } - } - - fn tabulate_managed(lo: uint, hi: uint) { - fn isSorted<T:Ord>(arr: &const [@T]) { - for uint::range(0, arr.len()-1) |i| { - if arr[i] > arr[i+1] { - fail!("Array not sorted"); - } - } - } - - let rng = rand::rng(); - - for uint::range(lo, hi) |i| { - let n = 1 << i; - let arr: ~[@float] = do vec::from_fn(n) |_i| { - @rng.gen() - }; - let mut arr = arr; - - tim_sort(arr); // *sort - isSorted(arr); - - vec::reverse(arr); - tim_sort(arr); // \sort - isSorted(arr); - - tim_sort(arr); // /sort - isSorted(arr); - - for 3.times { - let i1 = rng.gen_uint_range(0, n); - let i2 = rng.gen_uint_range(0, n); - vec::swap(arr, i1, i2); - } - tim_sort(arr); // 3sort - isSorted(arr); - - if n >= 10 { - let size = arr.len(); - let mut idx = 1; - while idx <= 10 { - arr[size-idx] = @rng.gen(); - idx += 1; - } - } - tim_sort(arr); // +sort - isSorted(arr); - - for (n/100).times { - let idx = rng.gen_uint_range(0, n); - arr[idx] = @rng.gen(); - } - tim_sort(arr); - isSorted(arr); - - let mut arr = if n > 4 { - let part = vec::slice(arr, 0, 4); - multiplyVec(part, n) - } else { arr }; - tim_sort(arr); // ~sort - isSorted(arr); - - let mut arr = vec::from_elem(n, @(-0.5)); - tim_sort(arr); // =sort - isSorted(arr); - - let half = n / 2; - let mut arr = makeRange(half).map(|i| @(*i as float)); - tim_sort(arr); // !sort - isSorted(arr); - } - } - - struct LVal<'self> { - val: uint, - key: &'self fn(@uint), - } - - #[unsafe_destructor] - impl<'self> Drop for LVal<'self> { - fn finalize(&self) { - let x = unsafe { local_data::local_data_get(self.key) }; - match x { - Some(@y) => { - unsafe { - local_data::local_data_set(self.key, @(y+1)); - } - } - _ => fail!("Expected key to work"), - } - } - } - - impl<'self> Ord for LVal<'self> { - fn lt<'a>(&self, other: &'a LVal<'self>) -> bool { - (*self).val < other.val - } - fn le<'a>(&self, other: &'a LVal<'self>) -> bool { - (*self).val <= other.val - } - fn gt<'a>(&self, other: &'a LVal<'self>) -> bool { - (*self).val > other.val - } - fn ge<'a>(&self, other: &'a LVal<'self>) -> bool { - (*self).val >= other.val - } - } -} - -// Local Variables: -// mode: rust; -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: diff --git a/src/libstd/std.rc b/src/libstd/std.rc index d29791449b6..72f06f0befa 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -63,18 +63,12 @@ pub mod flatpipes; pub mod bitv; pub mod deque; -#[cfg(not(stage0))] pub mod fun_treemap; pub mod list; pub mod priority_queue; pub mod rope; pub mod smallintmap; -#[cfg(stage0)] -#[path="sort_stage0.rs"] -pub mod sort; - -#[cfg(not(stage0))] pub mod sort; pub mod dlist; diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index e4026d7306f..93f8d06ee08 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -105,45 +105,21 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> { } /// Visit all key-value pairs in order - #[cfg(stage0)] - fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) { - each(&self.root, f); - } - /// Visit all key-value pairs in order - #[cfg(not(stage0))] fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { each(&self.root, f) } /// Visit all keys in order - #[cfg(stage0)] - fn each_key(&self, f: &fn(&K) -> bool) { - self.each(|k, _| f(k)) - } - /// Visit all keys in order - #[cfg(not(stage0))] fn each_key(&self, f: &fn(&K) -> bool) -> bool { self.each(|k, _| f(k)) } /// Visit all values in order - #[cfg(stage0)] - fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) { - self.each(|_, v| f(v)) - } - /// Visit all values in order - #[cfg(not(stage0))] fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool { self.each(|_, v| f(v)) } /// Iterate over the map and mutate the contained values - #[cfg(stage0)] - fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) { - mutate_values(&mut self.root, f); - } - /// Iterate over the map and mutate the contained values - #[cfg(not(stage0))] fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool { mutate_values(&mut self.root, f) } @@ -201,33 +177,6 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> { } } -#[cfg(stage0)] -pub impl<K: TotalOrd, V> TreeMap<K, V> { - /// Create an empty TreeMap - fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} } - - /// Visit all key-value pairs in reverse order - fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) { - each_reverse(&self.root, f); - } - - /// Visit all keys in reverse order - fn each_key_reverse(&self, f: &fn(&K) -> bool) { - self.each_reverse(|k, _| f(k)) - } - - /// Visit all values in reverse order - fn each_value_reverse(&self, f: &fn(&V) -> bool) { - self.each_reverse(|_, v| f(v)) - } - - /// Get a lazy iterator over the key-value pairs in the map. - /// Requires that it be frozen (immutable). - fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> { - TreeMapIterator{stack: ~[], node: &self.root} - } -} -#[cfg(not(stage0))] pub impl<K: TotalOrd, V> TreeMap<K, V> { /// Create an empty TreeMap fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} } @@ -297,11 +246,6 @@ pub struct TreeSet<T> { impl<T: TotalOrd> BaseIter<T> for TreeSet<T> { /// Visit all values in order #[inline(always)] - #[cfg(stage0)] - fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } - /// Visit all values in order - #[inline(always)] - #[cfg(not(stage0))] fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } #[inline(always)] fn size_hint(&self) -> Option<uint> { Some(self.len()) } @@ -309,13 +253,6 @@ impl<T: TotalOrd> BaseIter<T> for TreeSet<T> { impl<T: TotalOrd> ReverseIter<T> for TreeSet<T> { /// Visit all values in reverse order - #[cfg(stage0)] - #[inline(always)] - fn each_reverse(&self, f: &fn(&T) -> bool) { - self.map.each_key_reverse(f) - } - /// Visit all values in reverse order - #[cfg(not(stage0))] #[inline(always)] fn each_reverse(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key_reverse(f) @@ -424,37 +361,6 @@ impl<T: TotalOrd> Set<T> for TreeSet<T> { } /// Visit the values (in-order) representing the difference - #[cfg(stage0)] - fn difference(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) { - let mut x = self.iter(); - let mut y = other.iter(); - - let mut a = x.next(); - let mut b = y.next(); - - while a.is_some() { - if b.is_none() { - return do a.while_some() |a1| { - if f(a1) { x.next() } else { None } - } - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - let cmp = a1.cmp(b1); - - if cmp == Less { - if !f(a1) { return } - a = x.next(); - } else { - if cmp == Equal { a = x.next() } - b = y.next(); - } - } - } - /// Visit the values (in-order) representing the difference - #[cfg(not(stage0))] fn difference(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) -> bool { let mut x = self.iter(); let mut y = other.iter(); @@ -484,45 +390,6 @@ impl<T: TotalOrd> Set<T> for TreeSet<T> { } /// Visit the values (in-order) representing the symmetric difference - #[cfg(stage0)] - fn symmetric_difference(&self, other: &TreeSet<T>, - f: &fn(&T) -> bool) { - let mut x = self.iter(); - let mut y = other.iter(); - - let mut a = x.next(); - let mut b = y.next(); - - while a.is_some() { - if b.is_none() { - return do a.while_some() |a1| { - if f(a1) { x.next() } else { None } - } - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - let cmp = a1.cmp(b1); - - if cmp == Less { - if !f(a1) { return } - a = x.next(); - } else { - if cmp == Greater { - if !f(b1) { return } - } else { - a = x.next(); - } - b = y.next(); - } - } - do b.while_some |b1| { - if f(b1) { y.next() } else { None } - } - } - /// Visit the values (in-order) representing the symmetric difference - #[cfg(not(stage0))] fn symmetric_difference(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) -> bool { let mut x = self.iter(); @@ -557,32 +424,6 @@ impl<T: TotalOrd> Set<T> for TreeSet<T> { } /// Visit the values (in-order) representing the intersection - #[cfg(stage0)] - fn intersection(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) { - let mut x = self.iter(); - let mut y = other.iter(); - - let mut a = x.next(); - let mut b = y.next(); - - while a.is_some() && b.is_some() { - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - let cmp = a1.cmp(b1); - - if cmp == Less { - a = x.next(); - } else { - if cmp == Equal { - if !f(a1) { return } - } - b = y.next(); - } - } - } - /// Visit the values (in-order) representing the intersection - #[cfg(not(stage0))] fn intersection(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) -> bool { let mut x = self.iter(); let mut y = other.iter(); @@ -609,43 +450,6 @@ impl<T: TotalOrd> Set<T> for TreeSet<T> { } /// Visit the values (in-order) representing the union - #[cfg(stage0)] - fn union(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) { - let mut x = self.iter(); - let mut y = other.iter(); - - let mut a = x.next(); - let mut b = y.next(); - - while a.is_some() { - if b.is_none() { - return do a.while_some() |a1| { - if f(a1) { x.next() } else { None } - } - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - let cmp = a1.cmp(b1); - - if cmp == Greater { - if !f(b1) { return } - b = y.next(); - } else { - if !f(a1) { return } - if cmp == Equal { - b = y.next(); - } - a = x.next(); - } - } - do b.while_some |b1| { - if f(b1) { y.next() } else { None } - } - } - /// Visit the values (in-order) representing the union - #[cfg(not(stage0))] fn union(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) -> bool { let mut x = self.iter(); let mut y = other.iter(); @@ -713,24 +517,12 @@ pub impl<K: TotalOrd, V> TreeNode<K, V> { } } -#[cfg(stage0)] -fn each<'r, K: TotalOrd, V>(_: &'r Option<~TreeNode<K, V>>, - _: &fn(&'r K, &'r V) -> bool) -> bool { - fail!("don't use me in stage0!") -} -#[cfg(not(stage0))] fn each<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode<K, V>>, f: &fn(&'r K, &'r V) -> bool) -> bool { node.each(|x| each(&x.left, f) && f(&x.key, &x.value) && each(&x.right, f)) } -#[cfg(stage0)] -fn each_reverse<'r, K: TotalOrd, V>(_: &'r Option<~TreeNode<K, V>>, - _: &fn(&'r K, &'r V) -> bool) -> bool { - fail!("don't use me in stage0!") -} -#[cfg(not(stage0))] fn each_reverse<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode<K, V>>, f: &fn(&'r K, &'r V) -> bool) -> bool { node.each(|x| each_reverse(&x.right, f) && f(&x.key, &x.value) && diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index 3889650d012..ee57bf2f3a1 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -97,17 +97,6 @@ struct WorkKey { name: ~str } -#[cfg(stage0)] -impl to_bytes::IterBytes for WorkKey { - #[inline(always)] - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { - let mut flag = true; - self.kind.iter_bytes(lsb0, |bytes| {flag = f(bytes); flag}); - if !flag { return; } - self.name.iter_bytes(lsb0, f); - } -} -#[cfg(not(stage0))] impl to_bytes::IterBytes for WorkKey { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { |
