@@ -532,35 +532,47 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
532
532
i += block_size as isize ;
533
533
}
534
534
535
- // Swap remaining bytes 8 at a time if x & y are properly aligned
536
- if align_of :: < T > ( ) % 8 == 0 {
537
- while i + 8 <= len as isize {
538
- let t = * ( x. offset ( i) as * mut u64 ) ;
539
- * ( x. offset ( i) as * mut u64 ) = * ( y. offset ( i) as * mut u64 ) ;
540
- * ( y. offset ( i) as * mut u64 ) = t;
541
- i += 8 ;
542
- }
543
- }
544
-
545
- // Swap remaining bytes 4 at a time if x & y are properly aligned
546
- if align_of :: < T > ( ) % 4 == 0 {
547
- while i + 4 <= len as isize {
548
- let t = * ( x. offset ( i) as * mut u32 ) ;
549
- * ( x. offset ( i) as * mut u32 ) = * ( y. offset ( i) as * mut u32 ) ;
550
- * ( y. offset ( i) as * mut u32 ) = t;
551
- i += 4 ;
552
- }
553
- }
554
535
555
536
if i < len {
556
- // Swap any remaining bytes
537
+ // Swap any remaining bytes, using aligned types to copy
538
+ // where appropriate (this information is lost by conversion
539
+ // to *mut u8, so restore it manually here)
557
540
let mut t: UnalignedBlock = uninitialized ( ) ;
558
- let t = & mut t as * mut _ as * mut u8 ;
559
-
560
541
let rem = ( len - i) as usize ;
561
- ptr:: copy_nonoverlapping ( x. offset ( i) , t, rem) ;
562
- ptr:: copy_nonoverlapping ( y. offset ( i) , x. offset ( i) , rem) ;
563
- ptr:: copy_nonoverlapping ( t, y. offset ( i) , rem) ;
542
+
543
+ if align_of :: < T > ( ) % 8 == 0 && len % 8 == 0 {
544
+ let t = & mut t as * mut _ as * mut u64 ;
545
+ let x = x. offset ( i) as * mut u64 ;
546
+ let y = y. offset ( i) as * mut u64 ;
547
+
548
+ ptr:: copy_nonoverlapping ( x, t, rem / 8 ) ;
549
+ ptr:: copy_nonoverlapping ( y, x, rem / 8 ) ;
550
+ ptr:: copy_nonoverlapping ( t, y, rem / 8 ) ;
551
+ } else if align_of :: < T > ( ) % 4 == 0 && len % 4 == 0 {
552
+ let t = & mut t as * mut _ as * mut u32 ;
553
+ let x = x. offset ( i) as * mut u32 ;
554
+ let y = y. offset ( i) as * mut u32 ;
555
+
556
+ ptr:: copy_nonoverlapping ( x, t, rem / 4 ) ;
557
+ ptr:: copy_nonoverlapping ( y, x, rem / 4 ) ;
558
+ ptr:: copy_nonoverlapping ( t, y, rem / 4 ) ;
559
+ } else if align_of :: < T > ( ) % 2 == 0 && len % 2 == 0 {
560
+ let t = & mut t as * mut _ as * mut u16 ;
561
+ let x = x. offset ( i) as * mut u16 ;
562
+ let y = y. offset ( i) as * mut u16 ;
563
+
564
+ ptr:: copy_nonoverlapping ( x, t, rem / 2 ) ;
565
+ ptr:: copy_nonoverlapping ( y, x, rem / 2 ) ;
566
+ ptr:: copy_nonoverlapping ( t, y, rem / 2 ) ;
567
+ } else {
568
+ let t = & mut t as * mut _ as * mut u8 ;
569
+ let x = x. offset ( i) ;
570
+ let y = y. offset ( i) ;
571
+
572
+ ptr:: copy_nonoverlapping ( x, t, rem) ;
573
+ ptr:: copy_nonoverlapping ( y, x, rem) ;
574
+ ptr:: copy_nonoverlapping ( t, y, rem) ;
575
+ }
564
576
}
565
577
}
566
578
}
0 commit comments