1use std::borrow::{Borrow, BorrowMut};
6use std::collections::hash_map::{Entry, OccupiedError};
7use std::hash::Hash;
8use std::iter::{Product, Sum};
9use std::ops::Index;
10
11use rustc_macros::{Decodable_NoContext, Encodable_NoContext};
12
13use crate::fingerprint::Fingerprint;
14use crate::fx::{FxBuildHasher, FxHashMap, FxHashSet};
15use crate::stable_hasher::{
16 StableCompare, StableHash, StableHashCtxt, StableHasher, ToStableHashKey,
17};
18
19#[derive(#[automatically_derived]
impl<T: ::core::clone::Clone, I: ::core::clone::Clone + Iterator<Item = T>>
::core::clone::Clone for UnordItems<T, I> {
#[inline]
fn clone(&self) -> UnordItems<T, I> {
UnordItems(::core::clone::Clone::clone(&self.0))
}
}Clone)]
34pub struct UnordItems<T, I: Iterator<Item = T>>(I);
35
36impl<T, I: Iterator<Item = T>> UnordItems<T, I> {
37 #[inline]
38 pub fn map<U, F: Fn(T) -> U>(self, f: F) -> UnordItems<U, impl Iterator<Item = U>> {
39 UnordItems(self.0.map(f))
40 }
41
42 #[inline]
43 pub fn all<F: Fn(T) -> bool>(mut self, f: F) -> bool {
44 self.0.all(f)
45 }
46
47 #[inline]
48 pub fn any<F: Fn(T) -> bool>(mut self, f: F) -> bool {
49 self.0.any(f)
50 }
51
52 #[inline]
53 pub fn filter<F: Fn(&T) -> bool>(self, f: F) -> UnordItems<T, impl Iterator<Item = T>> {
54 UnordItems(self.0.filter(f))
55 }
56
57 #[inline]
58 pub fn filter_map<U, F: Fn(T) -> Option<U>>(
59 self,
60 f: F,
61 ) -> UnordItems<U, impl Iterator<Item = U>> {
62 UnordItems(self.0.filter_map(f))
63 }
64
65 #[inline]
66 pub fn max(self) -> Option<T>
67 where
68 T: Ord,
69 {
70 self.0.max()
71 }
72
73 #[inline]
74 pub fn min(self) -> Option<T>
75 where
76 T: Ord,
77 {
78 self.0.min()
79 }
80
81 #[inline]
82 pub fn sum<S>(self) -> S
83 where
84 S: Sum<T>,
85 {
86 self.0.sum()
87 }
88
89 #[inline]
90 pub fn product<S>(self) -> S
91 where
92 S: Product<T>,
93 {
94 self.0.product()
95 }
96
97 #[inline]
98 pub fn count(self) -> usize {
99 self.0.count()
100 }
101
102 #[inline]
103 pub fn flat_map<U, F, O>(self, f: F) -> UnordItems<O, impl Iterator<Item = O>>
104 where
105 U: IntoIterator<Item = O>,
106 F: Fn(T) -> U,
107 {
108 UnordItems(self.0.flat_map(f))
109 }
110
111 pub fn collect<C: From<UnordItems<T, I>>>(self) -> C {
112 self.into()
113 }
114
115 #[track_caller]
117 pub fn get_only(mut self) -> Option<T> {
118 let item = self.0.next();
119 if self.0.next().is_some() {
120 return None;
121 }
122 item
123 }
124}
125
126impl<T> UnordItems<T, std::iter::Empty<T>> {
127 pub fn empty() -> Self {
128 UnordItems(std::iter::empty())
129 }
130}
131
132impl<'a, T: Clone + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
133 #[inline]
134 pub fn cloned(self) -> UnordItems<T, impl Iterator<Item = T>> {
135 UnordItems(self.0.cloned())
136 }
137}
138
139impl<'a, T: Copy + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
140 #[inline]
141 pub fn copied(self) -> UnordItems<T, impl Iterator<Item = T>> {
142 UnordItems(self.0.copied())
143 }
144}
145
146impl<T, I: Iterator<Item = T>> UnordItems<T, I> {
147 #[inline]
148 pub fn into_sorted<Hcx: StableHashCtxt>(self, hcx: &mut Hcx) -> Vec<T>
149 where
150 T: ToStableHashKey,
151 {
152 self.collect_sorted(hcx, true)
153 }
154
155 #[inline]
156 pub fn into_sorted_stable_ord(self) -> Vec<T>
157 where
158 T: StableCompare,
159 {
160 self.collect_stable_ord_by_key(|x| x)
161 }
162
163 #[inline]
164 pub fn into_sorted_stable_ord_by_key<K, C>(self, project_to_key: C) -> Vec<T>
165 where
166 K: StableCompare,
167 C: for<'a> Fn(&'a T) -> &'a K,
168 {
169 self.collect_stable_ord_by_key(project_to_key)
170 }
171
172 #[inline]
173 pub fn collect_sorted<Hcx, C>(self, hcx: &mut Hcx, cache_sort_key: bool) -> C
174 where
175 Hcx: StableHashCtxt,
176 T: ToStableHashKey,
177 C: FromIterator<T> + BorrowMut<[T]>,
178 {
179 let mut items: C = self.0.collect();
180
181 let slice = items.borrow_mut();
182 if slice.len() > 1 {
183 if cache_sort_key {
184 slice.sort_by_cached_key(|x| x.to_stable_hash_key(hcx));
185 } else {
186 slice.sort_by_key(|x| x.to_stable_hash_key(hcx));
187 }
188 }
189
190 items
191 }
192
193 #[inline]
194 pub fn collect_stable_ord_by_key<K, C, P>(self, project_to_key: P) -> C
195 where
196 K: StableCompare,
197 P: for<'a> Fn(&'a T) -> &'a K,
198 C: FromIterator<T> + BorrowMut<[T]>,
199 {
200 let mut items: C = self.0.collect();
201
202 let slice = items.borrow_mut();
203 if slice.len() > 1 {
204 if !K::CAN_USE_UNSTABLE_SORT {
205 slice.sort_by(|a, b| {
206 let a_key = project_to_key(a);
207 let b_key = project_to_key(b);
208 a_key.stable_cmp(b_key)
209 });
210 } else {
211 slice.sort_unstable_by(|a, b| {
212 let a_key = project_to_key(a);
213 let b_key = project_to_key(b);
214 a_key.stable_cmp(b_key)
215 });
216 }
217 }
218
219 items
220 }
221}
222
223trait UnordCollection {}
230
231#[derive(#[automatically_derived]
impl<V: ::core::fmt::Debug + Eq + Hash> ::core::fmt::Debug for UnordSet<V> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "UnordSet",
"inner", &&self.inner)
}
}Debug, #[automatically_derived]
impl<V: ::core::cmp::Eq + Eq + Hash> ::core::cmp::Eq for UnordSet<V> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<FxHashSet<V>>;
}
}Eq, #[automatically_derived]
impl<V: ::core::cmp::PartialEq + Eq + Hash> ::core::cmp::PartialEq for
UnordSet<V> {
#[inline]
fn eq(&self, other: &UnordSet<V>) -> bool { self.inner == other.inner }
}PartialEq, #[automatically_derived]
impl<V: ::core::clone::Clone + Eq + Hash> ::core::clone::Clone for UnordSet<V>
{
#[inline]
fn clone(&self) -> UnordSet<V> {
UnordSet { inner: ::core::clone::Clone::clone(&self.inner) }
}
}Clone, const _: () =
{
impl<V: Eq + Hash, __E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for UnordSet<V> where
FxHashSet<V>: ::rustc_serialize::Encodable<__E> {
fn encode(&self, __encoder: &mut __E) {
match *self {
UnordSet { inner: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<V: Eq + Hash, __D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for UnordSet<V> where
FxHashSet<V>: ::rustc_serialize::Decodable<__D> {
fn decode(__decoder: &mut __D) -> Self {
UnordSet {
inner: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable_NoContext)]
241pub struct UnordSet<V: Eq + Hash> {
242 inner: FxHashSet<V>,
243}
244
245impl<V: Eq + Hash> UnordCollection for UnordSet<V> {}
246
247impl<V: Eq + Hash> const Default for UnordSet<V> {
248 #[inline]
249 fn default() -> Self {
250 Self { inner: FxHashSet::with_hasher(FxBuildHasher) }
251 }
252}
253
254impl<V: Eq + Hash> UnordSet<V> {
255 #[inline]
256 pub fn new() -> Self {
257 Self { inner: Default::default() }
258 }
259
260 #[inline]
261 pub fn with_capacity(capacity: usize) -> Self {
262 Self { inner: FxHashSet::with_capacity_and_hasher(capacity, Default::default()) }
263 }
264
265 #[inline]
266 pub fn len(&self) -> usize {
267 self.inner.len()
268 }
269
270 #[inline]
271 pub fn is_empty(&self) -> bool {
272 self.inner.is_empty()
273 }
274
275 #[inline]
277 pub fn get_only(&self) -> Option<&V> {
278 if self.inner.len() == 1 { self.inner.iter().next() } else { None }
279 }
280
281 #[inline]
282 pub fn insert(&mut self, v: V) -> bool {
283 self.inner.insert(v)
284 }
285
286 #[inline]
287 pub fn contains<Q: ?Sized>(&self, v: &Q) -> bool
288 where
289 V: Borrow<Q>,
290 Q: Hash + Eq,
291 {
292 self.inner.contains(v)
293 }
294
295 #[inline]
296 pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> bool
297 where
298 V: Borrow<Q>,
299 Q: Hash + Eq,
300 {
301 self.inner.remove(k)
302 }
303
304 #[inline]
305 pub fn items(&self) -> UnordItems<&V, impl Iterator<Item = &V>> {
306 UnordItems(self.inner.iter())
307 }
308
309 #[inline]
310 pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> {
311 UnordItems(self.inner.into_iter())
312 }
313
314 #[inline]
321 pub fn to_sorted<Hcx>(&self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<&V>
322 where
323 Hcx: StableHashCtxt,
324 V: ToStableHashKey,
325 {
326 to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&x| x)
327 }
328
329 #[inline]
334 pub fn to_sorted_stable_ord(&self) -> Vec<&V>
335 where
336 V: StableCompare,
337 {
338 let mut items: Vec<&V> = self.inner.iter().collect();
339 items.sort_unstable_by(|a, b| a.stable_cmp(*b));
340 items
341 }
342
343 #[inline]
348 pub fn into_sorted_stable_ord(self) -> Vec<V>
349 where
350 V: StableCompare,
351 {
352 let mut items: Vec<V> = self.inner.into_iter().collect();
353 items.sort_unstable_by(V::stable_cmp);
354 items
355 }
356
357 #[inline]
364 pub fn into_sorted<Hcx>(self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<V>
365 where
366 Hcx: StableHashCtxt,
367 V: ToStableHashKey,
368 {
369 to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |x| x)
370 }
371
372 #[inline]
373 pub fn clear(&mut self) {
374 self.inner.clear();
375 }
376}
377
378pub trait ExtendUnord<T> {
379 fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>);
385}
386
387impl<C: Extend<T> + UnordCollection, T> ExtendUnord<T> for C {
391 #[inline]
392 fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>) {
393 self.extend(items.0)
394 }
395}
396
397impl<V: Hash + Eq> Extend<V> for UnordSet<V> {
398 #[inline]
399 fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
400 self.inner.extend(iter)
401 }
402}
403
404impl<V: Hash + Eq> FromIterator<V> for UnordSet<V> {
405 #[inline]
406 fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
407 UnordSet { inner: FxHashSet::from_iter(iter) }
408 }
409}
410
411impl<V: Hash + Eq> From<FxHashSet<V>> for UnordSet<V> {
412 fn from(value: FxHashSet<V>) -> Self {
413 UnordSet { inner: value }
414 }
415}
416
417impl<V: Hash + Eq, I: Iterator<Item = V>> From<UnordItems<V, I>> for UnordSet<V> {
418 fn from(value: UnordItems<V, I>) -> Self {
419 UnordSet { inner: FxHashSet::from_iter(value.0) }
420 }
421}
422
423impl<V: Hash + Eq + StableHash> StableHash for UnordSet<V> {
424 #[inline]
425 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
426 hash_iter_order_independent(self.inner.iter(), hcx, hasher);
427 }
428}
429
430#[derive(#[automatically_derived]
impl<K: ::core::fmt::Debug + Eq + Hash, V: ::core::fmt::Debug>
::core::fmt::Debug for UnordMap<K, V> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "UnordMap",
"inner", &&self.inner)
}
}Debug, #[automatically_derived]
impl<K: ::core::cmp::Eq + Eq + Hash, V: ::core::cmp::Eq> ::core::cmp::Eq for
UnordMap<K, V> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<FxHashMap<K, V>>;
}
}Eq, #[automatically_derived]
impl<K: ::core::cmp::PartialEq + Eq + Hash, V: ::core::cmp::PartialEq>
::core::cmp::PartialEq for UnordMap<K, V> {
#[inline]
fn eq(&self, other: &UnordMap<K, V>) -> bool { self.inner == other.inner }
}PartialEq, #[automatically_derived]
impl<K: ::core::clone::Clone + Eq + Hash, V: ::core::clone::Clone>
::core::clone::Clone for UnordMap<K, V> {
#[inline]
fn clone(&self) -> UnordMap<K, V> {
UnordMap { inner: ::core::clone::Clone::clone(&self.inner) }
}
}Clone, const _: () =
{
impl<K: Eq + Hash, V, __E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for UnordMap<K, V> where
FxHashMap<K, V>: ::rustc_serialize::Encodable<__E> {
fn encode(&self, __encoder: &mut __E) {
match *self {
UnordMap { inner: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<K: Eq + Hash, V, __D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for UnordMap<K, V> where
FxHashMap<K, V>: ::rustc_serialize::Decodable<__D> {
fn decode(__decoder: &mut __D) -> Self {
UnordMap {
inner: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable_NoContext)]
440pub struct UnordMap<K: Eq + Hash, V> {
441 inner: FxHashMap<K, V>,
442}
443
444impl<K: Eq + Hash, V> UnordCollection for UnordMap<K, V> {}
445
446impl<K: Eq + Hash, V> const Default for UnordMap<K, V> {
447 #[inline]
448 fn default() -> Self {
449 Self { inner: FxHashMap::with_hasher(FxBuildHasher) }
450 }
451}
452
453impl<K: Hash + Eq, V> Extend<(K, V)> for UnordMap<K, V> {
454 #[inline]
455 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
456 self.inner.extend(iter)
457 }
458}
459
460impl<K: Hash + Eq, V> FromIterator<(K, V)> for UnordMap<K, V> {
461 #[inline]
462 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
463 UnordMap { inner: FxHashMap::from_iter(iter) }
464 }
465}
466
467impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> for UnordMap<K, V> {
468 #[inline]
469 fn from(items: UnordItems<(K, V), I>) -> Self {
470 UnordMap { inner: FxHashMap::from_iter(items.0) }
471 }
472}
473
474impl<K: Eq + Hash, V> UnordMap<K, V> {
475 #[inline]
476 pub fn with_capacity(capacity: usize) -> Self {
477 Self { inner: FxHashMap::with_capacity_and_hasher(capacity, Default::default()) }
478 }
479
480 #[inline]
481 pub fn len(&self) -> usize {
482 self.inner.len()
483 }
484
485 #[inline]
486 pub fn insert(&mut self, k: K, v: V) -> Option<V> {
487 self.inner.insert(k, v)
488 }
489
490 #[inline]
491 pub fn try_insert(&mut self, k: K, v: V) -> Result<&mut V, OccupiedError<'_, K, V>> {
492 self.inner.try_insert(k, v)
493 }
494
495 #[inline]
496 pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
497 where
498 K: Borrow<Q>,
499 Q: Hash + Eq,
500 {
501 self.inner.contains_key(k)
502 }
503
504 #[inline]
505 pub fn is_empty(&self) -> bool {
506 self.inner.is_empty()
507 }
508
509 #[inline]
510 pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
511 self.inner.entry(key)
512 }
513
514 #[inline]
515 pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
516 where
517 K: Borrow<Q>,
518 Q: Hash + Eq,
519 {
520 self.inner.get(k)
521 }
522
523 #[inline]
524 pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
525 where
526 K: Borrow<Q>,
527 Q: Hash + Eq,
528 {
529 self.inner.get_mut(k)
530 }
531
532 #[inline]
533 pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
534 where
535 K: Borrow<Q>,
536 Q: Hash + Eq,
537 {
538 self.inner.remove(k)
539 }
540
541 #[inline]
542 pub fn items(&self) -> UnordItems<(&K, &V), impl Iterator<Item = (&K, &V)>> {
543 UnordItems(self.inner.iter())
544 }
545
546 #[inline]
547 pub fn into_items(self) -> UnordItems<(K, V), impl Iterator<Item = (K, V)>> {
548 UnordItems(self.inner.into_iter())
549 }
550
551 #[inline]
552 pub fn keys(&self) -> UnordItems<&K, impl Iterator<Item = &K>> {
553 UnordItems(self.inner.keys())
554 }
555
556 #[inline]
563 pub fn to_sorted<Hcx>(&self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<(&K, &V)>
564 where
565 Hcx: StableHashCtxt,
566 K: ToStableHashKey,
567 {
568 to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&(k, _)| k)
569 }
570
571 #[inline]
575 pub fn to_sorted_stable_ord(&self) -> Vec<(&K, &V)>
576 where
577 K: StableCompare,
578 {
579 let mut items: Vec<_> = self.inner.iter().collect();
580 items.sort_unstable_by(|(a, _), (b, _)| a.stable_cmp(*b));
581 items
582 }
583
584 #[inline]
591 pub fn into_sorted<Hcx>(self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<(K, V)>
592 where
593 Hcx: StableHashCtxt,
594 K: ToStableHashKey,
595 {
596 to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |(k, _)| k)
597 }
598
599 #[inline]
603 pub fn into_sorted_stable_ord(self) -> Vec<(K, V)>
604 where
605 K: StableCompare,
606 {
607 let mut items: Vec<(K, V)> = self.inner.into_iter().collect();
608 items.sort_unstable_by(|a, b| a.0.stable_cmp(&b.0));
609 items
610 }
611
612 #[inline]
620 pub fn values_sorted<Hcx>(
621 &self,
622 hcx: &mut Hcx,
623 cache_sort_key: bool,
624 ) -> impl Iterator<Item = &V>
625 where
626 Hcx: StableHashCtxt,
627 K: ToStableHashKey,
628 {
629 to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&(k, _)| k)
630 .into_iter()
631 .map(|(_, v)| v)
632 }
633
634 #[inline]
635 pub fn clear(&mut self) {
636 self.inner.clear()
637 }
638}
639
640impl<K, Q: ?Sized, V> Index<&Q> for UnordMap<K, V>
641where
642 K: Eq + Hash + Borrow<Q>,
643 Q: Eq + Hash,
644{
645 type Output = V;
646
647 #[inline]
648 fn index(&self, key: &Q) -> &V {
649 &self.inner[key]
650 }
651}
652
653impl<K: Hash + Eq + StableHash, V: StableHash> StableHash for UnordMap<K, V> {
654 #[inline]
655 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
656 hash_iter_order_independent(self.inner.iter(), hcx, hasher);
657 }
658}
659
660#[derive(#[automatically_derived]
impl<V: ::core::default::Default> ::core::default::Default for UnordBag<V> {
#[inline]
fn default() -> UnordBag<V> {
UnordBag { inner: ::core::default::Default::default() }
}
}Default, #[automatically_derived]
impl<V: ::core::fmt::Debug> ::core::fmt::Debug for UnordBag<V> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "UnordBag",
"inner", &&self.inner)
}
}Debug, #[automatically_derived]
impl<V: ::core::cmp::Eq> ::core::cmp::Eq for UnordBag<V> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Vec<V>>;
}
}Eq, #[automatically_derived]
impl<V: ::core::cmp::PartialEq> ::core::cmp::PartialEq for UnordBag<V> {
#[inline]
fn eq(&self, other: &UnordBag<V>) -> bool { self.inner == other.inner }
}PartialEq, #[automatically_derived]
impl<V: ::core::clone::Clone> ::core::clone::Clone for UnordBag<V> {
#[inline]
fn clone(&self) -> UnordBag<V> {
UnordBag { inner: ::core::clone::Clone::clone(&self.inner) }
}
}Clone, const _: () =
{
impl<V, __E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for UnordBag<V> where
Vec<V>: ::rustc_serialize::Encodable<__E> {
fn encode(&self, __encoder: &mut __E) {
match *self {
UnordBag { inner: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<V, __D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for UnordBag<V> where
Vec<V>: ::rustc_serialize::Decodable<__D> {
fn decode(__decoder: &mut __D) -> Self {
UnordBag {
inner: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable_NoContext)]
671pub struct UnordBag<V> {
672 inner: Vec<V>,
673}
674
675impl<V> UnordBag<V> {
676 #[inline]
677 pub fn new() -> Self {
678 Self { inner: Default::default() }
679 }
680
681 #[inline]
682 pub fn len(&self) -> usize {
683 self.inner.len()
684 }
685
686 #[inline]
687 pub fn push(&mut self, v: V) {
688 self.inner.push(v);
689 }
690
691 #[inline]
692 pub fn items(&self) -> UnordItems<&V, impl Iterator<Item = &V>> {
693 UnordItems(self.inner.iter())
694 }
695
696 #[inline]
697 pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> {
698 UnordItems(self.inner.into_iter())
699 }
700}
701
702impl<T> UnordCollection for UnordBag<T> {}
703
704impl<T> Extend<T> for UnordBag<T> {
705 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
706 self.inner.extend(iter)
707 }
708}
709
710impl<T, I: Iterator<Item = T>> From<UnordItems<T, I>> for UnordBag<T> {
711 fn from(value: UnordItems<T, I>) -> Self {
712 UnordBag { inner: Vec::from_iter(value.0) }
713 }
714}
715
716impl<V: Hash + Eq + StableHash> StableHash for UnordBag<V> {
717 #[inline]
718 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
719 hash_iter_order_independent(self.inner.iter(), hcx, hasher);
720 }
721}
722
723#[inline]
724fn to_sorted_vec<Hcx, T, K, I>(
725 hcx: &mut Hcx,
726 iter: I,
727 cache_sort_key: bool,
728 extract_key: fn(&T) -> &K,
729) -> Vec<T>
730where
731 Hcx: StableHashCtxt,
732 I: Iterator<Item = T>,
733 K: ToStableHashKey,
734{
735 let mut items: Vec<T> = iter.collect();
736 if cache_sort_key {
737 items.sort_by_cached_key(|x| extract_key(x).to_stable_hash_key(hcx));
738 } else {
739 items.sort_unstable_by_key(|x| extract_key(x).to_stable_hash_key(hcx));
740 }
741
742 items
743}
744
745fn hash_iter_order_independent<
746 Hcx: StableHashCtxt,
747 T: StableHash,
748 I: Iterator<Item = T> + ExactSizeIterator,
749>(
750 mut it: I,
751 hcx: &mut Hcx,
752 hasher: &mut StableHasher,
753) {
754 let len = it.len();
755 len.stable_hash(hcx, hasher);
756
757 match len {
758 0 => {
759 }
761 1 => {
762 it.next().unwrap().stable_hash(hcx, hasher);
764 }
765 _ => {
766 let mut accumulator = Fingerprint::ZERO;
767 for item in it {
768 let mut item_hasher = StableHasher::new();
769 item.stable_hash(hcx, &mut item_hasher);
770 let item_fingerprint: Fingerprint = item_hasher.finish();
771 accumulator = accumulator.combine_commutative(item_fingerprint);
772 }
773 accumulator.stable_hash(hcx, hasher);
774 }
775 }
776}
777
778impl<T> !IntoIterator for UnordBag<T> {}
781impl<V> !IntoIterator for UnordSet<V> {}
782impl<K, V> !IntoIterator for UnordMap<K, V> {}
783impl<T, I> !IntoIterator for UnordItems<T, I> {}