Remove reliance on const_trait in sort implementations · model-checking/verify-rust-std@489dfce (original) (raw)
`@@ -93,10 +93,62 @@ impl UnstableSmallSortTypeImpl for T {
`
93
93
`impl<T: FreezeMarker> UnstableSmallSortTypeImpl for T {
`
94
94
`#[inline(always)]
`
95
95
`fn small_sort_threshold() -> usize {
`
96
``
`-
match const { choose_unstable_small_sort::() } {
`
97
``
`-
UnstableSmallSort::Fallback => SMALL_SORT_FALLBACK_THRESHOLD,
`
98
``
`-
UnstableSmallSort::General => SMALL_SORT_GENERAL_THRESHOLD,
`
99
``
`-
UnstableSmallSort::Network => SMALL_SORT_NETWORK_THRESHOLD,
`
``
96
`+
::small_sort_threshold()
`
``
97
`+
}
`
``
98
+
``
99
`+
#[inline(always)]
`
``
100
`+
fn small_sort(v: &mut [T], is_less: &mut F)
`
``
101
`+
where
`
``
102
`+
F: FnMut(&T, &T) -> bool,
`
``
103
`+
{
`
``
104
`+
::small_sort(v, is_less);
`
``
105
`+
}
`
``
106
`+
}
`
``
107
+
``
108
`+
/// FIXME(effects) use original ipnsort approach with choose_unstable_small_sort,
`
``
109
`+
/// as found here https://github.com/Voultapher/sort-research-rs/blob/438fad5d0495f65d4b72aa87f0b62fc96611dff3/ipnsort/src/smallsort.rs#L83C10-L83C36.
`
``
110
`+
pub(crate) trait UnstableSmallSortFreezeTypeImpl: Sized + FreezeMarker {
`
``
111
`+
fn small_sort_threshold() -> usize;
`
``
112
+
``
113
`+
fn small_sort<F: FnMut(&Self, &Self) -> bool>(v: &mut [Self], is_less: &mut F);
`
``
114
`+
}
`
``
115
+
``
116
`+
impl<T: FreezeMarker> UnstableSmallSortFreezeTypeImpl for T {
`
``
117
`+
#[inline(always)]
`
``
118
`+
default fn small_sort_threshold() -> usize {
`
``
119
`+
if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
`
``
120
`+
SMALL_SORT_GENERAL_THRESHOLD
`
``
121
`+
} else {
`
``
122
`+
SMALL_SORT_FALLBACK_THRESHOLD
`
``
123
`+
}
`
``
124
`+
}
`
``
125
+
``
126
`+
#[inline(always)]
`
``
127
`+
default fn small_sort(v: &mut [T], is_less: &mut F)
`
``
128
`+
where
`
``
129
`+
F: FnMut(&T, &T) -> bool,
`
``
130
`+
{
`
``
131
`+
if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
`
``
132
`+
small_sort_general(v, is_less);
`
``
133
`+
} else {
`
``
134
`+
small_sort_fallback(v, is_less);
`
``
135
`+
}
`
``
136
`+
}
`
``
137
`+
}
`
``
138
+
``
139
`+
/// SAFETY: Only used for run-time optimization heuristic.
`
``
140
`+
#[rustc_unsafe_specialization_marker]
`
``
141
`+
trait CopyMarker {}
`
``
142
+
``
143
`+
impl<T: FreezeMarker + CopyMarker> UnstableSmallSortFreezeTypeImpl for T {
`
``
144
`+
#[inline(always)]
`
``
145
`+
fn small_sort_threshold() -> usize {
`
``
146
`+
if has_efficient_in_place_swap::()
`
``
147
`+
&& (mem::size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE
`
``
148
`+
{
`
``
149
`+
SMALL_SORT_NETWORK_SCRATCH_LEN
`
``
150
`+
} else {
`
``
151
`+
SMALL_SORT_FALLBACK_THRESHOLD
`
100
152
`}
`
101
153
`}
`
102
154
``
`@@ -105,9 +157,13 @@ impl<T: FreezeMarker> UnstableSmallSortTypeImpl for T {
`
105
157
`where
`
106
158
`F: FnMut(&T, &T) -> bool,
`
107
159
`{
`
108
``
`-
// This construct is used to limit the LLVM IR generated, which saves large amounts of
`
109
``
`-
// compile-time by only instantiating the code that is needed. Idea by Frank Steffahn.
`
110
``
`-
(const { inst_unstable_small_sort::<T, F>() })(v, is_less);
`
``
160
`+
if has_efficient_in_place_swap::()
`
``
161
`+
&& (mem::size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE
`
``
162
`+
{
`
``
163
`+
small_sort_network(v, is_less);
`
``
164
`+
} else {
`
``
165
`+
small_sort_fallback(v, is_less);
`
``
166
`+
}
`
111
167
`}
`
112
168
`}
`
113
169
``
`@@ -137,37 +193,6 @@ const SMALL_SORT_NETWORK_SCRATCH_LEN: usize = SMALL_SORT_NETWORK_THRESHOLD;
`
137
193
`/// within this limit.
`
138
194
`const MAX_STACK_ARRAY_SIZE: usize = 4096;
`
139
195
``
140
``
`-
enum UnstableSmallSort {
`
141
``
`-
Fallback,
`
142
``
`-
General,
`
143
``
`-
Network,
`
144
``
`-
}
`
145
``
-
146
``
`-
const fn choose_unstable_small_sort<T: FreezeMarker>() -> UnstableSmallSort {
`
147
``
`-
if T::is_copy()
`
148
``
`-
&& has_efficient_in_place_swap::()
`
149
``
`-
&& (mem::size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE
`
150
``
`-
{
`
151
``
`-
// Heuristic for int like types.
`
152
``
`-
return UnstableSmallSort::Network;
`
153
``
`-
}
`
154
``
-
155
``
`-
if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
`
156
``
`-
return UnstableSmallSort::General;
`
157
``
`-
}
`
158
``
-
159
``
`-
UnstableSmallSort::Fallback
`
160
``
`-
}
`
161
``
-
162
``
`-
const fn inst_unstable_small_sort<T: FreezeMarker, F: FnMut(&T, &T) -> bool>()
`
163
``
`-
-> fn(&mut [T], &mut F) {
`
164
``
`-
match const { choose_unstable_small_sort::() } {
`
165
``
`-
UnstableSmallSort::Fallback => small_sort_fallback::<T, F>,
`
166
``
`-
UnstableSmallSort::General => small_sort_general::<T, F>,
`
167
``
`-
UnstableSmallSort::Network => small_sort_network::<T, F>,
`
168
``
`-
}
`
169
``
`-
}
`
170
``
-
171
196
`fn small_sort_fallback<T, F: FnMut(&T, &T) -> bool>(v: &mut [T], is_less: &mut F) {
`
172
197
`if v.len() >= 2 {
`
173
198
`insertion_sort_shift_left(v, 1, is_less);
`
`@@ -822,25 +847,3 @@ pub(crate) const fn has_efficient_in_place_swap() -> bool {
`
822
847
`// Heuristic that holds true on all tested 64-bit capable architectures.
`
823
848
` mem::size_of::() <= 8 // mem::size_of::()
`
824
849
`}
`
825
``
-
826
``
`-
/// SAFETY: Only used for run-time optimization heuristic.
`
827
``
`-
#[rustc_unsafe_specialization_marker]
`
828
``
`-
trait CopyMarker {}
`
829
``
-
830
``
`-
impl<T: Copy> CopyMarker for T {}
`
831
``
-
832
``
`-
#[const_trait]
`
833
``
`-
trait IsCopy {
`
834
``
`-
fn is_copy() -> bool;
`
835
``
`-
}
`
836
``
-
837
``
`-
impl const IsCopy for T {
`
838
``
`-
default fn is_copy() -> bool {
`
839
``
`-
false
`
840
``
`-
}
`
841
``
`-
}
`
842
``
`-
impl<T: CopyMarker> const IsCopy for T {
`
843
``
`-
fn is_copy() -> bool {
`
844
``
`-
true
`
845
``
`-
}
`
846
``
`-
}
`