1#[doc(hidden)]
35#[macro_export(local_inner_macros)]
36macro_rules! __impl_slice_eq1 {
37 ($Lhs: ty, $Rhs: ty) => {
38 __impl_slice_eq1! { $Lhs, $Rhs, Sized }
39 };
40 ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
41 impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
42 #[inline]
43 fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] }
44 #[inline]
45 fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] }
46 }
47 }
48}
49
50#[doc(hidden)]
51#[macro_export(local_inner_macros)]
52macro_rules! __impl_slice_eq2 {
53 ($Lhs: ty, $Rhs: ty) => {
54 __impl_slice_eq2! { $Lhs, $Rhs, Sized }
55 };
56 ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
57 __impl_slice_eq1!($Lhs, $Rhs, $Bound);
58
59 impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> {
60 #[inline]
61 fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] }
62 #[inline]
63 fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] }
64 }
65 }
66}
67
68#[doc(hidden)]
69#[macro_export(local_inner_macros)]
71macro_rules! __array_impls {
72 ($name:ident, $size:expr) => {
73 impl<T> AsRef<[T]> for $name<T> {
74 #[inline]
75 fn as_ref(&self) -> &[T] {
76 &self.0[..]
77 }
78 }
79
80 impl<T> AsMut<[T]> for $name<T> {
81 #[inline]
82 fn as_mut(&mut self) -> &mut [T] {
83 &mut self.0[..]
84 }
85 }
86
87 impl<T> ::std::borrow::Borrow<[T]> for $name<T> {
88 fn borrow(&self) -> &[T] {
89 &self.0
90 }
91 }
92
93 impl<T> ::std::borrow::BorrowMut<[T]> for $name<T> {
94 fn borrow_mut(&mut self) -> &mut [T] {
95 &mut self.0
96 }
97 }
98
99 impl<T: ::std::hash::Hash> ::std::hash::Hash for $name<T> {
100 fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
101 ::std::hash::Hash::hash(&self.0[..], state)
102 }
103 }
104
105 impl<T: ::std::fmt::Debug> ::std::fmt::Debug for $name<T> {
106 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
107 ::std::fmt::Debug::fmt(&&self.0[..], f)
108 }
109 }
110
111 impl<'a, T> IntoIterator for &'a $name<T> {
112 type Item = &'a T;
113 type IntoIter = ::std::slice::Iter<'a, T>;
114
115 fn into_iter(self) -> ::std::slice::Iter<'a, T> {
116 self.0.iter()
117 }
118 }
119
120 impl<'a, T> IntoIterator for &'a mut $name<T> {
121 type Item = &'a mut T;
122 type IntoIter = ::std::slice::IterMut<'a, T>;
123
124 fn into_iter(self) -> ::std::slice::IterMut<'a, T> {
125 self.0.iter_mut()
126 }
127 }
128
129 __impl_slice_eq1! { $name<A>, $name<B> }
131 impl<T:Eq> Eq for $name<T> { }
138
139 impl<T:PartialOrd> PartialOrd for $name<T> {
140 #[inline]
141 fn partial_cmp(&self, other: &$name<T>) -> Option<::std::cmp::Ordering> {
142 PartialOrd::partial_cmp(&&self[..], &&other[..])
143 }
144 #[inline]
145 fn lt(&self, other: &$name<T>) -> bool {
146 PartialOrd::lt(&&self[..], &&other[..])
147 }
148 #[inline]
149 fn le(&self, other: &$name<T>) -> bool {
150 PartialOrd::le(&&self[..], &&other[..])
151 }
152 #[inline]
153 fn ge(&self, other: &$name<T>) -> bool {
154 PartialOrd::ge(&&self[..], &&other[..])
155 }
156 #[inline]
157 fn gt(&self, other: &$name<T>) -> bool {
158 PartialOrd::gt(&&self[..], &&other[..])
159 }
160 }
161
162 impl<T:Ord> Ord for $name<T> {
163 #[inline]
164 fn cmp(&self, other: &$name<T>) -> ::std::cmp::Ordering {
165 Ord::cmp(&&self[..], &&other[..])
166 }
167 }
168
169 impl<T> ::std::ops::Index<usize> for $name<T> {
172 type Output = T;
173
174 fn index(&self, idx: usize) -> &T {
175 &self.0[idx]
176 }
177 }
178
179 impl<T> ::std::ops::IndexMut<usize> for $name<T> {
180 fn index_mut(&mut self, idx: usize) -> &mut T {
181 &mut self.0[idx]
182 }
183 }
184
185 impl<T> ::std::ops::Index<::std::ops::Range<usize>> for $name<T> {
186 type Output = [T];
187
188 fn index(&self, index: ::std::ops::Range<usize>) -> &[T] {
189 &self.0[index]
190 }
191 }
192
193 impl<T> ::std::ops::IndexMut<::std::ops::Range<usize>> for $name<T> {
194 fn index_mut(&mut self, index: ::std::ops::Range<usize>) -> &mut [T] {
195 &mut self.0[index]
196 }
197 }
198
199 impl<T> ::std::ops::Index<::std::ops::RangeFrom<usize>> for $name<T> {
200 type Output = [T];
201
202 fn index(&self, index: ::std::ops::RangeFrom<usize>) -> &[T] {
203 &self.0[index]
204 }
205 }
206
207 impl<T> ::std::ops::IndexMut<::std::ops::RangeFrom<usize>> for $name<T> {
208 fn index_mut(&mut self, index: ::std::ops::RangeFrom<usize>) -> &mut [T] {
209 &mut self.0[index]
210 }
211 }
212
213 impl<T> ::std::ops::Index<::std::ops::RangeTo<usize>> for $name<T> {
214 type Output = [T];
215
216 fn index(&self, index: ::std::ops::RangeTo<usize>) -> &[T] {
217 &self.0[index]
218 }
219 }
220
221 impl<T> ::std::ops::IndexMut<::std::ops::RangeTo<usize>> for $name<T> {
222 fn index_mut(&mut self, index: ::std::ops::RangeTo<usize>) -> &mut [T] {
223 &mut self.0[index]
224 }
225 }
226
227 impl<T> ::std::ops::Index<::std::ops::RangeInclusive<usize>> for $name<T> {
228 type Output = [T];
229
230 fn index(&self, index: ::std::ops::RangeInclusive<usize>) -> &[T] {
231 &self.0[index]
232 }
233 }
234
235 impl<T> ::std::ops::IndexMut<::std::ops::RangeInclusive<usize>> for $name<T> {
236 fn index_mut(&mut self, index: ::std::ops::RangeInclusive<usize>) -> &mut [T] {
237 &mut self.0[index]
238 }
239 }
240
241 impl<T> ::std::ops::Index<::std::ops::RangeToInclusive<usize>> for $name<T> {
242 type Output = [T];
243
244 fn index(&self, index: ::std::ops::RangeToInclusive<usize>) -> &[T] {
245 &self.0[index]
246 }
247 }
248
249 impl<T> ::std::ops::IndexMut<::std::ops::RangeToInclusive<usize>> for $name<T> {
250 fn index_mut(&mut self, index: ::std::ops::RangeToInclusive<usize>) -> &mut [T] {
251 &mut self.0[index]
252 }
253 }
254 impl<T> ::std::ops::Index<::std::ops::RangeFull> for $name<T> {
255 type Output = [T];
256
257 fn index(&self, index: ::std::ops::RangeFull) -> &[T] {
258 &self.0[index]
259 }
260 }
261
262 impl<T> ::std::ops::IndexMut<::std::ops::RangeFull> for $name<T> {
263 fn index_mut(&mut self, index: ::std::ops::RangeFull) -> &mut [T] {
264 &mut self.0[index]
265 }
266 }
267
268 impl<T> From<[T; $size]> for $name<T> {
269 fn from(from: [T; $size]) -> $name<T> {
270 $name(from)
271 }
272 }
273
274 impl<T> Into<[T; $size]> for $name<T> {
275 fn into(self) -> [T; $size] {
276 self.0
277 }
278 }
279
280 impl<T> AsRef<[T; $size]> for $name<T> {
281 fn as_ref(&self) -> &[T; $size] {
282 &self.0
283 }
284 }
285
286 impl<T: Default + Copy> Default for $name<T> {
287 fn default() -> Self {
288 $name([T::default(); $size])
289 }
290 }
291 }
292}
293
294#[macro_export(local_inner_macros)]
295macro_rules! newtype_array {
296 (pub struct $name:ident(pub $size:expr)) => {
297 #[derive(Copy, Clone)]
300 pub struct $name<T>(pub [T; $size]);
301 __array_impls!($name, $size);
302 };
303 (pub struct $name:ident($size:expr)) => {
304 #[derive(Copy, Clone)]
307 pub struct $name<T>([T; $size]);
308 __array_impls!($name, $size);
309 };
310 (struct $name:ident($size:expr)) => {
311 #[derive(Copy, Clone)]
314 struct $name<T>([T; $size]);
315 __array_impls!($name, $size);
316 }
317}
318
319#[cfg(test)]
320mod tests {
321 use std::collections::HashMap;
322 #[test]
323 fn it_works() {
324
325 newtype_array!(pub struct Array48(pub 48));
327 newtype_array!(pub struct Array64(pub 64));
329
330 let arr1: Array48<u8> = [0; 48].into();
332 let arr2 = arr1.clone();
333 assert_eq!(arr1, arr2);
334
335 let mut map = HashMap::new();
337 map.insert(arr1, "hello");
338
339 let dflt: Array48<u32> = Array48::default();
341 assert_eq!(dflt[0], 0);
342 }
343}