11use crate :: mem:: { MaybeUninit , SizedTypeProperties } ;
2- use crate :: { cmp , ptr} ;
2+ use crate :: ptr;
33
44type BufType = [ usize ; 32 ] ;
55
@@ -11,7 +11,7 @@ type BufType = [usize; 32];
1111///
1212/// The specified range must be valid for reading and writing.
1313#[ inline]
14- pub ( super ) unsafe fn ptr_rotate < T > ( left : usize , mid : * mut T , right : usize ) {
14+ pub ( super ) const unsafe fn ptr_rotate < T > ( left : usize , mid : * mut T , right : usize ) {
1515 if T :: IS_ZST {
1616 return ;
1717 }
@@ -21,7 +21,8 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
2121 }
2222 // `T` is not a zero-sized type, so it's okay to divide by its size.
2323 if !cfg ! ( feature = "optimize_for_size" )
24- && cmp:: min ( left, right) <= size_of :: < BufType > ( ) / size_of :: < T > ( )
24+ // FIXME(const-hack): Use cmp::min when available in const
25+ && const_min ( left, right) <= size_of :: < BufType > ( ) / size_of :: < T > ( )
2526 {
2627 // SAFETY: guaranteed by the caller
2728 unsafe { ptr_rotate_memmove ( left, mid, right) } ;
@@ -45,7 +46,7 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
4546///
4647/// The specified range must be valid for reading and writing.
4748#[ inline]
48- unsafe fn ptr_rotate_memmove < T > ( left : usize , mid : * mut T , right : usize ) {
49+ const unsafe fn ptr_rotate_memmove < T > ( left : usize , mid : * mut T , right : usize ) {
4950 // The `[T; 0]` here is to ensure this is appropriately aligned for T
5051 let mut rawarray = MaybeUninit :: < ( BufType , [ T ; 0 ] ) > :: uninit ( ) ;
5152 let buf = rawarray. as_mut_ptr ( ) as * mut T ;
@@ -117,7 +118,7 @@ unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) {
117118///
118119/// The specified range must be valid for reading and writing.
119120#[ inline]
120- unsafe fn ptr_rotate_gcd < T > ( left : usize , mid : * mut T , right : usize ) {
121+ const unsafe fn ptr_rotate_gcd < T > ( left : usize , mid : * mut T , right : usize ) {
121122 // Algorithm 2
122123 // Microbenchmarks indicate that the average performance for random shifts is better all
123124 // the way until about `left + right == 32`, but the worst case performance breaks even
@@ -175,7 +176,9 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
175176 }
176177 }
177178 // finish the chunk with more rounds
178- for start in 1 ..gcd {
179+ // FIXME(const-hack): Use `for start in 1..gcd` when available in const
180+ let mut start = 1 ;
181+ while start < gcd {
179182 // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for
180183 // reading and writing as per the function's safety contract, see [long-safety-expl]
181184 // above
@@ -201,6 +204,8 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
201204 i += right;
202205 }
203206 }
207+
208+ start += 1 ;
204209 }
205210}
206211
@@ -222,7 +227,7 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
222227///
223228/// The specified range must be valid for reading and writing.
224229#[ inline]
225- unsafe fn ptr_rotate_swap < T > ( mut left : usize , mut mid : * mut T , mut right : usize ) {
230+ const unsafe fn ptr_rotate_swap < T > ( mut left : usize , mut mid : * mut T , mut right : usize ) {
226231 loop {
227232 if left >= right {
228233 // Algorithm 3
@@ -265,3 +270,8 @@ unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize)
265270 }
266271 }
267272}
273+
274+ // FIXME(const-hack): Use cmp::min when available in const
275+ const fn const_min ( left : usize , right : usize ) -> usize {
276+ if right < left { right } else { left }
277+ }
0 commit comments