1 | use core::hash::{BuildHasher, Hash}; |
2 | |
3 | use super::{Equivalent, IndexSet}; |
4 | use crate::map::MutableKeys; |
5 | |
6 | /// Opt-in mutable access to [`IndexSet`] values. |
7 | /// |
8 | /// These methods expose `&mut T`, mutable references to the value as it is stored |
9 | /// in the set. |
10 | /// You are allowed to modify the values in the set **if the modification |
11 | /// does not change the value’s hash and equality**. |
12 | /// |
13 | /// If values are modified erroneously, you can no longer look them up. |
14 | /// This is sound (memory safe) but a logical error hazard (just like |
15 | /// implementing `PartialEq`, `Eq`, or `Hash` incorrectly would be). |
16 | /// |
17 | /// `use` this trait to enable its methods for `IndexSet`. |
18 | /// |
19 | /// This trait is sealed and cannot be implemented for types outside this crate. |
20 | pub trait MutableValues: private::Sealed { |
21 | type Value; |
22 | |
23 | /// Return item index and mutable reference to the value |
24 | /// |
25 | /// Computes in **O(1)** time (average). |
26 | fn get_full_mut2<Q>(&mut self, value: &Q) -> Option<(usize, &mut Self::Value)> |
27 | where |
28 | Q: ?Sized + Hash + Equivalent<Self::Value>; |
29 | |
30 | /// Return mutable reference to the value at an index. |
31 | /// |
32 | /// Valid indices are `0 <= index < self.len()`. |
33 | /// |
34 | /// Computes in **O(1)** time. |
35 | fn get_index_mut2(&mut self, index: usize) -> Option<&mut Self::Value>; |
36 | |
37 | /// Scan through each value in the set and keep those where the |
38 | /// closure `keep` returns `true`. |
39 | /// |
40 | /// The values are visited in order, and remaining values keep their order. |
41 | /// |
42 | /// Computes in **O(n)** time (average). |
43 | fn retain2<F>(&mut self, keep: F) |
44 | where |
45 | F: FnMut(&mut Self::Value) -> bool; |
46 | } |
47 | |
48 | /// Opt-in mutable access to [`IndexSet`] values. |
49 | /// |
50 | /// See [`MutableValues`] for more information. |
51 | impl<T, S> MutableValues for IndexSet<T, S> |
52 | where |
53 | S: BuildHasher, |
54 | { |
55 | type Value = T; |
56 | |
57 | fn get_full_mut2<Q>(&mut self, value: &Q) -> Option<(usize, &mut T)> |
58 | where |
59 | Q: ?Sized + Hash + Equivalent<T>, |
60 | { |
61 | match self.map.get_full_mut2(value) { |
62 | Some((index, value, ())) => Some((index, value)), |
63 | None => None, |
64 | } |
65 | } |
66 | |
67 | fn get_index_mut2(&mut self, index: usize) -> Option<&mut T> { |
68 | match self.map.get_index_mut2(index) { |
69 | Some((value, ())) => Some(value), |
70 | None => None, |
71 | } |
72 | } |
73 | |
74 | fn retain2<F>(&mut self, mut keep: F) |
75 | where |
76 | F: FnMut(&mut T) -> bool, |
77 | { |
78 | self.map.retain2(move |value, ()| keep(value)); |
79 | } |
80 | } |
81 | |
82 | mod private { |
83 | pub trait Sealed {} |
84 | |
85 | impl<T, S> Sealed for super::IndexSet<T, S> {} |
86 | } |
87 | |