Skip to content

Commit 2512606

Browse files
author
root
committed
Add .map_unboxed for now
1 parent dc52c86 commit 2512606

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![feature(unboxed_closures)]
12
#![feature(macro_rules)]
23
#![crate_name="itertools"]
34
#![crate_type="dylib"]
@@ -32,6 +33,7 @@ pub use adaptors::Product;
3233
pub use adaptors::PutBack;
3334
pub use adaptors::FnMap;
3435
pub use intersperse::Intersperse;
36+
pub use map::MapMut;
3537
pub use stride::Stride;
3638
pub use stride::StrideMut;
3739
pub use times::Times;
@@ -40,6 +42,7 @@ pub use linspace::{linspace, Linspace};
4042
mod adaptors;
4143
mod intersperse;
4244
mod linspace;
45+
mod map;
4346
mod stride;
4447
mod times;
4548

@@ -217,6 +220,13 @@ pub trait Itertools<A> : Iterator<A> {
217220
FnMap::new(self, map)
218221
}
219222

223+
/// Like regular `.map`, but using an unboxed closure instead.
224+
///
225+
/// Iterator element type is `B`
226+
fn map_unboxed<B, F: FnMut(A) -> B>(self, map: F) -> MapMut<A, B, F, Self> {
227+
MapMut::new(self, map)
228+
}
229+
220230
/// Alternate elements from two iterators until both
221231
/// are run out
222232
///

src/map.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
/// Clonable iterator adaptor to map elementwise
3+
/// from `Iterator<A>` to `Iterator<B>`
4+
///
5+
/// Created with `.map_unboxed(..)` on an iterator
6+
///
7+
/// Iterator element type is `B`
8+
pub struct MapMut<A, B, F, I> {
9+
map: F,
10+
iter: I,
11+
}
12+
13+
impl<A, B, F: FnMut(A) -> B, I> MapMut<A, B, F, I>
14+
{
15+
pub fn new(iter: I, map: F) -> MapMut<A, B, F, I> {
16+
MapMut{iter: iter, map: map}
17+
}
18+
}
19+
20+
impl<A, B, F: FnMut(A) -> B, I: Iterator<A>> Iterator<B> for MapMut<A, B, F, I>
21+
{
22+
#[inline]
23+
fn next(&mut self) -> Option<B> {
24+
self.iter.next().map(|a| (self.map)(a))
25+
}
26+
27+
fn size_hint(&self) -> (uint, Option<uint>) {
28+
self.iter.size_hint()
29+
}
30+
}
31+
32+
impl<A, B, F: FnMut(A) -> B, I: DoubleEndedIterator<A>> DoubleEndedIterator<B>
33+
for MapMut<A, B, F, I>
34+
{
35+
#[inline]
36+
fn next_back(&mut self) -> Option<B> {
37+
self.iter.next_back().map(|a| (self.map)(a))
38+
}
39+
}
40+
41+
impl<A, B, F: Clone + FnMut(A) -> B, I: Clone> Clone for MapMut<A, B, F, I>
42+
{
43+
#[inline]
44+
fn clone(&self) -> MapMut<A, B, F, I> {
45+
MapMut::new(self.iter.clone(), self.map.clone())
46+
}
47+
}
48+

tests/tests.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ fn fn_map() {
7272
assert!(it.zip(jt).all(|(x,y)| x == y));
7373
}
7474

75+
#[test]
76+
fn map_unboxed() {
77+
let xs = [0, 1, 2i];
78+
fn mapper(x: &int) -> String { x.to_string() }
79+
let it = xs.iter().map_unboxed(mapper);
80+
let jt = it.clone();
81+
assert!(it.zip(jt).all(|(x,y)| x == y));
82+
83+
// NOTE: This doesn't compile :(
84+
//let mut sum = 0i;
85+
//let it = xs.iter().map_unboxed(|x| sum += *x).drain();
86+
//assert_eq!(sum, 3);
87+
}
88+
7589
#[test]
7690
fn write_to() {
7791
let xs = [7i, 9, 8];

0 commit comments

Comments
 (0)