Skip to main content

indexical/
vec.rs

1//! Vector-like collection for indexed keys.
2
3use std::{
4    ops::{Index, IndexMut},
5    slice::GetDisjointMutError,
6};
7
8use index_vec::Idx;
9
10use crate::{
11    IndexedDomain, IndexedValue, ToIndex,
12    pointer::{ArcFamily, PointerFamily, RcFamily, RefFamily},
13};
14
15/// A fixed-sized vector with one value for each key in the domain.
16pub struct IndexVec<'a, K: IndexedValue + 'a, V, P: PointerFamily<'a>> {
17    vec: Vec<V>,
18    pub(crate) domain: P::Pointer<IndexedDomain<K>>,
19}
20
21impl<'a, K, V, P> IndexVec<'a, K, V, P>
22where
23    K: IndexedValue + 'a,
24    P: PointerFamily<'a>,
25    V: Clone,
26{
27    /// Constructs a new vector where each index maps to the initial element `elem`.
28    pub fn from_elem(elem: V, domain: &P::Pointer<IndexedDomain<K>>) -> Self {
29        let vec = vec![elem; domain.len()];
30        IndexVec {
31            vec,
32            domain: domain.clone(),
33        }
34    }
35}
36
37impl<'a, K, V, P> IndexVec<'a, K, V, P>
38where
39    K: IndexedValue + 'a,
40    P: PointerFamily<'a>,
41{
42    /// Constructs a new vector where each index maps to the output of `f(index)`.
43    pub fn from_fn(f: impl FnMut(K::Index) -> V, domain: &P::Pointer<IndexedDomain<K>>) -> Self {
44        let vec = domain.indices().map(f).collect();
45        IndexVec {
46            vec,
47            domain: domain.clone(),
48        }
49    }
50
51    /// Returns an immutable reference to a value for a given index.
52    pub fn get<M>(&self, idx: impl ToIndex<K, M>) -> &V {
53        let idx = idx.to_index(&self.domain);
54        debug_assert!(self.domain.contains_index(idx));
55        unsafe { self.vec.get_unchecked(idx.index()) }
56    }
57
58    /// Returns a mutable reference to a value for a given index.
59    pub fn get_mut<M>(&mut self, idx: impl ToIndex<K, M>) -> &mut V {
60        let idx = idx.to_index(&self.domain);
61        debug_assert!(self.domain.contains_index(idx));
62        unsafe { self.vec.get_unchecked_mut(idx.index()) }
63    }
64
65    /// Returns an iterator over immutable references to the values.
66    pub fn iter(&self) -> impl DoubleEndedIterator<Item = &V> + ExactSizeIterator<Item = &V> {
67        self.vec.iter()
68    }
69
70    /// Returns an iterator over mutable references to the values.
71    pub fn iter_mut(
72        &mut self,
73    ) -> impl DoubleEndedIterator<Item = &mut V> + ExactSizeIterator<Item = &mut V> {
74        self.vec.iter_mut()
75    }
76
77    /// Returns the underlying vector as a slice.
78    pub fn as_slice(&self) -> &[V] {
79        &self.vec
80    }
81
82    /// Returns the underlying vector as a mutable slice.
83    pub fn as_slice_mut(&mut self) -> &mut [V] {
84        &mut self.vec
85    }
86
87    /// Returns multiple mutable references to disjoint indices.
88    ///
89    /// # Errors
90    /// Returns [`GetDisjointMutError`] if not disjoint or in-bounds.    
91    pub fn get_disjoint_mut<const N: usize>(
92        &mut self,
93        indices: [K::Index; N],
94    ) -> Result<[&mut V; N], GetDisjointMutError> {
95        self.vec.get_disjoint_mut(indices.map(Idx::index))
96    }
97}
98
99impl<'a, K, V, P> Clone for IndexVec<'a, K, V, P>
100where
101    K: IndexedValue + 'a,
102    P: PointerFamily<'a>,
103    V: Clone,
104{
105    fn clone(&self) -> Self {
106        IndexVec {
107            vec: self.vec.clone(),
108            domain: self.domain.clone(),
109        }
110    }
111
112    fn clone_from(&mut self, source: &Self) {
113        self.vec.clone_from(&source.vec);
114    }
115}
116
117impl<'a, K, V, P> PartialEq for IndexVec<'a, K, V, P>
118where
119    K: IndexedValue + 'a,
120    P: PointerFamily<'a>,
121    V: PartialEq,
122{
123    fn eq(&self, other: &Self) -> bool {
124        self.vec == other.vec
125    }
126}
127
128impl<'a, K, V, P> Eq for IndexVec<'a, K, V, P>
129where
130    K: IndexedValue + 'a,
131    P: PointerFamily<'a>,
132    V: Eq,
133{
134}
135
136impl<'a, K, V, P> Index<K::Index> for IndexVec<'a, K, V, P>
137where
138    K: IndexedValue + 'a,
139    P: PointerFamily<'a>,
140{
141    type Output = V;
142
143    fn index(&self, index: K::Index) -> &Self::Output {
144        self.get(index)
145    }
146}
147
148impl<'a, K, V, P> IndexMut<K::Index> for IndexVec<'a, K, V, P>
149where
150    K: IndexedValue + 'a,
151    P: PointerFamily<'a>,
152{
153    fn index_mut(&mut self, index: K::Index) -> &mut Self::Output {
154        self.get_mut(index)
155    }
156}
157
158/// [`IndexVec`] specialized to the [`RcFamily`].
159pub type RcIndexVec<K, V> = IndexVec<'static, K, V, RcFamily>;
160
161/// [`IndexVec`] specialized to the [`ArcFamily`].
162pub type ArcIndexVec<K, V> = IndexVec<'static, K, V, ArcFamily>;
163
164/// [`IndexVec`] specialized to the [`RefFamily`].
165pub type RefIndexVec<'a, K, V> = IndexVec<'a, K, V, RefFamily<'a>>;