1
1
use crate :: mem:: { MaybeUninit , SizedTypeProperties } ;
2
- use crate :: { cmp , ptr} ;
2
+ use crate :: ptr;
3
3
4
4
type BufType = [ usize ; 32 ] ;
5
5
@@ -11,7 +11,7 @@ type BufType = [usize; 32];
11
11
///
12
12
/// The specified range must be valid for reading and writing.
13
13
#[ 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 ) {
15
15
if T :: IS_ZST {
16
16
return ;
17
17
}
@@ -21,7 +21,8 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
21
21
}
22
22
// `T` is not a zero-sized type, so it's okay to divide by its size.
23
23
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 > ( )
25
26
{
26
27
// SAFETY: guaranteed by the caller
27
28
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) {
45
46
///
46
47
/// The specified range must be valid for reading and writing.
47
48
#[ 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 ) {
49
50
// The `[T; 0]` here is to ensure this is appropriately aligned for T
50
51
let mut rawarray = MaybeUninit :: < ( BufType , [ T ; 0 ] ) > :: uninit ( ) ;
51
52
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) {
117
118
///
118
119
/// The specified range must be valid for reading and writing.
119
120
#[ 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 ) {
121
122
// Algorithm 2
122
123
// Microbenchmarks indicate that the average performance for random shifts is better all
123
124
// 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) {
175
176
}
176
177
}
177
178
// 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 {
179
182
// SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for
180
183
// reading and writing as per the function's safety contract, see [long-safety-expl]
181
184
// above
@@ -201,6 +204,8 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
201
204
i += right;
202
205
}
203
206
}
207
+
208
+ start += 1 ;
204
209
}
205
210
}
206
211
@@ -222,7 +227,7 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
222
227
///
223
228
/// The specified range must be valid for reading and writing.
224
229
#[ 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 ) {
226
231
loop {
227
232
if left >= right {
228
233
// Algorithm 3
@@ -265,3 +270,8 @@ unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize)
265
270
}
266
271
}
267
272
}
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