1use crate::scalar::{OpaqueScalar, ScalarAllocator};
4
5mod ext;
6mod flag;
7mod sequence;
8
9pub use flag::Flag;
10pub use sequence::Sequence;
11
12#[doc(hidden)]
13pub mod export {
14 #[cfg(feature = "std")]
15 pub use super::ext::LocalKey;
16}
17
18#[doc(hidden)]
19#[macro_export]
20macro_rules! __global_pool {
21 ($name:ident($imp:ty)) => {
22 impl $crate::Init for $name {
23 const INIT: Self = Self;
24 }
25
26 const _: () = {
27 static __IMP_POOL: $imp = $crate::Init::INIT;
28
29 impl<A: $crate::scalar::ScalarAllocator> $crate::pool::PoolMut<A> for $name
30 where
31 $imp: $crate::pool::Pool<A>,
32 {
33 fn insert_mut(
34 &mut self,
35 scalar: $crate::scalar::OpaqueScalar<A>,
36 ) -> Option<$crate::scalar::OpaqueScalar<A>> {
37 $crate::pool::Pool::insert(&__IMP_POOL, scalar)
38 }
39
40 fn remove_mut(&mut self) -> Option<$crate::scalar::OpaqueScalar<A>> {
41 $crate::pool::Pool::remove(&__IMP_POOL)
42 }
43 }
44
45 impl<A: $crate::scalar::ScalarAllocator> $crate::pool::Pool<A> for $name
46 where
47 $imp: $crate::pool::Pool<A>,
48 {
49 fn insert(&self, scalar: $crate::scalar::OpaqueScalar<A>) -> Option<$crate::scalar::OpaqueScalar<A>> {
50 $crate::pool::Pool::insert(&__IMP_POOL, scalar)
51 }
52
53 fn remove(&self) -> Option<$crate::scalar::OpaqueScalar<A>> { $crate::pool::Pool::remove(&__IMP_POOL) }
54 }
55 };
56 };
57 (thread_local $name:ident($imp:ty)) => {
58 impl $crate::Init for $name {
59 const INIT: Self = Self;
60 }
61
62 const _: () = {
63 $crate::export::thread_local! {
64 static __IMP_POOL: $imp = $crate::export::Default::default();
65 }
66
67 impl<A: $crate::scalar::ScalarAllocator> $crate::pool::PoolMut<A> for $name
68 where
69 $imp: $crate::pool::Pool<A>,
70 {
71 fn insert_mut(
72 &mut self,
73 scalar: $crate::scalar::OpaqueScalar<A>,
74 ) -> Option<$crate::scalar::OpaqueScalar<A>> {
75 $crate::pool::Pool::insert(&$crate::pool::export::LocalKey(&__IMP_POOL), scalar)
76 }
77
78 fn remove_mut(&mut self) -> Option<$crate::scalar::OpaqueScalar<A>> {
79 $crate::pool::Pool::remove(&$crate::pool::export::LocalKey(&__IMP_POOL))
80 }
81 }
82
83 impl<A: $crate::scalar::ScalarAllocator> $crate::pool::Pool<A> for $name
84 where
85 $imp: $crate::pool::Pool<A>,
86 {
87 fn insert(&self, scalar: $crate::scalar::OpaqueScalar<A>) -> Option<$crate::scalar::OpaqueScalar<A>> {
88 $crate::pool::Pool::insert(&$crate::pool::export::LocalKey(&__IMP_POOL), scalar)
89 }
90
91 fn remove(&self) -> Option<$crate::scalar::OpaqueScalar<A>> {
92 $crate::pool::Pool::remove(&$crate::pool::export::LocalKey(&__IMP_POOL))
93 }
94 }
95 };
96 };
97}
98
99#[macro_export]
115macro_rules! global_pool {
116 (
117 $(#[$meta:meta])*
118 $v:vis struct $name:ident($imp:ty);
119 ) => {
120 $(#[$meta])*
121 $v struct $name;
122
123 $crate::__global_pool!{$name($imp)}
124 };
125 (
126 $(#[$meta:meta])*
127 $v:vis thread_local struct $name:ident($imp:ty);
128 ) => {
129 $(#[$meta])*
130 $v struct $name;
131
132 $crate::__global_pool!{thread_local $name($imp)}
133 };
134}
135
136#[cfg(feature = "alloc")]
137cfg_if::cfg_if! {
138 if #[cfg(feature = "parking_lot")] {
139 use parking_lot::Mutex;
140 use std::vec::Vec;
141 use std::collections::VecDeque;
142
143 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
145 pub struct SyncStackPool<T: ScalarAllocator>(Mutex<Vec<crate::scalar::OpaqueScalar<T>>>);
146
147 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
149 pub struct SyncQueuePool<T: ScalarAllocator>(once_cell::sync::Lazy<Mutex<VecDeque<crate::scalar::OpaqueScalar<T>>>>);
150 } else if #[cfg(feature = "std")] {
151 use std::sync::Mutex;
152 use std::collections::VecDeque;
153
154 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
156 pub struct SyncStackPool<T: ScalarAllocator>(once_cell::sync::Lazy<Mutex<Vec<crate::scalar::OpaqueScalar<T>>>>);
157
158 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
160 pub struct SyncQueuePool<T: ScalarAllocator>(once_cell::sync::Lazy<Mutex<VecDeque<crate::scalar::OpaqueScalar<T>>>>);
161 }
162}
163
164pub trait PoolMut<A: ScalarAllocator> {
166 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>>;
168
169 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>>;
171}
172
173pub trait Pool<A: ScalarAllocator>: PoolMut<A> {
175 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>>;
177
178 fn remove(&self) -> Option<OpaqueScalar<A>>;
180}
181
182impl crate::Init for () {
183 const INIT: Self = ();
184}
185
186impl<A: ScalarAllocator> PoolMut<A> for () {
187 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { Some(scalar) }
188
189 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { None }
190}
191
192impl<A: ScalarAllocator> Pool<A> for () {
193 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { Some(scalar) }
194
195 fn remove(&self) -> Option<OpaqueScalar<A>> { None }
196}
197
198impl<P: ?Sized + PoolMut<A>, A: ScalarAllocator> PoolMut<A> for &mut P {
199 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { P::insert_mut(self, scalar) }
200
201 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { P::remove_mut(self) }
202}
203
204impl<P: ?Sized + Pool<A>, A: ScalarAllocator> Pool<A> for &mut P {
205 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { P::insert(self, scalar) }
206
207 fn remove(&self) -> Option<OpaqueScalar<A>> { P::remove(self) }
208}
209
210impl<P: ?Sized + Pool<A>, A: ScalarAllocator> PoolMut<A> for &P {
211 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { P::insert(self, scalar) }
212
213 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { P::remove(self) }
214}
215
216impl<P: ?Sized + Pool<A>, A: ScalarAllocator> Pool<A> for &P {
217 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { P::insert(self, scalar) }
218
219 fn remove(&self) -> Option<OpaqueScalar<A>> { P::remove(self) }
220}