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}