Skip to content

Commit c51defd

Browse files
committed
Merge pull request #12 from llogiq/map
new map method
2 parents 61bb918 + 6c283b4 commit c51defd

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ documentation = "http://fizyk20.github.io/generic-array/generic_array/"
1212
name = "generic_array"
1313

1414
[dependencies]
15-
typenum = "1.*"
15+
typenum = "1.3.1"
16+
nodrop = "0.1.6"
1617

1718
[features]
1819
no_std = ["typenum/no_std"]

src/lib.rs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
#[cfg(feature="no_std")]
3636
extern crate core as std;
3737
extern crate typenum;
38+
extern crate nodrop;
3839
pub mod arr;
40+
use nodrop::NoDrop;
3941
use typenum::uint::{Unsigned, UTerm, UInt};
4042
use typenum::bit::{B0, B1};
4143
use std::fmt::Debug;
@@ -45,7 +47,7 @@ use std::ops::{Deref, DerefMut};
4547
use std::ptr;
4648
use 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
4951
pub 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)]
110112
pub 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+
132162
impl<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

159188
impl<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

Comments
 (0)