1 #![allow(deprecated)] 2 3 use super::{IntoIter, IterMut, ThreadLocal}; 4 use std::fmt; 5 use std::panic::UnwindSafe; 6 use std::usize; 7 8 /// Wrapper around [`ThreadLocal`]. 9 /// 10 /// This used to add a fast path for a single thread, however that has been 11 /// obsoleted by performance improvements to [`ThreadLocal`] itself. 12 #[deprecated(since = "1.1.0", note = "Use `ThreadLocal` instead")] 13 pub struct CachedThreadLocal<T: Send> { 14 inner: ThreadLocal<T>, 15 } 16 17 impl<T: Send> Default for CachedThreadLocal<T> { default() -> CachedThreadLocal<T>18 fn default() -> CachedThreadLocal<T> { 19 CachedThreadLocal::new() 20 } 21 } 22 23 impl<T: Send> CachedThreadLocal<T> { 24 /// Creates a new empty `CachedThreadLocal`. 25 #[inline] new() -> CachedThreadLocal<T>26 pub fn new() -> CachedThreadLocal<T> { 27 CachedThreadLocal { 28 inner: ThreadLocal::new(), 29 } 30 } 31 32 /// Returns the element for the current thread, if it exists. 33 #[inline] get(&self) -> Option<&T>34 pub fn get(&self) -> Option<&T> { 35 self.inner.get() 36 } 37 38 /// Returns the element for the current thread, or creates it if it doesn't 39 /// exist. 40 #[inline] get_or<F>(&self, create: F) -> &T where F: FnOnce() -> T,41 pub fn get_or<F>(&self, create: F) -> &T 42 where 43 F: FnOnce() -> T, 44 { 45 self.inner.get_or(create) 46 } 47 48 /// Returns the element for the current thread, or creates it if it doesn't 49 /// exist. If `create` fails, that error is returned and no element is 50 /// added. 51 #[inline] get_or_try<F, E>(&self, create: F) -> Result<&T, E> where F: FnOnce() -> Result<T, E>,52 pub fn get_or_try<F, E>(&self, create: F) -> Result<&T, E> 53 where 54 F: FnOnce() -> Result<T, E>, 55 { 56 self.inner.get_or_try(create) 57 } 58 59 /// Returns a mutable iterator over the local values of all threads. 60 /// 61 /// Since this call borrows the `ThreadLocal` mutably, this operation can 62 /// be done safely---the mutable borrow statically guarantees no other 63 /// threads are currently accessing their associated values. 64 #[inline] iter_mut(&mut self) -> CachedIterMut<T>65 pub fn iter_mut(&mut self) -> CachedIterMut<T> { 66 CachedIterMut { 67 inner: self.inner.iter_mut(), 68 } 69 } 70 71 /// Removes all thread-specific values from the `ThreadLocal`, effectively 72 /// reseting it to its original state. 73 /// 74 /// Since this call borrows the `ThreadLocal` mutably, this operation can 75 /// be done safely---the mutable borrow statically guarantees no other 76 /// threads are currently accessing their associated values. 77 #[inline] clear(&mut self)78 pub fn clear(&mut self) { 79 self.inner.clear(); 80 } 81 } 82 83 impl<T: Send> IntoIterator for CachedThreadLocal<T> { 84 type Item = T; 85 type IntoIter = CachedIntoIter<T>; 86 into_iter(self) -> CachedIntoIter<T>87 fn into_iter(self) -> CachedIntoIter<T> { 88 CachedIntoIter { 89 inner: self.inner.into_iter(), 90 } 91 } 92 } 93 94 impl<'a, T: Send + 'a> IntoIterator for &'a mut CachedThreadLocal<T> { 95 type Item = &'a mut T; 96 type IntoIter = CachedIterMut<'a, T>; 97 into_iter(self) -> CachedIterMut<'a, T>98 fn into_iter(self) -> CachedIterMut<'a, T> { 99 self.iter_mut() 100 } 101 } 102 103 impl<T: Send + Default> CachedThreadLocal<T> { 104 /// Returns the element for the current thread, or creates a default one if 105 /// it doesn't exist. get_or_default(&self) -> &T106 pub fn get_or_default(&self) -> &T { 107 self.get_or(T::default) 108 } 109 } 110 111 impl<T: Send + fmt::Debug> fmt::Debug for CachedThreadLocal<T> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 113 write!(f, "ThreadLocal {{ local_data: {:?} }}", self.get()) 114 } 115 } 116 117 impl<T: Send + UnwindSafe> UnwindSafe for CachedThreadLocal<T> {} 118 119 /// Mutable iterator over the contents of a `CachedThreadLocal`. 120 #[deprecated(since = "1.1.0", note = "Use `IterMut` instead")] 121 pub struct CachedIterMut<'a, T: Send + 'a> { 122 inner: IterMut<'a, T>, 123 } 124 125 impl<'a, T: Send + 'a> Iterator for CachedIterMut<'a, T> { 126 type Item = &'a mut T; 127 128 #[inline] next(&mut self) -> Option<&'a mut T>129 fn next(&mut self) -> Option<&'a mut T> { 130 self.inner.next() 131 } 132 133 #[inline] size_hint(&self) -> (usize, Option<usize>)134 fn size_hint(&self) -> (usize, Option<usize>) { 135 self.inner.size_hint() 136 } 137 } 138 139 impl<'a, T: Send + 'a> ExactSizeIterator for CachedIterMut<'a, T> {} 140 141 /// An iterator that moves out of a `CachedThreadLocal`. 142 #[deprecated(since = "1.1.0", note = "Use `IntoIter` instead")] 143 pub struct CachedIntoIter<T: Send> { 144 inner: IntoIter<T>, 145 } 146 147 impl<T: Send> Iterator for CachedIntoIter<T> { 148 type Item = T; 149 150 #[inline] next(&mut self) -> Option<T>151 fn next(&mut self) -> Option<T> { 152 self.inner.next() 153 } 154 155 #[inline] size_hint(&self) -> (usize, Option<usize>)156 fn size_hint(&self) -> (usize, Option<usize>) { 157 self.inner.size_hint() 158 } 159 } 160 161 impl<T: Send> ExactSizeIterator for CachedIntoIter<T> {} 162