convert doc-attributes to doc-comments using ./src/etc/sugarise-doc-comments.py (and manually tweaking) - for issue #2498

This commit is contained in:
Gareth Daniel Smith 2012-07-04 22:53:12 +01:00 committed by Brian Anderson
parent bfa43ca301
commit be0141666d
123 changed files with 4981 additions and 5044 deletions

View file

@ -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);

View file

@ -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]

View file

@ -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) }
}

View file

@ -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 }

View file

@ -1,4 +1,4 @@
#[doc="Interfaces used for comparison."]
/// Interfaces used for comparison.
iface ord {
fn lt(&&other: self) -> bool;

View file

@ -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];

View file

@ -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"]

View file

@ -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";
}

View file

@ -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 }
}

View file

@ -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();

View file

@ -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 } }
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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 {

View file

@ -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 }

View file

@ -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 {

View file

@ -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; }

View file

@ -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;

View file

@ -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 })

View file

@ -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.

View file

@ -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();
}

View file

@ -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;

View file

@ -1,4 +1,4 @@
#[doc="An interface for numbers."]
/// An interface for numbers.
iface num {
// FIXME: Cross-crate overloading doesn't work yet. (#2615)

View file

@ -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) }
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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) }
}

View file

@ -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
}

View file

@ -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 {

View file

@ -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);

File diff suppressed because it is too large Load diff

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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]

View file

@ -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;

View file

@ -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'

View file

@ -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

View file

@ -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;

View file

@ -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 */
}
}
}

View file

@ -1,4 +1,4 @@
#[doc="Additional general-purpose comparison functionality."]
/// Additional general-purpose comparison functionality.
const fuzzy_epsilon: float = 1.0e-6;

View file

@ -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();
}

View file

@ -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};

View file

@ -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 { }

View file

@ -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>; }

View file

@ -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 }

View file

@ -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 {

View file

@ -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)
}

View file

@ -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;

View file

@ -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) }

View file

@ -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 =

View file

@ -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

View file

@ -1,4 +1,4 @@
#[doc = "Support code for serialization."];
//! Support code for serialization.
use core;

View file

@ -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],

View file

@ -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>
}

View file

@ -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,

View file

@ -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];

View file

@ -1,4 +1,4 @@
#[doc = "Temporary files and directories"];
//! Temporary files and directories
import core::option;
import option::{none, some};

View file

@ -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);
}

View file

@ -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")

View file

@ -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> {

View file

@ -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 { }

View file

@ -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 {

View file

@ -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;

View file

@ -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();
}

View file

@ -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 {

View file

@ -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;

View file

@ -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 }

View file

@ -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| {

View file

@ -1,4 +1,4 @@
#[doc = "The main parser interface"];
//! The main parser interface
import dvec::extensions;
export parse_sess;

View file

@ -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,

View file

@ -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 }

View file

@ -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) }

View file

@ -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 = ~[

View file

@ -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;
}

View file

@ -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)
}

View file

@ -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,

View file

@ -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};

View file

@ -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);

View file

@ -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);

View file

@ -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};

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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};

View file

@ -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 } {

View file

@ -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");

View file

@ -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; }

View file

@ -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};

View file

@ -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,

View file

@ -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;

View file

@ -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| {

View file

@ -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,

View file

@ -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) {
}

View file

@ -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;

View file

@ -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] {

View file

@ -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