atomic_array/
option_ref_array.rs

1use atomic_ref2::{AtomicOptionRef, IntoOptionArc};
2use std::sync::Arc;
3
4/// An array of references in which elements may be updated and retrieved atomically.
5///
6/// This is a Rust interpretation of [AtomicReferenceArray](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicReferenceArray.html) from Java.
7pub struct AtomicOptionRefArray<T> {
8    buf: Box<[AtomicOptionRef<T>]>,
9}
10
11impl<T> AtomicOptionRefArray<T> {
12    /// Constructs a new array with the specified length.
13    /// All values will be `None`.
14    pub fn new(len: usize) -> Self {
15        let mut buf = Vec::with_capacity(len);
16
17        for _ in 0..len {
18            buf.push(AtomicOptionRef::new());
19        }
20
21        Self {
22            buf: buf.into_boxed_slice(),
23        }
24    }
25
26    /// Constructs a new array with the specified length.
27    /// Uses the given function to construct each value.
28    pub fn new_with<U: IntoOptionArc<T>>(len: usize, f: impl Fn(usize) -> U) -> Self {
29        let mut buf = Vec::with_capacity(len);
30
31        for i in 0..len {
32            buf.push(AtomicOptionRef::from(f(i)));
33        }
34
35        Self {
36            buf: buf.into_boxed_slice(),
37        }
38    }
39
40    /// Returns the number of elements in the array.
41    pub fn len(&self) -> usize {
42        self.buf.len()
43    }
44
45    /// Returns `true` if the array has a length of 0.
46    pub fn is_empty(&self) -> bool {
47        self.buf.is_empty()
48    }
49
50    /// Loads and returns a reference to an value at the given position or `None`
51    /// if the value at the index is not set.
52    ///
53    /// Panics if `index` is out of bounds.
54    pub fn load(&self, index: usize) -> Option<Arc<T>> {
55        self.buf[index].load()
56    }
57
58    /// Stores the value at the given position.
59    ///
60    /// Panics if `index` is out of bounds.
61    pub fn store(&self, index: usize, value: impl IntoOptionArc<T>) {
62        self.buf[index].store(value);
63    }
64
65    /// Swaps the value at the given position, returning the previous value.
66    ///
67    /// Panics if `index` is out of bounds.
68    pub fn swap(&self, index: usize, value: impl IntoOptionArc<T>) -> Option<Arc<T>> {
69        self.buf[index].swap(value)
70    }
71}