orx_v/
nvec_mut.rs

1use crate::{
2    dim::{Dim, IntoIdx},
3    nvec::NVec,
4};
5
6/// A `D` dimensional mutable vector.
7///
8/// [`V1Mut`], [`V2Mut`], etc. are type aliases for `NVecMut<D1, T>`, `NVecMut<D2, T>`, and so on.
9///
10/// [`V1Mut`]: crate::V1Mut
11/// [`V2Mut`]: crate::V2Mut
12pub trait NVecMut<D: Dim, T>: NVec<D, T> {
13    // required
14
15    /// Returns a mutable reference to the element at the `idx`-th
16    /// position of the vector.
17    ///
18    /// Note that the dimensions of the vector and the index are equal;
19    /// and hence, the result is the scalar.
20    ///
21    /// # Panics
22    ///
23    /// Panics if the `idx` is not `in_bounds`.
24    ///
25    /// # Examples
26    ///
27    /// ```rust
28    /// use orx_v::*;
29    ///
30    /// let mut vec = vec![
31    ///     vec![0, 1, 2],
32    ///     vec![3],
33    ///     vec![4, 5],
34    /// ];
35    ///
36    /// *vec.at_mut([0, 1]) = 42;
37    /// *vec.at_mut([2, 0]) = 7;
38    ///
39    /// assert_eq!(
40    ///     vec.equality(&[vec![0, 42, 2], vec![3], vec![7, 5]]),
41    ///     Equality::Equal
42    /// );
43    /// ```
44    fn at_mut<Idx: IntoIdx<D>>(&mut self, idx: Idx) -> &mut T;
45
46    /// Sets `value`of the element at the `idx`-th position of the vector.
47    ///
48    /// Note that the dimensions of the vector and the index are equal;
49    /// and hence, the method sets value of the scalar.
50    ///
51    /// # Panics
52    ///
53    /// Panics if the `idx` is not `in_bounds`.
54    ///
55    /// # Examples
56    ///
57    /// ```rust
58    /// use orx_v::*;
59    ///
60    /// let mut vec = vec![
61    ///     vec![0, 1, 2],
62    ///     vec![3],
63    ///     vec![4, 5],
64    /// ];
65    ///
66    /// vec.set([0, 1], 42);
67    /// vec.set([2, 0], 7);
68    ///
69    /// assert_eq!(
70    ///     vec.equality(&[vec![0, 42, 2], vec![3], vec![7, 5]]),
71    ///     Equality::Equal
72    /// );
73    /// ```
74    fn set<Idx: IntoIdx<D>>(&mut self, idx: Idx, value: T) {
75        *self.at_mut(idx) = value;
76    }
77
78    /// Returns a mutable reference to the `i`-th child of the vector.
79    ///
80    /// Note that child has a dimension that is one less than the dimension
81    /// of this vector.
82    ///
83    /// # Panics
84    ///
85    /// Panics if `i` is out of bounds; i.e., `i >= vec.num_children()`.
86    ///
87    /// # Examples
88    ///
89    /// ```rust
90    /// use orx_v::*;
91    ///
92    /// // D2
93    /// let mut vec = vec![
94    ///     vec![0, 1, 2],
95    ///     vec![3],
96    ///     vec![4, 5],
97    /// ];
98    ///
99    /// {
100    ///     // child is a D1 vec
101    ///     let mut child = vec.child_mut(2);
102    ///
103    ///     *child.at_mut([0]) = 42;
104    ///     child.set([1], 7);
105    /// }
106    ///
107    /// assert_eq!(
108    ///     vec.equality(&[vec![0, 1, 2], vec![3], vec![42, 7]]),
109    ///     Equality::Equal
110    /// );
111    /// ```
112    fn child_mut(&mut self, i: D::ChildIdx) -> impl NVecMut<D::PrevDim, T>;
113
114    /// Applies the mutating function `f` over all scalar elements of the vector.
115    ///
116    /// # Example
117    /// ```
118    /// use orx_v::*;
119    ///
120    /// let mut v1 = [3, 6, 12];
121    /// v1.mut_all(|x| *x *= 10);
122    /// assert_eq!(v1.equality(&[30, 60, 120]), Equality::Equal);
123    ///
124    /// let mut v2 = vec![
125    ///     vec![1, 2],
126    ///     vec![3, 4],
127    ///     vec![5, 6],
128    /// ];
129    /// v2.mut_all(|x| *x *= 10);
130    /// assert_eq!(
131    ///     v2.equality(&[[10, 20], [30, 40], [50, 60]]),
132    ///     Equality::Equal,
133    /// );
134    /// ```
135    fn mut_all<F>(&mut self, f: F)
136    where
137        F: FnMut(&mut T);
138
139    /// Sets all elements of the vector to the given `value`.
140    /// This method is often used at initialization stage of algorithms.
141    ///
142    /// # Examples
143    ///
144    /// ```
145    /// use orx_v::*;
146    ///
147    /// let mut v1 = vec![1, 2, 3, 4, 5];
148    /// v1.reset_all(0);
149    /// assert_eq!(
150    ///     v1.equality(&[0, 0, 0, 0, 0]),
151    ///     Equality::Equal,
152    /// );
153    ///
154    /// let mut v2 =[
155    ///     [1, 2, 3],
156    ///     [4, 5, 6],
157    /// ];
158    /// v2.reset_all(42);
159    /// assert_eq!(
160    ///     v2.equality(&[[42, 42, 42], [42, 42, 42]]),
161    ///     Equality::<D2>::Equal,
162    /// );
163    /// ```
164    ///
165    /// Or more practically, consider the Dijkstra's shortest path algorithm as implemented in the
166    /// [Algorithms](https://github.com/TianyiShi2001/Algorithms/blob/main/src/graph/shortest_path/dijkstra.rs)
167    /// repository.
168    ///
169    /// In addition to a priority queue, the implementation uses a distances vector throughout the
170    /// search. One way to avoid re-allocation of such internal data, we often cache and reuse them.
171    /// In such a case, we need to set all elements of this vector to infinity on initialization,
172    /// where `reset_all` method is useful.
173    ///
174    /// ```ignore
175    /// use orx_v::*;
176    ///
177    /// impl WeightedAdjacencyList {
178    ///     fn dijkstra(&mut self, start: usize, end: usize) -> Option<(f64, Vec<usize>)> {
179    ///         // initialization
180    ///         self.distances.reset_all(f64::INFINITY);
181    ///         ...
182    ///
183    ///         // search
184    ///         while let Some((node, cur_dist)) = pq.pop() {
185    ///             ...
186    ///         }
187    ///         ...
188    ///     }
189    /// }
190    /// ```
191    fn reset_all(&mut self, value: T)
192    where
193        T: PartialEq + Copy;
194
195    // provided
196
197    /// Returns a mutable reference to the element at the `idx`-th
198    /// position of the vector if the index is `in_bounds`;
199    /// returns None otherwise.
200    ///
201    /// # Examples
202    ///
203    /// ```rust
204    /// use orx_v::*;
205    ///
206    /// let mut vec = vec![
207    ///     vec![0, 1, 2],
208    ///     vec![3],
209    ///     vec![4, 5],
210    /// ];
211    ///
212    /// *vec.try_at_mut([0, 1]).unwrap() = 42;
213    /// assert_eq!(vec.at([0, 1]), 42);
214    ///
215    /// // vec.at_mut([1, 1]); // panics!
216    /// assert_eq!(vec.try_at_mut([1, 1]), None);
217    /// ```
218    fn try_at_mut(&mut self, idx: impl IntoIdx<D>) -> Option<&mut T> {
219        match D::in_bounds(idx, self) {
220            true => Some(self.at_mut(idx)),
221            false => None,
222        }
223    }
224}
225
226// &mut V auto impl
227
228impl<T, D: Dim, V: NVecMut<D, T>> NVecMut<D, T> for &mut V {
229    fn at_mut<Idx: IntoIdx<D>>(&mut self, idx: Idx) -> &mut T {
230        <V as NVecMut<D, T>>::at_mut(self, idx)
231    }
232
233    fn set<Idx: IntoIdx<D>>(&mut self, idx: Idx, value: T) {
234        <V as NVecMut<D, T>>::set(self, idx, value);
235    }
236
237    fn child_mut(&mut self, i: <D as Dim>::ChildIdx) -> impl NVecMut<<D as Dim>::PrevDim, T> {
238        <V as NVecMut<D, T>>::child_mut(self, i)
239    }
240
241    fn mut_all<F>(&mut self, f: F)
242    where
243        F: FnMut(&mut T),
244    {
245        <V as NVecMut<D, T>>::mut_all(self, f);
246    }
247
248    fn reset_all(&mut self, value: T)
249    where
250        T: PartialEq + Copy,
251    {
252        <V as NVecMut<D, T>>::reset_all(self, value);
253    }
254}