Coverage Report

Created: 2026-08-31 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/thread_local-1.1.10/src/cached.rs
Line
Count
Source
1
#![allow(deprecated)]
2
3
use super::{IntoIter, IterMut, ThreadLocal};
4
use std::fmt;
5
use 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")]
12
pub struct CachedThreadLocal<T: Send> {
13
    inner: ThreadLocal<T>,
14
}
15
16
impl<T: Send> Default for CachedThreadLocal<T> {
17
0
    fn default() -> CachedThreadLocal<T> {
18
0
        CachedThreadLocal::new()
19
0
    }
20
}
21
22
impl<T: Send> CachedThreadLocal<T> {
23
    /// Creates a new empty `CachedThreadLocal`.
24
    #[inline]
25
0
    pub fn new() -> CachedThreadLocal<T> {
26
0
        CachedThreadLocal {
27
0
            inner: ThreadLocal::new(),
28
0
        }
29
0
    }
30
31
    /// Returns the element for the current thread, if it exists.
32
    #[inline]
33
0
    pub fn get(&self) -> Option<&T> {
34
0
        self.inner.get()
35
0
    }
36
37
    /// Returns the element for the current thread, or creates it if it doesn't
38
    /// exist.
39
    #[inline]
40
0
    pub fn get_or<F>(&self, create: F) -> &T
41
0
    where
42
0
        F: FnOnce() -> T,
43
    {
44
0
        self.inner.get_or(create)
45
0
    }
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
0
    pub fn get_or_try<F, E>(&self, create: F) -> Result<&T, E>
52
0
    where
53
0
        F: FnOnce() -> Result<T, E>,
54
    {
55
0
        self.inner.get_or_try(create)
56
0
    }
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
0
    pub fn iter_mut(&mut self) -> CachedIterMut<'_, T> {
65
0
        CachedIterMut {
66
0
            inner: self.inner.iter_mut(),
67
0
        }
68
0
    }
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
0
    pub fn clear(&mut self) {
78
0
        self.inner.clear();
79
0
    }
80
}
81
82
impl<T: Send> IntoIterator for CachedThreadLocal<T> {
83
    type Item = T;
84
    type IntoIter = CachedIntoIter<T>;
85
86
0
    fn into_iter(self) -> CachedIntoIter<T> {
87
0
        CachedIntoIter {
88
0
            inner: self.inner.into_iter(),
89
0
        }
90
0
    }
91
}
92
93
impl<'a, T: Send + 'a> IntoIterator for &'a mut CachedThreadLocal<T> {
94
    type Item = &'a mut T;
95
    type IntoIter = CachedIterMut<'a, T>;
96
97
0
    fn into_iter(self) -> CachedIterMut<'a, T> {
98
0
        self.iter_mut()
99
0
    }
100
}
101
102
impl<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
0
    pub fn get_or_default(&self) -> &T {
106
0
        self.get_or(T::default)
107
0
    }
108
}
109
110
impl<T: Send + fmt::Debug> fmt::Debug for CachedThreadLocal<T> {
111
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
112
0
        write!(f, "ThreadLocal {{ local_data: {:?} }}", self.get())
113
0
    }
114
}
115
116
impl<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")]
120
pub struct CachedIterMut<'a, T: Send + 'a> {
121
    inner: IterMut<'a, T>,
122
}
123
124
impl<'a, T: Send + 'a> Iterator for CachedIterMut<'a, T> {
125
    type Item = &'a mut T;
126
127
    #[inline]
128
0
    fn next(&mut self) -> Option<&'a mut T> {
129
0
        self.inner.next()
130
0
    }
131
132
    #[inline]
133
0
    fn size_hint(&self) -> (usize, Option<usize>) {
134
0
        self.inner.size_hint()
135
0
    }
136
}
137
138
impl<'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")]
142
pub struct CachedIntoIter<T: Send> {
143
    inner: IntoIter<T>,
144
}
145
146
impl<T: Send> Iterator for CachedIntoIter<T> {
147
    type Item = T;
148
149
    #[inline]
150
0
    fn next(&mut self) -> Option<T> {
151
0
        self.inner.next()
152
0
    }
153
154
    #[inline]
155
0
    fn size_hint(&self) -> (usize, Option<usize>) {
156
0
        self.inner.size_hint()
157
0
    }
158
}
159
160
impl<T: Send> ExactSizeIterator for CachedIntoIter<T> {}