]> git.lizzy.rs Git - rust.git/blob - src/libcore/array.rs
144543be7c465a00b31c8f0d09afd5a2a8b6ee9a
[rust.git] / src / libcore / array.rs
1 //! Implementations of things like `Eq` for fixed-length arrays
2 //! up to a certain length. Eventually we should able to generalize
3 //! to all lengths.
4 //!
5 //! *[See also the array primitive type](../../std/primitive.array.html).*
6
7 #![stable(feature = "core_array", since = "1.36.0")]
8
9 use crate::borrow::{Borrow, BorrowMut};
10 use crate::cmp::Ordering;
11 use crate::convert::{Infallible, TryFrom};
12 use crate::fmt;
13 use crate::hash::{Hash, self};
14 use crate::marker::Unsize;
15 use crate::slice::{Iter, IterMut};
16
17 /// Utility trait implemented only on arrays of fixed size
18 ///
19 /// This trait can be used to implement other traits on fixed-size arrays
20 /// without causing much metadata bloat.
21 ///
22 /// The trait is marked unsafe in order to restrict implementors to fixed-size
23 /// arrays. User of this trait can assume that implementors have the exact
24 /// layout in memory of a fixed size array (for example, for unsafe
25 /// initialization).
26 ///
27 /// Note that the traits AsRef and AsMut provide similar methods for types that
28 /// may not be fixed-size arrays. Implementors should prefer those traits
29 /// instead.
30 #[unstable(feature = "fixed_size_array", issue = "27778")]
31 pub unsafe trait FixedSizeArray<T> {
32     /// Converts the array to immutable slice
33     #[unstable(feature = "fixed_size_array", issue = "27778")]
34     fn as_slice(&self) -> &[T];
35     /// Converts the array to mutable slice
36     #[unstable(feature = "fixed_size_array", issue = "27778")]
37     fn as_mut_slice(&mut self) -> &mut [T];
38 }
39
40 #[unstable(feature = "fixed_size_array", issue = "27778")]
41 unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
42     #[inline]
43     fn as_slice(&self) -> &[T] {
44         self
45     }
46     #[inline]
47     fn as_mut_slice(&mut self) -> &mut [T] {
48         self
49     }
50 }
51
52 /// The error type returned when a conversion from a slice to an array fails.
53 #[stable(feature = "try_from", since = "1.34.0")]
54 #[derive(Debug, Copy, Clone)]
55 pub struct TryFromSliceError(());
56
57 #[stable(feature = "core_array", since = "1.36.0")]
58 impl fmt::Display for TryFromSliceError {
59     #[inline]
60     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61         fmt::Display::fmt(self.__description(), f)
62     }
63 }
64
65 impl TryFromSliceError {
66     #[unstable(feature = "array_error_internals",
67            reason = "available through Error trait and this method should not \
68                      be exposed publicly",
69            issue = "0")]
70     #[inline]
71     #[doc(hidden)]
72     pub fn __description(&self) -> &str {
73         "could not convert slice to array"
74     }
75 }
76
77 #[stable(feature = "try_from_slice_error", since = "1.36.0")]
78 impl From<Infallible> for TryFromSliceError {
79     fn from(x: Infallible) -> TryFromSliceError {
80         match x {}
81     }
82 }
83
84 #[cfg(bootstrap)]
85 macro_rules! __impl_slice_eq1 {
86     ($Lhs: ty, $Rhs: ty) => {
87         __impl_slice_eq1! { $Lhs, $Rhs, Sized }
88     };
89     ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
90         #[stable(feature = "rust1", since = "1.0.0")]
91         impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
92             #[inline]
93             fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] }
94             #[inline]
95             fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] }
96         }
97     }
98 }
99
100 #[cfg(bootstrap)]
101 macro_rules! __impl_slice_eq2 {
102     ($Lhs: ty, $Rhs: ty) => {
103         __impl_slice_eq2! { $Lhs, $Rhs, Sized }
104     };
105     ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
106         __impl_slice_eq1!($Lhs, $Rhs, $Bound);
107
108         #[stable(feature = "rust1", since = "1.0.0")]
109         impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> {
110             #[inline]
111             fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] }
112             #[inline]
113             fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] }
114         }
115     }
116 }
117
118 // macro for implementing n-element array functions and operations
119 #[cfg(bootstrap)]
120 macro_rules! array_impls {
121     ($($N:expr)+) => {
122         $(
123             #[stable(feature = "rust1", since = "1.0.0")]
124             impl<T> AsRef<[T]> for [T; $N] {
125                 #[inline]
126                 fn as_ref(&self) -> &[T] {
127                     &self[..]
128                 }
129             }
130
131             #[stable(feature = "rust1", since = "1.0.0")]
132             impl<T> AsMut<[T]> for [T; $N] {
133                 #[inline]
134                 fn as_mut(&mut self) -> &mut [T] {
135                     &mut self[..]
136                 }
137             }
138
139             #[stable(feature = "array_borrow", since = "1.4.0")]
140             impl<T> Borrow<[T]> for [T; $N] {
141                 fn borrow(&self) -> &[T] {
142                     self
143                 }
144             }
145
146             #[stable(feature = "array_borrow", since = "1.4.0")]
147             impl<T> BorrowMut<[T]> for [T; $N] {
148                 fn borrow_mut(&mut self) -> &mut [T] {
149                     self
150                 }
151             }
152
153             #[stable(feature = "try_from", since = "1.34.0")]
154             impl<T> TryFrom<&[T]> for [T; $N] where T: Copy {
155                 type Error = TryFromSliceError;
156
157                 fn try_from(slice: &[T]) -> Result<[T; $N], TryFromSliceError> {
158                     <&Self>::try_from(slice).map(|r| *r)
159                 }
160             }
161
162             #[stable(feature = "try_from", since = "1.34.0")]
163             impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
164                 type Error = TryFromSliceError;
165
166                 fn try_from(slice: &[T]) -> Result<&[T; $N], TryFromSliceError> {
167                     if slice.len() == $N {
168                         let ptr = slice.as_ptr() as *const [T; $N];
169                         unsafe { Ok(&*ptr) }
170                     } else {
171                         Err(TryFromSliceError(()))
172                     }
173                 }
174             }
175
176             #[stable(feature = "try_from", since = "1.34.0")]
177             impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
178                 type Error = TryFromSliceError;
179
180                 fn try_from(slice: &mut [T]) -> Result<&mut [T; $N], TryFromSliceError> {
181                     if slice.len() == $N {
182                         let ptr = slice.as_mut_ptr() as *mut [T; $N];
183                         unsafe { Ok(&mut *ptr) }
184                     } else {
185                         Err(TryFromSliceError(()))
186                     }
187                 }
188             }
189
190             #[stable(feature = "rust1", since = "1.0.0")]
191             impl<T: Hash> Hash for [T; $N] {
192                 fn hash<H: hash::Hasher>(&self, state: &mut H) {
193                     Hash::hash(&self[..], state)
194                 }
195             }
196
197             #[stable(feature = "rust1", since = "1.0.0")]
198             impl<T: fmt::Debug> fmt::Debug for [T; $N] {
199                 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200                     fmt::Debug::fmt(&&self[..], f)
201                 }
202             }
203
204             #[stable(feature = "rust1", since = "1.0.0")]
205             impl<'a, T> IntoIterator for &'a [T; $N] {
206                 type Item = &'a T;
207                 type IntoIter = Iter<'a, T>;
208
209                 fn into_iter(self) -> Iter<'a, T> {
210                     self.iter()
211                 }
212             }
213
214             #[stable(feature = "rust1", since = "1.0.0")]
215             impl<'a, T> IntoIterator for &'a mut [T; $N] {
216                 type Item = &'a mut T;
217                 type IntoIter = IterMut<'a, T>;
218
219                 fn into_iter(self) -> IterMut<'a, T> {
220                     self.iter_mut()
221                 }
222             }
223
224             // NOTE: some less important impls are omitted to reduce code bloat
225             __impl_slice_eq1! { [A; $N], [B; $N] }
226             __impl_slice_eq2! { [A; $N], [B] }
227             __impl_slice_eq2! { [A; $N], &'b [B] }
228             __impl_slice_eq2! { [A; $N], &'b mut [B] }
229             // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
230             // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
231
232             #[stable(feature = "rust1", since = "1.0.0")]
233             impl<T:Eq> Eq for [T; $N] { }
234
235             #[stable(feature = "rust1", since = "1.0.0")]
236             impl<T:PartialOrd> PartialOrd for [T; $N] {
237                 #[inline]
238                 fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
239                     PartialOrd::partial_cmp(&&self[..], &&other[..])
240                 }
241                 #[inline]
242                 fn lt(&self, other: &[T; $N]) -> bool {
243                     PartialOrd::lt(&&self[..], &&other[..])
244                 }
245                 #[inline]
246                 fn le(&self, other: &[T; $N]) -> bool {
247                     PartialOrd::le(&&self[..], &&other[..])
248                 }
249                 #[inline]
250                 fn ge(&self, other: &[T; $N]) -> bool {
251                     PartialOrd::ge(&&self[..], &&other[..])
252                 }
253                 #[inline]
254                 fn gt(&self, other: &[T; $N]) -> bool {
255                     PartialOrd::gt(&&self[..], &&other[..])
256                 }
257             }
258
259             #[stable(feature = "rust1", since = "1.0.0")]
260             impl<T:Ord> Ord for [T; $N] {
261                 #[inline]
262                 fn cmp(&self, other: &[T; $N]) -> Ordering {
263                     Ord::cmp(&&self[..], &&other[..])
264                 }
265             }
266         )+
267     }
268 }
269
270 #[cfg(not(bootstrap))]
271 mod impls_using_const_generics {
272     use super::*;
273
274     #[stable(feature = "rust1", since = "1.0.0")]
275     impl<T, const N: usize> AsRef<[T]> for [T; N]
276     where
277         [T; N]: LengthAtMost32,
278     {
279         #[inline]
280         fn as_ref(&self) -> &[T] {
281             &self[..]
282         }
283     }
284
285     #[stable(feature = "rust1", since = "1.0.0")]
286     impl<T, const N: usize> AsMut<[T]> for [T; N]
287     where
288         [T; N]: LengthAtMost32,
289     {
290         #[inline]
291         fn as_mut(&mut self) -> &mut [T] {
292             &mut self[..]
293         }
294     }
295
296     #[stable(feature = "array_borrow", since = "1.4.0")]
297     impl<T, const N: usize> Borrow<[T]> for [T; N]
298     where
299         [T; N]: LengthAtMost32,
300     {
301         fn borrow(&self) -> &[T] {
302             self
303         }
304     }
305
306     #[stable(feature = "array_borrow", since = "1.4.0")]
307     impl<T, const N: usize> BorrowMut<[T]> for [T; N]
308     where
309         [T; N]: LengthAtMost32,
310     {
311         fn borrow_mut(&mut self) -> &mut [T] {
312             self
313         }
314     }
315
316     #[stable(feature = "try_from", since = "1.34.0")]
317     impl<T, const N: usize> TryFrom<&[T]> for [T; N]
318     where
319         T: Copy,
320         [T; N]: LengthAtMost32,
321     {
322         type Error = TryFromSliceError;
323
324         fn try_from(slice: &[T]) -> Result<[T; N], TryFromSliceError> {
325             <&Self>::try_from(slice).map(|r| *r)
326         }
327     }
328
329     #[stable(feature = "try_from", since = "1.34.0")]
330     impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N]
331     where
332         [T; N]: LengthAtMost32,
333     {
334         type Error = TryFromSliceError;
335
336         fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> {
337             if slice.len() == N {
338                 let ptr = slice.as_ptr() as *const [T; N];
339                 unsafe { Ok(&*ptr) }
340             } else {
341                 Err(TryFromSliceError(()))
342             }
343         }
344     }
345
346     #[stable(feature = "try_from", since = "1.34.0")]
347     impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N]
348     where
349         [T; N]: LengthAtMost32,
350     {
351         type Error = TryFromSliceError;
352
353         fn try_from(slice: &mut [T]) -> Result<&mut [T; N], TryFromSliceError> {
354             if slice.len() == N {
355                 let ptr = slice.as_mut_ptr() as *mut [T; N];
356                 unsafe { Ok(&mut *ptr) }
357             } else {
358                 Err(TryFromSliceError(()))
359             }
360         }
361     }
362
363     #[stable(feature = "rust1", since = "1.0.0")]
364     impl<T: Hash, const N: usize> Hash for [T; N]
365     where
366         [T; N]: LengthAtMost32,
367     {
368         fn hash<H: hash::Hasher>(&self, state: &mut H) {
369             Hash::hash(&self[..], state)
370         }
371     }
372
373     #[stable(feature = "rust1", since = "1.0.0")]
374     impl<T: fmt::Debug, const N: usize> fmt::Debug for [T; N]
375     where
376         [T; N]: LengthAtMost32,
377     {
378         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
379             fmt::Debug::fmt(&&self[..], f)
380         }
381     }
382
383     #[stable(feature = "rust1", since = "1.0.0")]
384     impl<'a, T, const N: usize> IntoIterator for &'a [T; N]
385     where
386         [T; N]: LengthAtMost32,
387     {
388         type Item = &'a T;
389         type IntoIter = Iter<'a, T>;
390
391         fn into_iter(self) -> Iter<'a, T> {
392             self.iter()
393         }
394     }
395
396     #[stable(feature = "rust1", since = "1.0.0")]
397     impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N]
398     where
399         [T; N]: LengthAtMost32,
400     {
401         type Item = &'a mut T;
402         type IntoIter = IterMut<'a, T>;
403
404         fn into_iter(self) -> IterMut<'a, T> {
405             self.iter_mut()
406         }
407     }
408
409     #[stable(feature = "rust1", since = "1.0.0")]
410     impl<'a, 'b, A, B, const N: usize> PartialEq<[B; N]> for [A; N]
411     where
412         A: PartialEq<B>,
413         [A; N]: LengthAtMost32,
414         [B; N]: LengthAtMost32,
415     {
416         #[inline]
417         fn eq(&self, other: &[B; N]) -> bool {
418             self[..] == other[..]
419         }
420         #[inline]
421         fn ne(&self, other: &[B; N]) -> bool {
422             self[..] != other[..]
423         }
424     }
425
426     #[stable(feature = "rust1", since = "1.0.0")]
427     impl<'a, 'b, A, B, const N: usize> PartialEq<[B]> for [A; N]
428     where
429         A: PartialEq<B>,
430         [A; N]: LengthAtMost32,
431     {
432         #[inline]
433         fn eq(&self, other: &[B]) -> bool {
434             self[..] == other[..]
435         }
436         #[inline]
437         fn ne(&self, other: &[B]) -> bool {
438             self[..] != other[..]
439         }
440     }
441
442     #[stable(feature = "rust1", since = "1.0.0")]
443     impl<'a, 'b, A, B, const N: usize> PartialEq<[A; N]> for [B]
444     where
445         B: PartialEq<A>,
446         [A; N]: LengthAtMost32,
447     {
448         #[inline]
449         fn eq(&self, other: &[A; N]) -> bool {
450             self[..] == other[..]
451         }
452         #[inline]
453         fn ne(&self, other: &[A; N]) -> bool {
454             self[..] != other[..]
455         }
456     }
457
458     #[stable(feature = "rust1", since = "1.0.0")]
459     impl<'a, 'b, A, B, const N: usize> PartialEq<&'b [B]> for [A; N]
460     where
461         A: PartialEq<B>,
462         [A; N]: LengthAtMost32,
463     {
464         #[inline]
465         fn eq(&self, other: &&'b [B]) -> bool {
466             self[..] == other[..]
467         }
468         #[inline]
469         fn ne(&self, other: &&'b [B]) -> bool {
470             self[..] != other[..]
471         }
472     }
473
474     #[stable(feature = "rust1", since = "1.0.0")]
475     impl<'a, 'b, A, B, const N: usize> PartialEq<[A; N]> for &'b [B]
476     where
477         B: PartialEq<A>,
478         [A; N]: LengthAtMost32,
479     {
480         #[inline]
481         fn eq(&self, other: &[A; N]) -> bool {
482             self[..] == other[..]
483         }
484         #[inline]
485         fn ne(&self, other: &[A; N]) -> bool {
486             self[..] != other[..]
487         }
488     }
489
490     #[stable(feature = "rust1", since = "1.0.0")]
491     impl<'a, 'b, A, B, const N: usize> PartialEq<&'b mut [B]> for [A; N]
492     where
493         A: PartialEq<B>,
494         [A; N]: LengthAtMost32,
495     {
496         #[inline]
497         fn eq(&self, other: &&'b mut [B]) -> bool {
498             self[..] == other[..]
499         }
500         #[inline]
501         fn ne(&self, other: &&'b mut [B]) -> bool {
502             self[..] != other[..]
503         }
504     }
505
506     #[stable(feature = "rust1", since = "1.0.0")]
507     impl<'a, 'b, A, B, const N: usize> PartialEq<[A; N]> for &'b mut [B]
508     where
509         B: PartialEq<A>,
510         [A; N]: LengthAtMost32,
511     {
512         #[inline]
513         fn eq(&self, other: &[A; N]) -> bool {
514             self[..] == other[..]
515         }
516         #[inline]
517         fn ne(&self, other: &[A; N]) -> bool {
518             self[..] != other[..]
519         }
520     }
521
522     // NOTE: some less important impls are omitted to reduce code bloat
523     // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
524     // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
525
526     #[stable(feature = "rust1", since = "1.0.0")]
527     impl<T: Eq, const N: usize> Eq for [T; N] where [T; N]: LengthAtMost32 {}
528
529     #[stable(feature = "rust1", since = "1.0.0")]
530     impl<T: PartialOrd, const N: usize> PartialOrd for [T; N]
531     where
532         [T; N]: LengthAtMost32,
533     {
534         #[inline]
535         fn partial_cmp(&self, other: &[T; N]) -> Option<Ordering> {
536             PartialOrd::partial_cmp(&&self[..], &&other[..])
537         }
538         #[inline]
539         fn lt(&self, other: &[T; N]) -> bool {
540             PartialOrd::lt(&&self[..], &&other[..])
541         }
542         #[inline]
543         fn le(&self, other: &[T; N]) -> bool {
544             PartialOrd::le(&&self[..], &&other[..])
545         }
546         #[inline]
547         fn ge(&self, other: &[T; N]) -> bool {
548             PartialOrd::ge(&&self[..], &&other[..])
549         }
550         #[inline]
551         fn gt(&self, other: &[T; N]) -> bool {
552             PartialOrd::gt(&&self[..], &&other[..])
553         }
554     }
555
556     #[stable(feature = "rust1", since = "1.0.0")]
557     impl<T: Ord, const N: usize> Ord for [T; N]
558     where
559         [T; N]: LengthAtMost32,
560     {
561         #[inline]
562         fn cmp(&self, other: &[T; N]) -> Ordering {
563             Ord::cmp(&&self[..], &&other[..])
564         }
565     }
566 }
567
568 /// Implemented for lengths where trait impls are allowed on arrays in core/std
569 #[rustc_on_unimplemented(
570     message="arrays only have std trait implementations for lengths 0..=32",
571 )]
572 #[unstable(feature = "const_generic_impls_guard", issue = "0",
573     reason = "will never be stable, just a temporary step until const generics are stable")]
574 #[cfg(not(bootstrap))]
575 pub trait LengthAtMost32 {}
576
577 #[cfg(not(bootstrap))]
578 macro_rules! array_impls {
579     ($($N:literal)+) => {
580         $(
581             #[unstable(feature = "const_generic_impls_guard", issue = "0")]
582             impl<T> LengthAtMost32 for [T; $N] {}
583         )+
584     }
585 }
586
587 array_impls! {
588      0  1  2  3  4  5  6  7  8  9
589     10 11 12 13 14 15 16 17 18 19
590     20 21 22 23 24 25 26 27 28 29
591     30 31 32
592 }
593
594 // The Default impls cannot be generated using the array_impls! macro because
595 // they require array literals.
596
597 macro_rules! array_impl_default {
598     {$n:expr, $t:ident $($ts:ident)*} => {
599         #[stable(since = "1.4.0", feature = "array_default")]
600         impl<T> Default for [T; $n] where T: Default {
601             fn default() -> [T; $n] {
602                 [$t::default(), $($ts::default()),*]
603             }
604         }
605         array_impl_default!{($n - 1), $($ts)*}
606     };
607     {$n:expr,} => {
608         #[stable(since = "1.4.0", feature = "array_default")]
609         impl<T> Default for [T; $n] {
610             fn default() -> [T; $n] { [] }
611         }
612     };
613 }
614
615 array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}