33//! as required by the query system.
44
55use rustc_hash:: { FxHashMap , FxHashSet } ;
6- use smallvec:: SmallVec ;
76use std:: {
8- borrow:: Borrow ,
7+ borrow:: { Borrow , BorrowMut } ,
98 collections:: hash_map:: Entry ,
109 hash:: Hash ,
1110 iter:: { Product , Sum } ,
@@ -14,7 +13,7 @@ use std::{
1413
1514use crate :: {
1615 fingerprint:: Fingerprint ,
17- stable_hasher:: { HashStable , StableHasher , StableOrd , ToStableHashKey } ,
16+ stable_hasher:: { HashStable , StableCompare , StableHasher , ToStableHashKey } ,
1817} ;
1918
2019/// `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> {
134133 }
135134}
136135
137- impl < T : Ord , I : Iterator < Item = T > > UnordItems < T , I > {
136+ impl < T , I : Iterator < Item = T > > UnordItems < T , I > {
137+ #[ inline]
138138 pub fn into_sorted < HCX > ( self , hcx : & HCX ) -> Vec < T >
139139 where
140140 T : ToStableHashKey < HCX > ,
141141 {
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 )
145143 }
146144
147145 #[ inline]
148146 pub fn into_sorted_stable_ord ( self ) -> Vec < T >
149147 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 ,
151158 {
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+ }
157177 }
178+
158179 items
159180 }
160181
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
162184 where
163- T : ToStableHashKey < HCX > ,
185+ K : StableCompare ,
186+ P : for < ' a > Fn ( & ' a T ) -> & ' a K ,
187+ C : FromIterator < T > + BorrowMut < [ T ] > ,
164188 {
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+
167208 items
168209 }
169210}
@@ -268,16 +309,30 @@ impl<V: Eq + Hash> UnordSet<V> {
268309 }
269310
270311 /// 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
272313 /// `into_sorted` because it does not need to transform keys to their
273314 /// `ToStableHashKey` equivalent.
274315 #[ inline]
275- pub fn to_sorted_stable_ord ( & self ) -> Vec < V >
316+ pub fn to_sorted_stable_ord ( & self ) -> Vec < & V >
276317 where
277- V : Ord + StableOrd + Clone ,
318+ V : StableCompare ,
278319 {
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) ;
281336 items
282337 }
283338
@@ -483,16 +538,16 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
483538 to_sorted_vec ( hcx, self . inner . iter ( ) , cache_sort_key, |& ( k, _) | k)
484539 }
485540
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 `).
487542 /// This method can be much more efficient than `into_sorted` because it does not need
488543 /// to transform keys to their `ToStableHashKey` equivalent.
489544 #[ inline]
490- pub fn to_sorted_stable_ord ( & self ) -> Vec < ( K , & V ) >
545+ pub fn to_sorted_stable_ord ( & self ) -> Vec < ( & K , & V ) >
491546 where
492- K : Ord + StableOrd + Copy ,
547+ K : StableCompare ,
493548 {
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 ) ) ;
496551 items
497552 }
498553
@@ -510,6 +565,19 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
510565 to_sorted_vec ( hcx, self . inner . into_iter ( ) , cache_sort_key, |( k, _) | k)
511566 }
512567
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+
513581 /// Returns the values of this map in stable sort order (as defined by K's
514582 /// `ToStableHashKey` implementation).
515583 ///
0 commit comments