convert doc-attributes to doc-comments using ./src/etc/sugarise-doc-comments.py (and manually tweaking) - for issue #2498
This commit is contained in:
parent
bfa43ca301
commit
be0141666d
123 changed files with 4981 additions and 5044 deletions
|
|
@ -1,5 +1,7 @@
|
|||
#[doc = "An atomically reference counted wrapper that can be used to
|
||||
share immutable data between tasks."]
|
||||
/**
|
||||
* An atomically reference counted wrapper that can be used to
|
||||
* share immutable data between tasks.
|
||||
*/
|
||||
|
||||
import comm::{port, chan, methods};
|
||||
import sys::methods;
|
||||
|
|
@ -41,7 +43,7 @@ class arc_destruct<T> {
|
|||
|
||||
type arc<T: const> = arc_destruct<T>;
|
||||
|
||||
#[doc="Create an atomically reference counted wrapper."]
|
||||
/// Create an atomically reference counted wrapper.
|
||||
fn arc<T: const>(-data: T) -> arc<T> {
|
||||
let data = ~{mut count: 1, data: data};
|
||||
unsafe {
|
||||
|
|
@ -50,8 +52,10 @@ fn arc<T: const>(-data: T) -> arc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Access the underlying data in an atomically reference counted
|
||||
wrapper."]
|
||||
/**
|
||||
* Access the underlying data in an atomically reference counted
|
||||
* wrapper.
|
||||
*/
|
||||
fn get<T: const>(rc: &a.arc<T>) -> &a.T {
|
||||
unsafe {
|
||||
let ptr: ~arc_data<T> = unsafe::reinterpret_cast((*rc).data);
|
||||
|
|
@ -62,11 +66,13 @@ fn get<T: const>(rc: &a.arc<T>) -> &a.T {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Duplicate an atomically reference counted wrapper.
|
||||
|
||||
The resulting two `arc` objects will point to the same underlying data
|
||||
object. However, one of the `arc` objects can be sent to another task,
|
||||
allowing them to share the underlying data."]
|
||||
/**
|
||||
* Duplicate an atomically reference counted wrapper.
|
||||
*
|
||||
* The resulting two `arc` objects will point to the same underlying data
|
||||
* object. However, one of the `arc` objects can be sent to another task,
|
||||
* allowing them to share the underlying data.
|
||||
*/
|
||||
fn clone<T: const>(rc: &arc<T>) -> arc<T> {
|
||||
unsafe {
|
||||
let ptr: ~arc_data<T> = unsafe::reinterpret_cast((*rc).data);
|
||||
|
|
|
|||
|
|
@ -1,45 +1,43 @@
|
|||
// -*- rust -*-
|
||||
|
||||
#[doc = "Boolean logic"];
|
||||
//! Boolean logic
|
||||
|
||||
export not, and, or, xor, implies;
|
||||
export eq, ne, is_true, is_false;
|
||||
export from_str, to_str, all_values, to_bit;
|
||||
|
||||
#[doc = "Negation / inverse"]
|
||||
/// Negation / inverse
|
||||
pure fn not(v: bool) -> bool { !v }
|
||||
|
||||
#[doc = "Conjunction"]
|
||||
/// Conjunction
|
||||
pure fn and(a: bool, b: bool) -> bool { a && b }
|
||||
|
||||
#[doc = "Disjunction"]
|
||||
/// Disjunction
|
||||
pure fn or(a: bool, b: bool) -> bool { a || b }
|
||||
|
||||
#[doc = "
|
||||
Exclusive or
|
||||
|
||||
Identical to `or(and(a, not(b)), and(not(a), b))`
|
||||
"]
|
||||
/**
|
||||
* Exclusive or
|
||||
*
|
||||
* Identical to `or(and(a, not(b)), and(not(a), b))`
|
||||
*/
|
||||
pure fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) }
|
||||
|
||||
#[doc = "Implication in the logic, i.e. from `a` follows `b`"]
|
||||
/// Implication in the logic, i.e. from `a` follows `b`
|
||||
pure fn implies(a: bool, b: bool) -> bool { !a || b }
|
||||
|
||||
#[doc = "
|
||||
true if truth values `a` and `b` are indistinguishable in the logic
|
||||
"]
|
||||
/// true if truth values `a` and `b` are indistinguishable in the logic
|
||||
pure fn eq(a: bool, b: bool) -> bool { a == b }
|
||||
|
||||
#[doc = "true if truth values `a` and `b` are distinguishable in the logic"]
|
||||
/// true if truth values `a` and `b` are distinguishable in the logic
|
||||
pure fn ne(a: bool, b: bool) -> bool { a != b }
|
||||
|
||||
#[doc = "true if `v` represents truth in the logic"]
|
||||
/// true if `v` represents truth in the logic
|
||||
pure fn is_true(v: bool) -> bool { v }
|
||||
|
||||
#[doc = "true if `v` represents falsehood in the logic"]
|
||||
/// true if `v` represents falsehood in the logic
|
||||
pure fn is_false(v: bool) -> bool { !v }
|
||||
|
||||
#[doc = "Parse logic value from `s`"]
|
||||
/// Parse logic value from `s`
|
||||
pure fn from_str(s: str) -> option<bool> {
|
||||
alt check s {
|
||||
"true" { some(true) }
|
||||
|
|
@ -48,19 +46,19 @@ pure fn from_str(s: str) -> option<bool> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Convert `v` into a string"]
|
||||
/// Convert `v` into a string
|
||||
pure fn to_str(v: bool) -> str { if v { "true" } else { "false" } }
|
||||
|
||||
#[doc = "
|
||||
Iterates over all truth values by passing them to `blk` in an unspecified
|
||||
order
|
||||
"]
|
||||
/**
|
||||
* Iterates over all truth values by passing them to `blk` in an unspecified
|
||||
* order
|
||||
*/
|
||||
fn all_values(blk: fn(v: bool)) {
|
||||
blk(true);
|
||||
blk(false);
|
||||
}
|
||||
|
||||
#[doc = "converts truth value to an 8 bit byte"]
|
||||
/// converts truth value to an 8 bit byte
|
||||
pure fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } }
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#[doc = "Operations on shared box types"];
|
||||
//! Operations on shared box types
|
||||
|
||||
export ptr_eq;
|
||||
|
||||
pure fn ptr_eq<T>(a: @T, b: @T) -> bool {
|
||||
#[doc = "Determine if two shared boxes point to the same object"];
|
||||
//! Determine if two shared boxes point to the same object
|
||||
unsafe { ptr::addr_of(*a) == ptr::addr_of(*b) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Utilities for manipulating the char type"];
|
||||
//! Utilities for manipulating the char type
|
||||
|
||||
/*
|
||||
Lu Uppercase_Letter an uppercase letter
|
||||
|
|
@ -46,27 +46,27 @@ import is_XID_start = unicode::derived_property::XID_Start;
|
|||
import is_XID_continue = unicode::derived_property::XID_Continue;
|
||||
|
||||
|
||||
#[doc = "
|
||||
Indicates whether a character is in lower case, defined
|
||||
in terms of the Unicode General Category 'Ll'
|
||||
"]
|
||||
/**
|
||||
* Indicates whether a character is in lower case, defined
|
||||
* in terms of the Unicode General Category 'Ll'
|
||||
*/
|
||||
pure fn is_lowercase(c: char) -> bool {
|
||||
ret unicode::general_category::Ll(c);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Indicates whether a character is in upper case, defined
|
||||
in terms of the Unicode General Category 'Lu'.
|
||||
"]
|
||||
/**
|
||||
* Indicates whether a character is in upper case, defined
|
||||
* in terms of the Unicode General Category 'Lu'.
|
||||
*/
|
||||
pure fn is_uppercase(c: char) -> bool {
|
||||
ret unicode::general_category::Lu(c);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Indicates whether a character is whitespace, defined in
|
||||
terms of the Unicode General Categories 'Zs', 'Zl', 'Zp'
|
||||
additional 'Cc'-category control codes in the range [0x09, 0x0d]/~
|
||||
"]
|
||||
/**
|
||||
* Indicates whether a character is whitespace, defined in
|
||||
* terms of the Unicode General Categories 'Zs', 'Zl', 'Zp'
|
||||
* additional 'Cc'-category control codes in the range [0x09, 0x0d]
|
||||
*/
|
||||
pure fn is_whitespace(c: char) -> bool {
|
||||
ret ('\x09' <= c && c <= '\x0d')
|
||||
|| unicode::general_category::Zs(c)
|
||||
|
|
@ -74,11 +74,11 @@ pure fn is_whitespace(c: char) -> bool {
|
|||
|| unicode::general_category::Zp(c);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Indicates whether a character is alphanumeric, defined
|
||||
in terms of the Unicode General Categories 'Nd',
|
||||
'Nl', 'No' and the Derived Core Property 'Alphabetic'.
|
||||
"]
|
||||
/**
|
||||
* Indicates whether a character is alphanumeric, defined
|
||||
* in terms of the Unicode General Categories 'Nd',
|
||||
* 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
|
||||
*/
|
||||
pure fn is_alphanumeric(c: char) -> bool {
|
||||
ret unicode::derived_property::Alphabetic(c) ||
|
||||
unicode::general_category::Nd(c) ||
|
||||
|
|
@ -86,32 +86,32 @@ pure fn is_alphanumeric(c: char) -> bool {
|
|||
unicode::general_category::No(c);
|
||||
}
|
||||
|
||||
#[doc = "Indicates whether the character is an ASCII character"]
|
||||
/// Indicates whether the character is an ASCII character
|
||||
pure fn is_ascii(c: char) -> bool {
|
||||
c - ('\x7F' & c) == '\x00'
|
||||
}
|
||||
|
||||
#[doc = "Indicates whether the character is numeric (Nd, Nl, or No)"]
|
||||
/// Indicates whether the character is numeric (Nd, Nl, or No)
|
||||
pure fn is_digit(c: char) -> bool {
|
||||
ret unicode::general_category::Nd(c) ||
|
||||
unicode::general_category::Nl(c) ||
|
||||
unicode::general_category::No(c);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Convert a char to the corresponding digit.
|
||||
|
||||
# Safety note
|
||||
|
||||
This function fails if `c` is not a valid char
|
||||
|
||||
# Return value
|
||||
|
||||
If `c` is between '0' and '9', the corresponding value
|
||||
between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is
|
||||
'b' or 'B', 11, etc. Returns none if the char does not
|
||||
refer to a digit in the given radix.
|
||||
"]
|
||||
/**
|
||||
* Convert a char to the corresponding digit.
|
||||
*
|
||||
* # Safety note
|
||||
*
|
||||
* This function fails if `c` is not a valid char
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* If `c` is between '0' and '9', the corresponding value
|
||||
* between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is
|
||||
* 'b' or 'B', 11, etc. Returns none if the char does not
|
||||
* refer to a digit in the given radix.
|
||||
*/
|
||||
pure fn to_digit(c: char, radix: uint) -> option<uint> {
|
||||
let val = alt c {
|
||||
'0' to '9' { c as uint - ('0' as uint) }
|
||||
|
|
@ -123,15 +123,15 @@ pure fn to_digit(c: char, radix: uint) -> option<uint> {
|
|||
else { none }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Return the hexadecimal unicode escape of a char.
|
||||
|
||||
The rules are as follows:
|
||||
|
||||
- chars in [0,0xff]/~ get 2-digit escapes: `\\xNN`
|
||||
- chars in [0x100,0xffff]/~ get 4-digit escapes: `\\uNNNN`
|
||||
- chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN`
|
||||
"]
|
||||
/**
|
||||
* Return the hexadecimal unicode escape of a char.
|
||||
*
|
||||
* The rules are as follows:
|
||||
*
|
||||
* - chars in [0,0xff] get 2-digit escapes: `\\xNN`
|
||||
* - chars in [0x100,0xffff] get 4-digit escapes: `\\uNNNN`
|
||||
* - chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN`
|
||||
*/
|
||||
fn escape_unicode(c: char) -> str {
|
||||
let s = u32::to_str(c as u32, 16u);
|
||||
let (c, pad) = (if c <= '\xff' { ('x', 2u) }
|
||||
|
|
@ -145,18 +145,18 @@ fn escape_unicode(c: char) -> str {
|
|||
ret out;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Return a 'default' ASCII and C++11-like char-literal escape of a char.
|
||||
|
||||
The default is chosen with a bias toward producing literals that are
|
||||
legal in a variety of languages, including C++11 and similar C-family
|
||||
languages. The exact rules are:
|
||||
|
||||
- Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
|
||||
- Single-quote, double-quote and backslash chars are backslash-escaped.
|
||||
- Any other chars in the range [0x20,0x7e]/~ are not escaped.
|
||||
- Any other chars are given hex unicode escapes; see `escape_unicode`.
|
||||
"]
|
||||
/**
|
||||
* Return a 'default' ASCII and C++11-like char-literal escape of a char.
|
||||
*
|
||||
* The default is chosen with a bias toward producing literals that are
|
||||
* legal in a variety of languages, including C++11 and similar C-family
|
||||
* languages. The exact rules are:
|
||||
*
|
||||
* - Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
|
||||
* - Single-quote, double-quote and backslash chars are backslash-escaped.
|
||||
* - Any other chars in the range [0x20,0x7e] are not escaped.
|
||||
* - Any other chars are given hex unicode escapes; see `escape_unicode`.
|
||||
*/
|
||||
fn escape_default(c: char) -> str {
|
||||
alt c {
|
||||
'\t' { "\\t" }
|
||||
|
|
@ -170,13 +170,13 @@ fn escape_default(c: char) -> str {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Compare two chars
|
||||
|
||||
# Return value
|
||||
|
||||
-1 if a < b, 0 if a == b, +1 if a > b
|
||||
"]
|
||||
/**
|
||||
* Compare two chars
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* -1 if a < b, 0 if a == b, +1 if a > b
|
||||
*/
|
||||
pure fn cmp(a: char, b: char) -> int {
|
||||
ret if b > a { -1 }
|
||||
else if b < a { 1 }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc="Interfaces used for comparison."]
|
||||
/// Interfaces used for comparison.
|
||||
|
||||
iface ord {
|
||||
fn lt(&&other: self) -> bool;
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
#[doc = "
|
||||
Communication between tasks
|
||||
|
||||
Communication between tasks is facilitated by ports (in the receiving
|
||||
task), and channels (in the sending task). Any number of channels may
|
||||
feed into a single port. Ports and channels may only transmit values
|
||||
of unique types; that is, values that are statically guaranteed to be
|
||||
accessed by a single 'owner' at a time. Unique types include scalars,
|
||||
vectors, strings, and records, tags, tuples and unique boxes (`~T`)
|
||||
thereof. Most notably, shared boxes (`@T`) may not be transmitted
|
||||
across channels.
|
||||
|
||||
# Example
|
||||
|
||||
~~~
|
||||
let po = comm::port();
|
||||
let ch = comm::chan(po);
|
||||
|
||||
task::spawn {||
|
||||
comm::send(ch, \"Hello, World\");
|
||||
});
|
||||
|
||||
io::println(comm::recv(p));
|
||||
~~~
|
||||
"];
|
||||
/*!
|
||||
* Communication between tasks
|
||||
*
|
||||
* Communication between tasks is facilitated by ports (in the receiving
|
||||
* task), and channels (in the sending task). Any number of channels may
|
||||
* feed into a single port. Ports and channels may only transmit values
|
||||
* of unique types; that is, values that are statically guaranteed to be
|
||||
* accessed by a single 'owner' at a time. Unique types include scalars,
|
||||
* vectors, strings, and records, tags, tuples and unique boxes (`~T`)
|
||||
* thereof. Most notably, shared boxes (`@T`) may not be transmitted
|
||||
* across channels.
|
||||
*
|
||||
* # Example
|
||||
*
|
||||
* ~~~
|
||||
* let po = comm::port();
|
||||
* let ch = comm::chan(po);
|
||||
*
|
||||
* task::spawn {||
|
||||
* comm::send(ch, "Hello, World");
|
||||
* });
|
||||
*
|
||||
* io::println(comm::recv(p));
|
||||
* ~~~
|
||||
*/
|
||||
|
||||
import either::either;
|
||||
import libc::size_t;
|
||||
|
|
@ -38,34 +38,34 @@ export methods;
|
|||
export listen;
|
||||
|
||||
|
||||
#[doc = "
|
||||
A communication endpoint that can receive messages
|
||||
|
||||
Each port has a unique per-task identity and may not be replicated or
|
||||
transmitted. If a port value is copied, both copies refer to the same
|
||||
port. Ports may be associated with multiple `chan`s.
|
||||
"]
|
||||
/**
|
||||
* A communication endpoint that can receive messages
|
||||
*
|
||||
* Each port has a unique per-task identity and may not be replicated or
|
||||
* transmitted. If a port value is copied, both copies refer to the same
|
||||
* port. Ports may be associated with multiple `chan`s.
|
||||
*/
|
||||
enum port<T: send> {
|
||||
port_t(@port_ptr<T>)
|
||||
}
|
||||
|
||||
// It's critical that this only have one variant, so it has a record
|
||||
// layout, and will work in the rust_task structure in task.rs.
|
||||
#[doc = "
|
||||
A communication endpoint that can send messages
|
||||
|
||||
Each channel is bound to a port when the channel is constructed, so
|
||||
the destination port for a channel must exist before the channel
|
||||
itself. Channels are weak: a channel does not keep the port it is
|
||||
bound to alive. If a channel attempts to send data to a dead port that
|
||||
data will be silently dropped. Channels may be duplicated and
|
||||
themselves transmitted over other channels.
|
||||
"]
|
||||
/**
|
||||
* A communication endpoint that can send messages
|
||||
*
|
||||
* Each channel is bound to a port when the channel is constructed, so
|
||||
* the destination port for a channel must exist before the channel
|
||||
* itself. Channels are weak: a channel does not keep the port it is
|
||||
* bound to alive. If a channel attempts to send data to a dead port that
|
||||
* data will be silently dropped. Channels may be duplicated and
|
||||
* themselves transmitted over other channels.
|
||||
*/
|
||||
enum chan<T: send> {
|
||||
chan_t(port_id)
|
||||
}
|
||||
|
||||
#[doc = "Constructs a port"]
|
||||
/// Constructs a port
|
||||
fn port<T: send>() -> port<T> {
|
||||
port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>() as size_t)))
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ impl methods<T: send> for chan<T> {
|
|||
|
||||
}
|
||||
|
||||
#[doc = "Open a new receiving channel for the duration of a function"]
|
||||
/// Open a new receiving channel for the duration of a function
|
||||
fn listen<T: send, U>(f: fn(chan<T>) -> U) -> U {
|
||||
let po = port();
|
||||
f(po.chan())
|
||||
|
|
@ -119,14 +119,14 @@ class port_ptr<T:send> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Internal function for converting from a channel to a port
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the port is detached or dead. Fails if the port
|
||||
is owned by a different task.
|
||||
"]
|
||||
/**
|
||||
* Internal function for converting from a channel to a port
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if the port is detached or dead. Fails if the port
|
||||
* is owned by a different task.
|
||||
*/
|
||||
fn as_raw_port<T: send, U>(ch: comm::chan<T>, f: fn(*rust_port) -> U) -> U {
|
||||
|
||||
class portref {
|
||||
|
|
@ -150,18 +150,18 @@ fn as_raw_port<T: send, U>(ch: comm::chan<T>, f: fn(*rust_port) -> U) -> U {
|
|||
f(p.p)
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Constructs a channel. The channel is bound to the port used to
|
||||
construct it.
|
||||
"]
|
||||
/**
|
||||
* Constructs a channel. The channel is bound to the port used to
|
||||
* construct it.
|
||||
*/
|
||||
fn chan<T: send>(p: port<T>) -> chan<T> {
|
||||
chan_t(rustrt::get_port_id((**p).po))
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Sends data over a channel. The sent data is moved into the channel,
|
||||
whereupon the caller loses access to it.
|
||||
"]
|
||||
/**
|
||||
* Sends data over a channel. The sent data is moved into the channel,
|
||||
* whereupon the caller loses access to it.
|
||||
*/
|
||||
fn send<T: send>(ch: chan<T>, -data: T) {
|
||||
let chan_t(p) = ch;
|
||||
let data_ptr = ptr::addr_of(data) as *();
|
||||
|
|
@ -173,13 +173,13 @@ fn send<T: send>(ch: chan<T>, -data: T) {
|
|||
task::yield();
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Receive from a port. If no data is available on the port then the
|
||||
task will block until data becomes available.
|
||||
"]
|
||||
/**
|
||||
* Receive from a port. If no data is available on the port then the
|
||||
* task will block until data becomes available.
|
||||
*/
|
||||
fn recv<T: send>(p: port<T>) -> T { recv_((**p).po) }
|
||||
|
||||
#[doc = "Returns true if there are messages available"]
|
||||
/// Returns true if there are messages available
|
||||
fn peek<T: send>(p: port<T>) -> bool { peek_((**p).po) }
|
||||
|
||||
#[doc(hidden)]
|
||||
|
|
@ -191,7 +191,7 @@ fn peek_chan<T: send>(ch: comm::chan<T>) -> bool {
|
|||
as_raw_port(ch, |x|peek_(x))
|
||||
}
|
||||
|
||||
#[doc = "Receive on a raw port pointer"]
|
||||
/// Receive on a raw port pointer
|
||||
fn recv_<T: send>(p: *rust_port) -> T {
|
||||
let yield = 0u;
|
||||
let yieldp = ptr::addr_of(yield);
|
||||
|
|
@ -214,7 +214,7 @@ fn peek_(p: *rust_port) -> bool {
|
|||
rustrt::rust_port_size(p) != 0u as libc::size_t
|
||||
}
|
||||
|
||||
#[doc = "Receive on one of two ports"]
|
||||
/// Receive on one of two ports
|
||||
fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
|
||||
-> either<A, B> {
|
||||
let ports = ~[(**p_a).po, (**p_b).po];
|
||||
|
|
|
|||
|
|
@ -7,26 +7,26 @@
|
|||
#[license = "MIT"];
|
||||
#[crate_type = "lib"];
|
||||
|
||||
#[doc = "
|
||||
The Rust core library provides functionality that is closely tied to the Rust
|
||||
built-in types and runtime services, or that is used in nearly every
|
||||
non-trivial program.
|
||||
|
||||
`core` includes modules corresponding to each of the integer types, each of
|
||||
the floating point types, the `bool` type, tuples, characters, strings,
|
||||
vectors (`vec`), shared boxes (`box`), and unsafe pointers (`ptr`).
|
||||
Additionally, `core` provides very commonly used built-in types and
|
||||
operations, concurrency primitives, platform abstractions, I/O, and complete
|
||||
bindings to the C standard library.
|
||||
|
||||
`core` is linked by default to all crates and the contents imported.
|
||||
Implicitly, all crates behave as if they included the following prologue:
|
||||
|
||||
use core;
|
||||
import core::*;
|
||||
|
||||
This behavior can be disabled with the `#[no_core]` crate attribute.
|
||||
"];
|
||||
/*!
|
||||
* The Rust core library provides functionality that is closely tied to the
|
||||
* Rust built-in types and runtime services, or that is used in nearly every
|
||||
* non-trivial program.
|
||||
*
|
||||
* `core` includes modules corresponding to each of the integer types, each of
|
||||
* the floating point types, the `bool` type, tuples, characters, strings,
|
||||
* vectors (`vec`), shared boxes (`box`), and unsafe pointers (`ptr`).
|
||||
* Additionally, `core` provides very commonly used built-in types and
|
||||
* operations, concurrency primitives, platform abstractions, I/O, and
|
||||
* complete bindings to the C standard library.
|
||||
*
|
||||
* `core` is linked by default to all crates and the contents imported.
|
||||
* Implicitly, all crates behave as if they included the following prologue:
|
||||
*
|
||||
* use core;
|
||||
* import core::*;
|
||||
*
|
||||
* This behavior can be disabled with the `#[no_core]` crate attribute.
|
||||
*/
|
||||
|
||||
// Don't link to core. We are core.
|
||||
#[no_core];
|
||||
|
|
@ -58,7 +58,7 @@ export priv;
|
|||
|
||||
// Built-in-type support modules
|
||||
|
||||
#[doc = "Operations and constants for `int`"]
|
||||
/// Operations and constants for `int`
|
||||
#[path = "int-template"]
|
||||
mod int {
|
||||
import inst::{ hash, pow };
|
||||
|
|
@ -67,35 +67,35 @@ mod int {
|
|||
mod inst;
|
||||
}
|
||||
|
||||
#[doc = "Operations and constants for `i8`"]
|
||||
/// Operations and constants for `i8`
|
||||
#[path = "int-template"]
|
||||
mod i8 {
|
||||
#[path = "i8.rs"]
|
||||
mod inst;
|
||||
}
|
||||
|
||||
#[doc = "Operations and constants for `i16`"]
|
||||
/// Operations and constants for `i16`
|
||||
#[path = "int-template"]
|
||||
mod i16 {
|
||||
#[path = "i16.rs"]
|
||||
mod inst;
|
||||
}
|
||||
|
||||
#[doc = "Operations and constants for `i32`"]
|
||||
/// Operations and constants for `i32`
|
||||
#[path = "int-template"]
|
||||
mod i32 {
|
||||
#[path = "i32.rs"]
|
||||
mod inst;
|
||||
}
|
||||
|
||||
#[doc = "Operations and constants for `i64`"]
|
||||
/// Operations and constants for `i64`
|
||||
#[path = "int-template"]
|
||||
mod i64 {
|
||||
#[path = "i64.rs"]
|
||||
mod inst;
|
||||
}
|
||||
|
||||
#[doc = "Operations and constants for `uint`"]
|
||||
/// Operations and constants for `uint`
|
||||
#[path = "uint-template"]
|
||||
mod uint {
|
||||
import inst::{
|
||||
|
|
@ -109,7 +109,7 @@ mod uint {
|
|||
mod inst;
|
||||
}
|
||||
|
||||
#[doc = "Operations and constants for `u8`"]
|
||||
/// Operations and constants for `u8`
|
||||
#[path = "uint-template"]
|
||||
mod u8 {
|
||||
import inst::is_ascii;
|
||||
|
|
@ -119,21 +119,21 @@ mod u8 {
|
|||
mod inst;
|
||||
}
|
||||
|
||||
#[doc = "Operations and constants for `u16`"]
|
||||
/// Operations and constants for `u16`
|
||||
#[path = "uint-template"]
|
||||
mod u16 {
|
||||
#[path = "u16.rs"]
|
||||
mod inst;
|
||||
}
|
||||
|
||||
#[doc = "Operations and constants for `u32`"]
|
||||
/// Operations and constants for `u32`
|
||||
#[path = "uint-template"]
|
||||
mod u32 {
|
||||
#[path = "u32.rs"]
|
||||
mod inst;
|
||||
}
|
||||
|
||||
#[doc = "Operations and constants for `u64`"]
|
||||
/// Operations and constants for `u64`
|
||||
#[path = "uint-template"]
|
||||
mod u64 {
|
||||
#[path = "u64.rs"]
|
||||
|
|
|
|||
|
|
@ -37,13 +37,13 @@ export num;
|
|||
|
||||
export error, warn, info, debug;
|
||||
|
||||
#[doc = "The error log level"]
|
||||
/// The error log level
|
||||
const error : u32 = 0_u32;
|
||||
#[doc = "The warning log level"]
|
||||
/// The warning log level
|
||||
const warn : u32 = 1_u32;
|
||||
#[doc = "The info log level"]
|
||||
/// The info log level
|
||||
const info : u32 = 2_u32;
|
||||
#[doc = "The debug log level"]
|
||||
/// The debug log level
|
||||
const debug : u32 = 3_u32;
|
||||
|
||||
// A curious inner-module that's not exported that contains the binding
|
||||
|
|
@ -63,11 +63,11 @@ mod std {
|
|||
import std::test;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
A standard function to use to indicate unreachable code. Because the
|
||||
function is guaranteed to fail typestate will correctly identify
|
||||
any code paths following the appearance of this function as unreachable.
|
||||
"]
|
||||
/**
|
||||
* A standard function to use to indicate unreachable code. Because the
|
||||
* function is guaranteed to fail typestate will correctly identify
|
||||
* any code paths following the appearance of this function as unreachable.
|
||||
*/
|
||||
fn unreachable() -> ! {
|
||||
fail "Internal error: entered unreachable code";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#[doc = "
|
||||
A doubly-linked list. Supports O(1) head, tail, count, push, pop, etc.
|
||||
|
||||
Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
|
||||
"]
|
||||
/**
|
||||
* A doubly-linked list. Supports O(1) head, tail, count, push, pop, etc.
|
||||
*
|
||||
* Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
|
||||
*/
|
||||
|
||||
import dlist_iter::extensions;
|
||||
|
||||
|
|
@ -57,24 +57,24 @@ impl private_methods<T> for dlist_node<T> {
|
|||
}
|
||||
|
||||
impl extensions<T> for dlist_node<T> {
|
||||
#[doc = "Get the next node in the list, if there is one."]
|
||||
/// Get the next node in the list, if there is one.
|
||||
pure fn next_link() -> option<dlist_node<T>> {
|
||||
self.assert_links();
|
||||
self.next
|
||||
}
|
||||
#[doc = "Get the next node in the list, failing if there isn't one."]
|
||||
/// Get the next node in the list, failing if there isn't one.
|
||||
pure fn next_node() -> dlist_node<T> {
|
||||
alt self.next_link() {
|
||||
some(nobe) { nobe }
|
||||
none { fail "This dlist node has no next neighbour." }
|
||||
}
|
||||
}
|
||||
#[doc = "Get the previous node in the list, if there is one."]
|
||||
/// Get the previous node in the list, if there is one.
|
||||
pure fn prev_link() -> option<dlist_node<T>> {
|
||||
self.assert_links();
|
||||
self.prev
|
||||
}
|
||||
#[doc = "Get the previous node in the list, failing if there isn't one."]
|
||||
/// Get the previous node in the list, failing if there isn't one.
|
||||
pure fn prev_node() -> dlist_node<T> {
|
||||
alt self.prev_link() {
|
||||
some(nobe) { nobe }
|
||||
|
|
@ -82,7 +82,7 @@ impl extensions<T> for dlist_node<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Remove a node from whatever dlist it's on (failing if none)."]
|
||||
/// Remove a node from whatever dlist it's on (failing if none).
|
||||
fn remove() {
|
||||
if option::is_some(self.root) {
|
||||
option::get(self.root).remove(self);
|
||||
|
|
@ -92,17 +92,17 @@ impl extensions<T> for dlist_node<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Creates a new dlist node with the given data."]
|
||||
/// Creates a new dlist node with the given data.
|
||||
pure fn create_node<T>(+data: T) -> dlist_node<T> {
|
||||
dlist_node(@{data: data, mut root: none, mut prev: none, mut next: none})
|
||||
}
|
||||
|
||||
#[doc = "Creates a new, empty dlist."]
|
||||
/// Creates a new, empty dlist.
|
||||
pure fn create<T>() -> dlist<T> {
|
||||
dlist(@{mut size: 0, mut hd: none, mut tl: none})
|
||||
}
|
||||
|
||||
#[doc = "Creates a new dlist with a single element"]
|
||||
/// Creates a new dlist with a single element
|
||||
fn from_elt<T>(+data: T) -> dlist<T> {
|
||||
let list = create();
|
||||
list.push(data);
|
||||
|
|
@ -184,97 +184,113 @@ impl private_methods<T> for dlist<T> {
|
|||
}
|
||||
|
||||
impl extensions<T> for dlist<T> {
|
||||
#[doc = "Get the size of the list. O(1)."]
|
||||
/// Get the size of the list. O(1).
|
||||
pure fn len() -> uint { self.size }
|
||||
#[doc = "Returns true if the list is empty. O(1)."]
|
||||
/// Returns true if the list is empty. O(1).
|
||||
pure fn is_empty() -> bool { self.len() == 0 }
|
||||
#[doc = "Returns true if the list is not empty. O(1)."]
|
||||
/// Returns true if the list is not empty. O(1).
|
||||
pure fn is_not_empty() -> bool { self.len() != 0 }
|
||||
|
||||
#[doc = "Add data to the head of the list. O(1)."]
|
||||
/// Add data to the head of the list. O(1).
|
||||
fn push_head(+data: T) {
|
||||
self.add_head(self.new_link(data));
|
||||
}
|
||||
#[doc = "Add data to the head of the list, and get the new containing
|
||||
node. O(1)."]
|
||||
/**
|
||||
* Add data to the head of the list, and get the new containing
|
||||
* node. O(1).
|
||||
*/
|
||||
fn push_head_n(+data: T) -> dlist_node<T> {
|
||||
let mut nobe = self.new_link(data);
|
||||
self.add_head(nobe);
|
||||
option::get(nobe)
|
||||
}
|
||||
#[doc = "Add data to the tail of the list. O(1)."]
|
||||
/// Add data to the tail of the list. O(1).
|
||||
fn push(+data: T) {
|
||||
self.add_tail(self.new_link(data));
|
||||
}
|
||||
#[doc = "Add data to the tail of the list, and get the new containing
|
||||
node. O(1)."]
|
||||
/**
|
||||
* Add data to the tail of the list, and get the new containing
|
||||
* node. O(1).
|
||||
*/
|
||||
fn push_n(+data: T) -> dlist_node<T> {
|
||||
let mut nobe = self.new_link(data);
|
||||
self.add_tail(nobe);
|
||||
option::get(nobe)
|
||||
}
|
||||
#[doc = "Insert data into the middle of the list, left of the given node.
|
||||
O(1)."]
|
||||
/**
|
||||
* Insert data into the middle of the list, left of the given node.
|
||||
* O(1).
|
||||
*/
|
||||
fn insert_before(+data: T, neighbour: dlist_node<T>) {
|
||||
self.insert_left(self.new_link(data), neighbour);
|
||||
}
|
||||
#[doc = "Insert an existing node in the middle of the list, left of the
|
||||
given node. O(1)."]
|
||||
/**
|
||||
* Insert an existing node in the middle of the list, left of the
|
||||
* given node. O(1).
|
||||
*/
|
||||
fn insert_n_before(nobe: dlist_node<T>, neighbour: dlist_node<T>) {
|
||||
self.make_mine(nobe);
|
||||
self.insert_left(some(nobe), neighbour);
|
||||
}
|
||||
#[doc = "Insert data in the middle of the list, left of the given node,
|
||||
and get its containing node. O(1)."]
|
||||
/**
|
||||
* Insert data in the middle of the list, left of the given node,
|
||||
* and get its containing node. O(1).
|
||||
*/
|
||||
fn insert_before_n(+data: T, neighbour: dlist_node<T>) -> dlist_node<T> {
|
||||
let mut nobe = self.new_link(data);
|
||||
self.insert_left(nobe, neighbour);
|
||||
option::get(nobe)
|
||||
}
|
||||
#[doc = "Insert data into the middle of the list, right of the given node.
|
||||
O(1)."]
|
||||
/**
|
||||
* Insert data into the middle of the list, right of the given node.
|
||||
* O(1).
|
||||
*/
|
||||
fn insert_after(+data: T, neighbour: dlist_node<T>) {
|
||||
self.insert_right(neighbour, self.new_link(data));
|
||||
}
|
||||
#[doc = "Insert an existing node in the middle of the list, right of the
|
||||
given node. O(1)."]
|
||||
/**
|
||||
* Insert an existing node in the middle of the list, right of the
|
||||
* given node. O(1).
|
||||
*/
|
||||
fn insert_n_after(nobe: dlist_node<T>, neighbour: dlist_node<T>) {
|
||||
self.make_mine(nobe);
|
||||
self.insert_right(neighbour, some(nobe));
|
||||
}
|
||||
#[doc = "Insert data in the middle of the list, right of the given node,
|
||||
and get its containing node. O(1)."]
|
||||
/**
|
||||
* Insert data in the middle of the list, right of the given node,
|
||||
* and get its containing node. O(1).
|
||||
*/
|
||||
fn insert_after_n(+data: T, neighbour: dlist_node<T>) -> dlist_node<T> {
|
||||
let mut nobe = self.new_link(data);
|
||||
self.insert_right(neighbour, nobe);
|
||||
option::get(nobe)
|
||||
}
|
||||
|
||||
#[doc = "Remove a node from the head of the list. O(1)."]
|
||||
/// Remove a node from the head of the list. O(1).
|
||||
fn pop_n() -> option<dlist_node<T>> {
|
||||
let hd = self.peek_n();
|
||||
hd.map(|nobe| self.unlink(nobe));
|
||||
hd
|
||||
}
|
||||
#[doc = "Remove a node from the tail of the list. O(1)."]
|
||||
/// Remove a node from the tail of the list. O(1).
|
||||
fn pop_tail_n() -> option<dlist_node<T>> {
|
||||
let tl = self.peek_tail_n();
|
||||
tl.map(|nobe| self.unlink(nobe));
|
||||
tl
|
||||
}
|
||||
#[doc = "Get the node at the list's head. O(1)."]
|
||||
/// Get the node at the list's head. O(1).
|
||||
pure fn peek_n() -> option<dlist_node<T>> { self.hd }
|
||||
#[doc = "Get the node at the list's tail. O(1)."]
|
||||
/// Get the node at the list's tail. O(1).
|
||||
pure fn peek_tail_n() -> option<dlist_node<T>> { self.tl }
|
||||
|
||||
#[doc = "Get the node at the list's head, failing if empty. O(1)."]
|
||||
/// Get the node at the list's head, failing if empty. O(1).
|
||||
pure fn head_n() -> dlist_node<T> {
|
||||
alt self.hd {
|
||||
some(nobe) { nobe }
|
||||
none { fail "Attempted to get the head of an empty dlist." }
|
||||
}
|
||||
}
|
||||
#[doc = "Get the node at the list's tail, failing if empty. O(1)."]
|
||||
/// Get the node at the list's tail, failing if empty. O(1).
|
||||
pure fn tail_n() -> dlist_node<T> {
|
||||
alt self.tl {
|
||||
some(nobe) { nobe }
|
||||
|
|
@ -282,10 +298,10 @@ impl extensions<T> for dlist<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Remove a node from anywhere in the list. O(1)."]
|
||||
/// Remove a node from anywhere in the list. O(1).
|
||||
fn remove(nobe: dlist_node<T>) { self.unlink(nobe); }
|
||||
|
||||
#[doc = "Check data structure integrity. O(n)."]
|
||||
/// Check data structure integrity. O(n).
|
||||
fn assert_consistent() {
|
||||
if option::is_none(self.hd) || option::is_none(self.tl) {
|
||||
assert option::is_none(self.hd) && option::is_none(self.tl);
|
||||
|
|
@ -333,17 +349,17 @@ impl extensions<T> for dlist<T> {
|
|||
}
|
||||
|
||||
impl extensions<T: copy> for dlist<T> {
|
||||
#[doc = "Remove data from the head of the list. O(1)."]
|
||||
/// Remove data from the head of the list. O(1).
|
||||
fn pop() -> option<T> { self.pop_n().map (|nobe| nobe.data) }
|
||||
#[doc = "Remove data from the tail of the list. O(1)."]
|
||||
/// Remove data from the tail of the list. O(1).
|
||||
fn pop_tail() -> option<T> { self.pop_tail_n().map (|nobe| nobe.data) }
|
||||
#[doc = "Get data at the list's head. O(1)."]
|
||||
/// Get data at the list's head. O(1).
|
||||
fn peek() -> option<T> { self.peek_n().map (|nobe| nobe.data) }
|
||||
#[doc = "Get data at the list's tail. O(1)."]
|
||||
/// Get data at the list's tail. O(1).
|
||||
fn peek_tail() -> option<T> { self.peek_tail_n().map (|nobe| nobe.data) }
|
||||
#[doc = "Get data at the list's head, failing if empty. O(1)."]
|
||||
/// Get data at the list's head, failing if empty. O(1).
|
||||
pure fn head() -> T { self.head_n().data }
|
||||
#[doc = "Get data at the list's tail, failing if empty. O(1)."]
|
||||
/// Get data at the list's tail, failing if empty. O(1).
|
||||
pure fn tail() -> T { self.tail_n().data }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,59 +15,57 @@ export from_vec;
|
|||
export extensions;
|
||||
export unwrap;
|
||||
|
||||
#[doc = "
|
||||
|
||||
A growable, modifiable vector type that accumulates elements into a
|
||||
unique vector.
|
||||
|
||||
# Limitations on recursive use
|
||||
|
||||
This class works by swapping the unique vector out of the data
|
||||
structure whenever it is to be used. Therefore, recursive use is not
|
||||
permitted. That is, while iterating through a vector, you cannot
|
||||
access the vector in any other way or else the program will fail. If
|
||||
you wish, you can use the `swap()` method to gain access to the raw
|
||||
vector and transform it or use it any way you like. Eventually, we
|
||||
may permit read-only access during iteration or other use.
|
||||
|
||||
# WARNING
|
||||
|
||||
For maximum performance, this type is implemented using some rather
|
||||
unsafe code. In particular, this innocent looking `[mut A]/~` pointer
|
||||
*may be null!* Therefore, it is important you not reach into the
|
||||
data structure manually but instead use the provided extensions.
|
||||
|
||||
The reason that I did not use an unsafe pointer in the structure
|
||||
itself is that I wanted to ensure that the vector would be freed when
|
||||
the dvec is dropped. The reason that I did not use an `option<T>`
|
||||
instead of a nullable pointer is that I found experimentally that it
|
||||
becomes approximately 50% slower. This can probably be improved
|
||||
through optimization. You can run your own experiments using
|
||||
`src/test/bench/vec-append.rs`. My own tests found that using null
|
||||
pointers achieved about 103 million pushes/second. Using an option
|
||||
type could only produce 47 million pushes/second.
|
||||
|
||||
"]
|
||||
/**
|
||||
* A growable, modifiable vector type that accumulates elements into a
|
||||
* unique vector.
|
||||
*
|
||||
* # Limitations on recursive use
|
||||
*
|
||||
* This class works by swapping the unique vector out of the data
|
||||
* structure whenever it is to be used. Therefore, recursive use is not
|
||||
* permitted. That is, while iterating through a vector, you cannot
|
||||
* access the vector in any other way or else the program will fail. If
|
||||
* you wish, you can use the `swap()` method to gain access to the raw
|
||||
* vector and transform it or use it any way you like. Eventually, we
|
||||
* may permit read-only access during iteration or other use.
|
||||
*
|
||||
* # WARNING
|
||||
*
|
||||
* For maximum performance, this type is implemented using some rather
|
||||
* unsafe code. In particular, this innocent looking `[mut A]/~` pointer
|
||||
* *may be null!* Therefore, it is important you not reach into the
|
||||
* data structure manually but instead use the provided extensions.
|
||||
*
|
||||
* The reason that I did not use an unsafe pointer in the structure
|
||||
* itself is that I wanted to ensure that the vector would be freed when
|
||||
* the dvec is dropped. The reason that I did not use an `option<T>`
|
||||
* instead of a nullable pointer is that I found experimentally that it
|
||||
* becomes approximately 50% slower. This can probably be improved
|
||||
* through optimization. You can run your own experiments using
|
||||
* `src/test/bench/vec-append.rs`. My own tests found that using null
|
||||
* pointers achieved about 103 million pushes/second. Using an option
|
||||
* type could only produce 47 million pushes/second.
|
||||
*/
|
||||
type dvec<A> = {
|
||||
mut data: ~[mut A]
|
||||
};
|
||||
|
||||
#[doc = "Creates a new, empty dvec"]
|
||||
/// Creates a new, empty dvec
|
||||
fn dvec<A>() -> dvec<A> {
|
||||
{mut data: ~[mut]}
|
||||
}
|
||||
|
||||
#[doc = "Creates a new dvec with a single element"]
|
||||
/// Creates a new dvec with a single element
|
||||
fn from_elt<A>(+e: A) -> dvec<A> {
|
||||
{mut data: ~[mut e]}
|
||||
}
|
||||
|
||||
#[doc = "Creates a new dvec with the contents of a vector"]
|
||||
/// Creates a new dvec with the contents of a vector
|
||||
fn from_vec<A>(+v: ~[mut A]) -> dvec<A> {
|
||||
{mut data: v}
|
||||
}
|
||||
|
||||
#[doc = "Consumes the vector and returns its contents"]
|
||||
/// Consumes the vector and returns its contents
|
||||
fn unwrap<A>(-d: dvec<A>) -> ~[mut A] {
|
||||
let {data: v} <- d;
|
||||
ret v;
|
||||
|
|
@ -106,19 +104,17 @@ impl private_methods<A> for dvec<A> {
|
|||
// almost nothing works without the copy bound due to limitations
|
||||
// around closures.
|
||||
impl extensions<A> for dvec<A> {
|
||||
#[doc = "
|
||||
|
||||
Swaps out the current vector and hands it off to a user-provided
|
||||
function `f`. The function should transform it however is desired
|
||||
and return a new vector to replace it with.
|
||||
|
||||
"]
|
||||
/**
|
||||
* Swaps out the current vector and hands it off to a user-provided
|
||||
* function `f`. The function should transform it however is desired
|
||||
* and return a new vector to replace it with.
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn swap(f: fn(-~[mut A]) -> ~[mut A]) {
|
||||
self.borrow(|v| self.return(f(v)))
|
||||
}
|
||||
|
||||
#[doc = "Returns the number of elements currently in the dvec"]
|
||||
/// Returns the number of elements currently in the dvec
|
||||
fn len() -> uint {
|
||||
do self.borrow |v| {
|
||||
let l = v.len();
|
||||
|
|
@ -127,13 +123,13 @@ impl extensions<A> for dvec<A> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Overwrite the current contents"]
|
||||
/// Overwrite the current contents
|
||||
fn set(+w: ~[mut A]) {
|
||||
self.check_not_borrowed();
|
||||
self.data <- w;
|
||||
}
|
||||
|
||||
#[doc = "Remove and return the last element"]
|
||||
/// Remove and return the last element
|
||||
fn pop() -> A {
|
||||
do self.borrow |v| {
|
||||
let mut v <- v;
|
||||
|
|
@ -143,7 +139,7 @@ impl extensions<A> for dvec<A> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Insert a single item at the front of the list"]
|
||||
/// Insert a single item at the front of the list
|
||||
fn unshift(-t: A) {
|
||||
unsafe {
|
||||
let mut data = unsafe::reinterpret_cast(null::<()>());
|
||||
|
|
@ -157,13 +153,13 @@ impl extensions<A> for dvec<A> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Append a single item to the end of the list"]
|
||||
/// Append a single item to the end of the list
|
||||
fn push(+t: A) {
|
||||
self.check_not_borrowed();
|
||||
vec::push(self.data, t);
|
||||
}
|
||||
|
||||
#[doc = "Remove and return the first element"]
|
||||
/// Remove and return the first element
|
||||
fn shift() -> A {
|
||||
do self.borrow |v| {
|
||||
let mut v = vec::from_mut(v);
|
||||
|
|
@ -175,18 +171,16 @@ impl extensions<A> for dvec<A> {
|
|||
}
|
||||
|
||||
impl extensions<A:copy> for dvec<A> {
|
||||
#[doc = "
|
||||
Append all elements of a vector to the end of the list
|
||||
|
||||
Equivalent to `append_iter()` but potentially more efficient.
|
||||
"]
|
||||
/**
|
||||
* Append all elements of a vector to the end of the list
|
||||
*
|
||||
* Equivalent to `append_iter()` but potentially more efficient.
|
||||
*/
|
||||
fn push_all(ts: &[const A]) {
|
||||
self.push_slice(ts, 0u, vec::len(ts));
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Appends elements from `from_idx` to `to_idx` (exclusive)
|
||||
"]
|
||||
/// Appends elements from `from_idx` to `to_idx` (exclusive)
|
||||
fn push_slice(ts: &[const A], from_idx: uint, to_idx: uint) {
|
||||
do self.swap |v| {
|
||||
let mut v <- v;
|
||||
|
|
@ -202,12 +196,12 @@ impl extensions<A:copy> for dvec<A> {
|
|||
}
|
||||
|
||||
/*
|
||||
#[doc = "
|
||||
Append all elements of an iterable.
|
||||
|
||||
Failure will occur if the iterable's `each()` method
|
||||
attempts to access this vector.
|
||||
"]
|
||||
/**
|
||||
* Append all elements of an iterable.
|
||||
*
|
||||
* Failure will occur if the iterable's `each()` method
|
||||
* attempts to access this vector.
|
||||
*/
|
||||
fn append_iter<A, I:iter::base_iter<A>>(ts: I) {
|
||||
do self.swap |v| {
|
||||
let mut v = alt ts.size_hint() {
|
||||
|
|
@ -226,11 +220,11 @@ impl extensions<A:copy> for dvec<A> {
|
|||
}
|
||||
*/
|
||||
|
||||
#[doc = "
|
||||
Gets a copy of the current contents.
|
||||
|
||||
See `unwrap()` if you do not wish to copy the contents.
|
||||
"]
|
||||
/**
|
||||
* Gets a copy of the current contents.
|
||||
*
|
||||
* See `unwrap()` if you do not wish to copy the contents.
|
||||
*/
|
||||
fn get() -> ~[A] {
|
||||
do self.borrow |v| {
|
||||
let w = vec::from_mut(copy v);
|
||||
|
|
@ -239,28 +233,30 @@ impl extensions<A:copy> for dvec<A> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Copy out an individual element"]
|
||||
/// Copy out an individual element
|
||||
#[inline(always)]
|
||||
fn [](idx: uint) -> A {
|
||||
self.get_elt(idx)
|
||||
}
|
||||
|
||||
#[doc = "Copy out an individual element"]
|
||||
/// Copy out an individual element
|
||||
#[inline(always)]
|
||||
fn get_elt(idx: uint) -> A {
|
||||
self.check_not_borrowed();
|
||||
ret self.data[idx];
|
||||
}
|
||||
|
||||
#[doc = "Overwrites the contents of the element at `idx` with `a`"]
|
||||
/// Overwrites the contents of the element at `idx` with `a`
|
||||
fn set_elt(idx: uint, a: A) {
|
||||
self.check_not_borrowed();
|
||||
self.data[idx] = a;
|
||||
}
|
||||
|
||||
#[doc = "Overwrites the contents of the element at `idx` with `a`,
|
||||
growing the vector if necessary. New elements will be initialized
|
||||
with `initval`"]
|
||||
/**
|
||||
* Overwrites the contents of the element at `idx` with `a`,
|
||||
* growing the vector if necessary. New elements will be initialized
|
||||
* with `initval`
|
||||
*/
|
||||
fn grow_set_elt(idx: uint, initval: A, val: A) {
|
||||
do self.swap |v| {
|
||||
let mut v <- v;
|
||||
|
|
@ -269,7 +265,7 @@ impl extensions<A:copy> for dvec<A> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Returns the last element, failing if the vector is empty"]
|
||||
/// Returns the last element, failing if the vector is empty
|
||||
#[inline(always)]
|
||||
fn last() -> A {
|
||||
self.check_not_borrowed();
|
||||
|
|
@ -282,7 +278,7 @@ impl extensions<A:copy> for dvec<A> {
|
|||
ret self.data[length - 1u];
|
||||
}
|
||||
|
||||
#[doc="Iterates over the elements in reverse order"]
|
||||
/// Iterates over the elements in reverse order
|
||||
#[inline(always)]
|
||||
fn reach(f: fn(A) -> bool) {
|
||||
let length = self.len();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#[doc = "A type that represents one of two alternatives"];
|
||||
//! A type that represents one of two alternatives
|
||||
|
||||
import result::result;
|
||||
|
||||
#[doc = "The either type"]
|
||||
/// The either type
|
||||
enum either<T, U> {
|
||||
left(T),
|
||||
right(U)
|
||||
|
|
@ -10,19 +10,19 @@ enum either<T, U> {
|
|||
|
||||
fn either<T, U, V>(f_left: fn(T) -> V,
|
||||
f_right: fn(U) -> V, value: either<T, U>) -> V {
|
||||
#[doc = "
|
||||
Applies a function based on the given either value
|
||||
|
||||
If `value` is left(T) then `f_left` is applied to its contents, if `value`
|
||||
is right(U) then `f_right` is applied to its contents, and the result is
|
||||
returned.
|
||||
"];
|
||||
/*!
|
||||
* Applies a function based on the given either value
|
||||
*
|
||||
* If `value` is left(T) then `f_left` is applied to its contents, if
|
||||
* `value` is right(U) then `f_right` is applied to its contents, and the
|
||||
* result is returned.
|
||||
*/
|
||||
|
||||
alt value { left(l) { f_left(l) } right(r) { f_right(r) } }
|
||||
}
|
||||
|
||||
fn lefts<T: copy, U>(eithers: ~[either<T, U>]) -> ~[T] {
|
||||
#[doc = "Extracts from a vector of either all the left values"];
|
||||
//! Extracts from a vector of either all the left values
|
||||
|
||||
let mut result: ~[T] = ~[];
|
||||
for vec::each(eithers) |elt| {
|
||||
|
|
@ -32,7 +32,7 @@ fn lefts<T: copy, U>(eithers: ~[either<T, U>]) -> ~[T] {
|
|||
}
|
||||
|
||||
fn rights<T, U: copy>(eithers: ~[either<T, U>]) -> ~[U] {
|
||||
#[doc = "Extracts from a vector of either all the right values"];
|
||||
//! Extracts from a vector of either all the right values
|
||||
|
||||
let mut result: ~[U] = ~[];
|
||||
for vec::each(eithers) |elt| {
|
||||
|
|
@ -43,12 +43,12 @@ fn rights<T, U: copy>(eithers: ~[either<T, U>]) -> ~[U] {
|
|||
|
||||
fn partition<T: copy, U: copy>(eithers: ~[either<T, U>])
|
||||
-> {lefts: ~[T], rights: ~[U]} {
|
||||
#[doc = "
|
||||
Extracts from a vector of either all the left values and right values
|
||||
|
||||
Returns a structure containing a vector of left values and a vector of
|
||||
right values.
|
||||
"];
|
||||
/*!
|
||||
* Extracts from a vector of either all the left values and right values
|
||||
*
|
||||
* Returns a structure containing a vector of left values and a vector of
|
||||
* right values.
|
||||
*/
|
||||
|
||||
let mut lefts: ~[T] = ~[];
|
||||
let mut rights: ~[U] = ~[];
|
||||
|
|
@ -62,7 +62,7 @@ fn partition<T: copy, U: copy>(eithers: ~[either<T, U>])
|
|||
}
|
||||
|
||||
pure fn flip<T: copy, U: copy>(eith: either<T, U>) -> either<U, T> {
|
||||
#[doc = "Flips between left and right of a given either"];
|
||||
//! Flips between left and right of a given either
|
||||
|
||||
alt eith {
|
||||
right(r) { left(r) }
|
||||
|
|
@ -72,12 +72,12 @@ pure fn flip<T: copy, U: copy>(eith: either<T, U>) -> either<U, T> {
|
|||
|
||||
pure fn to_result<T: copy, U: copy>(
|
||||
eith: either<T, U>) -> result<U, T> {
|
||||
#[doc = "
|
||||
Converts either::t to a result::t
|
||||
|
||||
Converts an `either` type to a `result` type, making the \"right\" choice
|
||||
an ok result, and the \"left\" choice a fail
|
||||
"];
|
||||
/*!
|
||||
* Converts either::t to a result::t
|
||||
*
|
||||
* Converts an `either` type to a `result` type, making the "right" choice
|
||||
* an ok result, and the "left" choice a fail
|
||||
*/
|
||||
|
||||
alt eith {
|
||||
right(r) { result::ok(r) }
|
||||
|
|
@ -86,13 +86,13 @@ pure fn to_result<T: copy, U: copy>(
|
|||
}
|
||||
|
||||
pure fn is_left<T, U>(eith: either<T, U>) -> bool {
|
||||
#[doc = "Checks whether the given value is a left"];
|
||||
//! Checks whether the given value is a left
|
||||
|
||||
alt eith { left(_) { true } _ { false } }
|
||||
}
|
||||
|
||||
pure fn is_right<T, U>(eith: either<T, U>) -> bool {
|
||||
#[doc = "Checks whether the given value is a right"];
|
||||
//! Checks whether the given value is a right
|
||||
|
||||
alt eith { right(_) { true } _ { false } }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Operations and constants for `f32`"];
|
||||
//! Operations and constants for `f32`
|
||||
|
||||
// PORT
|
||||
|
||||
|
|
@ -56,49 +56,43 @@ pure fn gt(x: f32, y: f32) -> bool { ret x > y; }
|
|||
// FIXME (#1999): replace the predicates below with llvm intrinsics or
|
||||
// calls to the libmath macros in the rust runtime for performance.
|
||||
|
||||
#[doc = "
|
||||
Returns true if `x` is a positive number, including +0.0f320 and +Infinity
|
||||
"]
|
||||
/// Returns true if `x` is a positive number, including +0.0f320 and +Infinity
|
||||
pure fn is_positive(x: f32) -> bool
|
||||
{ ret x > 0.0f32 || (1.0f32/x) == infinity; }
|
||||
|
||||
#[doc = "
|
||||
Returns true if `x` is a negative number, including -0.0f320 and -Infinity
|
||||
"]
|
||||
/// Returns true if `x` is a negative number, including -0.0f320 and -Infinity
|
||||
pure fn is_negative(x: f32) -> bool
|
||||
{ ret x < 0.0f32 || (1.0f32/x) == neg_infinity; }
|
||||
|
||||
#[doc = "
|
||||
Returns true if `x` is a negative number, including -0.0f320 and -Infinity
|
||||
|
||||
This is the same as `f32::is_negative`.
|
||||
"]
|
||||
/**
|
||||
* Returns true if `x` is a negative number, including -0.0f320 and -Infinity
|
||||
*
|
||||
* This is the same as `f32::is_negative`.
|
||||
*/
|
||||
pure fn is_nonpositive(x: f32) -> bool {
|
||||
ret x < 0.0f32 || (1.0f32/x) == neg_infinity;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns true if `x` is a positive number, including +0.0f320 and +Infinity
|
||||
|
||||
This is the same as `f32::is_positive`.)
|
||||
"]
|
||||
/**
|
||||
* Returns true if `x` is a positive number, including +0.0f320 and +Infinity
|
||||
*
|
||||
* This is the same as `f32::is_positive`.)
|
||||
*/
|
||||
pure fn is_nonnegative(x: f32) -> bool {
|
||||
ret x > 0.0f32 || (1.0f32/x) == infinity;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns true if `x` is a zero number (positive or negative zero)
|
||||
"]
|
||||
/// Returns true if `x` is a zero number (positive or negative zero)
|
||||
pure fn is_zero(x: f32) -> bool {
|
||||
ret x == 0.0f32 || x == -0.0f32;
|
||||
}
|
||||
|
||||
#[doc = "Returns true if `x`is an infinite number"]
|
||||
/// Returns true if `x`is an infinite number
|
||||
pure fn is_infinite(x: f32) -> bool {
|
||||
ret x == infinity || x == neg_infinity;
|
||||
}
|
||||
|
||||
#[doc = "Returns true if `x`is a finite number"]
|
||||
/// Returns true if `x`is a finite number
|
||||
pure fn is_finite(x: f32) -> bool {
|
||||
ret !(is_NaN(x) || is_infinite(x));
|
||||
}
|
||||
|
|
@ -110,43 +104,43 @@ mod consts {
|
|||
|
||||
// FIXME (requires Issue #1433 to fix): replace with mathematical
|
||||
// constants from cmath.
|
||||
#[doc = "Archimedes' constant"]
|
||||
/// Archimedes' constant
|
||||
const pi: f32 = 3.14159265358979323846264338327950288_f32;
|
||||
|
||||
#[doc = "pi/2.0"]
|
||||
/// pi/2.0
|
||||
const frac_pi_2: f32 = 1.57079632679489661923132169163975144_f32;
|
||||
|
||||
#[doc = "pi/4.0"]
|
||||
/// pi/4.0
|
||||
const frac_pi_4: f32 = 0.785398163397448309615660845819875721_f32;
|
||||
|
||||
#[doc = "1.0/pi"]
|
||||
/// 1.0/pi
|
||||
const frac_1_pi: f32 = 0.318309886183790671537767526745028724_f32;
|
||||
|
||||
#[doc = "2.0/pi"]
|
||||
/// 2.0/pi
|
||||
const frac_2_pi: f32 = 0.636619772367581343075535053490057448_f32;
|
||||
|
||||
#[doc = "2.0/sqrt(pi)"]
|
||||
/// 2.0/sqrt(pi)
|
||||
const frac_2_sqrtpi: f32 = 1.12837916709551257389615890312154517_f32;
|
||||
|
||||
#[doc = "sqrt(2.0)"]
|
||||
/// sqrt(2.0)
|
||||
const sqrt2: f32 = 1.41421356237309504880168872420969808_f32;
|
||||
|
||||
#[doc = "1.0/sqrt(2.0)"]
|
||||
/// 1.0/sqrt(2.0)
|
||||
const frac_1_sqrt2: f32 = 0.707106781186547524400844362104849039_f32;
|
||||
|
||||
#[doc = "Euler's number"]
|
||||
/// Euler's number
|
||||
const e: f32 = 2.71828182845904523536028747135266250_f32;
|
||||
|
||||
#[doc = "log2(e)"]
|
||||
/// log2(e)
|
||||
const log2_e: f32 = 1.44269504088896340735992468100189214_f32;
|
||||
|
||||
#[doc = "log10(e)"]
|
||||
/// log10(e)
|
||||
const log10_e: f32 = 0.434294481903251827651128918916605082_f32;
|
||||
|
||||
#[doc = "ln(2.0)"]
|
||||
/// ln(2.0)
|
||||
const ln_2: f32 = 0.693147180559945309417232121458176568_f32;
|
||||
|
||||
#[doc = "ln(10.0)"]
|
||||
/// ln(10.0)
|
||||
const ln_10: f32 = 2.30258509299404568401799145468436421_f32;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Operations and constants for `f64`"];
|
||||
//! Operations and constants for `f64`
|
||||
|
||||
// PORT
|
||||
|
||||
|
|
@ -83,47 +83,43 @@ pure fn sqrt(x: f64) -> f64 {
|
|||
cmath::c_double::sqrt(x as libc::c_double) as f64
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns true if `x` is a positive number, including +0.0f640 and +Infinity.
|
||||
"]
|
||||
/// Returns true if `x` is a positive number, including +0.0f640 and +Infinity
|
||||
pure fn is_positive(x: f64) -> bool
|
||||
{ ret x > 0.0f64 || (1.0f64/x) == infinity; }
|
||||
|
||||
#[doc = "
|
||||
Returns true if `x` is a negative number, including -0.0f640 and -Infinity
|
||||
"]
|
||||
/// Returns true if `x` is a negative number, including -0.0f640 and -Infinity
|
||||
pure fn is_negative(x: f64) -> bool
|
||||
{ ret x < 0.0f64 || (1.0f64/x) == neg_infinity; }
|
||||
|
||||
#[doc = "
|
||||
Returns true if `x` is a negative number, including -0.0f640 and -Infinity
|
||||
|
||||
This is the same as `f64::is_negative`.
|
||||
"]
|
||||
/**
|
||||
* Returns true if `x` is a negative number, including -0.0f640 and -Infinity
|
||||
*
|
||||
* This is the same as `f64::is_negative`.
|
||||
*/
|
||||
pure fn is_nonpositive(x: f64) -> bool {
|
||||
ret x < 0.0f64 || (1.0f64/x) == neg_infinity;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns true if `x` is a positive number, including +0.0f640 and +Infinity
|
||||
|
||||
This is the same as `f64::positive`.
|
||||
"]
|
||||
/**
|
||||
* Returns true if `x` is a positive number, including +0.0f640 and +Infinity
|
||||
*
|
||||
* This is the same as `f64::positive`.
|
||||
*/
|
||||
pure fn is_nonnegative(x: f64) -> bool {
|
||||
ret x > 0.0f64 || (1.0f64/x) == infinity;
|
||||
}
|
||||
|
||||
#[doc = "Returns true if `x` is a zero number (positive or negative zero)"]
|
||||
/// Returns true if `x` is a zero number (positive or negative zero)
|
||||
pure fn is_zero(x: f64) -> bool {
|
||||
ret x == 0.0f64 || x == -0.0f64;
|
||||
}
|
||||
|
||||
#[doc = "Returns true if `x`is an infinite number"]
|
||||
/// Returns true if `x`is an infinite number
|
||||
pure fn is_infinite(x: f64) -> bool {
|
||||
ret x == infinity || x == neg_infinity;
|
||||
}
|
||||
|
||||
#[doc = "Returns true if `x`is a finite number"]
|
||||
/// Returns true if `x`is a finite number
|
||||
pure fn is_finite(x: f64) -> bool {
|
||||
ret !(is_NaN(x) || is_infinite(x));
|
||||
}
|
||||
|
|
@ -135,43 +131,43 @@ mod consts {
|
|||
|
||||
// FIXME (requires Issue #1433 to fix): replace with mathematical
|
||||
// constants from cmath.
|
||||
#[doc = "Archimedes' constant"]
|
||||
/// Archimedes' constant
|
||||
const pi: f64 = 3.14159265358979323846264338327950288_f64;
|
||||
|
||||
#[doc = "pi/2.0"]
|
||||
/// pi/2.0
|
||||
const frac_pi_2: f64 = 1.57079632679489661923132169163975144_f64;
|
||||
|
||||
#[doc = "pi/4.0"]
|
||||
/// pi/4.0
|
||||
const frac_pi_4: f64 = 0.785398163397448309615660845819875721_f64;
|
||||
|
||||
#[doc = "1.0/pi"]
|
||||
/// 1.0/pi
|
||||
const frac_1_pi: f64 = 0.318309886183790671537767526745028724_f64;
|
||||
|
||||
#[doc = "2.0/pi"]
|
||||
/// 2.0/pi
|
||||
const frac_2_pi: f64 = 0.636619772367581343075535053490057448_f64;
|
||||
|
||||
#[doc = "2.0/sqrt(pi)"]
|
||||
/// 2.0/sqrt(pi)
|
||||
const frac_2_sqrtpi: f64 = 1.12837916709551257389615890312154517_f64;
|
||||
|
||||
#[doc = "sqrt(2.0)"]
|
||||
/// sqrt(2.0)
|
||||
const sqrt2: f64 = 1.41421356237309504880168872420969808_f64;
|
||||
|
||||
#[doc = "1.0/sqrt(2.0)"]
|
||||
/// 1.0/sqrt(2.0)
|
||||
const frac_1_sqrt2: f64 = 0.707106781186547524400844362104849039_f64;
|
||||
|
||||
#[doc = "Euler's number"]
|
||||
/// Euler's number
|
||||
const e: f64 = 2.71828182845904523536028747135266250_f64;
|
||||
|
||||
#[doc = "log2(e)"]
|
||||
/// log2(e)
|
||||
const log2_e: f64 = 1.44269504088896340735992468100189214_f64;
|
||||
|
||||
#[doc = "log10(e)"]
|
||||
/// log10(e)
|
||||
const log10_e: f64 = 0.434294481903251827651128918916605082_f64;
|
||||
|
||||
#[doc = "ln(2.0)"]
|
||||
/// ln(2.0)
|
||||
const ln_2: f64 = 0.693147180559945309417232121458176568_f64;
|
||||
|
||||
#[doc = "ln(10.0)"]
|
||||
/// ln(10.0)
|
||||
const ln_10: f64 = 2.30258509299404568401799145468436421_f64;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Operations and constants for `float`"];
|
||||
//! Operations and constants for `float`
|
||||
|
||||
// Even though this module exports everything defined in it,
|
||||
// because it contains re-exports, we also have to explicitly
|
||||
|
|
@ -49,43 +49,43 @@ mod consts {
|
|||
|
||||
// FIXME (requires Issue #1433 to fix): replace with mathematical
|
||||
// constants from cmath.
|
||||
#[doc = "Archimedes' constant"]
|
||||
/// Archimedes' constant
|
||||
const pi: float = 3.14159265358979323846264338327950288;
|
||||
|
||||
#[doc = "pi/2.0"]
|
||||
/// pi/2.0
|
||||
const frac_pi_2: float = 1.57079632679489661923132169163975144;
|
||||
|
||||
#[doc = "pi/4.0"]
|
||||
/// pi/4.0
|
||||
const frac_pi_4: float = 0.785398163397448309615660845819875721;
|
||||
|
||||
#[doc = "1.0/pi"]
|
||||
/// 1.0/pi
|
||||
const frac_1_pi: float = 0.318309886183790671537767526745028724;
|
||||
|
||||
#[doc = "2.0/pi"]
|
||||
/// 2.0/pi
|
||||
const frac_2_pi: float = 0.636619772367581343075535053490057448;
|
||||
|
||||
#[doc = "2.0/sqrt(pi)"]
|
||||
/// 2.0/sqrt(pi)
|
||||
const frac_2_sqrtpi: float = 1.12837916709551257389615890312154517;
|
||||
|
||||
#[doc = "sqrt(2.0)"]
|
||||
/// sqrt(2.0)
|
||||
const sqrt2: float = 1.41421356237309504880168872420969808;
|
||||
|
||||
#[doc = "1.0/sqrt(2.0)"]
|
||||
/// 1.0/sqrt(2.0)
|
||||
const frac_1_sqrt2: float = 0.707106781186547524400844362104849039;
|
||||
|
||||
#[doc = "Euler's number"]
|
||||
/// Euler's number
|
||||
const e: float = 2.71828182845904523536028747135266250;
|
||||
|
||||
#[doc = "log2(e)"]
|
||||
/// log2(e)
|
||||
const log2_e: float = 1.44269504088896340735992468100189214;
|
||||
|
||||
#[doc = "log10(e)"]
|
||||
/// log10(e)
|
||||
const log10_e: float = 0.434294481903251827651128918916605082;
|
||||
|
||||
#[doc = "ln(2.0)"]
|
||||
/// ln(2.0)
|
||||
const ln_2: float = 0.693147180559945309417232121458176568;
|
||||
|
||||
#[doc = "ln(10.0)"]
|
||||
/// ln(10.0)
|
||||
const ln_10: float = 2.30258509299404568401799145468436421;
|
||||
}
|
||||
|
||||
|
|
@ -93,15 +93,15 @@ mod consts {
|
|||
* Section: String Conversions
|
||||
*/
|
||||
|
||||
#[doc = "
|
||||
Converts a float to a string
|
||||
|
||||
# Arguments
|
||||
|
||||
* num - The float value
|
||||
* digits - The number of significant digits
|
||||
* exact - Whether to enforce the exact number of significant digits
|
||||
"]
|
||||
/**
|
||||
* Converts a float to a string
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * num - The float value
|
||||
* * digits - The number of significant digits
|
||||
* * exact - Whether to enforce the exact number of significant digits
|
||||
*/
|
||||
fn to_str_common(num: float, digits: uint, exact: bool) -> str {
|
||||
if is_NaN(num) { ret "NaN"; }
|
||||
if num == infinity { ret "inf"; }
|
||||
|
|
@ -179,15 +179,15 @@ fn to_str_common(num: float, digits: uint, exact: bool) -> str {
|
|||
ret acc;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Converts a float to a string with exactly the number of
|
||||
provided significant digits
|
||||
|
||||
# Arguments
|
||||
|
||||
* num - The float value
|
||||
* digits - The number of significant digits
|
||||
"]
|
||||
/**
|
||||
* Converts a float to a string with exactly the number of
|
||||
* provided significant digits
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * num - The float value
|
||||
* * digits - The number of significant digits
|
||||
*/
|
||||
fn to_str_exact(num: float, digits: uint) -> str {
|
||||
to_str_common(num, digits, true)
|
||||
}
|
||||
|
|
@ -199,45 +199,45 @@ fn test_to_str_exact_do_decimal() {
|
|||
}
|
||||
|
||||
|
||||
#[doc = "
|
||||
Converts a float to a string with a maximum number of
|
||||
significant digits
|
||||
|
||||
# Arguments
|
||||
|
||||
* num - The float value
|
||||
* digits - The number of significant digits
|
||||
"]
|
||||
/**
|
||||
* Converts a float to a string with a maximum number of
|
||||
* significant digits
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * num - The float value
|
||||
* * digits - The number of significant digits
|
||||
*/
|
||||
fn to_str(num: float, digits: uint) -> str {
|
||||
to_str_common(num, digits, false)
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Convert a string to a float
|
||||
|
||||
This function accepts strings such as
|
||||
|
||||
* '3.14'
|
||||
* '+3.14', equivalent to '3.14'
|
||||
* '-3.14'
|
||||
* '2.5E10', or equivalently, '2.5e10'
|
||||
* '2.5E-10'
|
||||
* '', or, equivalently, '.' (understood as 0)
|
||||
* '5.'
|
||||
* '.5', or, equivalently, '0.5'
|
||||
* 'inf', '-inf', 'NaN'
|
||||
|
||||
Leading and trailing whitespace are ignored.
|
||||
|
||||
# Arguments
|
||||
|
||||
* num - A string
|
||||
|
||||
# Return value
|
||||
|
||||
`none` if the string did not represent a valid number. Otherwise, `some(n)`
|
||||
where `n` is the floating-point number represented by `[num]/~`.
|
||||
"]
|
||||
/**
|
||||
* Convert a string to a float
|
||||
*
|
||||
* This function accepts strings such as
|
||||
*
|
||||
* * '3.14'
|
||||
* * '+3.14', equivalent to '3.14'
|
||||
* * '-3.14'
|
||||
* * '2.5E10', or equivalently, '2.5e10'
|
||||
* * '2.5E-10'
|
||||
* * '', or, equivalently, '.' (understood as 0)
|
||||
* * '5.'
|
||||
* * '.5', or, equivalently, '0.5'
|
||||
* * 'inf', '-inf', 'NaN'
|
||||
*
|
||||
* Leading and trailing whitespace are ignored.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * num - A string
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* `none` if the string did not represent a valid number. Otherwise,
|
||||
* `some(n)` where `n` is the floating-point number represented by `[num]/~`.
|
||||
*/
|
||||
fn from_str(num: str) -> option<float> {
|
||||
if num == "inf" {
|
||||
ret some(infinity as float);
|
||||
|
|
@ -371,18 +371,18 @@ fn from_str(num: str) -> option<float> {
|
|||
* Section: Arithmetics
|
||||
*/
|
||||
|
||||
#[doc = "
|
||||
Compute the exponentiation of an integer by another integer as a float
|
||||
|
||||
# Arguments
|
||||
|
||||
* x - The base
|
||||
* pow - The exponent
|
||||
|
||||
# Return value
|
||||
|
||||
`NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
|
||||
"]
|
||||
/**
|
||||
* Compute the exponentiation of an integer by another integer as a float
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * x - The base
|
||||
* * pow - The exponent
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
|
||||
*/
|
||||
fn pow_with_uint(base: uint, pow: uint) -> float {
|
||||
if base == 0u {
|
||||
if pow == 0u {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
#[doc = "
|
||||
A type representing values that may be computed concurrently and
|
||||
operations for working with them.
|
||||
|
||||
# Example
|
||||
|
||||
~~~
|
||||
let delayed_fib = future::spawn {|| fib(5000) };
|
||||
make_a_sandwich();
|
||||
io::println(#fmt(\"fib(5000) = %?\", delayed_fib.get()))
|
||||
~~~
|
||||
"];
|
||||
/*!
|
||||
* A type representing values that may be computed concurrently and
|
||||
* operations for working with them.
|
||||
*
|
||||
* # Example
|
||||
*
|
||||
* ~~~
|
||||
* let delayed_fib = future::spawn {|| fib(5000) };
|
||||
* make_a_sandwich();
|
||||
* io::println(#fmt("fib(5000) = %?", delayed_fib.get()))
|
||||
* ~~~
|
||||
*/
|
||||
|
||||
import either::either;
|
||||
|
||||
|
|
@ -22,34 +22,34 @@ export get;
|
|||
export with;
|
||||
export spawn;
|
||||
|
||||
#[doc = "The future type"]
|
||||
/// The future type
|
||||
enum future<A> = {
|
||||
mut v: either<@A, fn@() -> A>
|
||||
};
|
||||
|
||||
#[doc = "Methods on the `future` type"]
|
||||
/// Methods on the `future` type
|
||||
impl extensions<A:copy send> for future<A> {
|
||||
|
||||
fn get() -> A {
|
||||
#[doc = "Get the value of the future"];
|
||||
//! Get the value of the future
|
||||
|
||||
get(self)
|
||||
}
|
||||
|
||||
fn with<B>(blk: fn(A) -> B) -> B {
|
||||
#[doc = "Work with the value without copying it"];
|
||||
//! Work with the value without copying it
|
||||
|
||||
with(self, blk)
|
||||
}
|
||||
}
|
||||
|
||||
fn from_value<A>(+val: A) -> future<A> {
|
||||
#[doc = "
|
||||
Create a future from a value
|
||||
|
||||
The value is immediately available and calling `get` later will
|
||||
not block.
|
||||
"];
|
||||
/*!
|
||||
* Create a future from a value
|
||||
*
|
||||
* The value is immediately available and calling `get` later will
|
||||
* not block.
|
||||
*/
|
||||
|
||||
future({
|
||||
mut v: either::left(@val)
|
||||
|
|
@ -57,12 +57,12 @@ fn from_value<A>(+val: A) -> future<A> {
|
|||
}
|
||||
|
||||
fn from_port<A:send>(-port: comm::port<A>) -> future<A> {
|
||||
#[doc = "
|
||||
Create a future from a port
|
||||
|
||||
The first time that the value is requested the task will block
|
||||
waiting for the result to be received on the port.
|
||||
"];
|
||||
/*!
|
||||
* Create a future from a port
|
||||
*
|
||||
* The first time that the value is requested the task will block
|
||||
* waiting for the result to be received on the port.
|
||||
*/
|
||||
|
||||
do from_fn {
|
||||
comm::recv(port)
|
||||
|
|
@ -70,13 +70,13 @@ fn from_port<A:send>(-port: comm::port<A>) -> future<A> {
|
|||
}
|
||||
|
||||
fn from_fn<A>(f: fn@() -> A) -> future<A> {
|
||||
#[doc = "
|
||||
Create a future from a function.
|
||||
|
||||
The first time that the value is requested it will be retreived by
|
||||
calling the function. Note that this function is a local
|
||||
function. It is not spawned into another task.
|
||||
"];
|
||||
/*!
|
||||
* Create a future from a function.
|
||||
*
|
||||
* The first time that the value is requested it will be retreived by
|
||||
* calling the function. Note that this function is a local
|
||||
* function. It is not spawned into another task.
|
||||
*/
|
||||
|
||||
future({
|
||||
mut v: either::right(f)
|
||||
|
|
@ -84,12 +84,12 @@ fn from_fn<A>(f: fn@() -> A) -> future<A> {
|
|||
}
|
||||
|
||||
fn spawn<A:send>(+blk: fn~() -> A) -> future<A> {
|
||||
#[doc = "
|
||||
Create a future from a unique closure.
|
||||
|
||||
The closure will be run in a new task and its result used as the
|
||||
value of the future.
|
||||
"];
|
||||
/*!
|
||||
* Create a future from a unique closure.
|
||||
*
|
||||
* The closure will be run in a new task and its result used as the
|
||||
* value of the future.
|
||||
*/
|
||||
|
||||
let mut po = comm::port();
|
||||
let ch = comm::chan(po);
|
||||
|
|
@ -100,13 +100,13 @@ fn spawn<A:send>(+blk: fn~() -> A) -> future<A> {
|
|||
}
|
||||
|
||||
fn get<A:copy>(future: future<A>) -> A {
|
||||
#[doc = "Get the value of the future"];
|
||||
//! Get the value of the future
|
||||
|
||||
do with(future) |v| { v }
|
||||
}
|
||||
|
||||
fn with<A,B>(future: future<A>, blk: fn(A) -> B) -> B {
|
||||
#[doc = "Work with the value without copying it"];
|
||||
//! Work with the value without copying it
|
||||
|
||||
let v = alt copy future.v {
|
||||
either::left(v) { v }
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
|
|||
pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }
|
||||
|
||||
#[inline(always)]
|
||||
#[doc = "Iterate over the range [`lo`..`hi`)"]
|
||||
/// Iterate over the range [`lo`..`hi`)
|
||||
fn range(lo: T, hi: T, it: fn(T) -> bool) {
|
||||
let mut i = lo;
|
||||
while i < hi {
|
||||
|
|
@ -47,25 +47,25 @@ fn range(lo: T, hi: T, it: fn(T) -> bool) {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Computes the bitwise complement"]
|
||||
/// Computes the bitwise complement
|
||||
pure fn compl(i: T) -> T {
|
||||
-1 as T ^ i
|
||||
}
|
||||
|
||||
#[doc = "Computes the absolute value"]
|
||||
/// Computes the absolute value
|
||||
// FIXME: abs should return an unsigned int (#2353)
|
||||
pure fn abs(i: T) -> T {
|
||||
if is_negative(i) { -i } else { i }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Parse a buffer of bytes
|
||||
|
||||
# Arguments
|
||||
|
||||
* buf - A byte buffer
|
||||
* radix - The base of the number
|
||||
"]
|
||||
/**
|
||||
* Parse a buffer of bytes
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * buf - A byte buffer
|
||||
* * radix - The base of the number
|
||||
*/
|
||||
fn parse_buf(buf: ~[u8], radix: uint) -> option<T> {
|
||||
if vec::len(buf) == 0u { ret none; }
|
||||
let mut i = vec::len(buf) - 1u;
|
||||
|
|
@ -88,10 +88,10 @@ fn parse_buf(buf: ~[u8], radix: uint) -> option<T> {
|
|||
};
|
||||
}
|
||||
|
||||
#[doc = "Parse a string to an int"]
|
||||
/// Parse a string to an int
|
||||
fn from_str(s: str) -> option<T> { parse_buf(str::bytes(s), 10u) }
|
||||
|
||||
#[doc = "Convert to a string in a given base"]
|
||||
/// Convert to a string in a given base
|
||||
fn to_str(n: T, radix: uint) -> str {
|
||||
do to_str_bytes(n, radix) |slice| {
|
||||
do vec::unpack_slice(slice) |p, len| {
|
||||
|
|
@ -108,7 +108,7 @@ fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Convert to a string"]
|
||||
/// Convert to a string
|
||||
fn str(i: T) -> str { ret to_str(i, 10u); }
|
||||
|
||||
impl ord of ord for T {
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ const bits: T = 32 as T;
|
|||
#[cfg(target_arch = "x86_64")]
|
||||
const bits: T = 64 as T;
|
||||
|
||||
#[doc = "Produce a uint suitable for use in a hash table"]
|
||||
/// Produce a uint suitable for use in a hash table
|
||||
pure fn hash(&&x: int) -> uint { ret x as uint; }
|
||||
|
||||
#[doc = "Returns `base` raised to the power of `exponent`"]
|
||||
/// Returns `base` raised to the power of `exponent`
|
||||
fn pow(base: int, exponent: uint) -> int {
|
||||
if exponent == 0u { ret 1; } //Not mathemtically true if ~[base == 0]
|
||||
if base == 0 { ret 0; }
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
type IMPL_T<A> = dlist::dlist<A>;
|
||||
|
||||
#[doc = "
|
||||
Iterates through the current contents.
|
||||
|
||||
Attempts to access this dlist during iteration are allowed (to allow for e.g.
|
||||
breadth-first search with in-place enqueues), but removing the current node
|
||||
is forbidden.
|
||||
"]
|
||||
/**
|
||||
* Iterates through the current contents.
|
||||
*
|
||||
* Attempts to access this dlist during iteration are allowed (to allow for
|
||||
* e.g. breadth-first search with in-place enqueues), but removing the current
|
||||
* node is forbidden.
|
||||
*/
|
||||
fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
|
||||
import dlist::extensions;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
type IMPL_T<A> = dvec::dvec<A>;
|
||||
|
||||
#[doc = "
|
||||
Iterates through the current contents.
|
||||
|
||||
Attempts to access this dvec during iteration will fail.
|
||||
"]
|
||||
/**
|
||||
* Iterates through the current contents.
|
||||
*
|
||||
* Attempts to access this dvec during iteration will fail.
|
||||
*/
|
||||
fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
|
||||
import dvec::extensions;
|
||||
self.swap(|v| { vec::each(v, f); v })
|
||||
|
|
|
|||
|
|
@ -1,38 +1,38 @@
|
|||
#[doc = "
|
||||
Bindings for libc.
|
||||
|
||||
We consider the following specs reasonably normative with respect
|
||||
to interoperating with the C standard library (libc/msvcrt):
|
||||
|
||||
* ISO 9899:1990 ('C95', 'ANSI C', 'Standard C'), NA1, 1995.
|
||||
* ISO 9899:1999 ('C99' or 'C9x').
|
||||
* ISO 9945:1988 / IEEE 1003.1-1988 ('POSIX.1').
|
||||
* ISO 9945:2001 / IEEE 1003.1-2001 ('POSIX:2001', 'SUSv3').
|
||||
* ISO 9945:2008 / IEEE 1003.1-2008 ('POSIX:2008', 'SUSv4').
|
||||
|
||||
Despite having several names each, these are *reasonably* coherent
|
||||
point-in-time, list-of-definition sorts of specs. You can get each under a
|
||||
variety of names but will wind up with the same definition in each case.
|
||||
|
||||
Our interface to these libraries is complicated by the non-universality of
|
||||
conformance to any of them. About the only thing universally supported is
|
||||
the first (C95), beyond that definitions quickly become absent on various
|
||||
platforms.
|
||||
|
||||
We therefore wind up dividing our module-space up (mostly for the sake of
|
||||
sanity while editing, filling-in-details and eliminating duplication) into
|
||||
definitions common-to-all (held in modules named c95, c99, posix88, posix01
|
||||
and posix08) and definitions that appear only on *some* platforms (named
|
||||
'extra'). This would be things like significant OSX foundation kit, or
|
||||
win32 library kernel32.dll, or various fancy glibc, linux or BSD
|
||||
extensions.
|
||||
|
||||
In addition to the per-platform 'extra' modules, we define a module of
|
||||
'common BSD' libc routines that never quite made it into POSIX but show up
|
||||
in multiple derived systems. This is the 4.4BSD r2 / 1995 release, the
|
||||
final one from Berkeley after the lawsuits died down and the CSRG
|
||||
dissolved.
|
||||
"];
|
||||
/*!
|
||||
* Bindings for libc.
|
||||
*
|
||||
* We consider the following specs reasonably normative with respect
|
||||
* to interoperating with the C standard library (libc/msvcrt):
|
||||
*
|
||||
* * ISO 9899:1990 ('C95', 'ANSI C', 'Standard C'), NA1, 1995.
|
||||
* * ISO 9899:1999 ('C99' or 'C9x').
|
||||
* * ISO 9945:1988 / IEEE 1003.1-1988 ('POSIX.1').
|
||||
* * ISO 9945:2001 / IEEE 1003.1-2001 ('POSIX:2001', 'SUSv3').
|
||||
* * ISO 9945:2008 / IEEE 1003.1-2008 ('POSIX:2008', 'SUSv4').
|
||||
*
|
||||
* Despite having several names each, these are *reasonably* coherent
|
||||
* point-in-time, list-of-definition sorts of specs. You can get each under a
|
||||
* variety of names but will wind up with the same definition in each case.
|
||||
*
|
||||
* Our interface to these libraries is complicated by the non-universality of
|
||||
* conformance to any of them. About the only thing universally supported is
|
||||
* the first (C95), beyond that definitions quickly become absent on various
|
||||
* platforms.
|
||||
*
|
||||
* We therefore wind up dividing our module-space up (mostly for the sake of
|
||||
* sanity while editing, filling-in-details and eliminating duplication) into
|
||||
* definitions common-to-all (held in modules named c95, c99, posix88, posix01
|
||||
* and posix08) and definitions that appear only on *some* platforms (named
|
||||
* 'extra'). This would be things like significant OSX foundation kit, or
|
||||
* win32 library kernel32.dll, or various fancy glibc, linux or BSD
|
||||
* extensions.
|
||||
*
|
||||
* In addition to the per-platform 'extra' modules, we define a module of
|
||||
* 'common BSD' libc routines that never quite made it into POSIX but show up
|
||||
* in multiple derived systems. This is the 4.4BSD r2 / 1995 release, the
|
||||
* final one from Berkeley after the lawsuits died down and the CSRG
|
||||
* dissolved.
|
||||
*/
|
||||
|
||||
// Initial glob-exports mean that all the contents of all the modules
|
||||
// wind up exported, if you're interested in writing platform-specific code.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Logging"];
|
||||
//! Logging
|
||||
|
||||
export console_on, console_off;
|
||||
|
||||
|
|
@ -8,18 +8,18 @@ extern mod rustrt {
|
|||
fn rust_log_console_off();
|
||||
}
|
||||
|
||||
#[doc = "Turns on logging to stdout globally"]
|
||||
/// Turns on logging to stdout globally
|
||||
fn console_on() {
|
||||
rustrt::rust_log_console_on();
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Turns off logging to stdout globally
|
||||
|
||||
Turns off the console unless the user has overridden the
|
||||
runtime environment's logging spec, e.g. by setting
|
||||
the RUST_LOG environment variable
|
||||
"]
|
||||
/**
|
||||
* Turns off logging to stdout globally
|
||||
*
|
||||
* Turns off the console unless the user has overridden the
|
||||
* runtime environment's logging spec, e.g. by setting
|
||||
* the RUST_LOG environment variable
|
||||
*/
|
||||
fn console_off() {
|
||||
rustrt::rust_log_console_off();
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
#[doc="A new implementation of communication.
|
||||
|
||||
This should be implementing almost entirely in Rust, and hopefully
|
||||
avoid needing a single global lock."]
|
||||
/**
|
||||
* A new implementation of communication.
|
||||
*
|
||||
* This should be implementing almost entirely in Rust, and hopefully
|
||||
* avoid needing a single global lock.
|
||||
*/
|
||||
|
||||
import arc::methods;
|
||||
import dvec::dvec;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc="An interface for numbers."]
|
||||
/// An interface for numbers.
|
||||
|
||||
iface num {
|
||||
// FIXME: Cross-crate overloading doesn't work yet. (#2615)
|
||||
|
|
|
|||
|
|
@ -1,26 +1,27 @@
|
|||
#[doc = "
|
||||
Operations on the ubiquitous `option` type.
|
||||
/*!
|
||||
* Operations on the ubiquitous `option` type.
|
||||
*
|
||||
* Type `option` represents an optional value.
|
||||
*
|
||||
* Every `option<T>` value can either be `some(T)` or `none`. Where in other
|
||||
* languages you might use a nullable type, in Rust you would use an option
|
||||
* type.
|
||||
*/
|
||||
|
||||
Type `option` represents an optional value.
|
||||
|
||||
Every `option<T>` value can either be `some(T)` or `none`. Where in other
|
||||
languages you might use a nullable type, in Rust you would use an option type.
|
||||
"];
|
||||
|
||||
#[doc = "The option type"]
|
||||
/// The option type
|
||||
enum option<T> {
|
||||
none,
|
||||
some(T),
|
||||
}
|
||||
|
||||
pure fn get<T: copy>(opt: option<T>) -> T {
|
||||
#[doc = "
|
||||
Gets the value out of an option
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the value equals `none`
|
||||
"];
|
||||
/*!
|
||||
* Gets the value out of an option
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if the value equals `none`
|
||||
*/
|
||||
|
||||
alt opt { some(x) { ret x; } none { fail "option none"; } }
|
||||
}
|
||||
|
|
@ -37,57 +38,57 @@ pure fn expect<T: copy>(opt: option<T>, reason: str) -> T {
|
|||
}
|
||||
|
||||
pure fn map<T, U: copy>(opt: option<T>, f: fn(T) -> U) -> option<U> {
|
||||
#[doc = "Maps a `some` value from one type to another"];
|
||||
//! Maps a `some` value from one type to another
|
||||
|
||||
alt opt { some(x) { some(f(x)) } none { none } }
|
||||
}
|
||||
|
||||
pure fn chain<T, U>(opt: option<T>, f: fn(T) -> option<U>) -> option<U> {
|
||||
#[doc = "
|
||||
Update an optional value by optionally running its content through a
|
||||
function that returns an option.
|
||||
"];
|
||||
/*!
|
||||
* Update an optional value by optionally running its content through a
|
||||
* function that returns an option.
|
||||
*/
|
||||
|
||||
alt opt { some(x) { f(x) } none { none } }
|
||||
}
|
||||
|
||||
pure fn is_none<T>(opt: option<T>) -> bool {
|
||||
#[doc = "Returns true if the option equals `none`"];
|
||||
//! Returns true if the option equals `none`
|
||||
|
||||
alt opt { none { true } some(_) { false } }
|
||||
}
|
||||
|
||||
pure fn is_some<T>(opt: option<T>) -> bool {
|
||||
#[doc = "Returns true if the option contains some value"];
|
||||
//! Returns true if the option contains some value
|
||||
|
||||
!is_none(opt)
|
||||
}
|
||||
|
||||
pure fn get_default<T: copy>(opt: option<T>, def: T) -> T {
|
||||
#[doc = "Returns the contained value or a default"];
|
||||
//! Returns the contained value or a default
|
||||
|
||||
alt opt { some(x) { x } none { def } }
|
||||
}
|
||||
|
||||
pure fn map_default<T, U: copy>(opt: option<T>, def: U, f: fn(T) -> U) -> U {
|
||||
#[doc = "Applies a function to the contained value or returns a default"];
|
||||
//! Applies a function to the contained value or returns a default
|
||||
|
||||
alt opt { none { def } some(t) { f(t) } }
|
||||
}
|
||||
|
||||
pure fn iter<T>(opt: option<T>, f: fn(T)) {
|
||||
#[doc = "Performs an operation on the contained value or does nothing"];
|
||||
//! Performs an operation on the contained value or does nothing
|
||||
|
||||
alt opt { none { } some(t) { f(t); } }
|
||||
}
|
||||
|
||||
pure fn unwrap<T>(-opt: option<T>) -> T {
|
||||
#[doc = "
|
||||
Moves a value out of an option type and returns it.
|
||||
|
||||
Useful primarily for getting strings, vectors and unique pointers out of
|
||||
option types without copying them.
|
||||
"];
|
||||
/*!
|
||||
* Moves a value out of an option type and returns it.
|
||||
*
|
||||
* Useful primarily for getting strings, vectors and unique pointers out
|
||||
* of option types without copying them.
|
||||
*/
|
||||
|
||||
unsafe {
|
||||
let addr = alt opt {
|
||||
|
|
@ -101,41 +102,42 @@ pure fn unwrap<T>(-opt: option<T>) -> T {
|
|||
}
|
||||
|
||||
impl extensions<T> for option<T> {
|
||||
#[doc = "
|
||||
Update an optional value by optionally running its content through a
|
||||
function that returns an option.
|
||||
"]
|
||||
pure fn chain<U>(f: fn(T) -> option<U>) -> option<U> { chain(self, f) }
|
||||
#[doc = "Applies a function to the contained value or returns a default"]
|
||||
pure fn map_default<U: copy>(def: U, f: fn(T) -> U) -> U
|
||||
/**
|
||||
* Update an optional value by optionally running its content through a
|
||||
* function that returns an option.
|
||||
*/
|
||||
fn chain<U>(f: fn(T) -> option<U>) -> option<U> { chain(self, f) }
|
||||
/// Applies a function to the contained value or returns a default
|
||||
fn map_default<U: copy>(def: U, f: fn(T) -> U) -> U
|
||||
{ map_default(self, def, f) }
|
||||
#[doc = "Performs an operation on the contained value or does nothing"]
|
||||
pure fn iter(f: fn(T)) { iter(self, f) }
|
||||
#[doc = "Returns true if the option equals `none`"]
|
||||
pure fn is_none() -> bool { is_none(self) }
|
||||
#[doc = "Returns true if the option contains some value"]
|
||||
pure fn is_some() -> bool { is_some(self) }
|
||||
#[doc = "Maps a `some` value from one type to another"]
|
||||
pure fn map<U:copy>(f: fn(T) -> U) -> option<U> { map(self, f) }
|
||||
/// Performs an operation on the contained value or does nothing
|
||||
fn iter(f: fn(T)) { iter(self, f) }
|
||||
/// Returns true if the option equals `none`
|
||||
fn is_none() -> bool { is_none(self) }
|
||||
/// Returns true if the option contains some value
|
||||
fn is_some() -> bool { is_some(self) }
|
||||
/// Maps a `some` value from one type to another
|
||||
fn map<U:copy>(f: fn(T) -> U) -> option<U> { map(self, f) }
|
||||
}
|
||||
|
||||
impl extensions<T: copy> for option<T> {
|
||||
#[doc = "
|
||||
Gets the value out of an option
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the value equals `none`
|
||||
"]
|
||||
pure fn get() -> T { get(self) }
|
||||
pure fn get_default(def: T) -> T { get_default(self, def) }
|
||||
#[doc = "
|
||||
Gets the value out of an option, printing a specified message on failure
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the value equals `none`
|
||||
"]
|
||||
/**
|
||||
* Gets the value out of an option
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if the value equals `none`
|
||||
*/
|
||||
fn get() -> T { get(self) }
|
||||
fn get_default(def: T) -> T { get_default(self, def) }
|
||||
/**
|
||||
* Gets the value out of an option, printing a specified message on
|
||||
* failure
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if the value equals `none`
|
||||
*/
|
||||
pure fn expect(reason: str) -> T { expect(self, reason) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
#[doc = "
|
||||
Higher-level interfaces to libc::* functions and operating system services.
|
||||
|
||||
In general these take and return rust types, use rust idioms (enums,
|
||||
closures, vectors) rather than C idioms, and do more extensive safety
|
||||
checks.
|
||||
|
||||
This module is not meant to only contain 1:1 mappings to libc entries; any
|
||||
os-interface code that is reasonably useful and broadly applicable can go
|
||||
here. Including utility routines that merely build on other os code.
|
||||
|
||||
We assume the general case is that users do not care, and do not want to
|
||||
be made to care, which operating system they are on. While they may want
|
||||
to special case various special cases -- and so we will not _hide_ the
|
||||
facts of which OS the user is on -- they should be given the opportunity
|
||||
to write OS-ignorant code by default.
|
||||
"];
|
||||
/*!
|
||||
* Higher-level interfaces to libc::* functions and operating system services.
|
||||
*
|
||||
* In general these take and return rust types, use rust idioms (enums,
|
||||
* closures, vectors) rather than C idioms, and do more extensive safety
|
||||
* checks.
|
||||
*
|
||||
* This module is not meant to only contain 1:1 mappings to libc entries; any
|
||||
* os-interface code that is reasonably useful and broadly applicable can go
|
||||
* here. Including utility routines that merely build on other os code.
|
||||
*
|
||||
* We assume the general case is that users do not care, and do not want to
|
||||
* be made to care, which operating system they are on. While they may want
|
||||
* to special case various special cases -- and so we will not _hide_ the
|
||||
* facts of which OS the user is on -- they should be given the opportunity
|
||||
* to write OS-ignorant code by default.
|
||||
*/
|
||||
|
||||
import libc::{c_char, c_void, c_int, c_uint, size_t, ssize_t,
|
||||
mode_t, pid_t, FILE};
|
||||
|
|
@ -130,7 +130,7 @@ fn setenv(n: str, v: str) {
|
|||
}
|
||||
|
||||
mod global_env {
|
||||
#[doc = "Internal module for serializing access to getenv/setenv"];
|
||||
//! Internal module for serializing access to getenv/setenv
|
||||
|
||||
export getenv;
|
||||
export setenv;
|
||||
|
|
@ -418,19 +418,19 @@ fn self_exe_path() -> option<path> {
|
|||
}
|
||||
|
||||
|
||||
#[doc = "
|
||||
Returns the path to the user's home directory, if known.
|
||||
|
||||
On Unix, returns the value of the 'HOME' environment variable if it is set and
|
||||
not equal to the empty string.
|
||||
|
||||
On Windows, returns the value of the 'HOME' environment variable if it is set
|
||||
and not equal to the empty string. Otherwise, returns the value of the
|
||||
'USERPROFILE' environment variable if it is set and not equal to the empty
|
||||
string.
|
||||
|
||||
Otherwise, homedir returns option::none.
|
||||
"]
|
||||
/**
|
||||
* Returns the path to the user's home directory, if known.
|
||||
*
|
||||
* On Unix, returns the value of the 'HOME' environment variable if it is set
|
||||
* and not equal to the empty string.
|
||||
*
|
||||
* On Windows, returns the value of the 'HOME' environment variable if it is
|
||||
* set and not equal to the empty string. Otherwise, returns the value of the
|
||||
* 'USERPROFILE' environment variable if it is set and not equal to the empty
|
||||
* string.
|
||||
*
|
||||
* Otherwise, homedir returns option::none.
|
||||
*/
|
||||
fn homedir() -> option<path> {
|
||||
ret alt getenv("HOME") {
|
||||
some(p) {
|
||||
|
|
@ -462,7 +462,7 @@ fn homedir() -> option<path> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Recursively walk a directory structure"]
|
||||
/// Recursively walk a directory structure
|
||||
fn walk_dir(p: path, f: fn(path) -> bool) {
|
||||
|
||||
walk_dir_(p, f);
|
||||
|
|
@ -491,14 +491,14 @@ fn walk_dir(p: path, f: fn(path) -> bool) {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Indicates whether a path represents a directory"]
|
||||
/// Indicates whether a path represents a directory
|
||||
fn path_is_dir(p: path) -> bool {
|
||||
do str::as_c_str(p) |buf| {
|
||||
rustrt::rust_path_is_dir(buf) != 0 as c_int
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Indicates whether a path exists"]
|
||||
/// Indicates whether a path exists
|
||||
fn path_exists(p: path) -> bool {
|
||||
do str::as_c_str(p) |buf| {
|
||||
rustrt::rust_path_exists(buf) != 0 as c_int
|
||||
|
|
@ -507,13 +507,13 @@ fn path_exists(p: path) -> bool {
|
|||
|
||||
// FIXME (#2622): under Windows, we should prepend the current drive letter
|
||||
// to paths that start with a slash.
|
||||
#[doc = "
|
||||
Convert a relative path to an absolute path
|
||||
|
||||
If the given path is relative, return it prepended with the current working
|
||||
directory. If the given path is already an absolute path, return it
|
||||
as is.
|
||||
"]
|
||||
/**
|
||||
* Convert a relative path to an absolute path
|
||||
*
|
||||
* If the given path is relative, return it prepended with the current working
|
||||
* directory. If the given path is already an absolute path, return it
|
||||
* as is.
|
||||
*/
|
||||
// NB: this is here rather than in path because it is a form of environment
|
||||
// querying; what it does depends on the process working directory, not just
|
||||
// the input paths.
|
||||
|
|
@ -526,7 +526,7 @@ fn make_absolute(p: path) -> path {
|
|||
}
|
||||
|
||||
|
||||
#[doc = "Creates a directory at the specified path"]
|
||||
/// Creates a directory at the specified path
|
||||
fn make_dir(p: path, mode: c_int) -> bool {
|
||||
ret mkdir(p, mode);
|
||||
|
||||
|
|
@ -551,7 +551,7 @@ fn make_dir(p: path, mode: c_int) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Lists the contents of a directory"]
|
||||
/// Lists the contents of a directory
|
||||
fn list_dir(p: path) -> ~[str] {
|
||||
|
||||
#[cfg(unix)]
|
||||
|
|
@ -573,11 +573,11 @@ fn list_dir(p: path) -> ~[str] {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Lists the contents of a directory
|
||||
|
||||
This version prepends each entry with the directory.
|
||||
"]
|
||||
/**
|
||||
* Lists the contents of a directory
|
||||
*
|
||||
* This version prepends each entry with the directory.
|
||||
*/
|
||||
fn list_dir_path(p: path) -> ~[str] {
|
||||
let mut p = p;
|
||||
let pl = str::len(p);
|
||||
|
|
@ -588,7 +588,7 @@ fn list_dir_path(p: path) -> ~[str] {
|
|||
os::list_dir(p).map(|f| p + f)
|
||||
}
|
||||
|
||||
#[doc = "Removes a directory at the specified path"]
|
||||
/// Removes a directory at the specified path
|
||||
fn remove_dir(p: path) -> bool {
|
||||
ret rmdir(p);
|
||||
|
||||
|
|
@ -633,7 +633,7 @@ fn change_dir(p: path) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Copies a file from one location to another"]
|
||||
/// Copies a file from one location to another
|
||||
fn copy_file(from: path, to: path) -> bool {
|
||||
ret do_copy_file(from, to);
|
||||
|
||||
|
|
@ -696,7 +696,7 @@ fn copy_file(from: path, to: path) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Deletes an existing file"]
|
||||
/// Deletes an existing file
|
||||
fn remove_file(p: path) -> bool {
|
||||
ret unlink(p);
|
||||
|
||||
|
|
@ -720,19 +720,19 @@ fn remove_file(p: path) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Get a string representing the platform-dependent last error"]
|
||||
/// Get a string representing the platform-dependent last error
|
||||
fn last_os_error() -> str {
|
||||
rustrt::last_os_error()
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Sets the process exit code
|
||||
|
||||
Sets the exit code returned by the process if all supervised tasks terminate
|
||||
successfully (without failing). If the current root task fails and is
|
||||
supervised by the scheduler then any user-specified exit status is ignored and
|
||||
the process exits with the default failure status
|
||||
"]
|
||||
/**
|
||||
* Sets the process exit code
|
||||
*
|
||||
* Sets the exit code returned by the process if all supervised tasks
|
||||
* terminate successfully (without failing). If the current root task fails
|
||||
* and is supervised by the scheduler then any user-specified exit status is
|
||||
* ignored and the process exits with the default failure status
|
||||
*/
|
||||
fn set_exit_status(code: int) {
|
||||
rustrt::rust_set_exit_status(code as libc::intptr_t);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Path data type and helper functions"];
|
||||
//! Path data type and helper functions
|
||||
|
||||
export path;
|
||||
export consts;
|
||||
|
|
@ -13,22 +13,22 @@ export splitext;
|
|||
export normalize;
|
||||
|
||||
// FIXME: This type should probably be constrained (#2624)
|
||||
#[doc = "A path or fragment of a filesystem path"]
|
||||
/// A path or fragment of a filesystem path
|
||||
type path = str;
|
||||
|
||||
#[cfg(unix)]
|
||||
mod consts {
|
||||
#[doc = "
|
||||
The primary path separator character for the platform
|
||||
|
||||
On all platforms it is '/'
|
||||
"]
|
||||
/**
|
||||
* The primary path separator character for the platform
|
||||
*
|
||||
* On all platforms it is '/'
|
||||
*/
|
||||
const path_sep: char = '/';
|
||||
#[doc = "
|
||||
The secondary path separator character for the platform
|
||||
|
||||
On Unixes it is '/'. On Windows it is '\\'.
|
||||
"]
|
||||
/**
|
||||
* The secondary path separator character for the platform
|
||||
*
|
||||
* On Unixes it is '/'. On Windows it is '\'.
|
||||
*/
|
||||
const alt_path_sep: char = '/';
|
||||
}
|
||||
|
||||
|
|
@ -38,12 +38,12 @@ mod consts {
|
|||
const alt_path_sep: char = '\\';
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Indicates whether a path is absolute.
|
||||
|
||||
A path is considered absolute if it begins at the filesystem root (\"/\") or,
|
||||
on Windows, begins with a drive letter.
|
||||
"]
|
||||
/**
|
||||
* Indicates whether a path is absolute.
|
||||
*
|
||||
* A path is considered absolute if it begins at the filesystem root ("/") or,
|
||||
* on Windows, begins with a drive letter.
|
||||
*/
|
||||
#[cfg(unix)]
|
||||
fn path_is_absolute(p: path) -> bool {
|
||||
str::char_at(p, 0u) == '/'
|
||||
|
|
@ -57,7 +57,7 @@ fn path_is_absolute(p: str) -> bool {
|
|||
|| str::char_at(p, 2u) == consts::alt_path_sep);
|
||||
}
|
||||
|
||||
#[doc = "Get the default path separator for the host platform"]
|
||||
/// Get the default path separator for the host platform
|
||||
fn path_sep() -> str { ret str::from_char(consts::path_sep); }
|
||||
|
||||
fn split_dirname_basename (pp: path) -> {dirname: str, basename: str} {
|
||||
|
|
@ -72,39 +72,39 @@ fn split_dirname_basename (pp: path) -> {dirname: str, basename: str} {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Get the directory portion of a path
|
||||
|
||||
Returns all of the path up to, but excluding, the final path separator.
|
||||
The dirname of \"/usr/share\" will be \"/usr\", but the dirname of
|
||||
\"/usr/share/\" is \"/usr/share\".
|
||||
|
||||
If the path is not prefixed with a directory, then \".\" is returned.
|
||||
"]
|
||||
/**
|
||||
* Get the directory portion of a path
|
||||
*
|
||||
* Returns all of the path up to, but excluding, the final path separator.
|
||||
* The dirname of "/usr/share" will be "/usr", but the dirname of
|
||||
* "/usr/share/" is "/usr/share".
|
||||
*
|
||||
* If the path is not prefixed with a directory, then "." is returned.
|
||||
*/
|
||||
fn dirname(pp: path) -> path {
|
||||
ret split_dirname_basename(pp).dirname;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Get the file name portion of a path
|
||||
|
||||
Returns the portion of the path after the final path separator.
|
||||
The basename of \"/usr/share\" will be \"share\". If there are no
|
||||
path separators in the path then the returned path is identical to
|
||||
the provided path. If an empty path is provided or the path ends
|
||||
with a path separator then an empty path is returned.
|
||||
"]
|
||||
/**
|
||||
* Get the file name portion of a path
|
||||
*
|
||||
* Returns the portion of the path after the final path separator.
|
||||
* The basename of "/usr/share" will be "share". If there are no
|
||||
* path separators in the path then the returned path is identical to
|
||||
* the provided path. If an empty path is provided or the path ends
|
||||
* with a path separator then an empty path is returned.
|
||||
*/
|
||||
fn basename(pp: path) -> path {
|
||||
ret split_dirname_basename(pp).basename;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Connects to path segments
|
||||
|
||||
Given paths `pre` and `post, removes any trailing path separator on `pre` and
|
||||
any leading path separator on `post`, and returns the concatenation of the two
|
||||
with a single path separator between them.
|
||||
"]
|
||||
/**
|
||||
* Connects to path segments
|
||||
*
|
||||
* Given paths `pre` and `post, removes any trailing path separator on `pre`
|
||||
* and any leading path separator on `post`, and returns the concatenation of
|
||||
* the two with a single path separator between them.
|
||||
*/
|
||||
fn connect(pre: path, post: path) -> path {
|
||||
let mut pre_ = pre;
|
||||
let mut post_ = post;
|
||||
|
|
@ -122,11 +122,11 @@ fn connect(pre: path, post: path) -> path {
|
|||
ret pre_ + path_sep() + post_;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Connects a vector of path segments into a single path.
|
||||
|
||||
Inserts path separators as needed.
|
||||
"]
|
||||
/**
|
||||
* Connects a vector of path segments into a single path.
|
||||
*
|
||||
* Inserts path separators as needed.
|
||||
*/
|
||||
fn connect_many(paths: ~[path]) -> path {
|
||||
ret if vec::len(paths) == 1u {
|
||||
paths[0]
|
||||
|
|
@ -136,29 +136,29 @@ fn connect_many(paths: ~[path]) -> path {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Split a path into its individual components
|
||||
|
||||
Splits a given path by path separators and returns a vector containing
|
||||
each piece of the path. On Windows, if the path is absolute then
|
||||
the first element of the returned vector will be the drive letter
|
||||
followed by a colon.
|
||||
"]
|
||||
/**
|
||||
* Split a path into its individual components
|
||||
*
|
||||
* Splits a given path by path separators and returns a vector containing
|
||||
* each piece of the path. On Windows, if the path is absolute then
|
||||
* the first element of the returned vector will be the drive letter
|
||||
* followed by a colon.
|
||||
*/
|
||||
fn split(p: path) -> ~[path] {
|
||||
str::split_nonempty(p, |c| {
|
||||
c == consts::path_sep || c == consts::alt_path_sep
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Split a path into the part before the extension and the extension
|
||||
|
||||
Split a path into a pair of strings with the first element being the filename
|
||||
without the extension and the second being either empty or the file extension
|
||||
including the period. Leading periods in the basename are ignored. If the
|
||||
path includes directory components then they are included in the filename part
|
||||
of the result pair.
|
||||
"]
|
||||
/**
|
||||
* Split a path into the part before the extension and the extension
|
||||
*
|
||||
* Split a path into a pair of strings with the first element being the
|
||||
* filename without the extension and the second being either empty or the
|
||||
* file extension including the period. Leading periods in the basename are
|
||||
* ignored. If the path includes directory components then they are included
|
||||
* in the filename part of the result pair.
|
||||
*/
|
||||
fn splitext(p: path) -> (str, str) {
|
||||
if str::is_empty(p) { ("", "") }
|
||||
else {
|
||||
|
|
@ -200,19 +200,18 @@ fn splitext(p: path) -> (str, str) {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Collapses redundant path separators.
|
||||
|
||||
Does not follow symbolic links.
|
||||
|
||||
# Examples
|
||||
|
||||
* '/a/../b' becomes '/b'
|
||||
* 'a/./b/' becomes 'a/b/'
|
||||
* 'a/b/../../../' becomes '..'
|
||||
* '/a/b/c/../d/./../../e/' becomes '/a/e/'
|
||||
|
||||
"]
|
||||
/**
|
||||
* Collapses redundant path separators.
|
||||
*
|
||||
* Does not follow symbolic links.
|
||||
*
|
||||
* # Examples
|
||||
*
|
||||
* * '/a/../b' becomes '/b'
|
||||
* * 'a/./b/' becomes 'a/b/'
|
||||
* * 'a/b/../../../' becomes '..'
|
||||
* * '/a/b/c/../d/./../../e/' becomes '/a/e/'
|
||||
*/
|
||||
fn normalize(p: path) -> path {
|
||||
let s = split(p);
|
||||
let s = strip_dots(s);
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ extern mod rustrt {
|
|||
|
||||
type global_ptr = *libc::uintptr_t;
|
||||
|
||||
#[doc = "
|
||||
Atomically gets a channel from a pointer to a pointer-sized memory location
|
||||
or, if no channel exists creates and installs a new channel and sets up a new
|
||||
task to receive from it.
|
||||
"]
|
||||
/**
|
||||
* Atomically gets a channel from a pointer to a pointer-sized memory location
|
||||
* or, if no channel exists creates and installs a new channel and sets up a
|
||||
* new task to receive from it.
|
||||
*/
|
||||
unsafe fn chan_from_global_ptr<T: send>(
|
||||
global: global_ptr,
|
||||
builder: fn() -> task::builder,
|
||||
|
|
@ -161,25 +161,25 @@ fn test_from_global_chan2() {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Convert the current task to a 'weak' task temporarily
|
||||
|
||||
As a weak task it will not be counted towards the runtime's set
|
||||
of live tasks. When there are no more outstanding live (non-weak) tasks
|
||||
the runtime will send an exit message on the provided channel.
|
||||
|
||||
This function is super-unsafe. Do not use.
|
||||
|
||||
# Safety notes
|
||||
|
||||
* Weak tasks must either die on their own or exit upon receipt of
|
||||
the exit message. Failure to do so will cause the runtime to never
|
||||
exit
|
||||
* Tasks must not call `weaken_task` multiple times. This will
|
||||
break the kernel's accounting of live tasks.
|
||||
* Weak tasks must not be supervised. A supervised task keeps
|
||||
a reference to its parent, so the parent will not die.
|
||||
"]
|
||||
/**
|
||||
* Convert the current task to a 'weak' task temporarily
|
||||
*
|
||||
* As a weak task it will not be counted towards the runtime's set
|
||||
* of live tasks. When there are no more outstanding live (non-weak) tasks
|
||||
* the runtime will send an exit message on the provided channel.
|
||||
*
|
||||
* This function is super-unsafe. Do not use.
|
||||
*
|
||||
* # Safety notes
|
||||
*
|
||||
* * Weak tasks must either die on their own or exit upon receipt of
|
||||
* the exit message. Failure to do so will cause the runtime to never
|
||||
* exit
|
||||
* * Tasks must not call `weaken_task` multiple times. This will
|
||||
* break the kernel's accounting of live tasks.
|
||||
* * Weak tasks must not be supervised. A supervised task keeps
|
||||
* a reference to its parent, so the parent will not die.
|
||||
*/
|
||||
unsafe fn weaken_task(f: fn(comm::port<()>)) {
|
||||
let po = comm::port();
|
||||
let ch = comm::chan(po);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Unsafe pointer utility functions"];
|
||||
//! Unsafe pointer utility functions
|
||||
|
||||
export addr_of;
|
||||
export mut_addr_of;
|
||||
|
|
@ -33,11 +33,11 @@ extern mod rusti {
|
|||
fn addr_of<T>(val: T) -> *T;
|
||||
}
|
||||
|
||||
#[doc = "Get an unsafe pointer to a value"]
|
||||
/// Get an unsafe pointer to a value
|
||||
#[inline(always)]
|
||||
pure fn addr_of<T>(val: T) -> *T { unchecked { rusti::addr_of(val) } }
|
||||
|
||||
#[doc = "Get an unsafe mut pointer to a value"]
|
||||
/// Get an unsafe mut pointer to a value
|
||||
#[inline(always)]
|
||||
pure fn mut_addr_of<T>(val: T) -> *mut T {
|
||||
unsafe {
|
||||
|
|
@ -45,7 +45,7 @@ pure fn mut_addr_of<T>(val: T) -> *mut T {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Calculate the offset from a pointer"]
|
||||
/// Calculate the offset from a pointer
|
||||
#[inline(always)]
|
||||
fn offset<T>(ptr: *T, count: uint) -> *T {
|
||||
unsafe {
|
||||
|
|
@ -53,7 +53,7 @@ fn offset<T>(ptr: *T, count: uint) -> *T {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Calculate the offset from a const pointer"]
|
||||
/// Calculate the offset from a const pointer
|
||||
#[inline(always)]
|
||||
fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
|
||||
unsafe {
|
||||
|
|
@ -61,19 +61,19 @@ fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Calculate the offset from a mut pointer"]
|
||||
/// Calculate the offset from a mut pointer
|
||||
#[inline(always)]
|
||||
fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
|
||||
(ptr as uint + count * sys::size_of::<T>()) as *mut T
|
||||
}
|
||||
|
||||
#[doc = "Return the offset of the first null pointer in `buf`."]
|
||||
/// Return the offset of the first null pointer in `buf`.
|
||||
#[inline(always)]
|
||||
unsafe fn buf_len<T>(buf: **T) -> uint {
|
||||
position(buf, |i| i == null())
|
||||
}
|
||||
|
||||
#[doc = "Return the first offset `i` such that `f(buf[i]) == true`."]
|
||||
/// Return the first offset `i` such that `f(buf[i]) == true`.
|
||||
#[inline(always)]
|
||||
unsafe fn position<T>(buf: *T, f: fn(T) -> bool) -> uint {
|
||||
let mut i = 0u;
|
||||
|
|
@ -83,34 +83,34 @@ unsafe fn position<T>(buf: *T, f: fn(T) -> bool) -> uint {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Create an unsafe null pointer"]
|
||||
/// Create an unsafe null pointer
|
||||
#[inline(always)]
|
||||
pure fn null<T>() -> *T { unsafe { unsafe::reinterpret_cast(0u) } }
|
||||
|
||||
#[doc = "Returns true if the pointer is equal to the null pointer."]
|
||||
/// Returns true if the pointer is equal to the null pointer.
|
||||
pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }
|
||||
|
||||
#[doc = "Returns true if the pointer is not equal to the null pointer."]
|
||||
/// Returns true if the pointer is not equal to the null pointer.
|
||||
pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
|
||||
|
||||
#[doc = "
|
||||
Copies data from one location to another
|
||||
|
||||
Copies `count` elements (not bytes) from `src` to `dst`. The source
|
||||
and destination may not overlap.
|
||||
"]
|
||||
/**
|
||||
* Copies data from one location to another
|
||||
*
|
||||
* Copies `count` elements (not bytes) from `src` to `dst`. The source
|
||||
* and destination may not overlap.
|
||||
*/
|
||||
#[inline(always)]
|
||||
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
|
||||
let n = count * sys::size_of::<T>();
|
||||
libc_::memcpy(dst as *c_void, src as *c_void, n as size_t);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Copies data from one location to another
|
||||
|
||||
Copies `count` elements (not bytes) from `src` to `dst`. The source
|
||||
and destination may overlap.
|
||||
"]
|
||||
/**
|
||||
* Copies data from one location to another
|
||||
*
|
||||
* Copies `count` elements (not bytes) from `src` to `dst`. The source
|
||||
* and destination may overlap.
|
||||
*/
|
||||
#[inline(always)]
|
||||
unsafe fn memmove<T>(dst: *T, src: *T, count: uint) {
|
||||
let n = count * sys::size_of::<T>();
|
||||
|
|
@ -123,12 +123,12 @@ unsafe fn memset<T>(dst: *mut T, c: int, count: uint) {
|
|||
libc_::memset(dst as *c_void, c as libc::c_int, n as size_t);
|
||||
}
|
||||
|
||||
#[doc = "Extension methods for pointers"]
|
||||
/// Extension methods for pointers
|
||||
impl extensions<T> for *T {
|
||||
#[doc = "Returns true if the pointer is equal to the null pointer."]
|
||||
/// Returns true if the pointer is equal to the null pointer.
|
||||
pure fn is_null() -> bool { is_null(self) }
|
||||
|
||||
#[doc = "Returns true if the pointer is not equal to the null pointer."]
|
||||
/// Returns true if the pointer is not equal to the null pointer.
|
||||
pure fn is_not_null() -> bool { is_not_null(self) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Random number generation"];
|
||||
//! Random number generation
|
||||
|
||||
export rng, seed, seeded_rng, weighted, extensions;
|
||||
export xorshift, seeded_xorshift;
|
||||
|
|
@ -14,93 +14,97 @@ extern mod rustrt {
|
|||
fn rand_free(c: *rctx);
|
||||
}
|
||||
|
||||
#[doc = "A random number generator"]
|
||||
/// A random number generator
|
||||
iface rng {
|
||||
#[doc = "Return the next random integer"]
|
||||
/// Return the next random integer
|
||||
fn next() -> u32;
|
||||
}
|
||||
|
||||
#[doc = "A value with a particular weight compared to other values"]
|
||||
/// A value with a particular weight compared to other values
|
||||
type weighted<T> = { weight: uint, item: T };
|
||||
|
||||
#[doc = "Extension methods for random number generators"]
|
||||
/// Extension methods for random number generators
|
||||
impl extensions for rng {
|
||||
|
||||
#[doc = "Return a random int"]
|
||||
/// Return a random int
|
||||
fn gen_int() -> int {
|
||||
self.gen_i64() as int
|
||||
}
|
||||
|
||||
#[doc = "Return an int randomly chosen from the range [start, end), \
|
||||
failing if start >= end"]
|
||||
/**
|
||||
* Return an int randomly chosen from the range [start, end),
|
||||
* failing if start >= end
|
||||
*/
|
||||
fn gen_int_range(start: int, end: int) -> int {
|
||||
assert start < end;
|
||||
start + int::abs(self.gen_int() % (end - start))
|
||||
}
|
||||
|
||||
#[doc = "Return a random i8"]
|
||||
/// Return a random i8
|
||||
fn gen_i8() -> i8 {
|
||||
self.next() as i8
|
||||
}
|
||||
|
||||
#[doc = "Return a random i16"]
|
||||
/// Return a random i16
|
||||
fn gen_i16() -> i16 {
|
||||
self.next() as i16
|
||||
}
|
||||
|
||||
#[doc = "Return a random i32"]
|
||||
/// Return a random i32
|
||||
fn gen_i32() -> i32 {
|
||||
self.next() as i32
|
||||
}
|
||||
|
||||
#[doc = "Return a random i64"]
|
||||
/// Return a random i64
|
||||
fn gen_i64() -> i64 {
|
||||
(self.next() as i64 << 32) | self.next() as i64
|
||||
}
|
||||
|
||||
#[doc = "Return a random uint"]
|
||||
/// Return a random uint
|
||||
fn gen_uint() -> uint {
|
||||
self.gen_u64() as uint
|
||||
}
|
||||
|
||||
#[doc = "Return a uint randomly chosen from the range [start, end), \
|
||||
failing if start >= end"]
|
||||
/**
|
||||
* Return a uint randomly chosen from the range [start, end),
|
||||
* failing if start >= end
|
||||
*/
|
||||
fn gen_uint_range(start: uint, end: uint) -> uint {
|
||||
assert start < end;
|
||||
start + (self.gen_uint() % (end - start))
|
||||
}
|
||||
|
||||
#[doc = "Return a random u8"]
|
||||
/// Return a random u8
|
||||
fn gen_u8() -> u8 {
|
||||
self.next() as u8
|
||||
}
|
||||
|
||||
#[doc = "Return a random u16"]
|
||||
/// Return a random u16
|
||||
fn gen_u16() -> u16 {
|
||||
self.next() as u16
|
||||
}
|
||||
|
||||
#[doc = "Return a random u32"]
|
||||
/// Return a random u32
|
||||
fn gen_u32() -> u32 {
|
||||
self.next()
|
||||
}
|
||||
|
||||
#[doc = "Return a random u64"]
|
||||
/// Return a random u64
|
||||
fn gen_u64() -> u64 {
|
||||
(self.next() as u64 << 32) | self.next() as u64
|
||||
}
|
||||
|
||||
#[doc = "Return a random float"]
|
||||
/// Return a random float
|
||||
fn gen_float() -> float {
|
||||
self.gen_f64() as float
|
||||
}
|
||||
|
||||
#[doc = "Return a random f32"]
|
||||
/// Return a random f32
|
||||
fn gen_f32() -> f32 {
|
||||
self.gen_f64() as f32
|
||||
}
|
||||
|
||||
#[doc = "Return a random f64"]
|
||||
/// Return a random f64
|
||||
fn gen_f64() -> f64 {
|
||||
let u1 = self.next() as f64;
|
||||
let u2 = self.next() as f64;
|
||||
|
|
@ -109,24 +113,25 @@ impl extensions for rng {
|
|||
ret ((u1 / scale + u2) / scale + u3) / scale;
|
||||
}
|
||||
|
||||
#[doc = "Return a random char"]
|
||||
/// Return a random char
|
||||
fn gen_char() -> char {
|
||||
self.next() as char
|
||||
}
|
||||
|
||||
#[doc = "Return a char randomly chosen from chars, failing if chars is \
|
||||
empty"]
|
||||
/**
|
||||
* Return a char randomly chosen from chars, failing if chars is empty
|
||||
*/
|
||||
fn gen_char_from(chars: str) -> char {
|
||||
assert !chars.is_empty();
|
||||
self.choose(str::chars(chars))
|
||||
}
|
||||
|
||||
#[doc = "Return a random bool"]
|
||||
/// Return a random bool
|
||||
fn gen_bool() -> bool {
|
||||
self.next() & 1u32 == 1u32
|
||||
}
|
||||
|
||||
#[doc = "Return a bool with a 1 in n chance of true"]
|
||||
/// Return a bool with a 1 in n chance of true
|
||||
fn gen_weighted_bool(n: uint) -> bool {
|
||||
if n == 0u {
|
||||
true
|
||||
|
|
@ -135,8 +140,9 @@ impl extensions for rng {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Return a random string of the specified length composed of A-Z, \
|
||||
a-z, 0-9"]
|
||||
/**
|
||||
* Return a random string of the specified length composed of A-Z,a-z,0-9
|
||||
*/
|
||||
fn gen_str(len: uint) -> str {
|
||||
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
|
||||
"abcdefghijklmnopqrstuvwxyz" +
|
||||
|
|
@ -150,19 +156,19 @@ impl extensions for rng {
|
|||
s
|
||||
}
|
||||
|
||||
#[doc = "Return a random byte string of the specified length"]
|
||||
/// Return a random byte string of the specified length
|
||||
fn gen_bytes(len: uint) -> ~[u8] {
|
||||
do vec::from_fn(len) |_i| {
|
||||
self.gen_u8()
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Choose an item randomly, failing if values is empty"]
|
||||
/// Choose an item randomly, failing if values is empty
|
||||
fn choose<T:copy>(values: ~[T]) -> T {
|
||||
self.choose_option(values).get()
|
||||
}
|
||||
|
||||
#[doc = "Choose some(item) randomly, returning none if values is empty"]
|
||||
/// Choose some(item) randomly, returning none if values is empty
|
||||
fn choose_option<T:copy>(values: ~[T]) -> option<T> {
|
||||
if values.is_empty() {
|
||||
none
|
||||
|
|
@ -171,14 +177,18 @@ impl extensions for rng {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Choose an item respecting the relative weights, failing if \
|
||||
the sum of the weights is 0"]
|
||||
/**
|
||||
* Choose an item respecting the relative weights, failing if the sum of
|
||||
* the weights is 0
|
||||
*/
|
||||
fn choose_weighted<T: copy>(v : ~[weighted<T>]) -> T {
|
||||
self.choose_weighted_option(v).get()
|
||||
}
|
||||
|
||||
#[doc = "Choose some(item) respecting the relative weights, returning \
|
||||
none if the sum of the weights is 0"]
|
||||
/**
|
||||
* Choose some(item) respecting the relative weights, returning none if
|
||||
* the sum of the weights is 0
|
||||
*/
|
||||
fn choose_weighted_option<T:copy>(v: ~[weighted<T>]) -> option<T> {
|
||||
let mut total = 0u;
|
||||
for v.each |item| {
|
||||
|
|
@ -198,8 +208,10 @@ impl extensions for rng {
|
|||
unreachable();
|
||||
}
|
||||
|
||||
#[doc = "Return a vec containing copies of the items, in order, where \
|
||||
the weight of the item determines how many copies there are"]
|
||||
/**
|
||||
* Return a vec containing copies of the items, in order, where
|
||||
* the weight of the item determines how many copies there are
|
||||
*/
|
||||
fn weighted_vec<T:copy>(v: ~[weighted<T>]) -> ~[T] {
|
||||
let mut r = ~[];
|
||||
for v.each |item| {
|
||||
|
|
@ -210,14 +222,14 @@ impl extensions for rng {
|
|||
r
|
||||
}
|
||||
|
||||
#[doc = "Shuffle a vec"]
|
||||
/// Shuffle a vec
|
||||
fn shuffle<T:copy>(values: ~[T]) -> ~[T] {
|
||||
let mut m = vec::to_mut(values);
|
||||
self.shuffle_mut(m);
|
||||
ret vec::from_mut(m);
|
||||
}
|
||||
|
||||
#[doc = "Shuffle a mutable vec in place"]
|
||||
/// Shuffle a mutable vec in place
|
||||
fn shuffle_mut<T>(&&values: ~[mut T]) {
|
||||
let mut i = values.len();
|
||||
while i >= 2u {
|
||||
|
|
@ -240,20 +252,22 @@ impl of rng for @rand_res {
|
|||
fn next() -> u32 { ret rustrt::rand_next((*self).c); }
|
||||
}
|
||||
|
||||
#[doc = "Create a new random seed for seeded_rng"]
|
||||
/// Create a new random seed for seeded_rng
|
||||
fn seed() -> ~[u8] {
|
||||
rustrt::rand_seed()
|
||||
}
|
||||
|
||||
#[doc = "Create a random number generator with a system specified seed"]
|
||||
/// Create a random number generator with a system specified seed
|
||||
fn rng() -> rng {
|
||||
@rand_res(rustrt::rand_new()) as rng
|
||||
}
|
||||
|
||||
#[doc = "Create a random number generator using the specified seed. A \
|
||||
generator constructed with a given seed will generate the same \
|
||||
sequence of values as all other generators constructed with the \
|
||||
same seed. The seed may be any length."]
|
||||
/**
|
||||
* Create a random number generator using the specified seed. A generator
|
||||
* constructed with a given seed will generate the same sequence of values as
|
||||
* all other generators constructed with the same seed. The seed may be any
|
||||
* length.
|
||||
*/
|
||||
fn seeded_rng(seed: ~[u8]) -> rng {
|
||||
@rand_res(rustrt::rand_new_seeded(seed)) as rng
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
#[doc = "A type representing either success or failure"];
|
||||
//! A type representing either success or failure
|
||||
|
||||
import either::either;
|
||||
|
||||
#[doc = "The result type"]
|
||||
/// The result type
|
||||
enum result<T, U> {
|
||||
#[doc = "Contains the successful result value"]
|
||||
/// Contains the successful result value
|
||||
ok(T),
|
||||
#[doc = "Contains the error value"]
|
||||
/// Contains the error value
|
||||
err(U)
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Get the value out of a successful result
|
||||
|
||||
# Failure
|
||||
|
||||
If the result is an error
|
||||
"]
|
||||
/**
|
||||
* Get the value out of a successful result
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* If the result is an error
|
||||
*/
|
||||
pure fn get<T: copy, U>(res: result<T, U>) -> T {
|
||||
alt res {
|
||||
ok(t) { t }
|
||||
|
|
@ -26,13 +26,13 @@ pure fn get<T: copy, U>(res: result<T, U>) -> T {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Get the value out of an error result
|
||||
|
||||
# Failure
|
||||
|
||||
If the result is not an error
|
||||
"]
|
||||
/**
|
||||
* Get the value out of an error result
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* If the result is not an error
|
||||
*/
|
||||
pure fn get_err<T, U: copy>(res: result<T, U>) -> U {
|
||||
alt res {
|
||||
err(u) { u }
|
||||
|
|
@ -42,7 +42,7 @@ pure fn get_err<T, U: copy>(res: result<T, U>) -> U {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Returns true if the result is `ok`"]
|
||||
/// Returns true if the result is `ok`
|
||||
pure fn is_ok<T, U>(res: result<T, U>) -> bool {
|
||||
alt res {
|
||||
ok(_) { true }
|
||||
|
|
@ -50,17 +50,17 @@ pure fn is_ok<T, U>(res: result<T, U>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Returns true if the result is `err`"]
|
||||
/// Returns true if the result is `err`
|
||||
pure fn is_err<T, U>(res: result<T, U>) -> bool {
|
||||
!is_ok(res)
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Convert to the `either` type
|
||||
|
||||
`ok` result variants are converted to `either::right` variants, `err`
|
||||
result variants are converted to `either::left`.
|
||||
"]
|
||||
/**
|
||||
* Convert to the `either` type
|
||||
*
|
||||
* `ok` result variants are converted to `either::right` variants, `err`
|
||||
* result variants are converted to `either::left`.
|
||||
*/
|
||||
pure fn to_either<T: copy, U: copy>(res: result<U, T>) -> either<T, U> {
|
||||
alt res {
|
||||
ok(res) { either::right(res) }
|
||||
|
|
@ -68,19 +68,20 @@ pure fn to_either<T: copy, U: copy>(res: result<U, T>) -> either<T, U> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Call a function based on a previous result
|
||||
|
||||
If `res` is `ok` then the value is extracted and passed to `op` whereupon
|
||||
`op`s result is returned. if `res` is `err` then it is immediately returned.
|
||||
This function can be used to compose the results of two functions.
|
||||
|
||||
Example:
|
||||
|
||||
let res = chain(read_file(file)) { |buf|
|
||||
ok(parse_buf(buf))
|
||||
}
|
||||
"]
|
||||
/**
|
||||
* Call a function based on a previous result
|
||||
*
|
||||
* If `res` is `ok` then the value is extracted and passed to `op` whereupon
|
||||
* `op`s result is returned. if `res` is `err` then it is immediately
|
||||
* returned. This function can be used to compose the results of two
|
||||
* functions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* let res = chain(read_file(file)) { |buf|
|
||||
* ok(parse_buf(buf))
|
||||
* }
|
||||
*/
|
||||
fn chain<T, U: copy, V: copy>(res: result<T, V>, op: fn(T) -> result<U, V>)
|
||||
-> result<U, V> {
|
||||
alt res {
|
||||
|
|
@ -89,14 +90,14 @@ fn chain<T, U: copy, V: copy>(res: result<T, V>, op: fn(T) -> result<U, V>)
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Call a function based on a previous result
|
||||
|
||||
If `res` is `err` then the value is extracted and passed to `op`
|
||||
whereupon `op`s result is returned. if `res` is `ok` then it is
|
||||
immediately returned. This function can be used to pass through a
|
||||
successful result while handling an error.
|
||||
"]
|
||||
/**
|
||||
* Call a function based on a previous result
|
||||
*
|
||||
* If `res` is `err` then the value is extracted and passed to `op`
|
||||
* whereupon `op`s result is returned. if `res` is `ok` then it is
|
||||
* immediately returned. This function can be used to pass through a
|
||||
* successful result while handling an error.
|
||||
*/
|
||||
fn chain_err<T: copy, U: copy, V: copy>(
|
||||
res: result<T, V>,
|
||||
op: fn(V) -> result<T, U>)
|
||||
|
|
@ -107,19 +108,20 @@ fn chain_err<T: copy, U: copy, V: copy>(
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Call a function based on a previous result
|
||||
|
||||
If `res` is `ok` then the value is extracted and passed to `op` whereupon
|
||||
`op`s result is returned. if `res` is `err` then it is immediately returned.
|
||||
This function can be used to compose the results of two functions.
|
||||
|
||||
Example:
|
||||
|
||||
iter(read_file(file)) { |buf|
|
||||
print_buf(buf)
|
||||
}
|
||||
"]
|
||||
/**
|
||||
* Call a function based on a previous result
|
||||
*
|
||||
* If `res` is `ok` then the value is extracted and passed to `op` whereupon
|
||||
* `op`s result is returned. if `res` is `err` then it is immediately
|
||||
* returned. This function can be used to compose the results of two
|
||||
* functions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* iter(read_file(file)) { |buf|
|
||||
* print_buf(buf)
|
||||
* }
|
||||
*/
|
||||
fn iter<T, E>(res: result<T, E>, f: fn(T)) {
|
||||
alt res {
|
||||
ok(t) { f(t) }
|
||||
|
|
@ -127,14 +129,14 @@ fn iter<T, E>(res: result<T, E>, f: fn(T)) {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Call a function based on a previous result
|
||||
|
||||
If `res` is `err` then the value is extracted and passed to `op` whereupon
|
||||
`op`s result is returned. if `res` is `ok` then it is immediately returned.
|
||||
This function can be used to pass through a successful result while handling
|
||||
an error.
|
||||
"]
|
||||
/**
|
||||
* Call a function based on a previous result
|
||||
*
|
||||
* If `res` is `err` then the value is extracted and passed to `op` whereupon
|
||||
* `op`s result is returned. if `res` is `ok` then it is immediately returned.
|
||||
* This function can be used to pass through a successful result while
|
||||
* handling an error.
|
||||
*/
|
||||
fn iter_err<T, E>(res: result<T, E>, f: fn(E)) {
|
||||
alt res {
|
||||
ok(_) { }
|
||||
|
|
@ -142,20 +144,20 @@ fn iter_err<T, E>(res: result<T, E>, f: fn(E)) {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Call a function based on a previous result
|
||||
|
||||
If `res` is `ok` then the value is extracted and passed to `op` whereupon
|
||||
`op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
|
||||
immediately returned. This function can be used to compose the results of two
|
||||
functions.
|
||||
|
||||
Example:
|
||||
|
||||
let res = map(read_file(file)) { |buf|
|
||||
parse_buf(buf)
|
||||
}
|
||||
"]
|
||||
/**
|
||||
* Call a function based on a previous result
|
||||
*
|
||||
* If `res` is `ok` then the value is extracted and passed to `op` whereupon
|
||||
* `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
|
||||
* immediately returned. This function can be used to compose the results of
|
||||
* two functions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* let res = map(read_file(file)) { |buf|
|
||||
* parse_buf(buf)
|
||||
* }
|
||||
*/
|
||||
fn map<T, E: copy, U: copy>(res: result<T, E>, op: fn(T) -> U)
|
||||
-> result<U, E> {
|
||||
alt res {
|
||||
|
|
@ -164,14 +166,14 @@ fn map<T, E: copy, U: copy>(res: result<T, E>, op: fn(T) -> U)
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Call a function based on a previous result
|
||||
|
||||
If `res` is `err` then the value is extracted and passed to `op` whereupon
|
||||
`op`s result is wrapped in an `err` and returned. if `res` is `ok` then it is
|
||||
immediately returned. This function can be used to pass through a successful
|
||||
result while handling an error.
|
||||
"]
|
||||
/**
|
||||
* Call a function based on a previous result
|
||||
*
|
||||
* If `res` is `err` then the value is extracted and passed to `op` whereupon
|
||||
* `op`s result is wrapped in an `err` and returned. if `res` is `ok` then it
|
||||
* is immediately returned. This function can be used to pass through a
|
||||
* successful result while handling an error.
|
||||
*/
|
||||
fn map_err<T: copy, E, F: copy>(res: result<T, E>, op: fn(E) -> F)
|
||||
-> result<T, F> {
|
||||
alt res {
|
||||
|
|
@ -232,23 +234,23 @@ impl extensions<T:copy, E:copy> for result<T,E> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Maps each element in the vector `ts` using the operation `op`. Should an
|
||||
error occur, no further mappings are performed and the error is returned.
|
||||
Should no error occur, a vector containing the result of each map is
|
||||
returned.
|
||||
|
||||
Here is an example which increments every integer in a vector,
|
||||
checking for overflow:
|
||||
|
||||
fn inc_conditionally(x: uint) -> result<uint,str> {
|
||||
if x == uint::max_value { ret err(\"overflow\"); }
|
||||
else { ret ok(x+1u); }
|
||||
}
|
||||
map([1u, 2u, 3u]/~, inc_conditionally).chain {|incd|
|
||||
assert incd == [2u, 3u, 4u]/~;
|
||||
}
|
||||
"]
|
||||
/**
|
||||
* Maps each element in the vector `ts` using the operation `op`. Should an
|
||||
* error occur, no further mappings are performed and the error is returned.
|
||||
* Should no error occur, a vector containing the result of each map is
|
||||
* returned.
|
||||
*
|
||||
* Here is an example which increments every integer in a vector,
|
||||
* checking for overflow:
|
||||
*
|
||||
* fn inc_conditionally(x: uint) -> result<uint,str> {
|
||||
* if x == uint::max_value { ret err("overflow"); }
|
||||
* else { ret ok(x+1u); }
|
||||
* }
|
||||
* map([1u, 2u, 3u]/~, inc_conditionally).chain {|incd|
|
||||
* assert incd == [2u, 3u, 4u]/~;
|
||||
* }
|
||||
*/
|
||||
fn map_vec<T,U:copy,V:copy>(
|
||||
ts: ~[T], op: fn(T) -> result<V,U>) -> result<~[V],U> {
|
||||
|
||||
|
|
@ -277,13 +279,15 @@ fn map_opt<T,U:copy,V:copy>(
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Same as map, but it operates over two parallel vectors.
|
||||
|
||||
A precondition is used here to ensure that the vectors are the same
|
||||
length. While we do not often use preconditions in the standard
|
||||
library, a precondition is used here because result::t is generally
|
||||
used in 'careful' code contexts where it is both appropriate and easy
|
||||
to accommodate an error like the vectors being of different lengths."]
|
||||
/**
|
||||
* Same as map, but it operates over two parallel vectors.
|
||||
*
|
||||
* A precondition is used here to ensure that the vectors are the same
|
||||
* length. While we do not often use preconditions in the standard
|
||||
* library, a precondition is used here because result::t is generally
|
||||
* used in 'careful' code contexts where it is both appropriate and easy
|
||||
* to accommodate an error like the vectors being of different lengths.
|
||||
*/
|
||||
fn map_vec2<S,T,U:copy,V:copy>(ss: ~[S], ts: ~[T],
|
||||
op: fn(S,T) -> result<V,U>)
|
||||
: vec::same_length(ss, ts) -> result<~[V],U> {
|
||||
|
|
@ -302,11 +306,11 @@ fn map_vec2<S,T,U:copy,V:copy>(ss: ~[S], ts: ~[T],
|
|||
ret ok(vs);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Applies op to the pairwise elements from `ss` and `ts`, aborting on
|
||||
error. This could be implemented using `map2()` but it is more efficient
|
||||
on its own as no result vector is built.
|
||||
"]
|
||||
/**
|
||||
* Applies op to the pairwise elements from `ss` and `ts`, aborting on
|
||||
* error. This could be implemented using `map2()` but it is more efficient
|
||||
* on its own as no result vector is built.
|
||||
*/
|
||||
fn iter_vec2<S,T,U:copy>(ss: ~[S], ts: ~[T],
|
||||
op: fn(S,T) -> result<(),U>)
|
||||
: vec::same_length(ss, ts)
|
||||
|
|
@ -324,9 +328,7 @@ fn iter_vec2<S,T,U:copy>(ss: ~[S], ts: ~[T],
|
|||
ret ok(());
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Unwraps a result, assuming it is an `ok(T)`
|
||||
"]
|
||||
/// Unwraps a result, assuming it is an `ok(T)`
|
||||
fn unwrap<T, U>(-res: result<T, U>) -> T {
|
||||
unsafe {
|
||||
let addr = alt res {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc ="Process spawning"];
|
||||
//! Process spawning
|
||||
import option::{some, none};
|
||||
import libc::{pid_t, c_void, c_int};
|
||||
|
||||
|
|
@ -17,51 +17,51 @@ extern mod rustrt {
|
|||
-> pid_t;
|
||||
}
|
||||
|
||||
#[doc ="A value representing a child process"]
|
||||
/// A value representing a child process
|
||||
iface program {
|
||||
#[doc ="Returns the process id of the program"]
|
||||
/// Returns the process id of the program
|
||||
fn get_id() -> pid_t;
|
||||
|
||||
#[doc ="Returns an io::writer that can be used to write to stdin"]
|
||||
/// Returns an io::writer that can be used to write to stdin
|
||||
fn input() -> io::writer;
|
||||
|
||||
#[doc ="Returns an io::reader that can be used to read from stdout"]
|
||||
/// Returns an io::reader that can be used to read from stdout
|
||||
fn output() -> io::reader;
|
||||
|
||||
#[doc ="Returns an io::reader that can be used to read from stderr"]
|
||||
/// Returns an io::reader that can be used to read from stderr
|
||||
fn err() -> io::reader;
|
||||
|
||||
#[doc = "Closes the handle to the child processes standard input"]
|
||||
/// Closes the handle to the child processes standard input
|
||||
fn close_input();
|
||||
|
||||
#[doc = "
|
||||
Waits for the child process to terminate. Closes the handle
|
||||
to stdin if necessary.
|
||||
"]
|
||||
/**
|
||||
* Waits for the child process to terminate. Closes the handle
|
||||
* to stdin if necessary.
|
||||
*/
|
||||
fn finish() -> int;
|
||||
|
||||
#[doc ="Closes open handles"]
|
||||
/// Closes open handles
|
||||
fn destroy();
|
||||
}
|
||||
|
||||
|
||||
#[doc = "
|
||||
Run a program, providing stdin, stdout and stderr handles
|
||||
|
||||
# Arguments
|
||||
|
||||
* prog - The path to an executable
|
||||
* args - Vector of arguments to pass to the child process
|
||||
* env - optional env-modification for child
|
||||
* dir - optional dir to run child in (default current dir)
|
||||
* in_fd - A file descriptor for the child to use as std input
|
||||
* out_fd - A file descriptor for the child to use as std output
|
||||
* err_fd - A file descriptor for the child to use as std error
|
||||
|
||||
# Return value
|
||||
|
||||
The process id of the spawned process
|
||||
"]
|
||||
/**
|
||||
* Run a program, providing stdin, stdout and stderr handles
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * prog - The path to an executable
|
||||
* * args - Vector of arguments to pass to the child process
|
||||
* * env - optional env-modification for child
|
||||
* * dir - optional dir to run child in (default current dir)
|
||||
* * in_fd - A file descriptor for the child to use as std input
|
||||
* * out_fd - A file descriptor for the child to use as std output
|
||||
* * err_fd - A file descriptor for the child to use as std error
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* The process id of the spawned process
|
||||
*/
|
||||
fn spawn_process(prog: str, args: ~[str],
|
||||
env: option<~[(str,str)]>,
|
||||
dir: option<str>,
|
||||
|
|
@ -152,18 +152,18 @@ fn with_dirp<T>(d: option<str>,
|
|||
}
|
||||
}
|
||||
|
||||
#[doc ="
|
||||
Spawns a process and waits for it to terminate
|
||||
|
||||
# Arguments
|
||||
|
||||
* prog - The path to an executable
|
||||
* args - Vector of arguments to pass to the child process
|
||||
|
||||
# Return value
|
||||
|
||||
The process id
|
||||
"]
|
||||
/**
|
||||
* Spawns a process and waits for it to terminate
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * prog - The path to an executable
|
||||
* * args - Vector of arguments to pass to the child process
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* The process id
|
||||
*/
|
||||
fn run_program(prog: str, args: ~[str]) -> int {
|
||||
let pid = spawn_process(prog, args, none, none,
|
||||
0i32, 0i32, 0i32);
|
||||
|
|
@ -171,22 +171,22 @@ fn run_program(prog: str, args: ~[str]) -> int {
|
|||
ret waitpid(pid);
|
||||
}
|
||||
|
||||
#[doc ="
|
||||
Spawns a process and returns a program
|
||||
|
||||
The returned value is a boxed class containing a <program> object that can
|
||||
be used for sending and receiving data over the standard file descriptors.
|
||||
The class will ensure that file descriptors are closed properly.
|
||||
|
||||
# Arguments
|
||||
|
||||
* prog - The path to an executable
|
||||
* args - Vector of arguments to pass to the child process
|
||||
|
||||
# Return value
|
||||
|
||||
A class with a <program> field
|
||||
"]
|
||||
/**
|
||||
* Spawns a process and returns a program
|
||||
*
|
||||
* The returned value is a boxed class containing a <program> object that can
|
||||
* be used for sending and receiving data over the standard file descriptors.
|
||||
* The class will ensure that file descriptors are closed properly.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * prog - The path to an executable
|
||||
* * args - Vector of arguments to pass to the child process
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* A class with a <program> field
|
||||
*/
|
||||
fn start_program(prog: str, args: ~[str]) -> program {
|
||||
let pipe_input = os::pipe();
|
||||
let pipe_output = os::pipe();
|
||||
|
|
@ -257,20 +257,20 @@ fn read_all(rd: io::reader) -> str {
|
|||
ret buf;
|
||||
}
|
||||
|
||||
#[doc ="
|
||||
Spawns a process, waits for it to exit, and returns the exit code, and
|
||||
contents of stdout and stderr.
|
||||
|
||||
# Arguments
|
||||
|
||||
* prog - The path to an executable
|
||||
* args - Vector of arguments to pass to the child process
|
||||
|
||||
# Return value
|
||||
|
||||
A record, {status: int, out: str, err: str} containing the exit code,
|
||||
the contents of stdout and the contents of stderr.
|
||||
"]
|
||||
/**
|
||||
* Spawns a process, waits for it to exit, and returns the exit code, and
|
||||
* contents of stdout and stderr.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * prog - The path to an executable
|
||||
* * args - Vector of arguments to pass to the child process
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* A record, {status: int, out: str, err: str} containing the exit code,
|
||||
* the contents of stdout and the contents of stderr.
|
||||
*/
|
||||
fn program_output(prog: str, args: ~[str]) ->
|
||||
{status: int, out: str, err: str} {
|
||||
|
||||
|
|
@ -347,7 +347,7 @@ fn readclose(fd: c_int) -> str {
|
|||
ret buf;
|
||||
}
|
||||
|
||||
#[doc ="Waits for a process to exit and returns the exit code"]
|
||||
/// Waits for a process to exit and returns the exit code
|
||||
fn waitpid(pid: pid_t) -> int {
|
||||
ret waitpid_os(pid);
|
||||
|
||||
|
|
|
|||
1511
src/libcore/str.rs
1511
src/libcore/str.rs
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Misc low level stuff"];
|
||||
//! Misc low level stuff
|
||||
|
||||
export type_desc;
|
||||
export get_type_desc;
|
||||
|
|
@ -39,38 +39,38 @@ extern mod rusti {
|
|||
fn min_align_of<T>() -> uint;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns a pointer to a type descriptor.
|
||||
|
||||
Useful for calling certain function in the Rust runtime or otherwise
|
||||
performing dark magick.
|
||||
"]
|
||||
/**
|
||||
* Returns a pointer to a type descriptor.
|
||||
*
|
||||
* Useful for calling certain function in the Rust runtime or otherwise
|
||||
* performing dark magick.
|
||||
*/
|
||||
pure fn get_type_desc<T>() -> *type_desc {
|
||||
unchecked { rusti::get_tydesc::<T>() as *type_desc }
|
||||
}
|
||||
|
||||
#[doc = "Returns the size of a type"]
|
||||
/// Returns the size of a type
|
||||
#[inline(always)]
|
||||
pure fn size_of<T>() -> uint {
|
||||
unchecked { rusti::size_of::<T>() }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns the ABI-required minimum alignment of a type
|
||||
|
||||
This is the alignment used for struct fields. It may be smaller
|
||||
than the preferred alignment.
|
||||
"]
|
||||
/**
|
||||
* Returns the ABI-required minimum alignment of a type
|
||||
*
|
||||
* This is the alignment used for struct fields. It may be smaller
|
||||
* than the preferred alignment.
|
||||
*/
|
||||
pure fn min_align_of<T>() -> uint {
|
||||
unchecked { rusti::min_align_of::<T>() }
|
||||
}
|
||||
|
||||
#[doc = "Returns the preferred alignment of a type"]
|
||||
/// Returns the preferred alignment of a type
|
||||
pure fn pref_align_of<T>() -> uint {
|
||||
unchecked { rusti::pref_align_of::<T>() }
|
||||
}
|
||||
|
||||
#[doc = "Returns the refcount of a shared box (as just before calling this)"]
|
||||
/// Returns the refcount of a shared box (as just before calling this)
|
||||
pure fn refcount<T>(+t: @T) -> uint {
|
||||
unsafe {
|
||||
let ref_ptr: *uint = unsafe::reinterpret_cast(t);
|
||||
|
|
|
|||
|
|
@ -1,26 +1,27 @@
|
|||
#[doc = "
|
||||
Task management.
|
||||
|
||||
An executing Rust program consists of a tree of tasks, each with their own
|
||||
stack, and sole ownership of their allocated heap data. Tasks communicate
|
||||
with each other using ports and channels.
|
||||
|
||||
When a task fails, that failure will propagate to its parent (the task
|
||||
that spawned it) and the parent will fail as well. The reverse is not
|
||||
true: when a parent task fails its children will continue executing. When
|
||||
the root (main) task fails, all tasks fail, and then so does the entire
|
||||
process.
|
||||
|
||||
Tasks may execute in parallel and are scheduled automatically by the runtime.
|
||||
|
||||
# Example
|
||||
|
||||
~~~
|
||||
spawn {||
|
||||
log(error, \"Hello, World!\");
|
||||
}
|
||||
~~~
|
||||
"];
|
||||
/*!
|
||||
* Task management.
|
||||
*
|
||||
* An executing Rust program consists of a tree of tasks, each with their own
|
||||
* stack, and sole ownership of their allocated heap data. Tasks communicate
|
||||
* with each other using ports and channels.
|
||||
*
|
||||
* When a task fails, that failure will propagate to its parent (the task
|
||||
* that spawned it) and the parent will fail as well. The reverse is not
|
||||
* true: when a parent task fails its children will continue executing. When
|
||||
* the root (main) task fails, all tasks fail, and then so does the entire
|
||||
* process.
|
||||
*
|
||||
* Tasks may execute in parallel and are scheduled automatically by the
|
||||
* runtime.
|
||||
*
|
||||
* # Example
|
||||
*
|
||||
* ~~~
|
||||
* spawn {||
|
||||
* log(error, "Hello, World!");
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
|
||||
import result::result;
|
||||
import dvec::extensions;
|
||||
|
|
@ -63,106 +64,106 @@ export local_data_modify;
|
|||
|
||||
/* Data types */
|
||||
|
||||
#[doc = "A handle to a task"]
|
||||
/// A handle to a task
|
||||
enum task = task_id;
|
||||
|
||||
#[doc = "
|
||||
Indicates the manner in which a task exited.
|
||||
|
||||
A task that completes without failing and whose supervised children complete
|
||||
without failing is considered to exit successfully.
|
||||
|
||||
FIXME (See #1868): This description does not indicate the current behavior
|
||||
for linked failure.
|
||||
"]
|
||||
/**
|
||||
* Indicates the manner in which a task exited.
|
||||
*
|
||||
* A task that completes without failing and whose supervised children
|
||||
* complete without failing is considered to exit successfully.
|
||||
*
|
||||
* FIXME (See #1868): This description does not indicate the current behavior
|
||||
* for linked failure.
|
||||
*/
|
||||
enum task_result {
|
||||
success,
|
||||
failure,
|
||||
}
|
||||
|
||||
#[doc = "A message type for notifying of task lifecycle events"]
|
||||
/// A message type for notifying of task lifecycle events
|
||||
enum notification {
|
||||
#[doc = "Sent when a task exits with the task handle and result"]
|
||||
/// Sent when a task exits with the task handle and result
|
||||
exit(task, task_result)
|
||||
}
|
||||
|
||||
#[doc = "Scheduler modes"]
|
||||
/// Scheduler modes
|
||||
enum sched_mode {
|
||||
#[doc = "1:N -- All tasks run in the same OS thread"]
|
||||
/// All tasks run in the same OS thread
|
||||
single_threaded,
|
||||
#[doc = "M:N -- Tasks are distributed among available CPUs"]
|
||||
/// Tasks are distributed among available CPUs
|
||||
thread_per_core,
|
||||
#[doc = "N:N -- Each task runs in its own OS thread"]
|
||||
/// Each task runs in its own OS thread
|
||||
thread_per_task,
|
||||
#[doc = "?:N -- Tasks are distributed among a fixed number of OS threads"]
|
||||
/// Tasks are distributed among a fixed number of OS threads
|
||||
manual_threads(uint),
|
||||
#[doc = "
|
||||
Tasks are scheduled on the main OS thread
|
||||
|
||||
The main OS thread is the thread used to launch the runtime which,
|
||||
in most cases, is the process's initial thread as created by the OS.
|
||||
"]
|
||||
/**
|
||||
* Tasks are scheduled on the main OS thread
|
||||
*
|
||||
* The main OS thread is the thread used to launch the runtime which,
|
||||
* in most cases, is the process's initial thread as created by the OS.
|
||||
*/
|
||||
osmain
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Scheduler configuration options
|
||||
|
||||
# Fields
|
||||
|
||||
* sched_mode - The operating mode of the scheduler
|
||||
|
||||
* foreign_stack_size - The size of the foreign stack, in bytes
|
||||
|
||||
Rust code runs on Rust-specific stacks. When Rust code calls foreign code
|
||||
(via functions in foreign modules) it switches to a typical, large stack
|
||||
appropriate for running code written in languages like C. By default these
|
||||
foreign stacks have unspecified size, but with this option their size can
|
||||
be precisely specified.
|
||||
"]
|
||||
/**
|
||||
* Scheduler configuration options
|
||||
*
|
||||
* # Fields
|
||||
*
|
||||
* * sched_mode - The operating mode of the scheduler
|
||||
*
|
||||
* * foreign_stack_size - The size of the foreign stack, in bytes
|
||||
*
|
||||
* Rust code runs on Rust-specific stacks. When Rust code calls foreign
|
||||
* code (via functions in foreign modules) it switches to a typical, large
|
||||
* stack appropriate for running code written in languages like C. By
|
||||
* default these foreign stacks have unspecified size, but with this
|
||||
* option their size can be precisely specified.
|
||||
*/
|
||||
type sched_opts = {
|
||||
mode: sched_mode,
|
||||
foreign_stack_size: option<uint>
|
||||
};
|
||||
|
||||
#[doc = "
|
||||
Task configuration options
|
||||
|
||||
# Fields
|
||||
|
||||
* supervise - Do not propagate failure to the parent task
|
||||
|
||||
All tasks are linked together via a tree, from parents to children. By
|
||||
default children are 'supervised' by their parent and when they fail
|
||||
so too will their parents. Settings this flag to false disables that
|
||||
behavior.
|
||||
|
||||
* notify_chan - Enable lifecycle notifications on the given channel
|
||||
|
||||
* sched - Specify the configuration of a new scheduler to create the task in
|
||||
|
||||
By default, every task is created in the same scheduler as its
|
||||
parent, where it is scheduled cooperatively with all other tasks
|
||||
in that scheduler. Some specialized applications may want more
|
||||
control over their scheduling, in which case they can be spawned
|
||||
into a new scheduler with the specific properties required.
|
||||
|
||||
This is of particular importance for libraries which want to call
|
||||
into foreign code that blocks. Without doing so in a different
|
||||
scheduler other tasks will be impeded or even blocked indefinitely.
|
||||
|
||||
"]
|
||||
/**
|
||||
* Task configuration options
|
||||
*
|
||||
* # Fields
|
||||
*
|
||||
* * supervise - Do not propagate failure to the parent task
|
||||
*
|
||||
* All tasks are linked together via a tree, from parents to children. By
|
||||
* default children are 'supervised' by their parent and when they fail
|
||||
* so too will their parents. Settings this flag to false disables that
|
||||
* behavior.
|
||||
*
|
||||
* * notify_chan - Enable lifecycle notifications on the given channel
|
||||
*
|
||||
* * sched - Specify the configuration of a new scheduler to create the task
|
||||
* in
|
||||
*
|
||||
* By default, every task is created in the same scheduler as its
|
||||
* parent, where it is scheduled cooperatively with all other tasks
|
||||
* in that scheduler. Some specialized applications may want more
|
||||
* control over their scheduling, in which case they can be spawned
|
||||
* into a new scheduler with the specific properties required.
|
||||
*
|
||||
* This is of particular importance for libraries which want to call
|
||||
* into foreign code that blocks. Without doing so in a different
|
||||
* scheduler other tasks will be impeded or even blocked indefinitely.
|
||||
*/
|
||||
type task_opts = {
|
||||
supervise: bool,
|
||||
notify_chan: option<comm::chan<notification>>,
|
||||
sched: option<sched_opts>,
|
||||
};
|
||||
|
||||
#[doc = "
|
||||
The task builder type.
|
||||
|
||||
Provides detailed control over the properties and behavior of new tasks.
|
||||
"]
|
||||
/**
|
||||
* The task builder type.
|
||||
*
|
||||
* Provides detailed control over the properties and behavior of new tasks.
|
||||
*/
|
||||
// NB: Builders are designed to be single-use because they do stateful
|
||||
// things that get weird when reusing - e.g. if you create a result future
|
||||
// it only applies to a single task, so then you have to maintain some
|
||||
|
|
@ -182,12 +183,12 @@ enum builder {
|
|||
/* Task construction */
|
||||
|
||||
fn default_task_opts() -> task_opts {
|
||||
#[doc = "
|
||||
The default task options
|
||||
|
||||
By default all tasks are supervised by their parent, are spawned
|
||||
into the same scheduler, and do not post lifecycle notifications.
|
||||
"];
|
||||
/*!
|
||||
* The default task options
|
||||
*
|
||||
* By default all tasks are supervised by their parent, are spawned
|
||||
* into the same scheduler, and do not post lifecycle notifications.
|
||||
*/
|
||||
|
||||
{
|
||||
supervise: true,
|
||||
|
|
@ -197,7 +198,7 @@ fn default_task_opts() -> task_opts {
|
|||
}
|
||||
|
||||
fn builder() -> builder {
|
||||
#[doc = "Construct a builder"];
|
||||
//! Construct a builder
|
||||
|
||||
let body_identity = fn@(+body: fn~()) -> fn~() { body };
|
||||
|
||||
|
|
@ -209,39 +210,39 @@ fn builder() -> builder {
|
|||
}
|
||||
|
||||
fn get_opts(builder: builder) -> task_opts {
|
||||
#[doc = "Get the task_opts associated with a builder"];
|
||||
//! Get the task_opts associated with a builder
|
||||
|
||||
builder.opts
|
||||
}
|
||||
|
||||
fn set_opts(builder: builder, opts: task_opts) {
|
||||
#[doc = "
|
||||
Set the task_opts associated with a builder
|
||||
|
||||
To update a single option use a pattern like the following:
|
||||
|
||||
set_opts(builder, {
|
||||
supervise: false
|
||||
with get_opts(builder)
|
||||
});
|
||||
"];
|
||||
/*!
|
||||
* Set the task_opts associated with a builder
|
||||
*
|
||||
* To update a single option use a pattern like the following:
|
||||
*
|
||||
* set_opts(builder, {
|
||||
* supervise: false
|
||||
* with get_opts(builder)
|
||||
* });
|
||||
*/
|
||||
|
||||
builder.opts = opts;
|
||||
}
|
||||
|
||||
fn add_wrapper(builder: builder, gen_body: fn@(+fn~()) -> fn~()) {
|
||||
#[doc = "
|
||||
Add a wrapper to the body of the spawned task.
|
||||
|
||||
Before the task is spawned it is passed through a 'body generator'
|
||||
function that may perform local setup operations as well as wrap
|
||||
the task body in remote setup operations. With this the behavior
|
||||
of tasks can be extended in simple ways.
|
||||
|
||||
This function augments the current body generator with a new body
|
||||
generator by applying the task body which results from the
|
||||
existing body generator to the new body generator.
|
||||
"];
|
||||
/*!
|
||||
* Add a wrapper to the body of the spawned task.
|
||||
*
|
||||
* Before the task is spawned it is passed through a 'body generator'
|
||||
* function that may perform local setup operations as well as wrap
|
||||
* the task body in remote setup operations. With this the behavior
|
||||
* of tasks can be extended in simple ways.
|
||||
*
|
||||
* This function augments the current body generator with a new body
|
||||
* generator by applying the task body which results from the
|
||||
* existing body generator to the new body generator.
|
||||
*/
|
||||
|
||||
let prev_gen_body = builder.gen_body;
|
||||
builder.gen_body = fn@(+body: fn~()) -> fn~() {
|
||||
|
|
@ -250,18 +251,18 @@ fn add_wrapper(builder: builder, gen_body: fn@(+fn~()) -> fn~()) {
|
|||
}
|
||||
|
||||
fn run(-builder: builder, +f: fn~()) {
|
||||
#[doc = "
|
||||
Creates and exucutes a new child task
|
||||
|
||||
Sets up a new task with its own call stack and schedules it to run
|
||||
the provided unique closure. The task has the properties and behavior
|
||||
specified by `builder`.
|
||||
|
||||
# Failure
|
||||
|
||||
When spawning into a new scheduler, the number of threads requested
|
||||
must be greater than zero.
|
||||
"];
|
||||
/*!
|
||||
* Creates and exucutes a new child task
|
||||
*
|
||||
* Sets up a new task with its own call stack and schedules it to run
|
||||
* the provided unique closure. The task has the properties and behavior
|
||||
* specified by `builder`.
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* When spawning into a new scheduler, the number of threads requested
|
||||
* must be greater than zero.
|
||||
*/
|
||||
|
||||
let body = builder.gen_body(f);
|
||||
spawn_raw(builder.opts, body);
|
||||
|
|
@ -271,17 +272,18 @@ fn run(-builder: builder, +f: fn~()) {
|
|||
/* Builder convenience functions */
|
||||
|
||||
fn future_result(builder: builder) -> future::future<task_result> {
|
||||
#[doc = "
|
||||
Get a future representing the exit status of the task.
|
||||
|
||||
Taking the value of the future will block until the child task terminates.
|
||||
|
||||
Note that the future returning by this function is only useful for
|
||||
obtaining the value of the next task to be spawning with the
|
||||
builder. If additional tasks are spawned with the same builder
|
||||
then a new result future must be obtained prior to spawning each
|
||||
task.
|
||||
"];
|
||||
/*!
|
||||
* Get a future representing the exit status of the task.
|
||||
*
|
||||
* Taking the value of the future will block until the child task
|
||||
* terminates.
|
||||
*
|
||||
* Note that the future returning by this function is only useful for
|
||||
* obtaining the value of the next task to be spawning with the
|
||||
* builder. If additional tasks are spawned with the same builder
|
||||
* then a new result future must be obtained prior to spawning each
|
||||
* task.
|
||||
*/
|
||||
|
||||
// FIXME (#1087, #1857): Once linked failure and notification are
|
||||
// handled in the library, I can imagine implementing this by just
|
||||
|
|
@ -304,7 +306,7 @@ fn future_result(builder: builder) -> future::future<task_result> {
|
|||
}
|
||||
|
||||
fn future_task(builder: builder) -> future::future<task> {
|
||||
#[doc = "Get a future representing the handle to the new task"];
|
||||
//! Get a future representing the handle to the new task
|
||||
|
||||
let mut po = comm::port();
|
||||
let ch = comm::chan(po);
|
||||
|
|
@ -318,7 +320,7 @@ fn future_task(builder: builder) -> future::future<task> {
|
|||
}
|
||||
|
||||
fn unsupervise(builder: builder) {
|
||||
#[doc = "Configures the new task to not propagate failure to its parent"];
|
||||
//! Configures the new task to not propagate failure to its parent
|
||||
|
||||
set_opts(builder, {
|
||||
supervise: false
|
||||
|
|
@ -328,17 +330,17 @@ fn unsupervise(builder: builder) {
|
|||
|
||||
fn run_listener<A:send>(-builder: builder,
|
||||
+f: fn~(comm::port<A>)) -> comm::chan<A> {
|
||||
#[doc = "
|
||||
Runs a new task while providing a channel from the parent to the child
|
||||
|
||||
Sets up a communication channel from the current task to the new
|
||||
child task, passes the port to child's body, and returns a channel
|
||||
linked to the port to the parent.
|
||||
|
||||
This encapsulates some boilerplate handshaking logic that would
|
||||
otherwise be required to establish communication from the parent
|
||||
to the child.
|
||||
"];
|
||||
/*!
|
||||
* Runs a new task while providing a channel from the parent to the child
|
||||
*
|
||||
* Sets up a communication channel from the current task to the new
|
||||
* child task, passes the port to child's body, and returns a channel
|
||||
* linked to the port to the parent.
|
||||
*
|
||||
* This encapsulates some boilerplate handshaking logic that would
|
||||
* otherwise be required to establish communication from the parent
|
||||
* to the child.
|
||||
*/
|
||||
|
||||
let setup_po = comm::port();
|
||||
let setup_ch = comm::chan(setup_po);
|
||||
|
|
@ -357,60 +359,60 @@ fn run_listener<A:send>(-builder: builder,
|
|||
/* Spawn convenience functions */
|
||||
|
||||
fn spawn(+f: fn~()) {
|
||||
#[doc = "
|
||||
Creates and executes a new child task
|
||||
|
||||
Sets up a new task with its own call stack and schedules it to run
|
||||
the provided unique closure.
|
||||
|
||||
This function is equivalent to `run(new_builder(), f)`.
|
||||
"];
|
||||
/*!
|
||||
* Creates and executes a new child task
|
||||
*
|
||||
* Sets up a new task with its own call stack and schedules it to run
|
||||
* the provided unique closure.
|
||||
*
|
||||
* This function is equivalent to `run(new_builder(), f)`.
|
||||
*/
|
||||
|
||||
run(builder(), f);
|
||||
}
|
||||
|
||||
fn spawn_listener<A:send>(+f: fn~(comm::port<A>)) -> comm::chan<A> {
|
||||
#[doc = "
|
||||
Runs a new task while providing a channel from the parent to the child
|
||||
|
||||
Sets up a communication channel from the current task to the new
|
||||
child task, passes the port to child's body, and returns a channel
|
||||
linked to the port to the parent.
|
||||
|
||||
This encapsulates some boilerplate handshaking logic that would
|
||||
otherwise be required to establish communication from the parent
|
||||
to the child.
|
||||
|
||||
The simplest way to establish bidirectional communication between
|
||||
a parent in child is as follows:
|
||||
|
||||
let po = comm::port();
|
||||
let ch = comm::chan(po);
|
||||
let ch = spawn_listener {|po|
|
||||
// Now the child has a port called 'po' to read from and
|
||||
// an environment-captured channel called 'ch'.
|
||||
};
|
||||
// Likewise, the parent has both a 'po' and 'ch'
|
||||
|
||||
This function is equivalent to `run_listener(builder(), f)`.
|
||||
"];
|
||||
/*!
|
||||
* Runs a new task while providing a channel from the parent to the child
|
||||
*
|
||||
* Sets up a communication channel from the current task to the new
|
||||
* child task, passes the port to child's body, and returns a channel
|
||||
* linked to the port to the parent.
|
||||
*
|
||||
* This encapsulates some boilerplate handshaking logic that would
|
||||
* otherwise be required to establish communication from the parent
|
||||
* to the child.
|
||||
*
|
||||
* The simplest way to establish bidirectional communication between
|
||||
* a parent in child is as follows:
|
||||
*
|
||||
* let po = comm::port();
|
||||
* let ch = comm::chan(po);
|
||||
* let ch = spawn_listener {|po|
|
||||
* // Now the child has a port called 'po' to read from and
|
||||
* // an environment-captured channel called 'ch'.
|
||||
* };
|
||||
* // Likewise, the parent has both a 'po' and 'ch'
|
||||
*
|
||||
* This function is equivalent to `run_listener(builder(), f)`.
|
||||
*/
|
||||
|
||||
run_listener(builder(), f)
|
||||
}
|
||||
|
||||
fn spawn_sched(mode: sched_mode, +f: fn~()) {
|
||||
#[doc = "
|
||||
Creates a new scheduler and executes a task on it
|
||||
|
||||
Tasks subsequently spawned by that task will also execute on
|
||||
the new scheduler. When there are no more tasks to execute the
|
||||
scheduler terminates.
|
||||
|
||||
# Failure
|
||||
|
||||
In manual threads mode the number of threads requested must be
|
||||
greater than zero.
|
||||
"];
|
||||
/*!
|
||||
* Creates a new scheduler and executes a task on it
|
||||
*
|
||||
* Tasks subsequently spawned by that task will also execute on
|
||||
* the new scheduler. When there are no more tasks to execute the
|
||||
* scheduler terminates.
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* In manual threads mode the number of threads requested must be
|
||||
* greater than zero.
|
||||
*/
|
||||
|
||||
let mut builder = builder();
|
||||
set_opts(builder, {
|
||||
|
|
@ -424,16 +426,16 @@ fn spawn_sched(mode: sched_mode, +f: fn~()) {
|
|||
}
|
||||
|
||||
fn try<T:send>(+f: fn~() -> T) -> result<T,()> {
|
||||
#[doc = "
|
||||
Execute a function in another task and return either the return value
|
||||
of the function or result::err.
|
||||
|
||||
# Return value
|
||||
|
||||
If the function executed successfully then try returns result::ok
|
||||
containing the value returned by the function. If the function fails
|
||||
then try returns result::err containing nil.
|
||||
"];
|
||||
/*!
|
||||
* Execute a function in another task and return either the return value
|
||||
* of the function or result::err.
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* If the function executed successfully then try returns result::ok
|
||||
* containing the value returned by the function. If the function fails
|
||||
* then try returns result::err containing nil.
|
||||
*/
|
||||
|
||||
let po = comm::port();
|
||||
let ch = comm::chan(po);
|
||||
|
|
@ -453,7 +455,7 @@ fn try<T:send>(+f: fn~() -> T) -> result<T,()> {
|
|||
/* Lifecycle functions */
|
||||
|
||||
fn yield() {
|
||||
#[doc = "Yield control to the task scheduler"];
|
||||
//! Yield control to the task scheduler
|
||||
|
||||
let task_ = rustrt::rust_get_task();
|
||||
let mut killed = false;
|
||||
|
|
@ -464,31 +466,30 @@ fn yield() {
|
|||
}
|
||||
|
||||
fn failing() -> bool {
|
||||
#[doc = "True if the running task has failed"];
|
||||
//! True if the running task has failed
|
||||
|
||||
rustrt::rust_task_is_unwinding(rustrt::rust_get_task())
|
||||
}
|
||||
|
||||
fn get_task() -> task {
|
||||
#[doc = "Get a handle to the running task"];
|
||||
//! Get a handle to the running task
|
||||
|
||||
task(rustrt::get_task_id())
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Temporarily make the task unkillable
|
||||
|
||||
# Example
|
||||
|
||||
task::unkillable {||
|
||||
// detach / yield / destroy must all be called together
|
||||
rustrt::rust_port_detach(po);
|
||||
// This must not result in the current task being killed
|
||||
task::yield();
|
||||
rustrt::rust_port_destroy(po);
|
||||
}
|
||||
|
||||
"]
|
||||
/**
|
||||
* Temporarily make the task unkillable
|
||||
*
|
||||
* # Example
|
||||
*
|
||||
* task::unkillable {||
|
||||
* // detach / yield / destroy must all be called together
|
||||
* rustrt::rust_port_detach(po);
|
||||
* // This must not result in the current task being killed
|
||||
* task::yield();
|
||||
* rustrt::rust_port_destroy(po);
|
||||
* }
|
||||
*/
|
||||
unsafe fn unkillable(f: fn()) {
|
||||
class allow_failure {
|
||||
let i: (); // since a class must have at least one field
|
||||
|
|
@ -596,14 +597,16 @@ fn spawn_raw(opts: task_opts, +f: fn~()) {
|
|||
* Casting 'Arcane Sight' reveals an overwhelming aura of Transmutation magic.
|
||||
****************************************************************************/
|
||||
|
||||
#[doc = "Indexes a task-local data slot. The function itself is used to
|
||||
automatically finalise stored values; also, its code pointer is used for
|
||||
comparison. Recommended use is to write an empty function for each desired
|
||||
task-local data slot (and use class destructors, instead of code inside the
|
||||
finaliser, if specific teardown is needed). DO NOT use multiple instantiations
|
||||
of a single polymorphic function to index data of different types; arbitrary
|
||||
type coercion is possible this way. The interface is safe as long as all key
|
||||
functions are monomorphic."]
|
||||
/**
|
||||
* Indexes a task-local data slot. The function itself is used to
|
||||
* automatically finalise stored values; also, its code pointer is used for
|
||||
* comparison. Recommended use is to write an empty function for each desired
|
||||
* task-local data slot (and use class destructors, instead of code inside the
|
||||
* finaliser, if specific teardown is needed). DO NOT use multiple
|
||||
* instantiations of a single polymorphic function to index data of different
|
||||
* types; arbitrary type coercion is possible this way. The interface is safe
|
||||
* as long as all key functions are monomorphic.
|
||||
*/
|
||||
type local_data_key<T> = fn@(+@T);
|
||||
|
||||
// We use dvec because it's the best data structure in core. If TLS is used
|
||||
|
|
@ -741,23 +744,31 @@ unsafe fn local_modify<T>(task: *rust_task, key: local_data_key<T>,
|
|||
}
|
||||
|
||||
/* Exported interface for task-local data (plus local_data_key above). */
|
||||
#[doc = "Remove a task-local data value from the table, returning the
|
||||
reference that was originally created to insert it."]
|
||||
/**
|
||||
* Remove a task-local data value from the table, returning the
|
||||
* reference that was originally created to insert it.
|
||||
*/
|
||||
unsafe fn local_data_pop<T>(key: local_data_key<T>) -> option<@T> {
|
||||
local_pop(rustrt::rust_get_task(), key)
|
||||
}
|
||||
#[doc = "Retrieve a task-local data value. It will also be kept alive in the
|
||||
table until explicitly removed."]
|
||||
/**
|
||||
* Retrieve a task-local data value. It will also be kept alive in the
|
||||
* table until explicitly removed.
|
||||
*/
|
||||
unsafe fn local_data_get<T>(key: local_data_key<T>) -> option<@T> {
|
||||
local_get(rustrt::rust_get_task(), key)
|
||||
}
|
||||
#[doc = "Store a value in task-local data. If this key already has a value,
|
||||
that value is overwritten (and its destructor is run)."]
|
||||
/**
|
||||
* Store a value in task-local data. If this key already has a value,
|
||||
* that value is overwritten (and its destructor is run).
|
||||
*/
|
||||
unsafe fn local_data_set<T>(key: local_data_key<T>, -data: @T) {
|
||||
local_set(rustrt::rust_get_task(), key, data)
|
||||
}
|
||||
#[doc = "Modify a task-local data value. If the function returns 'none', the
|
||||
data is removed (and its reference dropped)."]
|
||||
/**
|
||||
* Modify a task-local data value. If the function returns 'none', the
|
||||
* data is removed (and its reference dropped).
|
||||
*/
|
||||
unsafe fn local_data_modify<T>(key: local_data_key<T>,
|
||||
modify_fn: fn(option<@T>) -> option<@T>) {
|
||||
local_modify(rustrt::rust_get_task(), key, modify_fn)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
#[doc = "Operations on tuples"];
|
||||
//! Operations on tuples
|
||||
|
||||
#[doc = "Return the first element of a pair"]
|
||||
/// Return the first element of a pair
|
||||
pure fn first<T:copy, U:copy>(pair: (T, U)) -> T {
|
||||
let (t, _) = pair;
|
||||
ret t;
|
||||
}
|
||||
|
||||
#[doc = "Return the second element of a pair"]
|
||||
/// Return the second element of a pair
|
||||
pure fn second<T:copy, U:copy>(pair: (T, U)) -> U {
|
||||
let (_, u) = pair;
|
||||
ret u;
|
||||
}
|
||||
|
||||
#[doc = "Return the results of swapping the two elements of a pair"]
|
||||
/// Return the results of swapping the two elements of a pair
|
||||
pure fn swap<T:copy, U:copy>(pair: (T, U)) -> (U, T) {
|
||||
let (t, u) = pair;
|
||||
ret (u, t);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
|
|||
pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }
|
||||
|
||||
#[inline(always)]
|
||||
#[doc = "Iterate over the range [`lo`..`hi`)"]
|
||||
/// Iterate over the range [`lo`..`hi`)
|
||||
fn range(lo: T, hi: T, it: fn(T) -> bool) {
|
||||
let mut i = lo;
|
||||
while i < hi {
|
||||
|
|
@ -47,7 +47,7 @@ fn range(lo: T, hi: T, it: fn(T) -> bool) {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Computes the bitwise complement"]
|
||||
/// Computes the bitwise complement
|
||||
pure fn compl(i: T) -> T {
|
||||
max_value ^ i
|
||||
}
|
||||
|
|
@ -76,18 +76,18 @@ impl num of num::num for T {
|
|||
fn from_int(n: int) -> T { ret n as T; }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Parse a buffer of bytes
|
||||
|
||||
# Arguments
|
||||
|
||||
* buf - A byte buffer
|
||||
* radix - The base of the number
|
||||
|
||||
# Failure
|
||||
|
||||
`buf` must not be empty
|
||||
"]
|
||||
/**
|
||||
* Parse a buffer of bytes
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * buf - A byte buffer
|
||||
* * radix - The base of the number
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* `buf` must not be empty
|
||||
*/
|
||||
fn parse_buf(buf: ~[u8], radix: uint) -> option<T> {
|
||||
if vec::len(buf) == 0u { ret none; }
|
||||
let mut i = vec::len(buf) - 1u;
|
||||
|
|
@ -104,10 +104,10 @@ fn parse_buf(buf: ~[u8], radix: uint) -> option<T> {
|
|||
};
|
||||
}
|
||||
|
||||
#[doc = "Parse a string to an int"]
|
||||
/// Parse a string to an int
|
||||
fn from_str(s: str) -> option<T> { parse_buf(str::bytes(s), 10u) }
|
||||
|
||||
#[doc = "Parse a string as an unsigned integer."]
|
||||
/// Parse a string as an unsigned integer.
|
||||
fn from_str_radix(buf: str, radix: u64) -> option<u64> {
|
||||
if str::len(buf) == 0u { ret none; }
|
||||
let mut i = str::len(buf) - 1u;
|
||||
|
|
@ -123,13 +123,13 @@ fn from_str_radix(buf: str, radix: u64) -> option<u64> {
|
|||
};
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Convert to a string in a given base
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if `radix` < 2 or `radix` > 16
|
||||
"]
|
||||
/**
|
||||
* Convert to a string in a given base
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if `radix` < 2 or `radix` > 16
|
||||
*/
|
||||
fn to_str(num: T, radix: uint) -> str {
|
||||
do to_str_bytes(false, num, radix) |slice| {
|
||||
do vec::unpack_slice(slice) |p, len| {
|
||||
|
|
@ -138,7 +138,7 @@ fn to_str(num: T, radix: uint) -> str {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Low-level helper routine for string conversion."]
|
||||
/// Low-level helper routine for string conversion.
|
||||
fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
|
||||
f: fn(v: &[u8]) -> U) -> U {
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Convert to a string"]
|
||||
/// Convert to a string
|
||||
fn str(i: T) -> str { ret to_str(i, 10u); }
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1,76 +1,76 @@
|
|||
type T = uint;
|
||||
|
||||
#[doc = "
|
||||
Divide two numbers, return the result, rounded up.
|
||||
|
||||
# Arguments
|
||||
|
||||
* x - an integer
|
||||
* y - an integer distinct from 0u
|
||||
|
||||
# Return value
|
||||
|
||||
The smallest integer `q` such that `x/y <= q`.
|
||||
"]
|
||||
/**
|
||||
* Divide two numbers, return the result, rounded up.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * x - an integer
|
||||
* * y - an integer distinct from 0u
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* The smallest integer `q` such that `x/y <= q`.
|
||||
*/
|
||||
pure fn div_ceil(x: uint, y: uint) -> uint {
|
||||
let div = div(x, y);
|
||||
if x % y == 0u { ret div;}
|
||||
else { ret div + 1u; }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Divide two numbers, return the result, rounded to the closest integer.
|
||||
|
||||
# Arguments
|
||||
|
||||
* x - an integer
|
||||
* y - an integer distinct from 0u
|
||||
|
||||
# Return value
|
||||
|
||||
The integer `q` closest to `x/y`.
|
||||
"]
|
||||
/**
|
||||
* Divide two numbers, return the result, rounded to the closest integer.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * x - an integer
|
||||
* * y - an integer distinct from 0u
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* The integer `q` closest to `x/y`.
|
||||
*/
|
||||
pure fn div_round(x: uint, y: uint) -> uint {
|
||||
let div = div(x, y);
|
||||
if x % y * 2u < y { ret div;}
|
||||
else { ret div + 1u; }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Divide two numbers, return the result, rounded down.
|
||||
|
||||
Note: This is the same function as `div`.
|
||||
|
||||
# Arguments
|
||||
|
||||
* x - an integer
|
||||
* y - an integer distinct from 0u
|
||||
|
||||
# Return value
|
||||
|
||||
The smallest integer `q` such that `x/y <= q`. This
|
||||
is either `x/y` or `x/y + 1`.
|
||||
"]
|
||||
/**
|
||||
* Divide two numbers, return the result, rounded down.
|
||||
*
|
||||
* Note: This is the same function as `div`.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * x - an integer
|
||||
* * y - an integer distinct from 0u
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* The smallest integer `q` such that `x/y <= q`. This
|
||||
* is either `x/y` or `x/y + 1`.
|
||||
*/
|
||||
pure fn div_floor(x: uint, y: uint) -> uint { ret x / y; }
|
||||
|
||||
#[doc = "Produce a uint suitable for use in a hash table"]
|
||||
/// Produce a uint suitable for use in a hash table
|
||||
pure fn hash(&&x: uint) -> uint { ret x; }
|
||||
|
||||
#[doc = "
|
||||
Iterate over the range [`lo`..`hi`), or stop when requested
|
||||
|
||||
# Arguments
|
||||
|
||||
* lo - The integer at which to start the loop (included)
|
||||
* hi - The integer at which to stop the loop (excluded)
|
||||
* it - A block to execute with each consecutive integer of the range.
|
||||
Return `true` to continue, `false` to stop.
|
||||
|
||||
# Return value
|
||||
|
||||
`true` If execution proceeded correctly, `false` if it was interrupted,
|
||||
that is if `it` returned `false` at any point.
|
||||
"]
|
||||
/**
|
||||
* Iterate over the range [`lo`..`hi`), or stop when requested
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * lo - The integer at which to start the loop (included)
|
||||
* * hi - The integer at which to stop the loop (excluded)
|
||||
* * it - A block to execute with each consecutive integer of the range.
|
||||
* Return `true` to continue, `false` to stop.
|
||||
*
|
||||
* # Return value
|
||||
*
|
||||
* `true` If execution proceeded correctly, `false` if it was interrupted,
|
||||
* that is if `it` returned `false` at any point.
|
||||
*/
|
||||
fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool {
|
||||
let mut i = lo;
|
||||
while i < hi {
|
||||
|
|
@ -80,7 +80,7 @@ fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool {
|
|||
ret true;
|
||||
}
|
||||
|
||||
#[doc = "Returns the smallest power of 2 greater than or equal to `n`"]
|
||||
/// Returns the smallest power of 2 greater than or equal to `n`
|
||||
#[inline(always)]
|
||||
fn next_power_of_two(n: uint) -> uint {
|
||||
let halfbits: uint = sys::size_of::<uint>() * 4u;
|
||||
|
|
|
|||
|
|
@ -2565,7 +2565,7 @@ mod general_category {
|
|||
|
||||
}
|
||||
mod derived_property {
|
||||
#[doc = "Check if a character has the alphabetic unicode property"]
|
||||
/// Check if a character has the alphabetic unicode property
|
||||
pure fn Alphabetic(c: char) -> bool {
|
||||
ret alt c {
|
||||
'\x41' to '\x5a'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Unsafe operations"];
|
||||
//! Unsafe operations
|
||||
|
||||
export reinterpret_cast, forget, bump_box_refcount, transmute;
|
||||
|
||||
|
|
@ -8,39 +8,39 @@ extern mod rusti {
|
|||
fn reinterpret_cast<T, U>(e: T) -> U;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Casts the value at `src` to U. The two types must have the same length.
|
||||
"]
|
||||
/// Casts the value at `src` to U. The two types must have the same length.
|
||||
#[inline(always)]
|
||||
unsafe fn reinterpret_cast<T, U>(src: T) -> U {
|
||||
rusti::reinterpret_cast(src)
|
||||
}
|
||||
|
||||
#[doc ="
|
||||
Move a thing into the void
|
||||
|
||||
The forget function will take ownership of the provided value but neglect
|
||||
to run any required cleanup or memory-management operations on it. This
|
||||
can be used for various acts of magick, particularly when using
|
||||
reinterpret_cast on managed pointer types.
|
||||
"]
|
||||
/**
|
||||
* Move a thing into the void
|
||||
*
|
||||
* The forget function will take ownership of the provided value but neglect
|
||||
* to run any required cleanup or memory-management operations on it. This
|
||||
* can be used for various acts of magick, particularly when using
|
||||
* reinterpret_cast on managed pointer types.
|
||||
*/
|
||||
#[inline(always)]
|
||||
unsafe fn forget<T>(-thing: T) { rusti::forget(thing); }
|
||||
|
||||
#[doc = "Force-increment the reference count on a shared box. If used
|
||||
uncarefully, this can leak the box. Use this in conjunction with transmute
|
||||
and/or reinterpret_cast when such calls would otherwise scramble a box's
|
||||
reference count"]
|
||||
/**
|
||||
* Force-increment the reference count on a shared box. If used
|
||||
* uncarefully, this can leak the box. Use this in conjunction with transmute
|
||||
* and/or reinterpret_cast when such calls would otherwise scramble a box's
|
||||
* reference count
|
||||
*/
|
||||
unsafe fn bump_box_refcount<T>(+t: @T) { forget(t); }
|
||||
|
||||
#[doc = "
|
||||
Transform a value of one type into a value of another type.
|
||||
Both types must have the same size and alignment.
|
||||
|
||||
# Example
|
||||
|
||||
assert transmute(\"L\") == [76u8, 0u8]/~;
|
||||
"]
|
||||
/**
|
||||
* Transform a value of one type into a value of another type.
|
||||
* Both types must have the same size and alignment.
|
||||
*
|
||||
* # Example
|
||||
*
|
||||
* assert transmute("L") == [76u8, 0u8]/~;
|
||||
*/
|
||||
unsafe fn transmute<L, G>(-thing: L) -> G {
|
||||
let newthing = reinterpret_cast(thing);
|
||||
forget(thing);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -21,19 +21,19 @@ export eq_vec;
|
|||
// write an optimizing version of this module that produces a different obj
|
||||
// for the case where nbits <= 32.
|
||||
|
||||
#[doc = "The bitvector type"]
|
||||
/// The bitvector type
|
||||
type bitv = @{storage: ~[mut uint], nbits: uint};
|
||||
|
||||
const uint_bits: uint = 32u + (1u << 32u >> 27u);
|
||||
|
||||
#[doc = "
|
||||
Constructs a bitvector
|
||||
|
||||
# Arguments
|
||||
|
||||
* nbits - The number of bits in the bitvector
|
||||
* init - If true then the bits are initialized to 1, otherwise 0
|
||||
"]
|
||||
/**
|
||||
* Constructs a bitvector
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * nbits - The number of bits in the bitvector
|
||||
* * init - If true then the bits are initialized to 1, otherwise 0
|
||||
*/
|
||||
fn bitv(nbits: uint, init: bool) -> bitv {
|
||||
let elt = if init { !0u } else { 0u };
|
||||
let storage = vec::to_mut(vec::from_elem(nbits / uint_bits + 1u, elt));
|
||||
|
|
@ -63,12 +63,12 @@ fn union(v0: bitv, v1: bitv) -> bool {
|
|||
|
||||
fn land(w0: uint, w1: uint) -> uint { ret w0 & w1; }
|
||||
|
||||
#[doc = "
|
||||
Calculates the intersection of two bitvectors
|
||||
|
||||
Sets `v0` to the intersection of `v0` and `v1`. Both bitvectors must be the
|
||||
same length. Returns 'true' if `v0` was changed.
|
||||
"]
|
||||
/**
|
||||
* Calculates the intersection of two bitvectors
|
||||
*
|
||||
* Sets `v0` to the intersection of `v0` and `v1`. Both bitvectors must be the
|
||||
* same length. Returns 'true' if `v0` was changed.
|
||||
*/
|
||||
fn intersect(v0: bitv, v1: bitv) -> bool {
|
||||
let sub = land;
|
||||
ret process(v0, v1, sub);
|
||||
|
|
@ -76,16 +76,16 @@ fn intersect(v0: bitv, v1: bitv) -> bool {
|
|||
|
||||
fn right(_w0: uint, w1: uint) -> uint { ret w1; }
|
||||
|
||||
#[doc = "
|
||||
Assigns the value of `v1` to `v0`
|
||||
|
||||
Both bitvectors must be the same length. Returns `true` if `v0` was changed
|
||||
"]
|
||||
/**
|
||||
* Assigns the value of `v1` to `v0`
|
||||
*
|
||||
* Both bitvectors must be the same length. Returns `true` if `v0` was changed
|
||||
*/
|
||||
fn assign(v0: bitv, v1: bitv) -> bool {
|
||||
let sub = right; ret process(v0, v1, sub);
|
||||
}
|
||||
|
||||
#[doc = "Makes a copy of a bitvector"]
|
||||
/// Makes a copy of a bitvector
|
||||
fn clone(v: bitv) -> bitv {
|
||||
let storage = vec::to_mut(vec::from_elem(v.nbits / uint_bits + 1u, 0u));
|
||||
let len = vec::len(v.storage);
|
||||
|
|
@ -93,7 +93,7 @@ fn clone(v: bitv) -> bitv {
|
|||
ret @{storage: storage, nbits: v.nbits};
|
||||
}
|
||||
|
||||
#[doc = "Retrieve the value at index `i`"]
|
||||
/// Retrieve the value at index `i`
|
||||
#[inline(always)]
|
||||
pure fn get(v: bitv, i: uint) -> bool {
|
||||
assert (i < v.nbits);
|
||||
|
|
@ -104,12 +104,12 @@ pure fn get(v: bitv, i: uint) -> bool {
|
|||
ret x == 1u;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Compares two bitvectors
|
||||
|
||||
Both bitvectors must be the same length. Returns `true` if both bitvectors
|
||||
contain identical elements.
|
||||
"]
|
||||
/**
|
||||
* Compares two bitvectors
|
||||
*
|
||||
* Both bitvectors must be the same length. Returns `true` if both bitvectors
|
||||
* contain identical elements.
|
||||
*/
|
||||
fn equal(v0: bitv, v1: bitv) -> bool {
|
||||
if v0.nbits != v1.nbits { ret false; }
|
||||
let len = vec::len(v1.storage);
|
||||
|
|
@ -118,26 +118,26 @@ fn equal(v0: bitv, v1: bitv) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Set all bits to 0"]
|
||||
/// Set all bits to 0
|
||||
#[inline(always)]
|
||||
fn clear(v: bitv) { for each_storage(v) |w| { w = 0u } }
|
||||
|
||||
#[doc = "Set all bits to 1"]
|
||||
/// Set all bits to 1
|
||||
#[inline(always)]
|
||||
fn set_all(v: bitv) { for each_storage(v) |w| { w = !0u } }
|
||||
|
||||
#[doc = "Invert all bits"]
|
||||
/// Invert all bits
|
||||
#[inline(always)]
|
||||
fn invert(v: bitv) { for each_storage(v) |w| { w = !w } }
|
||||
|
||||
#[doc = "
|
||||
Calculate the difference between two bitvectors
|
||||
|
||||
Sets each element of `v0` to the value of that element minus the element
|
||||
of `v1` at the same index. Both bitvectors must be the same length.
|
||||
|
||||
Returns `true` if `v0` was changed.
|
||||
"]
|
||||
/**
|
||||
* Calculate the difference between two bitvectors
|
||||
*
|
||||
* Sets each element of `v0` to the value of that element minus the element
|
||||
* of `v1` at the same index. Both bitvectors must be the same length.
|
||||
*
|
||||
* Returns `true` if `v0` was changed.
|
||||
*/
|
||||
fn difference(v0: bitv, v1: bitv) -> bool {
|
||||
invert(v1);
|
||||
let b = intersect(v0, v1);
|
||||
|
|
@ -145,11 +145,11 @@ fn difference(v0: bitv, v1: bitv) -> bool {
|
|||
ret b;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Set the value of a bit at a given index
|
||||
|
||||
`i` must be less than the length of the bitvector.
|
||||
"]
|
||||
/**
|
||||
* Set the value of a bit at a given index
|
||||
*
|
||||
* `i` must be less than the length of the bitvector.
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn set(v: bitv, i: uint, x: bool) {
|
||||
assert (i < v.nbits);
|
||||
|
|
@ -161,14 +161,14 @@ fn set(v: bitv, i: uint, x: bool) {
|
|||
}
|
||||
|
||||
|
||||
#[doc = "Returns true if all bits are 1"]
|
||||
/// Returns true if all bits are 1
|
||||
fn is_true(v: bitv) -> bool {
|
||||
for each(v) |i| { if !i { ret false; } }
|
||||
ret true;
|
||||
}
|
||||
|
||||
|
||||
#[doc = "Returns true if all bits are 0"]
|
||||
/// Returns true if all bits are 0
|
||||
fn is_false(v: bitv) -> bool {
|
||||
for each(v) |i| { if i { ret false; } }
|
||||
ret true;
|
||||
|
|
@ -178,11 +178,11 @@ fn init_to_vec(v: bitv, i: uint) -> uint {
|
|||
ret if get(v, i) { 1u } else { 0u };
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Converts the bitvector to a vector of uint with the same length.
|
||||
|
||||
Each uint in the resulting vector has either value 0u or 1u.
|
||||
"]
|
||||
/**
|
||||
* Converts the bitvector to a vector of uint with the same length.
|
||||
*
|
||||
* Each uint in the resulting vector has either value 0u or 1u.
|
||||
*/
|
||||
fn to_vec(v: bitv) -> ~[uint] {
|
||||
let sub = |x| init_to_vec(v, x);
|
||||
ret vec::from_fn::<uint>(v.nbits, sub);
|
||||
|
|
@ -207,24 +207,24 @@ fn each_storage(v: bitv, op: fn(&uint) -> bool) {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Converts the bitvector to a string.
|
||||
|
||||
The resulting string has the same length as the bitvector, and each character
|
||||
is either '0' or '1'.
|
||||
"]
|
||||
/**
|
||||
* Converts the bitvector to a string.
|
||||
*
|
||||
* The resulting string has the same length as the bitvector, and each
|
||||
* character is either '0' or '1'.
|
||||
*/
|
||||
fn to_str(v: bitv) -> str {
|
||||
let mut rs = "";
|
||||
for each(v) |i| { if i { rs += "1"; } else { rs += "0"; } }
|
||||
ret rs;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Compare a bitvector to a vector of uint
|
||||
|
||||
The uint vector is expected to only contain the values 0u and 1u. Both the
|
||||
bitvector and vector must have the same length
|
||||
"]
|
||||
/**
|
||||
* Compare a bitvector to a vector of uint
|
||||
*
|
||||
* The uint vector is expected to only contain the values 0u and 1u. Both the
|
||||
* bitvector and vector must have the same length
|
||||
*/
|
||||
fn eq_vec(v0: bitv, v1: ~[uint]) -> bool {
|
||||
assert (v0.nbits == vec::len::<uint>(v1));
|
||||
let len = v0.nbits;
|
||||
|
|
|
|||
|
|
@ -1,29 +1,30 @@
|
|||
#[doc = "
|
||||
Library to interface with chunks of memory allocated in C.
|
||||
|
||||
It is often desirable to safely interface with memory allocated from C,
|
||||
encapsulating the unsafety into allocation and destruction time. Indeed,
|
||||
allocating memory externally is currently the only way to give Rust shared
|
||||
mut state with C programs that keep their own references; vectors are
|
||||
unsuitable because they could be reallocated or moved at any time, and
|
||||
importing C memory into a vector takes a one-time snapshot of the memory.
|
||||
|
||||
This module simplifies the usage of such external blocks of memory. Memory
|
||||
is encapsulated into an opaque object after creation; the lifecycle of the
|
||||
memory can be optionally managed by Rust, if an appropriate destructor
|
||||
closure is provided. Safety is ensured by bounds-checking accesses, which
|
||||
are marshalled through get and set functions.
|
||||
|
||||
There are three unsafe functions: the two introduction forms, and the
|
||||
pointer elimination form. The introduction forms are unsafe for the obvious
|
||||
reason (they act on a pointer that cannot be checked inside the method), but
|
||||
the elimination form is somewhat more subtle in its unsafety. By using a
|
||||
pointer taken from a c_vec::t without keeping a reference to the c_vec::t
|
||||
itself around, the c_vec could be garbage collected, and the memory within
|
||||
could be destroyed. There are legitimate uses for the pointer elimination
|
||||
form -- for instance, to pass memory back into C -- but great care must be
|
||||
taken to ensure that a reference to the c_vec::t is still held if needed.
|
||||
"];
|
||||
/*!
|
||||
* Library to interface with chunks of memory allocated in C.
|
||||
*
|
||||
* It is often desirable to safely interface with memory allocated from C,
|
||||
* encapsulating the unsafety into allocation and destruction time. Indeed,
|
||||
* allocating memory externally is currently the only way to give Rust shared
|
||||
* mut state with C programs that keep their own references; vectors are
|
||||
* unsuitable because they could be reallocated or moved at any time, and
|
||||
* importing C memory into a vector takes a one-time snapshot of the memory.
|
||||
*
|
||||
* This module simplifies the usage of such external blocks of memory. Memory
|
||||
* is encapsulated into an opaque object after creation; the lifecycle of the
|
||||
* memory can be optionally managed by Rust, if an appropriate destructor
|
||||
* closure is provided. Safety is ensured by bounds-checking accesses, which
|
||||
* are marshalled through get and set functions.
|
||||
*
|
||||
* There are three unsafe functions: the two introduction forms, and the
|
||||
* pointer elimination form. The introduction forms are unsafe for the
|
||||
* obvious reason (they act on a pointer that cannot be checked inside the
|
||||
* method), but the elimination form is somewhat more subtle in its unsafety.
|
||||
* By using a pointer taken from a c_vec::t without keeping a reference to the
|
||||
* c_vec::t itself around, the c_vec could be garbage collected, and the
|
||||
* memory within could be destroyed. There are legitimate uses for the
|
||||
* pointer elimination form -- for instance, to pass memory back into C -- but
|
||||
* great care must be taken to ensure that a reference to the c_vec::t is
|
||||
* still held if needed.
|
||||
*/
|
||||
|
||||
export c_vec;
|
||||
export c_vec, c_vec_with_dtor;
|
||||
|
|
@ -31,12 +32,12 @@ export get, set;
|
|||
export len;
|
||||
export ptr;
|
||||
|
||||
#[doc = "
|
||||
The type representing a foreign chunk of memory
|
||||
|
||||
Wrapped in a enum for opacity; FIXME #818 when it is possible to have
|
||||
truly opaque types, this should be revisited.
|
||||
"]
|
||||
/**
|
||||
* The type representing a foreign chunk of memory
|
||||
*
|
||||
* Wrapped in a enum for opacity; FIXME #818 when it is possible to have
|
||||
* truly opaque types, this should be revisited.
|
||||
*/
|
||||
enum c_vec<T> {
|
||||
c_vec_({ base: *mut T, len: uint, rsrc: @dtor_res})
|
||||
}
|
||||
|
|
@ -56,14 +57,14 @@ class dtor_res {
|
|||
Section: Introduction forms
|
||||
*/
|
||||
|
||||
#[doc = "
|
||||
Create a `c_vec` from a foreign buffer with a given length.
|
||||
|
||||
# Arguments
|
||||
|
||||
* base - A foreign pointer to a buffer
|
||||
* len - The number of elements in the buffer
|
||||
"]
|
||||
/**
|
||||
* Create a `c_vec` from a foreign buffer with a given length.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * base - A foreign pointer to a buffer
|
||||
* * len - The number of elements in the buffer
|
||||
*/
|
||||
unsafe fn c_vec<T>(base: *mut T, len: uint) -> c_vec<T> {
|
||||
ret c_vec_({
|
||||
base: base,
|
||||
|
|
@ -72,17 +73,17 @@ unsafe fn c_vec<T>(base: *mut T, len: uint) -> c_vec<T> {
|
|||
});
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Create a `c_vec` from a foreign buffer, with a given length,
|
||||
and a function to run upon destruction.
|
||||
|
||||
# Arguments
|
||||
|
||||
* base - A foreign pointer to a buffer
|
||||
* len - The number of elements in the buffer
|
||||
* dtor - A function to run when the value is destructed, useful
|
||||
for freeing the buffer, etc.
|
||||
"]
|
||||
/**
|
||||
* Create a `c_vec` from a foreign buffer, with a given length,
|
||||
* and a function to run upon destruction.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * base - A foreign pointer to a buffer
|
||||
* * len - The number of elements in the buffer
|
||||
* * dtor - A function to run when the value is destructed, useful
|
||||
* for freeing the buffer, etc.
|
||||
*/
|
||||
unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: fn@())
|
||||
-> c_vec<T> {
|
||||
ret c_vec_({
|
||||
|
|
@ -96,21 +97,21 @@ unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: fn@())
|
|||
Section: Operations
|
||||
*/
|
||||
|
||||
#[doc = "
|
||||
Retrieves an element at a given index
|
||||
|
||||
Fails if `ofs` is greater or equal to the length of the vector
|
||||
"]
|
||||
/**
|
||||
* Retrieves an element at a given index
|
||||
*
|
||||
* Fails if `ofs` is greater or equal to the length of the vector
|
||||
*/
|
||||
fn get<T: copy>(t: c_vec<T>, ofs: uint) -> T {
|
||||
assert ofs < len(t);
|
||||
ret unsafe { *ptr::mut_offset((*t).base, ofs) };
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Sets the value of an element at a given index
|
||||
|
||||
Fails if `ofs` is greater or equal to the length of the vector
|
||||
"]
|
||||
/**
|
||||
* Sets the value of an element at a given index
|
||||
*
|
||||
* Fails if `ofs` is greater or equal to the length of the vector
|
||||
*/
|
||||
fn set<T: copy>(t: c_vec<T>, ofs: uint, v: T) {
|
||||
assert ofs < len(t);
|
||||
unsafe { *ptr::mut_offset((*t).base, ofs) = v };
|
||||
|
|
@ -120,12 +121,12 @@ fn set<T: copy>(t: c_vec<T>, ofs: uint, v: T) {
|
|||
Section: Elimination forms
|
||||
*/
|
||||
|
||||
#[doc = "Returns the length of the vector"]
|
||||
/// Returns the length of the vector
|
||||
fn len<T>(t: c_vec<T>) -> uint {
|
||||
ret (*t).len;
|
||||
}
|
||||
|
||||
#[doc = "Returns a pointer to the first element of the vector"]
|
||||
/// Returns a pointer to the first element of the vector
|
||||
unsafe fn ptr<T>(t: c_vec<T>) -> *mut T {
|
||||
ret (*t).base;
|
||||
}
|
||||
|
|
@ -183,4 +184,4 @@ mod tests {
|
|||
set(cv, 2u, 34u8); /* safety */
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc="Additional general-purpose comparison functionality."]
|
||||
/// Additional general-purpose comparison functionality.
|
||||
|
||||
const fuzzy_epsilon: float = 1.0e-6;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Unsafe debugging functions for inspecting values."];
|
||||
//! Unsafe debugging functions for inspecting values.
|
||||
|
||||
import unsafe::reinterpret_cast;
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ unsafe fn ptr_cast<T, U>(x: @T) -> @U {
|
|||
reinterpret_cast(x)))
|
||||
}
|
||||
|
||||
#[doc = "Triggers a debugger breakpoint"]
|
||||
/// Triggers a debugger breakpoint
|
||||
fn breakpoint() {
|
||||
rustrt::rust_dbg_breakpoint();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "A deque. Untested as of yet. Likely buggy"];
|
||||
//! A deque. Untested as of yet. Likely buggy
|
||||
|
||||
import option::{some, none};
|
||||
import dvec::{dvec, extensions};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#[doc = "
|
||||
A functional key,value store that works on anything.
|
||||
|
||||
This works using a binary search tree. In the first version, it's a
|
||||
very naive algorithm, but it will probably be updated to be a
|
||||
red-black tree or something else.
|
||||
|
||||
This is copied and modified from treemap right now. It's missing a lot
|
||||
of features.
|
||||
"];
|
||||
/*!
|
||||
* A functional key,value store that works on anything.
|
||||
*
|
||||
* This works using a binary search tree. In the first version, it's a
|
||||
* very naive algorithm, but it will probably be updated to be a
|
||||
* red-black tree or something else.
|
||||
*
|
||||
* This is copied and modified from treemap right now. It's missing a lot
|
||||
* of features.
|
||||
*/
|
||||
|
||||
import option::{some, none};
|
||||
import option = option;
|
||||
|
|
@ -25,10 +25,10 @@ enum tree_node<K, V> {
|
|||
node(@K, @V, @tree_node<K, V>, @tree_node<K, V>)
|
||||
}
|
||||
|
||||
#[doc = "Create a treemap"]
|
||||
/// Create a treemap
|
||||
fn init<K, V>() -> treemap<K, V> { @empty }
|
||||
|
||||
#[doc = "Insert a value into the map"]
|
||||
/// Insert a value into the map
|
||||
fn insert<K: copy, V: copy>(m: treemap<K, V>, k: K, v: V) -> treemap<K, V> {
|
||||
@alt m {
|
||||
@empty { node(@k, @v, @empty, @empty) }
|
||||
|
|
@ -42,7 +42,7 @@ fn insert<K: copy, V: copy>(m: treemap<K, V>, k: K, v: V) -> treemap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Find a value based on the key"]
|
||||
/// Find a value based on the key
|
||||
fn find<K, V: copy>(m: treemap<K, V>, k: K) -> option<V> {
|
||||
alt *m {
|
||||
empty { none }
|
||||
|
|
@ -54,7 +54,7 @@ fn find<K, V: copy>(m: treemap<K, V>, k: K) -> option<V> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Visit all pairs in the map in order."]
|
||||
/// Visit all pairs in the map in order.
|
||||
fn traverse<K, V: copy>(m: treemap<K, V>, f: fn(K, V)) {
|
||||
alt *m {
|
||||
empty { }
|
||||
|
|
|
|||
|
|
@ -1,67 +1,66 @@
|
|||
#[doc = "
|
||||
Simple getopt alternative.
|
||||
|
||||
Construct a vector of options, either by using reqopt, optopt, and optflag or
|
||||
by building them from components yourself, and pass them to getopts, along
|
||||
with a vector of actual arguments (not including argv[0]). You'll either get a
|
||||
failure code back, or a match. You'll have to verify whether the amount of
|
||||
'free' arguments in the match is what you expect. Use opt_* accessors to get
|
||||
argument values out of the match object.
|
||||
|
||||
Single-character options are expected to appear on the command line with a
|
||||
single preceding dash; multiple-character options are expected to be
|
||||
proceeded by two dashes. Options that expect an argument accept their argument
|
||||
following either a space or an equals sign.
|
||||
|
||||
# Example
|
||||
|
||||
The following example shows simple command line parsing for an application
|
||||
that requires an input file to be specified, accepts an optional output file
|
||||
name following -o, and accepts both -h and --help as optional flags.
|
||||
|
||||
use std;
|
||||
import std::getopts::{optopt,optflag,getopts,opt_present,opt_maybe_str,
|
||||
fail_str};
|
||||
|
||||
fn do_work(in: str, out: option<str>) {
|
||||
// ...
|
||||
}
|
||||
|
||||
fn print_usage(program: str) {
|
||||
io::println(\"Usage: \" + program + \" [options]/~\");
|
||||
io::println(\"-o\t\tOutput\");
|
||||
io::println(\"-h --help\tUsage\");
|
||||
}
|
||||
|
||||
fn main(args: [str]/~) {
|
||||
check vec::is_not_empty(args);
|
||||
|
||||
let program : str = vec::head(args);
|
||||
|
||||
let opts = [
|
||||
optopt(\"o\"),
|
||||
optflag(\"h\"),
|
||||
optflag(\"help\")
|
||||
]/~;
|
||||
let match = alt getopts(vec::tail(args), opts) {
|
||||
result::ok(m) { m }
|
||||
result::err(f) { fail fail_str(f) }
|
||||
};
|
||||
if opt_present(match, \"h\") || opt_present(match, \"help\") {
|
||||
print_usage(program);
|
||||
ret;
|
||||
}
|
||||
let output = opt_maybe_str(match, \"o\");
|
||||
let input = if vec::is_not_empty(match.free) {
|
||||
match.free[0]
|
||||
} else {
|
||||
print_usage(program);
|
||||
ret;
|
||||
};
|
||||
do_work(input, output);
|
||||
}
|
||||
|
||||
"];
|
||||
/*!
|
||||
* Simple getopt alternative.
|
||||
*
|
||||
* Construct a vector of options, either by using reqopt, optopt, and optflag
|
||||
* or by building them from components yourself, and pass them to getopts,
|
||||
* along with a vector of actual arguments (not including argv[0]). You'll
|
||||
* either get a failure code back, or a match. You'll have to verify whether
|
||||
* the amount of 'free' arguments in the match is what you expect. Use opt_*
|
||||
* accessors to get argument values out of the match object.
|
||||
*
|
||||
* Single-character options are expected to appear on the command line with a
|
||||
* single preceding dash; multiple-character options are expected to be
|
||||
* proceeded by two dashes. Options that expect an argument accept their
|
||||
* argument following either a space or an equals sign.
|
||||
*
|
||||
* # Example
|
||||
*
|
||||
* The following example shows simple command line parsing for an application
|
||||
* that requires an input file to be specified, accepts an optional output
|
||||
* file name following -o, and accepts both -h and --help as optional flags.
|
||||
*
|
||||
* use std;
|
||||
* import std::getopts::{optopt,optflag,getopts,opt_present,opt_maybe_str,
|
||||
* fail_str};
|
||||
*
|
||||
* fn do_work(in: str, out: option<str>) {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* fn print_usage(program: str) {
|
||||
* io::println("Usage: " + program + " [options]/~");
|
||||
* io::println("-o\t\tOutput");
|
||||
* io::println("-h --help\tUsage");
|
||||
* }
|
||||
*
|
||||
* fn main(args: [str]/~) {
|
||||
* check vec::is_not_empty(args);
|
||||
*
|
||||
* let program : str = vec::head(args);
|
||||
*
|
||||
* let opts = [
|
||||
* optopt("o"),
|
||||
* optflag("h"),
|
||||
* optflag("help")
|
||||
* ]/~;
|
||||
* let match = alt getopts(vec::tail(args), opts) {
|
||||
* result::ok(m) { m }
|
||||
* result::err(f) { fail fail_str(f) }
|
||||
* };
|
||||
* if opt_present(match, "h") || opt_present(match, "help") {
|
||||
* print_usage(program);
|
||||
* ret;
|
||||
* }
|
||||
* let output = opt_maybe_str(match, "o");
|
||||
* let input = if vec::is_not_empty(match.free) {
|
||||
* match.free[0]
|
||||
* } else {
|
||||
* print_usage(program);
|
||||
* ret;
|
||||
* };
|
||||
* do_work(input, output);
|
||||
* }
|
||||
*/
|
||||
|
||||
import core::result::{err, ok};
|
||||
import core::option;
|
||||
|
|
@ -91,7 +90,7 @@ enum hasarg { yes, no, maybe, }
|
|||
|
||||
enum occur { req, optional, multi, }
|
||||
|
||||
#[doc = "A description of a possible option"]
|
||||
/// A description of a possible option
|
||||
type opt = {name: name, hasarg: hasarg, occur: occur};
|
||||
|
||||
fn mkname(nm: str) -> name {
|
||||
|
|
@ -100,40 +99,40 @@ fn mkname(nm: str) -> name {
|
|||
} else { long(nm) };
|
||||
}
|
||||
|
||||
#[doc = "Create an option that is required and takes an argument"]
|
||||
/// Create an option that is required and takes an argument
|
||||
fn reqopt(name: str) -> opt {
|
||||
ret {name: mkname(name), hasarg: yes, occur: req};
|
||||
}
|
||||
|
||||
#[doc = "Create an option that is optional and takes an argument"]
|
||||
/// Create an option that is optional and takes an argument
|
||||
fn optopt(name: str) -> opt {
|
||||
ret {name: mkname(name), hasarg: yes, occur: optional};
|
||||
}
|
||||
|
||||
#[doc = "Create an option that is optional and does not take an argument"]
|
||||
/// Create an option that is optional and does not take an argument
|
||||
fn optflag(name: str) -> opt {
|
||||
ret {name: mkname(name), hasarg: no, occur: optional};
|
||||
}
|
||||
|
||||
#[doc = "Create an option that is optional and takes an optional argument"]
|
||||
/// Create an option that is optional and takes an optional argument
|
||||
fn optflagopt(name: str) -> opt {
|
||||
ret {name: mkname(name), hasarg: maybe, occur: optional};
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Create an option that is optional, takes an argument, and may occur
|
||||
multiple times
|
||||
"]
|
||||
/**
|
||||
* Create an option that is optional, takes an argument, and may occur
|
||||
* multiple times
|
||||
*/
|
||||
fn optmulti(name: str) -> opt {
|
||||
ret {name: mkname(name), hasarg: yes, occur: multi};
|
||||
}
|
||||
|
||||
enum optval { val(str), given, }
|
||||
|
||||
#[doc = "
|
||||
The result of checking command line arguments. Contains a vector
|
||||
of matches and a vector of free strings.
|
||||
"]
|
||||
/**
|
||||
* The result of checking command line arguments. Contains a vector
|
||||
* of matches and a vector of free strings.
|
||||
*/
|
||||
type match = {opts: ~[opt], vals: ~[~[optval]], free: ~[str]};
|
||||
|
||||
fn is_arg(arg: str) -> bool {
|
||||
|
|
@ -148,10 +147,10 @@ fn find_opt(opts: ~[opt], nm: name) -> option<uint> {
|
|||
vec::position(opts, |opt| opt.name == nm)
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
The type returned when the command line does not conform to the
|
||||
expected format. Pass this value to <fail_str> to get an error message.
|
||||
"]
|
||||
/**
|
||||
* The type returned when the command line does not conform to the
|
||||
* expected format. Pass this value to <fail_str> to get an error message.
|
||||
*/
|
||||
enum fail_ {
|
||||
argument_missing(str),
|
||||
unrecognized_option(str),
|
||||
|
|
@ -160,7 +159,7 @@ enum fail_ {
|
|||
unexpected_argument(str),
|
||||
}
|
||||
|
||||
#[doc = "Convert a `fail_` enum into an error string"]
|
||||
/// Convert a `fail_` enum into an error string
|
||||
fn fail_str(f: fail_) -> str {
|
||||
ret alt f {
|
||||
argument_missing(nm) { "Argument to option '" + nm + "' missing." }
|
||||
|
|
@ -175,19 +174,19 @@ fn fail_str(f: fail_) -> str {
|
|||
};
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
The result of parsing a command line with a set of options
|
||||
(result::t<match, fail_>)
|
||||
"]
|
||||
/**
|
||||
* The result of parsing a command line with a set of options
|
||||
* (result::t<match, fail_>)
|
||||
*/
|
||||
type result = result::result<match, fail_>;
|
||||
|
||||
#[doc = "
|
||||
Parse command line arguments according to the provided options
|
||||
|
||||
On success returns `ok(opt)`. Use functions such as `opt_present` `opt_str`,
|
||||
etc. to interrogate results. Returns `err(fail_)` on failure. Use <fail_str>
|
||||
to get an error message.
|
||||
"]
|
||||
/**
|
||||
* Parse command line arguments according to the provided options
|
||||
*
|
||||
* On success returns `ok(opt)`. Use functions such as `opt_present`
|
||||
* `opt_str`, etc. to interrogate results. Returns `err(fail_)` on failure.
|
||||
* Use <fail_str> to get an error message.
|
||||
*/
|
||||
fn getopts(args: ~[str], opts: ~[opt]) -> result unsafe {
|
||||
let n_opts = vec::len::<opt>(opts);
|
||||
fn f(_x: uint) -> ~[optval] { ret ~[]; }
|
||||
|
|
@ -319,12 +318,12 @@ fn opt_vals(m: match, nm: str) -> ~[optval] {
|
|||
|
||||
fn opt_val(m: match, nm: str) -> optval { ret opt_vals(m, nm)[0]; }
|
||||
|
||||
#[doc = "Returns true if an option was matched"]
|
||||
/// Returns true if an option was matched
|
||||
fn opt_present(m: match, nm: str) -> bool {
|
||||
ret vec::len::<optval>(opt_vals(m, nm)) > 0u;
|
||||
}
|
||||
|
||||
#[doc = "Returns true if any of several options were matched"]
|
||||
/// Returns true if any of several options were matched
|
||||
fn opts_present(m: match, names: ~[str]) -> bool {
|
||||
for vec::each(names) |nm| {
|
||||
alt find_opt(m.opts, mkname(nm)) {
|
||||
|
|
@ -336,21 +335,22 @@ fn opts_present(m: match, names: ~[str]) -> bool {
|
|||
}
|
||||
|
||||
|
||||
#[doc = "
|
||||
Returns the string argument supplied to a matching option
|
||||
|
||||
Fails if the option was not matched or if the match did not take an argument
|
||||
"]
|
||||
/**
|
||||
* Returns the string argument supplied to a matching option
|
||||
*
|
||||
* Fails if the option was not matched or if the match did not take an
|
||||
* argument
|
||||
*/
|
||||
fn opt_str(m: match, nm: str) -> str {
|
||||
ret alt opt_val(m, nm) { val(s) { s } _ { fail } };
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns the string argument supplied to one of several matching options
|
||||
|
||||
Fails if the no option was provided from the given list, or if the no such
|
||||
option took an argument
|
||||
"]
|
||||
/**
|
||||
* Returns the string argument supplied to one of several matching options
|
||||
*
|
||||
* Fails if the no option was provided from the given list, or if the no such
|
||||
* option took an argument
|
||||
*/
|
||||
fn opts_str(m: match, names: ~[str]) -> str {
|
||||
for vec::each(names) |nm| {
|
||||
alt opt_val(m, nm) {
|
||||
|
|
@ -362,11 +362,12 @@ fn opts_str(m: match, names: ~[str]) -> str {
|
|||
}
|
||||
|
||||
|
||||
#[doc = "
|
||||
Returns a vector of the arguments provided to all matches of the given option.
|
||||
|
||||
Used when an option accepts multiple values.
|
||||
"]
|
||||
/**
|
||||
* Returns a vector of the arguments provided to all matches of the given
|
||||
* option.
|
||||
*
|
||||
* Used when an option accepts multiple values.
|
||||
*/
|
||||
fn opt_strs(m: match, nm: str) -> ~[str] {
|
||||
let mut acc: ~[str] = ~[];
|
||||
for vec::each(opt_vals(m, nm)) |v| {
|
||||
|
|
@ -375,9 +376,7 @@ fn opt_strs(m: match, nm: str) -> ~[str] {
|
|||
ret acc;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns the string argument supplied to a matching option or none
|
||||
"]
|
||||
/// Returns the string argument supplied to a matching option or none
|
||||
fn opt_maybe_str(m: match, nm: str) -> option<str> {
|
||||
let vals = opt_vals(m, nm);
|
||||
if vec::len::<optval>(vals) == 0u { ret none::<str>; }
|
||||
|
|
@ -385,13 +384,13 @@ fn opt_maybe_str(m: match, nm: str) -> option<str> {
|
|||
}
|
||||
|
||||
|
||||
#[doc = "
|
||||
Returns the matching string, a default, or none
|
||||
|
||||
Returns none if the option was not present, `def` if the option was
|
||||
present but no argument was provided, and the argument if the option was
|
||||
present and an argument was provided.
|
||||
"]
|
||||
/**
|
||||
* Returns the matching string, a default, or none
|
||||
*
|
||||
* Returns none if the option was not present, `def` if the option was
|
||||
* present but no argument was provided, and the argument if the option was
|
||||
* present and an argument was provided.
|
||||
*/
|
||||
fn opt_default(m: match, nm: str, def: str) -> option<str> {
|
||||
let vals = opt_vals(m, nm);
|
||||
if vec::len::<optval>(vals) == 0u { ret none::<str>; }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Rust JSON serialization library
|
||||
// Copyright (c) 2011 Google Inc.
|
||||
|
||||
#[doc = "json serialization"];
|
||||
//! json serialization
|
||||
|
||||
import result::{result, ok, err};
|
||||
import io;
|
||||
|
|
@ -26,7 +26,7 @@ export list;
|
|||
export dict;
|
||||
export null;
|
||||
|
||||
#[doc = "Represents a json value"]
|
||||
/// Represents a json value
|
||||
enum json {
|
||||
num(float),
|
||||
string(@str),
|
||||
|
|
@ -42,7 +42,7 @@ type error = {
|
|||
msg: @str,
|
||||
};
|
||||
|
||||
#[doc = "Serializes a json value into a io::writer"]
|
||||
/// Serializes a json value into a io::writer
|
||||
fn to_writer(wr: io::writer, j: json) {
|
||||
alt j {
|
||||
num(n) { wr.write_str(float::to_str(n, 6u)); }
|
||||
|
|
@ -109,7 +109,7 @@ fn escape_str(s: str) -> str {
|
|||
escaped
|
||||
}
|
||||
|
||||
#[doc = "Serializes a json value into a string"]
|
||||
/// Serializes a json value into a string
|
||||
fn to_str(j: json) -> str {
|
||||
io::with_str_writer(|wr| to_writer(wr, j))
|
||||
}
|
||||
|
|
@ -461,7 +461,7 @@ impl parser for parser {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Deserializes a json value from an io::reader"]
|
||||
/// Deserializes a json value from an io::reader
|
||||
fn from_reader(rdr: io::reader) -> result<json, error> {
|
||||
let parser = {
|
||||
rdr: rdr,
|
||||
|
|
@ -473,12 +473,12 @@ fn from_reader(rdr: io::reader) -> result<json, error> {
|
|||
parser.parse()
|
||||
}
|
||||
|
||||
#[doc = "Deserializes a json value from a string"]
|
||||
/// Deserializes a json value from a string
|
||||
fn from_str(s: str) -> result<json, error> {
|
||||
io::with_str_reader(s, from_reader)
|
||||
}
|
||||
|
||||
#[doc = "Test if two json values are equal"]
|
||||
/// Test if two json values are equal
|
||||
fn eq(value0: json, value1: json) -> bool {
|
||||
alt (value0, value1) {
|
||||
(num(f0), num(f1)) { f0 == f1 }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "A standard linked list"];
|
||||
//! A standard linked list
|
||||
|
||||
import core::option;
|
||||
import option::*;
|
||||
|
|
@ -9,37 +9,37 @@ enum list<T> {
|
|||
nil,
|
||||
}
|
||||
|
||||
#[doc = "Create a list from a vector"]
|
||||
/// Create a list from a vector
|
||||
fn from_vec<T: copy>(v: &[T]) -> @list<T> {
|
||||
vec::foldr(v, @nil::<T>, |h, t| @cons(h, t))
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Left fold
|
||||
|
||||
Applies `f` to `u` and the first element in the list, then applies `f` to the
|
||||
result of the previous call and the second element, and so on, returning the
|
||||
accumulated result.
|
||||
|
||||
# Arguments
|
||||
|
||||
* ls - The list to fold
|
||||
* z - The initial value
|
||||
* f - The function to apply
|
||||
"]
|
||||
/**
|
||||
* Left fold
|
||||
*
|
||||
* Applies `f` to `u` and the first element in the list, then applies `f` to
|
||||
* the result of the previous call and the second element, and so on,
|
||||
* returning the accumulated result.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * ls - The list to fold
|
||||
* * z - The initial value
|
||||
* * f - The function to apply
|
||||
*/
|
||||
fn foldl<T: copy, U>(z: T, ls: @list<U>, f: fn(T, U) -> T) -> T {
|
||||
let mut accum: T = z;
|
||||
do iter(ls) |elt| { accum = f(accum, elt);}
|
||||
accum
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Search for an element that matches a given predicate
|
||||
|
||||
Apply function `f` to each element of `v`, starting from the first.
|
||||
When function `f` returns true then an option containing the element
|
||||
is returned. If `f` matches no elements then none is returned.
|
||||
"]
|
||||
/**
|
||||
* Search for an element that matches a given predicate
|
||||
*
|
||||
* Apply function `f` to each element of `v`, starting from the first.
|
||||
* When function `f` returns true then an option containing the element
|
||||
* is returned. If `f` matches no elements then none is returned.
|
||||
*/
|
||||
fn find<T: copy>(ls: @list<T>, f: fn(T) -> bool) -> option<T> {
|
||||
let mut ls = ls;
|
||||
loop {
|
||||
|
|
@ -53,7 +53,7 @@ fn find<T: copy>(ls: @list<T>, f: fn(T) -> bool) -> option<T> {
|
|||
};
|
||||
}
|
||||
|
||||
#[doc = "Returns true if a list contains an element with the given value"]
|
||||
/// Returns true if a list contains an element with the given value
|
||||
fn has<T: copy>(ls: @list<T>, elt: T) -> bool {
|
||||
for each(ls) |e| {
|
||||
if e == elt { ret true; }
|
||||
|
|
@ -61,7 +61,7 @@ fn has<T: copy>(ls: @list<T>, elt: T) -> bool {
|
|||
ret false;
|
||||
}
|
||||
|
||||
#[doc = "Returns true if the list is empty"]
|
||||
/// Returns true if the list is empty
|
||||
pure fn is_empty<T: copy>(ls: @list<T>) -> bool {
|
||||
alt *ls {
|
||||
nil { true }
|
||||
|
|
@ -69,19 +69,19 @@ pure fn is_empty<T: copy>(ls: @list<T>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Returns true if the list is not empty"]
|
||||
/// Returns true if the list is not empty
|
||||
pure fn is_not_empty<T: copy>(ls: @list<T>) -> bool {
|
||||
ret !is_empty(ls);
|
||||
}
|
||||
|
||||
#[doc = "Returns the length of a list"]
|
||||
/// Returns the length of a list
|
||||
fn len<T>(ls: @list<T>) -> uint {
|
||||
let mut count = 0u;
|
||||
iter(ls, |_e| count += 1u);
|
||||
count
|
||||
}
|
||||
|
||||
#[doc = "Returns all but the first element of a list"]
|
||||
/// Returns all but the first element of a list
|
||||
pure fn tail<T: copy>(ls: @list<T>) -> @list<T> {
|
||||
alt *ls {
|
||||
cons(_, tl) { ret tl; }
|
||||
|
|
@ -89,12 +89,12 @@ pure fn tail<T: copy>(ls: @list<T>) -> @list<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Returns the first element of a list"]
|
||||
/// Returns the first element of a list
|
||||
pure fn head<T: copy>(ls: @list<T>) -> T {
|
||||
alt check *ls { cons(hd, _) { hd } }
|
||||
}
|
||||
|
||||
#[doc = "Appends one list to another"]
|
||||
/// Appends one list to another
|
||||
pure fn append<T: copy>(l: @list<T>, m: @list<T>) -> @list<T> {
|
||||
alt *l {
|
||||
nil { ret m; }
|
||||
|
|
@ -102,12 +102,12 @@ pure fn append<T: copy>(l: @list<T>, m: @list<T>) -> @list<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Push an element to the front of a list"]
|
||||
/// Push an element to the front of a list
|
||||
fn push<T: copy>(&l: list<T>, v: T) {
|
||||
l = cons(v, @l);
|
||||
}
|
||||
|
||||
#[doc = "Iterate over a list"]
|
||||
/// Iterate over a list
|
||||
fn iter<T>(l: @list<T>, f: fn(T)) {
|
||||
let mut cur = l;
|
||||
loop {
|
||||
|
|
@ -121,7 +121,7 @@ fn iter<T>(l: @list<T>, f: fn(T)) {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Iterate over a list"]
|
||||
/// Iterate over a list
|
||||
fn each<T>(l: @list<T>, f: fn(T) -> bool) {
|
||||
let mut cur = l;
|
||||
loop {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "A map type"];
|
||||
//! A map type
|
||||
|
||||
import chained::hashmap;
|
||||
export hashmap, hashfn, eqfn, set, map, chained, hashmap, str_hash;
|
||||
|
|
@ -8,65 +8,65 @@ export hash_from_vec, hash_from_strs, hash_from_bytes;
|
|||
export hash_from_ints, hash_from_uints;
|
||||
export vec_from_set;
|
||||
|
||||
#[doc = "
|
||||
A function that returns a hash of a value
|
||||
|
||||
The hash should concentrate entropy in the lower bits.
|
||||
"]
|
||||
/**
|
||||
* A function that returns a hash of a value
|
||||
*
|
||||
* The hash should concentrate entropy in the lower bits.
|
||||
*/
|
||||
type hashfn<K> = fn@(K) -> uint;
|
||||
|
||||
type eqfn<K> = fn@(K, K) -> bool;
|
||||
|
||||
#[doc = "A convenience type to treat a hashmap as a set"]
|
||||
/// A convenience type to treat a hashmap as a set
|
||||
type set<K> = hashmap<K, ()>;
|
||||
|
||||
type hashmap<K, V> = chained::t<K, V>;
|
||||
|
||||
iface map<K, V: copy> {
|
||||
#[doc = "Return the number of elements in the map"]
|
||||
/// Return the number of elements in the map
|
||||
fn size() -> uint;
|
||||
|
||||
#[doc = "
|
||||
Add a value to the map.
|
||||
|
||||
If the map already contains a value for the specified key then the
|
||||
original value is replaced.
|
||||
|
||||
Returns true if the key did not already exist in the map
|
||||
"]
|
||||
/**
|
||||
* Add a value to the map.
|
||||
*
|
||||
* If the map already contains a value for the specified key then the
|
||||
* original value is replaced.
|
||||
*
|
||||
* Returns true if the key did not already exist in the map
|
||||
*/
|
||||
fn insert(+K, +V) -> bool;
|
||||
|
||||
#[doc = "Returns true if the map contains a value for the specified key"]
|
||||
/// Returns true if the map contains a value for the specified key
|
||||
fn contains_key(K) -> bool;
|
||||
|
||||
#[doc = "
|
||||
Get the value for the specified key. Fails if the key does not exist in
|
||||
the map.
|
||||
"]
|
||||
/**
|
||||
* Get the value for the specified key. Fails if the key does not exist in
|
||||
* the map.
|
||||
*/
|
||||
fn get(K) -> V;
|
||||
|
||||
#[doc = "Like get, but as an operator."]
|
||||
/// Like get, but as an operator.
|
||||
fn [](K) -> V;
|
||||
|
||||
#[doc = "
|
||||
Get the value for the specified key. If the key does not exist in
|
||||
the map then returns none.
|
||||
"]
|
||||
/**
|
||||
* Get the value for the specified key. If the key does not exist in
|
||||
* the map then returns none.
|
||||
*/
|
||||
fn find(K) -> option<V>;
|
||||
|
||||
#[doc = "
|
||||
Remove and return a value from the map. If the key does not exist
|
||||
in the map then returns none.
|
||||
"]
|
||||
/**
|
||||
* Remove and return a value from the map. If the key does not exist
|
||||
* in the map then returns none.
|
||||
*/
|
||||
fn remove(K) -> option<V>;
|
||||
|
||||
#[doc = "Iterate over all the key/value pairs in the map"]
|
||||
/// Iterate over all the key/value pairs in the map
|
||||
fn each(fn(K, V) -> bool);
|
||||
|
||||
#[doc = "Iterate over all the keys in the map"]
|
||||
/// Iterate over all the keys in the map
|
||||
fn each_key(fn(K) -> bool);
|
||||
|
||||
#[doc = "Iterate over all the values in the map"]
|
||||
/// Iterate over all the values in the map
|
||||
fn each_value(fn(V) -> bool);
|
||||
}
|
||||
|
||||
|
|
@ -295,41 +295,37 @@ fn hashmap<K: const, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>)
|
|||
chained::mk(hasher, eqer)
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap for string keys"]
|
||||
/// Construct a hashmap for string keys
|
||||
fn str_hash<V: copy>() -> hashmap<str, V> {
|
||||
ret hashmap(str::hash, str::eq);
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap for boxed string keys"]
|
||||
/// Construct a hashmap for boxed string keys
|
||||
fn box_str_hash<V: copy>() -> hashmap<@str, V> {
|
||||
ret hashmap(|x: @str| str::hash(*x), |x,y| str::eq(*x,*y));
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap for byte string keys"]
|
||||
/// Construct a hashmap for byte string keys
|
||||
fn bytes_hash<V: copy>() -> hashmap<~[u8], V> {
|
||||
ret hashmap(vec::u8::hash, vec::u8::eq);
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap for int keys"]
|
||||
/// Construct a hashmap for int keys
|
||||
fn int_hash<V: copy>() -> hashmap<int, V> {
|
||||
ret hashmap(int::hash, int::eq);
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap for uint keys"]
|
||||
/// Construct a hashmap for uint keys
|
||||
fn uint_hash<V: copy>() -> hashmap<uint, V> {
|
||||
ret hashmap(uint::hash, uint::eq);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Convenience function for adding keys to a hashmap with nil type keys
|
||||
"]
|
||||
/// Convenience function for adding keys to a hashmap with nil type keys
|
||||
fn set_add<K: const copy>(set: set<K>, key: K) -> bool {
|
||||
ret set.insert(key, ());
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Convert a set into a vector.
|
||||
"]
|
||||
/// Convert a set into a vector.
|
||||
fn vec_from_set<T: copy>(s: set<T>) -> ~[T] {
|
||||
let mut v = ~[];
|
||||
do s.each_key() |k| {
|
||||
|
|
@ -339,7 +335,7 @@ fn vec_from_set<T: copy>(s: set<T>) -> ~[T] {
|
|||
v
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap from a vector"]
|
||||
/// Construct a hashmap from a vector
|
||||
fn hash_from_vec<K: const copy, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>,
|
||||
items: ~[(K, V)]) -> hashmap<K, V> {
|
||||
let map = hashmap(hasher, eqer);
|
||||
|
|
@ -350,22 +346,22 @@ fn hash_from_vec<K: const copy, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>,
|
|||
map
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap from a vector with string keys"]
|
||||
/// Construct a hashmap from a vector with string keys
|
||||
fn hash_from_strs<V: copy>(items: ~[(str, V)]) -> hashmap<str, V> {
|
||||
hash_from_vec(str::hash, str::eq, items)
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap from a vector with byte keys"]
|
||||
/// Construct a hashmap from a vector with byte keys
|
||||
fn hash_from_bytes<V: copy>(items: ~[(~[u8], V)]) -> hashmap<~[u8], V> {
|
||||
hash_from_vec(vec::u8::hash, vec::u8::eq, items)
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap from a vector with int keys"]
|
||||
/// Construct a hashmap from a vector with int keys
|
||||
fn hash_from_ints<V: copy>(items: ~[(int, V)]) -> hashmap<int, V> {
|
||||
hash_from_vec(int::hash, int::eq, items)
|
||||
}
|
||||
|
||||
#[doc = "Construct a hashmap from a vector with uint keys"]
|
||||
/// Construct a hashmap from a vector with uint keys
|
||||
fn hash_from_uints<V: copy>(items: ~[(uint, V)]) -> hashmap<uint, V> {
|
||||
hash_from_vec(uint::hash, uint::eq, items)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
#[doc="
|
||||
Top-level module for network-related functionality
|
||||
"];
|
||||
//! Top-level module for network-related functionality
|
||||
|
||||
import tcp = net_tcp;
|
||||
export tcp;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
#[doc="
|
||||
Types/fns concerning Internet Protocol (IP), versions 4 & 6
|
||||
"];
|
||||
//! Types/fns concerning Internet Protocol (IP), versions 4 & 6
|
||||
|
||||
import vec;
|
||||
import uint;
|
||||
|
|
@ -28,27 +26,25 @@ export format_addr;
|
|||
export v4, v6;
|
||||
export get_addr;
|
||||
|
||||
#[doc = "An IP address"]
|
||||
/// An IP address
|
||||
enum ip_addr {
|
||||
#[doc="An IPv4 address"]
|
||||
/// An IPv4 address
|
||||
ipv4(sockaddr_in),
|
||||
ipv6(sockaddr_in6)
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Human-friendly feedback on why a parse_addr attempt failed
|
||||
"]
|
||||
/// Human-friendly feedback on why a parse_addr attempt failed
|
||||
type parse_addr_err = {
|
||||
err_msg: str
|
||||
};
|
||||
|
||||
#[doc="
|
||||
Convert a `ip_addr` to a str
|
||||
|
||||
# Arguments
|
||||
|
||||
* ip - a `std::net::ip::ip_addr`
|
||||
"]
|
||||
/**
|
||||
* Convert a `ip_addr` to a str
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * ip - a `std::net::ip::ip_addr`
|
||||
*/
|
||||
fn format_addr(ip: ip_addr) -> str {
|
||||
alt ip {
|
||||
ipv4(addr) {
|
||||
|
|
@ -72,27 +68,25 @@ fn format_addr(ip: ip_addr) -> str {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Represents errors returned from `net::ip::get_addr()`
|
||||
"]
|
||||
/// Represents errors returned from `net::ip::get_addr()`
|
||||
enum ip_get_addr_err {
|
||||
get_addr_unknown_error
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Attempts name resolution on the provided `node` string
|
||||
|
||||
# Arguments
|
||||
|
||||
* `node` - a string representing some host address
|
||||
* `iotask` - a `uv::iotask` used to interact with the underlying event loop
|
||||
|
||||
# Returns
|
||||
|
||||
A `result<[ip_addr]/~, ip_get_addr_err>` instance that will contain
|
||||
a vector of `ip_addr` results, in the case of success, or an error
|
||||
object in the case of failure
|
||||
"]
|
||||
/**
|
||||
* Attempts name resolution on the provided `node` string
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `node` - a string representing some host address
|
||||
* * `iotask` - a `uv::iotask` used to interact with the underlying event loop
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A `result<[ip_addr]/~, ip_get_addr_err>` instance that will contain
|
||||
* a vector of `ip_addr` results, in the case of success, or an error
|
||||
* object in the case of failure
|
||||
*/
|
||||
fn get_addr(++node: str, iotask: iotask)
|
||||
-> result::result<[ip_addr]/~, ip_get_addr_err> unsafe {
|
||||
do comm::listen |output_ch| {
|
||||
|
|
@ -127,21 +121,21 @@ fn get_addr(++node: str, iotask: iotask)
|
|||
}
|
||||
|
||||
mod v4 {
|
||||
#[doc = "
|
||||
Convert a str to `ip_addr`
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the string is not a valid IPv4 address
|
||||
|
||||
# Arguments
|
||||
|
||||
* ip - a string of the format `x.x.x.x`
|
||||
|
||||
# Returns
|
||||
|
||||
* an `ip_addr` of the `ipv4` variant
|
||||
"]
|
||||
/**
|
||||
* Convert a str to `ip_addr`
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if the string is not a valid IPv4 address
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * ip - a string of the format `x.x.x.x`
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* * an `ip_addr` of the `ipv4` variant
|
||||
*/
|
||||
fn parse_addr(ip: str) -> ip_addr {
|
||||
alt try_parse_addr(ip) {
|
||||
result::ok(addr) { copy(addr) }
|
||||
|
|
@ -210,21 +204,21 @@ mod v4 {
|
|||
}
|
||||
}
|
||||
mod v6 {
|
||||
#[doc = "
|
||||
Convert a str to `ip_addr`
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the string is not a valid IPv6 address
|
||||
|
||||
# Arguments
|
||||
|
||||
* ip - an ipv6 string. See RFC2460 for spec.
|
||||
|
||||
# Returns
|
||||
|
||||
* an `ip_addr` of the `ipv6` variant
|
||||
"]
|
||||
/**
|
||||
* Convert a str to `ip_addr`
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if the string is not a valid IPv6 address
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * ip - an ipv6 string. See RFC2460 for spec.
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* * an `ip_addr` of the `ipv6` variant
|
||||
*/
|
||||
fn parse_addr(ip: str) -> ip_addr {
|
||||
alt try_parse_addr(ip) {
|
||||
result::ok(addr) { copy(addr) }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
#[doc="
|
||||
High-level interface to libuv's TCP functionality
|
||||
"];
|
||||
//! High-level interface to libuv's TCP functionality
|
||||
|
||||
import ip = net_ip;
|
||||
import uv::iotask;
|
||||
|
|
@ -34,13 +32,13 @@ extern mod rustrt {
|
|||
fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Encapsulates an open TCP/IP connection through libuv
|
||||
|
||||
`tcp_socket` is non-copyable/sendable and automagically handles closing the
|
||||
underlying libuv data structures when it goes out of scope. This is the
|
||||
data structure that is used for read/write operations over a TCP stream.
|
||||
"]
|
||||
/**
|
||||
* Encapsulates an open TCP/IP connection through libuv
|
||||
*
|
||||
* `tcp_socket` is non-copyable/sendable and automagically handles closing the
|
||||
* underlying libuv data structures when it goes out of scope. This is the
|
||||
* data structure that is used for read/write operations over a TCP stream.
|
||||
*/
|
||||
class tcp_socket {
|
||||
let socket_data: @tcp_socket_data;
|
||||
new(socket_data: @tcp_socket_data) { self.socket_data = socket_data; }
|
||||
|
|
@ -51,84 +49,76 @@ class tcp_socket {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
A buffered wrapper for `net::tcp::tcp_socket`
|
||||
|
||||
It is created with a call to `net::tcp::socket_buf()` and has impls that
|
||||
satisfy both the `io::reader` and `io::writer` ifaces.
|
||||
"]
|
||||
/**
|
||||
* A buffered wrapper for `net::tcp::tcp_socket`
|
||||
*
|
||||
* It is created with a call to `net::tcp::socket_buf()` and has impls that
|
||||
* satisfy both the `io::reader` and `io::writer` ifaces.
|
||||
*/
|
||||
class tcp_socket_buf {
|
||||
let data: @tcp_buffered_socket_data;
|
||||
new(data: @tcp_buffered_socket_data) { self.data = data; }
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Contains raw, string-based, error information returned from libuv
|
||||
"]
|
||||
/// Contains raw, string-based, error information returned from libuv
|
||||
type tcp_err_data = {
|
||||
err_name: str,
|
||||
err_msg: str
|
||||
};
|
||||
#[doc="
|
||||
Details returned as part of a `result::err` result from `tcp::listen`
|
||||
"]
|
||||
/// Details returned as part of a `result::err` result from `tcp::listen`
|
||||
enum tcp_listen_err_data {
|
||||
#[doc="
|
||||
Some unplanned-for error. The first and second fields correspond
|
||||
to libuv's `err_name` and `err_msg` fields, respectively.
|
||||
"]
|
||||
/**
|
||||
* Some unplanned-for error. The first and second fields correspond
|
||||
* to libuv's `err_name` and `err_msg` fields, respectively.
|
||||
*/
|
||||
generic_listen_err(str, str),
|
||||
#[doc="
|
||||
Failed to bind to the requested IP/Port, because it is already in use.
|
||||
|
||||
# Possible Causes
|
||||
|
||||
* Attempting to bind to a port already bound to another listener
|
||||
"]
|
||||
/**
|
||||
* Failed to bind to the requested IP/Port, because it is already in use.
|
||||
*
|
||||
* # Possible Causes
|
||||
*
|
||||
* * Attempting to bind to a port already bound to another listener
|
||||
*/
|
||||
address_in_use,
|
||||
#[doc="
|
||||
Request to bind to an IP/Port was denied by the system.
|
||||
|
||||
# Possible Causes
|
||||
|
||||
* Attemping to binding to an IP/Port as a non-Administrator
|
||||
on Windows Vista+
|
||||
* Attempting to bind, as a non-priv'd
|
||||
user, to 'privileged' ports (< 1024) on *nix
|
||||
"]
|
||||
/**
|
||||
* Request to bind to an IP/Port was denied by the system.
|
||||
*
|
||||
* # Possible Causes
|
||||
*
|
||||
* * Attemping to binding to an IP/Port as a non-Administrator
|
||||
* on Windows Vista+
|
||||
* * Attempting to bind, as a non-priv'd
|
||||
* user, to 'privileged' ports (< 1024) on *nix
|
||||
*/
|
||||
access_denied
|
||||
}
|
||||
#[doc="
|
||||
Details returned as part of a `result::err` result from `tcp::connect`
|
||||
"]
|
||||
/// Details returned as part of a `result::err` result from `tcp::connect`
|
||||
enum tcp_connect_err_data {
|
||||
#[doc="
|
||||
Some unplanned-for error. The first and second fields correspond
|
||||
to libuv's `err_name` and `err_msg` fields, respectively.
|
||||
"]
|
||||
/**
|
||||
* Some unplanned-for error. The first and second fields correspond
|
||||
* to libuv's `err_name` and `err_msg` fields, respectively.
|
||||
*/
|
||||
generic_connect_err(str, str),
|
||||
#[doc="
|
||||
Invalid IP or invalid port
|
||||
"]
|
||||
/// Invalid IP or invalid port
|
||||
connection_refused
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Initiate a client connection over TCP/IP
|
||||
|
||||
# Arguments
|
||||
|
||||
* `input_ip` - The IP address (versions 4 or 6) of the remote host
|
||||
* `port` - the unsigned integer of the desired remote host port
|
||||
* `iotask` - a `uv::iotask` that the tcp request will run on
|
||||
|
||||
# Returns
|
||||
|
||||
A `result` that, if the operation succeeds, contains a `net::net::tcp_socket`
|
||||
that can be used to send and receive data to/from the remote host. In the
|
||||
event of failure, a `net::tcp::tcp_connect_err_data` instance will be
|
||||
returned
|
||||
"]
|
||||
/**
|
||||
* Initiate a client connection over TCP/IP
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `input_ip` - The IP address (versions 4 or 6) of the remote host
|
||||
* * `port` - the unsigned integer of the desired remote host port
|
||||
* * `iotask` - a `uv::iotask` that the tcp request will run on
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A `result` that, if the operation succeeds, contains a
|
||||
* `net::net::tcp_socket` that can be used to send and receive data to/from
|
||||
* the remote host. In the event of failure, a
|
||||
* `net::tcp::tcp_connect_err_data` instance will be returned
|
||||
*/
|
||||
fn connect(-input_ip: ip::ip_addr, port: uint,
|
||||
iotask: iotask)
|
||||
-> result::result<tcp_socket, tcp_connect_err_data> unsafe {
|
||||
|
|
@ -252,56 +242,57 @@ fn connect(-input_ip: ip::ip_addr, port: uint,
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Write binary data to a tcp stream; Blocks until operation completes
|
||||
|
||||
# Arguments
|
||||
|
||||
* sock - a `tcp_socket` to write to
|
||||
* raw_write_data - a vector of `[u8]/~` that will be written to the stream.
|
||||
This value must remain valid for the duration of the `write` call
|
||||
|
||||
# Returns
|
||||
|
||||
A `result` object with a `nil` value as the `ok` variant, or a `tcp_err_data`
|
||||
value as the `err` variant
|
||||
"]
|
||||
/**
|
||||
* Write binary data to a tcp stream; Blocks until operation completes
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * sock - a `tcp_socket` to write to
|
||||
* * raw_write_data - a vector of `[u8]/~` that will be written to the stream.
|
||||
* This value must remain valid for the duration of the `write` call
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A `result` object with a `nil` value as the `ok` variant, or a
|
||||
* `tcp_err_data` value as the `err` variant
|
||||
*/
|
||||
fn write(sock: tcp_socket, raw_write_data: ~[u8])
|
||||
-> result::result<(), tcp_err_data> unsafe {
|
||||
let socket_data_ptr = ptr::addr_of(*(sock.socket_data));
|
||||
write_common_impl(socket_data_ptr, raw_write_data)
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Write binary data to tcp stream; Returns a `future::future` value immediately
|
||||
|
||||
# Safety
|
||||
|
||||
This function can produce unsafe results if:
|
||||
|
||||
1. the call to `write_future` is made
|
||||
2. the `future::future` value returned is never resolved via
|
||||
`future::get`
|
||||
3. and then the `tcp_socket` passed in to `write_future` leaves
|
||||
scope and is destructed before the task that runs the libuv write
|
||||
operation completes.
|
||||
|
||||
As such: If using `write_future`, always be sure to resolve the returned
|
||||
`future` so as to ensure libuv doesn't try to access a released write handle.
|
||||
Otherwise, use the blocking `tcp::write` function instead.
|
||||
|
||||
# Arguments
|
||||
|
||||
* sock - a `tcp_socket` to write to
|
||||
* raw_write_data - a vector of `[u8]/~` that will be written to the stream.
|
||||
This value must remain valid for the duration of the `write` call
|
||||
|
||||
# Returns
|
||||
|
||||
A `future` value that, once the `write` operation completes, resolves to a
|
||||
`result` object with a `nil` value as the `ok` variant, or a `tcp_err_data`
|
||||
value as the `err` variant
|
||||
"]
|
||||
/**
|
||||
* Write binary data to tcp stream; Returns a `future::future` value
|
||||
* immediately
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* This function can produce unsafe results if:
|
||||
*
|
||||
* 1. the call to `write_future` is made
|
||||
* 2. the `future::future` value returned is never resolved via
|
||||
* `future::get`
|
||||
* 3. and then the `tcp_socket` passed in to `write_future` leaves
|
||||
* scope and is destructed before the task that runs the libuv write
|
||||
* operation completes.
|
||||
*
|
||||
* As such: If using `write_future`, always be sure to resolve the returned
|
||||
* `future` so as to ensure libuv doesn't try to access a released write
|
||||
* handle. Otherwise, use the blocking `tcp::write` function instead.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * sock - a `tcp_socket` to write to
|
||||
* * raw_write_data - a vector of `[u8]/~` that will be written to the stream.
|
||||
* This value must remain valid for the duration of the `write` call
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A `future` value that, once the `write` operation completes, resolves to a
|
||||
* `result` object with a `nil` value as the `ok` variant, or a `tcp_err_data`
|
||||
* value as the `err` variant
|
||||
*/
|
||||
fn write_future(sock: tcp_socket, raw_write_data: ~[u8])
|
||||
-> future::future<result::result<(), tcp_err_data>> unsafe {
|
||||
let socket_data_ptr = ptr::addr_of(*(sock.socket_data));
|
||||
|
|
@ -311,19 +302,20 @@ fn write_future(sock: tcp_socket, raw_write_data: ~[u8])
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Begin reading binary data from an open TCP connection; used with `read_stop`
|
||||
|
||||
# Arguments
|
||||
|
||||
* sock -- a `net::tcp::tcp_socket` for the connection to read from
|
||||
|
||||
# Returns
|
||||
|
||||
* A `result` instance that will either contain a
|
||||
`comm::port<tcp_read_result>` that the user can read (and optionally, loop
|
||||
on) from until `read_stop` is called, or a `tcp_err_data` record
|
||||
"]
|
||||
/**
|
||||
* Begin reading binary data from an open TCP connection; used with
|
||||
* `read_stop`
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * sock -- a `net::tcp::tcp_socket` for the connection to read from
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* * A `result` instance that will either contain a
|
||||
* `comm::port<tcp_read_result>` that the user can read (and optionally, loop
|
||||
* on) from until `read_stop` is called, or a `tcp_err_data` record
|
||||
*/
|
||||
fn read_start(sock: tcp_socket)
|
||||
-> result::result<comm::port<
|
||||
result::result<~[u8], tcp_err_data>>, tcp_err_data> unsafe {
|
||||
|
|
@ -331,13 +323,13 @@ fn read_start(sock: tcp_socket)
|
|||
read_start_common_impl(socket_data)
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Stop reading from an open TCP connection; used with `read_start`
|
||||
|
||||
# Arguments
|
||||
|
||||
* `sock` - a `net::tcp::tcp_socket` that you wish to stop reading on
|
||||
"]
|
||||
/**
|
||||
* Stop reading from an open TCP connection; used with `read_start`
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `sock` - a `net::tcp::tcp_socket` that you wish to stop reading on
|
||||
*/
|
||||
fn read_stop(sock: tcp_socket,
|
||||
-read_port: comm::port<result::result<[u8]/~, tcp_err_data>>) ->
|
||||
result::result<(), tcp_err_data> unsafe {
|
||||
|
|
@ -346,54 +338,56 @@ fn read_stop(sock: tcp_socket,
|
|||
read_stop_common_impl(socket_data)
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Reads a single chunk of data from `tcp_socket`; block until data/error recv'd
|
||||
|
||||
Does a blocking read operation for a single chunk of data from a `tcp_socket`
|
||||
until a data arrives or an error is received. The provided `timeout_msecs`
|
||||
value is used to raise an error if the timeout period passes without any
|
||||
data received.
|
||||
|
||||
# Arguments
|
||||
|
||||
* `sock` - a `net::tcp::tcp_socket` that you wish to read from
|
||||
* `timeout_msecs` - a `uint` value, in msecs, to wait before dropping the
|
||||
read attempt. Pass `0u` to wait indefinitely
|
||||
"]
|
||||
/**
|
||||
* Reads a single chunk of data from `tcp_socket`; block until data/error
|
||||
* recv'd
|
||||
*
|
||||
* Does a blocking read operation for a single chunk of data from a
|
||||
* `tcp_socket` until a data arrives or an error is received. The provided
|
||||
* `timeout_msecs` value is used to raise an error if the timeout period
|
||||
* passes without any data received.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `sock` - a `net::tcp::tcp_socket` that you wish to read from
|
||||
* * `timeout_msecs` - a `uint` value, in msecs, to wait before dropping the
|
||||
* read attempt. Pass `0u` to wait indefinitely
|
||||
*/
|
||||
fn read(sock: tcp_socket, timeout_msecs: uint)
|
||||
-> result::result<~[u8],tcp_err_data> {
|
||||
let socket_data = ptr::addr_of(*(sock.socket_data));
|
||||
read_common_impl(socket_data, timeout_msecs)
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Reads a single chunk of data; returns a `future::future<[u8]/~>` immediately
|
||||
|
||||
Does a non-blocking read operation for a single chunk of data from a
|
||||
`tcp_socket` and immediately returns a `future` value representing the
|
||||
result. When resolving the returned `future`, it will block until data
|
||||
arrives or an error is received. The provided `timeout_msecs`
|
||||
value is used to raise an error if the timeout period passes without any
|
||||
data received.
|
||||
|
||||
# Safety
|
||||
|
||||
This function can produce unsafe results if the call to `read_future` is
|
||||
made, the `future::future` value returned is never resolved via
|
||||
`future::get`, and then the `tcp_socket` passed in to `read_future` leaves
|
||||
scope and is destructed before the task that runs the libuv read
|
||||
operation completes.
|
||||
|
||||
As such: If using `read_future`, always be sure to resolve the returned
|
||||
`future` so as to ensure libuv doesn't try to access a released read handle.
|
||||
Otherwise, use the blocking `tcp::read` function instead.
|
||||
|
||||
# Arguments
|
||||
|
||||
* `sock` - a `net::tcp::tcp_socket` that you wish to read from
|
||||
* `timeout_msecs` - a `uint` value, in msecs, to wait before dropping the
|
||||
read attempt. Pass `0u` to wait indefinitely
|
||||
"]
|
||||
/**
|
||||
* Reads a single chunk of data; returns a `future::future<[u8]/~>`
|
||||
* immediately
|
||||
*
|
||||
* Does a non-blocking read operation for a single chunk of data from a
|
||||
* `tcp_socket` and immediately returns a `future` value representing the
|
||||
* result. When resolving the returned `future`, it will block until data
|
||||
* arrives or an error is received. The provided `timeout_msecs`
|
||||
* value is used to raise an error if the timeout period passes without any
|
||||
* data received.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* This function can produce unsafe results if the call to `read_future` is
|
||||
* made, the `future::future` value returned is never resolved via
|
||||
* `future::get`, and then the `tcp_socket` passed in to `read_future` leaves
|
||||
* scope and is destructed before the task that runs the libuv read
|
||||
* operation completes.
|
||||
*
|
||||
* As such: If using `read_future`, always be sure to resolve the returned
|
||||
* `future` so as to ensure libuv doesn't try to access a released read
|
||||
* handle. Otherwise, use the blocking `tcp::read` function instead.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `sock` - a `net::tcp::tcp_socket` that you wish to read from
|
||||
* * `timeout_msecs` - a `uint` value, in msecs, to wait before dropping the
|
||||
* read attempt. Pass `0u` to wait indefinitely
|
||||
*/
|
||||
fn read_future(sock: tcp_socket, timeout_msecs: uint)
|
||||
-> future::future<result::result<~[u8],tcp_err_data>> {
|
||||
let socket_data = ptr::addr_of(*(sock.socket_data));
|
||||
|
|
@ -402,75 +396,75 @@ fn read_future(sock: tcp_socket, timeout_msecs: uint)
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Bind an incoming client connection to a `net::tcp::tcp_socket`
|
||||
|
||||
# Notes
|
||||
|
||||
It is safe to call `net::tcp::accept` _only_ within the context of the
|
||||
`new_connect_cb` callback provided as the final argument to the
|
||||
`net::tcp::listen` function.
|
||||
|
||||
The `new_conn` opaque value is provided _only_ as the first argument to the
|
||||
`new_connect_cb` provided as a part of `net::tcp::listen`.
|
||||
It can be safely sent to another task but it _must_ be
|
||||
used (via `net::tcp::accept`) before the `new_connect_cb` call it was
|
||||
provided to returns.
|
||||
|
||||
This implies that a port/chan pair must be used to make sure that the
|
||||
`new_connect_cb` call blocks until an attempt to create a
|
||||
`net::tcp::tcp_socket` is completed.
|
||||
|
||||
# Example
|
||||
|
||||
Here, the `new_conn` is used in conjunction with `accept` from within
|
||||
a task spawned by the `new_connect_cb` passed into `listen`
|
||||
|
||||
~~~~~~~~~~~
|
||||
net::tcp::listen(remote_ip, remote_port, backlog)
|
||||
// this callback is ran once after the connection is successfully
|
||||
// set up
|
||||
{|kill_ch|
|
||||
// pass the kill_ch to your main loop or wherever you want
|
||||
// to be able to externally kill the server from
|
||||
}
|
||||
// this callback is ran when a new connection arrives
|
||||
{|new_conn, kill_ch|
|
||||
let cont_po = comm::port::<option<tcp_err_data>>();
|
||||
let cont_ch = comm::chan(cont_po);
|
||||
task::spawn {||
|
||||
let accept_result = net::tcp::accept(new_conn);
|
||||
if accept_result.is_err() {
|
||||
comm::send(cont_ch, result::get_err(accept_result));
|
||||
// fail?
|
||||
}
|
||||
else {
|
||||
let sock = result::get(accept_result);
|
||||
comm::send(cont_ch, true);
|
||||
// do work here
|
||||
}
|
||||
};
|
||||
alt comm::recv(cont_po) {
|
||||
// shut down listen()
|
||||
some(err_data) { comm::send(kill_chan, some(err_data)) }
|
||||
// wait for next connection
|
||||
none {}
|
||||
}
|
||||
};
|
||||
~~~~~~~~~~~
|
||||
|
||||
# Arguments
|
||||
|
||||
* `new_conn` - an opaque value used to create a new `tcp_socket`
|
||||
|
||||
# Returns
|
||||
|
||||
On success, this function will return a `net::tcp::tcp_socket` as the
|
||||
`ok` variant of a `result`. The `net::tcp::tcp_socket` is anchored within
|
||||
the task that `accept` was called within for its lifetime. On failure,
|
||||
this function will return a `net::tcp::tcp_err_data` record
|
||||
as the `err` variant of a `result`.
|
||||
"]
|
||||
/**
|
||||
* Bind an incoming client connection to a `net::tcp::tcp_socket`
|
||||
*
|
||||
* # Notes
|
||||
*
|
||||
* It is safe to call `net::tcp::accept` _only_ within the context of the
|
||||
* `new_connect_cb` callback provided as the final argument to the
|
||||
* `net::tcp::listen` function.
|
||||
*
|
||||
* The `new_conn` opaque value is provided _only_ as the first argument to the
|
||||
* `new_connect_cb` provided as a part of `net::tcp::listen`.
|
||||
* It can be safely sent to another task but it _must_ be
|
||||
* used (via `net::tcp::accept`) before the `new_connect_cb` call it was
|
||||
* provided to returns.
|
||||
*
|
||||
* This implies that a port/chan pair must be used to make sure that the
|
||||
* `new_connect_cb` call blocks until an attempt to create a
|
||||
* `net::tcp::tcp_socket` is completed.
|
||||
*
|
||||
* # Example
|
||||
*
|
||||
* Here, the `new_conn` is used in conjunction with `accept` from within
|
||||
* a task spawned by the `new_connect_cb` passed into `listen`
|
||||
*
|
||||
* ~~~~~~~~~~~
|
||||
* net::tcp::listen(remote_ip, remote_port, backlog)
|
||||
* // this callback is ran once after the connection is successfully
|
||||
* // set up
|
||||
* {|kill_ch|
|
||||
* // pass the kill_ch to your main loop or wherever you want
|
||||
* // to be able to externally kill the server from
|
||||
* }
|
||||
* // this callback is ran when a new connection arrives
|
||||
* {|new_conn, kill_ch|
|
||||
* let cont_po = comm::port::<option<tcp_err_data>>();
|
||||
* let cont_ch = comm::chan(cont_po);
|
||||
* task::spawn {||
|
||||
* let accept_result = net::tcp::accept(new_conn);
|
||||
* if accept_result.is_err() {
|
||||
* comm::send(cont_ch, result::get_err(accept_result));
|
||||
* // fail?
|
||||
* }
|
||||
* else {
|
||||
* let sock = result::get(accept_result);
|
||||
* comm::send(cont_ch, true);
|
||||
* // do work here
|
||||
* }
|
||||
* };
|
||||
* alt comm::recv(cont_po) {
|
||||
* // shut down listen()
|
||||
* some(err_data) { comm::send(kill_chan, some(err_data)) }
|
||||
* // wait for next connection
|
||||
* none {}
|
||||
* }
|
||||
* };
|
||||
* ~~~~~~~~~~~
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `new_conn` - an opaque value used to create a new `tcp_socket`
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* On success, this function will return a `net::tcp::tcp_socket` as the
|
||||
* `ok` variant of a `result`. The `net::tcp::tcp_socket` is anchored within
|
||||
* the task that `accept` was called within for its lifetime. On failure,
|
||||
* this function will return a `net::tcp::tcp_err_data` record
|
||||
* as the `err` variant of a `result`.
|
||||
*/
|
||||
fn accept(new_conn: tcp_new_connection)
|
||||
-> result::result<tcp_socket, tcp_err_data> unsafe {
|
||||
|
||||
|
|
@ -545,34 +539,34 @@ fn accept(new_conn: tcp_new_connection)
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Bind to a given IP/port and listen for new connections
|
||||
|
||||
# Arguments
|
||||
|
||||
* `host_ip` - a `net::ip::ip_addr` representing a unique IP
|
||||
(versions 4 or 6)
|
||||
* `port` - a uint representing the port to listen on
|
||||
* `backlog` - a uint representing the number of incoming connections
|
||||
to cache in memory
|
||||
* `hl_loop` - a `uv::hl::high_level_loop` that the tcp request will run on
|
||||
* `on_establish_cb` - a callback that is evaluated if/when the listener
|
||||
is successfully established. it takes no parameters
|
||||
* `new_connect_cb` - a callback to be evaluated, on the libuv thread,
|
||||
whenever a client attempts to conect on the provided ip/port. the
|
||||
callback's arguments are:
|
||||
* `new_conn` - an opaque type that can be passed to
|
||||
`net::tcp::accept` in order to be converted to a `tcp_socket`.
|
||||
* `kill_ch` - channel of type `comm::chan<option<tcp_err_data>>`. this
|
||||
channel can be used to send a message to cause `listen` to begin
|
||||
closing the underlying libuv data structures.
|
||||
|
||||
# returns
|
||||
|
||||
a `result` instance containing empty data of type `()` on a
|
||||
successful/normal shutdown, and a `tcp_listen_err_data` enum in the event
|
||||
of listen exiting because of an error
|
||||
"]
|
||||
/**
|
||||
* Bind to a given IP/port and listen for new connections
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `host_ip` - a `net::ip::ip_addr` representing a unique IP
|
||||
* (versions 4 or 6)
|
||||
* * `port` - a uint representing the port to listen on
|
||||
* * `backlog` - a uint representing the number of incoming connections
|
||||
* to cache in memory
|
||||
* * `hl_loop` - a `uv::hl::high_level_loop` that the tcp request will run on
|
||||
* * `on_establish_cb` - a callback that is evaluated if/when the listener
|
||||
* is successfully established. it takes no parameters
|
||||
* * `new_connect_cb` - a callback to be evaluated, on the libuv thread,
|
||||
* whenever a client attempts to conect on the provided ip/port. the
|
||||
* callback's arguments are:
|
||||
* * `new_conn` - an opaque type that can be passed to
|
||||
* `net::tcp::accept` in order to be converted to a `tcp_socket`.
|
||||
* * `kill_ch` - channel of type `comm::chan<option<tcp_err_data>>`. this
|
||||
* channel can be used to send a message to cause `listen` to begin
|
||||
* closing the underlying libuv data structures.
|
||||
*
|
||||
* # returns
|
||||
*
|
||||
* a `result` instance containing empty data of type `()` on a
|
||||
* successful/normal shutdown, and a `tcp_listen_err_data` enum in the event
|
||||
* of listen exiting because of an error
|
||||
*/
|
||||
fn listen(-host_ip: ip::ip_addr, port: uint, backlog: uint,
|
||||
iotask: iotask,
|
||||
on_establish_cb: fn~(comm::chan<option<tcp_err_data>>),
|
||||
|
|
@ -721,28 +715,26 @@ fn listen_common(-host_ip: ip::ip_addr, port: uint, backlog: uint,
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Convert a `net::tcp::tcp_socket` to a `net::tcp::tcp_socket_buf`.
|
||||
|
||||
This function takes ownership of a `net::tcp::tcp_socket`, returning it
|
||||
stored within a buffered wrapper, which can be converted to a `io::reader`
|
||||
or `io::writer`
|
||||
|
||||
# Arguments
|
||||
|
||||
* `sock` -- a `net::tcp::tcp_socket` that you want to buffer
|
||||
|
||||
# Returns
|
||||
|
||||
A buffered wrapper that you can cast as an `io::reader` or `io::writer`
|
||||
"]
|
||||
/**
|
||||
* Convert a `net::tcp::tcp_socket` to a `net::tcp::tcp_socket_buf`.
|
||||
*
|
||||
* This function takes ownership of a `net::tcp::tcp_socket`, returning it
|
||||
* stored within a buffered wrapper, which can be converted to a `io::reader`
|
||||
* or `io::writer`
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `sock` -- a `net::tcp::tcp_socket` that you want to buffer
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A buffered wrapper that you can cast as an `io::reader` or `io::writer`
|
||||
*/
|
||||
fn socket_buf(-sock: tcp_socket) -> tcp_socket_buf {
|
||||
tcp_socket_buf(@{ sock: sock, mut buf: []/~ })
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Convenience methods extending `net::tcp::tcp_socket`
|
||||
"]
|
||||
/// Convenience methods extending `net::tcp::tcp_socket`
|
||||
impl tcp_socket for tcp_socket {
|
||||
fn read_start() -> result::result<comm::port<
|
||||
result::result<~[u8], tcp_err_data>>, tcp_err_data> {
|
||||
|
|
@ -771,9 +763,7 @@ impl tcp_socket for tcp_socket {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Implementation of `io::reader` iface for a buffered `net::tcp::tcp_socket`
|
||||
"]
|
||||
/// Implementation of `io::reader` iface for a buffered `net::tcp::tcp_socket`
|
||||
impl tcp_socket_buf of io::reader for @tcp_socket_buf {
|
||||
fn read_bytes(amt: uint) -> [u8]/~ {
|
||||
let has_amt_available =
|
||||
|
|
@ -819,9 +809,7 @@ impl tcp_socket_buf of io::reader for @tcp_socket_buf {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Implementation of `io::reader` iface for a buffered `net::tcp::tcp_socket`
|
||||
"]
|
||||
/// Implementation of `io::reader` iface for a buffered `net::tcp::tcp_socket`
|
||||
impl tcp_socket_buf of io::writer for @tcp_socket_buf {
|
||||
fn write(data: [const u8]/&) unsafe {
|
||||
let socket_data_ptr =
|
||||
|
|
|
|||
|
|
@ -8,18 +8,22 @@ import core::vec::extensions;
|
|||
|
||||
export map, mapi, alli, any, mapi_factory;
|
||||
|
||||
#[doc="The maximum number of tasks this module will spawn for a single
|
||||
operation."]
|
||||
/**
|
||||
* The maximum number of tasks this module will spawn for a single
|
||||
* operation.
|
||||
*/
|
||||
const max_tasks : uint = 32u;
|
||||
|
||||
#[doc="The minimum number of elements each task will process."]
|
||||
/// The minimum number of elements each task will process.
|
||||
const min_granularity : uint = 1024u;
|
||||
|
||||
#[doc="An internal helper to map a function over a large vector and
|
||||
return the intermediate results.
|
||||
|
||||
This is used to build most of the other parallel vector functions,
|
||||
like map or alli."]
|
||||
/**
|
||||
* An internal helper to map a function over a large vector and
|
||||
* return the intermediate results.
|
||||
*
|
||||
* This is used to build most of the other parallel vector functions,
|
||||
* like map or alli.
|
||||
*/
|
||||
fn map_slices<A: copy send, B: copy send>(
|
||||
xs: ~[A],
|
||||
f: fn() -> fn~(uint, v: &[A]) -> B)
|
||||
|
|
@ -75,7 +79,7 @@ fn map_slices<A: copy send, B: copy send>(
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="A parallel version of map."]
|
||||
/// A parallel version of map.
|
||||
fn map<A: copy send, B: copy send>(xs: ~[A], f: fn~(A) -> B) -> ~[B] {
|
||||
vec::concat(map_slices(xs, || {
|
||||
fn~(_base: uint, slice : &[A], copy f) -> ~[B] {
|
||||
|
|
@ -84,7 +88,7 @@ fn map<A: copy send, B: copy send>(xs: ~[A], f: fn~(A) -> B) -> ~[B] {
|
|||
}))
|
||||
}
|
||||
|
||||
#[doc="A parallel version of mapi."]
|
||||
/// A parallel version of mapi.
|
||||
fn mapi<A: copy send, B: copy send>(xs: ~[A],
|
||||
f: fn~(uint, A) -> B) -> ~[B] {
|
||||
let slices = map_slices(xs, || {
|
||||
|
|
@ -100,10 +104,12 @@ fn mapi<A: copy send, B: copy send>(xs: ~[A],
|
|||
r
|
||||
}
|
||||
|
||||
#[doc="A parallel version of mapi.
|
||||
|
||||
In this case, f is a function that creates functions to run over the
|
||||
inner elements. This is to skirt the need for copy constructors."]
|
||||
/**
|
||||
* A parallel version of mapi.
|
||||
*
|
||||
* In this case, f is a function that creates functions to run over the
|
||||
* inner elements. This is to skirt the need for copy constructors.
|
||||
*/
|
||||
fn mapi_factory<A: copy send, B: copy send>(
|
||||
xs: ~[A], f: fn() -> fn~(uint, A) -> B) -> ~[B] {
|
||||
let slices = map_slices(xs, || {
|
||||
|
|
@ -120,7 +126,7 @@ fn mapi_factory<A: copy send, B: copy send>(
|
|||
r
|
||||
}
|
||||
|
||||
#[doc="Returns true if the function holds for all elements in the vector."]
|
||||
/// Returns true if the function holds for all elements in the vector.
|
||||
fn alli<A: copy send>(xs: ~[A], f: fn~(uint, A) -> bool) -> bool {
|
||||
do vec::all(map_slices(xs, || {
|
||||
fn~(base: uint, slice : &[A], copy f) -> bool {
|
||||
|
|
@ -131,7 +137,7 @@ fn alli<A: copy send>(xs: ~[A], f: fn~(uint, A) -> bool) -> bool {
|
|||
})) |x| { x }
|
||||
}
|
||||
|
||||
#[doc="Returns true if the function holds for any elements in the vector."]
|
||||
/// Returns true if the function holds for any elements in the vector.
|
||||
fn any<A: copy send>(xs: ~[A], f: fn~(A) -> bool) -> bool {
|
||||
do vec::any(map_slices(xs, || {
|
||||
fn~(_base : uint, slice: &[A], copy f) -> bool {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Support code for serialization."];
|
||||
//! Support code for serialization.
|
||||
|
||||
use core;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
#[doc ="
|
||||
An implementation of the SHA-1 cryptographic hash.
|
||||
|
||||
First create a `sha1` object using the `sha1` constructor, then
|
||||
feed it input using the `input` or `input_str` methods, which may be
|
||||
called any number of times.
|
||||
|
||||
After the entire input has been fed to the hash read the result using
|
||||
the `result` or `result_str` methods.
|
||||
|
||||
The `sha1` object may be reused to create multiple hashes by calling
|
||||
the `reset` method.
|
||||
"];
|
||||
/*!
|
||||
* An implementation of the SHA-1 cryptographic hash.
|
||||
*
|
||||
* First create a `sha1` object using the `sha1` constructor, then
|
||||
* feed it input using the `input` or `input_str` methods, which may be
|
||||
* called any number of times.
|
||||
*
|
||||
* After the entire input has been fed to the hash read the result using
|
||||
* the `result` or `result_str` methods.
|
||||
*
|
||||
* The `sha1` object may be reused to create multiple hashes by calling
|
||||
* the `reset` method.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A SHA-1 implementation derived from Paul E. Jones's reference
|
||||
|
|
@ -19,23 +19,23 @@ the `reset` method.
|
|||
*/
|
||||
export sha1;
|
||||
|
||||
#[doc = "The SHA-1 interface"]
|
||||
/// The SHA-1 interface
|
||||
iface sha1 {
|
||||
#[doc = "Provide message input as bytes"]
|
||||
/// Provide message input as bytes
|
||||
fn input(~[u8]);
|
||||
#[doc = "Provide message input as string"]
|
||||
/// Provide message input as string
|
||||
fn input_str(str);
|
||||
#[doc = "
|
||||
Read the digest as a vector of 20 bytes. After calling this no further
|
||||
input may be provided until reset is called.
|
||||
"]
|
||||
/**
|
||||
* Read the digest as a vector of 20 bytes. After calling this no further
|
||||
* input may be provided until reset is called.
|
||||
*/
|
||||
fn result() -> ~[u8];
|
||||
#[doc = "
|
||||
Read the digest as a hex string. After calling this no further
|
||||
input may be provided until reset is called.
|
||||
"]
|
||||
/**
|
||||
* Read the digest as a hex string. After calling this no further
|
||||
* input may be provided until reset is called.
|
||||
*/
|
||||
fn result_str() -> str;
|
||||
#[doc = "Reset the SHA-1 state for reuse"]
|
||||
/// Reset the SHA-1 state for reuse
|
||||
fn reset();
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ const k2: u32 = 0x8F1BBCDCu32;
|
|||
const k3: u32 = 0xCA62C1D6u32;
|
||||
|
||||
|
||||
#[doc = "Construct a `sha` object"]
|
||||
/// Construct a `sha` object
|
||||
fn sha1() -> sha1 {
|
||||
type sha1state =
|
||||
{h: ~[mut u32],
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#[doc = "
|
||||
A simple map based on a vector for small integer keys. Space requirements
|
||||
are O(highest integer key).
|
||||
"];
|
||||
/*!
|
||||
* A simple map based on a vector for small integer keys. Space requirements
|
||||
* are O(highest integer key).
|
||||
*/
|
||||
import core::option;
|
||||
import core::option::{some, none};
|
||||
import dvec::{dvec, extensions};
|
||||
|
|
@ -10,36 +10,36 @@ import dvec::{dvec, extensions};
|
|||
// requires this to be.
|
||||
type smallintmap<T: copy> = @{v: dvec<option<T>>};
|
||||
|
||||
#[doc = "Create a smallintmap"]
|
||||
/// Create a smallintmap
|
||||
fn mk<T: copy>() -> smallintmap<T> {
|
||||
ret @{v: dvec()};
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Add a value to the map. If the map already contains a value for
|
||||
the specified key then the original value is replaced.
|
||||
"]
|
||||
/**
|
||||
* Add a value to the map. If the map already contains a value for
|
||||
* the specified key then the original value is replaced.
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn insert<T: copy>(self: smallintmap<T>, key: uint, val: T) {
|
||||
self.v.grow_set_elt(key, none, some(val));
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Get the value for the specified key. If the key does not exist
|
||||
in the map then returns none
|
||||
"]
|
||||
/**
|
||||
* Get the value for the specified key. If the key does not exist
|
||||
* in the map then returns none
|
||||
*/
|
||||
fn find<T: copy>(self: smallintmap<T>, key: uint) -> option<T> {
|
||||
if key < self.v.len() { ret self.v.get_elt(key); }
|
||||
ret none::<T>;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Get the value for the specified key
|
||||
|
||||
# Failure
|
||||
|
||||
If the key does not exist in the map
|
||||
"]
|
||||
/**
|
||||
* Get the value for the specified key
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* If the key does not exist in the map
|
||||
*/
|
||||
fn get<T: copy>(self: smallintmap<T>, key: uint) -> T {
|
||||
alt find(self, key) {
|
||||
none { #error("smallintmap::get(): key not present"); fail; }
|
||||
|
|
@ -47,14 +47,12 @@ fn get<T: copy>(self: smallintmap<T>, key: uint) -> T {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns true if the map contains a value for the specified key
|
||||
"]
|
||||
/// Returns true if the map contains a value for the specified key
|
||||
fn contains_key<T: copy>(self: smallintmap<T>, key: uint) -> bool {
|
||||
ret !option::is_none(find(self, key));
|
||||
}
|
||||
|
||||
#[doc = "Implements the map::map interface for smallintmap"]
|
||||
/// Implements the map::map interface for smallintmap
|
||||
impl <V: copy> of map::map<uint, V> for smallintmap<V> {
|
||||
fn size() -> uint {
|
||||
let mut sz = 0u;
|
||||
|
|
@ -106,7 +104,7 @@ impl <V: copy> of map::map<uint, V> for smallintmap<V> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Cast the given smallintmap to a map::map"]
|
||||
/// Cast the given smallintmap to a map::map
|
||||
fn as_map<V: copy>(s: smallintmap<V>) -> map::map<uint, V> {
|
||||
s as map::map::<uint, V>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Sorting methods"];
|
||||
//! Sorting methods
|
||||
import vec::{len, push};
|
||||
import int::{eq, ord};
|
||||
|
||||
|
|
@ -9,12 +9,12 @@ export quick_sort3;
|
|||
|
||||
type le<T> = fn(T, T) -> bool;
|
||||
|
||||
#[doc = "
|
||||
Merge sort. Returns a new vector containing the sorted list.
|
||||
|
||||
Has worst case O(n log n) performance, best case O(n), but
|
||||
is not space efficient. This is a stable sort.
|
||||
"]
|
||||
/**
|
||||
* Merge sort. Returns a new vector containing the sorted list.
|
||||
*
|
||||
* Has worst case O(n log n) performance, best case O(n), but
|
||||
* is not space efficient. This is a stable sort.
|
||||
*/
|
||||
fn merge_sort<T: copy>(le: le<T>, v: ~[const T]) -> ~[T] {
|
||||
type slice = (uint, uint);
|
||||
|
||||
|
|
@ -84,12 +84,12 @@ fn qsort<T: copy>(compare_func: le<T>, arr: ~[mut T], left: uint,
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Quicksort. Sorts a mut vector in place.
|
||||
|
||||
Has worst case O(n^2) performance, average case O(n log n).
|
||||
This is an unstable sort.
|
||||
"]
|
||||
/**
|
||||
* Quicksort. Sorts a mut vector in place.
|
||||
*
|
||||
* Has worst case O(n^2) performance, average case O(n log n).
|
||||
* This is an unstable sort.
|
||||
*/
|
||||
fn quick_sort<T: copy>(compare_func: le<T>, arr: ~[mut T]) {
|
||||
if len::<T>(arr) == 0u { ret; }
|
||||
qsort::<T>(compare_func, arr, 0u, len::<T>(arr) - 1u);
|
||||
|
|
@ -143,16 +143,16 @@ fn qsort3<T: copy>(compare_func_lt: le<T>, compare_func_eq: le<T>,
|
|||
qsort3::<T>(compare_func_lt, compare_func_eq, arr, i, right);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Fancy quicksort. Sorts a mut vector in place.
|
||||
|
||||
Based on algorithm presented by [Sedgewick and Bentley]/~
|
||||
(http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf).
|
||||
According to these slides this is the algorithm of choice for
|
||||
'randomly ordered keys, abstract compare' & 'small number of key values'.
|
||||
|
||||
This is an unstable sort.
|
||||
"]
|
||||
/**
|
||||
* Fancy quicksort. Sorts a mut vector in place.
|
||||
*
|
||||
* Based on algorithm presented by [Sedgewick and Bentley]/~
|
||||
* (http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf).
|
||||
* According to these slides this is the algorithm of choice for
|
||||
* 'randomly ordered keys, abstract compare' & 'small number of key values'.
|
||||
*
|
||||
* This is an unstable sort.
|
||||
*/
|
||||
fn quick_sort3<T: copy ord eq>(arr: ~[mut T]) {
|
||||
if len::<T>(arr) == 0u { ret; }
|
||||
qsort3::<T>(|x, y| x.lt(y), |x, y| x.eq(y), arr, 0,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#[comment = "The Rust standard library"];
|
||||
#[license = "MIT"];
|
||||
#[crate_type = "lib"];
|
||||
#[doc = "The Rust standard library"];
|
||||
//! The Rust standard library
|
||||
|
||||
#[no_core];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Temporary files and directories"];
|
||||
//! Temporary files and directories
|
||||
|
||||
import core::option;
|
||||
import option::{none, some};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Simple ANSI color library"];
|
||||
//! Simple ANSI color library
|
||||
|
||||
import core::option;
|
||||
|
||||
|
|
@ -25,13 +25,13 @@ const color_bright_white: u8 = 15u8;
|
|||
|
||||
fn esc(writer: io::writer) { writer.write([0x1bu8, '[' as u8]/~); }
|
||||
|
||||
#[doc = "Reset the foreground and background colors to default"]
|
||||
/// Reset the foreground and background colors to default
|
||||
fn reset(writer: io::writer) {
|
||||
esc(writer);
|
||||
writer.write(~['0' as u8, 'm' as u8]);
|
||||
}
|
||||
|
||||
#[doc = "Returns true if the terminal supports color"]
|
||||
/// Returns true if the terminal supports color
|
||||
fn color_supported() -> bool {
|
||||
let supported_terms = ~["xterm-color", "xterm",
|
||||
"screen-bce", "xterm-256color"];
|
||||
|
|
@ -54,12 +54,12 @@ fn set_color(writer: io::writer, first_char: u8, color: u8) {
|
|||
writer.write(~[first_char, ('0' as u8) + color, 'm' as u8]);
|
||||
}
|
||||
|
||||
#[doc = "Set the foreground color"]
|
||||
/// Set the foreground color
|
||||
fn fg(writer: io::writer, color: u8) {
|
||||
ret set_color(writer, '3' as u8, color);
|
||||
}
|
||||
|
||||
#[doc = "Set the background color"]
|
||||
/// Set the background color
|
||||
fn bg(writer: io::writer, color: u8) {
|
||||
ret set_color(writer, '4' as u8, color);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ extern mod rustrt {
|
|||
fn rust_mktime(&&tm: tm, &sec: i64);
|
||||
}
|
||||
|
||||
#[doc = "A record specifying a time value in seconds and microseconds."]
|
||||
/// A record specifying a time value in seconds and microseconds.
|
||||
type timespec = {sec: i64, nsec: i32};
|
||||
|
||||
#[doc = "
|
||||
Returns the current time as a `timespec` containing the seconds and
|
||||
microseconds since 1970-01-01T00:00:00Z.
|
||||
"]
|
||||
/**
|
||||
* Returns the current time as a `timespec` containing the seconds and
|
||||
* microseconds since 1970-01-01T00:00:00Z.
|
||||
*/
|
||||
fn get_time() -> timespec {
|
||||
let mut sec = 0i64;
|
||||
let mut nsec = 0i32;
|
||||
|
|
@ -43,20 +43,20 @@ fn get_time() -> timespec {
|
|||
ret {sec: sec, nsec: nsec};
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns the current value of a high-resolution performance counter
|
||||
in nanoseconds since an unspecified epoch.
|
||||
"]
|
||||
/**
|
||||
* Returns the current value of a high-resolution performance counter
|
||||
* in nanoseconds since an unspecified epoch.
|
||||
*/
|
||||
fn precise_time_ns() -> u64 {
|
||||
let mut ns = 0u64;
|
||||
rustrt::precise_time_ns(ns);
|
||||
ns
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns the current value of a high-resolution performance counter
|
||||
in seconds since an unspecified epoch.
|
||||
"]
|
||||
/**
|
||||
* Returns the current value of a high-resolution performance counter
|
||||
* in seconds since an unspecified epoch.
|
||||
*/
|
||||
fn precise_time_s() -> float {
|
||||
ret (precise_time_ns() as float) / 1000000000.;
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ fn empty_tm() -> tm {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Returns the specified time in UTC"]
|
||||
/// Returns the specified time in UTC
|
||||
fn at_utc(clock: timespec) -> tm {
|
||||
let mut {sec, nsec} = clock;
|
||||
let mut tm = empty_tm();
|
||||
|
|
@ -105,12 +105,12 @@ fn at_utc(clock: timespec) -> tm {
|
|||
tm
|
||||
}
|
||||
|
||||
#[doc = "Returns the current time in UTC"]
|
||||
/// Returns the current time in UTC
|
||||
fn now_utc() -> tm {
|
||||
at_utc(get_time())
|
||||
}
|
||||
|
||||
#[doc = "Returns the specified time in the local timezone"]
|
||||
/// Returns the specified time in the local timezone
|
||||
fn at(clock: timespec) -> tm {
|
||||
let mut {sec, nsec} = clock;
|
||||
let mut tm = empty_tm();
|
||||
|
|
@ -118,12 +118,12 @@ fn at(clock: timespec) -> tm {
|
|||
tm
|
||||
}
|
||||
|
||||
#[doc = "Returns the current time in the local timezone"]
|
||||
/// Returns the current time in the local timezone
|
||||
fn now() -> tm {
|
||||
at(get_time())
|
||||
}
|
||||
|
||||
#[doc = "Parses the time from the string according to the format string."]
|
||||
/// Parses the time from the string according to the format string.
|
||||
fn strptime(s: str, format: str) -> result<tm, str> {
|
||||
type tm_mut = {
|
||||
mut tm_sec: i32,
|
||||
|
|
@ -751,7 +751,7 @@ fn strftime(format: str, tm: tm) -> str {
|
|||
}
|
||||
|
||||
impl tm for tm {
|
||||
#[doc = "Convert time to the seconds from January 1, 1970"]
|
||||
/// Convert time to the seconds from January 1, 1970
|
||||
fn to_timespec() -> timespec {
|
||||
let mut sec = 0i64;
|
||||
if self.tm_gmtoff == 0_i32 {
|
||||
|
|
@ -762,31 +762,31 @@ impl tm for tm {
|
|||
{ sec: sec, nsec: self.tm_nsec }
|
||||
}
|
||||
|
||||
#[doc = "Convert time to the local timezone"]
|
||||
/// Convert time to the local timezone
|
||||
fn to_local() -> tm {
|
||||
at(self.to_timespec())
|
||||
}
|
||||
|
||||
#[doc = "Convert time to the UTC"]
|
||||
/// Convert time to the UTC
|
||||
fn to_utc() -> tm {
|
||||
at_utc(self.to_timespec())
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Return a string of the current time in the form
|
||||
\"Thu Jan 1 00:00:00 1970\".
|
||||
"]
|
||||
/**
|
||||
* Return a string of the current time in the form
|
||||
* "Thu Jan 1 00:00:00 1970".
|
||||
*/
|
||||
fn ctime() -> str { self.strftime("%c") }
|
||||
|
||||
#[doc = "Formats the time according to the format string."]
|
||||
/// Formats the time according to the format string.
|
||||
fn strftime(format: str) -> str { strftime(format, self) }
|
||||
|
||||
#[doc = "
|
||||
Returns a time string formatted according to RFC 822.
|
||||
|
||||
local: \"Thu, 22 Mar 2012 07:53:18 PST\"
|
||||
utc: \"Thu, 22 Mar 2012 14:53:18 UTC\"
|
||||
"]
|
||||
/**
|
||||
* Returns a time string formatted according to RFC 822.
|
||||
*
|
||||
* local: "Thu, 22 Mar 2012 07:53:18 PST"
|
||||
* utc: "Thu, 22 Mar 2012 14:53:18 UTC"
|
||||
*/
|
||||
fn rfc822() -> str {
|
||||
if self.tm_gmtoff == 0_i32 {
|
||||
self.strftime("%a, %d %b %Y %T GMT")
|
||||
|
|
@ -795,22 +795,22 @@ impl tm for tm {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns a time string formatted according to RFC 822 with Zulu time.
|
||||
|
||||
local: \"Thu, 22 Mar 2012 07:53:18 -0700\"
|
||||
utc: \"Thu, 22 Mar 2012 14:53:18 -0000\"
|
||||
"]
|
||||
/**
|
||||
* Returns a time string formatted according to RFC 822 with Zulu time.
|
||||
*
|
||||
* local: "Thu, 22 Mar 2012 07:53:18 -0700"
|
||||
* utc: "Thu, 22 Mar 2012 14:53:18 -0000"
|
||||
*/
|
||||
fn rfc822z() -> str {
|
||||
self.strftime("%a, %d %b %Y %T %z")
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns a time string formatted according to ISO 8601.
|
||||
|
||||
local: \"2012-02-22T07:53:18-07:00\"
|
||||
utc: \"2012-02-22T14:53:18Z\"
|
||||
"]
|
||||
/**
|
||||
* Returns a time string formatted according to ISO 8601.
|
||||
*
|
||||
* local: "2012-02-22T07:53:18-07:00"
|
||||
* utc: "2012-02-22T14:53:18Z"
|
||||
*/
|
||||
fn rfc3339() -> str {
|
||||
if self.tm_gmtoff == 0_i32 {
|
||||
self.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
|
|
|||
|
|
@ -1,28 +1,26 @@
|
|||
#[doc ="
|
||||
Utilities that leverage libuv's `uv_timer_*` API
|
||||
"];
|
||||
//! Utilities that leverage libuv's `uv_timer_*` API
|
||||
|
||||
import uv = uv;
|
||||
import uv::iotask;
|
||||
import iotask::iotask;
|
||||
export delayed_send, sleep, recv_timeout;
|
||||
|
||||
#[doc = "
|
||||
Wait for timeout period then send provided value over a channel
|
||||
|
||||
This call returns immediately. Useful as the building block for a number
|
||||
of higher-level timer functions.
|
||||
|
||||
Is not guaranteed to wait for exactly the specified time, but will wait
|
||||
for *at least* that period of time.
|
||||
|
||||
# Arguments
|
||||
|
||||
* `hl_loop` - a `uv::hl::high_level_loop` that the tcp request will run on
|
||||
* msecs - a timeout period, in milliseconds, to wait
|
||||
* ch - a channel of type T to send a `val` on
|
||||
* val - a value of type T to send over the provided `ch`
|
||||
"]
|
||||
/**
|
||||
* Wait for timeout period then send provided value over a channel
|
||||
*
|
||||
* This call returns immediately. Useful as the building block for a number
|
||||
* of higher-level timer functions.
|
||||
*
|
||||
* Is not guaranteed to wait for exactly the specified time, but will wait
|
||||
* for *at least* that period of time.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `hl_loop` - a `uv::hl::high_level_loop` that the tcp request will run on
|
||||
* * msecs - a timeout period, in milliseconds, to wait
|
||||
* * ch - a channel of type T to send a `val` on
|
||||
* * val - a value of type T to send over the provided `ch`
|
||||
*/
|
||||
fn delayed_send<T: copy send>(iotask: iotask,
|
||||
msecs: uint, ch: comm::chan<T>, val: T) {
|
||||
unsafe {
|
||||
|
|
@ -60,17 +58,17 @@ fn delayed_send<T: copy send>(iotask: iotask,
|
|||
};
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Blocks the current task for (at least) the specified time period.
|
||||
|
||||
Is not guaranteed to sleep for exactly the specified time, but will sleep
|
||||
for *at least* that period of time.
|
||||
|
||||
# Arguments
|
||||
|
||||
* `iotask` - a `uv::iotask` that the tcp request will run on
|
||||
* msecs - an amount of time, in milliseconds, for the current task to block
|
||||
"]
|
||||
/**
|
||||
* Blocks the current task for (at least) the specified time period.
|
||||
*
|
||||
* Is not guaranteed to sleep for exactly the specified time, but will sleep
|
||||
* for *at least* that period of time.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `iotask` - a `uv::iotask` that the tcp request will run on
|
||||
* * msecs - an amount of time, in milliseconds, for the current task to block
|
||||
*/
|
||||
fn sleep(iotask: iotask, msecs: uint) {
|
||||
let exit_po = comm::port::<()>();
|
||||
let exit_ch = comm::chan(exit_po);
|
||||
|
|
@ -78,25 +76,26 @@ fn sleep(iotask: iotask, msecs: uint) {
|
|||
comm::recv(exit_po);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Receive on a port for (up to) a specified time, then return an `option<T>`
|
||||
|
||||
This call will block to receive on the provided port for up to the specified
|
||||
timeout. Depending on whether the provided port receives in that time period,
|
||||
`recv_timeout` will return an `option<T>` representing the result.
|
||||
|
||||
# Arguments
|
||||
|
||||
* `iotask' - `uv::iotask` that the tcp request will run on
|
||||
* msecs - an mount of time, in milliseconds, to wait to receive
|
||||
* wait_port - a `comm::port<T>` to receive on
|
||||
|
||||
# Returns
|
||||
|
||||
An `option<T>` representing the outcome of the call. If the call `recv`'d on
|
||||
the provided port in the allotted timeout period, then the result will be a
|
||||
`some(T)`. If not, then `none` will be returned.
|
||||
"]
|
||||
/**
|
||||
* Receive on a port for (up to) a specified time, then return an `option<T>`
|
||||
*
|
||||
* This call will block to receive on the provided port for up to the
|
||||
* specified timeout. Depending on whether the provided port receives in that
|
||||
* time period, `recv_timeout` will return an `option<T>` representing the
|
||||
* result.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `iotask' - `uv::iotask` that the tcp request will run on
|
||||
* * msecs - an mount of time, in milliseconds, to wait to receive
|
||||
* * wait_port - a `comm::port<T>` to receive on
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* An `option<T>` representing the outcome of the call. If the call `recv`'d
|
||||
* on the provided port in the allotted timeout period, then the result will
|
||||
* be a `some(T)`. If not, then `none` will be returned.
|
||||
*/
|
||||
fn recv_timeout<T: copy send>(iotask: iotask,
|
||||
msecs: uint,
|
||||
wait_po: comm::port<T>) -> option<T> {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#[doc = "
|
||||
A key,value store that works on anything.
|
||||
|
||||
This works using a binary search tree. In the first version, it's a
|
||||
very naive algorithm, but it will probably be updated to be a
|
||||
red-black tree or something else.
|
||||
"];
|
||||
/*!
|
||||
* A key,value store that works on anything.
|
||||
*
|
||||
* This works using a binary search tree. In the first version, it's a
|
||||
* very naive algorithm, but it will probably be updated to be a
|
||||
* red-black tree or something else.
|
||||
*/
|
||||
|
||||
import core::option::{some, none};
|
||||
import option = core::option;
|
||||
|
|
@ -25,10 +25,10 @@ enum tree_node<K, V> = {
|
|||
mut right: tree_edge<K, V>
|
||||
};
|
||||
|
||||
#[doc = "Create a treemap"]
|
||||
/// Create a treemap
|
||||
fn treemap<K, V>() -> treemap<K, V> { @mut none }
|
||||
|
||||
#[doc = "Insert a value into the map"]
|
||||
/// Insert a value into the map
|
||||
fn insert<K: copy, V: copy>(m: &mut tree_edge<K, V>, k: K, v: V) {
|
||||
alt copy *m {
|
||||
none {
|
||||
|
|
@ -50,7 +50,7 @@ fn insert<K: copy, V: copy>(m: &mut tree_edge<K, V>, k: K, v: V) {
|
|||
};
|
||||
}
|
||||
|
||||
#[doc = "Find a value based on the key"]
|
||||
/// Find a value based on the key
|
||||
fn find<K: copy, V: copy>(m: &const tree_edge<K, V>, k: K) -> option<V> {
|
||||
alt copy *m {
|
||||
none { none }
|
||||
|
|
@ -68,7 +68,7 @@ fn find<K: copy, V: copy>(m: &const tree_edge<K, V>, k: K) -> option<V> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Visit all pairs in the map in order."]
|
||||
/// Visit all pairs in the map in order.
|
||||
fn traverse<K, V: copy>(m: &const tree_edge<K, V>, f: fn(K, V)) {
|
||||
alt copy *m {
|
||||
none { }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#[doc = "The identity function"]
|
||||
/// The identity function
|
||||
pure fn id<T: copy>(x: T) -> T { x }
|
||||
|
||||
/* FIXME (issue #141): See test/run-pass/constrained-type.rs. Uncomment
|
||||
* the constraint once fixed. */
|
||||
#[doc = "A rational number"]
|
||||
/// A rational number
|
||||
type rational = {num: int, den: int}; // : int::positive(*.den);
|
||||
|
||||
pure fn rational_leq(x: rational, y: rational) -> bool {
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
#[doc = "
|
||||
Rust bindings to libuv
|
||||
|
||||
This is the base-module for various levels of bindings to
|
||||
the libuv library.
|
||||
|
||||
These modules are seeing heavy work, currently, and the final
|
||||
API layout should not be inferred from its current form.
|
||||
|
||||
This base module currently contains a historical, rust-based
|
||||
implementation of a few libuv operations that hews closely to
|
||||
the patterns of the libuv C-API. It was used, mostly, to explore
|
||||
some implementation details and will most likely be deprecated
|
||||
in the near future.
|
||||
|
||||
The `ll` module contains low-level mappings for working directly
|
||||
with the libuv C-API.
|
||||
|
||||
The `hl` module contains a set of tools library developers can
|
||||
use for interacting with an active libuv loop. This modules's
|
||||
API is meant to be used to write high-level,
|
||||
rust-idiomatic abstractions for utilizes libuv's asynchronous IO
|
||||
facilities.
|
||||
"];
|
||||
/*!
|
||||
* Rust bindings to libuv
|
||||
*
|
||||
* This is the base-module for various levels of bindings to
|
||||
* the libuv library.
|
||||
*
|
||||
* These modules are seeing heavy work, currently, and the final
|
||||
* API layout should not be inferred from its current form.
|
||||
*
|
||||
* This base module currently contains a historical, rust-based
|
||||
* implementation of a few libuv operations that hews closely to
|
||||
* the patterns of the libuv C-API. It was used, mostly, to explore
|
||||
* some implementation details and will most likely be deprecated
|
||||
* in the near future.
|
||||
*
|
||||
* The `ll` module contains low-level mappings for working directly
|
||||
* with the libuv C-API.
|
||||
*
|
||||
* The `hl` module contains a set of tools library developers can
|
||||
* use for interacting with an active libuv loop. This modules's
|
||||
* API is meant to be used to write high-level,
|
||||
* rust-idiomatic abstractions for utilizes libuv's asynchronous IO
|
||||
* facilities.
|
||||
*/
|
||||
|
||||
import ll = uv_ll;
|
||||
export ll;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
#[doc="
|
||||
A process-wide libuv event loop for library use.
|
||||
"];
|
||||
//! A process-wide libuv event loop for library use.
|
||||
|
||||
export get;
|
||||
|
||||
|
|
@ -16,18 +14,18 @@ extern mod rustrt {
|
|||
fn rust_uv_get_kernel_global_chan_ptr() -> *libc::uintptr_t;
|
||||
}
|
||||
|
||||
#[doc ="
|
||||
Race-free helper to get access to a global task where a libuv
|
||||
loop is running.
|
||||
|
||||
Use `uv::hl::interact` to do operations against the global
|
||||
loop that this function returns.
|
||||
|
||||
# Return
|
||||
|
||||
* A `hl::high_level_loop` that encapsulates communication with the global
|
||||
loop.
|
||||
"]
|
||||
/**
|
||||
* Race-free helper to get access to a global task where a libuv
|
||||
* loop is running.
|
||||
*
|
||||
* Use `uv::hl::interact` to do operations against the global
|
||||
* loop that this function returns.
|
||||
*
|
||||
* # Return
|
||||
*
|
||||
* * A `hl::high_level_loop` that encapsulates communication with the global
|
||||
* loop.
|
||||
*/
|
||||
fn get() -> iotask {
|
||||
ret get_monitor_task_gl();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
#[doc = "
|
||||
|
||||
A task-based interface to the uv loop
|
||||
|
||||
The I/O task runs in its own single-threaded scheduler. By using the
|
||||
`interact` function you can execute code in a uv callback.
|
||||
|
||||
"];
|
||||
/*!
|
||||
* A task-based interface to the uv loop
|
||||
*
|
||||
* The I/O task runs in its own single-threaded scheduler. By using the
|
||||
* `interact` function you can execute code in a uv callback.
|
||||
*/
|
||||
|
||||
export iotask;
|
||||
export spawn_iotask;
|
||||
|
|
@ -17,9 +15,7 @@ import ptr::addr_of;
|
|||
import comm::{port, chan, methods, listen};
|
||||
import ll = uv_ll;
|
||||
|
||||
#[doc = "
|
||||
Used to abstract-away direct interaction with a libuv loop.
|
||||
"]
|
||||
/// Used to abstract-away direct interaction with a libuv loop.
|
||||
enum iotask {
|
||||
iotask_({
|
||||
async_handle: *ll::uv_async_t,
|
||||
|
|
@ -52,40 +48,40 @@ fn spawn_iotask(-builder: task::builder) -> iotask {
|
|||
}
|
||||
|
||||
|
||||
#[doc = "
|
||||
Provide a callback to be processed by `iotask`
|
||||
|
||||
The primary way to do operations again a running `iotask` that
|
||||
doesn't involve creating a uv handle via `safe_handle`
|
||||
|
||||
# Warning
|
||||
|
||||
This function is the only safe way to interact with _any_ `iotask`.
|
||||
Using functions in the `uv::ll` module outside of the `cb` passed into
|
||||
this function is _very dangerous_.
|
||||
|
||||
# Arguments
|
||||
|
||||
* iotask - a uv I/O task that you want to do operations against
|
||||
* cb - a function callback to be processed on the running loop's
|
||||
thread. The only parameter passed in is an opaque pointer representing the
|
||||
running `uv_loop_t*`. In the context of this callback, it is safe to use
|
||||
this pointer to do various uv_* API calls contained within the `uv::ll`
|
||||
module. It is not safe to send the `loop_ptr` param to this callback out
|
||||
via ports/chans.
|
||||
"]
|
||||
/**
|
||||
* Provide a callback to be processed by `iotask`
|
||||
*
|
||||
* The primary way to do operations again a running `iotask` that
|
||||
* doesn't involve creating a uv handle via `safe_handle`
|
||||
*
|
||||
* # Warning
|
||||
*
|
||||
* This function is the only safe way to interact with _any_ `iotask`.
|
||||
* Using functions in the `uv::ll` module outside of the `cb` passed into
|
||||
* this function is _very dangerous_.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * iotask - a uv I/O task that you want to do operations against
|
||||
* * cb - a function callback to be processed on the running loop's
|
||||
* thread. The only parameter passed in is an opaque pointer representing the
|
||||
* running `uv_loop_t*`. In the context of this callback, it is safe to use
|
||||
* this pointer to do various uv_* API calls contained within the `uv::ll`
|
||||
* module. It is not safe to send the `loop_ptr` param to this callback out
|
||||
* via ports/chans.
|
||||
*/
|
||||
unsafe fn interact(iotask: iotask,
|
||||
-cb: fn~(*c_void)) {
|
||||
send_msg(iotask, interaction(cb));
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Shut down the I/O task
|
||||
|
||||
Is used to signal to the loop that it should close the internally-held
|
||||
async handle and do a sanity check to make sure that all other handles are
|
||||
closed, causing a failure otherwise.
|
||||
"]
|
||||
/**
|
||||
* Shut down the I/O task
|
||||
*
|
||||
* Is used to signal to the loop that it should close the internally-held
|
||||
* async handle and do a sanity check to make sure that all other handles are
|
||||
* closed, causing a failure otherwise.
|
||||
*/
|
||||
fn exit(iotask: iotask) unsafe {
|
||||
send_msg(iotask, teardown_loop);
|
||||
}
|
||||
|
|
@ -98,9 +94,7 @@ enum iotask_msg {
|
|||
teardown_loop
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Run the loop and begin handling messages
|
||||
"]
|
||||
/// Run the loop and begin handling messages
|
||||
fn run_loop(iotask_ch: chan<iotask>) unsafe {
|
||||
|
||||
let loop_ptr = ll::loop_new();
|
||||
|
|
@ -147,7 +141,7 @@ fn send_msg(iotask: iotask,
|
|||
ll::async_send(iotask.async_handle);
|
||||
}
|
||||
|
||||
#[doc ="Dispatch all pending messages"]
|
||||
/// Dispatch all pending messages
|
||||
extern fn wake_up_cb(async_handle: *ll::uv_async_t,
|
||||
status: int) unsafe {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
#[doc = "
|
||||
Low-level bindings to the libuv library.
|
||||
|
||||
This module contains a set of direct, 'bare-metal' wrappers around
|
||||
the libuv C-API.
|
||||
|
||||
Also contained herein are a set of rust records that map, in
|
||||
approximate memory-size, to the libuv data structures. The record
|
||||
implementations are adjusted, per-platform, to match their respective
|
||||
representations.
|
||||
|
||||
There are also a collection of helper functions to ease interacting
|
||||
with the low-level API (such as a function to return the latest
|
||||
libuv error as a rust-formatted string).
|
||||
|
||||
As new functionality, existant in uv.h, is added to the rust stdlib,
|
||||
the mappings should be added in this module.
|
||||
|
||||
This module's implementation will hopefully be, eventually, replaced
|
||||
with per-platform, generated source files from rust-bindgen.
|
||||
"];
|
||||
/*!
|
||||
* Low-level bindings to the libuv library.
|
||||
*
|
||||
* This module contains a set of direct, 'bare-metal' wrappers around
|
||||
* the libuv C-API.
|
||||
*
|
||||
* Also contained herein are a set of rust records that map, in
|
||||
* approximate memory-size, to the libuv data structures. The record
|
||||
* implementations are adjusted, per-platform, to match their respective
|
||||
* representations.
|
||||
*
|
||||
* There are also a collection of helper functions to ease interacting
|
||||
* with the low-level API (such as a function to return the latest
|
||||
* libuv error as a rust-formatted string).
|
||||
*
|
||||
* As new functionality, existant in uv.h, is added to the rust stdlib,
|
||||
* the mappings should be added in this module.
|
||||
*
|
||||
* This module's implementation will hopefully be, eventually, replaced
|
||||
* with per-platform, generated source files from rust-bindgen.
|
||||
*/
|
||||
|
||||
import libc::size_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ fn is_self(d: ast::def) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Maps a binary operator to its precedence"]
|
||||
/// Maps a binary operator to its precedence
|
||||
fn operator_prec(op: ast::binop) -> uint {
|
||||
alt op {
|
||||
mul | div | rem { 12u }
|
||||
|
|
|
|||
|
|
@ -120,10 +120,10 @@ fn get_meta_item_name(meta: @ast::meta_item) -> ast::ident {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Gets the string value if the meta_item is a meta_name_value variant
|
||||
containing a string, otherwise none
|
||||
"]
|
||||
/**
|
||||
* Gets the string value if the meta_item is a meta_name_value variant
|
||||
* containing a string, otherwise none
|
||||
*/
|
||||
fn get_meta_item_value_str(meta: @ast::meta_item) -> option<@str> {
|
||||
alt meta.node {
|
||||
ast::meta_name_value(_, v) {
|
||||
|
|
@ -140,7 +140,7 @@ fn get_meta_item_value_str(meta: @ast::meta_item) -> option<@str> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Gets a list of inner meta items from a list meta_item type"]
|
||||
/// Gets a list of inner meta items from a list meta_item type
|
||||
fn get_meta_item_list(meta: @ast::meta_item) -> option<~[@ast::meta_item]> {
|
||||
alt meta.node {
|
||||
ast::meta_list(_, l) { option::some(/* FIXME (#2543) */ copy l) }
|
||||
|
|
@ -148,10 +148,10 @@ fn get_meta_item_list(meta: @ast::meta_item) -> option<~[@ast::meta_item]> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
If the meta item is a nam-value type with a string value then returns
|
||||
a tuple containing the name and string value, otherwise `none`
|
||||
"]
|
||||
/**
|
||||
* If the meta item is a nam-value type with a string value then returns
|
||||
* a tuple containing the name and string value, otherwise `none`
|
||||
*/
|
||||
fn get_name_value_str_pair(
|
||||
item: @ast::meta_item
|
||||
) -> option<(ast::ident, @str)> {
|
||||
|
|
@ -167,9 +167,7 @@ fn get_name_value_str_pair(
|
|||
|
||||
/* Searching */
|
||||
|
||||
#[doc = "
|
||||
Search a list of attributes and return only those with a specific name
|
||||
"]
|
||||
/// Search a list of attributes and return only those with a specific name
|
||||
fn find_attrs_by_name(attrs: ~[ast::attribute], +name: str) ->
|
||||
~[ast::attribute] {
|
||||
let filter = (
|
||||
|
|
@ -182,9 +180,7 @@ fn find_attrs_by_name(attrs: ~[ast::attribute], +name: str) ->
|
|||
ret vec::filter_map(attrs, filter);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Searcha list of meta items and return only those with a specific name
|
||||
"]
|
||||
/// Searcha list of meta items and return only those with a specific name
|
||||
fn find_meta_items_by_name(metas: ~[@ast::meta_item], +name: str) ->
|
||||
~[@ast::meta_item] {
|
||||
let filter = fn@(&&m: @ast::meta_item) -> option<@ast::meta_item> {
|
||||
|
|
@ -195,10 +191,10 @@ fn find_meta_items_by_name(metas: ~[@ast::meta_item], +name: str) ->
|
|||
ret vec::filter_map(metas, filter);
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns true if a list of meta items contains another meta item. The
|
||||
comparison is performed structurally.
|
||||
"]
|
||||
/**
|
||||
* Returns true if a list of meta items contains another meta item. The
|
||||
* comparison is performed structurally.
|
||||
*/
|
||||
fn contains(haystack: ~[@ast::meta_item], needle: @ast::meta_item) -> bool {
|
||||
#debug("looking for %s",
|
||||
print::pprust::meta_item_to_str(*needle));
|
||||
|
|
@ -332,10 +328,10 @@ fn find_linkage_attrs(attrs: ~[ast::attribute]) -> ~[ast::attribute] {
|
|||
ret found;
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
From a list of crate attributes get only the meta_items that impact crate
|
||||
linkage
|
||||
"]
|
||||
/**
|
||||
* From a list of crate attributes get only the meta_items that impact crate
|
||||
* linkage
|
||||
*/
|
||||
fn find_linkage_metas(attrs: ~[ast::attribute]) -> ~[@ast::meta_item] {
|
||||
do find_linkage_attrs(attrs).flat_map |attr| {
|
||||
alt check attr.node.value.node {
|
||||
|
|
@ -370,7 +366,7 @@ enum inline_attr {
|
|||
ia_always
|
||||
}
|
||||
|
||||
#[doc = "True if something like #[inline] is found in the list of attrs."]
|
||||
/// True if something like #[inline] is found in the list of attrs.
|
||||
fn find_inline_attr(attrs: ~[ast::attribute]) -> inline_attr {
|
||||
// TODO---validate the usage of #[inline] and #[inline(always)]
|
||||
do vec::foldl(ia_none, attrs) |ia,attr| {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "The main parser interface"];
|
||||
//! The main parser interface
|
||||
import dvec::extensions;
|
||||
|
||||
export parse_sess;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ enum tt_frame_up { /* to break a circularity */
|
|||
}
|
||||
|
||||
/* TODO: figure out how to have a uniquely linked stack, and change to `~` */
|
||||
#[doc = "an unzipping of `token_tree`s"]
|
||||
/// an unzipping of `token_tree`s
|
||||
type tt_frame = @{
|
||||
readme: ~[ast::token_tree],
|
||||
mut idx: uint,
|
||||
|
|
|
|||
|
|
@ -1057,7 +1057,7 @@ class parser {
|
|||
}
|
||||
|
||||
fn parse_token_tree() -> token_tree {
|
||||
#[doc="what's the opposite delimiter?"]
|
||||
/// what's the opposite delimiter?
|
||||
fn flip(&t: token::token) -> token::token {
|
||||
alt t {
|
||||
token::LPAREN { token::RPAREN }
|
||||
|
|
|
|||
|
|
@ -6,17 +6,19 @@ import token::*;
|
|||
import token::token;
|
||||
import ast::*;
|
||||
|
||||
#[doc = "Unary operators have higher precedence than binary"]
|
||||
/// Unary operators have higher precedence than binary
|
||||
const unop_prec: uint = 100u;
|
||||
|
||||
#[doc = "
|
||||
Precedence of the `as` operator, which is a binary operator
|
||||
but is not represented in the precedence table.
|
||||
"]
|
||||
/**
|
||||
* Precedence of the `as` operator, which is a binary operator
|
||||
* but is not represented in the precedence table.
|
||||
*/
|
||||
const as_prec: uint = 11u;
|
||||
|
||||
#[doc = "Maps a token to a record specifying the corresponding binary
|
||||
operator and its precedence"]
|
||||
/**
|
||||
* Maps a token to a record specifying the corresponding binary
|
||||
* operator and its precedence
|
||||
*/
|
||||
fn token_to_binop(tok: token) -> option<ast::binop> {
|
||||
alt tok {
|
||||
BINOP(STAR) { some(mul) }
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ enum token {
|
|||
}
|
||||
|
||||
#[auto_serialize]
|
||||
#[doc = "For interpolation during macro expansion."]
|
||||
/// For interpolation during macro expansion.
|
||||
enum whole_nt {
|
||||
w_item(@ast::item),
|
||||
w_block(ast::blk),
|
||||
|
|
@ -233,14 +233,14 @@ pure fn is_bar(t: token) -> bool {
|
|||
alt t { BINOP(OR) | OROR { true } _ { false } }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
All the valid words that have meaning in the Rust language.
|
||||
|
||||
Rust keywords are either 'contextual' or 'restricted'. Contextual
|
||||
keywords may be used as identifiers because their appearance in
|
||||
the grammar is unambiguous. Restricted keywords may not appear
|
||||
in positions that might otherwise contain _value identifiers_.
|
||||
"]
|
||||
/**
|
||||
* All the valid words that have meaning in the Rust language.
|
||||
*
|
||||
* Rust keywords are either 'contextual' or 'restricted'. Contextual
|
||||
* keywords may be used as identifiers because their appearance in
|
||||
* the grammar is unambiguous. Restricted keywords may not appear
|
||||
* in positions that might otherwise contain _value identifiers_.
|
||||
*/
|
||||
fn keyword_table() -> hashmap<str, ()> {
|
||||
let keywords = str_hash();
|
||||
for contextual_keyword_table().each_key |word| {
|
||||
|
|
@ -252,7 +252,7 @@ fn keyword_table() -> hashmap<str, ()> {
|
|||
keywords
|
||||
}
|
||||
|
||||
#[doc = "Keywords that may be used as identifiers"]
|
||||
/// Keywords that may be used as identifiers
|
||||
fn contextual_keyword_table() -> hashmap<str, ()> {
|
||||
let words = str_hash();
|
||||
let keys = ~[
|
||||
|
|
@ -274,19 +274,20 @@ fn contextual_keyword_table() -> hashmap<str, ()> {
|
|||
words
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Keywords that may not appear in any position that might otherwise contain a
|
||||
_value identifier_. Restricted keywords may still be used as other types of
|
||||
identifiers.
|
||||
|
||||
Reasons:
|
||||
|
||||
* For some (most?), if used at the start of a line, they will cause the line
|
||||
to be interpreted as a specific kind of statement, which would be confusing.
|
||||
|
||||
* `true` or `false` as identifiers would always be shadowed by
|
||||
the boolean constants
|
||||
"]
|
||||
/**
|
||||
* Keywords that may not appear in any position that might otherwise contain a
|
||||
* _value identifier_. Restricted keywords may still be used as other types of
|
||||
* identifiers.
|
||||
*
|
||||
* Reasons:
|
||||
*
|
||||
* * For some (most?), if used at the start of a line, they will cause the
|
||||
* line to be interpreted as a specific kind of statement, which would be
|
||||
* confusing.
|
||||
*
|
||||
* * `true` or `false` as identifiers would always be shadowed by
|
||||
* the boolean constants
|
||||
*/
|
||||
fn restricted_keyword_table() -> hashmap<str, ()> {
|
||||
let words = str_hash();
|
||||
let keys = ~[
|
||||
|
|
|
|||
|
|
@ -44,13 +44,13 @@ mod parse {
|
|||
mod comments;
|
||||
mod attr;
|
||||
|
||||
#[doc = "Common routines shared by parser mods"]
|
||||
/// Common routines shared by parser mods
|
||||
mod common;
|
||||
|
||||
#[doc = "Functions dealing with operator precedence"]
|
||||
/// Functions dealing with operator precedence
|
||||
mod prec;
|
||||
|
||||
#[doc = "Routines the parser uses to classify AST nodes"]
|
||||
/// Routines the parser uses to classify AST nodes
|
||||
mod classify;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ import std::map::hashmap;
|
|||
enum pp_mode {ppm_normal, ppm_expanded, ppm_typed, ppm_identified,
|
||||
ppm_expanded_identified }
|
||||
|
||||
#[doc = "
|
||||
The name used for source code that doesn't originate in a file
|
||||
(e.g. source from stdin or a string)
|
||||
"]
|
||||
/**
|
||||
* The name used for source code that doesn't originate in a file
|
||||
* (e.g. source from stdin or a string)
|
||||
*/
|
||||
fn anon_src() -> str { "<anon>" }
|
||||
|
||||
fn source_name(input: input) -> str {
|
||||
|
|
@ -88,9 +88,9 @@ fn parse_cfgspecs(cfgspecs: ~[str]) -> ast::crate_cfg {
|
|||
}
|
||||
|
||||
enum input {
|
||||
#[doc = "Load source from file"]
|
||||
/// Load source from file
|
||||
file_input(str),
|
||||
#[doc = "The string is the source"]
|
||||
/// The string is the source
|
||||
str_input(str)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ impl session for session {
|
|||
fn fast_resolve() -> bool { self.debugging_opt(fast_resolve) }
|
||||
}
|
||||
|
||||
#[doc = "Some reasonable defaults"]
|
||||
/// Some reasonable defaults
|
||||
fn basic_options() -> @options {
|
||||
@{
|
||||
crate_type: session::lib_crate,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
#[doc = "
|
||||
|
||||
Validates all used crates and extern libraries and loads their metadata
|
||||
|
||||
"];
|
||||
//! Validates all used crates and extern libraries and loads their metadata
|
||||
|
||||
import syntax::diagnostic::span_handler;
|
||||
import syntax::{ast, ast_util};
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ fn resolve_path(cstore: cstore::cstore, cnum: ast::crate_num,
|
|||
ret result;
|
||||
}
|
||||
|
||||
#[doc="Iterates over all the paths in the given crate."]
|
||||
/// Iterates over all the paths in the given crate.
|
||||
fn each_path(cstore: cstore::cstore, cnum: ast::crate_num,
|
||||
f: fn(decoder::path_entry) -> bool) {
|
||||
let crate_data = cstore::get_crate_data(cstore, cnum);
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ class path_entry {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Iterates over all the paths in the given crate."]
|
||||
/// Iterates over all the paths in the given crate.
|
||||
fn each_path(cdata: cmd, f: fn(path_entry) -> bool) {
|
||||
let root = ebml::doc(cdata.data);
|
||||
let items = ebml::get_doc(root, tag_items);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
#[doc = "
|
||||
|
||||
Finds crate binaries and loads their metadata
|
||||
|
||||
"];
|
||||
//! Finds crate binaries and loads their metadata
|
||||
|
||||
import syntax::diagnostic::span_handler;
|
||||
import syntax::{ast, attr};
|
||||
|
|
|
|||
|
|
@ -1,152 +1,150 @@
|
|||
#[doc = "
|
||||
|
||||
# Borrow check
|
||||
|
||||
This pass is in job of enforcing *memory safety* and *purity*. As
|
||||
memory safety is by far the more complex topic, I'll focus on that in
|
||||
this description, but purity will be covered later on. In the context
|
||||
of Rust, memory safety means three basic things:
|
||||
|
||||
- no writes to immutable memory;
|
||||
- all pointers point to non-freed memory;
|
||||
- all pointers point to memory of the same type as the pointer.
|
||||
|
||||
The last point might seem confusing: after all, for the most part,
|
||||
this condition is guaranteed by the type check. However, there are
|
||||
two cases where the type check effectively delegates to borrow check.
|
||||
|
||||
The first case has to do with enums. If there is a pointer to the
|
||||
interior of an enum, and the enum is in a mutable location (such as a
|
||||
local variable or field declared to be mutable), it is possible that
|
||||
the user will overwrite the enum with a new value of a different
|
||||
variant, and thus effectively change the type of the memory that the
|
||||
pointer is pointing at.
|
||||
|
||||
The second case has to do with mutability. Basically, the type
|
||||
checker has only a limited understanding of mutability. It will allow
|
||||
(for example) the user to get an immutable pointer with the address of
|
||||
a mutable local variable. It will also allow a `@mut T` or `~mut T`
|
||||
pointer to be borrowed as a `&r.T` pointer. These seeming oversights
|
||||
are in fact intentional; they allow the user to temporarily treat a
|
||||
mutable value as immutable. It is up to the borrow check to guarantee
|
||||
that the value in question is not in fact mutated during the lifetime
|
||||
`r` of the reference.
|
||||
|
||||
# Summary of the safety check
|
||||
|
||||
In order to enforce mutability, the borrow check has three tricks up
|
||||
its sleeve.
|
||||
|
||||
First, data which is uniquely tied to the current stack frame (that'll
|
||||
be defined shortly) is tracked very precisely. This means that, for
|
||||
example, if an immutable pointer to a mutable local variable is
|
||||
created, the borrowck will simply check for assignments to that
|
||||
particular local variable: no other memory is affected.
|
||||
|
||||
Second, if the data is not uniquely tied to the stack frame, it may
|
||||
still be possible to ensure its validity by rooting garbage collected
|
||||
pointers at runtime. For example, if there is a mutable local
|
||||
variable `x` of type `@T`, and its contents are borrowed with an
|
||||
expression like `&*x`, then the value of `x` will be rooted (today,
|
||||
that means its ref count will be temporary increased) for the lifetime
|
||||
of the reference that is created. This means that the pointer remains
|
||||
valid even if `x` is reassigned.
|
||||
|
||||
Finally, if neither of these two solutions are applicable, then we
|
||||
require that all operations within the scope of the reference be
|
||||
*pure*. A pure operation is effectively one that does not write to
|
||||
any aliasable memory. This means that it is still possible to write
|
||||
to local variables or other data that is uniquely tied to the stack
|
||||
frame (there's that term again; formal definition still pending) but
|
||||
not to data reached via a `&T` or `@T` pointer. Such writes could
|
||||
possibly have the side-effect of causing the data which must remain
|
||||
valid to be overwritten.
|
||||
|
||||
# Possible future directions
|
||||
|
||||
There are numerous ways that the `borrowck` could be strengthened, but
|
||||
these are the two most likely:
|
||||
|
||||
- flow-sensitivity: we do not currently consider flow at all but only
|
||||
block-scoping. This means that innocent code like the following is
|
||||
rejected:
|
||||
|
||||
let mut x: int;
|
||||
...
|
||||
x = 5;
|
||||
let y: &int = &x; // immutable ptr created
|
||||
...
|
||||
|
||||
The reason is that the scope of the pointer `y` is the entire
|
||||
enclosing block, and the assignment `x = 5` occurs within that
|
||||
block. The analysis is not smart enough to see that `x = 5` always
|
||||
happens before the immutable pointer is created. This is relatively
|
||||
easy to fix and will surely be fixed at some point.
|
||||
|
||||
- finer-grained purity checks: currently, our fallback for
|
||||
guaranteeing random references into mutable, aliasable memory is to
|
||||
require *total purity*. This is rather strong. We could use local
|
||||
type-based alias analysis to distinguish writes that could not
|
||||
possibly invalid the references which must be guaranteed. This
|
||||
would only work within the function boundaries; function calls would
|
||||
still require total purity. This seems less likely to be
|
||||
implemented in the short term as it would make the code
|
||||
significantly more complex; there is currently no code to analyze
|
||||
the types and determine the possible impacts of a write.
|
||||
|
||||
# Terminology
|
||||
|
||||
A **loan** is .
|
||||
|
||||
# How the code works
|
||||
|
||||
The borrow check code is divided into several major modules, each of
|
||||
which is documented in its own file.
|
||||
|
||||
The `gather_loans` and `check_loans` are the two major passes of the
|
||||
analysis. The `gather_loans` pass runs over the IR once to determine
|
||||
what memory must remain valid and for how long. Its name is a bit of
|
||||
a misnomer; it does in fact gather up the set of loans which are
|
||||
granted, but it also determines when @T pointers must be rooted and
|
||||
for which scopes purity must be required.
|
||||
|
||||
The `check_loans` pass walks the IR and examines the loans and purity
|
||||
requirements computed in `gather_loans`. It checks to ensure that (a)
|
||||
the conditions of all loans are honored; (b) no contradictory loans
|
||||
were granted (for example, loaning out the same memory as mutable and
|
||||
immutable simultaneously); and (c) any purity requirements are
|
||||
honored.
|
||||
|
||||
The remaining modules are helper modules used by `gather_loans` and
|
||||
`check_loans`:
|
||||
|
||||
- `categorization` has the job of analyzing an expression to determine
|
||||
what kind of memory is used in evaluating it (for example, where
|
||||
dereferences occur and what kind of pointer is dereferenced; whether
|
||||
the memory is mutable; etc)
|
||||
- `loan` determines when data uniquely tied to the stack frame can be
|
||||
loaned out.
|
||||
- `preserve` determines what actions (if any) must be taken to preserve
|
||||
aliasable data. This is the code which decides when to root
|
||||
an @T pointer or to require purity.
|
||||
|
||||
# Maps that are created
|
||||
|
||||
Borrowck results in two maps.
|
||||
|
||||
- `root_map`: identifies those expressions or patterns whose result
|
||||
needs to be rooted. Conceptually the root_map maps from an
|
||||
expression or pattern node to a `node_id` identifying the scope for
|
||||
which the expression must be rooted (this `node_id` should identify
|
||||
a block or call). The actual key to the map is not an expression id,
|
||||
however, but a `root_map_key`, which combines an expression id with a
|
||||
deref count and is used to cope with auto-deref.
|
||||
|
||||
- `mutbl_map`: identifies those local variables which are modified or
|
||||
moved. This is used by trans to guarantee that such variables are
|
||||
given a memory location and not used as immediates.
|
||||
|
||||
"];
|
||||
/*!
|
||||
* # Borrow check
|
||||
*
|
||||
* This pass is in job of enforcing *memory safety* and *purity*. As
|
||||
* memory safety is by far the more complex topic, I'll focus on that in
|
||||
* this description, but purity will be covered later on. In the context
|
||||
* of Rust, memory safety means three basic things:
|
||||
*
|
||||
* - no writes to immutable memory;
|
||||
* - all pointers point to non-freed memory;
|
||||
* - all pointers point to memory of the same type as the pointer.
|
||||
*
|
||||
* The last point might seem confusing: after all, for the most part,
|
||||
* this condition is guaranteed by the type check. However, there are
|
||||
* two cases where the type check effectively delegates to borrow check.
|
||||
*
|
||||
* The first case has to do with enums. If there is a pointer to the
|
||||
* interior of an enum, and the enum is in a mutable location (such as a
|
||||
* local variable or field declared to be mutable), it is possible that
|
||||
* the user will overwrite the enum with a new value of a different
|
||||
* variant, and thus effectively change the type of the memory that the
|
||||
* pointer is pointing at.
|
||||
*
|
||||
* The second case has to do with mutability. Basically, the type
|
||||
* checker has only a limited understanding of mutability. It will allow
|
||||
* (for example) the user to get an immutable pointer with the address of
|
||||
* a mutable local variable. It will also allow a `@mut T` or `~mut T`
|
||||
* pointer to be borrowed as a `&r.T` pointer. These seeming oversights
|
||||
* are in fact intentional; they allow the user to temporarily treat a
|
||||
* mutable value as immutable. It is up to the borrow check to guarantee
|
||||
* that the value in question is not in fact mutated during the lifetime
|
||||
* `r` of the reference.
|
||||
*
|
||||
* # Summary of the safety check
|
||||
*
|
||||
* In order to enforce mutability, the borrow check has three tricks up
|
||||
* its sleeve.
|
||||
*
|
||||
* First, data which is uniquely tied to the current stack frame (that'll
|
||||
* be defined shortly) is tracked very precisely. This means that, for
|
||||
* example, if an immutable pointer to a mutable local variable is
|
||||
* created, the borrowck will simply check for assignments to that
|
||||
* particular local variable: no other memory is affected.
|
||||
*
|
||||
* Second, if the data is not uniquely tied to the stack frame, it may
|
||||
* still be possible to ensure its validity by rooting garbage collected
|
||||
* pointers at runtime. For example, if there is a mutable local
|
||||
* variable `x` of type `@T`, and its contents are borrowed with an
|
||||
* expression like `&*x`, then the value of `x` will be rooted (today,
|
||||
* that means its ref count will be temporary increased) for the lifetime
|
||||
* of the reference that is created. This means that the pointer remains
|
||||
* valid even if `x` is reassigned.
|
||||
*
|
||||
* Finally, if neither of these two solutions are applicable, then we
|
||||
* require that all operations within the scope of the reference be
|
||||
* *pure*. A pure operation is effectively one that does not write to
|
||||
* any aliasable memory. This means that it is still possible to write
|
||||
* to local variables or other data that is uniquely tied to the stack
|
||||
* frame (there's that term again; formal definition still pending) but
|
||||
* not to data reached via a `&T` or `@T` pointer. Such writes could
|
||||
* possibly have the side-effect of causing the data which must remain
|
||||
* valid to be overwritten.
|
||||
*
|
||||
* # Possible future directions
|
||||
*
|
||||
* There are numerous ways that the `borrowck` could be strengthened, but
|
||||
* these are the two most likely:
|
||||
*
|
||||
* - flow-sensitivity: we do not currently consider flow at all but only
|
||||
* block-scoping. This means that innocent code like the following is
|
||||
* rejected:
|
||||
*
|
||||
* let mut x: int;
|
||||
* ...
|
||||
* x = 5;
|
||||
* let y: &int = &x; // immutable ptr created
|
||||
* ...
|
||||
*
|
||||
* The reason is that the scope of the pointer `y` is the entire
|
||||
* enclosing block, and the assignment `x = 5` occurs within that
|
||||
* block. The analysis is not smart enough to see that `x = 5` always
|
||||
* happens before the immutable pointer is created. This is relatively
|
||||
* easy to fix and will surely be fixed at some point.
|
||||
*
|
||||
* - finer-grained purity checks: currently, our fallback for
|
||||
* guaranteeing random references into mutable, aliasable memory is to
|
||||
* require *total purity*. This is rather strong. We could use local
|
||||
* type-based alias analysis to distinguish writes that could not
|
||||
* possibly invalid the references which must be guaranteed. This
|
||||
* would only work within the function boundaries; function calls would
|
||||
* still require total purity. This seems less likely to be
|
||||
* implemented in the short term as it would make the code
|
||||
* significantly more complex; there is currently no code to analyze
|
||||
* the types and determine the possible impacts of a write.
|
||||
*
|
||||
* # Terminology
|
||||
*
|
||||
* A **loan** is .
|
||||
*
|
||||
* # How the code works
|
||||
*
|
||||
* The borrow check code is divided into several major modules, each of
|
||||
* which is documented in its own file.
|
||||
*
|
||||
* The `gather_loans` and `check_loans` are the two major passes of the
|
||||
* analysis. The `gather_loans` pass runs over the IR once to determine
|
||||
* what memory must remain valid and for how long. Its name is a bit of
|
||||
* a misnomer; it does in fact gather up the set of loans which are
|
||||
* granted, but it also determines when @T pointers must be rooted and
|
||||
* for which scopes purity must be required.
|
||||
*
|
||||
* The `check_loans` pass walks the IR and examines the loans and purity
|
||||
* requirements computed in `gather_loans`. It checks to ensure that (a)
|
||||
* the conditions of all loans are honored; (b) no contradictory loans
|
||||
* were granted (for example, loaning out the same memory as mutable and
|
||||
* immutable simultaneously); and (c) any purity requirements are
|
||||
* honored.
|
||||
*
|
||||
* The remaining modules are helper modules used by `gather_loans` and
|
||||
* `check_loans`:
|
||||
*
|
||||
* - `categorization` has the job of analyzing an expression to determine
|
||||
* what kind of memory is used in evaluating it (for example, where
|
||||
* dereferences occur and what kind of pointer is dereferenced; whether
|
||||
* the memory is mutable; etc)
|
||||
* - `loan` determines when data uniquely tied to the stack frame can be
|
||||
* loaned out.
|
||||
* - `preserve` determines what actions (if any) must be taken to preserve
|
||||
* aliasable data. This is the code which decides when to root
|
||||
* an @T pointer or to require purity.
|
||||
*
|
||||
* # Maps that are created
|
||||
*
|
||||
* Borrowck results in two maps.
|
||||
*
|
||||
* - `root_map`: identifies those expressions or patterns whose result
|
||||
* needs to be rooted. Conceptually the root_map maps from an
|
||||
* expression or pattern node to a `node_id` identifying the scope for
|
||||
* which the expression must be rooted (this `node_id` should identify
|
||||
* a block or call). The actual key to the map is not an expression id,
|
||||
* however, but a `root_map_key`, which combines an expression id with a
|
||||
* deref count and is used to cope with auto-deref.
|
||||
*
|
||||
* - `mutbl_map`: identifies those local variables which are modified or
|
||||
* moved. This is used by trans to guarantee that such variables are
|
||||
* given a memory location and not used as immediates.
|
||||
*/
|
||||
|
||||
import syntax::ast;
|
||||
import syntax::ast::{mutability, m_mutbl, m_imm, m_const};
|
||||
|
|
@ -304,7 +302,7 @@ fn save_and_restore<T:copy,U>(&save_and_restore_t: T, f: fn() -> U) -> U {
|
|||
ret u;
|
||||
}
|
||||
|
||||
#[doc = "Creates and returns a new root_map"]
|
||||
/// Creates and returns a new root_map
|
||||
fn root_map() -> root_map {
|
||||
ret hashmap(root_map_key_hash, root_map_key_eq);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,41 +1,40 @@
|
|||
#[doc = "
|
||||
|
||||
# Categorization
|
||||
|
||||
The job of the categorization module is to analyze an expression to
|
||||
determine what kind of memory is used in evaluating it (for example,
|
||||
where dereferences occur and what kind of pointer is dereferenced;
|
||||
whether the memory is mutable; etc)
|
||||
|
||||
Categorization effectively transforms all of our expressions into
|
||||
expressions of the following forms (the actual enum has many more
|
||||
possibilities, naturally, but they are all variants of these base
|
||||
forms):
|
||||
|
||||
E = rvalue // some computed rvalue
|
||||
| x // address of a local variable, arg, or upvar
|
||||
| *E // deref of a ptr
|
||||
| E.comp // access to an interior component
|
||||
|
||||
Imagine a routine ToAddr(Expr) that evaluates an expression and returns an
|
||||
address where the result is to be found. If Expr is an lvalue, then this
|
||||
is the address of the lvalue. If Expr is an rvalue, this is the address of
|
||||
some temporary spot in memory where the result is stored.
|
||||
|
||||
Now, cat_expr() classies the expression Expr and the address A=ToAddr(Expr)
|
||||
as follows:
|
||||
|
||||
- cat: what kind of expression was this? This is a subset of the
|
||||
full expression forms which only includes those that we care about
|
||||
for the purpose of the analysis.
|
||||
- mutbl: mutability of the address A
|
||||
- ty: the type of data found at the address A
|
||||
|
||||
The resulting categorization tree differs somewhat from the expressions
|
||||
themselves. For example, auto-derefs are explicit. Also, an index a[b] is
|
||||
decomposed into two operations: a derefence to reach the array data and
|
||||
then an index to jump forward to the relevant item.
|
||||
"];
|
||||
/*!
|
||||
* # Categorization
|
||||
*
|
||||
* The job of the categorization module is to analyze an expression to
|
||||
* determine what kind of memory is used in evaluating it (for example,
|
||||
* where dereferences occur and what kind of pointer is dereferenced;
|
||||
* whether the memory is mutable; etc)
|
||||
*
|
||||
* Categorization effectively transforms all of our expressions into
|
||||
* expressions of the following forms (the actual enum has many more
|
||||
* possibilities, naturally, but they are all variants of these base
|
||||
* forms):
|
||||
*
|
||||
* E = rvalue // some computed rvalue
|
||||
* | x // address of a local variable, arg, or upvar
|
||||
* | *E // deref of a ptr
|
||||
* | E.comp // access to an interior component
|
||||
*
|
||||
* Imagine a routine ToAddr(Expr) that evaluates an expression and returns an
|
||||
* address where the result is to be found. If Expr is an lvalue, then this
|
||||
* is the address of the lvalue. If Expr is an rvalue, this is the address of
|
||||
* some temporary spot in memory where the result is stored.
|
||||
*
|
||||
* Now, cat_expr() classies the expression Expr and the address A=ToAddr(Expr)
|
||||
* as follows:
|
||||
*
|
||||
* - cat: what kind of expression was this? This is a subset of the
|
||||
* full expression forms which only includes those that we care about
|
||||
* for the purpose of the analysis.
|
||||
* - mutbl: mutability of the address A
|
||||
* - ty: the type of data found at the address A
|
||||
*
|
||||
* The resulting categorization tree differs somewhat from the expressions
|
||||
* themselves. For example, auto-derefs are explicit. Also, an index a[b] is
|
||||
* decomposed into two operations: a derefence to reach the array data and
|
||||
* then an index to jump forward to the relevant item.
|
||||
*/
|
||||
|
||||
export public_methods;
|
||||
export opt_deref_kind;
|
||||
|
|
|
|||
|
|
@ -17,27 +17,26 @@ export get_warning_level, get_warning_settings_level;
|
|||
export check_crate, build_settings_crate, mk_warning_settings;
|
||||
export warning_settings;
|
||||
|
||||
#[doc="
|
||||
|
||||
A 'lint' check is a kind of miscellaneous constraint that a user _might_ want
|
||||
to enforce, but might reasonably want to permit as well, on a module-by-module
|
||||
basis. They contrast with static constraints enforced by other phases of the
|
||||
compiler, which are generally required to hold in order to compile the program
|
||||
at all.
|
||||
|
||||
We also build up a table containing information about lint settings, in order
|
||||
to allow other passes to take advantage of the warning attribute
|
||||
infrastructure. To save space, the table is keyed by the id of /items/, not of
|
||||
every expression. When an item has the default settings, the entry will be
|
||||
omitted. If we start allowing warn attributes on expressions, we will start
|
||||
having entries for expressions that do not share their enclosing items
|
||||
settings.
|
||||
|
||||
This module then, exports two passes: one that populates the warning settings
|
||||
table in the session and is run early in the compile process, and one that
|
||||
does a variety of lint checks, and is run late in the compile process.
|
||||
|
||||
"]
|
||||
/**
|
||||
* A 'lint' check is a kind of miscellaneous constraint that a user _might_
|
||||
* want to enforce, but might reasonably want to permit as well, on a
|
||||
* module-by-module basis. They contrast with static constraints enforced by
|
||||
* other phases of the compiler, which are generally required to hold in order
|
||||
* to compile the program at all.
|
||||
*
|
||||
* We also build up a table containing information about lint settings, in
|
||||
* order to allow other passes to take advantage of the warning attribute
|
||||
* infrastructure. To save space, the table is keyed by the id of /items/, not
|
||||
* of every expression. When an item has the default settings, the entry will
|
||||
* be omitted. If we start allowing warn attributes on expressions, we will
|
||||
* start having entries for expressions that do not share their enclosing
|
||||
* items settings.
|
||||
*
|
||||
* This module then, exports two passes: one that populates the warning
|
||||
* settings table in the session and is run early in the compile process, and
|
||||
* one that does a variety of lint checks, and is run late in the compile
|
||||
* process.
|
||||
*/
|
||||
|
||||
enum lint {
|
||||
ctypes,
|
||||
|
|
@ -203,11 +202,11 @@ impl methods for ctxt {
|
|||
self.sess.span_lint_level(level, span, msg);
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Merge the warnings specified by any `warn(...)` attributes into the
|
||||
current lint context, call the provided function, then reset the
|
||||
warnings in effect to their previous state.
|
||||
"]
|
||||
/**
|
||||
* Merge the warnings specified by any `warn(...)` attributes into the
|
||||
* current lint context, call the provided function, then reset the
|
||||
* warnings in effect to their previous state.
|
||||
*/
|
||||
fn with_warn_attrs(attrs: ~[ast::attribute], f: fn(ctxt)) {
|
||||
|
||||
let mut new_ctxt = self;
|
||||
|
|
|
|||
|
|
@ -1,106 +1,104 @@
|
|||
#[doc = "
|
||||
|
||||
A classic liveness analysis based on dataflow over the AST. Computes,
|
||||
for each local variable in a function, whether that variable is live
|
||||
at a given point. Program execution points are identified by their
|
||||
id.
|
||||
|
||||
# Basic idea
|
||||
|
||||
The basic model is that each local variable is assigned an index. We
|
||||
represent sets of local variables using a vector indexed by this
|
||||
index. The value in the vector is either 0, indicating the variable
|
||||
is dead, or the id of an expression that uses the variable.
|
||||
|
||||
We conceptually walk over the AST in reverse execution order. If we
|
||||
find a use of a variable, we add it to the set of live variables. If
|
||||
we find an assignment to a variable, we remove it from the set of live
|
||||
variables. When we have to merge two flows, we take the union of
|
||||
those two flows---if the variable is live on both paths, we simply
|
||||
pick one id. In the event of loops, we continue doing this until a
|
||||
fixed point is reached.
|
||||
|
||||
## Checking initialization
|
||||
|
||||
At the function entry point, all variables must be dead. If this is
|
||||
not the case, we can report an error using the id found in the set of
|
||||
live variables, which identifies a use of the variable which is not
|
||||
dominated by an assignment.
|
||||
|
||||
## Checking moves
|
||||
|
||||
After each explicit move, the variable must be dead.
|
||||
|
||||
## Computing last uses
|
||||
|
||||
Any use of the variable where the variable is dead afterwards is a
|
||||
last use.
|
||||
|
||||
# Extension to handle constructors
|
||||
|
||||
Each field is assigned an index just as with local variables. A use of
|
||||
`self` is considered a use of all fields. A use of `self.f` is just a use
|
||||
of `f`.
|
||||
|
||||
# Implementation details
|
||||
|
||||
The actual implementation contains two (nested) walks over the AST.
|
||||
The outer walk has the job of building up the ir_maps instance for the
|
||||
enclosing function. On the way down the tree, it identifies those AST
|
||||
nodes and variable IDs that will be needed for the liveness analysis
|
||||
and assigns them contiguous IDs. The liveness id for an AST node is
|
||||
called a `live_node` (it's a newtype'd uint) and the id for a variable
|
||||
is called a `variable` (another newtype'd uint).
|
||||
|
||||
On the way back up the tree, as we are about to exit from a function
|
||||
declaration we allocate a `liveness` instance. Now that we know
|
||||
precisely how many nodes and variables we need, we can allocate all
|
||||
the various arrays that we will need to precisely the right size. We then
|
||||
perform the actual propagation on the `liveness` instance.
|
||||
|
||||
This propagation is encoded in the various `propagate_through_*()`
|
||||
methods. It effectively does a reverse walk of the AST; whenever we
|
||||
reach a loop node, we iterate until a fixed point is reached.
|
||||
|
||||
## The `users` struct
|
||||
|
||||
At each live node `N`, we track three pieces of information for each
|
||||
variable `V` (these are encapsulated in the `users` struct):
|
||||
|
||||
- `reader`: the `live_node` ID of some node which will read the value
|
||||
that `V` holds on entry to `N`. Formally: a node `M` such
|
||||
that there exists a path `P` from `N` to `M` where `P` does not
|
||||
write `V`. If the `reader` is `invalid_node()`, then the current
|
||||
value will never be read (the variable is dead, essentially).
|
||||
|
||||
- `writer`: the `live_node` ID of some node which will write the
|
||||
variable `V` and which is reachable from `N`. Formally: a node `M`
|
||||
such that there exists a path `P` from `N` to `M` and `M` writes
|
||||
`V`. If the `writer` is `invalid_node()`, then there is no writer
|
||||
of `V` that follows `N`.
|
||||
|
||||
- `used`: a boolean value indicating whether `V` is *used*. We
|
||||
distinguish a *read* from a *use* in that a *use* is some read that
|
||||
is not just used to generate a new value. For example, `x += 1` is
|
||||
a read but not a use. This is used to generate better warnings.
|
||||
|
||||
## Special Variables
|
||||
|
||||
We generate various special variables for various, well, special purposes.
|
||||
These are described in the `specials` struct:
|
||||
|
||||
- `exit_ln`: a live node that is generated to represent every 'exit' from the
|
||||
function, whether it be by explicit return, fail, or other means.
|
||||
|
||||
- `fallthrough_ln`: a live node that represents a fallthrough
|
||||
|
||||
- `no_ret_var`: a synthetic variable that is only 'read' from, the
|
||||
fallthrough node. This allows us to detect functions where we fail
|
||||
to return explicitly.
|
||||
|
||||
- `self_var`: a variable representing 'self'
|
||||
|
||||
"];
|
||||
/*!
|
||||
* A classic liveness analysis based on dataflow over the AST. Computes,
|
||||
* for each local variable in a function, whether that variable is live
|
||||
* at a given point. Program execution points are identified by their
|
||||
* id.
|
||||
*
|
||||
* # Basic idea
|
||||
*
|
||||
* The basic model is that each local variable is assigned an index. We
|
||||
* represent sets of local variables using a vector indexed by this
|
||||
* index. The value in the vector is either 0, indicating the variable
|
||||
* is dead, or the id of an expression that uses the variable.
|
||||
*
|
||||
* We conceptually walk over the AST in reverse execution order. If we
|
||||
* find a use of a variable, we add it to the set of live variables. If
|
||||
* we find an assignment to a variable, we remove it from the set of live
|
||||
* variables. When we have to merge two flows, we take the union of
|
||||
* those two flows---if the variable is live on both paths, we simply
|
||||
* pick one id. In the event of loops, we continue doing this until a
|
||||
* fixed point is reached.
|
||||
*
|
||||
* ## Checking initialization
|
||||
*
|
||||
* At the function entry point, all variables must be dead. If this is
|
||||
* not the case, we can report an error using the id found in the set of
|
||||
* live variables, which identifies a use of the variable which is not
|
||||
* dominated by an assignment.
|
||||
*
|
||||
* ## Checking moves
|
||||
*
|
||||
* After each explicit move, the variable must be dead.
|
||||
*
|
||||
* ## Computing last uses
|
||||
*
|
||||
* Any use of the variable where the variable is dead afterwards is a
|
||||
* last use.
|
||||
*
|
||||
* # Extension to handle constructors
|
||||
*
|
||||
* Each field is assigned an index just as with local variables. A use of
|
||||
* `self` is considered a use of all fields. A use of `self.f` is just a use
|
||||
* of `f`.
|
||||
*
|
||||
* # Implementation details
|
||||
*
|
||||
* The actual implementation contains two (nested) walks over the AST.
|
||||
* The outer walk has the job of building up the ir_maps instance for the
|
||||
* enclosing function. On the way down the tree, it identifies those AST
|
||||
* nodes and variable IDs that will be needed for the liveness analysis
|
||||
* and assigns them contiguous IDs. The liveness id for an AST node is
|
||||
* called a `live_node` (it's a newtype'd uint) and the id for a variable
|
||||
* is called a `variable` (another newtype'd uint).
|
||||
*
|
||||
* On the way back up the tree, as we are about to exit from a function
|
||||
* declaration we allocate a `liveness` instance. Now that we know
|
||||
* precisely how many nodes and variables we need, we can allocate all
|
||||
* the various arrays that we will need to precisely the right size. We then
|
||||
* perform the actual propagation on the `liveness` instance.
|
||||
*
|
||||
* This propagation is encoded in the various `propagate_through_*()`
|
||||
* methods. It effectively does a reverse walk of the AST; whenever we
|
||||
* reach a loop node, we iterate until a fixed point is reached.
|
||||
*
|
||||
* ## The `users` struct
|
||||
*
|
||||
* At each live node `N`, we track three pieces of information for each
|
||||
* variable `V` (these are encapsulated in the `users` struct):
|
||||
*
|
||||
* - `reader`: the `live_node` ID of some node which will read the value
|
||||
* that `V` holds on entry to `N`. Formally: a node `M` such
|
||||
* that there exists a path `P` from `N` to `M` where `P` does not
|
||||
* write `V`. If the `reader` is `invalid_node()`, then the current
|
||||
* value will never be read (the variable is dead, essentially).
|
||||
*
|
||||
* - `writer`: the `live_node` ID of some node which will write the
|
||||
* variable `V` and which is reachable from `N`. Formally: a node `M`
|
||||
* such that there exists a path `P` from `N` to `M` and `M` writes
|
||||
* `V`. If the `writer` is `invalid_node()`, then there is no writer
|
||||
* of `V` that follows `N`.
|
||||
*
|
||||
* - `used`: a boolean value indicating whether `V` is *used*. We
|
||||
* distinguish a *read* from a *use* in that a *use* is some read that
|
||||
* is not just used to generate a new value. For example, `x += 1` is
|
||||
* a read but not a use. This is used to generate better warnings.
|
||||
*
|
||||
* ## Special Variables
|
||||
*
|
||||
* We generate various special variables for various, well, special purposes.
|
||||
* These are described in the `specials` struct:
|
||||
*
|
||||
* - `exit_ln`: a live node that is generated to represent every 'exit' from
|
||||
* the function, whether it be by explicit return, fail, or other means.
|
||||
*
|
||||
* - `fallthrough_ln`: a live node that represents a fallthrough
|
||||
*
|
||||
* - `no_ret_var`: a synthetic variable that is only 'read' from, the
|
||||
* fallthrough node. This allows us to detect functions where we fail
|
||||
* to return explicitly.
|
||||
*
|
||||
* - `self_var`: a variable representing 'self'
|
||||
*/
|
||||
|
||||
import dvec::{dvec, extensions};
|
||||
import std::map::{hashmap, int_hash, str_hash, box_str_hash};
|
||||
|
|
|
|||
|
|
@ -109,13 +109,13 @@ enum ModuleDef {
|
|||
ModuleDef(@Module), // Defines a module.
|
||||
}
|
||||
|
||||
#[doc="Contains data for specific types of import directives."]
|
||||
/// Contains data for specific types of import directives.
|
||||
enum ImportDirectiveSubclass {
|
||||
SingleImport(Atom /* target */, Atom /* source */),
|
||||
GlobImport
|
||||
}
|
||||
|
||||
#[doc="The context that we thread through while building the reduced graph."]
|
||||
/// The context that we thread through while building the reduced graph.
|
||||
enum ReducedGraphParent {
|
||||
ModuleReducedGraphParent(@Module)
|
||||
}
|
||||
|
|
@ -235,15 +235,15 @@ class AtomTable {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Creates a hash table of atoms."]
|
||||
/// Creates a hash table of atoms.
|
||||
fn atom_hashmap<V:copy>() -> hashmap<Atom,V> {
|
||||
ret hashmap::<Atom,V>(|a| a, |a, b| a == b);
|
||||
}
|
||||
|
||||
#[doc="
|
||||
One local scope. In Rust, local scopes can only contain value bindings.
|
||||
Therefore, we don't have to worry about the other namespaces here.
|
||||
"]
|
||||
/**
|
||||
* One local scope. In Rust, local scopes can only contain value bindings.
|
||||
* Therefore, we don't have to worry about the other namespaces here.
|
||||
*/
|
||||
class Rib {
|
||||
let bindings: hashmap<Atom,def_like>;
|
||||
let kind: RibKind;
|
||||
|
|
@ -254,7 +254,7 @@ class Rib {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="One import directive."]
|
||||
/// One import directive.
|
||||
class ImportDirective {
|
||||
let module_path: @dvec<Atom>;
|
||||
let subclass: @ImportDirectiveSubclass;
|
||||
|
|
@ -265,7 +265,7 @@ class ImportDirective {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="The item that an import resolves to."]
|
||||
/// The item that an import resolves to.
|
||||
class Target {
|
||||
let target_module: @Module;
|
||||
let bindings: @NameBindings;
|
||||
|
|
@ -313,14 +313,14 @@ class ImportResolution {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="The link from a module up to its nearest parent node."]
|
||||
/// The link from a module up to its nearest parent node.
|
||||
enum ParentLink {
|
||||
NoParentLink,
|
||||
ModuleParentLink(@Module, Atom),
|
||||
BlockParentLink(@Module, node_id)
|
||||
}
|
||||
|
||||
#[doc="One node in the tree of modules."]
|
||||
/// One node in the tree of modules.
|
||||
class Module {
|
||||
let parent_link: ParentLink;
|
||||
let mut def_id: option<def_id>;
|
||||
|
|
@ -398,10 +398,10 @@ pure fn is_none<T>(x: option<T>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Records the definitions (at most one for each namespace) that a name is
|
||||
bound to.
|
||||
"]
|
||||
/**
|
||||
* Records the definitions (at most one for each namespace) that a name is
|
||||
* bound to.
|
||||
*/
|
||||
class NameBindings {
|
||||
let mut module_def: ModuleDef; //< Meaning in the module namespace.
|
||||
let mut type_def: option<def>; //< Meaning in the type namespace.
|
||||
|
|
@ -415,7 +415,7 @@ class NameBindings {
|
|||
self.impl_defs = ~[];
|
||||
}
|
||||
|
||||
#[doc="Creates a new module in this set of name bindings."]
|
||||
/// Creates a new module in this set of name bindings.
|
||||
fn define_module(parent_link: ParentLink, def_id: option<def_id>) {
|
||||
if self.module_def == NoModuleDef {
|
||||
let module = @Module(parent_link, def_id);
|
||||
|
|
@ -423,22 +423,22 @@ class NameBindings {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Records a type definition."]
|
||||
/// Records a type definition.
|
||||
fn define_type(def: def) {
|
||||
self.type_def = some(def);
|
||||
}
|
||||
|
||||
#[doc="Records a value definition."]
|
||||
/// Records a value definition.
|
||||
fn define_value(def: def) {
|
||||
self.value_def = some(def);
|
||||
}
|
||||
|
||||
#[doc="Records an impl definition."]
|
||||
/// Records an impl definition.
|
||||
fn define_impl(implementation: @Impl) {
|
||||
self.impl_defs += ~[implementation];
|
||||
}
|
||||
|
||||
#[doc="Returns the module node if applicable."]
|
||||
/// Returns the module node if applicable.
|
||||
fn get_module_if_available() -> option<@Module> {
|
||||
alt self.module_def {
|
||||
NoModuleDef { ret none; }
|
||||
|
|
@ -446,10 +446,10 @@ class NameBindings {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Returns the module node. Fails if this node does not have a module
|
||||
definition.
|
||||
"]
|
||||
/**
|
||||
* Returns the module node. Fails if this node does not have a module
|
||||
* definition.
|
||||
*/
|
||||
fn get_module() -> @Module {
|
||||
alt self.module_def {
|
||||
NoModuleDef {
|
||||
|
|
@ -508,7 +508,7 @@ class NameBindings {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Interns the names of the primitive types."]
|
||||
/// Interns the names of the primitive types.
|
||||
class PrimitiveTypeTable {
|
||||
let primitive_types: hashmap<Atom,prim_ty>;
|
||||
|
||||
|
|
@ -539,7 +539,7 @@ class PrimitiveTypeTable {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="The main resolver class."]
|
||||
/// The main resolver class.
|
||||
class Resolver {
|
||||
let session: session;
|
||||
let ast_map: ASTMap;
|
||||
|
|
@ -611,7 +611,7 @@ class Resolver {
|
|||
self.export_map = int_hash();
|
||||
}
|
||||
|
||||
#[doc="The main name resolution procedure."]
|
||||
/// The main name resolution procedure.
|
||||
fn resolve(this: @Resolver) {
|
||||
self.build_reduced_graph(this);
|
||||
self.resolve_imports();
|
||||
|
|
@ -627,7 +627,7 @@ class Resolver {
|
|||
// any imports resolved.
|
||||
//
|
||||
|
||||
#[doc="Constructs the reduced graph for the entire crate."]
|
||||
/// Constructs the reduced graph for the entire crate.
|
||||
fn build_reduced_graph(this: @Resolver) {
|
||||
let initial_parent =
|
||||
ModuleReducedGraphParent((*self.graph_root).get_module());
|
||||
|
|
@ -654,7 +654,7 @@ class Resolver {
|
|||
}));
|
||||
}
|
||||
|
||||
#[doc="Returns the current module tracked by the reduced graph parent."]
|
||||
/// Returns the current module tracked by the reduced graph parent.
|
||||
fn get_module_from_parent(reduced_graph_parent: ReducedGraphParent)
|
||||
-> @Module {
|
||||
alt reduced_graph_parent {
|
||||
|
|
@ -664,16 +664,16 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Adds a new child item to the module definition of the parent node and
|
||||
returns its corresponding name bindings as well as the current parent.
|
||||
Or, if we're inside a block, creates (or reuses) an anonymous module
|
||||
corresponding to the innermost block ID and returns the name bindings
|
||||
as well as the newly-created parent.
|
||||
|
||||
If this node does not have a module definition and we are not inside
|
||||
a block, fails.
|
||||
"]
|
||||
/**
|
||||
* Adds a new child item to the module definition of the parent node and
|
||||
* returns its corresponding name bindings as well as the current parent.
|
||||
* Or, if we're inside a block, creates (or reuses) an anonymous module
|
||||
* corresponding to the innermost block ID and returns the name bindings
|
||||
* as well as the newly-created parent.
|
||||
*
|
||||
* If this node does not have a module definition and we are not inside
|
||||
* a block, fails.
|
||||
*/
|
||||
fn add_child(name: Atom,
|
||||
reduced_graph_parent: ReducedGraphParent)
|
||||
-> (@NameBindings, ReducedGraphParent) {
|
||||
|
|
@ -742,7 +742,7 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Constructs the reduced graph for one item."]
|
||||
/// Constructs the reduced graph for one item.
|
||||
fn build_reduced_graph_for_item(item: @item,
|
||||
parent: ReducedGraphParent,
|
||||
&&visitor: vt<ReducedGraphParent>) {
|
||||
|
|
@ -874,10 +874,10 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Constructs the reduced graph for one variant. Variants exist in the
|
||||
type namespace.
|
||||
"]
|
||||
/**
|
||||
* Constructs the reduced graph for one variant. Variants exist in the
|
||||
* type namespace.
|
||||
*/
|
||||
fn build_reduced_graph_for_variant(variant: variant,
|
||||
item_id: def_id,
|
||||
parent: ReducedGraphParent,
|
||||
|
|
@ -890,10 +890,10 @@ class Resolver {
|
|||
local_def(variant.node.id)));
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Constructs the reduced graph for one 'view item'. View items consist
|
||||
of imports and use directives.
|
||||
"]
|
||||
/**
|
||||
* Constructs the reduced graph for one 'view item'. View items consist
|
||||
* of imports and use directives.
|
||||
*/
|
||||
fn build_reduced_graph_for_view_item(view_item: @view_item,
|
||||
parent: ReducedGraphParent,
|
||||
&&_visitor: vt<ReducedGraphParent>) {
|
||||
|
|
@ -1045,7 +1045,7 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Constructs the reduced graph for one foreign item."]
|
||||
/// Constructs the reduced graph for one foreign item.
|
||||
fn build_reduced_graph_for_foreign_item(foreign_item: @foreign_item,
|
||||
parent: ReducedGraphParent,
|
||||
&&visitor:
|
||||
|
|
@ -1095,10 +1095,10 @@ class Resolver {
|
|||
visit_block(block, new_parent, visitor);
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Builds the reduced graph rooted at the 'use' directive for an external
|
||||
crate.
|
||||
"]
|
||||
/**
|
||||
* Builds the reduced graph rooted at the 'use' directive for an external
|
||||
* crate.
|
||||
*/
|
||||
fn build_reduced_graph_for_external_crate(root: @Module) {
|
||||
// Create all the items reachable by paths.
|
||||
for each_path(self.session.cstore, get(root.def_id).crate)
|
||||
|
|
@ -1285,7 +1285,7 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Creates and adds an import directive to the given module."]
|
||||
/// Creates and adds an import directive to the given module.
|
||||
fn build_import_directive(module: @Module,
|
||||
module_path: @dvec<Atom>,
|
||||
subclass: @ImportDirectiveSubclass) {
|
||||
|
|
@ -1328,10 +1328,10 @@ class Resolver {
|
|||
// remain or unsuccessfully when no forward progress in resolving imports
|
||||
// is made.
|
||||
|
||||
#[doc="
|
||||
Resolves all imports for the crate. This method performs the fixed-
|
||||
point iteration.
|
||||
"]
|
||||
/**
|
||||
* Resolves all imports for the crate. This method performs the fixed-
|
||||
* point iteration.
|
||||
*/
|
||||
fn resolve_imports() {
|
||||
let mut i = 0u;
|
||||
let mut prev_unresolved_imports = 0u;
|
||||
|
|
@ -1358,10 +1358,10 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Attempts to resolve imports for the given module and all of its
|
||||
submodules.
|
||||
"]
|
||||
/**
|
||||
* Attempts to resolve imports for the given module and all of its
|
||||
* submodules.
|
||||
*/
|
||||
fn resolve_imports_for_module_subtree(module: @Module) {
|
||||
#debug("(resolving imports for module subtree) resolving %s",
|
||||
self.module_to_str(module));
|
||||
|
|
@ -1383,7 +1383,7 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Attempts to resolve imports for the given module only."]
|
||||
/// Attempts to resolve imports for the given module only.
|
||||
fn resolve_imports_for_module(module: @Module) {
|
||||
if (*module).all_imports_resolved() {
|
||||
#debug("(resolving imports for module) all imports resolved for \
|
||||
|
|
@ -1416,13 +1416,13 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Attempts to resolve the given import. The return value indicates
|
||||
failure if we're certain the name does not exist, indeterminate if we
|
||||
don't know whether the name exists at the moment due to other
|
||||
currently-unresolved imports, or success if we know the name exists.
|
||||
If successful, the resolved bindings are written into the module.
|
||||
"]
|
||||
/**
|
||||
* Attempts to resolve the given import. The return value indicates
|
||||
* failure if we're certain the name does not exist, indeterminate if we
|
||||
* don't know whether the name exists at the moment due to other
|
||||
* currently-unresolved imports, or success if we know the name exists.
|
||||
* If successful, the resolved bindings are written into the module.
|
||||
*/
|
||||
fn resolve_import_for_module(module: @Module,
|
||||
import_directive: @ImportDirective)
|
||||
-> ResolveResult<()> {
|
||||
|
|
@ -1721,11 +1721,11 @@ class Resolver {
|
|||
ret Success(());
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Resolves a glob import. Note that this function cannot fail; it either
|
||||
succeeds or bails out (as importing * from an empty module or a module
|
||||
that exports nothing is valid).
|
||||
"]
|
||||
/**
|
||||
* Resolves a glob import. Note that this function cannot fail; it either
|
||||
* succeeds or bails out (as importing * from an empty module or a module
|
||||
* that exports nothing is valid).
|
||||
*/
|
||||
fn resolve_glob_import(module: @Module, containing_module: @Module)
|
||||
-> ResolveResult<()> {
|
||||
|
||||
|
|
@ -1927,10 +1927,10 @@ class Resolver {
|
|||
ret Success(search_module);
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Attempts to resolve the module part of an import directive rooted at
|
||||
the given module.
|
||||
"]
|
||||
/**
|
||||
* Attempts to resolve the module part of an import directive rooted at
|
||||
* the given module.
|
||||
*/
|
||||
fn resolve_module_path_for_import(module: @Module,
|
||||
module_path: @dvec<Atom>,
|
||||
xray: XrayFlag)
|
||||
|
|
@ -2093,11 +2093,11 @@ class Resolver {
|
|||
module.exported_names.contains_key(name);
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Attempts to resolve the supplied name in the given module for the
|
||||
given namespace. If successful, returns the target corresponding to
|
||||
the name.
|
||||
"]
|
||||
/**
|
||||
* Attempts to resolve the supplied name in the given module for the
|
||||
* given namespace. If successful, returns the target corresponding to
|
||||
* the name.
|
||||
*/
|
||||
fn resolve_name_in_module(module: @Module,
|
||||
name: Atom,
|
||||
namespace: Namespace,
|
||||
|
|
@ -2168,11 +2168,11 @@ class Resolver {
|
|||
ret Failed;
|
||||
}
|
||||
|
||||
#[doc="
|
||||
Resolves a one-level renaming import of the kind `import foo = bar;`
|
||||
This needs special handling, as, unlike all of the other imports, it
|
||||
needs to look in the scope chain for modules and non-modules alike.
|
||||
"]
|
||||
/**
|
||||
* Resolves a one-level renaming import of the kind `import foo = bar;`
|
||||
* This needs special handling, as, unlike all of the other imports, it
|
||||
* needs to look in the scope chain for modules and non-modules alike.
|
||||
*/
|
||||
fn resolve_one_level_renaming_import(module: @Module,
|
||||
import_directive: @ImportDirective)
|
||||
-> ResolveResult<()> {
|
||||
|
|
@ -3496,10 +3496,10 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="
|
||||
If `check_ribs` is true, checks the local definitions first; i.e.
|
||||
doesn't skip straight to the containing module.
|
||||
"]
|
||||
/**
|
||||
* If `check_ribs` is true, checks the local definitions first; i.e.
|
||||
* doesn't skip straight to the containing module.
|
||||
*/
|
||||
fn resolve_path(path: @path, namespace: Namespace, check_ribs: bool,
|
||||
visitor: ResolveVisitor)
|
||||
-> option<def> {
|
||||
|
|
@ -3859,7 +3859,7 @@ class Resolver {
|
|||
// hit.
|
||||
//
|
||||
|
||||
#[doc="A somewhat inefficient routine to print out the name of a module."]
|
||||
/// A somewhat inefficient routine to print out the name of a module.
|
||||
fn module_to_str(module: @Module) -> str {
|
||||
let atoms = dvec();
|
||||
let mut current_module = module;
|
||||
|
|
@ -3977,7 +3977,7 @@ class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc="Entry point to crate resolution."]
|
||||
/// Entry point to crate resolution.
|
||||
fn resolve_crate(session: session, ast_map: ASTMap, crate: @crate)
|
||||
-> { def_map: DefMap, exp_map: ExportMap, impl_map: ImplMap } {
|
||||
|
||||
|
|
|
|||
|
|
@ -2735,14 +2735,14 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Get the type of a box in the default address space.
|
||||
|
||||
Shared box pointers live in address space 1 so the GC strategy can find them.
|
||||
Before taking a pointer to the inside of a box it should be cast into address
|
||||
space 0. Otherwise the resulting (non-box) pointer will be in the wrong
|
||||
address space and thus be the wrong type.
|
||||
"]
|
||||
/**
|
||||
* Get the type of a box in the default address space.
|
||||
*
|
||||
* Shared box pointers live in address space 1 so the GC strategy can find
|
||||
* them. Before taking a pointer to the inside of a box it should be cast into
|
||||
* address space 0. Otherwise the resulting (non-box) pointer will be in the
|
||||
* wrong address space and thus be the wrong type.
|
||||
*/
|
||||
fn non_gc_box_cast(cx: block, val: ValueRef) -> ValueRef {
|
||||
#debug("non_gc_box_cast");
|
||||
add_comment(cx, "non_gc_box_cast");
|
||||
|
|
|
|||
|
|
@ -2996,9 +2996,7 @@ fn ty_params_to_tys(tcx: ty::ctxt, tps: ~[ast::ty_param]) -> ~[t] {
|
|||
})
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Returns an equivalent type with all the typedefs and self regions removed.
|
||||
"]
|
||||
/// Returns an equivalent type with all the typedefs and self regions removed.
|
||||
fn normalize_ty(cx: ctxt, t: t) -> t {
|
||||
alt cx.normalized_cache.find(t) {
|
||||
some(t) { ret t; }
|
||||
|
|
|
|||
|
|
@ -1,48 +1,46 @@
|
|||
#[doc = "
|
||||
|
||||
Conversion from AST representation of types to the ty.rs
|
||||
representation. The main routine here is `ast_ty_to_ty()`: each use
|
||||
is parameterized by an instance of `ast_conv` and a `region_scope`.
|
||||
|
||||
The parameterization of `ast_ty_to_ty()` is because it behaves
|
||||
somewhat differently during the collect and check phases, particularly
|
||||
with respect to looking up the types of top-level items. In the
|
||||
collect phase, the crate context is used as the `ast_conv` instance;
|
||||
in this phase, the `get_item_ty()` function triggers a recursive call
|
||||
to `ty_of_item()` (note that `ast_ty_to_ty()` will detect recursive
|
||||
types and report an error). In the check phase, when the @fn_ctxt is
|
||||
used as the `ast_conv`, `get_item_ty()` just looks up the item type in
|
||||
`tcx.tcache`.
|
||||
|
||||
The `region_scope` interface controls how region references are
|
||||
handled. It has two methods which are used to resolve anonymous
|
||||
region references (e.g., `&T`) and named region references (e.g.,
|
||||
`&a.T`). There are numerous region scopes that can be used, but most
|
||||
commonly you want either `empty_rscope`, which permits only the static
|
||||
region, or `type_rscope`, which permits the self region if the type in
|
||||
question is parameterized by a region.
|
||||
|
||||
Unlike the `ast_conv` iface, the region scope can change as we descend
|
||||
the type. This is to accommodate the fact that (a) fn types are binding
|
||||
scopes and (b) the default region may change. To understand case (a),
|
||||
consider something like:
|
||||
|
||||
type foo = { x: &a.int, y: fn(&a.int) }
|
||||
|
||||
The type of `x` is an error because there is no region `a` in scope.
|
||||
In the type of `y`, however, region `a` is considered a bound region
|
||||
as it does not already appear in scope.
|
||||
|
||||
Case (b) says that if you have a type:
|
||||
type foo/& = ...;
|
||||
type bar = fn(&foo, &a.foo)
|
||||
The fully expanded version of type bar is:
|
||||
type bar = fn(&foo/&, &a.foo/&a)
|
||||
Note that the self region for the `foo` defaulted to `&` in the first
|
||||
case but `&a` in the second. Basically, defaults that appear inside
|
||||
an rptr (`&r.T`) use the region `r` that appears in the rptr.
|
||||
|
||||
"];
|
||||
/*!
|
||||
* Conversion from AST representation of types to the ty.rs
|
||||
* representation. The main routine here is `ast_ty_to_ty()`: each use
|
||||
* is parameterized by an instance of `ast_conv` and a `region_scope`.
|
||||
*
|
||||
* The parameterization of `ast_ty_to_ty()` is because it behaves
|
||||
* somewhat differently during the collect and check phases, particularly
|
||||
* with respect to looking up the types of top-level items. In the
|
||||
* collect phase, the crate context is used as the `ast_conv` instance;
|
||||
* in this phase, the `get_item_ty()` function triggers a recursive call
|
||||
* to `ty_of_item()` (note that `ast_ty_to_ty()` will detect recursive
|
||||
* types and report an error). In the check phase, when the @fn_ctxt is
|
||||
* used as the `ast_conv`, `get_item_ty()` just looks up the item type in
|
||||
* `tcx.tcache`.
|
||||
*
|
||||
* The `region_scope` interface controls how region references are
|
||||
* handled. It has two methods which are used to resolve anonymous
|
||||
* region references (e.g., `&T`) and named region references (e.g.,
|
||||
* `&a.T`). There are numerous region scopes that can be used, but most
|
||||
* commonly you want either `empty_rscope`, which permits only the static
|
||||
* region, or `type_rscope`, which permits the self region if the type in
|
||||
* question is parameterized by a region.
|
||||
*
|
||||
* Unlike the `ast_conv` iface, the region scope can change as we descend
|
||||
* the type. This is to accommodate the fact that (a) fn types are binding
|
||||
* scopes and (b) the default region may change. To understand case (a),
|
||||
* consider something like:
|
||||
*
|
||||
* type foo = { x: &a.int, y: fn(&a.int) }
|
||||
*
|
||||
* The type of `x` is an error because there is no region `a` in scope.
|
||||
* In the type of `y`, however, region `a` is considered a bound region
|
||||
* as it does not already appear in scope.
|
||||
*
|
||||
* Case (b) says that if you have a type:
|
||||
* type foo/& = ...;
|
||||
* type bar = fn(&foo, &a.foo)
|
||||
* The fully expanded version of type bar is:
|
||||
* type bar = fn(&foo/&, &a.foo/&a)
|
||||
* Note that the self region for the `foo` defaulted to `&` in the first
|
||||
* case but `&a` in the second. Basically, defaults that appear inside
|
||||
* an rptr (`&r.T`) use the region `r` that appears in the rptr.
|
||||
*/
|
||||
|
||||
import check::fn_ctxt;
|
||||
import rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope};
|
||||
|
|
|
|||
|
|
@ -152,18 +152,18 @@ fn ensure_iface_methods(ccx: @crate_ctxt, id: ast::node_id) {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Checks that a method from an impl/class conforms to the signature of
|
||||
the same method as declared in the iface.
|
||||
|
||||
# Parameters
|
||||
|
||||
- impl_m: the method in the impl
|
||||
- impl_tps: the type params declared on the impl itself (not the method!)
|
||||
- if_m: the method in the iface
|
||||
- if_substs: the substitutions used on the type of the iface
|
||||
- self_ty: the self type of the impl
|
||||
"]
|
||||
/**
|
||||
* Checks that a method from an impl/class conforms to the signature of
|
||||
* the same method as declared in the iface.
|
||||
*
|
||||
* # Parameters
|
||||
*
|
||||
* - impl_m: the method in the impl
|
||||
* - impl_tps: the type params declared on the impl itself (not the method!)
|
||||
* - if_m: the method in the iface
|
||||
* - if_substs: the substitutions used on the type of the iface
|
||||
* - self_ty: the self type of the impl
|
||||
*/
|
||||
fn compare_impl_method(tcx: ty::ctxt, sp: span,
|
||||
impl_m: ty::method, impl_tps: uint,
|
||||
if_m: ty::method, if_substs: ty::substs,
|
||||
|
|
|
|||
|
|
@ -546,7 +546,7 @@ fn rollback_to<V:copy vid, T:copy>(
|
|||
}
|
||||
|
||||
impl transaction_methods for infer_ctxt {
|
||||
#[doc = "Execute `f` and commit the bindings if successful"]
|
||||
/// Execute `f` and commit the bindings if successful
|
||||
fn commit<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
|
||||
|
||||
assert self.tvb.bindings.len() == 0u;
|
||||
|
|
@ -562,7 +562,7 @@ impl transaction_methods for infer_ctxt {
|
|||
ret r;
|
||||
}
|
||||
|
||||
#[doc = "Execute `f`, unroll bindings on failure"]
|
||||
/// Execute `f`, unroll bindings on failure
|
||||
fn try<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
|
||||
|
||||
let tvbl = self.tvb.bindings.len();
|
||||
|
|
@ -580,7 +580,7 @@ impl transaction_methods for infer_ctxt {
|
|||
ret r;
|
||||
}
|
||||
|
||||
#[doc = "Execute `f` then unroll any bindings it creates"]
|
||||
/// Execute `f` then unroll any bindings it creates
|
||||
fn probe<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
|
||||
assert self.tvb.bindings.len() == 0u;
|
||||
assert self.rb.bindings.len() == 0u;
|
||||
|
|
|
|||
|
|
@ -39,9 +39,10 @@ fn doc_meta(
|
|||
attrs: ~[ast::attribute]
|
||||
) -> option<@ast::meta_item> {
|
||||
|
||||
#[doc =
|
||||
"Given a vec of attributes, extract the meta_items contained in the \
|
||||
doc attribute"];
|
||||
/*!
|
||||
* Given a vec of attributes, extract the meta_items contained in the \
|
||||
* doc attribute
|
||||
*/
|
||||
|
||||
let doc_attrs = attr::find_attrs_by_name(attrs, "doc");
|
||||
let doc_metas = do doc_attrs.map |attr| {
|
||||
|
|
|
|||
|
|
@ -8,23 +8,23 @@ export default_config;
|
|||
export parse_config;
|
||||
export usage;
|
||||
|
||||
#[doc = "The type of document to output"]
|
||||
/// The type of document to output
|
||||
enum output_format {
|
||||
#[doc = "Markdown"]
|
||||
/// Markdown
|
||||
markdown,
|
||||
#[doc = "HTML, via markdown and pandoc"]
|
||||
/// HTML, via markdown and pandoc
|
||||
pandoc_html
|
||||
}
|
||||
|
||||
#[doc = "How to organize the output"]
|
||||
/// How to organize the output
|
||||
enum output_style {
|
||||
#[doc = "All in a single document"]
|
||||
/// All in a single document
|
||||
doc_per_crate,
|
||||
#[doc = "Each module in its own document"]
|
||||
/// Each module in its own document
|
||||
doc_per_mod
|
||||
}
|
||||
|
||||
#[doc = "The configuration for a rustdoc session"]
|
||||
/// The configuration for a rustdoc session
|
||||
type config = {
|
||||
input_crate: str,
|
||||
output_dir: str,
|
||||
|
|
|
|||
|
|
@ -1,30 +1,28 @@
|
|||
// no-reformat
|
||||
|
||||
#[doc = "
|
||||
/*!
|
||||
* A demonstration module
|
||||
*
|
||||
* Contains documentation in various forms that rustdoc understands,
|
||||
* for testing purposes. It doesn't surve any functional
|
||||
* purpose. This here, for instance, is just some filler text.
|
||||
*
|
||||
* FIXME (#1654): It would be nice if we could run some automated
|
||||
* tests on this file
|
||||
*/
|
||||
|
||||
A demonstration module
|
||||
|
||||
Contains documentation in various forms that rustdoc understands,
|
||||
for testing purposes. It doesn't surve any functional
|
||||
purpose. This here, for instance, is just some filler text.
|
||||
|
||||
FIXME (#1654): It would be nice if we could run some automated
|
||||
tests on this file
|
||||
|
||||
"];
|
||||
|
||||
#[doc = "The base price of a muffin on a non-holiday"]
|
||||
/// The base price of a muffin on a non-holiday
|
||||
const price_of_a_muffin: float = 70f;
|
||||
|
||||
type waitress = {
|
||||
hair_color: str
|
||||
};
|
||||
|
||||
#[doc = "The type of things that produce omnomnom"]
|
||||
/// The type of things that produce omnomnom
|
||||
enum omnomnomy {
|
||||
#[doc = "Delicious sugar cookies"]
|
||||
/// Delicious sugar cookies
|
||||
cookie,
|
||||
#[doc = "It's pizza"]
|
||||
/// It's pizza
|
||||
pizza_pie(~[uint])
|
||||
}
|
||||
|
||||
|
|
@ -33,154 +31,151 @@ fn take_my_order_please(
|
|||
_order: ~[omnomnomy]
|
||||
) -> uint {
|
||||
|
||||
#[doc = "
|
||||
OMG would you take my order already?
|
||||
|
||||
# Arguments
|
||||
|
||||
* _waitress - The waitress that you want to bother
|
||||
* _order - The order vector. It should be filled with food
|
||||
|
||||
# Return
|
||||
|
||||
The price of the order, including tax
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
|
||||
molestie nisl. Duis massa risus, pharetra a scelerisque a,
|
||||
molestie eu velit. Donec mattis ligula at ante imperdiet ut
|
||||
dapibus mauris malesuada.
|
||||
|
||||
Sed gravida nisi a metus elementum sit amet hendrerit dolor
|
||||
bibendum. Aenean sit amet neque massa, sed tempus tortor. Sed ut
|
||||
lobortis enim. Proin a mauris quis nunc fermentum ultrices eget a
|
||||
erat. Mauris in lectus vitae metus sodales auctor. Morbi nunc
|
||||
quam, ultricies at venenatis non, pellentesque ac dui.
|
||||
|
||||
# Failure
|
||||
|
||||
This function is full of fail
|
||||
"];
|
||||
/*!
|
||||
* OMG would you take my order already?
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * _waitress - The waitress that you want to bother
|
||||
* * _order - The order vector. It should be filled with food
|
||||
*
|
||||
* # Return
|
||||
*
|
||||
* The price of the order, including tax
|
||||
*
|
||||
* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
|
||||
* molestie nisl. Duis massa risus, pharetra a scelerisque a,
|
||||
* molestie eu velit. Donec mattis ligula at ante imperdiet ut
|
||||
* dapibus mauris malesuada.
|
||||
*
|
||||
* Sed gravida nisi a metus elementum sit amet hendrerit dolor
|
||||
* bibendum. Aenean sit amet neque massa, sed tempus tortor. Sed ut
|
||||
* lobortis enim. Proin a mauris quis nunc fermentum ultrices eget a
|
||||
* erat. Mauris in lectus vitae metus sodales auctor. Morbi nunc
|
||||
* quam, ultricies at venenatis non, pellentesque ac dui.
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* This function is full of fail
|
||||
*/
|
||||
|
||||
fail;
|
||||
}
|
||||
|
||||
mod fortress_of_solitude {
|
||||
#[doc = "
|
||||
Superman's vacation home
|
||||
|
||||
The fortress of solitude is located in the Arctic and it is
|
||||
cold. What you may not know about the fortress of solitude
|
||||
though is that it contains two separate bowling alleys. One of
|
||||
them features bumper-bowling and is kind of lame.
|
||||
|
||||
Really, it's pretty cool.
|
||||
|
||||
"];
|
||||
/*!
|
||||
* Superman's vacation home
|
||||
*
|
||||
* The fortress of solitude is located in the Arctic and it is
|
||||
* cold. What you may not know about the fortress of solitude
|
||||
* though is that it contains two separate bowling alleys. One of
|
||||
* them features bumper-bowling and is kind of lame.
|
||||
*
|
||||
* Really, it's pretty cool.
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
mod blade_runner {
|
||||
#[doc = "
|
||||
Blade Runner is probably the best movie ever
|
||||
|
||||
I like that in the world of Blade Runner it is always
|
||||
raining, and that it's always night time. And Aliens
|
||||
was also a really good movie.
|
||||
|
||||
Alien 3 was crap though.
|
||||
"];
|
||||
/*!
|
||||
* Blade Runner is probably the best movie ever
|
||||
*
|
||||
* I like that in the world of Blade Runner it is always
|
||||
* raining, and that it's always night time. And Aliens
|
||||
* was also a really good movie.
|
||||
*
|
||||
* Alien 3 was crap though.
|
||||
*/
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Bored
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
|
||||
molestie nisl. Duis massa risus, pharetra a scelerisque a,
|
||||
molestie eu velit. Donec mattis ligula at ante imperdiet ut
|
||||
dapibus mauris malesuada. Sed gravida nisi a metus elementum sit
|
||||
amet hendrerit dolor bibendum. Aenean sit amet neque massa, sed
|
||||
tempus tortor. Sed ut lobortis enim. Proin a mauris quis nunc
|
||||
fermentum ultrices eget a erat. Mauris in lectus vitae metus
|
||||
sodales auctor. Morbi nunc quam, ultricies at venenatis non,
|
||||
pellentesque ac dui.
|
||||
|
||||
Quisque vitae est id eros placerat laoreet sit amet eu
|
||||
nisi. Curabitur suscipit neque porttitor est euismod
|
||||
lacinia. Curabitur non quam vitae ipsum adipiscing
|
||||
condimentum. Mauris ut ante eget metus sollicitudin
|
||||
blandit. Aliquam erat volutpat. Morbi sed nisl mauris. Nulla
|
||||
facilisi. Phasellus at mollis ipsum. Maecenas sed convallis
|
||||
sapien. Nullam in ligula turpis. Pellentesque a neque augue. Sed
|
||||
eget ante feugiat tortor congue auctor ac quis ante. Proin
|
||||
condimentum lacinia tincidunt.
|
||||
|
||||
"]
|
||||
/**
|
||||
* Bored
|
||||
*
|
||||
* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
|
||||
* molestie nisl. Duis massa risus, pharetra a scelerisque a,
|
||||
* molestie eu velit. Donec mattis ligula at ante imperdiet ut
|
||||
* dapibus mauris malesuada. Sed gravida nisi a metus elementum sit
|
||||
* amet hendrerit dolor bibendum. Aenean sit amet neque massa, sed
|
||||
* tempus tortor. Sed ut lobortis enim. Proin a mauris quis nunc
|
||||
* fermentum ultrices eget a erat. Mauris in lectus vitae metus
|
||||
* sodales auctor. Morbi nunc quam, ultricies at venenatis non,
|
||||
* pellentesque ac dui.
|
||||
*
|
||||
* Quisque vitae est id eros placerat laoreet sit amet eu
|
||||
* nisi. Curabitur suscipit neque porttitor est euismod
|
||||
* lacinia. Curabitur non quam vitae ipsum adipiscing
|
||||
* condimentum. Mauris ut ante eget metus sollicitudin
|
||||
* blandit. Aliquam erat volutpat. Morbi sed nisl mauris. Nulla
|
||||
* facilisi. Phasellus at mollis ipsum. Maecenas sed convallis
|
||||
* sapien. Nullam in ligula turpis. Pellentesque a neque augue. Sed
|
||||
* eget ante feugiat tortor congue auctor ac quis ante. Proin
|
||||
* condimentum lacinia tincidunt.
|
||||
*/
|
||||
class bored {
|
||||
let bored: bool;
|
||||
new(bored: bool) { self.bored = bored; }
|
||||
drop { log(error, self.bored); }
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
The Shunned House
|
||||
|
||||
From even the greatest of horrors irony is seldom absent. Sometimes it
|
||||
enters directly into the composition of the events, while sometimes it
|
||||
relates only to their fortuitous position among persons and
|
||||
places. The latter sort is splendidly exemplified by a case in the
|
||||
ancient city of Providence, where in the late forties Edgar Allan Poe
|
||||
used to sojourn often during his unsuccessful wooing of the gifted
|
||||
poetess, Mrs. Whitman. Poe generally stopped at the Mansion House in
|
||||
Benefit Street--the renamed Golden Ball Inn whose roof has sheltered
|
||||
Washington, Jefferson, and Lafayette--and his favorite walk led
|
||||
northward along the same street to Mrs. Whitman's home and the
|
||||
neighboring hillside churchyard of St. John's, whose hidden expanse of
|
||||
Eighteenth Century gravestones had for him a peculiar fascination.
|
||||
|
||||
"]
|
||||
/**
|
||||
* The Shunned House
|
||||
*
|
||||
* From even the greatest of horrors irony is seldom absent. Sometimes it
|
||||
* enters directly into the composition of the events, while sometimes it
|
||||
* relates only to their fortuitous position among persons and
|
||||
* places. The latter sort is splendidly exemplified by a case in the
|
||||
* ancient city of Providence, where in the late forties Edgar Allan Poe
|
||||
* used to sojourn often during his unsuccessful wooing of the gifted
|
||||
* poetess, Mrs. Whitman. Poe generally stopped at the Mansion House in
|
||||
* Benefit Street--the renamed Golden Ball Inn whose roof has sheltered
|
||||
* Washington, Jefferson, and Lafayette--and his favorite walk led
|
||||
* northward along the same street to Mrs. Whitman's home and the
|
||||
* neighboring hillside churchyard of St. John's, whose hidden expanse of
|
||||
* Eighteenth Century gravestones had for him a peculiar fascination.
|
||||
*/
|
||||
iface the_shunned_house {
|
||||
#[doc = "
|
||||
Now the irony is this. In this walk, so many times repeated, the
|
||||
world's greatest master of the terrible and the bizarre was
|
||||
obliged to pass a particular house on the eastern side of the
|
||||
street; a dingy, antiquated structure perched on the abruptly
|
||||
rising side hill, with a great unkempt yard dating from a time
|
||||
when the region was partly open country. It does not appear that
|
||||
he ever wrote or spoke of it, nor is there any evidence that he
|
||||
even noticed it. And yet that house, to the two persons in
|
||||
possession of certain information, equals or outranks in horror
|
||||
the wildest fantasy of the genius who so often passed it
|
||||
unknowingly, and stands starkly leering as a symbol of all that is
|
||||
unutterably hideous.
|
||||
|
||||
# Arguments
|
||||
|
||||
* unkempt_yard - A yard dating from a time when the region was partly
|
||||
open country
|
||||
"]
|
||||
/**
|
||||
* Now the irony is this. In this walk, so many times repeated, the
|
||||
* world's greatest master of the terrible and the bizarre was
|
||||
* obliged to pass a particular house on the eastern side of the
|
||||
* street; a dingy, antiquated structure perched on the abruptly
|
||||
* rising side hill, with a great unkempt yard dating from a time
|
||||
* when the region was partly open country. It does not appear that
|
||||
* he ever wrote or spoke of it, nor is there any evidence that he
|
||||
* even noticed it. And yet that house, to the two persons in
|
||||
* possession of certain information, equals or outranks in horror
|
||||
* the wildest fantasy of the genius who so often passed it
|
||||
* unknowingly, and stands starkly leering as a symbol of all that is
|
||||
* unutterably hideous.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * unkempt_yard - A yard dating from a time when the region was partly
|
||||
* open country
|
||||
*/
|
||||
fn dingy_house(unkempt_yard: int);
|
||||
|
||||
#[doc = "
|
||||
The house was--and for that matter still is--of a kind to attract
|
||||
the attention of the curious. Originally a farm or semi-farm
|
||||
building, it followed the average New England colonial lines of
|
||||
the middle Eighteenth Century--the prosperous peaked-roof sort,
|
||||
with two stories and dormerless attic, and with the Georgian
|
||||
doorway and interior panelling dictated by the progress of taste
|
||||
at that time. It faced south, with one gable end buried to the
|
||||
lower windows in the eastward rising hill, and the other exposed
|
||||
to the foundations toward the street. Its construction, over a
|
||||
century and a half ago, had followed the grading and straightening
|
||||
of the road in that especial vicinity; for Benefit Street--at
|
||||
first called Back Street--was laid out as a lane winding amongst
|
||||
the graveyards of the first settlers, and straightened only when
|
||||
the removal of the bodies to the North Burial Ground made it
|
||||
decently possible to cut through the old family plots.
|
||||
"]
|
||||
/**
|
||||
* The house was--and for that matter still is--of a kind to attract
|
||||
* the attention of the curious. Originally a farm or semi-farm
|
||||
* building, it followed the average New England colonial lines of
|
||||
* the middle Eighteenth Century--the prosperous peaked-roof sort,
|
||||
* with two stories and dormerless attic, and with the Georgian
|
||||
* doorway and interior panelling dictated by the progress of taste
|
||||
* at that time. It faced south, with one gable end buried to the
|
||||
* lower windows in the eastward rising hill, and the other exposed
|
||||
* to the foundations toward the street. Its construction, over a
|
||||
* century and a half ago, had followed the grading and straightening
|
||||
* of the road in that especial vicinity; for Benefit Street--at
|
||||
* first called Back Street--was laid out as a lane winding amongst
|
||||
* the graveyards of the first settlers, and straightened only when
|
||||
* the removal of the bodies to the North Burial Ground made it
|
||||
* decently possible to cut through the old family plots.
|
||||
*/
|
||||
fn construct() -> bool;
|
||||
}
|
||||
|
||||
#[doc = "Whatever"]
|
||||
/// Whatever
|
||||
impl of the_shunned_house for omnomnomy {
|
||||
fn dingy_house(_unkempt_yard: int) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
#[doc = "
|
||||
|
||||
Pulls a brief description out of a long description.
|
||||
|
||||
If the first paragraph of a long description is short enough then it
|
||||
is interpreted as the brief description.
|
||||
|
||||
"];
|
||||
/*!
|
||||
* Pulls a brief description out of a long description.
|
||||
*
|
||||
* If the first paragraph of a long description is short enough then it
|
||||
* is interpreted as the brief description.
|
||||
*/
|
||||
|
||||
export mk_pass;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "The document model"];
|
||||
//! The document model
|
||||
|
||||
type ast_id = int;
|
||||
|
||||
|
|
@ -11,10 +11,10 @@ enum page {
|
|||
itempage(itemtag)
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Most rustdocs can be parsed into 'sections' according to their markdown
|
||||
headers
|
||||
"]
|
||||
/**
|
||||
* Most rustdocs can be parsed into 'sections' according to their markdown
|
||||
* headers
|
||||
*/
|
||||
type section = {
|
||||
header: str,
|
||||
body: str
|
||||
|
|
@ -107,18 +107,16 @@ type index = {
|
|||
entries: ~[index_entry]
|
||||
};
|
||||
|
||||
#[doc = "
|
||||
|
||||
A single entry in an index
|
||||
|
||||
Fields:
|
||||
|
||||
* kind - The type of thing being indexed, e.g. 'Module'
|
||||
* name - The name of the thing
|
||||
* brief - The brief description
|
||||
* link - A format-specific string representing the link target
|
||||
|
||||
"]
|
||||
/**
|
||||
* A single entry in an index
|
||||
*
|
||||
* Fields:
|
||||
*
|
||||
* * kind - The type of thing being indexed, e.g. 'Module'
|
||||
* * name - The name of the thing
|
||||
* * brief - The brief description
|
||||
* * link - A format-specific string representing the link target
|
||||
*/
|
||||
type index_entry = {
|
||||
kind: str,
|
||||
name: str,
|
||||
|
|
@ -141,7 +139,7 @@ impl util for doc {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc = "Some helper methods on moddoc, mostly for testing"]
|
||||
/// Some helper methods on moddoc, mostly for testing
|
||||
impl util for moddoc {
|
||||
|
||||
fn mods() -> ~[moddoc] {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[doc = "Escapes text sequences"];
|
||||
//! Escapes text sequences
|
||||
|
||||
export mk_pass;
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue