1use core::borrow::{Borrow, BorrowMut};
2use core::cmp::Ordering;
3use core::fmt::{self, Debug};
4use core::hash::{Hash, Hasher};
5
6use typenum::{consts, Const};
7
8use super::{ArrayLength, ConstArrayLength, GenericArray, IntoArrayLength};
9
10use crate::functional::*;
11use crate::sequence::*;
12
13impl<T: Default, N: ArrayLength> Default for GenericArray<T, N> {
14 #[inline(always)]
15 fn default() -> Self {
16 Self::generate(|_| T::default())
17 }
18}
19
20impl<T: Clone, N: ArrayLength> Clone for GenericArray<T, N> {
21 #[inline]
22 fn clone(&self) -> GenericArray<T, N> {
23 self.map(Clone::clone)
24 }
25}
26
27impl<T: Copy, N: ArrayLength> Copy for GenericArray<T, N> where N::ArrayType<T>: Copy {}
28
29impl<T: PartialEq, N: ArrayLength> PartialEq for GenericArray<T, N> {
30 #[inline(always)]
31 fn eq(&self, other: &Self) -> bool {
32 **self == **other
33 }
34}
35impl<T: Eq, N: ArrayLength> Eq for GenericArray<T, N> {}
36
37impl<T: PartialOrd, N: ArrayLength> PartialOrd for GenericArray<T, N> {
38 #[inline(always)]
39 fn partial_cmp(&self, other: &GenericArray<T, N>) -> Option<Ordering> {
40 PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
41 }
42}
43
44impl<T: Ord, N: ArrayLength> Ord for GenericArray<T, N> {
45 #[inline(always)]
46 fn cmp(&self, other: &GenericArray<T, N>) -> Ordering {
47 Ord::cmp(self.as_slice(), other.as_slice())
48 }
49}
50
51impl<T: Debug, N: ArrayLength> Debug for GenericArray<T, N> {
52 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
53 self.as_slice().fmt(fmt)
54 }
55}
56
57impl<T, N: ArrayLength> Borrow<[T]> for GenericArray<T, N> {
58 #[inline(always)]
59 fn borrow(&self) -> &[T] {
60 self.as_slice()
61 }
62}
63
64impl<T, N: ArrayLength> BorrowMut<[T]> for GenericArray<T, N> {
65 #[inline(always)]
66 fn borrow_mut(&mut self) -> &mut [T] {
67 self.as_mut_slice()
68 }
69}
70
71impl<T, N: ArrayLength> AsRef<[T]> for GenericArray<T, N> {
72 #[inline(always)]
73 fn as_ref(&self) -> &[T] {
74 self.as_slice()
75 }
76}
77
78impl<T, N: ArrayLength> AsMut<[T]> for GenericArray<T, N> {
79 #[inline(always)]
80 fn as_mut(&mut self) -> &mut [T] {
81 self.as_mut_slice()
82 }
83}
84
85impl<T: Hash, N: ArrayLength> Hash for GenericArray<T, N> {
86 #[inline]
87 fn hash<H>(&self, state: &mut H)
88 where
89 H: Hasher,
90 {
91 Hash::hash(self.as_slice(), state)
92 }
93}
94
95impl<T, const N: usize> From<[T; N]> for GenericArray<T, ConstArrayLength<N>>
96where
97 Const<N>: IntoArrayLength,
98{
99 #[inline(always)]
100 fn from(value: [T; N]) -> Self {
101 GenericArray::from_array(value)
102 }
103}
104
105impl<T, const N: usize> From<GenericArray<T, ConstArrayLength<N>>> for [T; N]
106where
107 Const<N>: IntoArrayLength,
108{
109 #[inline(always)]
110 fn from(value: GenericArray<T, ConstArrayLength<N>>) -> Self {
111 value.into_array()
112 }
113}
114
115impl<'a, T, const N: usize> From<&'a [T; N]> for &'a GenericArray<T, ConstArrayLength<N>>
116where
117 Const<N>: IntoArrayLength,
118{
119 #[inline(always)]
120 fn from(slice: &'a [T; N]) -> Self {
121 unsafe { &*(slice.as_ptr() as *const GenericArray<T, ConstArrayLength<N>>) }
122 }
123}
124
125impl<'a, T, const N: usize> From<&'a mut [T; N]> for &'a mut GenericArray<T, ConstArrayLength<N>>
126where
127 Const<N>: IntoArrayLength,
128{
129 #[inline(always)]
130 fn from(slice: &'a mut [T; N]) -> Self {
131 unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, ConstArrayLength<N>>) }
132 }
133}
134
135impl<T, const N: usize> AsRef<[T; N]> for GenericArray<T, ConstArrayLength<N>>
136where
137 Const<N>: IntoArrayLength,
138{
139 #[inline(always)]
140 fn as_ref(&self) -> &[T; N] {
141 unsafe { core::mem::transmute(self) }
142 }
143}
144impl<T, const N: usize> AsMut<[T; N]> for GenericArray<T, ConstArrayLength<N>>
145where
146 Const<N>: IntoArrayLength,
147{
148 #[inline(always)]
149 fn as_mut(&mut self) -> &mut [T; N] {
150 unsafe { core::mem::transmute(self) }
151 }
152}
153
154macro_rules! impl_tuple {
155 (@T $t:ident) => { T };
156
157 ($($len:ty => ($($t:ident,)*);)*) => {$(
158 impl<T> From<($(impl_tuple!(@T $t),)*)> for GenericArray<T, $len> {
159 #[inline]
160 #[allow(non_snake_case)]
161 fn from(tuple: ($(impl_tuple!(@T $t),)*)) -> Self {
162 let ($($t,)*) = tuple;
163 GenericArray::from_array([$($t,)*])
164 }
165 }
166
167 impl<T> From<GenericArray<T, $len>> for ($(impl_tuple!(@T $t),)*) {
168 #[inline]
169 #[allow(non_snake_case)]
170 fn from(array: GenericArray<T, $len>) -> Self {
171 let [$($t),*] = array.into_array();
172 ($($t,)*)
173 }
174 }
175 )*};
176}
177
178impl_tuple! {
179 consts::U1 => (A,);
180 consts::U2 => (A,B,);
181 consts::U3 => (A,B,C,);
182 consts::U4 => (A,B,C,D,);
183 consts::U5 => (A,B,C,D,E,);
184 consts::U6 => (A,B,C,D,E,F,);
185 consts::U7 => (A,B,C,D,E,F,G,);
186 consts::U8 => (A,B,C,D,E,F,G,H,);
187 consts::U9 => (A,B,C,D,E,F,G,H,I,);
188 consts::U10 => (A,B,C,D,E,F,G,H,I,J,);
189 consts::U11 => (A,B,C,D,E,F,G,H,I,J,K,);
190 consts::U12 => (A,B,C,D,E,F,G,H,I,J,K,L,);
191}
192
193#[cfg(test)]
194mod tests {
195 use crate::*;
196
197 #[test]
198 fn test_from_inference() {
199 let a = arr![1, 2, 3, 4];
200 let _: [i8; 4] = a.into();
201 }
202}