Skip to content

Commit fb61f91

Browse files
committed
Add copy bound to sort
1 parent e0a9d41 commit fb61f91

File tree

1 file changed

+52
-104
lines changed

1 file changed

+52
-104
lines changed

src/libstd/sort.rs

Lines changed: 52 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ const MIN_MERGE: uint = 64;
166166
const MIN_GALLOP: uint = 7;
167167
const INITIAL_TMP_STORAGE: uint = 128;
168168

169-
pub fn tim_sort<T: Ord>(array: &[mut T]) {
169+
pub fn tim_sort<T: Copy Ord>(array: &[mut T]) {
170170
let size = array.len();
171171
if size < 2 {
172172
return;
@@ -210,7 +210,7 @@ pub fn tim_sort<T: Ord>(array: &[mut T]) {
210210
fn reverse_slice<T>(v: &[mut T], start: uint, end:uint) {
211211
let mut i = start;
212212
while i < end / 2 {
213-
v[i] <-> v[end - i - 1];
213+
util::swap(&mut v[i], &mut v[end - i - 1]);
214214
i += 1;
215215
}
216216
}
@@ -226,7 +226,7 @@ pure fn min_run_length(n: uint) -> uint {
226226
return n + r;
227227
}
228228

229-
fn count_run_ascending<T: Ord>(array: &[mut T]) -> uint {
229+
fn count_run_ascending<T: Copy Ord>(array: &[mut T]) -> uint {
230230
let size = array.len();
231231
assert size > 0;
232232
if size == 1 { return 1; }
@@ -246,7 +246,7 @@ fn count_run_ascending<T: Ord>(array: &[mut T]) -> uint {
246246
return run;
247247
}
248248

249-
pure fn gallop_left<T: Ord>(key: &const T, array: &[const T],
249+
pure fn gallop_left<T: Copy Ord>(key: &const T, array: &[const T],
250250
hint: uint) -> uint {
251251
let size = array.len();
252252
assert size != 0 && hint < size;
@@ -295,7 +295,7 @@ pure fn gallop_left<T: Ord>(key: &const T, array: &[const T],
295295
return ofs;
296296
}
297297

298-
pure fn gallop_right<T: Ord>(key: &const T, array: &[const T],
298+
pure fn gallop_right<T: Copy Ord>(key: &const T, array: &[const T],
299299
hint: uint) -> uint {
300300
let size = array.len();
301301
assert size != 0 && hint < size;
@@ -353,15 +353,15 @@ struct RunState {
353353

354354
struct MergeState<T> {
355355
mut min_gallop: uint,
356-
mut tmp: ~[T],
356+
//mut tmp: ~[T],
357357
mut last_hi: bool,
358358
mut last_bsort: bool,
359359
mut mergePt: uint,
360360
mut tmpPt: uint,
361361
mut array: &[mut T],
362362
runs: DVec<RunState>,
363363

364-
drop {
364+
/*drop {
365365
unsafe {
366366
let size = self.tmp.len();
367367
// Move tmp back into invalid part of array
@@ -376,15 +376,15 @@ struct MergeState<T> {
376376
}
377377
vec::raw::set_len(&mut self.tmp, 0);
378378
}
379-
}
379+
}*/
380380
}
381381

382382
fn MergeState<T>() -> MergeState<T> {
383-
let mut tmp = ~[];
384-
vec::reserve(&mut tmp, INITIAL_TMP_STORAGE);
383+
//let mut tmp = ~[];
384+
//vec::reserve(&mut tmp, INITIAL_TMP_STORAGE);
385385
MergeState {
386386
min_gallop: MIN_GALLOP,
387-
tmp: move tmp,
387+
//tmp: move tmp,
388388
last_hi: false,
389389
last_bsort: false,
390390
mergePt: 0,
@@ -394,7 +394,7 @@ fn MergeState<T>() -> MergeState<T> {
394394
}
395395
}
396396

397-
impl<T: Ord> MergeState<T> {
397+
impl<T: Copy Ord> MergeState<T> {
398398
fn binarysort(&self, array: &[mut T], start: uint) {
399399
let size = array.len();
400400
let mut start = start;
@@ -403,19 +403,16 @@ impl<T: Ord> MergeState<T> {
403403
if start == 0 { start += 1; }
404404

405405
self.last_bsort = true;
406-
unsafe { vec::raw::set_len(&mut self.tmp, 1); };
407406

408407
while start < size {
409-
unsafe {
410-
move_vec(self.tmp, 0, array, start, 1);
411-
}
408+
let pivot = array[start];
412409
let mut left = 0;
413410
let mut right = start;
414411
assert left <= right;
415412

416413
while left < right {
417414
let mid = (left + right) >> 1;
418-
if self.tmp[0] < array[mid] {
415+
if pivot < array[mid] {
419416
right = mid;
420417
} else {
421418
left = mid+1;
@@ -424,14 +421,10 @@ impl<T: Ord> MergeState<T> {
424421
assert left == right;
425422
let mut n = start-left;
426423

427-
unsafe {
428-
move_vec(array, left+1, array, left, n);
429-
}
430-
array[left] <-> self.tmp[0];
424+
copy_vec(array, left+1, array, left, n);
425+
array[left] = move pivot;
431426
start += 1;
432427
}
433-
// Forget the boxed element
434-
unsafe { vec::raw::set_len(&mut self.tmp, 0); }
435428
self.last_bsort = false;
436429
}
437430

@@ -488,13 +481,9 @@ impl<T: Ord> MergeState<T> {
488481
base2: uint, len2: uint) {
489482
assert len1 != 0 && len2 != 0 && base1+len1 == base2;
490483

491-
vec::reserve(&mut self.tmp, len1);
484+
//vec::reserve(&mut self.tmp, len1);
492485
self.last_hi = false;
493-
494-
unsafe {
495-
vec::raw::set_len(&mut self.tmp, len1);
496-
move_vec(self.tmp, 0, array, base1, len1);
497-
}
486+
let tmp = vec::to_mut(vec::slice(array, base1, base1+len1));
498487
self.tmpPt = 0;
499488
self.mergePt = base1;
500489

@@ -509,18 +498,12 @@ impl<T: Ord> MergeState<T> {
509498
self.mergePt += 1;
510499

511500
if len2 == 0 {
512-
unsafe {
513-
move_vec(array, dest, self.tmp, 0, len1);
514-
vec::raw::set_len(&mut self.tmp, 0); // Forget the elements
515-
}
501+
copy_vec(array, dest, tmp, 0, len1);
516502
return;
517503
}
518504
if len1 == 1 {
519-
unsafe {
520-
move_vec(array, dest, array, c2, len2);
521-
array[dest+len2] <-> self.tmp[c1];
522-
vec::raw::set_len(&mut self.tmp, 0); // Forget the element
523-
}
505+
copy_vec(array, dest, array, c2, len2);
506+
array[dest+len2] <-> tmp[c1];
524507
return;
525508
}
526509

@@ -532,7 +515,7 @@ impl<T: Ord> MergeState<T> {
532515

533516
loop {
534517
assert len1 > 1 && len2 != 0;
535-
if array[c2] < self.tmp[c1] {
518+
if array[c2] < tmp[c1] {
536519
array[dest] <-> array[c2];
537520
dest += 1; c2 += 1; len2 -= 1;
538521
self.mergePt += 1;
@@ -541,7 +524,7 @@ impl<T: Ord> MergeState<T> {
541524
break_outer = true;
542525
}
543526
} else {
544-
array[dest] <-> self.tmp[c1];
527+
array[dest] <-> tmp[c1];
545528
dest += 1; c1 += 1; len1 -= 1;
546529
self.mergePt += 1;
547530
self.tmpPt += 1;
@@ -560,13 +543,11 @@ impl<T: Ord> MergeState<T> {
560543
loop {
561544
assert len1 > 1 && len2 != 0;
562545

563-
//let tmp_view = vec::const_view(self.tmp, c1, c1+len1);
546+
//let tmp_view = vec::const_view(tmp, c1, c1+len1);
564547
count1 = gallop_right(&const array[c2],
565-
vec::const_view(self.tmp, c1, c1+len1), 0);
548+
vec::const_view(tmp, c1, c1+len1), 0);
566549
if count1 != 0 {
567-
unsafe {
568-
move_vec(array, dest, self.tmp, c1, count1);
569-
}
550+
copy_vec(array, dest, tmp, c1, count1);
570551
dest += count1; c1 += count1; len1 -= count1;
571552
self.mergePt += count1; self.tmpPt += count1;
572553
if len1 <= 1 { break_outer = true; break; }
@@ -577,16 +558,14 @@ impl<T: Ord> MergeState<T> {
577558
if len2 == 0 { break_outer = true; break; }
578559

579560
let tmp_view = vec::const_view(array, c2, c2+len2);
580-
count2 = gallop_left(&const self.tmp[c1], tmp_view, 0);
561+
count2 = gallop_left(&const tmp[c1], tmp_view, 0);
581562
if count2 != 0 {
582-
unsafe {
583-
move_vec(array, dest, array, c2, count2);
584-
}
563+
copy_vec(array, dest, array, c2, count2);
585564
dest += count2; c2 += count2; len2 -= count2;
586565
self.mergePt += count2;
587566
if len2 == 0 { break_outer = true; break; }
588567
}
589-
array[dest] <-> self.tmp[c1];
568+
array[dest] <-> tmp[c1];
590569
dest += 1; c1 += 1; len1 -= 1;
591570
self.mergePt += 1; self.tmpPt += 1;
592571
if len1 == 1 { break_outer = true; break; }
@@ -603,34 +582,25 @@ impl<T: Ord> MergeState<T> {
603582

604583
if len1 == 1 {
605584
assert len2 > 0;
606-
unsafe {
607-
move_vec(array, dest, array, c2, len2);
608-
}
609-
array[dest+len2] <-> self.tmp[c1];
585+
copy_vec(array, dest, array, c2, len2);
586+
array[dest+len2] <-> tmp[c1];
610587
} else if len1 == 0 {
611588
fail ~"Comparison violates its contract!";
612589
} else {
613590
assert len2 == 0;
614591
assert len1 > 1;
615-
unsafe {
616-
move_vec(array, dest, self.tmp, c1, len1);
617-
}
592+
copy_vec(array, dest, tmp, c1, len1);
618593
}
619594
self.tmpPt = 0;
620-
unsafe { vec::raw::set_len(&mut self.tmp, 0); }
621595
}
622596
623597
fn merge_hi(&self, array: &[mut T], base1: uint, len1: uint,
624598
base2: uint, len2: uint) {
625599
assert len1 != 1 && len2 != 0 && base1 + len1 == base2;
626600
627-
vec::reserve(&mut self.tmp, len2);
628601
self.last_hi = true;
629602
630-
unsafe {
631-
vec::raw::set_len(&mut self.tmp, len2);
632-
move_vec(self.tmp, 0, array, base2, len2);
633-
}
603+
let tmp = vec::to_mut(vec::slice(array, base2, base2+len2));
634604
635605
let mut c1 = base1 + len1 - 1;
636606
let mut c2 = len2 - 1;
@@ -645,20 +615,14 @@ impl<T: Ord> MergeState<T> {
645615
dest -= 1; c1 -= 1; len1 -= 1;
646616
647617
if len1 == 0 {
648-
unsafe {
649-
move_vec(array, dest-(len2-1), self.tmp, 0, len2);
650-
vec::raw::set_len(&mut self.tmp, 0); // Forget the elements
651-
}
618+
copy_vec(array, dest-(len2-1), tmp, 0, len2);
652619
return;
653620
}
654621
if len2 == 1 {
655622
dest -= len1;
656623
c1 -= len1;
657-
unsafe {
658-
move_vec(array, dest+1, array, c1+1, len1);
659-
array[dest] <-> self.tmp[c2];
660-
vec::raw::set_len(&mut self.tmp, 0); // Forget the element
661-
}
624+
copy_vec(array, dest+1, array, c1+1, len1);
625+
array[dest] <-> tmp[c2];
662626
return;
663627
}
664628
@@ -670,7 +634,7 @@ impl<T: Ord> MergeState<T> {
670634
671635
loop {
672636
assert len1 != 0 && len2 > 1;
673-
if self.tmp[c2] < array[c1] {
637+
if tmp[c2] < array[c1] {
674638
array[dest] <-> array[c1];
675639
dest -= 1; c1 -= 1; len1 -= 1;
676640
self.mergePt -= 1;
@@ -679,7 +643,7 @@ impl<T: Ord> MergeState<T> {
679643
break_outer = true;
680644
}
681645
} else {
682-
array[dest] <-> self.tmp[c2];
646+
array[dest] <-> tmp[c2];
683647
dest -= 1; c2 -= 1; len2 -= 1;
684648
self.mergePt -= 1; self.tmpPt -= 1;
685649
count2 += 1; count1 = 0;
@@ -699,31 +663,27 @@ impl<T: Ord> MergeState<T> {
699663
700664
let tmp_view = vec::mut_view(array, base1, base1+len1);
701665
count1 = len1 - gallop_right(
702-
&const self.tmp[c2], tmp_view, len1-1);
666+
&const tmp[c2], tmp_view, len1-1);
703667
704668
if count1 != 0 {
705669
dest -= count1; c1 -= count1; len1 -= count1;
706670
self.mergePt -= count1;
707-
unsafe {
708-
move_vec(array, dest+1, array, c1+1, count1);
709-
}
671+
copy_vec(array, dest+1, array, c1+1, count1);
710672
if len1 == 0 { break_outer = true; break; }
711673
}
712674
713-
array[dest] <-> self.tmp[c2];
675+
array[dest] <-> tmp[c2];
714676
dest -= 1; c2 -= 1; len2 -= 1;
715677
self.mergePt -= 1; self.tmpPt -= 1;
716678
if len2 == 1 { break_outer = true; break; }
717679
718-
//let tmp_view = vec::mut_view(self.tmp, 0, len2);
680+
//let tmp_view = vec::mut_view(tmp, 0, len2);
719681
let count2 = len2 - gallop_left(&const array[c1],
720-
vec::mut_view(self.tmp, 0, len2), len2-1);
682+
vec::mut_view(tmp, 0, len2), len2-1);
721683
if count2 != 0 {
722684
dest -= count2; c2 -= count2; len2 -= count2;
723685
self.mergePt -= count2; self.tmpPt -= count2;
724-
unsafe {
725-
move_vec(array, dest+1, self.tmp, c2+1, count2);
726-
}
686+
copy_vec(array, dest+1, tmp, c2+1, count2);
727687
if len2 <= 1 { break_outer = true; break; }
728688
}
729689
array[dest] <-> array[c1];
@@ -746,21 +706,16 @@ impl<T: Ord> MergeState<T> {
746706
assert len1 > 0;
747707
dest -= len1;
748708
c1 -= len1;
749-
unsafe {
750-
move_vec(array, dest+1, array, c1+1, len1);
751-
}
752-
array[dest] <-> self.tmp[c2];
709+
copy_vec(array, dest+1, array, c1+1, len1);
710+
array[dest] <-> tmp[c2];
753711
} else if len2 == 0 {
754712
fail ~"Comparison violates its contract!";
755713
} else {
756714
assert len1 == 0;
757715
assert len2 != 0;
758-
unsafe {
759-
move_vec(array, dest-(len2-1), self.tmp, 0, len2);
760-
}
716+
copy_vec(array, dest-(len2-1), tmp, 0, len2);
761717
}
762718
self.tmpPt = 0;
763-
unsafe { vec::raw::set_len(&mut self.tmp, 0); }
764719
}
765720

766721
fn merge_collapse(&self, array: &[mut T]) {
@@ -796,21 +751,14 @@ impl<T: Ord> MergeState<T> {
796751
}
797752
}
798753

799-
// Moves elements to from dest to from
800-
// Unsafe as it makes the from parameter invalid between s2 and s2+len
801754
#[inline(always)]
802-
unsafe fn move_vec<T>(dest: &[mut T], s1: uint,
755+
fn copy_vec<T: Copy>(dest: &[mut T], s1: uint,
803756
from: &[const T], s2: uint, len: uint) {
804757
assert s1+len <= dest.len() && s2+len <= from.len();
805-
806-
do vec::as_mut_buf(dest) |p, _len| {
807-
let destPtr = ptr::mut_offset(p, s1);
808-
809-
do vec::as_const_buf(from) |p, _len| {
810-
let fromPtr = ptr::const_offset(p, s2);
811-
812-
ptr::memmove(destPtr, fromPtr, len);
813-
}
758+
759+
let slice = vec::slice(from, s2, s2+len);
760+
for slice.eachi |i, v| {
761+
dest[s1+i] = *v;
814762
}
815763
}
816764

0 commit comments

Comments
 (0)