diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:47:55 +0000 |
commit | 2aadc03ef15cb5ca5cc2af8a7c08e070742f0ac4 (patch) | |
tree | 033cc839730fda84ff08db877037977be94e5e3a /vendor/thread_local/src/cached.rs | |
parent | Initial commit. (diff) | |
download | cargo-2aadc03ef15cb5ca5cc2af8a7c08e070742f0ac4.tar.xz cargo-2aadc03ef15cb5ca5cc2af8a7c08e070742f0ac4.zip |
Adding upstream version 0.70.1+ds1.upstream/0.70.1+ds1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/thread_local/src/cached.rs')
-rw-r--r-- | vendor/thread_local/src/cached.rs | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/vendor/thread_local/src/cached.rs b/vendor/thread_local/src/cached.rs new file mode 100644 index 0000000..16f6516 --- /dev/null +++ b/vendor/thread_local/src/cached.rs @@ -0,0 +1,161 @@ +#![allow(deprecated)] + +use super::{IntoIter, IterMut, ThreadLocal}; +use std::fmt; +use std::panic::UnwindSafe; +use std::usize; + +/// Wrapper around [`ThreadLocal`]. +/// +/// This used to add a fast path for a single thread, however that has been +/// obsoleted by performance improvements to [`ThreadLocal`] itself. +#[deprecated(since = "1.1.0", note = "Use `ThreadLocal` instead")] +pub struct CachedThreadLocal<T: Send> { + inner: ThreadLocal<T>, +} + +impl<T: Send> Default for CachedThreadLocal<T> { + fn default() -> CachedThreadLocal<T> { + CachedThreadLocal::new() + } +} + +impl<T: Send> CachedThreadLocal<T> { + /// Creates a new empty `CachedThreadLocal`. + #[inline] + pub fn new() -> CachedThreadLocal<T> { + CachedThreadLocal { + inner: ThreadLocal::new(), + } + } + + /// Returns the element for the current thread, if it exists. + #[inline] + pub fn get(&self) -> Option<&T> { + self.inner.get() + } + + /// Returns the element for the current thread, or creates it if it doesn't + /// exist. + #[inline] + pub fn get_or<F>(&self, create: F) -> &T + where + F: FnOnce() -> T, + { + self.inner.get_or(create) + } + + /// Returns the element for the current thread, or creates it if it doesn't + /// exist. If `create` fails, that error is returned and no element is + /// added. + #[inline] + pub fn get_or_try<F, E>(&self, create: F) -> Result<&T, E> + where + F: FnOnce() -> Result<T, E>, + { + self.inner.get_or_try(create) + } + + /// Returns a mutable iterator over the local values of all threads. + /// + /// Since this call borrows the `ThreadLocal` mutably, this operation can + /// be done safely---the mutable borrow statically guarantees no other + /// threads are currently accessing their associated values. + #[inline] + pub fn iter_mut(&mut self) -> CachedIterMut<T> { + CachedIterMut { + inner: self.inner.iter_mut(), + } + } + + /// Removes all thread-specific values from the `ThreadLocal`, effectively + /// reseting it to its original state. + /// + /// Since this call borrows the `ThreadLocal` mutably, this operation can + /// be done safely---the mutable borrow statically guarantees no other + /// threads are currently accessing their associated values. + #[inline] + pub fn clear(&mut self) { + self.inner.clear(); + } +} + +impl<T: Send> IntoIterator for CachedThreadLocal<T> { + type Item = T; + type IntoIter = CachedIntoIter<T>; + + fn into_iter(self) -> CachedIntoIter<T> { + CachedIntoIter { + inner: self.inner.into_iter(), + } + } +} + +impl<'a, T: Send + 'a> IntoIterator for &'a mut CachedThreadLocal<T> { + type Item = &'a mut T; + type IntoIter = CachedIterMut<'a, T>; + + fn into_iter(self) -> CachedIterMut<'a, T> { + self.iter_mut() + } +} + +impl<T: Send + Default> CachedThreadLocal<T> { + /// Returns the element for the current thread, or creates a default one if + /// it doesn't exist. + pub fn get_or_default(&self) -> &T { + self.get_or(T::default) + } +} + +impl<T: Send + fmt::Debug> fmt::Debug for CachedThreadLocal<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "ThreadLocal {{ local_data: {:?} }}", self.get()) + } +} + +impl<T: Send + UnwindSafe> UnwindSafe for CachedThreadLocal<T> {} + +/// Mutable iterator over the contents of a `CachedThreadLocal`. +#[deprecated(since = "1.1.0", note = "Use `IterMut` instead")] +pub struct CachedIterMut<'a, T: Send + 'a> { + inner: IterMut<'a, T>, +} + +impl<'a, T: Send + 'a> Iterator for CachedIterMut<'a, T> { + type Item = &'a mut T; + + #[inline] + fn next(&mut self) -> Option<&'a mut T> { + self.inner.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.inner.size_hint() + } +} + +impl<'a, T: Send + 'a> ExactSizeIterator for CachedIterMut<'a, T> {} + +/// An iterator that moves out of a `CachedThreadLocal`. +#[deprecated(since = "1.1.0", note = "Use `IntoIter` instead")] +pub struct CachedIntoIter<T: Send> { + inner: IntoIter<T>, +} + +impl<T: Send> Iterator for CachedIntoIter<T> { + type Item = T; + + #[inline] + fn next(&mut self) -> Option<T> { + self.inner.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.inner.size_hint() + } +} + +impl<T: Send> ExactSizeIterator for CachedIntoIter<T> {} |