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}