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.
clear(&mut self)26     fn clear(&mut self);
27 }
28 
29 impl<T> Clear for Option<T> {
clear(&mut self)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]
clear(&mut self)40     fn clear(&mut self) {
41         self.deref_mut().clear()
42     }
43 }
44 
45 impl<T> Clear for Vec<T> {
46     #[inline]
clear(&mut self)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]
clear(&mut self)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]
clear(&mut self)69     fn clear(&mut self) {
70         collections::HashSet::clear(self)
71     }
72 }
73 
74 impl Clear for String {
75     #[inline]
clear(&mut self)76     fn clear(&mut self) {
77         String::clear(self)
78     }
79 }
80 
81 impl<T: Clear> Clear for sync::Mutex<T> {
82     #[inline]
clear(&mut self)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]
clear(&mut self)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> {
clear(&mut self)97     fn clear(&mut self) {
98         self.get_mut().clear()
99     }
100 }
101