Skip to content
Permalink
Browse files

libstd: use unboxed closures

  • Loading branch information...
japaric committed Dec 7, 2014
1 parent be53d61 commit cdbb3ca9b776b066e2c93acfb60da8537d2b1c9b
@@ -20,6 +20,7 @@ use fmt;
use iter::IteratorExt;
use kinds::Copy;
use mem;
use ops::FnMut;
use option::Option;
use option::Option::{Some, None};
use slice::{SlicePrelude, AsSlice};
@@ -527,7 +528,9 @@ impl OwnedAsciiExt for Vec<u8> {
/// - Any other chars are given hex escapes.
/// - Unicode escapes are never generated by this function.
#[unstable = "needs to be updated to use an iterator"]
pub fn escape_default(c: u8, f: |u8|) {
pub fn escape_default<F>(c: u8, mut f: F) where
F: FnMut(u8),
{
match c {
b'\t' => { f(b'\\'); f(b't'); }
b'\r' => { f(b'\\'); f(b'r'); }
@@ -24,7 +24,7 @@ use iter::{mod, Iterator, IteratorExt, FromIterator, Extend};
use kinds::Sized;
use mem::{mod, replace};
use num::{Int, UnsignedInt};
use ops::{Deref, Index, IndexMut};
use ops::{Deref, FnMut, Index, IndexMut};
use option::Option;
use option::Option::{Some, None};
use result::Result;
@@ -296,10 +296,13 @@ pub struct HashMap<K, V, H = RandomSipHasher> {
}

/// Search for a pre-hashed key.
fn search_hashed<K, V, M: Deref<RawTable<K, V>>>(table: M,
hash: &SafeHash,
is_match: |&K| -> bool)
-> SearchResult<K, V, M> {
fn search_hashed<K, V, M, F>(table: M,
hash: &SafeHash,
mut is_match: F)
-> SearchResult<K, V, M> where
M: Deref<RawTable<K, V>>,
F: FnMut(&K) -> bool,
{
let size = table.size();
let mut probe = Bucket::new(table, hash);
let ib = probe.index();
@@ -749,12 +752,14 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
self.insert_or_replace_with(hash, k, v, |_, _, _| ())
}

fn insert_or_replace_with<'a>(&'a mut self,
hash: SafeHash,
k: K,
v: V,
found_existing: |&mut K, &mut V, V|)
-> &'a mut V {
fn insert_or_replace_with<'a, F>(&'a mut self,
hash: SafeHash,
k: K,
v: V,
mut found_existing: F)
-> &'a mut V where
F: FnMut(&mut K, &mut V, V),
{
// Worst case, we'll find one empty bucket among `size + 1` buckets.
let size = self.table.size();
let mut probe = Bucket::new(&mut self.table, &hash);
@@ -216,6 +216,7 @@ pub mod dl {
use c_str::{CString, ToCStr};
use libc;
use kinds::Copy;
use ops::FnOnce;
use ptr;
use result::*;
use result::Result::{Err, Ok};
@@ -231,7 +232,9 @@ pub mod dl {
dlopen(ptr::null(), Lazy as libc::c_int) as *mut u8
}

pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
F: FnOnce() -> T,
{
use sync::{StaticMutex, MUTEX_INIT};
static LOCK: StaticMutex = MUTEX_INIT;
unsafe {
@@ -312,7 +315,9 @@ pub mod dl {
handle as *mut u8
}

pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
F: FnOnce() -> T,
{
unsafe {
SetLastError(0);

@@ -19,6 +19,7 @@ use io::{IoError, IoResult, Reader};
use io;
use iter::Iterator;
use num::Int;
use ops::FnOnce;
use option::Option;
use option::Option::{Some, None};
use ptr::RawPtr;
@@ -76,7 +77,9 @@ impl<'r, R: Reader> Iterator<IoResult<u8>> for Bytes<'r, R> {
/// * `f`: A callback that receives the value.
///
/// This function returns the value returned by the callback, for convenience.
pub fn u64_to_le_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
pub fn u64_to_le_bytes<T, F>(n: u64, size: uint, f: F) -> T where
F: FnOnce(&[u8]) -> T,
{
use mem::transmute;

// LLVM fails to properly optimize this when using shifts instead of the to_le* intrinsics
@@ -115,7 +118,9 @@ pub fn u64_to_le_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
/// * `f`: A callback that receives the value.
///
/// This function returns the value returned by the callback, for convenience.
pub fn u64_to_be_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
pub fn u64_to_be_bytes<T, F>(n: u64, size: uint, f: F) -> T where
F: FnOnce(&[u8]) -> T,
{
use mem::transmute;

// LLVM fails to properly optimize this when using shifts instead of the to_be* intrinsics
@@ -233,7 +233,7 @@ use int;
use iter::{Iterator, IteratorExt};
use kinds::Copy;
use mem::transmute;
use ops::{BitOr, BitXor, BitAnd, Sub, Not};
use ops::{BitOr, BitXor, BitAnd, Sub, Not, FnOnce};
use option::Option;
use option::Option::{Some, None};
use os;
@@ -426,27 +426,33 @@ impl Copy for IoErrorKind {}
/// A trait that lets you add a `detail` to an IoError easily
trait UpdateIoError<T> {
/// Returns an IoError with updated description and detail
fn update_err(self, desc: &'static str, detail: |&IoError| -> String) -> Self;
fn update_err<D>(self, desc: &'static str, detail: D) -> Self where
D: FnOnce(&IoError) -> String;

/// Returns an IoError with updated detail
fn update_detail(self, detail: |&IoError| -> String) -> Self;
fn update_detail<D>(self, detail: D) -> Self where
D: FnOnce(&IoError) -> String;

/// Returns an IoError with update description
fn update_desc(self, desc: &'static str) -> Self;
}

impl<T> UpdateIoError<T> for IoResult<T> {
fn update_err(self, desc: &'static str, detail: |&IoError| -> String) -> IoResult<T> {
self.map_err(|mut e| {
fn update_err<D>(self, desc: &'static str, detail: D) -> IoResult<T> where
D: FnOnce(&IoError) -> String,
{
self.map_err(move |mut e| {
let detail = detail(&e);
e.desc = desc;
e.detail = Some(detail);
e
})
}

fn update_detail(self, detail: |&IoError| -> String) -> IoResult<T> {
self.map_err(|mut e| { e.detail = Some(detail(&e)); e })
fn update_detail<D>(self, detail: D) -> IoResult<T> where
D: FnOnce(&IoError) -> String,
{
self.map_err(move |mut e| { e.detail = Some(detail(&e)); e })
}

fn update_desc(self, desc: &'static str) -> IoResult<T> {
@@ -22,6 +22,7 @@ use kinds::Copy;
use io::{mod, IoResult, IoError};
use io::net;
use iter::{Iterator, IteratorExt};
use ops::FnOnce;
use option::Option;
use option::Option::{None, Some};
use result::Result::{Ok, Err};
@@ -100,8 +101,9 @@ impl<'a> Parser<'a> {
}

// Commit only if parser returns Some
fn read_atomically<T>(&mut self, cb: |&mut Parser| -> Option<T>)
-> Option<T> {
fn read_atomically<T, F>(&mut self, cb: F) -> Option<T> where
F: FnOnce(&mut Parser) -> Option<T>,
{
let pos = self.pos;
let r = cb(self);
if r.is_none() {
@@ -111,9 +113,10 @@ impl<'a> Parser<'a> {
}

// Commit only if parser read till EOF
fn read_till_eof<T>(&mut self, cb: |&mut Parser| -> Option<T>)
-> Option<T> {
self.read_atomically(|p| {
fn read_till_eof<T, F>(&mut self, cb: F) -> Option<T> where
F: FnOnce(&mut Parser) -> Option<T>,
{
self.read_atomically(move |p| {
match cb(p) {
Some(x) => if p.is_eof() {Some(x)} else {None},
None => None,
@@ -134,15 +137,16 @@ impl<'a> Parser<'a> {
}

// Apply 3 parsers sequentially
fn read_seq_3<A,
B,
C>(
&mut self,
pa: |&mut Parser| -> Option<A>,
pb: |&mut Parser| -> Option<B>,
pc: |&mut Parser| -> Option<C>)
-> Option<(A, B, C)> {
self.read_atomically(|p| {
fn read_seq_3<A, B, C, PA, PB, PC>(&mut self,
pa: PA,
pb: PB,
pc: PC)
-> Option<(A, B, C)> where
PA: FnOnce(&mut Parser) -> Option<A>,
PB: FnOnce(&mut Parser) -> Option<B>,
PC: FnOnce(&mut Parser) -> Option<C>,
{
self.read_atomically(move |p| {
let a = pa(p);
let b = if a.is_some() { pb(p) } else { None };
let c = if b.is_some() { pc(p) } else { None };
@@ -327,22 +331,22 @@ impl<'a> Parser<'a> {
}

fn read_socket_addr(&mut self) -> Option<SocketAddr> {
let ip_addr = |p: &mut Parser| {
let ip_addr = |&: p: &mut Parser| {
let ipv4_p = |p: &mut Parser| p.read_ip_addr();
let ipv6_p = |p: &mut Parser| {
let open_br = |p: &mut Parser| p.read_given_char('[');
let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
let clos_br = |p: &mut Parser| p.read_given_char(']');
p.read_seq_3::<char, IpAddr, char>(open_br, ip_addr, clos_br)
let open_br = |&: p: &mut Parser| p.read_given_char('[');
let ip_addr = |&: p: &mut Parser| p.read_ipv6_addr();
let clos_br = |&: p: &mut Parser| p.read_given_char(']');
p.read_seq_3::<char, IpAddr, char, _, _, _>(open_br, ip_addr, clos_br)
.map(|t| match t { (_, ip, _) => ip })
};
p.read_or(&mut [ipv4_p, ipv6_p])
};
let colon = |p: &mut Parser| p.read_given_char(':');
let port = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
let colon = |&: p: &mut Parser| p.read_given_char(':');
let port = |&: p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);

// host, colon, port
self.read_seq_3::<IpAddr, char, u16>(ip_addr, colon, port)
self.read_seq_3::<IpAddr, char, u16, _, _, _>(ip_addr, colon, port)
.map(|t| match t { (ip, _, port) => SocketAddr { ip: ip, port: port } })
}
}
@@ -11,6 +11,7 @@
//! Networking I/O

use io::{IoError, IoResult, InvalidInput};
use ops::FnMut;
use option::Option::None;
use result::Result::{Ok, Err};
use self::ip::{SocketAddr, ToSocketAddr};
@@ -23,8 +24,10 @@ pub mod udp;
pub mod ip;
pub mod pipe;

fn with_addresses<A: ToSocketAddr, T>(addr: A, action: |SocketAddr| -> IoResult<T>)
-> IoResult<T> {
fn with_addresses<A, T, F>(addr: A, mut action: F) -> IoResult<T> where
A: ToSocketAddr,
F: FnMut(SocketAddr) -> IoResult<T>,
{
const DEFAULT_ERROR: IoError = IoError {
kind: InvalidInput,
desc: "no addresses found for hostname",
@@ -18,6 +18,7 @@
use clone::Clone;
use io::net::ip::{SocketAddr, IpAddr, ToSocketAddr};
use io::{Reader, Writer, IoResult};
use ops::FnOnce;
use option::Option;
use result::Result::{Ok, Err};
use sys::udp::UdpSocket as UdpSocketImp;
@@ -210,7 +211,9 @@ impl UdpStream {
/// Allows access to the underlying UDP socket owned by this stream. This
/// is useful to, for example, use the socket to send data to hosts other
/// than the one that this stream is connected to.
pub fn as_socket<T>(&mut self, f: |&mut UdpSocket| -> T) -> T {
pub fn as_socket<T, F>(&mut self, f: F) -> T where
F: FnOnce(&mut UdpSocket) -> T,
{
f(&mut self.socket)
}

@@ -39,7 +39,7 @@ use libc;
use mem;
use option::Option;
use option::Option::{Some, None};
use ops::{Deref, DerefMut};
use ops::{Deref, DerefMut, FnOnce};
use result::Result::{Ok, Err};
use rustrt;
use rustrt::local::Local;
@@ -85,7 +85,9 @@ enum StdSource {
File(fs::FileDesc),
}

fn src<T>(fd: libc::c_int, _readable: bool, f: |StdSource| -> T) -> T {
fn src<T, F>(fd: libc::c_int, _readable: bool, f: F) -> T where
F: FnOnce(StdSource) -> T,
{
match tty::TTY::new(fd) {
Ok(tty) => f(TTY(tty)),
Err(_) => f(File(fs::FileDesc::new(fd, false))),
@@ -318,7 +320,9 @@ pub fn set_stderr(stderr: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
// // io1 aliases io2
// })
// })
fn with_task_stdout(f: |&mut Writer| -> IoResult<()>) {
fn with_task_stdout<F>(f: F) where
F: FnOnce(&mut Writer) -> IoResult<()>,
{
let result = if Local::exists(None::<Task>) {
let mut my_stdout = LOCAL_STDOUT.with(|slot| {
slot.borrow_mut().take()
@@ -21,6 +21,7 @@ use char::Char;
use kinds::Copy;
use num;
use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive};
use ops::FnMut;
use slice::{SlicePrelude, CloneSliceAllocPrelude};
use str::StrPrelude;
use string::String;
@@ -93,7 +94,10 @@ impl Copy for SignFormat {}
/// # Panics
///
/// - Panics if `radix` < 2 or `radix` > 36.
fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8|) {
fn int_to_str_bytes_common<T, F>(num: T, radix: uint, sign: SignFormat, mut f: F) where
T: Int,
F: FnMut(u8),
{
assert!(2 <= radix && radix <= 36);

let _0: T = Int::zero();
@@ -15,4 +15,6 @@

pub use core::u16::{BITS, BYTES, MIN, MAX};

use ops::FnOnce;

uint_module!(u16)
@@ -15,4 +15,6 @@

pub use core::u32::{BITS, BYTES, MIN, MAX};

use ops::FnOnce;

uint_module!(u32)
@@ -15,4 +15,6 @@

pub use core::u64::{BITS, BYTES, MIN, MAX};

use ops::FnOnce;

uint_module!(u64)
@@ -15,4 +15,6 @@

pub use core::u8::{BITS, BYTES, MIN, MAX};

use ops::FnOnce;

uint_module!(u8)
@@ -15,4 +15,6 @@

pub use core::uint::{BITS, BYTES, MIN, MAX};

use ops::FnOnce;

uint_module!(uint)
Oops, something went wrong.

0 comments on commit cdbb3ca

Please sign in to comment.
You can’t perform that action at this time.