about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStjepan Glavina <stjepang@gmail.com>2017-03-21 02:38:03 +0100
committerStjepan Glavina <stjepang@gmail.com>2017-03-21 20:46:20 +0100
commita718051f63308638ecf40a7570dbd18f4fc99703 (patch)
tree4a0c488b1fa8fcef586b4fc81459675435134e60
parenta18b2aa641da7c000fea9e9ac62d2da89fa034ad (diff)
downloadrust-a718051f63308638ecf40a7570dbd18f4fc99703.tar.gz
rust-a718051f63308638ecf40a7570dbd18f4fc99703.zip
Unit test heapsort
-rw-r--r--src/libcore/slice/mod.rs9
-rw-r--r--src/libcore/slice/sort.rs4
-rw-r--r--src/libcoretest/lib.rs1
-rw-r--r--src/libcoretest/slice.rs44
4 files changed, 43 insertions, 15 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 53cbdd84c3a..6f8b199f886 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -2253,6 +2253,15 @@ pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
     mem::transmute(Repr { data: p, len: len })
 }
 
+// This function is public only because there is no other way to unit test heapsort.
+#[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "0")]
+#[doc(hidden)]
+pub fn heapsort<T, F>(v: &mut [T], mut is_less: F)
+    where F: FnMut(&T, &T) -> bool
+{
+    sort::heapsort(v, &mut is_less);
+}
+
 //
 // Comparison traits
 //
diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs
index a015c8fc120..fdfba33f8a9 100644
--- a/src/libcore/slice/sort.rs
+++ b/src/libcore/slice/sort.rs
@@ -57,7 +57,7 @@ fn shift_head<T, F>(v: &mut [T], is_less: &mut F)
             ptr::copy_nonoverlapping(v.get_unchecked(1), v.get_unchecked_mut(0), 1);
 
             for i in 2..len {
-                if !is_less(&v[i], &tmp.value) {
+                if !is_less(v.get_unchecked(i), &tmp.value) {
                     break;
                 }
 
@@ -159,7 +159,7 @@ fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F)
 
 /// Sorts `v` using heapsort, which guarantees `O(n log n)` worst-case.
 #[cold]
-fn heapsort<T, F>(v: &mut [T], is_less: &mut F)
+pub fn heapsort<T, F>(v: &mut [T], is_less: &mut F)
     where F: FnMut(&T, &T) -> bool
 {
     // This binary heap respects the invariant `parent >= child`.
diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs
index 4f3b775ceb2..d92c378160d 100644
--- a/src/libcoretest/lib.rs
+++ b/src/libcoretest/lib.rs
@@ -26,6 +26,7 @@
 #![feature(raw)]
 #![feature(sip_hash_13)]
 #![feature(slice_patterns)]
+#![feature(sort_internals)]
 #![feature(sort_unstable)]
 #![feature(step_by)]
 #![feature(test)]
diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs
index b51bae4db22..89bd3be0851 100644
--- a/src/libcoretest/slice.rs
+++ b/src/libcoretest/slice.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::slice::heapsort;
 use core::result::Result::{Ok, Err};
 use rand::{Rng, XorShiftRng};
 
@@ -226,26 +227,43 @@ fn get_unchecked_mut_range() {
 #[test]
 fn sort_unstable() {
     let mut v = [0; 600];
-    let mut v1 = [0; 600];
+    let mut tmp = [0; 600];
     let mut rng = XorShiftRng::new_unseeded();
 
     for len in (2..25).chain(500..510) {
-        for &modulus in &[10, 1000] {
+        let v = &mut v[0..len];
+        let tmp = &mut tmp[0..len];
+
+        for &modulus in &[5, 10, 100, 1000] {
             for _ in 0..100 {
                 for i in 0..len {
-                    let num = rng.gen::<i32>() % modulus;
-                    v[i] = num;
-                    v1[i] = num;
+                    v[i] = rng.gen::<i32>() % modulus;
                 }
 
-                v.sort_unstable();
-                assert!(v.windows(2).all(|w| w[0] <= w[1]));
-
-                v1.sort_unstable_by(|a, b| a.cmp(b));
-                assert!(v1.windows(2).all(|w| w[0] <= w[1]));
-
-                v1.sort_unstable_by(|a, b| b.cmp(a));
-                assert!(v1.windows(2).all(|w| w[0] >= w[1]));
+                // Sort in default order.
+                tmp.copy_from_slice(v);
+                tmp.sort_unstable();
+                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
+
+                // Sort in ascending order.
+                tmp.copy_from_slice(v);
+                tmp.sort_unstable_by(|a, b| a.cmp(b));
+                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
+
+                // Sort in descending order.
+                tmp.copy_from_slice(v);
+                tmp.sort_unstable_by(|a, b| b.cmp(a));
+                assert!(tmp.windows(2).all(|w| w[0] >= w[1]));
+
+                // Test heapsort using `<` operator.
+                tmp.copy_from_slice(v);
+                heapsort(tmp, |a, b| a < b);
+                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
+
+                // Test heapsort using `>` operator.
+                tmp.copy_from_slice(v);
+                heapsort(tmp, |a, b| a > b);
+                assert!(tmp.windows(2).all(|w| w[0] >= w[1]));
             }
         }
     }