]> git.lizzy.rs Git - rust.git/blob - src/libcore/array.rs
Rollup merge of #63055 - Mark-Simulacrum:save-analysis-clean-2, r=Xanewok
[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 #[stable(feature = "rust1", since = "1.0.0")]
85 impl<T, const N: usize> AsRef<[T]> for [T; N]
86 where
87     [T; N]: LengthAtMost32,
88 {
89     #[inline]
90     fn as_ref(&self) -> &[T] {
91         &self[..]
92     }
93 }
94
95 #[stable(feature = "rust1", since = "1.0.0")]
96 impl<T, const N: usize> AsMut<[T]> for [T; N]
97 where
98     [T; N]: LengthAtMost32,
99 {
100     #[inline]
101     fn as_mut(&mut self) -> &mut [T] {
102         &mut self[..]
103     }
104 }
105
106 #[stable(feature = "array_borrow", since = "1.4.0")]
107 impl<T, const N: usize> Borrow<[T]> for [T; N]
108 where
109     [T; N]: LengthAtMost32,
110 {
111     fn borrow(&self) -> &[T] {
112         self
113     }
114 }
115
116 #[stable(feature = "array_borrow", since = "1.4.0")]
117 impl<T, const N: usize> BorrowMut<[T]> for [T; N]
118 where
119     [T; N]: LengthAtMost32,
120 {
121     fn borrow_mut(&mut self) -> &mut [T] {
122         self
123     }
124 }
125
126 #[stable(feature = "try_from", since = "1.34.0")]
127 impl<T, const N: usize> TryFrom<&[T]> for [T; N]
128 where
129     T: Copy,
130     [T; N]: LengthAtMost32,
131 {
132     type Error = TryFromSliceError;
133
134     fn try_from(slice: &[T]) -> Result<[T; N], TryFromSliceError> {
135         <&Self>::try_from(slice).map(|r| *r)
136     }
137 }
138
139 #[stable(feature = "try_from", since = "1.34.0")]
140 impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N]
141 where
142     [T; N]: LengthAtMost32,
143 {
144     type Error = TryFromSliceError;
145
146     fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> {
147         if slice.len() == N {
148             let ptr = slice.as_ptr() as *const [T; N];
149             unsafe { Ok(&*ptr) }
150         } else {
151             Err(TryFromSliceError(()))
152         }
153     }
154 }
155
156 #[stable(feature = "try_from", since = "1.34.0")]
157 impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N]
158 where
159     [T; N]: LengthAtMost32,
160 {
161     type Error = TryFromSliceError;
162
163     fn try_from(slice: &mut [T]) -> Result<&mut [T; N], TryFromSliceError> {
164         if slice.len() == N {
165             let ptr = slice.as_mut_ptr() as *mut [T; N];
166             unsafe { Ok(&mut *ptr) }
167         } else {
168             Err(TryFromSliceError(()))
169         }
170     }
171 }
172
173 #[stable(feature = "rust1", since = "1.0.0")]
174 impl<T: Hash, const N: usize> Hash for [T; N]
175 where
176     [T; N]: LengthAtMost32,
177 {
178     fn hash<H: hash::Hasher>(&self, state: &mut H) {
179         Hash::hash(&self[..], state)
180     }
181 }
182
183 #[stable(feature = "rust1", since = "1.0.0")]
184 impl<T: fmt::Debug, const N: usize> fmt::Debug for [T; N]
185 where
186     [T; N]: LengthAtMost32,
187 {
188     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189         fmt::Debug::fmt(&&self[..], f)
190     }
191 }
192
193 #[stable(feature = "rust1", since = "1.0.0")]
194 impl<'a, T, const N: usize> IntoIterator for &'a [T; N]
195 where
196     [T; N]: LengthAtMost32,
197 {
198     type Item = &'a T;
199     type IntoIter = Iter<'a, T>;
200
201     fn into_iter(self) -> Iter<'a, T> {
202         self.iter()
203     }
204 }
205
206 #[stable(feature = "rust1", since = "1.0.0")]
207 impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N]
208 where
209     [T; N]: LengthAtMost32,
210 {
211     type Item = &'a mut T;
212     type IntoIter = IterMut<'a, T>;
213
214     fn into_iter(self) -> IterMut<'a, T> {
215         self.iter_mut()
216     }
217 }
218
219 #[stable(feature = "rust1", since = "1.0.0")]
220 impl<A, B, const N: usize> PartialEq<[B; N]> for [A; N]
221 where
222     A: PartialEq<B>,
223     [A; N]: LengthAtMost32,
224     [B; N]: LengthAtMost32,
225 {
226     #[inline]
227     fn eq(&self, other: &[B; N]) -> bool {
228         self[..] == other[..]
229     }
230     #[inline]
231     fn ne(&self, other: &[B; N]) -> bool {
232         self[..] != other[..]
233     }
234 }
235
236 #[stable(feature = "rust1", since = "1.0.0")]
237 impl<A, B, const N: usize> PartialEq<[B]> for [A; N]
238 where
239     A: PartialEq<B>,
240     [A; N]: LengthAtMost32,
241 {
242     #[inline]
243     fn eq(&self, other: &[B]) -> bool {
244         self[..] == other[..]
245     }
246     #[inline]
247     fn ne(&self, other: &[B]) -> bool {
248         self[..] != other[..]
249     }
250 }
251
252 #[stable(feature = "rust1", since = "1.0.0")]
253 impl<A, B, const N: usize> PartialEq<[A; N]> for [B]
254 where
255     B: PartialEq<A>,
256     [A; N]: LengthAtMost32,
257 {
258     #[inline]
259     fn eq(&self, other: &[A; N]) -> bool {
260         self[..] == other[..]
261     }
262     #[inline]
263     fn ne(&self, other: &[A; N]) -> bool {
264         self[..] != other[..]
265     }
266 }
267
268 #[stable(feature = "rust1", since = "1.0.0")]
269 impl<'b, A, B, const N: usize> PartialEq<&'b [B]> for [A; N]
270 where
271     A: PartialEq<B>,
272     [A; N]: LengthAtMost32,
273 {
274     #[inline]
275     fn eq(&self, other: &&'b [B]) -> bool {
276         self[..] == other[..]
277     }
278     #[inline]
279     fn ne(&self, other: &&'b [B]) -> bool {
280         self[..] != other[..]
281     }
282 }
283
284 #[stable(feature = "rust1", since = "1.0.0")]
285 impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b [B]
286 where
287     B: PartialEq<A>,
288     [A; N]: LengthAtMost32,
289 {
290     #[inline]
291     fn eq(&self, other: &[A; N]) -> bool {
292         self[..] == other[..]
293     }
294     #[inline]
295     fn ne(&self, other: &[A; N]) -> bool {
296         self[..] != other[..]
297     }
298 }
299
300 #[stable(feature = "rust1", since = "1.0.0")]
301 impl<'b, A, B, const N: usize> PartialEq<&'b mut [B]> for [A; N]
302 where
303     A: PartialEq<B>,
304     [A; N]: LengthAtMost32,
305 {
306     #[inline]
307     fn eq(&self, other: &&'b mut [B]) -> bool {
308         self[..] == other[..]
309     }
310     #[inline]
311     fn ne(&self, other: &&'b mut [B]) -> bool {
312         self[..] != other[..]
313     }
314 }
315
316 #[stable(feature = "rust1", since = "1.0.0")]
317 impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b mut [B]
318 where
319     B: PartialEq<A>,
320     [A; N]: LengthAtMost32,
321 {
322     #[inline]
323     fn eq(&self, other: &[A; N]) -> bool {
324         self[..] == other[..]
325     }
326     #[inline]
327     fn ne(&self, other: &[A; N]) -> bool {
328         self[..] != other[..]
329     }
330 }
331
332 // NOTE: some less important impls are omitted to reduce code bloat
333 // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
334 // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
335
336 #[stable(feature = "rust1", since = "1.0.0")]
337 impl<T: Eq, const N: usize> Eq for [T; N] where [T; N]: LengthAtMost32 {}
338
339 #[stable(feature = "rust1", since = "1.0.0")]
340 impl<T: PartialOrd, const N: usize> PartialOrd for [T; N]
341 where
342     [T; N]: LengthAtMost32,
343 {
344     #[inline]
345     fn partial_cmp(&self, other: &[T; N]) -> Option<Ordering> {
346         PartialOrd::partial_cmp(&&self[..], &&other[..])
347     }
348     #[inline]
349     fn lt(&self, other: &[T; N]) -> bool {
350         PartialOrd::lt(&&self[..], &&other[..])
351     }
352     #[inline]
353     fn le(&self, other: &[T; N]) -> bool {
354         PartialOrd::le(&&self[..], &&other[..])
355     }
356     #[inline]
357     fn ge(&self, other: &[T; N]) -> bool {
358         PartialOrd::ge(&&self[..], &&other[..])
359     }
360     #[inline]
361     fn gt(&self, other: &[T; N]) -> bool {
362         PartialOrd::gt(&&self[..], &&other[..])
363     }
364 }
365
366 #[stable(feature = "rust1", since = "1.0.0")]
367 impl<T: Ord, const N: usize> Ord for [T; N]
368 where
369     [T; N]: LengthAtMost32,
370 {
371     #[inline]
372     fn cmp(&self, other: &[T; N]) -> Ordering {
373         Ord::cmp(&&self[..], &&other[..])
374     }
375 }
376
377 /// Implemented for lengths where trait impls are allowed on arrays in core/std
378 #[rustc_on_unimplemented(
379     message="arrays only have std trait implementations for lengths 0..=32",
380 )]
381 #[unstable(feature = "const_generic_impls_guard", issue = "0",
382     reason = "will never be stable, just a temporary step until const generics are stable")]
383 pub trait LengthAtMost32 {}
384
385 macro_rules! array_impls {
386     ($($N:literal)+) => {
387         $(
388             #[unstable(feature = "const_generic_impls_guard", issue = "0")]
389             impl<T> LengthAtMost32 for [T; $N] {}
390         )+
391     }
392 }
393
394 array_impls! {
395      0  1  2  3  4  5  6  7  8  9
396     10 11 12 13 14 15 16 17 18 19
397     20 21 22 23 24 25 26 27 28 29
398     30 31 32
399 }
400
401 // The Default impls cannot be generated using the array_impls! macro because
402 // they require array literals.
403
404 macro_rules! array_impl_default {
405     {$n:expr, $t:ident $($ts:ident)*} => {
406         #[stable(since = "1.4.0", feature = "array_default")]
407         impl<T> Default for [T; $n] where T: Default {
408             fn default() -> [T; $n] {
409                 [$t::default(), $($ts::default()),*]
410             }
411         }
412         array_impl_default!{($n - 1), $($ts)*}
413     };
414     {$n:expr,} => {
415         #[stable(since = "1.4.0", feature = "array_default")]
416         impl<T> Default for [T; $n] {
417             fn default() -> [T; $n] { [] }
418         }
419     };
420 }
421
422 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}