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_hash::{
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 new(iter: I) -> UnordItems<T, I> {
39 UnordItems(iter)
40 }
41
42 #[inline]
43 pub fn map<U, F: Fn(T) -> U>(self, f: F) -> UnordItems<U, impl Iterator<Item = U>> {
44 UnordItems(self.0.map(f))
45 }
46
47 #[inline]
48 pub fn all<F: Fn(T) -> bool>(mut self, f: F) -> bool {
49 self.0.all(f)
50 }
51
52 #[inline]
53 pub fn any<F: Fn(T) -> bool>(mut self, f: F) -> bool {
54 self.0.any(f)
55 }
56
57 #[inline]
58 pub fn filter<F: Fn(&T) -> bool>(self, f: F) -> UnordItems<T, impl Iterator<Item = T>> {
59 UnordItems(self.0.filter(f))
60 }
61
62 #[inline]
63 pub fn filter_map<U, F: Fn(T) -> Option<U>>(
64 self,
65 f: F,
66 ) -> UnordItems<U, impl Iterator<Item = U>> {
67 UnordItems(self.0.filter_map(f))
68 }
69
70 #[inline]
71 pub fn chain(
72 self,
73 other: UnordItems<T, impl Iterator<Item = T>>,
74 ) -> UnordItems<T, impl Iterator<Item = T>> {
75 UnordItems(self.0.chain(other.0))
76 }
77
78 #[inline]
79 pub fn max(self) -> Option<T>
80 where
81 T: Ord,
82 {
83 self.0.max()
84 }
85
86 #[inline]
87 pub fn min(self) -> Option<T>
88 where
89 T: Ord,
90 {
91 self.0.min()
92 }
93
94 #[inline]
95 pub fn sum<S>(self) -> S
96 where
97 S: Sum<T>,
98 {
99 self.0.sum()
100 }
101
102 #[inline]
103 pub fn product<S>(self) -> S
104 where
105 S: Product<T>,
106 {
107 self.0.product()
108 }
109
110 #[inline]
111 pub fn count(self) -> usize {
112 self.0.count()
113 }
114
115 #[inline]
116 pub fn flat_map<U, F, O>(self, f: F) -> UnordItems<O, impl Iterator<Item = O>>
117 where
118 U: Iterator<Item = O>,
119 F: Fn(T) -> UnordItems<O, U>,
120 {
121 UnordItems(self.0.flat_map(move |x| f(x).0))
122 }
123
124 pub fn collect<C: From<UnordItems<T, I>>>(self) -> C {
125 self.into()
126 }
127
128 #[track_caller]
130 pub fn get_only(mut self) -> Option<T> {
131 let item = self.0.next();
132 if self.0.next().is_some() {
133 return None;
134 }
135 item
136 }
137}
138
139impl<T> UnordItems<T, std::iter::Empty<T>> {
140 pub fn empty() -> Self {
141 UnordItems(std::iter::empty())
142 }
143}
144
145impl<'a, T: Clone + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
146 #[inline]
147 pub fn cloned(self) -> UnordItems<T, impl Iterator<Item = T>> {
148 UnordItems(self.0.cloned())
149 }
150}
151
152impl<'a, T: Copy + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
153 #[inline]
154 pub fn copied(self) -> UnordItems<T, impl Iterator<Item = T>> {
155 UnordItems(self.0.copied())
156 }
157}
158
159impl<T, I: Iterator<Item = T>> UnordItems<T, I> {
160 #[inline]
161 pub fn into_sorted<Hcx: StableHashCtxt>(self, hcx: &mut Hcx) -> Vec<T>
162 where
163 T: ToStableHashKey,
164 {
165 self.collect_sorted(hcx, true)
166 }
167
168 #[inline]
169 pub fn into_sorted_stable_ord(self) -> Vec<T>
170 where
171 T: StableCompare,
172 {
173 self.collect_stable_ord_by_key(|x| x)
174 }
175
176 #[inline]
177 pub fn into_sorted_stable_ord_by_key<K, C>(self, project_to_key: C) -> Vec<T>
178 where
179 K: StableCompare,
180 C: for<'a> Fn(&'a T) -> &'a K,
181 {
182 self.collect_stable_ord_by_key(project_to_key)
183 }
184
185 #[inline]
186 pub fn collect_sorted<Hcx, C>(self, hcx: &mut Hcx, cache_sort_key: bool) -> C
187 where
188 Hcx: StableHashCtxt,
189 T: ToStableHashKey,
190 C: FromIterator<T> + BorrowMut<[T]>,
191 {
192 let mut items: C = self.0.collect();
193
194 let slice = items.borrow_mut();
195 if slice.len() > 1 {
196 if cache_sort_key {
197 slice.sort_by_cached_key(|x| x.to_stable_hash_key(hcx));
198 } else {
199 slice.sort_by_key(|x| x.to_stable_hash_key(hcx));
200 }
201 }
202
203 items
204 }
205
206 #[inline]
207 pub fn collect_stable_ord_by_key<K, C, P>(self, project_to_key: P) -> C
208 where
209 K: StableCompare,
210 P: for<'a> Fn(&'a T) -> &'a K,
211 C: FromIterator<T> + BorrowMut<[T]>,
212 {
213 let mut items: C = self.0.collect();
214
215 let slice = items.borrow_mut();
216 if slice.len() > 1 {
217 if !K::CAN_USE_UNSTABLE_SORT {
218 slice.sort_by(|a, b| {
219 let a_key = project_to_key(a);
220 let b_key = project_to_key(b);
221 a_key.stable_cmp(b_key)
222 });
223 } else {
224 slice.sort_unstable_by(|a, b| {
225 let a_key = project_to_key(a);
226 let b_key = project_to_key(b);
227 a_key.stable_cmp(b_key)
228 });
229 }
230 }
231
232 items
233 }
234}
235
236trait UnordCollection {}
243
244#[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)]
254pub struct UnordSet<V: Eq + Hash> {
255 inner: FxHashSet<V>,
256}
257
258impl<V: Eq + Hash> UnordCollection for UnordSet<V> {}
259
260impl<V: Eq + Hash> const Default for UnordSet<V> {
261 #[inline]
262 fn default() -> Self {
263 Self { inner: FxHashSet::with_hasher(FxBuildHasher) }
264 }
265}
266
267impl<V: Eq + Hash> UnordSet<V> {
268 #[inline]
269 pub fn new() -> Self {
270 Self { inner: Default::default() }
271 }
272
273 #[inline]
274 pub fn with_capacity(capacity: usize) -> Self {
275 Self { inner: FxHashSet::with_capacity_and_hasher(capacity, Default::default()) }
276 }
277
278 #[inline]
279 pub fn len(&self) -> usize {
280 self.inner.len()
281 }
282
283 #[inline]
284 pub fn is_empty(&self) -> bool {
285 self.inner.is_empty()
286 }
287
288 #[inline]
290 pub fn get_only(&self) -> Option<&V> {
291 if self.inner.len() == 1 { self.inner.iter().next() } else { None }
292 }
293
294 #[inline]
295 pub fn insert(&mut self, v: V) -> bool {
296 self.inner.insert(v)
297 }
298
299 #[inline]
300 pub fn contains<Q: ?Sized>(&self, v: &Q) -> bool
301 where
302 V: Borrow<Q>,
303 Q: Hash + Eq,
304 {
305 self.inner.contains(v)
306 }
307
308 #[inline]
309 pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> bool
310 where
311 V: Borrow<Q>,
312 Q: Hash + Eq,
313 {
314 self.inner.remove(k)
315 }
316
317 #[inline]
318 pub fn items(&self) -> UnordItems<&V, impl Iterator<Item = &V>> {
319 UnordItems(self.inner.iter())
320 }
321
322 #[inline]
323 pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> {
324 UnordItems(self.inner.into_iter())
325 }
326
327 #[inline]
334 pub fn to_sorted<Hcx>(&self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<&V>
335 where
336 Hcx: StableHashCtxt,
337 V: ToStableHashKey,
338 {
339 to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&x| x)
340 }
341
342 #[inline]
347 pub fn to_sorted_stable_ord(&self) -> Vec<&V>
348 where
349 V: StableCompare,
350 {
351 let mut items: Vec<&V> = self.inner.iter().collect();
352 items.sort_unstable_by(|a, b| a.stable_cmp(*b));
353 items
354 }
355
356 #[inline]
361 pub fn into_sorted_stable_ord(self) -> Vec<V>
362 where
363 V: StableCompare,
364 {
365 let mut items: Vec<V> = self.inner.into_iter().collect();
366 items.sort_unstable_by(V::stable_cmp);
367 items
368 }
369
370 #[inline]
377 pub fn into_sorted<Hcx>(self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<V>
378 where
379 Hcx: StableHashCtxt,
380 V: ToStableHashKey,
381 {
382 to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |x| x)
383 }
384
385 #[inline]
386 pub fn clear(&mut self) {
387 self.inner.clear();
388 }
389}
390
391pub trait ExtendUnord<T> {
392 fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>);
398}
399
400impl<C: Extend<T> + UnordCollection, T> ExtendUnord<T> for C {
404 #[inline]
405 fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>) {
406 self.extend(items.0)
407 }
408}
409
410impl<V: Hash + Eq> Extend<V> for UnordSet<V> {
411 #[inline]
412 fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
413 self.inner.extend(iter)
414 }
415}
416
417impl<V: Hash + Eq> FromIterator<V> for UnordSet<V> {
418 #[inline]
419 fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
420 UnordSet { inner: FxHashSet::from_iter(iter) }
421 }
422}
423
424impl<V: Hash + Eq> From<FxHashSet<V>> for UnordSet<V> {
425 fn from(value: FxHashSet<V>) -> Self {
426 UnordSet { inner: value }
427 }
428}
429
430impl<V: Hash + Eq, I: Iterator<Item = V>> From<UnordItems<V, I>> for UnordSet<V> {
431 fn from(value: UnordItems<V, I>) -> Self {
432 UnordSet { inner: FxHashSet::from_iter(value.0) }
433 }
434}
435
436impl<V: Hash + Eq + StableHash> StableHash for UnordSet<V> {
437 #[inline]
438 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
439 hash_iter_order_independent(self.inner.iter(), hcx, hasher);
440 }
441}
442
443#[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)]
453pub struct UnordMap<K: Eq + Hash, V> {
454 inner: FxHashMap<K, V>,
455}
456
457impl<K: Eq + Hash, V> UnordCollection for UnordMap<K, V> {}
458
459impl<K: Eq + Hash, V> const Default for UnordMap<K, V> {
460 #[inline]
461 fn default() -> Self {
462 Self { inner: FxHashMap::with_hasher(FxBuildHasher) }
463 }
464}
465
466impl<K: Hash + Eq, V> Extend<(K, V)> for UnordMap<K, V> {
467 #[inline]
468 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
469 self.inner.extend(iter)
470 }
471}
472
473impl<K: Hash + Eq, V> FromIterator<(K, V)> for UnordMap<K, V> {
474 #[inline]
475 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
476 UnordMap { inner: FxHashMap::from_iter(iter) }
477 }
478}
479
480impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> for UnordMap<K, V> {
481 #[inline]
482 fn from(items: UnordItems<(K, V), I>) -> Self {
483 UnordMap { inner: FxHashMap::from_iter(items.0) }
484 }
485}
486
487impl<K: Eq + Hash, V> UnordMap<K, V> {
488 #[inline]
489 pub fn with_capacity(capacity: usize) -> Self {
490 Self { inner: FxHashMap::with_capacity_and_hasher(capacity, Default::default()) }
491 }
492
493 #[inline]
494 pub fn len(&self) -> usize {
495 self.inner.len()
496 }
497
498 #[inline]
499 pub fn insert(&mut self, k: K, v: V) -> Option<V> {
500 self.inner.insert(k, v)
501 }
502
503 #[inline]
504 pub fn try_insert(&mut self, k: K, v: V) -> Result<&mut V, OccupiedError<'_, K, V>> {
505 self.inner.try_insert(k, v)
506 }
507
508 #[inline]
509 pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
510 where
511 K: Borrow<Q>,
512 Q: Hash + Eq,
513 {
514 self.inner.contains_key(k)
515 }
516
517 #[inline]
518 pub fn is_empty(&self) -> bool {
519 self.inner.is_empty()
520 }
521
522 #[inline]
523 pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
524 self.inner.entry(key)
525 }
526
527 #[inline]
528 pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
529 where
530 K: Borrow<Q>,
531 Q: Hash + Eq,
532 {
533 self.inner.get(k)
534 }
535
536 #[inline]
537 pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
538 where
539 K: Borrow<Q>,
540 Q: Hash + Eq,
541 {
542 self.inner.get_mut(k)
543 }
544
545 #[inline]
546 pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
547 where
548 K: Borrow<Q>,
549 Q: Hash + Eq,
550 {
551 self.inner.remove(k)
552 }
553
554 #[inline]
555 pub fn items(&self) -> UnordItems<(&K, &V), impl Iterator<Item = (&K, &V)>> {
556 UnordItems(self.inner.iter())
557 }
558
559 #[inline]
560 pub fn into_items(self) -> UnordItems<(K, V), impl Iterator<Item = (K, V)>> {
561 UnordItems(self.inner.into_iter())
562 }
563
564 #[inline]
565 pub fn keys(&self) -> UnordItems<&K, impl Iterator<Item = &K>> {
566 UnordItems(self.inner.keys())
567 }
568
569 #[inline]
576 pub fn to_sorted<Hcx>(&self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<(&K, &V)>
577 where
578 Hcx: StableHashCtxt,
579 K: ToStableHashKey,
580 {
581 to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&(k, _)| k)
582 }
583
584 #[inline]
588 pub fn to_sorted_stable_ord(&self) -> Vec<(&K, &V)>
589 where
590 K: StableCompare,
591 {
592 let mut items: Vec<_> = self.inner.iter().collect();
593 items.sort_unstable_by(|(a, _), (b, _)| a.stable_cmp(*b));
594 items
595 }
596
597 #[inline]
604 pub fn into_sorted<Hcx>(self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<(K, V)>
605 where
606 Hcx: StableHashCtxt,
607 K: ToStableHashKey,
608 {
609 to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |(k, _)| k)
610 }
611
612 #[inline]
616 pub fn into_sorted_stable_ord(self) -> Vec<(K, V)>
617 where
618 K: StableCompare,
619 {
620 let mut items: Vec<(K, V)> = self.inner.into_iter().collect();
621 items.sort_unstable_by(|a, b| a.0.stable_cmp(&b.0));
622 items
623 }
624
625 #[inline]
633 pub fn values_sorted<Hcx>(
634 &self,
635 hcx: &mut Hcx,
636 cache_sort_key: bool,
637 ) -> impl Iterator<Item = &V>
638 where
639 Hcx: StableHashCtxt,
640 K: ToStableHashKey,
641 {
642 to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&(k, _)| k)
643 .into_iter()
644 .map(|(_, v)| v)
645 }
646
647 #[inline]
648 pub fn clear(&mut self) {
649 self.inner.clear()
650 }
651}
652
653impl<K, Q: ?Sized, V> Index<&Q> for UnordMap<K, V>
654where
655 K: Eq + Hash + Borrow<Q>,
656 Q: Eq + Hash,
657{
658 type Output = V;
659
660 #[inline]
661 fn index(&self, key: &Q) -> &V {
662 &self.inner[key]
663 }
664}
665
666impl<K: Hash + Eq + StableHash, V: StableHash> StableHash for UnordMap<K, V> {
667 #[inline]
668 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
669 hash_iter_order_independent(self.inner.iter(), hcx, hasher);
670 }
671}
672
673#[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)]
684pub struct UnordBag<V> {
685 inner: Vec<V>,
686}
687
688impl<V> UnordBag<V> {
689 #[inline]
690 pub fn new() -> Self {
691 Self { inner: Default::default() }
692 }
693
694 #[inline]
695 pub fn len(&self) -> usize {
696 self.inner.len()
697 }
698
699 #[inline]
700 pub fn push(&mut self, v: V) {
701 self.inner.push(v);
702 }
703
704 #[inline]
705 pub fn items(&self) -> UnordItems<&V, impl Iterator<Item = &V>> {
706 UnordItems(self.inner.iter())
707 }
708
709 #[inline]
710 pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> {
711 UnordItems(self.inner.into_iter())
712 }
713}
714
715impl<T> UnordCollection for UnordBag<T> {}
716
717impl<T> Extend<T> for UnordBag<T> {
718 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
719 self.inner.extend(iter)
720 }
721}
722
723impl<T, I: Iterator<Item = T>> From<UnordItems<T, I>> for UnordBag<T> {
724 fn from(value: UnordItems<T, I>) -> Self {
725 UnordBag { inner: Vec::from_iter(value.0) }
726 }
727}
728
729impl<V: Hash + Eq + StableHash> StableHash for UnordBag<V> {
730 #[inline]
731 fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
732 hash_iter_order_independent(self.inner.iter(), hcx, hasher);
733 }
734}
735
736#[inline]
737fn to_sorted_vec<Hcx, T, K, I>(
738 hcx: &mut Hcx,
739 iter: I,
740 cache_sort_key: bool,
741 extract_key: fn(&T) -> &K,
742) -> Vec<T>
743where
744 Hcx: StableHashCtxt,
745 I: Iterator<Item = T>,
746 K: ToStableHashKey,
747{
748 let mut items: Vec<T> = iter.collect();
749 if cache_sort_key {
750 items.sort_by_cached_key(|x| extract_key(x).to_stable_hash_key(hcx));
751 } else {
752 items.sort_unstable_by_key(|x| extract_key(x).to_stable_hash_key(hcx));
753 }
754
755 items
756}
757
758fn hash_iter_order_independent<
759 Hcx: StableHashCtxt,
760 T: StableHash,
761 I: Iterator<Item = T> + ExactSizeIterator,
762>(
763 mut it: I,
764 hcx: &mut Hcx,
765 hasher: &mut StableHasher,
766) {
767 let len = it.len();
768 len.stable_hash(hcx, hasher);
769
770 match len {
771 0 => {
772 }
774 1 => {
775 it.next().unwrap().stable_hash(hcx, hasher);
777 }
778 _ => {
779 let mut accumulator = Fingerprint::ZERO;
780 for item in it {
781 let mut item_hasher = StableHasher::new();
782 item.stable_hash(hcx, &mut item_hasher);
783 let item_fingerprint: Fingerprint = item_hasher.finish();
784 accumulator = accumulator.combine_commutative(item_fingerprint);
785 }
786 accumulator.stable_hash(hcx, hasher);
787 }
788 }
789}
790
791impl<T> !IntoIterator for UnordBag<T> {}
794impl<V> !IntoIterator for UnordSet<V> {}
795impl<K, V> !IntoIterator for UnordMap<K, V> {}
796impl<T, I> !IntoIterator for UnordItems<T, I> {}