3
3
//! as required by the query system.
4
4
5
5
use rustc_hash:: { FxHashMap , FxHashSet } ;
6
- use smallvec:: SmallVec ;
7
6
use std:: {
8
- borrow:: Borrow ,
7
+ borrow:: { Borrow , BorrowMut } ,
9
8
collections:: hash_map:: Entry ,
10
9
hash:: Hash ,
11
10
iter:: { Product , Sum } ,
@@ -14,7 +13,7 @@ use std::{
14
13
15
14
use crate :: {
16
15
fingerprint:: Fingerprint ,
17
- stable_hasher:: { HashStable , StableHasher , StableOrd , ToStableHashKey } ,
16
+ stable_hasher:: { HashStable , StableCompare , StableHasher , ToStableHashKey } ,
18
17
} ;
19
18
20
19
/// `UnordItems` is the order-less version of `Iterator`. It only contains methods
@@ -134,36 +133,78 @@ impl<'a, T: Copy + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
134
133
}
135
134
}
136
135
137
- impl < T : Ord , I : Iterator < Item = T > > UnordItems < T , I > {
136
+ impl < T , I : Iterator < Item = T > > UnordItems < T , I > {
137
+ #[ inline]
138
138
pub fn into_sorted < HCX > ( self , hcx : & HCX ) -> Vec < T >
139
139
where
140
140
T : ToStableHashKey < HCX > ,
141
141
{
142
- let mut items: Vec < T > = self . 0 . collect ( ) ;
143
- items. sort_by_cached_key ( |x| x. to_stable_hash_key ( hcx) ) ;
144
- items
142
+ self . collect_sorted ( hcx, true )
145
143
}
146
144
147
145
#[ inline]
148
146
pub fn into_sorted_stable_ord ( self ) -> Vec < T >
149
147
where
150
- T : Ord + StableOrd ,
148
+ T : StableCompare ,
149
+ {
150
+ self . collect_stable_ord_by_key ( |x| x)
151
+ }
152
+
153
+ #[ inline]
154
+ pub fn into_sorted_stable_ord_by_key < K , C > ( self , project_to_key : C ) -> Vec < T >
155
+ where
156
+ K : StableCompare ,
157
+ C : for < ' a > Fn ( & ' a T ) -> & ' a K ,
151
158
{
152
- let mut items: Vec < T > = self . 0 . collect ( ) ;
153
- if !T :: CAN_USE_UNSTABLE_SORT {
154
- items. sort ( ) ;
155
- } else {
156
- items. sort_unstable ( )
159
+ self . collect_stable_ord_by_key ( project_to_key)
160
+ }
161
+
162
+ #[ inline]
163
+ pub fn collect_sorted < HCX , C > ( self , hcx : & HCX , cache_sort_key : bool ) -> C
164
+ where
165
+ T : ToStableHashKey < HCX > ,
166
+ C : FromIterator < T > + BorrowMut < [ T ] > ,
167
+ {
168
+ let mut items: C = self . 0 . collect ( ) ;
169
+
170
+ let slice = items. borrow_mut ( ) ;
171
+ if slice. len ( ) > 1 {
172
+ if cache_sort_key {
173
+ slice. sort_by_cached_key ( |x| x. to_stable_hash_key ( hcx) ) ;
174
+ } else {
175
+ slice. sort_by_key ( |x| x. to_stable_hash_key ( hcx) ) ;
176
+ }
157
177
}
178
+
158
179
items
159
180
}
160
181
161
- pub fn into_sorted_small_vec < HCX , const LEN : usize > ( self , hcx : & HCX ) -> SmallVec < [ T ; LEN ] >
182
+ #[ inline]
183
+ pub fn collect_stable_ord_by_key < K , C , P > ( self , project_to_key : P ) -> C
162
184
where
163
- T : ToStableHashKey < HCX > ,
185
+ K : StableCompare ,
186
+ P : for < ' a > Fn ( & ' a T ) -> & ' a K ,
187
+ C : FromIterator < T > + BorrowMut < [ T ] > ,
164
188
{
165
- let mut items: SmallVec < [ T ; LEN ] > = self . 0 . collect ( ) ;
166
- items. sort_by_cached_key ( |x| x. to_stable_hash_key ( hcx) ) ;
189
+ let mut items: C = self . 0 . collect ( ) ;
190
+
191
+ let slice = items. borrow_mut ( ) ;
192
+ if slice. len ( ) > 1 {
193
+ if !K :: CAN_USE_UNSTABLE_SORT {
194
+ slice. sort_by ( |a, b| {
195
+ let a_key = project_to_key ( a) ;
196
+ let b_key = project_to_key ( b) ;
197
+ a_key. stable_cmp ( b_key)
198
+ } ) ;
199
+ } else {
200
+ slice. sort_unstable_by ( |a, b| {
201
+ let a_key = project_to_key ( a) ;
202
+ let b_key = project_to_key ( b) ;
203
+ a_key. stable_cmp ( b_key)
204
+ } ) ;
205
+ }
206
+ }
207
+
167
208
items
168
209
}
169
210
}
@@ -268,16 +309,30 @@ impl<V: Eq + Hash> UnordSet<V> {
268
309
}
269
310
270
311
/// Returns the items of this set in stable sort order (as defined by
271
- /// `StableOrd `). This method is much more efficient than
312
+ /// `StableCompare `). This method is much more efficient than
272
313
/// `into_sorted` because it does not need to transform keys to their
273
314
/// `ToStableHashKey` equivalent.
274
315
#[ inline]
275
- pub fn to_sorted_stable_ord ( & self ) -> Vec < V >
316
+ pub fn to_sorted_stable_ord ( & self ) -> Vec < & V >
276
317
where
277
- V : Ord + StableOrd + Clone ,
318
+ V : StableCompare ,
278
319
{
279
- let mut items: Vec < V > = self . inner . iter ( ) . cloned ( ) . collect ( ) ;
280
- items. sort_unstable ( ) ;
320
+ let mut items: Vec < & V > = self . inner . iter ( ) . collect ( ) ;
321
+ items. sort_unstable_by ( |a, b| a. stable_cmp ( * b) ) ;
322
+ items
323
+ }
324
+
325
+ /// Returns the items of this set in stable sort order (as defined by
326
+ /// `StableCompare`). This method is much more efficient than
327
+ /// `into_sorted` because it does not need to transform keys to their
328
+ /// `ToStableHashKey` equivalent.
329
+ #[ inline]
330
+ pub fn into_sorted_stable_ord ( self ) -> Vec < V >
331
+ where
332
+ V : StableCompare ,
333
+ {
334
+ let mut items: Vec < V > = self . inner . into_iter ( ) . collect ( ) ;
335
+ items. sort_unstable_by ( V :: stable_cmp) ;
281
336
items
282
337
}
283
338
@@ -483,16 +538,16 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
483
538
to_sorted_vec ( hcx, self . inner . iter ( ) , cache_sort_key, |& ( k, _) | k)
484
539
}
485
540
486
- /// Returns the entries of this map in stable sort order (as defined by `StableOrd `).
541
+ /// Returns the entries of this map in stable sort order (as defined by `StableCompare `).
487
542
/// This method can be much more efficient than `into_sorted` because it does not need
488
543
/// to transform keys to their `ToStableHashKey` equivalent.
489
544
#[ inline]
490
- pub fn to_sorted_stable_ord ( & self ) -> Vec < ( K , & V ) >
545
+ pub fn to_sorted_stable_ord ( & self ) -> Vec < ( & K , & V ) >
491
546
where
492
- K : Ord + StableOrd + Copy ,
547
+ K : StableCompare ,
493
548
{
494
- let mut items: Vec < ( K , & V ) > = self . inner . iter ( ) . map ( | ( & k , v ) | ( k , v ) ) . collect ( ) ;
495
- items. sort_unstable_by_key ( | & ( k , _) | k ) ;
549
+ let mut items: Vec < _ > = self . inner . iter ( ) . collect ( ) ;
550
+ items. sort_unstable_by ( | ( a , _) , ( b , _ ) | a . stable_cmp ( * b ) ) ;
496
551
items
497
552
}
498
553
@@ -510,6 +565,19 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
510
565
to_sorted_vec ( hcx, self . inner . into_iter ( ) , cache_sort_key, |( k, _) | k)
511
566
}
512
567
568
+ /// Returns the entries of this map in stable sort order (as defined by `StableCompare`).
569
+ /// This method can be much more efficient than `into_sorted` because it does not need
570
+ /// to transform keys to their `ToStableHashKey` equivalent.
571
+ #[ inline]
572
+ pub fn into_sorted_stable_ord ( self ) -> Vec < ( K , V ) >
573
+ where
574
+ K : StableCompare ,
575
+ {
576
+ let mut items: Vec < ( K , V ) > = self . inner . into_iter ( ) . collect ( ) ;
577
+ items. sort_unstable_by ( |a, b| a. 0 . stable_cmp ( & b. 0 ) ) ;
578
+ items
579
+ }
580
+
513
581
/// Returns the values of this map in stable sort order (as defined by K's
514
582
/// `ToStableHashKey` implementation).
515
583
///
0 commit comments