@@ -31,6 +31,7 @@ use crate::{
31
31
///
32
32
/// It's still possible to do the same thing with an `Fn` by using interior mutability,
33
33
/// but the chance of doing it accidentally is reduced.
34
+ #[ derive( Clone ) ]
34
35
pub struct UnordItems < T , I : Iterator < Item = T > > ( I ) ;
35
36
36
37
impl < T , I : Iterator < Item = T > > UnordItems < T , I > {
@@ -167,6 +168,14 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
167
168
}
168
169
}
169
170
171
+ /// A marker trait specifying that `Self` can consume `UnordItems<_>` without
172
+ /// exposing any internal ordering.
173
+ ///
174
+ /// Note: right now this is just a marker trait. It could be extended to contain
175
+ /// some useful, common methods though, like `len`, `clear`, or the various
176
+ /// kinds of `to_sorted`.
177
+ trait UnordCollection { }
178
+
170
179
/// This is a set collection type that tries very hard to not expose
171
180
/// any internal iteration. This is a useful property when trying to
172
181
/// uphold the determinism invariants imposed by the query system.
@@ -181,6 +190,8 @@ pub struct UnordSet<V: Eq + Hash> {
181
190
inner : FxHashSet < V > ,
182
191
}
183
192
193
+ impl < V : Eq + Hash > UnordCollection for UnordSet < V > { }
194
+
184
195
impl < V : Eq + Hash > Default for UnordSet < V > {
185
196
#[ inline]
186
197
fn default ( ) -> Self {
@@ -194,6 +205,11 @@ impl<V: Eq + Hash> UnordSet<V> {
194
205
Self { inner : Default :: default ( ) }
195
206
}
196
207
208
+ #[ inline]
209
+ pub fn with_capacity ( capacity : usize ) -> Self {
210
+ Self { inner : FxHashSet :: with_capacity_and_hasher ( capacity, Default :: default ( ) ) }
211
+ }
212
+
197
213
#[ inline]
198
214
pub fn len ( & self ) -> usize {
199
215
self . inner . len ( )
@@ -258,9 +274,9 @@ impl<V: Eq + Hash> UnordSet<V> {
258
274
#[ inline]
259
275
pub fn to_sorted_stable_ord ( & self ) -> Vec < V >
260
276
where
261
- V : Ord + StableOrd + Copy ,
277
+ V : Ord + StableOrd + Clone ,
262
278
{
263
- let mut items: Vec < V > = self . inner . iter ( ) . copied ( ) . collect ( ) ;
279
+ let mut items: Vec < V > = self . inner . iter ( ) . cloned ( ) . collect ( ) ;
264
280
items. sort_unstable ( ) ;
265
281
items
266
282
}
@@ -279,16 +295,28 @@ impl<V: Eq + Hash> UnordSet<V> {
279
295
to_sorted_vec ( hcx, self . inner . into_iter ( ) , cache_sort_key, |x| x)
280
296
}
281
297
282
- // We can safely extend this UnordSet from a set of unordered values because that
283
- // won't expose the internal ordering anywhere.
284
298
#[ inline]
285
- pub fn extend_unord < I : Iterator < Item = V > > ( & mut self , items : UnordItems < V , I > ) {
286
- self . inner . extend ( items . 0 )
299
+ pub fn clear ( & mut self ) {
300
+ self . inner . clear ( ) ;
287
301
}
302
+ }
303
+
304
+ pub trait ExtendUnord < T > {
305
+ /// Extend this unord collection with the given `UnordItems`.
306
+ /// This method is called `extend_unord` instead of just `extend` so it
307
+ /// does not conflict with `Extend::extend`. Otherwise there would be many
308
+ /// places where the two methods would have to be explicitly disambiguated
309
+ /// via UFCS.
310
+ fn extend_unord < I : Iterator < Item = T > > ( & mut self , items : UnordItems < T , I > ) ;
311
+ }
288
312
313
+ // Note: it is important that `C` implements `UnordCollection` in addition to
314
+ // `Extend`, otherwise this impl would leak the internal iteration order of
315
+ // `items`, e.g. when calling `some_vec.extend_unord(some_unord_items)`.
316
+ impl < C : Extend < T > + UnordCollection , T > ExtendUnord < T > for C {
289
317
#[ inline]
290
- pub fn clear ( & mut self ) {
291
- self . inner . clear ( ) ;
318
+ fn extend_unord < I : Iterator < Item = T > > ( & mut self , items : UnordItems < T , I > ) {
319
+ self . extend ( items . 0 )
292
320
}
293
321
}
294
322
@@ -312,6 +340,12 @@ impl<V: Hash + Eq> From<FxHashSet<V>> for UnordSet<V> {
312
340
}
313
341
}
314
342
343
+ impl < V : Hash + Eq , I : Iterator < Item = V > > From < UnordItems < V , I > > for UnordSet < V > {
344
+ fn from ( value : UnordItems < V , I > ) -> Self {
345
+ UnordSet { inner : FxHashSet :: from_iter ( value. 0 ) }
346
+ }
347
+ }
348
+
315
349
impl < HCX , V : Hash + Eq + HashStable < HCX > > HashStable < HCX > for UnordSet < V > {
316
350
#[ inline]
317
351
fn hash_stable ( & self , hcx : & mut HCX , hasher : & mut StableHasher ) {
@@ -333,6 +367,8 @@ pub struct UnordMap<K: Eq + Hash, V> {
333
367
inner : FxHashMap < K , V > ,
334
368
}
335
369
370
+ impl < K : Eq + Hash , V > UnordCollection for UnordMap < K , V > { }
371
+
336
372
impl < K : Eq + Hash , V > Default for UnordMap < K , V > {
337
373
#[ inline]
338
374
fn default ( ) -> Self {
@@ -362,6 +398,11 @@ impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> fo
362
398
}
363
399
364
400
impl < K : Eq + Hash , V > UnordMap < K , V > {
401
+ #[ inline]
402
+ pub fn with_capacity ( capacity : usize ) -> Self {
403
+ Self { inner : FxHashMap :: with_capacity_and_hasher ( capacity, Default :: default ( ) ) }
404
+ }
405
+
365
406
#[ inline]
366
407
pub fn len ( & self ) -> usize {
367
408
self . inner . len ( )
@@ -428,13 +469,6 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
428
469
UnordItems ( self . inner . into_iter ( ) )
429
470
}
430
471
431
- // We can safely extend this UnordMap from a set of unordered values because that
432
- // won't expose the internal ordering anywhere.
433
- #[ inline]
434
- pub fn extend < I : Iterator < Item = ( K , V ) > > ( & mut self , items : UnordItems < ( K , V ) , I > ) {
435
- self . inner . extend ( items. 0 )
436
- }
437
-
438
472
/// Returns the entries of this map in stable sort order (as defined by `ToStableHashKey`).
439
473
///
440
474
/// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
@@ -554,15 +588,10 @@ impl<V> UnordBag<V> {
554
588
pub fn into_items ( self ) -> UnordItems < V , impl Iterator < Item = V > > {
555
589
UnordItems ( self . inner . into_iter ( ) )
556
590
}
557
-
558
- // We can safely extend this UnordSet from a set of unordered values because that
559
- // won't expose the internal ordering anywhere.
560
- #[ inline]
561
- pub fn extend < I : Iterator < Item = V > > ( & mut self , items : UnordItems < V , I > ) {
562
- self . inner . extend ( items. 0 )
563
- }
564
591
}
565
592
593
+ impl < T > UnordCollection for UnordBag < T > { }
594
+
566
595
impl < T > Extend < T > for UnordBag < T > {
567
596
fn extend < I : IntoIterator < Item = T > > ( & mut self , iter : I ) {
568
597
self . inner . extend ( iter)
0 commit comments