1 | //! A hash set implemented using `IndexMap` |
2 | |
3 | #[cfg (feature = "rayon" )] |
4 | pub use crate::rayon::set as rayon; |
5 | |
6 | #[cfg (has_std)] |
7 | use std::collections::hash_map::RandomState; |
8 | |
9 | use crate::vec::{self, Vec}; |
10 | use core::cmp::Ordering; |
11 | use core::fmt; |
12 | use core::hash::{BuildHasher, Hash}; |
13 | use core::iter::{Chain, FusedIterator}; |
14 | use core::ops::{BitAnd, BitOr, BitXor, Index, RangeBounds, Sub}; |
15 | use core::slice; |
16 | |
17 | use super::{Entries, Equivalent, IndexMap}; |
18 | |
19 | type Bucket<T> = super::Bucket<T, ()>; |
20 | |
21 | /// A hash set where the iteration order of the values is independent of their |
22 | /// hash values. |
23 | /// |
24 | /// The interface is closely compatible with the standard `HashSet`, but also |
25 | /// has additional features. |
26 | /// |
27 | /// # Order |
28 | /// |
29 | /// The values have a consistent order that is determined by the sequence of |
30 | /// insertion and removal calls on the set. The order does not depend on the |
31 | /// values or the hash function at all. Note that insertion order and value |
32 | /// are not affected if a re-insertion is attempted once an element is |
33 | /// already present. |
34 | /// |
35 | /// All iterators traverse the set *in order*. Set operation iterators like |
36 | /// `union` produce a concatenated order, as do their matching "bitwise" |
37 | /// operators. See their documentation for specifics. |
38 | /// |
39 | /// The insertion order is preserved, with **notable exceptions** like the |
40 | /// `.remove()` or `.swap_remove()` methods. Methods such as `.sort_by()` of |
41 | /// course result in a new order, depending on the sorting order. |
42 | /// |
43 | /// # Indices |
44 | /// |
45 | /// The values are indexed in a compact range without holes in the range |
46 | /// `0..self.len()`. For example, the method `.get_full` looks up the index for |
47 | /// a value, and the method `.get_index` looks up the value by index. |
48 | /// |
49 | /// # Examples |
50 | /// |
51 | /// ``` |
52 | /// use indexmap::IndexSet; |
53 | /// |
54 | /// // Collects which letters appear in a sentence. |
55 | /// let letters: IndexSet<_> = "a short treatise on fungi" .chars().collect(); |
56 | /// |
57 | /// assert!(letters.contains(&'s' )); |
58 | /// assert!(letters.contains(&'t' )); |
59 | /// assert!(letters.contains(&'u' )); |
60 | /// assert!(!letters.contains(&'y' )); |
61 | /// ``` |
62 | #[cfg (has_std)] |
63 | pub struct IndexSet<T, S = RandomState> { |
64 | pub(crate) map: IndexMap<T, (), S>, |
65 | } |
66 | #[cfg (not(has_std))] |
67 | pub struct IndexSet<T, S> { |
68 | pub(crate) map: IndexMap<T, (), S>, |
69 | } |
70 | |
71 | impl<T, S> Clone for IndexSet<T, S> |
72 | where |
73 | T: Clone, |
74 | S: Clone, |
75 | { |
76 | fn clone(&self) -> Self { |
77 | IndexSet { |
78 | map: self.map.clone(), |
79 | } |
80 | } |
81 | |
82 | fn clone_from(&mut self, other: &Self) { |
83 | self.map.clone_from(&other.map); |
84 | } |
85 | } |
86 | |
87 | impl<T, S> Entries for IndexSet<T, S> { |
88 | type Entry = Bucket<T>; |
89 | |
90 | #[inline ] |
91 | fn into_entries(self) -> Vec<Self::Entry> { |
92 | self.map.into_entries() |
93 | } |
94 | |
95 | #[inline ] |
96 | fn as_entries(&self) -> &[Self::Entry] { |
97 | self.map.as_entries() |
98 | } |
99 | |
100 | #[inline ] |
101 | fn as_entries_mut(&mut self) -> &mut [Self::Entry] { |
102 | self.map.as_entries_mut() |
103 | } |
104 | |
105 | fn with_entries<F>(&mut self, f: F) |
106 | where |
107 | F: FnOnce(&mut [Self::Entry]), |
108 | { |
109 | self.map.with_entries(f); |
110 | } |
111 | } |
112 | |
113 | impl<T, S> fmt::Debug for IndexSet<T, S> |
114 | where |
115 | T: fmt::Debug, |
116 | { |
117 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
118 | if cfg!(not(feature = "test_debug" )) { |
119 | f.debug_set().entries(self.iter()).finish() |
120 | } else { |
121 | // Let the inner `IndexMap` print all of its details |
122 | f.debug_struct("IndexSet" ).field(name:"map" , &self.map).finish() |
123 | } |
124 | } |
125 | } |
126 | |
127 | #[cfg (has_std)] |
128 | impl<T> IndexSet<T> { |
129 | /// Create a new set. (Does not allocate.) |
130 | pub fn new() -> Self { |
131 | IndexSet { |
132 | map: IndexMap::new(), |
133 | } |
134 | } |
135 | |
136 | /// Create a new set with capacity for `n` elements. |
137 | /// (Does not allocate if `n` is zero.) |
138 | /// |
139 | /// Computes in **O(n)** time. |
140 | pub fn with_capacity(n: usize) -> Self { |
141 | IndexSet { |
142 | map: IndexMap::with_capacity(n), |
143 | } |
144 | } |
145 | } |
146 | |
147 | impl<T, S> IndexSet<T, S> { |
148 | /// Create a new set with capacity for `n` elements. |
149 | /// (Does not allocate if `n` is zero.) |
150 | /// |
151 | /// Computes in **O(n)** time. |
152 | pub fn with_capacity_and_hasher(n: usize, hash_builder: S) -> Self { |
153 | IndexSet { |
154 | map: IndexMap::with_capacity_and_hasher(n, hash_builder), |
155 | } |
156 | } |
157 | |
158 | /// Create a new set with `hash_builder`. |
159 | /// |
160 | /// This function is `const`, so it |
161 | /// can be called in `static` contexts. |
162 | pub const fn with_hasher(hash_builder: S) -> Self { |
163 | IndexSet { |
164 | map: IndexMap::with_hasher(hash_builder), |
165 | } |
166 | } |
167 | |
168 | /// Computes in **O(1)** time. |
169 | pub fn capacity(&self) -> usize { |
170 | self.map.capacity() |
171 | } |
172 | |
173 | /// Return a reference to the set's `BuildHasher`. |
174 | pub fn hasher(&self) -> &S { |
175 | self.map.hasher() |
176 | } |
177 | |
178 | /// Return the number of elements in the set. |
179 | /// |
180 | /// Computes in **O(1)** time. |
181 | pub fn len(&self) -> usize { |
182 | self.map.len() |
183 | } |
184 | |
185 | /// Returns true if the set contains no elements. |
186 | /// |
187 | /// Computes in **O(1)** time. |
188 | pub fn is_empty(&self) -> bool { |
189 | self.map.is_empty() |
190 | } |
191 | |
192 | /// Return an iterator over the values of the set, in their order |
193 | pub fn iter(&self) -> Iter<'_, T> { |
194 | Iter { |
195 | iter: self.map.as_entries().iter(), |
196 | } |
197 | } |
198 | |
199 | /// Remove all elements in the set, while preserving its capacity. |
200 | /// |
201 | /// Computes in **O(n)** time. |
202 | pub fn clear(&mut self) { |
203 | self.map.clear(); |
204 | } |
205 | |
206 | /// Shortens the set, keeping the first `len` elements and dropping the rest. |
207 | /// |
208 | /// If `len` is greater than the set's current length, this has no effect. |
209 | pub fn truncate(&mut self, len: usize) { |
210 | self.map.truncate(len); |
211 | } |
212 | |
213 | /// Clears the `IndexSet` in the given index range, returning those values |
214 | /// as a drain iterator. |
215 | /// |
216 | /// The range may be any type that implements `RangeBounds<usize>`, |
217 | /// including all of the `std::ops::Range*` types, or even a tuple pair of |
218 | /// `Bound` start and end values. To drain the set entirely, use `RangeFull` |
219 | /// like `set.drain(..)`. |
220 | /// |
221 | /// This shifts down all entries following the drained range to fill the |
222 | /// gap, and keeps the allocated memory for reuse. |
223 | /// |
224 | /// ***Panics*** if the starting point is greater than the end point or if |
225 | /// the end point is greater than the length of the set. |
226 | pub fn drain<R>(&mut self, range: R) -> Drain<'_, T> |
227 | where |
228 | R: RangeBounds<usize>, |
229 | { |
230 | Drain { |
231 | iter: self.map.drain(range).iter, |
232 | } |
233 | } |
234 | |
235 | /// Splits the collection into two at the given index. |
236 | /// |
237 | /// Returns a newly allocated set containing the elements in the range |
238 | /// `[at, len)`. After the call, the original set will be left containing |
239 | /// the elements `[0, at)` with its previous capacity unchanged. |
240 | /// |
241 | /// ***Panics*** if `at > len`. |
242 | pub fn split_off(&mut self, at: usize) -> Self |
243 | where |
244 | S: Clone, |
245 | { |
246 | Self { |
247 | map: self.map.split_off(at), |
248 | } |
249 | } |
250 | } |
251 | |
252 | impl<T, S> IndexSet<T, S> |
253 | where |
254 | T: Hash + Eq, |
255 | S: BuildHasher, |
256 | { |
257 | /// Reserve capacity for `additional` more values. |
258 | /// |
259 | /// Computes in **O(n)** time. |
260 | pub fn reserve(&mut self, additional: usize) { |
261 | self.map.reserve(additional); |
262 | } |
263 | |
264 | /// Shrink the capacity of the set as much as possible. |
265 | /// |
266 | /// Computes in **O(n)** time. |
267 | pub fn shrink_to_fit(&mut self) { |
268 | self.map.shrink_to_fit(); |
269 | } |
270 | |
271 | /// Shrink the capacity of the set with a lower limit. |
272 | /// |
273 | /// Computes in **O(n)** time. |
274 | pub fn shrink_to(&mut self, min_capacity: usize) { |
275 | self.map.shrink_to(min_capacity); |
276 | } |
277 | |
278 | /// Insert the value into the set. |
279 | /// |
280 | /// If an equivalent item already exists in the set, it returns |
281 | /// `false` leaving the original value in the set and without |
282 | /// altering its insertion order. Otherwise, it inserts the new |
283 | /// item and returns `true`. |
284 | /// |
285 | /// Computes in **O(1)** time (amortized average). |
286 | pub fn insert(&mut self, value: T) -> bool { |
287 | self.map.insert(value, ()).is_none() |
288 | } |
289 | |
290 | /// Insert the value into the set, and get its index. |
291 | /// |
292 | /// If an equivalent item already exists in the set, it returns |
293 | /// the index of the existing item and `false`, leaving the |
294 | /// original value in the set and without altering its insertion |
295 | /// order. Otherwise, it inserts the new item and returns the index |
296 | /// of the inserted item and `true`. |
297 | /// |
298 | /// Computes in **O(1)** time (amortized average). |
299 | pub fn insert_full(&mut self, value: T) -> (usize, bool) { |
300 | use super::map::Entry::*; |
301 | |
302 | match self.map.entry(value) { |
303 | Occupied(e) => (e.index(), false), |
304 | Vacant(e) => { |
305 | let index = e.index(); |
306 | e.insert(()); |
307 | (index, true) |
308 | } |
309 | } |
310 | } |
311 | |
312 | /// Return an iterator over the values that are in `self` but not `other`. |
313 | /// |
314 | /// Values are produced in the same order that they appear in `self`. |
315 | pub fn difference<'a, S2>(&'a self, other: &'a IndexSet<T, S2>) -> Difference<'a, T, S2> |
316 | where |
317 | S2: BuildHasher, |
318 | { |
319 | Difference { |
320 | iter: self.iter(), |
321 | other, |
322 | } |
323 | } |
324 | |
325 | /// Return an iterator over the values that are in `self` or `other`, |
326 | /// but not in both. |
327 | /// |
328 | /// Values from `self` are produced in their original order, followed by |
329 | /// values from `other` in their original order. |
330 | pub fn symmetric_difference<'a, S2>( |
331 | &'a self, |
332 | other: &'a IndexSet<T, S2>, |
333 | ) -> SymmetricDifference<'a, T, S, S2> |
334 | where |
335 | S2: BuildHasher, |
336 | { |
337 | SymmetricDifference { |
338 | iter: self.difference(other).chain(other.difference(self)), |
339 | } |
340 | } |
341 | |
342 | /// Return an iterator over the values that are in both `self` and `other`. |
343 | /// |
344 | /// Values are produced in the same order that they appear in `self`. |
345 | pub fn intersection<'a, S2>(&'a self, other: &'a IndexSet<T, S2>) -> Intersection<'a, T, S2> |
346 | where |
347 | S2: BuildHasher, |
348 | { |
349 | Intersection { |
350 | iter: self.iter(), |
351 | other, |
352 | } |
353 | } |
354 | |
355 | /// Return an iterator over all values that are in `self` or `other`. |
356 | /// |
357 | /// Values from `self` are produced in their original order, followed by |
358 | /// values that are unique to `other` in their original order. |
359 | pub fn union<'a, S2>(&'a self, other: &'a IndexSet<T, S2>) -> Union<'a, T, S> |
360 | where |
361 | S2: BuildHasher, |
362 | { |
363 | Union { |
364 | iter: self.iter().chain(other.difference(self)), |
365 | } |
366 | } |
367 | |
368 | /// Return `true` if an equivalent to `value` exists in the set. |
369 | /// |
370 | /// Computes in **O(1)** time (average). |
371 | pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool |
372 | where |
373 | Q: Hash + Equivalent<T>, |
374 | { |
375 | self.map.contains_key(value) |
376 | } |
377 | |
378 | /// Return a reference to the value stored in the set, if it is present, |
379 | /// else `None`. |
380 | /// |
381 | /// Computes in **O(1)** time (average). |
382 | pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T> |
383 | where |
384 | Q: Hash + Equivalent<T>, |
385 | { |
386 | self.map.get_key_value(value).map(|(x, &())| x) |
387 | } |
388 | |
389 | /// Return item index and value |
390 | pub fn get_full<Q: ?Sized>(&self, value: &Q) -> Option<(usize, &T)> |
391 | where |
392 | Q: Hash + Equivalent<T>, |
393 | { |
394 | self.map.get_full(value).map(|(i, x, &())| (i, x)) |
395 | } |
396 | |
397 | /// Return item index, if it exists in the set |
398 | pub fn get_index_of<Q: ?Sized>(&self, value: &Q) -> Option<usize> |
399 | where |
400 | Q: Hash + Equivalent<T>, |
401 | { |
402 | self.map.get_index_of(value) |
403 | } |
404 | |
405 | /// Adds a value to the set, replacing the existing value, if any, that is |
406 | /// equal to the given one, without altering its insertion order. Returns |
407 | /// the replaced value. |
408 | /// |
409 | /// Computes in **O(1)** time (average). |
410 | pub fn replace(&mut self, value: T) -> Option<T> { |
411 | self.replace_full(value).1 |
412 | } |
413 | |
414 | /// Adds a value to the set, replacing the existing value, if any, that is |
415 | /// equal to the given one, without altering its insertion order. Returns |
416 | /// the index of the item and its replaced value. |
417 | /// |
418 | /// Computes in **O(1)** time (average). |
419 | pub fn replace_full(&mut self, value: T) -> (usize, Option<T>) { |
420 | use super::map::Entry::*; |
421 | |
422 | match self.map.entry(value) { |
423 | Vacant(e) => { |
424 | let index = e.index(); |
425 | e.insert(()); |
426 | (index, None) |
427 | } |
428 | Occupied(e) => (e.index(), Some(e.replace_key())), |
429 | } |
430 | } |
431 | |
432 | /// Remove the value from the set, and return `true` if it was present. |
433 | /// |
434 | /// **NOTE:** This is equivalent to `.swap_remove(value)`, if you want |
435 | /// to preserve the order of the values in the set, use `.shift_remove(value)`. |
436 | /// |
437 | /// Computes in **O(1)** time (average). |
438 | pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool |
439 | where |
440 | Q: Hash + Equivalent<T>, |
441 | { |
442 | self.swap_remove(value) |
443 | } |
444 | |
445 | /// Remove the value from the set, and return `true` if it was present. |
446 | /// |
447 | /// Like `Vec::swap_remove`, the value is removed by swapping it with the |
448 | /// last element of the set and popping it off. **This perturbs |
449 | /// the position of what used to be the last element!** |
450 | /// |
451 | /// Return `false` if `value` was not in the set. |
452 | /// |
453 | /// Computes in **O(1)** time (average). |
454 | pub fn swap_remove<Q: ?Sized>(&mut self, value: &Q) -> bool |
455 | where |
456 | Q: Hash + Equivalent<T>, |
457 | { |
458 | self.map.swap_remove(value).is_some() |
459 | } |
460 | |
461 | /// Remove the value from the set, and return `true` if it was present. |
462 | /// |
463 | /// Like `Vec::remove`, the value is removed by shifting all of the |
464 | /// elements that follow it, preserving their relative order. |
465 | /// **This perturbs the index of all of those elements!** |
466 | /// |
467 | /// Return `false` if `value` was not in the set. |
468 | /// |
469 | /// Computes in **O(n)** time (average). |
470 | pub fn shift_remove<Q: ?Sized>(&mut self, value: &Q) -> bool |
471 | where |
472 | Q: Hash + Equivalent<T>, |
473 | { |
474 | self.map.shift_remove(value).is_some() |
475 | } |
476 | |
477 | /// Removes and returns the value in the set, if any, that is equal to the |
478 | /// given one. |
479 | /// |
480 | /// **NOTE:** This is equivalent to `.swap_take(value)`, if you need to |
481 | /// preserve the order of the values in the set, use `.shift_take(value)` |
482 | /// instead. |
483 | /// |
484 | /// Computes in **O(1)** time (average). |
485 | pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T> |
486 | where |
487 | Q: Hash + Equivalent<T>, |
488 | { |
489 | self.swap_take(value) |
490 | } |
491 | |
492 | /// Removes and returns the value in the set, if any, that is equal to the |
493 | /// given one. |
494 | /// |
495 | /// Like `Vec::swap_remove`, the value is removed by swapping it with the |
496 | /// last element of the set and popping it off. **This perturbs |
497 | /// the position of what used to be the last element!** |
498 | /// |
499 | /// Return `None` if `value` was not in the set. |
500 | /// |
501 | /// Computes in **O(1)** time (average). |
502 | pub fn swap_take<Q: ?Sized>(&mut self, value: &Q) -> Option<T> |
503 | where |
504 | Q: Hash + Equivalent<T>, |
505 | { |
506 | self.map.swap_remove_entry(value).map(|(x, ())| x) |
507 | } |
508 | |
509 | /// Removes and returns the value in the set, if any, that is equal to the |
510 | /// given one. |
511 | /// |
512 | /// Like `Vec::remove`, the value is removed by shifting all of the |
513 | /// elements that follow it, preserving their relative order. |
514 | /// **This perturbs the index of all of those elements!** |
515 | /// |
516 | /// Return `None` if `value` was not in the set. |
517 | /// |
518 | /// Computes in **O(n)** time (average). |
519 | pub fn shift_take<Q: ?Sized>(&mut self, value: &Q) -> Option<T> |
520 | where |
521 | Q: Hash + Equivalent<T>, |
522 | { |
523 | self.map.shift_remove_entry(value).map(|(x, ())| x) |
524 | } |
525 | |
526 | /// Remove the value from the set return it and the index it had. |
527 | /// |
528 | /// Like `Vec::swap_remove`, the value is removed by swapping it with the |
529 | /// last element of the set and popping it off. **This perturbs |
530 | /// the position of what used to be the last element!** |
531 | /// |
532 | /// Return `None` if `value` was not in the set. |
533 | pub fn swap_remove_full<Q: ?Sized>(&mut self, value: &Q) -> Option<(usize, T)> |
534 | where |
535 | Q: Hash + Equivalent<T>, |
536 | { |
537 | self.map.swap_remove_full(value).map(|(i, x, ())| (i, x)) |
538 | } |
539 | |
540 | /// Remove the value from the set return it and the index it had. |
541 | /// |
542 | /// Like `Vec::remove`, the value is removed by shifting all of the |
543 | /// elements that follow it, preserving their relative order. |
544 | /// **This perturbs the index of all of those elements!** |
545 | /// |
546 | /// Return `None` if `value` was not in the set. |
547 | pub fn shift_remove_full<Q: ?Sized>(&mut self, value: &Q) -> Option<(usize, T)> |
548 | where |
549 | Q: Hash + Equivalent<T>, |
550 | { |
551 | self.map.shift_remove_full(value).map(|(i, x, ())| (i, x)) |
552 | } |
553 | |
554 | /// Remove the last value |
555 | /// |
556 | /// This preserves the order of the remaining elements. |
557 | /// |
558 | /// Computes in **O(1)** time (average). |
559 | pub fn pop(&mut self) -> Option<T> { |
560 | self.map.pop().map(|(x, ())| x) |
561 | } |
562 | |
563 | /// Scan through each value in the set and keep those where the |
564 | /// closure `keep` returns `true`. |
565 | /// |
566 | /// The elements are visited in order, and remaining elements keep their |
567 | /// order. |
568 | /// |
569 | /// Computes in **O(n)** time (average). |
570 | pub fn retain<F>(&mut self, mut keep: F) |
571 | where |
572 | F: FnMut(&T) -> bool, |
573 | { |
574 | self.map.retain(move |x, &mut ()| keep(x)) |
575 | } |
576 | |
577 | /// Sort the set’s values by their default ordering. |
578 | /// |
579 | /// See [`sort_by`](Self::sort_by) for details. |
580 | pub fn sort(&mut self) |
581 | where |
582 | T: Ord, |
583 | { |
584 | self.map.sort_keys() |
585 | } |
586 | |
587 | /// Sort the set’s values in place using the comparison function `cmp`. |
588 | /// |
589 | /// Computes in **O(n log n)** time and **O(n)** space. The sort is stable. |
590 | pub fn sort_by<F>(&mut self, mut cmp: F) |
591 | where |
592 | F: FnMut(&T, &T) -> Ordering, |
593 | { |
594 | self.map.sort_by(move |a, _, b, _| cmp(a, b)); |
595 | } |
596 | |
597 | /// Sort the values of the set and return a by-value iterator of |
598 | /// the values with the result. |
599 | /// |
600 | /// The sort is stable. |
601 | pub fn sorted_by<F>(self, mut cmp: F) -> IntoIter<T> |
602 | where |
603 | F: FnMut(&T, &T) -> Ordering, |
604 | { |
605 | let mut entries = self.into_entries(); |
606 | entries.sort_by(move |a, b| cmp(&a.key, &b.key)); |
607 | IntoIter { |
608 | iter: entries.into_iter(), |
609 | } |
610 | } |
611 | |
612 | /// Sort the set's values by their default ordering. |
613 | /// |
614 | /// See [`sort_unstable_by`](Self::sort_unstable_by) for details. |
615 | pub fn sort_unstable(&mut self) |
616 | where |
617 | T: Ord, |
618 | { |
619 | self.map.sort_unstable_keys() |
620 | } |
621 | |
622 | /// Sort the set's values in place using the comparison funtion `cmp`. |
623 | /// |
624 | /// Computes in **O(n log n)** time. The sort is unstable. |
625 | pub fn sort_unstable_by<F>(&mut self, mut cmp: F) |
626 | where |
627 | F: FnMut(&T, &T) -> Ordering, |
628 | { |
629 | self.map.sort_unstable_by(move |a, _, b, _| cmp(a, b)) |
630 | } |
631 | |
632 | /// Sort the values of the set and return a by-value iterator of |
633 | /// the values with the result. |
634 | pub fn sorted_unstable_by<F>(self, mut cmp: F) -> IntoIter<T> |
635 | where |
636 | F: FnMut(&T, &T) -> Ordering, |
637 | { |
638 | let mut entries = self.into_entries(); |
639 | entries.sort_unstable_by(move |a, b| cmp(&a.key, &b.key)); |
640 | IntoIter { |
641 | iter: entries.into_iter(), |
642 | } |
643 | } |
644 | |
645 | /// Reverses the order of the set’s values in place. |
646 | /// |
647 | /// Computes in **O(n)** time and **O(1)** space. |
648 | pub fn reverse(&mut self) { |
649 | self.map.reverse() |
650 | } |
651 | } |
652 | |
653 | impl<T, S> IndexSet<T, S> { |
654 | /// Get a value by index |
655 | /// |
656 | /// Valid indices are *0 <= index < self.len()* |
657 | /// |
658 | /// Computes in **O(1)** time. |
659 | pub fn get_index(&self, index: usize) -> Option<&T> { |
660 | self.as_entries().get(index).map(Bucket::key_ref) |
661 | } |
662 | |
663 | /// Get the first value |
664 | /// |
665 | /// Computes in **O(1)** time. |
666 | pub fn first(&self) -> Option<&T> { |
667 | self.as_entries().first().map(Bucket::key_ref) |
668 | } |
669 | |
670 | /// Get the last value |
671 | /// |
672 | /// Computes in **O(1)** time. |
673 | pub fn last(&self) -> Option<&T> { |
674 | self.as_entries().last().map(Bucket::key_ref) |
675 | } |
676 | |
677 | /// Remove the value by index |
678 | /// |
679 | /// Valid indices are *0 <= index < self.len()* |
680 | /// |
681 | /// Like `Vec::swap_remove`, the value is removed by swapping it with the |
682 | /// last element of the set and popping it off. **This perturbs |
683 | /// the position of what used to be the last element!** |
684 | /// |
685 | /// Computes in **O(1)** time (average). |
686 | pub fn swap_remove_index(&mut self, index: usize) -> Option<T> { |
687 | self.map.swap_remove_index(index).map(|(x, ())| x) |
688 | } |
689 | |
690 | /// Remove the value by index |
691 | /// |
692 | /// Valid indices are *0 <= index < self.len()* |
693 | /// |
694 | /// Like `Vec::remove`, the value is removed by shifting all of the |
695 | /// elements that follow it, preserving their relative order. |
696 | /// **This perturbs the index of all of those elements!** |
697 | /// |
698 | /// Computes in **O(n)** time (average). |
699 | pub fn shift_remove_index(&mut self, index: usize) -> Option<T> { |
700 | self.map.shift_remove_index(index).map(|(x, ())| x) |
701 | } |
702 | |
703 | /// Moves the position of a value from one index to another |
704 | /// by shifting all other values in-between. |
705 | /// |
706 | /// * If `from < to`, the other values will shift down while the targeted value moves up. |
707 | /// * If `from > to`, the other values will shift up while the targeted value moves down. |
708 | /// |
709 | /// ***Panics*** if `from` or `to` are out of bounds. |
710 | /// |
711 | /// Computes in **O(n)** time (average). |
712 | pub fn move_index(&mut self, from: usize, to: usize) { |
713 | self.map.move_index(from, to) |
714 | } |
715 | |
716 | /// Swaps the position of two values in the set. |
717 | /// |
718 | /// ***Panics*** if `a` or `b` are out of bounds. |
719 | pub fn swap_indices(&mut self, a: usize, b: usize) { |
720 | self.map.swap_indices(a, b) |
721 | } |
722 | } |
723 | |
724 | /// Access `IndexSet` values at indexed positions. |
725 | /// |
726 | /// # Examples |
727 | /// |
728 | /// ``` |
729 | /// use indexmap::IndexSet; |
730 | /// |
731 | /// let mut set = IndexSet::new(); |
732 | /// for word in "Lorem ipsum dolor sit amet" .split_whitespace() { |
733 | /// set.insert(word.to_string()); |
734 | /// } |
735 | /// assert_eq!(set[0], "Lorem" ); |
736 | /// assert_eq!(set[1], "ipsum" ); |
737 | /// set.reverse(); |
738 | /// assert_eq!(set[0], "amet" ); |
739 | /// assert_eq!(set[1], "sit" ); |
740 | /// set.sort(); |
741 | /// assert_eq!(set[0], "Lorem" ); |
742 | /// assert_eq!(set[1], "amet" ); |
743 | /// ``` |
744 | /// |
745 | /// ```should_panic |
746 | /// use indexmap::IndexSet; |
747 | /// |
748 | /// let mut set = IndexSet::new(); |
749 | /// set.insert("foo" ); |
750 | /// println!("{:?}" , set[10]); // panics! |
751 | /// ``` |
752 | impl<T, S> Index<usize> for IndexSet<T, S> { |
753 | type Output = T; |
754 | |
755 | /// Returns a reference to the value at the supplied `index`. |
756 | /// |
757 | /// ***Panics*** if `index` is out of bounds. |
758 | fn index(&self, index: usize) -> &T { |
759 | self.get_index(index) |
760 | .expect(msg:"IndexSet: index out of bounds" ) |
761 | } |
762 | } |
763 | |
764 | /// An owning iterator over the items of a `IndexSet`. |
765 | /// |
766 | /// This `struct` is created by the [`into_iter`] method on [`IndexSet`] |
767 | /// (provided by the `IntoIterator` trait). See its documentation for more. |
768 | /// |
769 | /// [`IndexSet`]: struct.IndexSet.html |
770 | /// [`into_iter`]: struct.IndexSet.html#method.into_iter |
771 | pub struct IntoIter<T> { |
772 | iter: vec::IntoIter<Bucket<T>>, |
773 | } |
774 | |
775 | impl<T> Iterator for IntoIter<T> { |
776 | type Item = T; |
777 | |
778 | iterator_methods!(Bucket::key); |
779 | } |
780 | |
781 | impl<T> DoubleEndedIterator for IntoIter<T> { |
782 | double_ended_iterator_methods!(Bucket::key); |
783 | } |
784 | |
785 | impl<T> ExactSizeIterator for IntoIter<T> { |
786 | fn len(&self) -> usize { |
787 | self.iter.len() |
788 | } |
789 | } |
790 | |
791 | impl<T> FusedIterator for IntoIter<T> {} |
792 | |
793 | impl<T: fmt::Debug> fmt::Debug for IntoIter<T> { |
794 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
795 | let iter: impl Iterator = self.iter.as_slice().iter().map(Bucket::key_ref); |
796 | f.debug_list().entries(iter).finish() |
797 | } |
798 | } |
799 | |
800 | /// An iterator over the items of a `IndexSet`. |
801 | /// |
802 | /// This `struct` is created by the [`iter`] method on [`IndexSet`]. |
803 | /// See its documentation for more. |
804 | /// |
805 | /// [`IndexSet`]: struct.IndexSet.html |
806 | /// [`iter`]: struct.IndexSet.html#method.iter |
807 | pub struct Iter<'a, T> { |
808 | iter: slice::Iter<'a, Bucket<T>>, |
809 | } |
810 | |
811 | impl<'a, T> Iterator for Iter<'a, T> { |
812 | type Item = &'a T; |
813 | |
814 | iterator_methods!(Bucket::key_ref); |
815 | } |
816 | |
817 | impl<T> DoubleEndedIterator for Iter<'_, T> { |
818 | double_ended_iterator_methods!(Bucket::key_ref); |
819 | } |
820 | |
821 | impl<T> ExactSizeIterator for Iter<'_, T> { |
822 | fn len(&self) -> usize { |
823 | self.iter.len() |
824 | } |
825 | } |
826 | |
827 | impl<T> FusedIterator for Iter<'_, T> {} |
828 | |
829 | impl<T> Clone for Iter<'_, T> { |
830 | fn clone(&self) -> Self { |
831 | Iter { |
832 | iter: self.iter.clone(), |
833 | } |
834 | } |
835 | } |
836 | |
837 | impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> { |
838 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
839 | f.debug_list().entries(self.clone()).finish() |
840 | } |
841 | } |
842 | |
843 | /// A draining iterator over the items of a `IndexSet`. |
844 | /// |
845 | /// This `struct` is created by the [`drain`] method on [`IndexSet`]. |
846 | /// See its documentation for more. |
847 | /// |
848 | /// [`IndexSet`]: struct.IndexSet.html |
849 | /// [`drain`]: struct.IndexSet.html#method.drain |
850 | pub struct Drain<'a, T> { |
851 | iter: vec::Drain<'a, Bucket<T>>, |
852 | } |
853 | |
854 | impl<T> Iterator for Drain<'_, T> { |
855 | type Item = T; |
856 | |
857 | iterator_methods!(Bucket::key); |
858 | } |
859 | |
860 | impl<T> DoubleEndedIterator for Drain<'_, T> { |
861 | double_ended_iterator_methods!(Bucket::key); |
862 | } |
863 | |
864 | impl<T> ExactSizeIterator for Drain<'_, T> { |
865 | fn len(&self) -> usize { |
866 | self.iter.len() |
867 | } |
868 | } |
869 | |
870 | impl<T> FusedIterator for Drain<'_, T> {} |
871 | |
872 | impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> { |
873 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
874 | let iter: impl Iterator = self.iter.as_slice().iter().map(Bucket::key_ref); |
875 | f.debug_list().entries(iter).finish() |
876 | } |
877 | } |
878 | |
879 | impl<'a, T, S> IntoIterator for &'a IndexSet<T, S> { |
880 | type Item = &'a T; |
881 | type IntoIter = Iter<'a, T>; |
882 | |
883 | fn into_iter(self) -> Self::IntoIter { |
884 | self.iter() |
885 | } |
886 | } |
887 | |
888 | impl<T, S> IntoIterator for IndexSet<T, S> { |
889 | type Item = T; |
890 | type IntoIter = IntoIter<T>; |
891 | |
892 | fn into_iter(self) -> Self::IntoIter { |
893 | IntoIter { |
894 | iter: self.into_entries().into_iter(), |
895 | } |
896 | } |
897 | } |
898 | |
899 | impl<T, S> FromIterator<T> for IndexSet<T, S> |
900 | where |
901 | T: Hash + Eq, |
902 | S: BuildHasher + Default, |
903 | { |
904 | fn from_iter<I: IntoIterator<Item = T>>(iterable: I) -> Self { |
905 | let iter: impl Iterator = iterable.into_iter().map(|x: T| (x, ())); |
906 | IndexSet { |
907 | map: IndexMap::from_iter(iter), |
908 | } |
909 | } |
910 | } |
911 | |
912 | #[cfg (has_std)] |
913 | impl<T, const N: usize> From<[T; N]> for IndexSet<T, RandomState> |
914 | where |
915 | T: Eq + Hash, |
916 | { |
917 | /// # Examples |
918 | /// |
919 | /// ``` |
920 | /// use indexmap::IndexSet; |
921 | /// |
922 | /// let set1 = IndexSet::from([1, 2, 3, 4]); |
923 | /// let set2: IndexSet<_> = [1, 2, 3, 4].into(); |
924 | /// assert_eq!(set1, set2); |
925 | /// ``` |
926 | fn from(arr: [T; N]) -> Self { |
927 | Self::from_iter(arr) |
928 | } |
929 | } |
930 | |
931 | impl<T, S> Extend<T> for IndexSet<T, S> |
932 | where |
933 | T: Hash + Eq, |
934 | S: BuildHasher, |
935 | { |
936 | fn extend<I: IntoIterator<Item = T>>(&mut self, iterable: I) { |
937 | let iter: impl Iterator = iterable.into_iter().map(|x: T| (x, ())); |
938 | self.map.extend(iter); |
939 | } |
940 | } |
941 | |
942 | impl<'a, T, S> Extend<&'a T> for IndexSet<T, S> |
943 | where |
944 | T: Hash + Eq + Copy + 'a, |
945 | S: BuildHasher, |
946 | { |
947 | fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iterable: I) { |
948 | let iter: impl Iterator = iterable.into_iter().copied(); |
949 | self.extend(iter); |
950 | } |
951 | } |
952 | |
953 | impl<T, S> Default for IndexSet<T, S> |
954 | where |
955 | S: Default, |
956 | { |
957 | /// Return an empty `IndexSet` |
958 | fn default() -> Self { |
959 | IndexSet { |
960 | map: IndexMap::default(), |
961 | } |
962 | } |
963 | } |
964 | |
965 | impl<T, S1, S2> PartialEq<IndexSet<T, S2>> for IndexSet<T, S1> |
966 | where |
967 | T: Hash + Eq, |
968 | S1: BuildHasher, |
969 | S2: BuildHasher, |
970 | { |
971 | fn eq(&self, other: &IndexSet<T, S2>) -> bool { |
972 | self.len() == other.len() && self.is_subset(other) |
973 | } |
974 | } |
975 | |
976 | impl<T, S> Eq for IndexSet<T, S> |
977 | where |
978 | T: Eq + Hash, |
979 | S: BuildHasher, |
980 | { |
981 | } |
982 | |
983 | impl<T, S> IndexSet<T, S> |
984 | where |
985 | T: Eq + Hash, |
986 | S: BuildHasher, |
987 | { |
988 | /// Returns `true` if `self` has no elements in common with `other`. |
989 | pub fn is_disjoint<S2>(&self, other: &IndexSet<T, S2>) -> bool |
990 | where |
991 | S2: BuildHasher, |
992 | { |
993 | if self.len() <= other.len() { |
994 | self.iter().all(move |value| !other.contains(value)) |
995 | } else { |
996 | other.iter().all(move |value| !self.contains(value)) |
997 | } |
998 | } |
999 | |
1000 | /// Returns `true` if all elements of `self` are contained in `other`. |
1001 | pub fn is_subset<S2>(&self, other: &IndexSet<T, S2>) -> bool |
1002 | where |
1003 | S2: BuildHasher, |
1004 | { |
1005 | self.len() <= other.len() && self.iter().all(move |value| other.contains(value)) |
1006 | } |
1007 | |
1008 | /// Returns `true` if all elements of `other` are contained in `self`. |
1009 | pub fn is_superset<S2>(&self, other: &IndexSet<T, S2>) -> bool |
1010 | where |
1011 | S2: BuildHasher, |
1012 | { |
1013 | other.is_subset(self) |
1014 | } |
1015 | } |
1016 | |
1017 | /// A lazy iterator producing elements in the difference of `IndexSet`s. |
1018 | /// |
1019 | /// This `struct` is created by the [`difference`] method on [`IndexSet`]. |
1020 | /// See its documentation for more. |
1021 | /// |
1022 | /// [`IndexSet`]: struct.IndexSet.html |
1023 | /// [`difference`]: struct.IndexSet.html#method.difference |
1024 | pub struct Difference<'a, T, S> { |
1025 | iter: Iter<'a, T>, |
1026 | other: &'a IndexSet<T, S>, |
1027 | } |
1028 | |
1029 | impl<'a, T, S> Iterator for Difference<'a, T, S> |
1030 | where |
1031 | T: Eq + Hash, |
1032 | S: BuildHasher, |
1033 | { |
1034 | type Item = &'a T; |
1035 | |
1036 | fn next(&mut self) -> Option<Self::Item> { |
1037 | while let Some(item: &T) = self.iter.next() { |
1038 | if !self.other.contains(item) { |
1039 | return Some(item); |
1040 | } |
1041 | } |
1042 | None |
1043 | } |
1044 | |
1045 | fn size_hint(&self) -> (usize, Option<usize>) { |
1046 | (0, self.iter.size_hint().1) |
1047 | } |
1048 | } |
1049 | |
1050 | impl<T, S> DoubleEndedIterator for Difference<'_, T, S> |
1051 | where |
1052 | T: Eq + Hash, |
1053 | S: BuildHasher, |
1054 | { |
1055 | fn next_back(&mut self) -> Option<Self::Item> { |
1056 | while let Some(item: &T) = self.iter.next_back() { |
1057 | if !self.other.contains(item) { |
1058 | return Some(item); |
1059 | } |
1060 | } |
1061 | None |
1062 | } |
1063 | } |
1064 | |
1065 | impl<T, S> FusedIterator for Difference<'_, T, S> |
1066 | where |
1067 | T: Eq + Hash, |
1068 | S: BuildHasher, |
1069 | { |
1070 | } |
1071 | |
1072 | impl<T, S> Clone for Difference<'_, T, S> { |
1073 | fn clone(&self) -> Self { |
1074 | Difference { |
1075 | iter: self.iter.clone(), |
1076 | ..*self |
1077 | } |
1078 | } |
1079 | } |
1080 | |
1081 | impl<T, S> fmt::Debug for Difference<'_, T, S> |
1082 | where |
1083 | T: fmt::Debug + Eq + Hash, |
1084 | S: BuildHasher, |
1085 | { |
1086 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1087 | f.debug_list().entries(self.clone()).finish() |
1088 | } |
1089 | } |
1090 | |
1091 | /// A lazy iterator producing elements in the intersection of `IndexSet`s. |
1092 | /// |
1093 | /// This `struct` is created by the [`intersection`] method on [`IndexSet`]. |
1094 | /// See its documentation for more. |
1095 | /// |
1096 | /// [`IndexSet`]: struct.IndexSet.html |
1097 | /// [`intersection`]: struct.IndexSet.html#method.intersection |
1098 | pub struct Intersection<'a, T, S> { |
1099 | iter: Iter<'a, T>, |
1100 | other: &'a IndexSet<T, S>, |
1101 | } |
1102 | |
1103 | impl<'a, T, S> Iterator for Intersection<'a, T, S> |
1104 | where |
1105 | T: Eq + Hash, |
1106 | S: BuildHasher, |
1107 | { |
1108 | type Item = &'a T; |
1109 | |
1110 | fn next(&mut self) -> Option<Self::Item> { |
1111 | while let Some(item: &T) = self.iter.next() { |
1112 | if self.other.contains(item) { |
1113 | return Some(item); |
1114 | } |
1115 | } |
1116 | None |
1117 | } |
1118 | |
1119 | fn size_hint(&self) -> (usize, Option<usize>) { |
1120 | (0, self.iter.size_hint().1) |
1121 | } |
1122 | } |
1123 | |
1124 | impl<T, S> DoubleEndedIterator for Intersection<'_, T, S> |
1125 | where |
1126 | T: Eq + Hash, |
1127 | S: BuildHasher, |
1128 | { |
1129 | fn next_back(&mut self) -> Option<Self::Item> { |
1130 | while let Some(item: &T) = self.iter.next_back() { |
1131 | if self.other.contains(item) { |
1132 | return Some(item); |
1133 | } |
1134 | } |
1135 | None |
1136 | } |
1137 | } |
1138 | |
1139 | impl<T, S> FusedIterator for Intersection<'_, T, S> |
1140 | where |
1141 | T: Eq + Hash, |
1142 | S: BuildHasher, |
1143 | { |
1144 | } |
1145 | |
1146 | impl<T, S> Clone for Intersection<'_, T, S> { |
1147 | fn clone(&self) -> Self { |
1148 | Intersection { |
1149 | iter: self.iter.clone(), |
1150 | ..*self |
1151 | } |
1152 | } |
1153 | } |
1154 | |
1155 | impl<T, S> fmt::Debug for Intersection<'_, T, S> |
1156 | where |
1157 | T: fmt::Debug + Eq + Hash, |
1158 | S: BuildHasher, |
1159 | { |
1160 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1161 | f.debug_list().entries(self.clone()).finish() |
1162 | } |
1163 | } |
1164 | |
1165 | /// A lazy iterator producing elements in the symmetric difference of `IndexSet`s. |
1166 | /// |
1167 | /// This `struct` is created by the [`symmetric_difference`] method on |
1168 | /// [`IndexSet`]. See its documentation for more. |
1169 | /// |
1170 | /// [`IndexSet`]: struct.IndexSet.html |
1171 | /// [`symmetric_difference`]: struct.IndexSet.html#method.symmetric_difference |
1172 | pub struct SymmetricDifference<'a, T, S1, S2> { |
1173 | iter: Chain<Difference<'a, T, S2>, Difference<'a, T, S1>>, |
1174 | } |
1175 | |
1176 | impl<'a, T, S1, S2> Iterator for SymmetricDifference<'a, T, S1, S2> |
1177 | where |
1178 | T: Eq + Hash, |
1179 | S1: BuildHasher, |
1180 | S2: BuildHasher, |
1181 | { |
1182 | type Item = &'a T; |
1183 | |
1184 | fn next(&mut self) -> Option<Self::Item> { |
1185 | self.iter.next() |
1186 | } |
1187 | |
1188 | fn size_hint(&self) -> (usize, Option<usize>) { |
1189 | self.iter.size_hint() |
1190 | } |
1191 | |
1192 | fn fold<B, F>(self, init: B, f: F) -> B |
1193 | where |
1194 | F: FnMut(B, Self::Item) -> B, |
1195 | { |
1196 | self.iter.fold(init, f) |
1197 | } |
1198 | } |
1199 | |
1200 | impl<T, S1, S2> DoubleEndedIterator for SymmetricDifference<'_, T, S1, S2> |
1201 | where |
1202 | T: Eq + Hash, |
1203 | S1: BuildHasher, |
1204 | S2: BuildHasher, |
1205 | { |
1206 | fn next_back(&mut self) -> Option<Self::Item> { |
1207 | self.iter.next_back() |
1208 | } |
1209 | |
1210 | fn rfold<B, F>(self, init: B, f: F) -> B |
1211 | where |
1212 | F: FnMut(B, Self::Item) -> B, |
1213 | { |
1214 | self.iter.rfold(init, f) |
1215 | } |
1216 | } |
1217 | |
1218 | impl<T, S1, S2> FusedIterator for SymmetricDifference<'_, T, S1, S2> |
1219 | where |
1220 | T: Eq + Hash, |
1221 | S1: BuildHasher, |
1222 | S2: BuildHasher, |
1223 | { |
1224 | } |
1225 | |
1226 | impl<T, S1, S2> Clone for SymmetricDifference<'_, T, S1, S2> { |
1227 | fn clone(&self) -> Self { |
1228 | SymmetricDifference { |
1229 | iter: self.iter.clone(), |
1230 | } |
1231 | } |
1232 | } |
1233 | |
1234 | impl<T, S1, S2> fmt::Debug for SymmetricDifference<'_, T, S1, S2> |
1235 | where |
1236 | T: fmt::Debug + Eq + Hash, |
1237 | S1: BuildHasher, |
1238 | S2: BuildHasher, |
1239 | { |
1240 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1241 | f.debug_list().entries(self.clone()).finish() |
1242 | } |
1243 | } |
1244 | |
1245 | /// A lazy iterator producing elements in the union of `IndexSet`s. |
1246 | /// |
1247 | /// This `struct` is created by the [`union`] method on [`IndexSet`]. |
1248 | /// See its documentation for more. |
1249 | /// |
1250 | /// [`IndexSet`]: struct.IndexSet.html |
1251 | /// [`union`]: struct.IndexSet.html#method.union |
1252 | pub struct Union<'a, T, S> { |
1253 | iter: Chain<Iter<'a, T>, Difference<'a, T, S>>, |
1254 | } |
1255 | |
1256 | impl<'a, T, S> Iterator for Union<'a, T, S> |
1257 | where |
1258 | T: Eq + Hash, |
1259 | S: BuildHasher, |
1260 | { |
1261 | type Item = &'a T; |
1262 | |
1263 | fn next(&mut self) -> Option<Self::Item> { |
1264 | self.iter.next() |
1265 | } |
1266 | |
1267 | fn size_hint(&self) -> (usize, Option<usize>) { |
1268 | self.iter.size_hint() |
1269 | } |
1270 | |
1271 | fn fold<B, F>(self, init: B, f: F) -> B |
1272 | where |
1273 | F: FnMut(B, Self::Item) -> B, |
1274 | { |
1275 | self.iter.fold(init, f) |
1276 | } |
1277 | } |
1278 | |
1279 | impl<T, S> DoubleEndedIterator for Union<'_, T, S> |
1280 | where |
1281 | T: Eq + Hash, |
1282 | S: BuildHasher, |
1283 | { |
1284 | fn next_back(&mut self) -> Option<Self::Item> { |
1285 | self.iter.next_back() |
1286 | } |
1287 | |
1288 | fn rfold<B, F>(self, init: B, f: F) -> B |
1289 | where |
1290 | F: FnMut(B, Self::Item) -> B, |
1291 | { |
1292 | self.iter.rfold(init, f) |
1293 | } |
1294 | } |
1295 | |
1296 | impl<T, S> FusedIterator for Union<'_, T, S> |
1297 | where |
1298 | T: Eq + Hash, |
1299 | S: BuildHasher, |
1300 | { |
1301 | } |
1302 | |
1303 | impl<T, S> Clone for Union<'_, T, S> { |
1304 | fn clone(&self) -> Self { |
1305 | Union { |
1306 | iter: self.iter.clone(), |
1307 | } |
1308 | } |
1309 | } |
1310 | |
1311 | impl<T, S> fmt::Debug for Union<'_, T, S> |
1312 | where |
1313 | T: fmt::Debug + Eq + Hash, |
1314 | S: BuildHasher, |
1315 | { |
1316 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1317 | f.debug_list().entries(self.clone()).finish() |
1318 | } |
1319 | } |
1320 | |
1321 | impl<T, S1, S2> BitAnd<&IndexSet<T, S2>> for &IndexSet<T, S1> |
1322 | where |
1323 | T: Eq + Hash + Clone, |
1324 | S1: BuildHasher + Default, |
1325 | S2: BuildHasher, |
1326 | { |
1327 | type Output = IndexSet<T, S1>; |
1328 | |
1329 | /// Returns the set intersection, cloned into a new set. |
1330 | /// |
1331 | /// Values are collected in the same order that they appear in `self`. |
1332 | fn bitand(self, other: &IndexSet<T, S2>) -> Self::Output { |
1333 | self.intersection(other).cloned().collect() |
1334 | } |
1335 | } |
1336 | |
1337 | impl<T, S1, S2> BitOr<&IndexSet<T, S2>> for &IndexSet<T, S1> |
1338 | where |
1339 | T: Eq + Hash + Clone, |
1340 | S1: BuildHasher + Default, |
1341 | S2: BuildHasher, |
1342 | { |
1343 | type Output = IndexSet<T, S1>; |
1344 | |
1345 | /// Returns the set union, cloned into a new set. |
1346 | /// |
1347 | /// Values from `self` are collected in their original order, followed by |
1348 | /// values that are unique to `other` in their original order. |
1349 | fn bitor(self, other: &IndexSet<T, S2>) -> Self::Output { |
1350 | self.union(other).cloned().collect() |
1351 | } |
1352 | } |
1353 | |
1354 | impl<T, S1, S2> BitXor<&IndexSet<T, S2>> for &IndexSet<T, S1> |
1355 | where |
1356 | T: Eq + Hash + Clone, |
1357 | S1: BuildHasher + Default, |
1358 | S2: BuildHasher, |
1359 | { |
1360 | type Output = IndexSet<T, S1>; |
1361 | |
1362 | /// Returns the set symmetric-difference, cloned into a new set. |
1363 | /// |
1364 | /// Values from `self` are collected in their original order, followed by |
1365 | /// values from `other` in their original order. |
1366 | fn bitxor(self, other: &IndexSet<T, S2>) -> Self::Output { |
1367 | self.symmetric_difference(other).cloned().collect() |
1368 | } |
1369 | } |
1370 | |
1371 | impl<T, S1, S2> Sub<&IndexSet<T, S2>> for &IndexSet<T, S1> |
1372 | where |
1373 | T: Eq + Hash + Clone, |
1374 | S1: BuildHasher + Default, |
1375 | S2: BuildHasher, |
1376 | { |
1377 | type Output = IndexSet<T, S1>; |
1378 | |
1379 | /// Returns the set difference, cloned into a new set. |
1380 | /// |
1381 | /// Values are collected in the same order that they appear in `self`. |
1382 | fn sub(self, other: &IndexSet<T, S2>) -> Self::Output { |
1383 | self.difference(other).cloned().collect() |
1384 | } |
1385 | } |
1386 | |
1387 | #[cfg (test)] |
1388 | mod tests { |
1389 | use super::*; |
1390 | use std::string::String; |
1391 | |
1392 | #[test ] |
1393 | fn it_works() { |
1394 | let mut set = IndexSet::new(); |
1395 | assert_eq!(set.is_empty(), true); |
1396 | set.insert(1); |
1397 | set.insert(1); |
1398 | assert_eq!(set.len(), 1); |
1399 | assert!(set.get(&1).is_some()); |
1400 | assert_eq!(set.is_empty(), false); |
1401 | } |
1402 | |
1403 | #[test ] |
1404 | fn new() { |
1405 | let set = IndexSet::<String>::new(); |
1406 | println!(" {:?}" , set); |
1407 | assert_eq!(set.capacity(), 0); |
1408 | assert_eq!(set.len(), 0); |
1409 | assert_eq!(set.is_empty(), true); |
1410 | } |
1411 | |
1412 | #[test ] |
1413 | fn insert() { |
1414 | let insert = [0, 4, 2, 12, 8, 7, 11, 5]; |
1415 | let not_present = [1, 3, 6, 9, 10]; |
1416 | let mut set = IndexSet::with_capacity(insert.len()); |
1417 | |
1418 | for (i, &elt) in insert.iter().enumerate() { |
1419 | assert_eq!(set.len(), i); |
1420 | set.insert(elt); |
1421 | assert_eq!(set.len(), i + 1); |
1422 | assert_eq!(set.get(&elt), Some(&elt)); |
1423 | } |
1424 | println!(" {:?}" , set); |
1425 | |
1426 | for &elt in ¬_present { |
1427 | assert!(set.get(&elt).is_none()); |
1428 | } |
1429 | } |
1430 | |
1431 | #[test ] |
1432 | fn insert_full() { |
1433 | let insert = vec![9, 2, 7, 1, 4, 6, 13]; |
1434 | let present = vec![1, 6, 2]; |
1435 | let mut set = IndexSet::with_capacity(insert.len()); |
1436 | |
1437 | for (i, &elt) in insert.iter().enumerate() { |
1438 | assert_eq!(set.len(), i); |
1439 | let (index, success) = set.insert_full(elt); |
1440 | assert!(success); |
1441 | assert_eq!(Some(index), set.get_full(&elt).map(|x| x.0)); |
1442 | assert_eq!(set.len(), i + 1); |
1443 | } |
1444 | |
1445 | let len = set.len(); |
1446 | for &elt in &present { |
1447 | let (index, success) = set.insert_full(elt); |
1448 | assert!(!success); |
1449 | assert_eq!(Some(index), set.get_full(&elt).map(|x| x.0)); |
1450 | assert_eq!(set.len(), len); |
1451 | } |
1452 | } |
1453 | |
1454 | #[test ] |
1455 | fn insert_2() { |
1456 | let mut set = IndexSet::with_capacity(16); |
1457 | |
1458 | let mut values = vec![]; |
1459 | values.extend(0..16); |
1460 | values.extend(if cfg!(miri) { 32..64 } else { 128..267 }); |
1461 | |
1462 | for &i in &values { |
1463 | let old_set = set.clone(); |
1464 | set.insert(i); |
1465 | for value in old_set.iter() { |
1466 | if set.get(value).is_none() { |
1467 | println!("old_set: {:?}" , old_set); |
1468 | println!("set: {:?}" , set); |
1469 | panic!("did not find {} in set" , value); |
1470 | } |
1471 | } |
1472 | } |
1473 | |
1474 | for &i in &values { |
1475 | assert!(set.get(&i).is_some(), "did not find {}" , i); |
1476 | } |
1477 | } |
1478 | |
1479 | #[test ] |
1480 | fn insert_dup() { |
1481 | let mut elements = vec![0, 2, 4, 6, 8]; |
1482 | let mut set: IndexSet<u8> = elements.drain(..).collect(); |
1483 | { |
1484 | let (i, v) = set.get_full(&0).unwrap(); |
1485 | assert_eq!(set.len(), 5); |
1486 | assert_eq!(i, 0); |
1487 | assert_eq!(*v, 0); |
1488 | } |
1489 | { |
1490 | let inserted = set.insert(0); |
1491 | let (i, v) = set.get_full(&0).unwrap(); |
1492 | assert_eq!(set.len(), 5); |
1493 | assert_eq!(inserted, false); |
1494 | assert_eq!(i, 0); |
1495 | assert_eq!(*v, 0); |
1496 | } |
1497 | } |
1498 | |
1499 | #[test ] |
1500 | fn insert_order() { |
1501 | let insert = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23]; |
1502 | let mut set = IndexSet::new(); |
1503 | |
1504 | for &elt in &insert { |
1505 | set.insert(elt); |
1506 | } |
1507 | |
1508 | assert_eq!(set.iter().count(), set.len()); |
1509 | assert_eq!(set.iter().count(), insert.len()); |
1510 | for (a, b) in insert.iter().zip(set.iter()) { |
1511 | assert_eq!(a, b); |
1512 | } |
1513 | for (i, v) in (0..insert.len()).zip(set.iter()) { |
1514 | assert_eq!(set.get_index(i).unwrap(), v); |
1515 | } |
1516 | } |
1517 | |
1518 | #[test ] |
1519 | fn replace() { |
1520 | let replace = [0, 4, 2, 12, 8, 7, 11, 5]; |
1521 | let not_present = [1, 3, 6, 9, 10]; |
1522 | let mut set = IndexSet::with_capacity(replace.len()); |
1523 | |
1524 | for (i, &elt) in replace.iter().enumerate() { |
1525 | assert_eq!(set.len(), i); |
1526 | set.replace(elt); |
1527 | assert_eq!(set.len(), i + 1); |
1528 | assert_eq!(set.get(&elt), Some(&elt)); |
1529 | } |
1530 | println!(" {:?}" , set); |
1531 | |
1532 | for &elt in ¬_present { |
1533 | assert!(set.get(&elt).is_none()); |
1534 | } |
1535 | } |
1536 | |
1537 | #[test ] |
1538 | fn replace_full() { |
1539 | let replace = vec![9, 2, 7, 1, 4, 6, 13]; |
1540 | let present = vec![1, 6, 2]; |
1541 | let mut set = IndexSet::with_capacity(replace.len()); |
1542 | |
1543 | for (i, &elt) in replace.iter().enumerate() { |
1544 | assert_eq!(set.len(), i); |
1545 | let (index, replaced) = set.replace_full(elt); |
1546 | assert!(replaced.is_none()); |
1547 | assert_eq!(Some(index), set.get_full(&elt).map(|x| x.0)); |
1548 | assert_eq!(set.len(), i + 1); |
1549 | } |
1550 | |
1551 | let len = set.len(); |
1552 | for &elt in &present { |
1553 | let (index, replaced) = set.replace_full(elt); |
1554 | assert_eq!(Some(elt), replaced); |
1555 | assert_eq!(Some(index), set.get_full(&elt).map(|x| x.0)); |
1556 | assert_eq!(set.len(), len); |
1557 | } |
1558 | } |
1559 | |
1560 | #[test ] |
1561 | fn replace_2() { |
1562 | let mut set = IndexSet::with_capacity(16); |
1563 | |
1564 | let mut values = vec![]; |
1565 | values.extend(0..16); |
1566 | values.extend(if cfg!(miri) { 32..64 } else { 128..267 }); |
1567 | |
1568 | for &i in &values { |
1569 | let old_set = set.clone(); |
1570 | set.replace(i); |
1571 | for value in old_set.iter() { |
1572 | if set.get(value).is_none() { |
1573 | println!("old_set: {:?}" , old_set); |
1574 | println!("set: {:?}" , set); |
1575 | panic!("did not find {} in set" , value); |
1576 | } |
1577 | } |
1578 | } |
1579 | |
1580 | for &i in &values { |
1581 | assert!(set.get(&i).is_some(), "did not find {}" , i); |
1582 | } |
1583 | } |
1584 | |
1585 | #[test ] |
1586 | fn replace_dup() { |
1587 | let mut elements = vec![0, 2, 4, 6, 8]; |
1588 | let mut set: IndexSet<u8> = elements.drain(..).collect(); |
1589 | { |
1590 | let (i, v) = set.get_full(&0).unwrap(); |
1591 | assert_eq!(set.len(), 5); |
1592 | assert_eq!(i, 0); |
1593 | assert_eq!(*v, 0); |
1594 | } |
1595 | { |
1596 | let replaced = set.replace(0); |
1597 | let (i, v) = set.get_full(&0).unwrap(); |
1598 | assert_eq!(set.len(), 5); |
1599 | assert_eq!(replaced, Some(0)); |
1600 | assert_eq!(i, 0); |
1601 | assert_eq!(*v, 0); |
1602 | } |
1603 | } |
1604 | |
1605 | #[test ] |
1606 | fn replace_order() { |
1607 | let replace = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23]; |
1608 | let mut set = IndexSet::new(); |
1609 | |
1610 | for &elt in &replace { |
1611 | set.replace(elt); |
1612 | } |
1613 | |
1614 | assert_eq!(set.iter().count(), set.len()); |
1615 | assert_eq!(set.iter().count(), replace.len()); |
1616 | for (a, b) in replace.iter().zip(set.iter()) { |
1617 | assert_eq!(a, b); |
1618 | } |
1619 | for (i, v) in (0..replace.len()).zip(set.iter()) { |
1620 | assert_eq!(set.get_index(i).unwrap(), v); |
1621 | } |
1622 | } |
1623 | |
1624 | #[test ] |
1625 | fn grow() { |
1626 | let insert = [0, 4, 2, 12, 8, 7, 11]; |
1627 | let not_present = [1, 3, 6, 9, 10]; |
1628 | let mut set = IndexSet::with_capacity(insert.len()); |
1629 | |
1630 | for (i, &elt) in insert.iter().enumerate() { |
1631 | assert_eq!(set.len(), i); |
1632 | set.insert(elt); |
1633 | assert_eq!(set.len(), i + 1); |
1634 | assert_eq!(set.get(&elt), Some(&elt)); |
1635 | } |
1636 | |
1637 | println!(" {:?}" , set); |
1638 | for &elt in &insert { |
1639 | set.insert(elt * 10); |
1640 | } |
1641 | for &elt in &insert { |
1642 | set.insert(elt * 100); |
1643 | } |
1644 | for (i, &elt) in insert.iter().cycle().enumerate().take(100) { |
1645 | set.insert(elt * 100 + i as i32); |
1646 | } |
1647 | println!(" {:?}" , set); |
1648 | for &elt in ¬_present { |
1649 | assert!(set.get(&elt).is_none()); |
1650 | } |
1651 | } |
1652 | |
1653 | #[test ] |
1654 | fn reserve() { |
1655 | let mut set = IndexSet::<usize>::new(); |
1656 | assert_eq!(set.capacity(), 0); |
1657 | set.reserve(100); |
1658 | let capacity = set.capacity(); |
1659 | assert!(capacity >= 100); |
1660 | for i in 0..capacity { |
1661 | assert_eq!(set.len(), i); |
1662 | set.insert(i); |
1663 | assert_eq!(set.len(), i + 1); |
1664 | assert_eq!(set.capacity(), capacity); |
1665 | assert_eq!(set.get(&i), Some(&i)); |
1666 | } |
1667 | set.insert(capacity); |
1668 | assert_eq!(set.len(), capacity + 1); |
1669 | assert!(set.capacity() > capacity); |
1670 | assert_eq!(set.get(&capacity), Some(&capacity)); |
1671 | } |
1672 | |
1673 | #[test ] |
1674 | fn shrink_to_fit() { |
1675 | let mut set = IndexSet::<usize>::new(); |
1676 | assert_eq!(set.capacity(), 0); |
1677 | for i in 0..100 { |
1678 | assert_eq!(set.len(), i); |
1679 | set.insert(i); |
1680 | assert_eq!(set.len(), i + 1); |
1681 | assert!(set.capacity() >= i + 1); |
1682 | assert_eq!(set.get(&i), Some(&i)); |
1683 | set.shrink_to_fit(); |
1684 | assert_eq!(set.len(), i + 1); |
1685 | assert_eq!(set.capacity(), i + 1); |
1686 | assert_eq!(set.get(&i), Some(&i)); |
1687 | } |
1688 | } |
1689 | |
1690 | #[test ] |
1691 | fn remove() { |
1692 | let insert = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23]; |
1693 | let mut set = IndexSet::new(); |
1694 | |
1695 | for &elt in &insert { |
1696 | set.insert(elt); |
1697 | } |
1698 | |
1699 | assert_eq!(set.iter().count(), set.len()); |
1700 | assert_eq!(set.iter().count(), insert.len()); |
1701 | for (a, b) in insert.iter().zip(set.iter()) { |
1702 | assert_eq!(a, b); |
1703 | } |
1704 | |
1705 | let remove_fail = [99, 77]; |
1706 | let remove = [4, 12, 8, 7]; |
1707 | |
1708 | for &value in &remove_fail { |
1709 | assert!(set.swap_remove_full(&value).is_none()); |
1710 | } |
1711 | println!(" {:?}" , set); |
1712 | for &value in &remove { |
1713 | //println!("{:?}", set); |
1714 | let index = set.get_full(&value).unwrap().0; |
1715 | assert_eq!(set.swap_remove_full(&value), Some((index, value))); |
1716 | } |
1717 | println!(" {:?}" , set); |
1718 | |
1719 | for value in &insert { |
1720 | assert_eq!(set.get(value).is_some(), !remove.contains(value)); |
1721 | } |
1722 | assert_eq!(set.len(), insert.len() - remove.len()); |
1723 | assert_eq!(set.iter().count(), insert.len() - remove.len()); |
1724 | } |
1725 | |
1726 | #[test ] |
1727 | fn swap_remove_index() { |
1728 | let insert = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23]; |
1729 | let mut set = IndexSet::new(); |
1730 | |
1731 | for &elt in &insert { |
1732 | set.insert(elt); |
1733 | } |
1734 | |
1735 | let mut vector = insert.to_vec(); |
1736 | let remove_sequence = &[3, 3, 10, 4, 5, 4, 3, 0, 1]; |
1737 | |
1738 | // check that the same swap remove sequence on vec and set |
1739 | // have the same result. |
1740 | for &rm in remove_sequence { |
1741 | let out_vec = vector.swap_remove(rm); |
1742 | let out_set = set.swap_remove_index(rm).unwrap(); |
1743 | assert_eq!(out_vec, out_set); |
1744 | } |
1745 | assert_eq!(vector.len(), set.len()); |
1746 | for (a, b) in vector.iter().zip(set.iter()) { |
1747 | assert_eq!(a, b); |
1748 | } |
1749 | } |
1750 | |
1751 | #[test ] |
1752 | fn partial_eq_and_eq() { |
1753 | let mut set_a = IndexSet::new(); |
1754 | set_a.insert(1); |
1755 | set_a.insert(2); |
1756 | let mut set_b = set_a.clone(); |
1757 | assert_eq!(set_a, set_b); |
1758 | set_b.swap_remove(&1); |
1759 | assert_ne!(set_a, set_b); |
1760 | |
1761 | let set_c: IndexSet<_> = set_b.into_iter().collect(); |
1762 | assert_ne!(set_a, set_c); |
1763 | assert_ne!(set_c, set_a); |
1764 | } |
1765 | |
1766 | #[test ] |
1767 | fn extend() { |
1768 | let mut set = IndexSet::new(); |
1769 | set.extend(vec![&1, &2, &3, &4]); |
1770 | set.extend(vec![5, 6]); |
1771 | assert_eq!(set.into_iter().collect::<Vec<_>>(), vec![1, 2, 3, 4, 5, 6]); |
1772 | } |
1773 | |
1774 | #[test ] |
1775 | fn comparisons() { |
1776 | let set_a: IndexSet<_> = (0..3).collect(); |
1777 | let set_b: IndexSet<_> = (3..6).collect(); |
1778 | let set_c: IndexSet<_> = (0..6).collect(); |
1779 | let set_d: IndexSet<_> = (3..9).collect(); |
1780 | |
1781 | assert!(!set_a.is_disjoint(&set_a)); |
1782 | assert!(set_a.is_subset(&set_a)); |
1783 | assert!(set_a.is_superset(&set_a)); |
1784 | |
1785 | assert!(set_a.is_disjoint(&set_b)); |
1786 | assert!(set_b.is_disjoint(&set_a)); |
1787 | assert!(!set_a.is_subset(&set_b)); |
1788 | assert!(!set_b.is_subset(&set_a)); |
1789 | assert!(!set_a.is_superset(&set_b)); |
1790 | assert!(!set_b.is_superset(&set_a)); |
1791 | |
1792 | assert!(!set_a.is_disjoint(&set_c)); |
1793 | assert!(!set_c.is_disjoint(&set_a)); |
1794 | assert!(set_a.is_subset(&set_c)); |
1795 | assert!(!set_c.is_subset(&set_a)); |
1796 | assert!(!set_a.is_superset(&set_c)); |
1797 | assert!(set_c.is_superset(&set_a)); |
1798 | |
1799 | assert!(!set_c.is_disjoint(&set_d)); |
1800 | assert!(!set_d.is_disjoint(&set_c)); |
1801 | assert!(!set_c.is_subset(&set_d)); |
1802 | assert!(!set_d.is_subset(&set_c)); |
1803 | assert!(!set_c.is_superset(&set_d)); |
1804 | assert!(!set_d.is_superset(&set_c)); |
1805 | } |
1806 | |
1807 | #[test ] |
1808 | fn iter_comparisons() { |
1809 | use std::iter::empty; |
1810 | |
1811 | fn check<'a, I1, I2>(iter1: I1, iter2: I2) |
1812 | where |
1813 | I1: Iterator<Item = &'a i32>, |
1814 | I2: Iterator<Item = i32>, |
1815 | { |
1816 | assert!(iter1.copied().eq(iter2)); |
1817 | } |
1818 | |
1819 | let set_a: IndexSet<_> = (0..3).collect(); |
1820 | let set_b: IndexSet<_> = (3..6).collect(); |
1821 | let set_c: IndexSet<_> = (0..6).collect(); |
1822 | let set_d: IndexSet<_> = (3..9).rev().collect(); |
1823 | |
1824 | check(set_a.difference(&set_a), empty()); |
1825 | check(set_a.symmetric_difference(&set_a), empty()); |
1826 | check(set_a.intersection(&set_a), 0..3); |
1827 | check(set_a.union(&set_a), 0..3); |
1828 | |
1829 | check(set_a.difference(&set_b), 0..3); |
1830 | check(set_b.difference(&set_a), 3..6); |
1831 | check(set_a.symmetric_difference(&set_b), 0..6); |
1832 | check(set_b.symmetric_difference(&set_a), (3..6).chain(0..3)); |
1833 | check(set_a.intersection(&set_b), empty()); |
1834 | check(set_b.intersection(&set_a), empty()); |
1835 | check(set_a.union(&set_b), 0..6); |
1836 | check(set_b.union(&set_a), (3..6).chain(0..3)); |
1837 | |
1838 | check(set_a.difference(&set_c), empty()); |
1839 | check(set_c.difference(&set_a), 3..6); |
1840 | check(set_a.symmetric_difference(&set_c), 3..6); |
1841 | check(set_c.symmetric_difference(&set_a), 3..6); |
1842 | check(set_a.intersection(&set_c), 0..3); |
1843 | check(set_c.intersection(&set_a), 0..3); |
1844 | check(set_a.union(&set_c), 0..6); |
1845 | check(set_c.union(&set_a), 0..6); |
1846 | |
1847 | check(set_c.difference(&set_d), 0..3); |
1848 | check(set_d.difference(&set_c), (6..9).rev()); |
1849 | check( |
1850 | set_c.symmetric_difference(&set_d), |
1851 | (0..3).chain((6..9).rev()), |
1852 | ); |
1853 | check(set_d.symmetric_difference(&set_c), (6..9).rev().chain(0..3)); |
1854 | check(set_c.intersection(&set_d), 3..6); |
1855 | check(set_d.intersection(&set_c), (3..6).rev()); |
1856 | check(set_c.union(&set_d), (0..6).chain((6..9).rev())); |
1857 | check(set_d.union(&set_c), (3..9).rev().chain(0..3)); |
1858 | } |
1859 | |
1860 | #[test ] |
1861 | fn ops() { |
1862 | let empty = IndexSet::<i32>::new(); |
1863 | let set_a: IndexSet<_> = (0..3).collect(); |
1864 | let set_b: IndexSet<_> = (3..6).collect(); |
1865 | let set_c: IndexSet<_> = (0..6).collect(); |
1866 | let set_d: IndexSet<_> = (3..9).rev().collect(); |
1867 | |
1868 | #[allow (clippy::eq_op)] |
1869 | { |
1870 | assert_eq!(&set_a & &set_a, set_a); |
1871 | assert_eq!(&set_a | &set_a, set_a); |
1872 | assert_eq!(&set_a ^ &set_a, empty); |
1873 | assert_eq!(&set_a - &set_a, empty); |
1874 | } |
1875 | |
1876 | assert_eq!(&set_a & &set_b, empty); |
1877 | assert_eq!(&set_b & &set_a, empty); |
1878 | assert_eq!(&set_a | &set_b, set_c); |
1879 | assert_eq!(&set_b | &set_a, set_c); |
1880 | assert_eq!(&set_a ^ &set_b, set_c); |
1881 | assert_eq!(&set_b ^ &set_a, set_c); |
1882 | assert_eq!(&set_a - &set_b, set_a); |
1883 | assert_eq!(&set_b - &set_a, set_b); |
1884 | |
1885 | assert_eq!(&set_a & &set_c, set_a); |
1886 | assert_eq!(&set_c & &set_a, set_a); |
1887 | assert_eq!(&set_a | &set_c, set_c); |
1888 | assert_eq!(&set_c | &set_a, set_c); |
1889 | assert_eq!(&set_a ^ &set_c, set_b); |
1890 | assert_eq!(&set_c ^ &set_a, set_b); |
1891 | assert_eq!(&set_a - &set_c, empty); |
1892 | assert_eq!(&set_c - &set_a, set_b); |
1893 | |
1894 | assert_eq!(&set_c & &set_d, set_b); |
1895 | assert_eq!(&set_d & &set_c, set_b); |
1896 | assert_eq!(&set_c | &set_d, &set_a | &set_d); |
1897 | assert_eq!(&set_d | &set_c, &set_a | &set_d); |
1898 | assert_eq!(&set_c ^ &set_d, &set_a | &(&set_d - &set_b)); |
1899 | assert_eq!(&set_d ^ &set_c, &set_a | &(&set_d - &set_b)); |
1900 | assert_eq!(&set_c - &set_d, set_a); |
1901 | assert_eq!(&set_d - &set_c, &set_d - &set_b); |
1902 | } |
1903 | |
1904 | #[test ] |
1905 | #[cfg (has_std)] |
1906 | fn from_array() { |
1907 | let set1 = IndexSet::from([1, 2, 3, 4]); |
1908 | let set2: IndexSet<_> = [1, 2, 3, 4].into(); |
1909 | |
1910 | assert_eq!(set1, set2); |
1911 | } |
1912 | } |
1913 | |