1use std::ops::{Index, IndexMut};
2use std::array;
3use crate::*;
4
5pub trait ArrayLike<T, const N : usize> :
6 From <[T; N]> +
7 Into <[T; N]> +
8 Index<usize,Output = T> + IndexMut<usize,Output = T>
9{
10 const DIMENSION : usize = N;
11 type WithType<T2> : ArrayLike<T2, N>;
12
13 fn splat(value : T) -> Self where T : Clone { Self::from(array::from_fn(|_| value.clone())) }
14
15 fn map<U, F>(self, f : F) -> Self::WithType<U> where F : FnMut(T) -> U { self.to_array().map(f).into() }
16
17 fn map_with<U, T2, F>(self, other : Self::WithType<T2>, mut f : F) -> Self::WithType<U>
18 where F : FnMut(T, T2) -> U
19 {
20 let mut t1_iter = self.to_array().into_iter();
21 let mut t2_iter = other.to_array().into_iter();
22 Self::WithType::<U>::from_array(std::array::from_fn(|_| f(t1_iter.next().unwrap(), t2_iter.next().unwrap())))
23 }
24
25
26 fn any<P>(&self, p : P) -> bool where P : FnMut(&T) -> bool { Iterator::any(&mut self.array().iter(), p) }
28 fn any_with<T2, P>(&self, other : Self::WithType<T2>, mut p : P) -> bool where P : FnMut(&T, &T2) -> bool
30 {
31 for i in 0..N
32 {
33 if p(&self[i], &other[i]) == true { return true; }
34 }
35 false
36 }
37
38 fn all<P>(&self, p : P) -> bool where P : FnMut(&T) -> bool { Iterator::all(&mut self.array().iter(), p) }
40 fn all_with<T2, P>(&self, other : &Self::WithType<T2>, mut p : P) -> bool where P : FnMut(&T, &T2) -> bool
42 {
43 for i in 0..N
44 {
45 if p(&self[i], &other[i]) == false { return false; }
46 }
47 true
48 }
49
50 fn for_each<F>(&self, f : F) where F : FnMut(&T) { self.array().iter().for_each(f); }
51 fn for_each_mut<F>(&mut self, f : F) where F : FnMut(&mut T) { self.array_mut().iter_mut().for_each(f); }
52
53 fn min_element(&self) -> &T where T : PartialOrd { self.array().iter().min_by(|a, b| a.partial_cmp(b).unwrap()).expect("size can't be empty") }
57 fn max_element(&self) -> &T where T : PartialOrd { self.array().iter().max_by(|a, b| a.partial_cmp(b).unwrap()).expect("size can't be empty") }
58
59 fn min_element_idx(&self) -> usize where T : PartialOrd
60 {
61 self.array().iter().enumerate()
62 .min_by(|(_,a), (_,b)| a.partial_cmp(b).unwrap()).map(|(idx,_)| idx).unwrap()
63 }
64 fn max_element_idx(&self) -> usize where T : PartialOrd
65 {
66 self.array().iter().enumerate()
67 .max_by(|(_,a), (_,b)| a.partial_cmp(b).unwrap()).map(|(idx,_)| idx).unwrap()
68 }
69
70 fn array(&self) -> &[T; N];
71 fn array_mut(&mut self) -> &mut[T; N];
72
73 fn slice(&self) -> &[T] { self.array().as_slice() }
74 fn slice_mut(&mut self) -> &mut [T] { self.array_mut().as_mut_slice() }
75
76 fn have_idx(&self, idx : usize) -> bool { idx < N }
77
78 fn get(&self, idx : usize) -> Option<&T> { self.slice().get(idx) }
79 fn get_mut(&mut self, idx : usize) -> Option<&mut T> { self.slice_mut().get_mut(idx) }
80
81 fn set_or_panic(&mut self, idx : usize, val : T) -> &mut Self { *self.get_mut(idx).unwrap() = val; self }
83 fn set(&mut self, idx : usize, val : T) -> &mut Self { self.get_mut(idx).map(|v| *v = val); self }
85
86 fn try_set(&mut self, idx : usize, val : T) -> Result<(), T>
87 {
88 match self.get_mut(idx)
89 {
90 Some(v) => { *v = val; Ok(()) },
91 None => Err(val),
92 }
93 }
94
95 fn with_or_panic(mut self, idx : usize, val : T) -> Self { self.set_or_panic(idx, val); self }
97 fn with(mut self, idx : usize, val : T) -> Self { self.set(idx, val); self }
99
100 fn replace(&mut self, idx : usize, val : T) -> T { std::mem::replace(self.array_mut().get_mut(idx).unwrap(),val) }
102}
103
104
105impl<T, const N : usize> ArrayLike<T,N> for [T; N]
106{
107 type WithType<T2> = [T2; N];
108
109 fn array(&self) -> &[T; N] { self }
110 fn array_mut(&mut self) -> &mut[T; N] { self }
111}