35
35
#[ cfg( feature="no_std" ) ]
36
36
extern crate core as std;
37
37
extern crate typenum;
38
+ extern crate nodrop;
38
39
pub mod arr;
40
+ use nodrop:: NoDrop ;
39
41
use typenum:: uint:: { Unsigned , UTerm , UInt } ;
40
42
use typenum:: bit:: { B0 , B1 } ;
41
43
use std:: fmt:: Debug ;
@@ -45,7 +47,7 @@ use std::ops::{Deref, DerefMut};
45
47
use std:: ptr;
46
48
use std:: slice;
47
49
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
49
51
pub unsafe trait ArrayLength < T > : Unsigned {
50
52
/// Associated type representing the array type for the number
51
53
type ArrayType ;
@@ -105,7 +107,7 @@ unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
105
107
type ArrayType = GenericArrayImplOdd < T , N :: ArrayType > ;
106
108
}
107
109
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]
109
111
#[ allow( dead_code) ]
110
112
pub struct GenericArray < T , U : ArrayLength < T > > {
111
113
data : U :: ArrayType
@@ -129,14 +131,45 @@ impl<T, N> DerefMut for GenericArray<T, N> where N: ArrayLength<T> {
129
131
}
130
132
}
131
133
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
+
132
162
impl < T : Default , N > GenericArray < T , N > where N : ArrayLength < T > {
133
163
134
164
/// Function constructing an array filled with default values
135
165
pub fn new ( ) -> GenericArray < T , N > {
136
166
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 ( )
140
173
}
141
174
}
142
175
@@ -147,21 +180,18 @@ impl<T: Clone, N> GenericArray<T, N> where N: ArrayLength<T> {
147
180
/// Function constructing an array from a slice; the length of the slice must be equal to the length of the array
148
181
pub fn from_slice ( list : & [ T ] ) -> GenericArray < T , N > {
149
182
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 ( ) )
155
184
}
156
185
157
186
}
158
187
159
188
impl < T : Clone , N > Clone for GenericArray < T , N > where N : ArrayLength < T > {
160
189
fn clone ( & self ) -> GenericArray < T , N > {
161
190
unsafe {
162
- let mut res: GenericArray < T , N > = mem:: uninitialized ( ) ;
191
+ let mut res : NoDrop < GenericArray < T , N > > =
192
+ NoDrop :: new ( std:: mem:: uninitialized ( ) ) ;
163
193
for i in 0 ..N :: to_usize ( ) { ptr:: write ( & mut res[ i] , self [ i] . clone ( ) ) }
164
- res
194
+ res. into_inner ( )
165
195
}
166
196
}
167
197
}
0 commit comments