1use core::{
2 marker::PhantomData,
3 mem,
4 sync::atomic::{Ordering::*, *},
5};
6
7use crate::{
8 pool::{Pool, PoolMut},
9 scalar::{OpaqueScalar, ScalarAllocator},
10 Init,
11};
12
13pub struct Flag<A> {
15 flag: AtomicBool,
16 alloc: PhantomData<A>,
17}
18
19impl<A> Init for Flag<A> {
20 const INIT: Self = Self::new();
21}
22
23impl<A> Flag<A> {
24 pub const fn new() -> Self {
26 Self {
27 flag: AtomicBool::new(false),
28 alloc: PhantomData,
29 }
30 }
31}
32
33impl<A: ScalarAllocator<Scalar = ()>> PoolMut<A> for Flag<A> {
34 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
35 let filled = self.flag.get_mut();
36 if mem::replace(filled, true) {
37 Some(scalar)
38 } else {
39 None
40 }
41 }
42
43 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> {
44 let filled = self.flag.get_mut();
45 if mem::replace(filled, false) {
46 Some(unsafe { OpaqueScalar::new(()) })
47 } else {
48 None
49 }
50 }
51}
52
53impl<A: ScalarAllocator<Scalar = ()>> Pool<A> for Flag<A> {
54 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
55 if self.flag.swap(true, Acquire) {
56 Some(scalar)
57 } else {
58 None
59 }
60 }
61
62 fn remove(&self) -> Option<OpaqueScalar<A>> {
63 if self.flag.swap(false, Release) {
64 Some(unsafe { OpaqueScalar::new(()) })
65 } else {
66 None
67 }
68 }
69}