1 | use std::{collections, hash, ops::DerefMut, sync}; |
2 | |
3 | /// Trait implemented by types which can be cleared in place, retaining any |
4 | /// allocated memory. |
5 | /// |
6 | /// This is essentially a generalization of methods on standard library |
7 | /// collection types, including as [`Vec::clear`], [`String::clear`], and |
8 | /// [`HashMap::clear`]. These methods drop all data stored in the collection, |
9 | /// but retain the collection's heap allocation for future use. Types such as |
10 | /// `BTreeMap`, whose `clear` methods drops allocations, should not |
11 | /// implement this trait. |
12 | /// |
13 | /// When implemented for types which do not own a heap allocation, `Clear` |
14 | /// should reset the type in place if possible. If the type has an empty state |
15 | /// or stores `Option`s, those values should be reset to the empty state. For |
16 | /// "plain old data" types, which hold no pointers to other data and do not have |
17 | /// an empty or initial state, it's okay for a `Clear` implementation to be a |
18 | /// no-op. In that case, it essentially serves as a marker indicating that the |
19 | /// type may be reused to store new data. |
20 | /// |
21 | /// [`Vec::clear`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.clear |
22 | /// [`String::clear`]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.clear |
23 | /// [`HashMap::clear`]: https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html#method.clear |
24 | pub trait Clear { |
25 | /// Clear all data in `self`, retaining the allocated capacithy. |
26 | fn clear(&mut self); |
27 | } |
28 | |
29 | impl<T> Clear for Option<T> { |
30 | fn clear(&mut self) { |
31 | let _ = self.take(); |
32 | } |
33 | } |
34 | |
35 | impl<T> Clear for Box<T> |
36 | where |
37 | T: Clear, |
38 | { |
39 | #[inline ] |
40 | fn clear(&mut self) { |
41 | self.deref_mut().clear() |
42 | } |
43 | } |
44 | |
45 | impl<T> Clear for Vec<T> { |
46 | #[inline ] |
47 | fn clear(&mut self) { |
48 | Vec::clear(self) |
49 | } |
50 | } |
51 | |
52 | impl<K, V, S> Clear for collections::HashMap<K, V, S> |
53 | where |
54 | K: hash::Hash + Eq, |
55 | S: hash::BuildHasher, |
56 | { |
57 | #[inline ] |
58 | fn clear(&mut self) { |
59 | collections::HashMap::clear(self) |
60 | } |
61 | } |
62 | |
63 | impl<T, S> Clear for collections::HashSet<T, S> |
64 | where |
65 | T: hash::Hash + Eq, |
66 | S: hash::BuildHasher, |
67 | { |
68 | #[inline ] |
69 | fn clear(&mut self) { |
70 | collections::HashSet::clear(self) |
71 | } |
72 | } |
73 | |
74 | impl Clear for String { |
75 | #[inline ] |
76 | fn clear(&mut self) { |
77 | String::clear(self) |
78 | } |
79 | } |
80 | |
81 | impl<T: Clear> Clear for sync::Mutex<T> { |
82 | #[inline ] |
83 | fn clear(&mut self) { |
84 | self.get_mut().unwrap().clear(); |
85 | } |
86 | } |
87 | |
88 | impl<T: Clear> Clear for sync::RwLock<T> { |
89 | #[inline ] |
90 | fn clear(&mut self) { |
91 | self.write().unwrap().clear(); |
92 | } |
93 | } |
94 | |
95 | #[cfg (all(loom, test))] |
96 | impl<T: Clear> Clear for crate::sync::alloc::Track<T> { |
97 | fn clear(&mut self) { |
98 | self.get_mut().clear() |
99 | } |
100 | } |
101 | |