1 //! Implementations of things like `Eq` for fixed-length arrays
2 //! up to a certain length. Eventually, we should be able to generalize
5 //! *[See also the array primitive type](../../std/primitive.array.html).*
7 #![stable(feature = "core_array", since = "1.36.0")]
9 use crate::borrow
::{Borrow, BorrowMut}
;
10 use crate::cmp
::Ordering
;
11 use crate::convert
::{Infallible, TryFrom}
;
13 use crate::hash
::{self, Hash}
;
14 use crate::marker
::Unsize
;
15 use crate::slice
::{Iter, IterMut}
;
19 #[unstable(feature = "array_value_iter", issue = "65798")]
20 pub use iter
::IntoIter
;
22 /// Converts a reference to `T` into a reference to an array of length 1 (without copying).
23 #[unstable(feature = "array_from_ref", issue = "77101")]
24 pub fn from_ref
<T
>(s
: &T
) -> &[T
; 1] {
25 // SAFETY: Converting `&T` to `&[T; 1]` is sound.
26 unsafe { &*(s as *const T).cast::<[T; 1]>() }
29 /// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying).
30 #[unstable(feature = "array_from_ref", issue = "77101")]
31 pub fn from_mut
<T
>(s
: &mut T
) -> &mut [T
; 1] {
32 // SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound.
33 unsafe { &mut *(s as *mut T).cast::<[T; 1]>() }
36 /// Utility trait implemented only on arrays of fixed size
38 /// This trait can be used to implement other traits on fixed-size arrays
39 /// without causing much metadata bloat.
41 /// The trait is marked unsafe in order to restrict implementors to fixed-size
42 /// arrays. User of this trait can assume that implementors have the exact
43 /// layout in memory of a fixed size array (for example, for unsafe
46 /// Note that the traits [`AsRef`] and [`AsMut`] provide similar methods for types that
47 /// may not be fixed-size arrays. Implementors should prefer those traits
49 #[unstable(feature = "fixed_size_array", issue = "27778")]
50 pub unsafe trait FixedSizeArray
<T
> {
51 /// Converts the array to immutable slice
52 #[unstable(feature = "fixed_size_array", issue = "27778")]
53 fn as_slice(&self) -> &[T
];
54 /// Converts the array to mutable slice
55 #[unstable(feature = "fixed_size_array", issue = "27778")]
56 fn as_mut_slice(&mut self) -> &mut [T
];
59 #[unstable(feature = "fixed_size_array", issue = "27778")]
60 unsafe impl<T
, A
: Unsize
<[T
]>> FixedSizeArray
<T
> for A
{
62 fn as_slice(&self) -> &[T
] {
66 fn as_mut_slice(&mut self) -> &mut [T
] {
71 /// The error type returned when a conversion from a slice to an array fails.
72 #[stable(feature = "try_from", since = "1.34.0")]
73 #[derive(Debug, Copy, Clone)]
74 pub struct TryFromSliceError(());
76 #[stable(feature = "core_array", since = "1.36.0")]
77 impl fmt
::Display
for TryFromSliceError
{
79 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
80 fmt
::Display
::fmt(self.__description(), f
)
84 impl TryFromSliceError
{
86 feature
= "array_error_internals",
87 reason
= "available through Error trait and this method should not \
93 pub fn __description(&self) -> &str {
94 "could not convert slice to array"
98 #[stable(feature = "try_from_slice_error", since = "1.36.0")]
99 impl From
<Infallible
> for TryFromSliceError
{
100 fn from(x
: Infallible
) -> TryFromSliceError
{
105 #[stable(feature = "rust1", since = "1.0.0")]
106 impl<T
, const N
: usize> AsRef
<[T
]> for [T
; N
] {
108 fn as_ref(&self) -> &[T
] {
113 #[stable(feature = "rust1", since = "1.0.0")]
114 impl<T
, const N
: usize> AsMut
<[T
]> for [T
; N
] {
116 fn as_mut(&mut self) -> &mut [T
] {
121 #[stable(feature = "array_borrow", since = "1.4.0")]
122 impl<T
, const N
: usize> Borrow
<[T
]> for [T
; N
] {
123 fn borrow(&self) -> &[T
] {
128 #[stable(feature = "array_borrow", since = "1.4.0")]
129 impl<T
, const N
: usize> BorrowMut
<[T
]> for [T
; N
] {
130 fn borrow_mut(&mut self) -> &mut [T
] {
135 #[stable(feature = "try_from", since = "1.34.0")]
136 impl<T
, const N
: usize> TryFrom
<&[T
]> for [T
; N
]
140 type Error
= TryFromSliceError
;
142 fn try_from(slice
: &[T
]) -> Result
<[T
; N
], TryFromSliceError
> {
143 <&Self>::try_from(slice
).map(|r
| *r
)
147 #[stable(feature = "try_from", since = "1.34.0")]
148 impl<'a
, T
, const N
: usize> TryFrom
<&'a
[T
]> for &'a
[T
; N
] {
149 type Error
= TryFromSliceError
;
151 fn try_from(slice
: &[T
]) -> Result
<&[T
; N
], TryFromSliceError
> {
152 if slice
.len() == N
{
153 let ptr
= slice
.as_ptr() as *const [T
; N
];
154 // SAFETY: ok because we just checked that the length fits
157 Err(TryFromSliceError(()))
162 #[stable(feature = "try_from", since = "1.34.0")]
163 impl<'a
, T
, const N
: usize> TryFrom
<&'a
mut [T
]> for &'a
mut [T
; N
] {
164 type Error
= TryFromSliceError
;
166 fn try_from(slice
: &mut [T
]) -> Result
<&mut [T
; N
], TryFromSliceError
> {
167 if slice
.len() == N
{
168 let ptr
= slice
.as_mut_ptr() as *mut [T
; N
];
169 // SAFETY: ok because we just checked that the length fits
170 unsafe { Ok(&mut *ptr) }
172 Err(TryFromSliceError(()))
177 #[stable(feature = "rust1", since = "1.0.0")]
178 impl<T
: Hash
, const N
: usize> Hash
for [T
; N
] {
179 fn hash
<H
: hash
::Hasher
>(&self, state
: &mut H
) {
180 Hash
::hash(&self[..], state
)
184 #[stable(feature = "rust1", since = "1.0.0")]
185 impl<T
: fmt
::Debug
, const N
: usize> fmt
::Debug
for [T
; N
] {
186 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
187 fmt
::Debug
::fmt(&&self[..], f
)
191 #[stable(feature = "rust1", since = "1.0.0")]
192 impl<'a
, T
, const N
: usize> IntoIterator
for &'a
[T
; N
] {
194 type IntoIter
= Iter
<'a
, T
>;
196 fn into_iter(self) -> Iter
<'a
, T
> {
201 #[stable(feature = "rust1", since = "1.0.0")]
202 impl<'a
, T
, const N
: usize> IntoIterator
for &'a
mut [T
; N
] {
203 type Item
= &'a
mut T
;
204 type IntoIter
= IterMut
<'a
, T
>;
206 fn into_iter(self) -> IterMut
<'a
, T
> {
211 #[stable(feature = "rust1", since = "1.0.0")]
212 impl<A
, B
, const N
: usize> PartialEq
<[B
; N
]> for [A
; N
]
217 fn eq(&self, other
: &[B
; N
]) -> bool
{
218 self[..] == other
[..]
221 fn ne(&self, other
: &[B
; N
]) -> bool
{
222 self[..] != other
[..]
226 #[stable(feature = "rust1", since = "1.0.0")]
227 impl<A
, B
, const N
: usize> PartialEq
<[B
]> for [A
; N
]
232 fn eq(&self, other
: &[B
]) -> bool
{
233 self[..] == other
[..]
236 fn ne(&self, other
: &[B
]) -> bool
{
237 self[..] != other
[..]
241 #[stable(feature = "rust1", since = "1.0.0")]
242 impl<A
, B
, const N
: usize> PartialEq
<[A
; N
]> for [B
]
247 fn eq(&self, other
: &[A
; N
]) -> bool
{
248 self[..] == other
[..]
251 fn ne(&self, other
: &[A
; N
]) -> bool
{
252 self[..] != other
[..]
256 #[stable(feature = "rust1", since = "1.0.0")]
257 impl<'b
, A
, B
, const N
: usize> PartialEq
<&'b
[B
]> for [A
; N
]
262 fn eq(&self, other
: &&'b
[B
]) -> bool
{
263 self[..] == other
[..]
266 fn ne(&self, other
: &&'b
[B
]) -> bool
{
267 self[..] != other
[..]
271 #[stable(feature = "rust1", since = "1.0.0")]
272 impl<'b
, A
, B
, const N
: usize> PartialEq
<[A
; N
]> for &'b
[B
]
277 fn eq(&self, other
: &[A
; N
]) -> bool
{
278 self[..] == other
[..]
281 fn ne(&self, other
: &[A
; N
]) -> bool
{
282 self[..] != other
[..]
286 #[stable(feature = "rust1", since = "1.0.0")]
287 impl<'b
, A
, B
, const N
: usize> PartialEq
<&'b
mut [B
]> for [A
; N
]
292 fn eq(&self, other
: &&'b
mut [B
]) -> bool
{
293 self[..] == other
[..]
296 fn ne(&self, other
: &&'b
mut [B
]) -> bool
{
297 self[..] != other
[..]
301 #[stable(feature = "rust1", since = "1.0.0")]
302 impl<'b
, A
, B
, const N
: usize> PartialEq
<[A
; N
]> for &'b
mut [B
]
307 fn eq(&self, other
: &[A
; N
]) -> bool
{
308 self[..] == other
[..]
311 fn ne(&self, other
: &[A
; N
]) -> bool
{
312 self[..] != other
[..]
316 // NOTE: some less important impls are omitted to reduce code bloat
317 // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
318 // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
320 #[stable(feature = "rust1", since = "1.0.0")]
321 impl<T
: Eq
, const N
: usize> Eq
for [T
; N
] {}
323 #[stable(feature = "rust1", since = "1.0.0")]
324 impl<T
: PartialOrd
, const N
: usize> PartialOrd
for [T
; N
] {
326 fn partial_cmp(&self, other
: &[T
; N
]) -> Option
<Ordering
> {
327 PartialOrd
::partial_cmp(&&self[..], &&other
[..])
330 fn lt(&self, other
: &[T
; N
]) -> bool
{
331 PartialOrd
::lt(&&self[..], &&other
[..])
334 fn le(&self, other
: &[T
; N
]) -> bool
{
335 PartialOrd
::le(&&self[..], &&other
[..])
338 fn ge(&self, other
: &[T
; N
]) -> bool
{
339 PartialOrd
::ge(&&self[..], &&other
[..])
342 fn gt(&self, other
: &[T
; N
]) -> bool
{
343 PartialOrd
::gt(&&self[..], &&other
[..])
347 /// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison).
348 #[stable(feature = "rust1", since = "1.0.0")]
349 impl<T
: Ord
, const N
: usize> Ord
for [T
; N
] {
351 fn cmp(&self, other
: &[T
; N
]) -> Ordering
{
352 Ord
::cmp(&&self[..], &&other
[..])
356 // The Default impls cannot be done with const generics because `[T; 0]` doesn't
357 // require Default to be implemented, and having different impl blocks for
358 // different numbers isn't supported yet.
360 macro_rules
! array_impl_default
{
361 {$n:expr, $t:ident $($ts:ident)*}
=> {
362 #[stable(since = "1.4.0", feature = "array_default")]
363 impl<T
> Default
for [T
; $n
] where T
: Default
{
364 fn default() -> [T
; $n
] {
365 [$t
::default(), $
($ts
::default()),*]
368 array_impl_default
!{($n - 1), $($ts)*}
371 #[stable(since = "1.4.0", feature = "array_default")]
372 impl<T
> Default
for [T
; $n
] {
373 fn default() -> [T
; $n
] { [] }
378 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}
381 impl<T
, const N
: usize> [T
; N
] {
382 /// Returns an array of the same size as `self`, with function `f` applied to each element
388 /// #![feature(array_map)]
389 /// let x = [1, 2, 3];
390 /// let y = x.map(|v| v + 1);
391 /// assert_eq!(y, [2, 3, 4]);
393 /// let x = [1, 2, 3];
394 /// let mut temp = 0;
395 /// let y = x.map(|v| { temp += 1; v * temp });
396 /// assert_eq!(y, [1, 4, 9]);
398 /// let x = ["Ferris", "Bueller's", "Day", "Off"];
399 /// let y = x.map(|v| v.len());
400 /// assert_eq!(y, [6, 9, 3, 3]);
402 #[unstable(feature = "array_map", issue = "75243")]
403 pub fn map
<F
, U
>(self, mut f
: F
) -> [U
; N
]
407 use crate::mem
::MaybeUninit
;
408 struct Guard
<T
, const N
: usize> {
413 impl<T
, const N
: usize> Drop
for Guard
<T
, N
> {
415 debug_assert
!(self.initialized
<= N
);
417 let initialized_part
=
418 crate::ptr
::slice_from_raw_parts_mut(self.dst
, self.initialized
);
419 // SAFETY: this raw slice will contain only initialized objects
420 // that's why, it is allowed to drop it.
422 crate::ptr
::drop_in_place(initialized_part
);
426 let mut dst
= MaybeUninit
::uninit_array
::<N
>();
427 let mut guard
: Guard
<U
, N
> =
428 Guard { dst: MaybeUninit::slice_as_mut_ptr(&mut dst), initialized: 0 }
;
429 for (src
, dst
) in IntoIter
::new(self).zip(&mut dst
) {
431 guard
.initialized
+= 1;
433 // FIXME: Convert to crate::mem::transmute once it works with generics.
434 // unsafe { crate::mem::transmute::<[MaybeUninit<U>; N], [U; N]>(dst) }
435 crate::mem
::forget(guard
);
436 // SAFETY: At this point we've properly initialized the whole array
437 // and we just need to cast it to the correct type.
438 unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) }
441 /// Returns a slice containing the entire array. Equivalent to `&s[..]`.
442 #[unstable(feature = "array_methods", issue = "76118")]
443 pub fn as_slice(&self) -> &[T
] {
447 /// Returns a mutable slice containing the entire array. Equivalent to
449 #[unstable(feature = "array_methods", issue = "76118")]
450 pub fn as_mut_slice(&mut self) -> &mut [T
] {