2014-11-14 11:37:59 +00:00
//! Implementations of things like `Eq` for fixed-length arrays
2019-11-27 09:27:30 +00:00
//! up to a certain length. Eventually, we should be able to generalize
2014-11-14 11:37:59 +00:00
//! to all lengths.
2015-07-20 18:21:02 +00:00
//!
2016-03-01 12:44:48 +00:00
//! *[See also the array primitive type](../../std/primitive.array.html).*
2014-10-31 09:41:25 +00:00
2019-05-09 02:58:39 +00:00
#![ stable(feature = " core_array " , since = " 1.36.0 " ) ]
2015-03-23 21:01:28 +00:00
2019-04-15 02:23:21 +00:00
use crate ::borrow ::{ Borrow , BorrowMut } ;
use crate ::cmp ::Ordering ;
2019-04-26 19:45:26 +00:00
use crate ::convert ::{ Infallible , TryFrom } ;
2019-04-15 02:23:21 +00:00
use crate ::fmt ;
2019-12-22 22:42:04 +00:00
use crate ::hash ::{ self , Hash } ;
2019-04-15 02:23:21 +00:00
use crate ::marker ::Unsize ;
2020-07-31 20:19:10 +00:00
use crate ::ops ::{ Index , IndexMut } ;
2019-04-15 02:23:21 +00:00
use crate ::slice ::{ Iter , IterMut } ;
2014-10-31 09:41:25 +00:00
2019-07-24 22:39:39 +00:00
mod iter ;
2019-10-25 08:50:21 +00:00
#[ unstable(feature = " array_value_iter " , issue = " 65798 " ) ]
2019-07-24 22:39:39 +00:00
pub use iter ::IntoIter ;
2020-09-22 19:35:43 +00:00
/// Converts a reference to `T` into a reference to an array of length 1 (without copying).
2020-09-23 11:48:21 +00:00
#[ unstable(feature = " array_from_ref " , issue = " 77101 " ) ]
2020-09-22 19:35:43 +00:00
pub fn from_ref < T > ( s : & T ) -> & [ T ; 1 ] {
// SAFETY: Converting `&T` to `&[T; 1]` is sound.
unsafe { & * ( s as * const T ) . cast ::< [ T ; 1 ] > ( ) }
}
/// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying).
2020-09-23 11:48:21 +00:00
#[ unstable(feature = " array_from_ref " , issue = " 77101 " ) ]
2020-09-22 19:35:43 +00:00
pub fn from_mut < T > ( s : & mut T ) -> & mut [ T ; 1 ] {
// SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound.
unsafe { & mut * ( s as * mut T ) . cast ::< [ T ; 1 ] > ( ) }
}
2015-02-27 19:48:51 +00:00
/// Utility trait implemented only on arrays of fixed size
///
/// This trait can be used to implement other traits on fixed-size arrays
/// without causing much metadata bloat.
2015-09-23 15:38:01 +00:00
///
/// The trait is marked unsafe in order to restrict implementors to fixed-size
/// arrays. User of this trait can assume that implementors have the exact
/// layout in memory of a fixed size array (for example, for unsafe
/// initialization).
///
2019-08-01 08:07:40 +00:00
/// Note that the traits [`AsRef`] and [`AsMut`] provide similar methods for types that
2015-09-23 15:38:01 +00:00
/// may not be fixed-size arrays. Implementors should prefer those traits
/// instead.
2019-05-09 02:58:39 +00:00
#[ unstable(feature = " fixed_size_array " , issue = " 27778 " ) ]
2015-09-19 19:33:34 +00:00
pub unsafe trait FixedSizeArray < T > {
2015-02-27 19:48:51 +00:00
/// Converts the array to immutable slice
2019-05-09 02:58:39 +00:00
#[ unstable(feature = " fixed_size_array " , issue = " 27778 " ) ]
2015-02-27 19:48:51 +00:00
fn as_slice ( & self ) -> & [ T ] ;
/// Converts the array to mutable slice
2019-05-09 02:58:39 +00:00
#[ unstable(feature = " fixed_size_array " , issue = " 27778 " ) ]
2015-02-27 19:48:51 +00:00
fn as_mut_slice ( & mut self ) -> & mut [ T ] ;
}
2019-05-09 02:58:39 +00:00
#[ unstable(feature = " fixed_size_array " , issue = " 27778 " ) ]
2015-09-19 19:33:34 +00:00
unsafe impl < T , A : Unsize < [ T ] > > FixedSizeArray < T > for A {
2015-08-29 16:30:05 +00:00
#[ inline ]
fn as_slice ( & self ) -> & [ T ] {
self
}
#[ inline ]
fn as_mut_slice ( & mut self ) -> & mut [ T ] {
self
}
}
2017-09-21 20:35:23 +00:00
/// The error type returned when a conversion from a slice to an array fails.
2019-02-08 14:00:47 +00:00
#[ stable(feature = " try_from " , since = " 1.34.0 " ) ]
2017-09-21 20:35:23 +00:00
#[ derive(Debug, Copy, Clone) ]
pub struct TryFromSliceError ( ( ) ) ;
2019-05-09 02:58:39 +00:00
#[ stable(feature = " core_array " , since = " 1.36.0 " ) ]
2017-09-29 15:15:05 +00:00
impl fmt ::Display for TryFromSliceError {
#[ inline ]
2019-04-18 23:37:12 +00:00
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
2017-09-29 15:26:19 +00:00
fmt ::Display ::fmt ( self . __description ( ) , f )
2017-09-29 15:15:05 +00:00
}
}
impl TryFromSliceError {
2019-12-22 22:42:04 +00:00
#[ unstable(
feature = " array_error_internals " ,
reason = " available through Error trait and this method should not \
2017-09-29 15:20:21 +00:00
be exposed publicly " ,
2019-12-22 22:42:04 +00:00
issue = " none "
) ]
2017-09-29 15:15:05 +00:00
#[ inline ]
#[ doc(hidden) ]
pub fn __description ( & self ) -> & str {
" could not convert slice to array "
}
}
2019-04-26 19:45:26 +00:00
#[ stable(feature = " try_from_slice_error " , since = " 1.36.0 " ) ]
impl From < Infallible > for TryFromSliceError {
fn from ( x : Infallible ) -> TryFromSliceError {
match x { }
}
}
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-07-04 10:30:09 +00:00
impl < T , const N : usize > AsRef < [ T ] > for [ T ; N ] {
2019-07-25 16:06:26 +00:00
#[ inline ]
fn as_ref ( & self ) -> & [ T ] {
& self [ .. ]
2015-12-03 01:31:49 +00:00
}
}
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-07-04 10:30:09 +00:00
impl < T , const N : usize > AsMut < [ T ] > for [ T ; N ] {
2019-07-25 16:06:26 +00:00
#[ inline ]
fn as_mut ( & mut self ) -> & mut [ T ] {
& mut self [ .. ]
2015-12-03 01:31:49 +00:00
}
}
2019-07-25 16:06:26 +00:00
#[ stable(feature = " array_borrow " , since = " 1.4.0 " ) ]
2020-07-04 10:30:09 +00:00
impl < T , const N : usize > Borrow < [ T ] > for [ T ; N ] {
2019-07-25 16:06:26 +00:00
fn borrow ( & self ) -> & [ T ] {
self
2014-10-31 09:41:25 +00:00
}
}
2019-07-25 16:06:26 +00:00
#[ stable(feature = " array_borrow " , since = " 1.4.0 " ) ]
2020-07-04 10:30:09 +00:00
impl < T , const N : usize > BorrowMut < [ T ] > for [ T ; N ] {
2019-07-25 16:06:26 +00:00
fn borrow_mut ( & mut self ) -> & mut [ T ] {
self
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " try_from " , since = " 1.34.0 " ) ]
impl < T , const N : usize > TryFrom < & [ T ] > for [ T ; N ]
where
T : Copy ,
{
type Error = TryFromSliceError ;
fn try_from ( slice : & [ T ] ) -> Result < [ T ; N ] , TryFromSliceError > {
< & Self > ::try_from ( slice ) . map ( | r | * r )
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " try_from " , since = " 1.34.0 " ) ]
2020-07-05 12:02:01 +00:00
impl < ' a , T , const N : usize > TryFrom < & ' a [ T ] > for & ' a [ T ; N ] {
2019-07-25 16:06:26 +00:00
type Error = TryFromSliceError ;
fn try_from ( slice : & [ T ] ) -> Result < & [ T ; N ] , TryFromSliceError > {
if slice . len ( ) = = N {
let ptr = slice . as_ptr ( ) as * const [ T ; N ] ;
2019-08-21 17:56:46 +00:00
// SAFETY: ok because we just checked that the length fits
2019-07-25 16:06:26 +00:00
unsafe { Ok ( & * ptr ) }
} else {
Err ( TryFromSliceError ( ( ) ) )
2019-07-06 06:59:59 +00:00
}
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " try_from " , since = " 1.34.0 " ) ]
2020-07-05 12:02:01 +00:00
impl < ' a , T , const N : usize > TryFrom < & ' a mut [ T ] > for & ' a mut [ T ; N ] {
2019-07-25 16:06:26 +00:00
type Error = TryFromSliceError ;
fn try_from ( slice : & mut [ T ] ) -> Result < & mut [ T ; N ] , TryFromSliceError > {
if slice . len ( ) = = N {
let ptr = slice . as_mut_ptr ( ) as * mut [ T ; N ] ;
2019-08-21 17:56:46 +00:00
// SAFETY: ok because we just checked that the length fits
2019-07-25 16:06:26 +00:00
unsafe { Ok ( & mut * ptr ) }
} else {
Err ( TryFromSliceError ( ( ) ) )
2019-07-06 06:59:59 +00:00
}
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-07-05 12:02:01 +00:00
impl < T : Hash , const N : usize > Hash for [ T ; N ] {
2019-07-25 16:06:26 +00:00
fn hash < H : hash ::Hasher > ( & self , state : & mut H ) {
Hash ::hash ( & self [ .. ] , state )
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-07-05 12:02:01 +00:00
impl < T : fmt ::Debug , const N : usize > fmt ::Debug for [ T ; N ] {
2019-07-25 16:06:26 +00:00
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
fmt ::Debug ::fmt ( & & self [ .. ] , f )
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-07-05 12:02:01 +00:00
impl < ' a , T , const N : usize > IntoIterator for & ' a [ T ; N ] {
2019-07-25 16:06:26 +00:00
type Item = & ' a T ;
type IntoIter = Iter < ' a , T > ;
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
fn into_iter ( self ) -> Iter < ' a , T > {
self . iter ( )
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-07-05 12:02:01 +00:00
impl < ' a , T , const N : usize > IntoIterator for & ' a mut [ T ; N ] {
2019-07-25 16:06:26 +00:00
type Item = & ' a mut T ;
type IntoIter = IterMut < ' a , T > ;
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
fn into_iter ( self ) -> IterMut < ' a , T > {
self . iter_mut ( )
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2020-07-31 20:19:10 +00:00
#[ stable(feature = " index_trait_on_arrays " , since = " 1.50.0 " ) ]
impl < T , I , const N : usize > Index < I > for [ T ; N ]
where
[ T ] : Index < I > ,
{
type Output = < [ T ] as Index < I > > ::Output ;
#[ inline ]
fn index ( & self , index : I ) -> & Self ::Output {
Index ::index ( self as & [ T ] , index )
}
}
#[ stable(feature = " index_trait_on_arrays " , since = " 1.50.0 " ) ]
impl < T , I , const N : usize > IndexMut < I > for [ T ; N ]
where
[ T ] : IndexMut < I > ,
{
#[ inline ]
fn index_mut ( & mut self , index : I ) -> & mut Self ::Output {
IndexMut ::index_mut ( self as & mut [ T ] , index )
}
}
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2019-07-24 08:44:14 +00:00
impl < A , B , const N : usize > PartialEq < [ B ; N ] > for [ A ; N ]
2019-07-25 16:06:26 +00:00
where
A : PartialEq < B > ,
{
#[ inline ]
fn eq ( & self , other : & [ B ; N ] ) -> bool {
self [ .. ] = = other [ .. ]
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
#[ inline ]
fn ne ( & self , other : & [ B ; N ] ) -> bool {
self [ .. ] ! = other [ .. ]
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2019-07-24 08:44:14 +00:00
impl < A , B , const N : usize > PartialEq < [ B ] > for [ A ; N ]
2019-07-25 16:06:26 +00:00
where
A : PartialEq < B > ,
{
#[ inline ]
fn eq ( & self , other : & [ B ] ) -> bool {
self [ .. ] = = other [ .. ]
}
#[ inline ]
fn ne ( & self , other : & [ B ] ) -> bool {
self [ .. ] ! = other [ .. ]
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2019-07-23 19:17:27 +00:00
impl < A , B , const N : usize > PartialEq < [ A ; N ] > for [ B ]
2019-07-25 16:06:26 +00:00
where
B : PartialEq < A > ,
{
#[ inline ]
fn eq ( & self , other : & [ A ; N ] ) -> bool {
self [ .. ] = = other [ .. ]
}
#[ inline ]
fn ne ( & self , other : & [ A ; N ] ) -> bool {
self [ .. ] ! = other [ .. ]
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-11-05 10:49:27 +00:00
impl < A , B , const N : usize > PartialEq < & [ B ] > for [ A ; N ]
2019-07-25 16:06:26 +00:00
where
A : PartialEq < B > ,
{
#[ inline ]
2020-11-05 10:49:27 +00:00
fn eq ( & self , other : & & [ B ] ) -> bool {
2019-07-25 16:06:26 +00:00
self [ .. ] = = other [ .. ]
}
#[ inline ]
2020-11-05 10:49:27 +00:00
fn ne ( & self , other : & & [ B ] ) -> bool {
2019-07-25 16:06:26 +00:00
self [ .. ] ! = other [ .. ]
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-11-05 10:49:27 +00:00
impl < A , B , const N : usize > PartialEq < [ A ; N ] > for & [ B ]
2019-07-25 16:06:26 +00:00
where
B : PartialEq < A > ,
{
#[ inline ]
fn eq ( & self , other : & [ A ; N ] ) -> bool {
self [ .. ] = = other [ .. ]
}
#[ inline ]
fn ne ( & self , other : & [ A ; N ] ) -> bool {
self [ .. ] ! = other [ .. ]
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-11-05 10:49:27 +00:00
impl < A , B , const N : usize > PartialEq < & mut [ B ] > for [ A ; N ]
2019-07-25 16:06:26 +00:00
where
A : PartialEq < B > ,
{
#[ inline ]
2020-11-05 10:49:27 +00:00
fn eq ( & self , other : & & mut [ B ] ) -> bool {
2019-07-25 16:06:26 +00:00
self [ .. ] = = other [ .. ]
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
#[ inline ]
2020-11-05 10:49:27 +00:00
fn ne ( & self , other : & & mut [ B ] ) -> bool {
2019-07-25 16:06:26 +00:00
self [ .. ] ! = other [ .. ]
}
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-11-05 10:49:27 +00:00
impl < A , B , const N : usize > PartialEq < [ A ; N ] > for & mut [ B ]
2019-07-25 16:06:26 +00:00
where
B : PartialEq < A > ,
{
#[ inline ]
fn eq ( & self , other : & [ A ; N ] ) -> bool {
self [ .. ] = = other [ .. ]
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
#[ inline ]
fn ne ( & self , other : & [ A ; N ] ) -> bool {
self [ .. ] ! = other [ .. ]
}
}
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
// NOTE: some less important impls are omitted to reduce code bloat
// __impl_slice_eq2! { [A; $N], &'b [B; $N] }
// __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-07-05 12:02:01 +00:00
impl < T : Eq , const N : usize > Eq for [ T ; N ] { }
2019-07-06 06:59:59 +00:00
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-07-05 12:02:01 +00:00
impl < T : PartialOrd , const N : usize > PartialOrd for [ T ; N ] {
2019-07-25 16:06:26 +00:00
#[ inline ]
fn partial_cmp ( & self , other : & [ T ; N ] ) -> Option < Ordering > {
PartialOrd ::partial_cmp ( & & self [ .. ] , & & other [ .. ] )
2019-07-06 06:59:59 +00:00
}
2019-07-25 16:06:26 +00:00
#[ inline ]
fn lt ( & self , other : & [ T ; N ] ) -> bool {
PartialOrd ::lt ( & & self [ .. ] , & & other [ .. ] )
}
#[ inline ]
fn le ( & self , other : & [ T ; N ] ) -> bool {
PartialOrd ::le ( & & self [ .. ] , & & other [ .. ] )
}
#[ inline ]
fn ge ( & self , other : & [ T ; N ] ) -> bool {
PartialOrd ::ge ( & & self [ .. ] , & & other [ .. ] )
}
#[ inline ]
fn gt ( & self , other : & [ T ; N ] ) -> bool {
PartialOrd ::gt ( & & self [ .. ] , & & other [ .. ] )
}
}
2019-07-06 06:59:59 +00:00
2020-10-25 09:46:45 +00:00
/// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison).
2019-07-25 16:06:26 +00:00
#[ stable(feature = " rust1 " , since = " 1.0.0 " ) ]
2020-07-05 12:02:01 +00:00
impl < T : Ord , const N : usize > Ord for [ T ; N ] {
2019-07-25 16:06:26 +00:00
#[ inline ]
fn cmp ( & self , other : & [ T ; N ] ) -> Ordering {
Ord ::cmp ( & & self [ .. ] , & & other [ .. ] )
2019-07-06 06:59:59 +00:00
}
}
2020-11-04 00:48:28 +00:00
// The Default impls cannot be done with const generics because `[T; 0]` doesn't
// require Default to be implemented, and having different impl blocks for
// different numbers isn't supported yet.
2015-08-14 17:11:19 +00:00
macro_rules ! array_impl_default {
{ $n :expr , $t :ident $( $ts :ident ) * } = > {
#[ stable(since = " 1.4.0 " , feature = " array_default " ) ]
impl < T > Default for [ T ; $n ] where T : Default {
fn default ( ) -> [ T ; $n ] {
[ $t ::default ( ) , $( $ts ::default ( ) ) , * ]
}
}
array_impl_default! { ( $n - 1 ) , $( $ts ) * }
} ;
{ $n :expr , } = > {
#[ stable(since = " 1.4.0 " , feature = " array_default " ) ]
impl < T > Default for [ T ; $n ] {
fn default ( ) -> [ T ; $n ] { [ ] }
}
} ;
}
2019-12-22 22:42:04 +00:00
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 }
2020-08-06 07:40:06 +00:00
#[ lang = " array " ]
impl < T , const N : usize > [ T ; N ] {
2020-08-08 23:20:28 +00:00
/// Returns an array of the same size as `self`, with function `f` applied to each element
/// in order.
2020-08-06 07:40:06 +00:00
///
/// # Examples
2020-08-07 06:00:52 +00:00
///
2020-08-06 07:40:06 +00:00
/// ```
2020-08-08 23:20:28 +00:00
/// #![feature(array_map)]
2020-08-06 23:36:50 +00:00
/// let x = [1, 2, 3];
2020-08-06 07:40:06 +00:00
/// let y = x.map(|v| v + 1);
2020-08-06 23:36:50 +00:00
/// assert_eq!(y, [2, 3, 4]);
2020-08-07 06:00:52 +00:00
///
/// let x = [1, 2, 3];
/// let mut temp = 0;
/// let y = x.map(|v| { temp += 1; v * temp });
/// assert_eq!(y, [1, 4, 9]);
2020-08-08 23:20:28 +00:00
///
/// let x = ["Ferris", "Bueller's", "Day", "Off"];
/// let y = x.map(|v| v.len());
/// assert_eq!(y, [6, 9, 3, 3]);
2020-08-06 07:40:06 +00:00
/// ```
2020-08-07 06:00:52 +00:00
#[ unstable(feature = " array_map " , issue = " 75243 " ) ]
2020-08-06 23:36:50 +00:00
pub fn map < F , U > ( self , mut f : F ) -> [ U ; N ]
2020-08-06 07:40:06 +00:00
where
2020-08-06 23:36:50 +00:00
F : FnMut ( T ) -> U ,
2020-08-06 07:40:06 +00:00
{
use crate ::mem ::MaybeUninit ;
struct Guard < T , const N : usize > {
dst : * mut T ,
2020-08-06 23:36:50 +00:00
initialized : usize ,
2020-08-06 07:40:06 +00:00
}
impl < T , const N : usize > Drop for Guard < T , N > {
fn drop ( & mut self ) {
2020-08-06 23:36:50 +00:00
debug_assert! ( self . initialized < = N ) ;
2020-08-06 07:40:06 +00:00
let initialized_part =
2020-08-06 23:36:50 +00:00
crate ::ptr ::slice_from_raw_parts_mut ( self . dst , self . initialized ) ;
2020-08-06 07:40:06 +00:00
// SAFETY: this raw slice will contain only initialized objects
// that's why, it is allowed to drop it.
unsafe {
crate ::ptr ::drop_in_place ( initialized_part ) ;
}
}
}
2020-08-06 22:08:56 +00:00
let mut dst = MaybeUninit ::uninit_array ::< N > ( ) ;
2020-08-11 18:39:12 +00:00
let mut guard : Guard < U , N > =
2020-09-01 21:16:51 +00:00
Guard { dst : MaybeUninit ::slice_as_mut_ptr ( & mut dst ) , initialized : 0 } ;
2020-08-06 23:36:50 +00:00
for ( src , dst ) in IntoIter ::new ( self ) . zip ( & mut dst ) {
dst . write ( f ( src ) ) ;
guard . initialized + = 1 ;
2020-08-06 07:40:06 +00:00
}
2020-08-06 23:36:50 +00:00
// FIXME: Convert to crate::mem::transmute once it works with generics.
// unsafe { crate::mem::transmute::<[MaybeUninit<U>; N], [U; N]>(dst) }
2020-08-06 22:08:56 +00:00
crate ::mem ::forget ( guard ) ;
// SAFETY: At this point we've properly initialized the whole array
2020-08-06 23:36:50 +00:00
// and we just need to cast it to the correct type.
2020-08-11 18:39:12 +00:00
unsafe { crate ::mem ::transmute_copy ::< _ , [ U ; N ] > ( & dst ) }
2020-08-06 07:40:06 +00:00
}
2020-08-30 18:22:09 +00:00
2020-11-26 22:22:36 +00:00
/// 'Zips up' two arrays into a single array of pairs.
/// `zip()` returns a new array where every element is a tuple where the first element comes from the first array, and the second element comes from the second array.
/// In other words, it zips two arrays together, into a single one.
///
/// # Examples
///
/// ```
/// #![feature(array_zip)]
/// let x = [1, 2, 3];
/// let y = [4, 5, 6];
/// let z = x.zip(y);
/// assert_eq!(z, [(1, 4), (2, 5), (3, 6)]);
/// ```
#[ unstable(feature = " array_zip " , issue = " none " ) ]
pub fn zip < U > ( self , rhs : [ U ; N ] ) -> [ ( T , U ) ; N ] {
use crate ::mem ::MaybeUninit ;
let mut dst = MaybeUninit ::uninit_array ::< N > ( ) ;
2020-12-16 17:32:29 +00:00
for ( i , ( lhs , rhs ) ) in IntoIter ::new ( self ) . zip ( IntoIter ::new ( rhs ) ) . enumerate ( ) {
dst [ i ] . write ( ( lhs , rhs ) ) ;
2020-11-26 22:22:36 +00:00
}
// FIXME: Convert to crate::mem::transmute once it works with generics.
// unsafe { crate::mem::transmute::<[MaybeUninit<U>; N], [U; N]>(dst) }
// SAFETY: At this point we've properly initialized the whole array
// and we just need to cast it to the correct type.
unsafe { crate ::mem ::transmute_copy ::< _ , [ ( T , U ) ; N ] > ( & dst ) }
}
2020-08-30 18:22:09 +00:00
/// Returns a slice containing the entire array. Equivalent to `&s[..]`.
#[ unstable(feature = " array_methods " , issue = " 76118 " ) ]
pub fn as_slice ( & self ) -> & [ T ] {
self
}
/// Returns a mutable slice containing the entire array. Equivalent to
/// `&mut s[..]`.
#[ unstable(feature = " array_methods " , issue = " 76118 " ) ]
pub fn as_mut_slice ( & mut self ) -> & mut [ T ] {
self
}
2020-08-06 07:40:06 +00:00
}