From 1646d10edc57ec82536d6253f866084beb69a73e Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 2 Dec 2014 13:59:08 -0500 Subject: [PATCH] libcore: use unboxed closures in the fields of `Map` --- src/libcore/iter.rs | 29 +++++++++++++++++++---------- src/libcore/str.rs | 16 +++++++++------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index ddca9d36bed..0c0562a8b68 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -62,7 +62,7 @@ use cmp::Ord; use kinds::Copy; use mem; use num::{ToPrimitive, Int}; -use ops::{Add, Deref}; +use ops::{Add, Deref, FnMut}; use option::Option; use option::Option::{Some, None}; use uint; @@ -165,7 +165,7 @@ pub trait IteratorExt: Iterator { /// ``` #[inline] #[unstable = "waiting for unboxed closures"] - fn map<'r, B>(self, f: |A|: 'r -> B) -> Map<'r, A, B, Self> { + fn map B>(self, f: F) -> Map { Map{iter: self, f: f} } @@ -778,7 +778,10 @@ impl<'a, A, T: ExactSizeIterator> ExactSizeIterator for Inspect<'a, A, T> #[unstable = "trait is unstable"] impl> ExactSizeIterator for Rev {} #[unstable = "trait is unstable"] -impl<'a, A, B, T: ExactSizeIterator> ExactSizeIterator for Map<'a, A, B, T> {} +impl ExactSizeIterator for Map where + I: ExactSizeIterator, + F: FnMut(A) -> B, +{} #[unstable = "trait is unstable"] impl ExactSizeIterator<(A, B)> for Zip where T: ExactSizeIterator, U: ExactSizeIterator {} @@ -1374,12 +1377,12 @@ RandomAccessIterator<(A, B)> for Zip { /// An iterator which maps the values of `iter` with `f` #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable] -pub struct Map<'a, A, B, T> { - iter: T, - f: |A|: 'a -> B +pub struct Map, F: FnMut(A) -> B> { + iter: I, + f: F, } -impl<'a, A, B, T> Map<'a, A, B, T> { +impl Map where I: Iterator, F: FnMut(A) -> B { #[inline] fn do_map(&mut self, elt: Option) -> Option { match elt { @@ -1390,7 +1393,7 @@ impl<'a, A, B, T> Map<'a, A, B, T> { } #[unstable = "trait is unstable"] -impl<'a, A, B, T: Iterator> Iterator for Map<'a, A, B, T> { +impl Iterator for Map where I: Iterator, F: FnMut(A) -> B { #[inline] fn next(&mut self) -> Option { let next = self.iter.next(); @@ -1404,7 +1407,10 @@ impl<'a, A, B, T: Iterator> Iterator for Map<'a, A, B, T> { } #[unstable = "trait is unstable"] -impl<'a, A, B, T: DoubleEndedIterator> DoubleEndedIterator for Map<'a, A, B, T> { +impl DoubleEndedIterator for Map where + I: DoubleEndedIterator, + F: FnMut(A) -> B, +{ #[inline] fn next_back(&mut self) -> Option { let next = self.iter.next_back(); @@ -1413,7 +1419,10 @@ impl<'a, A, B, T: DoubleEndedIterator> DoubleEndedIterator for Map<'a, A, } #[experimental = "trait is experimental"] -impl<'a, A, B, T: RandomAccessIterator> RandomAccessIterator for Map<'a, A, B, T> { +impl RandomAccessIterator for Map where + I: RandomAccessIterator, + F: FnMut(A) -> B, +{ #[inline] fn indexable(&self) -> uint { self.iter.indexable() diff --git a/src/libcore/str.rs b/src/libcore/str.rs index d0c8558b55d..051c36a2dc0 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -323,8 +323,7 @@ impl<'a> DoubleEndedIterator<(uint, char)> for CharOffsets<'a> { /// External iterator for a string's bytes. /// Use with the `std::iter` module. -pub type Bytes<'a> = - Map<'a, &'a u8, u8, slice::Items<'a, u8>>; +pub type Bytes<'a> = Map<&'a u8, u8, slice::Items<'a, u8>, fn(&u8) -> u8>; /// An iterator over the substrings of a string, separated by `sep`. #[deriving(Clone)] @@ -349,8 +348,7 @@ pub struct CharSplitsN<'a, Sep> { } /// An iterator over the lines of a string, separated by either `\n` or (`\r\n`). -pub type AnyLines<'a> = - Map<'a, &'a str, &'a str, CharSplits<'a, char>>; +pub type AnyLines<'a> = Map<&'a str, &'a str, CharSplits<'a, char>, fn(&str) -> &str>; impl<'a, Sep> CharSplits<'a, Sep> { #[inline] @@ -1980,7 +1978,9 @@ impl StrPrelude for str { #[inline] fn bytes(&self) -> Bytes { - self.as_bytes().iter().map(|&b| b) + fn deref(&x: &u8) -> u8 { x } + + self.as_bytes().iter().map(deref) } #[inline] @@ -2053,11 +2053,13 @@ impl StrPrelude for str { } fn lines_any(&self) -> AnyLines { - self.lines().map(|line| { + fn f(line: &str) -> &str { let l = line.len(); if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) } else { line } - }) + } + + self.lines().map(f) } #[inline]