1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use core::{
    marker::PhantomData,
    mem,
    sync::atomic::{Ordering::*, *},
};

use crate::{
    pool::{Pool, PoolMut},
    scalar::{OpaqueScalar, ScalarAllocator},
    Init,
};

/// A [`Pool`] that can hold one scalar element of type `()`
pub struct Flag<A> {
    flag: AtomicBool,
    alloc: PhantomData<A>,
}

impl<A> Init for Flag<A> {
    const INIT: Self = Self::new();
}

impl<A> Flag<A> {
    /// Create a new `Flag`
    pub const fn new() -> Self {
        Self {
            flag: AtomicBool::new(false),
            alloc: PhantomData,
        }
    }
}

impl<A: ScalarAllocator<Scalar = ()>> PoolMut<A> for Flag<A> {
    fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
        let filled = self.flag.get_mut();
        if mem::replace(filled, true) {
            Some(scalar)
        } else {
            None
        }
    }

    fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> {
        let filled = self.flag.get_mut();
        if mem::replace(filled, false) {
            Some(unsafe { OpaqueScalar::new(()) })
        } else {
            None
        }
    }
}

impl<A: ScalarAllocator<Scalar = ()>> Pool<A> for Flag<A> {
    fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
        if self.flag.swap(true, Acquire) {
            Some(scalar)
        } else {
            None
        }
    }

    fn remove(&self) -> Option<OpaqueScalar<A>> {
        if self.flag.swap(false, Release) {
            Some(unsafe { OpaqueScalar::new(()) })
        } else {
            None
        }
    }
}