Skip to main content

thread_local/
cached.rs

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