3535#[ cfg( feature="no_std" ) ]
3636extern crate core as std;
3737extern crate typenum;
38+ extern crate nodrop;
3839pub mod arr;
40+ use nodrop:: NoDrop ;
3941use typenum:: uint:: { Unsigned , UTerm , UInt } ;
4042use typenum:: bit:: { B0 , B1 } ;
4143use std:: fmt:: Debug ;
@@ -45,7 +47,7 @@ use std::ops::{Deref, DerefMut};
4547use std:: ptr;
4648use std:: slice;
4749
48- /// Trait making GenericArray work, marking types to be used as length of an array
50+ /// Trait making ` GenericArray` work, marking types to be used as length of an array
4951pub unsafe trait ArrayLength < T > : Unsigned {
5052 /// Associated type representing the array type for the number
5153 type ArrayType ;
@@ -105,7 +107,7 @@ unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
105107 type ArrayType = GenericArrayImplOdd < T , N :: ArrayType > ;
106108}
107109
108- /// Struct representing a generic array - GenericArray<T, N> works like [T; N]
110+ /// Struct representing a generic array - ` GenericArray<T, N>` works like [T; N]
109111#[ allow( dead_code) ]
110112pub struct GenericArray < T , U : ArrayLength < T > > {
111113 data : U :: ArrayType
@@ -129,14 +131,45 @@ impl<T, N> DerefMut for GenericArray<T, N> where N: ArrayLength<T> {
129131 }
130132}
131133
134+ impl < T , N > GenericArray < T , N > where N : ArrayLength < T > {
135+ /// map a function over a slice to a `GenericArray`.
136+ /// The length of the slice *must* be equal to the length of the array
137+ pub fn map_slice < S , F : Fn ( & S ) -> T > ( s : & [ S ] , f : F ) -> GenericArray < T , N > {
138+ assert_eq ! ( s. len( ) , N :: to_usize( ) ) ;
139+ map_inner ( s, f)
140+ }
141+
142+ /// map a function over a `GenericArray`.
143+ pub fn map < U , F > ( self , f : F ) -> GenericArray < U , N >
144+ where F : Fn ( & T ) -> U , N : ArrayLength < U > {
145+ map_inner ( & self , f)
146+ }
147+ }
148+
149+ #[ inline]
150+ fn map_inner < S , F , T , N > ( list : & [ S ] , f : F ) -> GenericArray < T , N >
151+ where F : Fn ( & S ) -> T , N : ArrayLength < T > {
152+ unsafe {
153+ let mut res : NoDrop < GenericArray < T , N > > =
154+ NoDrop :: new ( std:: mem:: uninitialized ( ) ) ;
155+ for ( s, r) in list. iter ( ) . zip ( res. iter_mut ( ) ) {
156+ std:: ptr:: write ( r, f ( s) )
157+ }
158+ res. into_inner ( )
159+ }
160+ }
161+
132162impl < T : Default , N > GenericArray < T , N > where N : ArrayLength < T > {
133163
134164 /// Function constructing an array filled with default values
135165 pub fn new ( ) -> GenericArray < T , N > {
136166 unsafe {
137- let mut res: GenericArray < T , N > = mem:: uninitialized ( ) ;
138- for r in res. iter_mut ( ) { ptr:: write ( r, T :: default ( ) ) }
139- res
167+ let mut res : NoDrop < GenericArray < T , N > > =
168+ NoDrop :: new ( std:: mem:: uninitialized ( ) ) ;
169+ for r in res. iter_mut ( ) {
170+ ptr:: write ( r, T :: default ( ) )
171+ }
172+ res. into_inner ( )
140173 }
141174 }
142175
@@ -147,21 +180,18 @@ impl<T: Clone, N> GenericArray<T, N> where N: ArrayLength<T> {
147180 /// Function constructing an array from a slice; the length of the slice must be equal to the length of the array
148181 pub fn from_slice ( list : & [ T ] ) -> GenericArray < T , N > {
149182 assert_eq ! ( list. len( ) , N :: to_usize( ) ) ;
150- unsafe {
151- let mut res: GenericArray < T , N > = mem:: uninitialized ( ) ;
152- for i in 0 ..N :: to_usize ( ) { ptr:: write ( & mut res[ i] , list[ i] . clone ( ) ) }
153- res
154- }
183+ map_inner ( list, |x : & T | x. clone ( ) )
155184 }
156185
157186}
158187
159188impl < T : Clone , N > Clone for GenericArray < T , N > where N : ArrayLength < T > {
160189 fn clone ( & self ) -> GenericArray < T , N > {
161190 unsafe {
162- let mut res: GenericArray < T , N > = mem:: uninitialized ( ) ;
191+ let mut res : NoDrop < GenericArray < T , N > > =
192+ NoDrop :: new ( std:: mem:: uninitialized ( ) ) ;
163193 for i in 0 ..N :: to_usize ( ) { ptr:: write ( & mut res[ i] , self [ i] . clone ( ) ) }
164- res
194+ res. into_inner ( )
165195 }
166196 }
167197}
0 commit comments