1use std::ops::{Index, IndexMut};
2use std::slice::{Iter, IterMut};
3use std::{alloc, fmt, mem, ops, ptr};
4
5pub struct Matrix<'a, T>
8where
9 T: Default + Clone,
10{
11 cols: usize,
12 buffer: &'a mut [T],
13}
14
15impl<'a, T> Matrix<'a, T>
16where
17 T: Default + Clone,
18{
19 pub fn new(rows: usize, cols: usize) -> Self {
25 Self {
26 cols,
27 buffer: Self::alloc(rows, cols),
28 }
29 }
30
31 pub fn clear(&mut self) {
34 Self::fill_with(self.buffer, T::default());
35 }
36
37 pub fn fill(&mut self, value: T) {
40 Self::fill_with(self.buffer, value);
41 }
42
43 pub fn rows(&self) -> usize {
46 self.buffer.len() / self.cols
47 }
48
49 pub fn cols(&self) -> usize {
52 self.cols
53 }
54
55 pub fn elements_number(&self) -> usize {
58 self.buffer.len()
59 }
60
61 pub fn nth(&self, index: usize) -> &T {
64 &self.buffer[index]
65 }
66
67 pub fn get(&self, row: usize, col: usize) -> &T {
72 &self.buffer[self.linear_index(row, col)]
73 }
74
75 pub fn set(&mut self, row: usize, col: usize, value: T) {
80 self.buffer[self.linear_index(row, col)] = value;
81 }
82
83 pub fn iter(&self) -> Iter<'_, T> {
86 self.buffer.iter()
87 }
88
89 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
92 self.buffer.iter_mut()
93 }
94
95 fn alloc(rows: usize, cols: usize) -> &'a mut [T] {
98 unsafe {
99 let buf = alloc::alloc(layout::<T>(rows * cols).unwrap()) as *mut T;
100 let slice = std::slice::from_raw_parts_mut(buf, rows * cols);
101 Self::fill_with(slice, T::default());
102 slice
103 }
104 }
105
106 fn fill_with(buf: &mut [T], value: T) {
109 let mut ptr = buf.as_mut_ptr();
110 for _ in 0..buf.len() {
111 unsafe {
112 ptr::write(ptr, value.clone());
113 ptr = ptr.offset(1);
114 }
115 }
116 }
117
118 fn linear_index(&self, row: usize, col: usize) -> usize {
119 if row >= self.rows() || col >= self.cols {
120 panic!("index out of bounds");
121 }
122 row * self.cols + col
123 }
124
125 fn is_same_size(&self, other: &Self) -> bool {
126 self.cols == other.cols && self.buffer.len() == other.buffer.len()
127 }
128}
129
130impl<'a, T> Drop for Matrix<'a, T>
131where
132 T: Default + Clone,
133{
134 fn drop(&mut self) {
135 unsafe {
136 alloc::dealloc(
137 self.buffer.as_mut_ptr() as *mut u8,
138 layout::<T>(self.buffer.len()).unwrap(),
139 );
140 }
141 }
142}
143
144fn layout<T>(size: usize) -> Result<alloc::Layout, alloc::LayoutError> {
145 alloc::Layout::from_size_align(size * mem::size_of::<T>(), mem::align_of::<T>())
146}
147
148impl<'a, T> PartialEq for Matrix<'a, T>
149where
150 T: Default + Clone + PartialEq,
151{
152 fn eq(&self, other: &Self) -> bool {
153 if self.cols == other.cols && self.buffer == other.buffer {
154 true
155 } else {
156 false
157 }
158 }
159}
160
161impl<'a, T> Index<usize> for Matrix<'a, T>
162where
163 T: Default + Clone,
164{
165 type Output = [T];
166
167 fn index(&self, row: usize) -> &Self::Output {
168 if row >= self.rows() {
169 panic!("index out of bounds")
170 }
171 &self.buffer[row * self.cols..(row + 1) * self.cols]
172 }
173}
174
175impl<'a, T> IndexMut<usize> for Matrix<'a, T>
176where
177 T: Default + Clone,
178{
179 fn index_mut(&mut self, row: usize) -> &mut Self::Output {
180 if row >= self.rows() {
181 panic!("index out of bounds")
182 }
183 &mut self.buffer[row * self.cols..(row + 1) * self.cols]
184 }
185}
186
187impl<'a, T> Clone for Matrix<'a, T>
188where
189 T: Default + Clone,
190{
191 fn clone(&self) -> Self {
192 let new_buf = Self::alloc(self.rows(), self.cols());
193 for idx in 0..self.buffer.len() {
194 new_buf[idx] = self.buffer[idx].clone();
195 }
196 Matrix {
197 cols: self.cols,
198 buffer: new_buf,
199 }
200 }
201}
202
203impl<'a, T> fmt::Debug for Matrix<'a, T>
204where
205 T: Default + Clone + fmt::Display,
206{
207 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208 write!(f, "{{")?;
209 for i in 0..self.rows() {
210 if i > 0 {
211 write!(f, " ")?;
212 }
213 write!(f, "{{")?;
214 for j in 0..self.cols() {
215 write!(f, "{}", self[i][j])?;
216 if j + 1 < self.cols() {
217 write!(f, ",")?;
218 }
219 }
220 write!(f, "}}")?;
221 if i + 1 < self.rows() {
222 writeln!(f)?;
223 }
224 }
225 write!(f, "}}")
226 }
227}
228
229impl<'a, T> ops::Add for Matrix<'a, T>
230where
231 T: Default + Clone + ops::Add<Output = T>,
232{
233 type Output = Self;
234
235 fn add(self, other: Self) -> Self {
238 if !self.is_same_size(&other) {
239 panic!("operands vary in size");
240 }
241 let result = Self::new(self.rows(), self.cols());
242 for idx in 0..self.elements_number() {
243 result.buffer[idx] = self.buffer[idx].clone() + other.buffer[idx].clone();
244 }
245 result
246 }
247}
248
249impl<'a, T> ops::Sub for Matrix<'a, T>
250where
251 T: Default + Clone + ops::Sub<Output = T>,
252{
253 type Output = Self;
254
255 fn sub(self, other: Self) -> Self {
258 if !self.is_same_size(&other) {
259 panic!("operands vary in size");
260 }
261 let result = Self::new(self.rows(), self.cols());
262 for idx in 0..self.elements_number() {
263 result.buffer[idx] = self.buffer[idx].clone() - other.buffer[idx].clone();
264 }
265 result
266 }
267}
268
269impl<'a, T> ops::Mul<T> for Matrix<'a, T>
270where
271 T: Default + Clone + ops::Mul<Output = T>,
272{
273 type Output = Self;
274
275 fn mul(self, value: T) -> Self {
277 let result = Self::new(self.rows(), self.cols());
278 for idx in 0..self.elements_number() {
279 result.buffer[idx] = self.buffer[idx].clone() * value.clone();
280 }
281 result
282 }
283}
284
285impl<'a, T> ops::Deref for Matrix<'a, T>
286where
287 T: Default + Clone,
288{
289 type Target = [T];
290
291 fn deref(&self) -> &Self::Target {
292 self.buffer
293 }
294}
295
296impl<'a, T> ops::DerefMut for Matrix<'a, T>
297where
298 T: Default + Clone,
299{
300 fn deref_mut(&mut self) -> &mut Self::Target {
301 self.buffer
302 }
303}
304
305#[cfg(test)]
306mod tests {
307 use super::Matrix;
308 use std::fmt::Debug;
309
310 #[test]
311 fn new_ok() {
312 let m = Matrix::<i32>::new(100, 100);
313 assert_eq_all::<i32>(&m, 0);
314 }
315
316 #[test]
317 fn fill_ok() {
318 let mut m = Matrix::<i32>::new(100, 100);
319 m.fill(1);
320 assert_eq_all::<i32>(&m, 1);
321 }
322
323 #[test]
324 fn clear_ok() {
325 let mut m = Matrix::<i32>::new(100, 100);
326 m.fill(1);
327 assert_eq_all::<i32>(&m, 1);
328 m.clear();
329 assert_eq_all::<i32>(&m, 0);
330 }
331
332 #[test]
333 fn get_set_ok() {
334 let mut m = Matrix::<i32>::new(2, 3);
335 m.set(1, 1, 777);
336 assert_eq!(m.get(1, 1), &777);
337 }
338
339 #[test]
340 fn index_ok() {
341 let mut m = Matrix::<i32>::new(2, 3);
342 m.set(1, 1, 777);
343 assert_eq!(m[0][2], 0);
344 assert_eq!(m[1][1], 777);
345 }
346
347 #[test]
348 fn index_mut_ok() {
349 let mut m = Matrix::<i32>::new(2, 3);
350 m[1][1] = 777;
351 assert_eq!(m.get(1, 1), &777);
352 m[0][0] = m[1][1] - 111;
353 assert_eq!(m.get(0, 0), &666);
354 }
355
356 #[test]
357 fn clone_ok() {
358 let mut a = Matrix::<i32>::new(2, 3);
360 a.fill(100);
361 let b = a.clone();
362 a.fill(200);
363 assert_eq_all(&b, 100);
364 assert_eq_all(&a, 200);
365
366 let mut s1 = Matrix::<String>::new(2, 3);
368 s1.fill(String::from("first"));
369 let s2 = s1.clone();
370 s1.fill(String::from("second"));
371 assert_eq_all(&s2, String::from("first"));
372 assert_eq_all(&s1, String::from("second"));
373 }
374
375 #[test]
376 fn debug_ok() {
377 let mut a = Matrix::<i32>::new(3, 3);
378 a.fill(2);
379 println!("{:?}", a);
380 }
381
382 #[test]
383 fn iter_ok() {
384 let mut m = Matrix::<i32>::new(2, 3);
385 m.fill(7);
386 let mut count = 0;
387 for e in m.iter() {
388 assert_eq!(e, &7);
389 count += 1;
390 }
391 assert_eq!(count, m.elements_number());
392 }
393
394 #[test]
395 fn iter_mut_ok() {
396 let mut m1 = Matrix::<i32>::new(2, 3);
397 for e in m1.iter_mut() {
398 *e = 7;
399 }
400 let mut m2 = Matrix::<i32>::new(2, 3);
401 m2.fill(7);
402 assert_eq!(m1, m2);
403 }
404
405 #[test]
406 fn add_ok() {
407 let mut a = Matrix::<i32>::new(2, 3);
408 a.fill(7);
409 let mut b = Matrix::<i32>::new(2, 3);
410 b.fill(5);
411 let c = a + b;
412 assert_eq_all(&c, 12);
413 }
414
415 #[test]
416 fn sub_ok() {
417 let mut a = Matrix::<i32>::new(2, 3);
418 a.fill(7);
419 let mut b = Matrix::<i32>::new(2, 3);
420 b.fill(5);
421 let c = a - b;
422 assert_eq_all(&c, 2);
423 }
424
425 #[test]
426 fn mul_ok() {
427 let mut a = Matrix::<i32>::new(2, 3);
428 a.fill(7);
429 let b = a * 10;
430 assert_eq_all(&b, 70);
431 }
432
433 #[test]
434 fn deref_ok() {
435 let mut m = Matrix::<i32>::new(2, 3);
436 m[0][0] = 7;
437 m[0][1] = 12;
438 m[0][2] = 17;
439 m[1][0] = 25;
440 m[1][1] = 31;
441 m[1][2] = 100;
442 assert_eq!(m.binary_search(&31), Ok(4));
443 }
444
445 #[test]
446 fn deref_mut_ok() {
447 let mut m = Matrix::<i32>::new(2, 3);
448 m.fill(7);
449 if let Some(first) = m.first_mut() {
450 *first = 70;
451 }
452 assert_eq!(m[0][0], 70);
453 }
454
455 fn assert_eq_all<T: Default + Clone + PartialEq + Debug>(m: &Matrix<T>, value: T) {
456 for i in 0..m.rows() {
457 for j in 0..m.cols() {
458 assert_eq!(m.get(i, j), &value);
459 }
460 }
461 }
462}