Skip to content

Commit 216b4a2

Browse files
committed
1 parent f3cbc52 commit 216b4a2

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

src/functional.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//! Functional programming with [`Array`]s.
2+
3+
use crate::{Array, ArraySize};
4+
5+
/// Defines functional programming methods for [`Array`]s.
6+
pub trait FunctionalSequence<T, U> {
7+
/// Maps an `Array` to another `Array`
8+
///
9+
/// If the mapping function panics, any already initialized elements in the new array will
10+
/// be dropped, AND any unused elements in the source array will also be dropped.
11+
fn map<O, F>(self, f: F) -> Array<O, U>
12+
where
13+
U: ArraySize,
14+
F: FnMut(T) -> O;
15+
16+
/// Combines two `Array` instances and iterates through both of them, initialization a new
17+
/// `Array` with the result of the zipped mapping function.
18+
///
19+
/// If the mapping function panics, any already initialized elements in the new array will
20+
/// be dropped, AND any unused elements in the source arrays will also be dropped.
21+
fn zip<Rhs, F, O>(self, rhs: Array<Rhs, U>, f: F) -> Array<O, U>
22+
where
23+
U: ArraySize,
24+
F: FnMut(T, Rhs) -> O;
25+
26+
/// Folds (or reduces) a sequence of data into a single value.
27+
///
28+
/// If the fold function panics, any unused elements will be dropped.
29+
fn fold<O, F>(self, init: O, f: F) -> O
30+
where
31+
F: FnMut(O, T) -> O;
32+
}
33+
34+
impl<T, U> FunctionalSequence<T, U> for Array<T, U>
35+
where
36+
U: ArraySize,
37+
{
38+
#[inline(always)]
39+
fn map<O, F>(self, mut f: F) -> Array<O, U>
40+
where
41+
F: FnMut(T) -> O,
42+
{
43+
let mut out = Array::uninit();
44+
45+
let mut s = self.into_iter();
46+
let mut i = 0;
47+
48+
while let Some(s) = s.next() {
49+
out[i].write(f(s));
50+
i += 1;
51+
}
52+
53+
unsafe { out.assume_init() }
54+
}
55+
56+
#[inline(always)]
57+
fn zip<Rhs, F, O>(self, rhs: Array<Rhs, U>, mut f: F) -> Array<O, U>
58+
where
59+
U: ArraySize,
60+
F: FnMut(T, Rhs) -> O,
61+
{
62+
let mut out = Array::uninit();
63+
64+
let mut s = self.into_iter();
65+
let mut r = rhs.into_iter();
66+
let mut i = 0;
67+
68+
loop {
69+
match (s.next(), r.next()) {
70+
(Some(s), Some(r)) => {
71+
out[i].write(f(s, r));
72+
i += 1;
73+
}
74+
_ => break,
75+
}
76+
}
77+
78+
unsafe { out.assume_init() }
79+
}
80+
81+
#[inline(always)]
82+
fn fold<O, F>(self, mut init: O, mut f: F) -> O
83+
where
84+
F: FnMut(O, T) -> O,
85+
{
86+
let mut s = self.into_iter();
87+
88+
while let Some(s) = s.next() {
89+
init = f(init, s)
90+
}
91+
92+
init
93+
}
94+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
extern crate std;
8989

9090
mod from_fn;
91+
pub mod functional;
9192
mod iter;
9293
mod sizes;
9394
mod traits;

0 commit comments

Comments
 (0)