java_asm/impls/util/
computable.rs

1use crate::computable::{Computable, InnerValue};
2use crate::{AsmErr, AsmResult, ComputableAccessor, ComputableOwner, ComputableSizedVec, ComputableSizedVecAccessor, ComputableSizedVecOwner};
3use std::cell::UnsafeCell;
4use std::sync::Arc;
5
6impl<V> Default for InnerValue<V> {
7    fn default() -> Self { InnerValue::UnInit }
8}
9
10
11
12/// manually impl due to rust default impl of Default trait requires `V: Default` 
13impl<V> Default for Computable<V> {
14    fn default() -> Self {
15        Self { inner_value: Default::default() }
16    }
17}
18
19impl<V: Clone> Clone for Computable<V> {
20    fn clone(&self) -> Self {
21        let inner_value = unsafe { &mut *self.inner_value.get() };
22        let cloned_inner = inner_value.clone();
23        Self { inner_value: UnsafeCell::new(cloned_inner) }
24    }
25}
26
27
28
29impl<T, V> ComputableAccessor<V> for T
30where
31    T: ComputableOwner<V>,
32{
33    fn force(&self) -> AsmResult<Arc<V>> {
34        self.computable_ref().force_with_fn(|| self.compute())
35    }
36}
37
38impl<V> Computable<V> {
39    pub fn force_with_fn(&self, f: impl FnOnce() -> AsmResult<V>) -> AsmResult<Arc<V>> {
40        let inner_value_ptr = self.inner_value.get();
41        let inner = unsafe { &mut *inner_value_ptr };
42        match inner {
43            InnerValue::UnInit => {
44                let value = Arc::new(f()?);
45                let copied = value.clone();
46                *inner = InnerValue::Initialized(value);
47                Ok(copied)
48            }
49            InnerValue::Initialized(value) => Ok(Arc::clone(value))
50        }
51    }
52}
53
54impl<V> ComputableSizedVec<V> {
55    pub fn new(size: usize) -> Self {
56        let mut vec = Vec::with_capacity(size);
57        vec.resize_with(size, || Default::default());
58        Self { vec_ref: vec }
59    }
60}
61
62impl<T, V> ComputableSizedVecAccessor<V> for T
63where
64    T: ComputableSizedVecOwner<V>,
65{
66    fn get_or_compute(&self, index: usize) -> AsmResult<Arc<V>> {
67        self.computable_vec().vec_ref.get(index)
68            .ok_or_else(|| AsmErr::OutOfRange(index))?
69            .force_with_fn(|| self.compute(index))
70    }
71}