#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(all(feature = "std", feature = "alloc"))]
pub(crate) struct Lease<T: 'static> {
v: Vec<T>,
slot: &'static std::thread::LocalKey<core::cell::RefCell<Vec<T>>>,
}
#[cfg(all(feature = "std", feature = "alloc"))]
impl<T: 'static> core::ops::Deref for Lease<T> {
type Target = Vec<T>;
#[inline(always)]
fn deref(&self) -> &Vec<T> {
&self.v
}
}
#[cfg(all(feature = "std", feature = "alloc"))]
impl<T: 'static> core::ops::DerefMut for Lease<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Vec<T> {
&mut self.v
}
}
#[cfg(all(feature = "std", feature = "alloc"))]
impl<T: 'static> Drop for Lease<T> {
#[inline(always)]
fn drop(&mut self) {
let mine = core::mem::take(&mut self.v);
let _ = self.slot.try_with(|c| {
if let Ok(mut cur) = c.try_borrow_mut() {
if cur.is_empty() || mine.capacity() > cur.capacity() {
*cur = mine;
}
}
});
}
}
#[cfg(all(feature = "std", feature = "alloc"))]
#[inline(always)]
pub(crate) fn lease<T: 'static>(
slot: &'static std::thread::LocalKey<core::cell::RefCell<Vec<T>>>,
) -> Lease<T> {
let v = slot
.try_with(|c| {
c.try_borrow_mut()
.map(|mut b| core::mem::take(&mut *b))
.unwrap_or_default()
})
.unwrap_or_default();
let mut v = v;
v.clear();
Lease { v, slot }
}
#[cfg(all(feature = "std", feature = "alloc"))]
#[inline(always)]
pub(crate) fn lease_pool<T: 'static>(
slot: &'static std::thread::LocalKey<core::cell::RefCell<Vec<T>>>,
) -> Lease<T> {
let v = slot
.try_with(|c| {
c.try_borrow_mut()
.map(|mut b| core::mem::take(&mut *b))
.unwrap_or_default()
})
.unwrap_or_default();
Lease { v, slot }
}
#[cfg(all(feature = "std", feature = "alloc"))]
macro_rules! scratch_slot {
($name:ident : $ty:ty) => {
thread_local! {
static $name: core::cell::RefCell<alloc::vec::Vec<$ty>> =
const { core::cell::RefCell::new(alloc::vec::Vec::new()) };
}
};
}
#[cfg(all(feature = "std", feature = "alloc"))]
pub(crate) use scratch_slot;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
pub(crate) struct Lease<T> {
v: Vec<T>,
}
#[cfg(all(not(feature = "std"), feature = "alloc"))]
impl<T> core::ops::Deref for Lease<T> {
type Target = Vec<T>;
#[inline(always)]
fn deref(&self) -> &Vec<T> {
&self.v
}
}
#[cfg(all(not(feature = "std"), feature = "alloc"))]
impl<T> core::ops::DerefMut for Lease<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Vec<T> {
&mut self.v
}
}
#[cfg(all(not(feature = "std"), feature = "alloc"))]
#[inline(always)]
pub(crate) fn lease<T>(_slot: &()) -> Lease<T> {
Lease { v: Vec::new() }
}
#[cfg(all(not(feature = "std"), feature = "alloc"))]
#[inline(always)]
pub(crate) fn lease_pool<T>(_slot: &()) -> Lease<T> {
Lease { v: Vec::new() }
}
#[cfg(all(not(feature = "std"), feature = "alloc"))]
macro_rules! scratch_slot {
($name:ident : $ty:ty) => {
#[allow(dead_code)]
static $name: () = ();
};
}
#[cfg(all(not(feature = "std"), feature = "alloc"))]
pub(crate) use scratch_slot;
#[cfg(all(feature = "std", feature = "alloc"))]
#[inline]
pub(crate) fn pool_take<T: 'static>(
slot: &'static std::thread::LocalKey<core::cell::RefCell<Vec<Vec<T>>>>,
) -> Vec<T> {
let mut v = slot
.try_with(|c| c.try_borrow_mut().ok().and_then(|mut p| p.pop()))
.ok()
.flatten()
.unwrap_or_default();
v.clear();
v
}
#[cfg(all(feature = "std", feature = "alloc"))]
#[inline]
pub(crate) fn pool_give<T: 'static>(
slot: &'static std::thread::LocalKey<core::cell::RefCell<Vec<Vec<T>>>>,
v: Vec<T>,
) {
if v.capacity() == 0 {
return;
}
let _ = slot.try_with(|c| {
if let Ok(mut p) = c.try_borrow_mut() {
if p.len() < 6 {
p.push(v);
}
}
});
}
#[cfg(all(feature = "std", feature = "alloc"))]
macro_rules! pool_slot {
($name:ident : $ty:ty) => {
thread_local! {
static $name: core::cell::RefCell<alloc::vec::Vec<alloc::vec::Vec<$ty>>> =
const { core::cell::RefCell::new(alloc::vec::Vec::new()) };
}
};
}
#[cfg(all(feature = "std", feature = "alloc"))]
pub(crate) use pool_slot;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
#[inline]
pub(crate) fn pool_take<T>(_slot: &()) -> Vec<T> {
Vec::new()
}
#[cfg(all(not(feature = "std"), feature = "alloc"))]
#[inline]
pub(crate) fn pool_give<T>(_slot: &(), _v: Vec<T>) {}
#[cfg(all(not(feature = "std"), feature = "alloc"))]
macro_rules! pool_slot {
($name:ident : $ty:ty) => {
#[allow(dead_code)]
static $name: () = ();
};
}
#[cfg(all(not(feature = "std"), feature = "alloc"))]
pub(crate) use pool_slot;