diff options
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/atomic.rs | 394 | ||||
| -rw-r--r-- | src/libcore/fmt/mod.rs | 149 | ||||
| -rw-r--r-- | src/libcore/fmt/num.rs | 5 | ||||
| -rw-r--r-- | src/libcore/fmt/rt.rs | 2 | ||||
| -rw-r--r-- | src/libcore/macros.rs | 15 | ||||
| -rw-r--r-- | src/libcore/result.rs | 46 |
6 files changed, 372 insertions, 239 deletions
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index d2bca1e6ec7..e930f353b52 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -18,28 +18,28 @@ use intrinsics; use std::kinds::marker; use cell::UnsafeCell; -/// An atomic boolean type. +/// A boolean type which can be safely shared between threads. #[stable] pub struct AtomicBool { v: UnsafeCell<uint>, nocopy: marker::NoCopy } -/// A signed atomic integer type, supporting basic atomic arithmetic operations +/// A signed integer type which can be safely shared between threads. #[stable] pub struct AtomicInt { v: UnsafeCell<int>, nocopy: marker::NoCopy } -/// An unsigned atomic integer type, supporting basic atomic arithmetic operations +/// An unsigned integer type which can be safely shared between threads. #[stable] pub struct AtomicUint { v: UnsafeCell<uint>, nocopy: marker::NoCopy } -/// An unsafe atomic pointer. Only supports basic atomic operations +/// A raw pointer type which can be safely shared between threads. #[stable] pub struct AtomicPtr<T> { p: UnsafeCell<uint>, @@ -54,43 +54,42 @@ pub struct AtomicPtr<T> { /// to be moved either before or after the atomic operation; on the other end /// "relaxed" atomics allow all reorderings. /// -/// Rust's memory orderings are the same as in C++[1]. -/// -/// 1: http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync +/// Rust's memory orderings are [the same as +/// C++'s](http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync). #[stable] pub enum Ordering { - /// No ordering constraints, only atomic operations + /// No ordering constraints, only atomic operations. #[stable] Relaxed, /// When coupled with a store, all previous writes become visible /// to another thread that performs a load with `Acquire` ordering - /// on the same value + /// on the same value. #[stable] Release, /// When coupled with a load, all subsequent loads will see data /// written before a store with `Release` ordering on the same value - /// in another thread + /// in another thread. #[stable] Acquire, /// When coupled with a load, uses `Acquire` ordering, and with a store - /// `Release` ordering + /// `Release` ordering. #[stable] AcqRel, /// Like `AcqRel` with the additional guarantee that all threads see all /// sequentially consistent operations in the same order. #[stable] - SeqCst + SeqCst, } -/// An `AtomicBool` initialized to `false` +/// An `AtomicBool` initialized to `false`. #[unstable = "may be renamed, pending conventions for static initalizers"] pub const INIT_ATOMIC_BOOL: AtomicBool = AtomicBool { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy }; -/// An `AtomicInt` initialized to `0` +/// An `AtomicInt` initialized to `0`. #[unstable = "may be renamed, pending conventions for static initalizers"] pub const INIT_ATOMIC_INT: AtomicInt = AtomicInt { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy }; -/// An `AtomicUint` initialized to `0` +/// An `AtomicUint` initialized to `0`. #[unstable = "may be renamed, pending conventions for static initalizers"] pub const INIT_ATOMIC_UINT: AtomicUint = AtomicUint { v: UnsafeCell { value: 0, }, nocopy: marker::NoCopy }; @@ -99,7 +98,16 @@ pub const INIT_ATOMIC_UINT: AtomicUint = const UINT_TRUE: uint = -1; impl AtomicBool { - /// Create a new `AtomicBool` + /// Creates a new `AtomicBool`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::AtomicBool; + /// + /// let atomic_true = AtomicBool::new(true); + /// let atomic_false = AtomicBool::new(false); + /// ``` #[inline] #[stable] pub fn new(v: bool) -> AtomicBool { @@ -107,18 +115,42 @@ impl AtomicBool { AtomicBool { v: UnsafeCell::new(val), nocopy: marker::NoCopy } } - /// Load the value + /// Loads a value from the bool. + /// + /// `load` takes an `Ordering` argument which describes the memory ordering of this operation. /// /// # Panics /// /// Panics if `order` is `Release` or `AcqRel`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// let value = some_bool.load(Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn load(&self, order: Ordering) -> bool { unsafe { atomic_load(self.v.get() as *const uint, order) > 0 } } - /// Store the value + /// Stores a value into the bool. + /// + /// `store` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// some_bool.store(false, Ordering::Relaxed); + /// ``` /// /// # Panics /// @@ -131,7 +163,19 @@ impl AtomicBool { unsafe { atomic_store(self.v.get(), val, order); } } - /// Store a value, returning the old value + /// Stores a value into the bool, returning the old value. + /// + /// `swap` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// let value = some_bool.swap(false, Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn swap(&self, val: bool, order: Ordering) -> bool { @@ -140,48 +184,21 @@ impl AtomicBool { unsafe { atomic_swap(self.v.get(), val, order) > 0 } } - /// If the current value is the same as expected, store a new value + /// Stores a value into the bool if the current value is the same as the expected value. /// - /// Compare the current value with `old`; if they are the same then - /// replace the current value with `new`. Return the previous value. /// If the return value is equal to `old` then the value was updated. /// - /// # Examples - /// - /// ```rust - /// use std::sync::Arc; - /// use std::sync::atomic::{AtomicBool, SeqCst}; - /// use std::task::deschedule; - /// - /// fn main() { - /// let spinlock = Arc::new(AtomicBool::new(false)); - /// let spinlock_clone = spinlock.clone(); + /// `swap` also takes an `Ordering` argument which describes the memory ordering of this + /// operation. /// - /// spawn(proc() { - /// with_lock(&spinlock, || println!("task 1 in lock")); - /// }); - /// - /// spawn(proc() { - /// with_lock(&spinlock_clone, || println!("task 2 in lock")); - /// }); - /// } + /// # Examples /// - /// fn with_lock(spinlock: &Arc<AtomicBool>, f: || -> ()) { - /// // CAS loop until we are able to replace `false` with `true` - /// while spinlock.compare_and_swap(false, true, SeqCst) != false { - /// // Since tasks may not be preemptive (if they are green threads) - /// // yield to the scheduler to let the other task run. Low level - /// // concurrent code needs to take into account Rust's two threading - /// // models. - /// deschedule(); - /// } + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; /// - /// // Now we have the spinlock - /// f(); + /// let some_bool = AtomicBool::new(true); /// - /// // Release the lock - /// spinlock.store(false, SeqCst); - /// } + /// let value = some_bool.store(false, Ordering::Relaxed); /// ``` #[inline] #[stable] @@ -192,10 +209,11 @@ impl AtomicBool { unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) > 0 } } - /// A logical "and" operation + /// Logical "and" with a boolean value. + /// + /// Performs a logical "and" operation on the current value and the argument `val`, and sets + /// the new value to the result. /// - /// Performs a logical "and" operation on the current value and the - /// argument `val`, and sets the new value to the result. /// Returns the previous value. /// /// # Examples @@ -223,10 +241,11 @@ impl AtomicBool { unsafe { atomic_and(self.v.get(), val, order) > 0 } } - /// A logical "nand" operation + /// Logical "nand" with a boolean value. + /// + /// Performs a logical "nand" operation on the current value and the argument `val`, and sets + /// the new value to the result. /// - /// Performs a logical "nand" operation on the current value and the - /// argument `val`, and sets the new value to the result. /// Returns the previous value. /// /// # Examples @@ -255,10 +274,11 @@ impl AtomicBool { unsafe { atomic_nand(self.v.get(), val, order) > 0 } } - /// A logical "or" operation + /// Logical "or" with a boolean value. + /// + /// Performs a logical "or" operation on the current value and the argument `val`, and sets the + /// new value to the result. /// - /// Performs a logical "or" operation on the current value and the - /// argument `val`, and sets the new value to the result. /// Returns the previous value. /// /// # Examples @@ -286,10 +306,11 @@ impl AtomicBool { unsafe { atomic_or(self.v.get(), val, order) > 0 } } - /// A logical "xor" operation + /// Logical "xor" with a boolean value. + /// + /// Performs a logical "xor" operation on the current value and the argument `val`, and sets + /// the new value to the result. /// - /// Performs a logical "xor" operation on the current value and the - /// argument `val`, and sets the new value to the result. /// Returns the previous value. /// /// # Examples @@ -319,25 +340,57 @@ impl AtomicBool { } impl AtomicInt { - /// Create a new `AtomicInt` + /// Creates a new `AtomicInt`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::AtomicInt; + /// + /// let atomic_forty_two = AtomicInt::new(42); + /// ``` #[inline] #[stable] pub fn new(v: int) -> AtomicInt { AtomicInt {v: UnsafeCell::new(v), nocopy: marker::NoCopy} } - /// Load the value + /// Loads a value from the int. + /// + /// `load` takes an `Ordering` argument which describes the memory ordering of this operation. /// /// # Panics /// /// Panics if `order` is `Release` or `AcqRel`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicInt, Ordering}; + /// + /// let some_int = AtomicInt::new(5); + /// + /// let value = some_int.load(Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn load(&self, order: Ordering) -> int { unsafe { atomic_load(self.v.get() as *const int, order) } } - /// Store the value + /// Stores a value into the int. + /// + /// `store` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicInt, Ordering}; + /// + /// let some_int = AtomicInt::new(5); + /// + /// some_int.store(10, Ordering::Relaxed); + /// ``` /// /// # Panics /// @@ -348,25 +401,48 @@ impl AtomicInt { unsafe { atomic_store(self.v.get(), val, order); } } - /// Store a value, returning the old value + /// Stores a value into the int, returning the old value. + /// + /// `swap` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicInt, Ordering}; + /// + /// let some_int = AtomicInt::new(5); + /// + /// let value = some_int.swap(10, Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn swap(&self, val: int, order: Ordering) -> int { unsafe { atomic_swap(self.v.get(), val, order) } } - /// If the current value is the same as expected, store a new value + /// Stores a value into the int if the current value is the same as the expected value. /// - /// Compare the current value with `old`; if they are the same then - /// replace the current value with `new`. Return the previous value. /// If the return value is equal to `old` then the value was updated. + /// + /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of + /// this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicInt, Ordering}; + /// + /// let some_int = AtomicInt::new(5); + /// + /// let value = some_int.compare_and_swap(5, 10, Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int { unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) } } - /// Add to the current value, returning the previous + /// Add an int to the current value, returning the previous value. /// /// # Examples /// @@ -383,7 +459,7 @@ impl AtomicInt { unsafe { atomic_add(self.v.get(), val, order) } } - /// Subtract from the current value, returning the previous + /// Subtract an int from the current value, returning the previous value. /// /// # Examples /// @@ -400,7 +476,7 @@ impl AtomicInt { unsafe { atomic_sub(self.v.get(), val, order) } } - /// Bitwise and with the current value, returning the previous + /// Bitwise and with the current int, returning the previous value. /// /// # Examples /// @@ -416,7 +492,7 @@ impl AtomicInt { unsafe { atomic_and(self.v.get(), val, order) } } - /// Bitwise or with the current value, returning the previous + /// Bitwise or with the current int, returning the previous value. /// /// # Examples /// @@ -432,7 +508,7 @@ impl AtomicInt { unsafe { atomic_or(self.v.get(), val, order) } } - /// Bitwise xor with the current value, returning the previous + /// Bitwise xor with the current int, returning the previous value. /// /// # Examples /// @@ -450,25 +526,57 @@ impl AtomicInt { } impl AtomicUint { - /// Create a new `AtomicUint` + /// Creates a new `AtomicUint`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::AtomicUint; + /// + /// let atomic_forty_two = AtomicUint::new(42u); + /// ``` #[inline] #[stable] pub fn new(v: uint) -> AtomicUint { AtomicUint { v: UnsafeCell::new(v), nocopy: marker::NoCopy } } - /// Load the value + /// Loads a value from the uint. + /// + /// `load` takes an `Ordering` argument which describes the memory ordering of this operation. /// /// # Panics /// /// Panics if `order` is `Release` or `AcqRel`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUint, Ordering}; + /// + /// let some_uint = AtomicUint::new(5); + /// + /// let value = some_uint.load(Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn load(&self, order: Ordering) -> uint { unsafe { atomic_load(self.v.get() as *const uint, order) } } - /// Store the value + /// Stores a value into the uint. + /// + /// `store` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUint, Ordering}; + /// + /// let some_uint = AtomicUint::new(5); + /// + /// some_uint.store(10, Ordering::Relaxed); + /// ``` /// /// # Panics /// @@ -479,25 +587,48 @@ impl AtomicUint { unsafe { atomic_store(self.v.get(), val, order); } } - /// Store a value, returning the old value + /// Stores a value into the uint, returning the old value. + /// + /// `swap` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUint, Ordering}; + /// + /// let some_uint = AtomicUint::new(5); + /// + /// let value = some_uint.swap(10, Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn swap(&self, val: uint, order: Ordering) -> uint { unsafe { atomic_swap(self.v.get(), val, order) } } - /// If the current value is the same as expected, store a new value + /// Stores a value into the uint if the current value is the same as the expected value. /// - /// Compare the current value with `old`; if they are the same then - /// replace the current value with `new`. Return the previous value. /// If the return value is equal to `old` then the value was updated. + /// + /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of + /// this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUint, Ordering}; + /// + /// let some_uint = AtomicUint::new(5); + /// + /// let value = some_uint.compare_and_swap(5, 10, Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint { unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) } } - /// Add to the current value, returning the previous + /// Add to the current uint, returning the previous value. /// /// # Examples /// @@ -514,7 +645,7 @@ impl AtomicUint { unsafe { atomic_add(self.v.get(), val, order) } } - /// Subtract from the current value, returning the previous + /// Subtract from the current uint, returning the previous value. /// /// # Examples /// @@ -531,7 +662,7 @@ impl AtomicUint { unsafe { atomic_sub(self.v.get(), val, order) } } - /// Bitwise and with the current value, returning the previous + /// Bitwise and with the current uint, returning the previous value. /// /// # Examples /// @@ -547,7 +678,7 @@ impl AtomicUint { unsafe { atomic_and(self.v.get(), val, order) } } - /// Bitwise or with the current value, returning the previous + /// Bitwise or with the current uint, returning the previous value. /// /// # Examples /// @@ -563,7 +694,7 @@ impl AtomicUint { unsafe { atomic_or(self.v.get(), val, order) } } - /// Bitwise xor with the current value, returning the previous + /// Bitwise xor with the current uint, returning the previous value. /// /// # Examples /// @@ -581,18 +712,40 @@ impl AtomicUint { } impl<T> AtomicPtr<T> { - /// Create a new `AtomicPtr` + /// Creates a new `AtomicPtr`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::AtomicPtr; + /// + /// let ptr = &mut 5i; + /// let atomic_ptr = AtomicPtr::new(ptr); + /// ``` #[inline] #[stable] pub fn new(p: *mut T) -> AtomicPtr<T> { AtomicPtr { p: UnsafeCell::new(p as uint), nocopy: marker::NoCopy } } - /// Load the value + /// Loads a value from the pointer. + /// + /// `load` takes an `Ordering` argument which describes the memory ordering of this operation. /// /// # Panics /// /// Panics if `order` is `Release` or `AcqRel`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5i; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let value = some_ptr.load(Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn load(&self, order: Ordering) -> *mut T { @@ -601,7 +754,22 @@ impl<T> AtomicPtr<T> { } } - /// Store the value + /// Stores a value into the pointer. + /// + /// `store` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5i; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10i; + /// + /// some_ptr.store(other_ptr, Ordering::Relaxed); + /// ``` /// /// # Panics /// @@ -612,18 +780,48 @@ impl<T> AtomicPtr<T> { unsafe { atomic_store(self.p.get(), ptr as uint, order); } } - /// Store a value, returning the old value + /// Stores a value into the pointer, returning the old value. + /// + /// `swap` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5i; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10i; + /// + /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { unsafe { atomic_swap(self.p.get(), ptr as uint, order) as *mut T } } - /// If the current value is the same as expected, store a new value + /// Stores a value into the pointer if the current value is the same as the expected value. /// - /// Compare the current value with `old`; if they are the same then - /// replace the current value with `new`. Return the previous value. /// If the return value is equal to `old` then the value was updated. + /// + /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of + /// this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5i; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10i; + /// let another_ptr = &mut 10i; + /// + /// let value = some_ptr.compare_and_swap(other_ptr, another_ptr, Ordering::Relaxed); + /// ``` #[inline] #[stable] pub fn compare_and_swap(&self, old: *mut T, new: *mut T, order: Ordering) -> *mut T { @@ -777,7 +975,7 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T { /// /// # Panics /// -/// Panics if `order` is `Relaxed` +/// Panics if `order` is `Relaxed`. #[inline] #[stable] pub fn fence(order: Ordering) { diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 1efb5956101..be8828b3ec8 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -12,8 +12,6 @@ #![allow(unused_variables)] -pub use self::FormatError::*; - use any; use cell::{Cell, Ref, RefMut}; use iter::{Iterator, range}; @@ -23,10 +21,9 @@ use option::{Option, Some, None}; use ops::Deref; use result::{Ok, Err}; use result; -use slice::{AsSlice, SlicePrelude}; +use slice::SlicePrelude; use slice; use str::StrPrelude; -use str; pub use self::num::radix; pub use self::num::Radix; @@ -36,18 +33,16 @@ mod num; mod float; pub mod rt; -pub type Result = result::Result<(), FormatError>; +#[experimental = "core and I/O reconciliation may alter this definition"] +pub type Result = result::Result<(), Error>; /// The error type which is returned from formatting a message into a stream. /// /// This type does not support transmission of an error other than that an error /// occurred. Any extra information must be arranged to be transmitted through /// some other means. -pub enum FormatError { - /// A generic write error occurred during formatting, no other information - /// is transmitted via this variant. - WriteError, -} +#[experimental = "core and I/O reconciliation may alter this definition"] +pub struct Error; /// A collection of methods that are required to format a message into a stream. /// @@ -58,6 +53,7 @@ pub enum FormatError { /// This trait should generally not be implemented by consumers of the standard /// library. The `write!` macro accepts an instance of `io::Writer`, and the /// `io::Writer` trait is favored over implementing this trait. +#[experimental = "waiting for core and I/O reconciliation"] pub trait FormatWriter { /// Writes a slice of bytes into this writer, returning whether the write /// succeeded. @@ -81,17 +77,13 @@ pub trait FormatWriter { /// A struct to represent both where to emit formatting strings to and how they /// should be formatted. A mutable version of this is passed to all formatting /// traits. +#[unstable = "name may change and implemented traits are also unstable"] pub struct Formatter<'a> { - /// Flags for formatting (packed version of rt::Flag) - pub flags: uint, - /// Character used as 'fill' whenever there is alignment - pub fill: char, - /// Boolean indication of whether the output should be left-aligned - pub align: rt::Alignment, - /// Optionally specified integer width that the output should be - pub width: Option<uint>, - /// Optionally specified precision for numeric types - pub precision: Option<uint>, + flags: uint, + fill: char, + align: rt::Alignment, + width: Option<uint>, + precision: Option<uint>, buf: &'a mut FormatWriter+'a, curarg: slice::Items<'a, Argument<'a>>, @@ -104,6 +96,7 @@ enum Void {} /// family of functions. It contains a function to format the given value. At /// compile time it is ensured that the function and the value have the correct /// types, and then this struct is used to canonicalize arguments to one type. +#[experimental = "implementation detail of the `format_args!` macro"] pub struct Argument<'a> { formatter: extern "Rust" fn(&Void, &mut Formatter) -> Result, value: &'a Void, @@ -115,6 +108,7 @@ impl<'a> Arguments<'a> { /// which is valid because the compiler performs all necessary validation to /// ensure that the resulting call to format/write would be safe. #[doc(hidden)] #[inline] + #[experimental = "implementation detail of the `format_args!` macro"] pub unsafe fn new<'a>(pieces: &'static [&'static str], args: &'a [Argument<'a>]) -> Arguments<'a> { Arguments { @@ -128,6 +122,7 @@ impl<'a> Arguments<'a> { /// The `pieces` array must be at least as long as `fmt` to construct /// a valid Arguments structure. #[doc(hidden)] #[inline] + #[experimental = "implementation detail of the `format_args!` macro"] pub unsafe fn with_placeholders<'a>(pieces: &'static [&'static str], fmt: &'static [rt::Argument<'static>], args: &'a [Argument<'a>]) -> Arguments<'a> { @@ -148,6 +143,7 @@ impl<'a> Arguments<'a> { /// and pass it to a function or closure, passed as the first argument. The /// macro validates the format string at compile-time so usage of the `write` /// and `format` functions can be safely performed. +#[stable] pub struct Arguments<'a> { // Format string pieces to print. pieces: &'a [&'a str], @@ -169,84 +165,57 @@ impl<'a> Show for Arguments<'a> { /// When a format is not otherwise specified, types are formatted by ascribing /// to this trait. There is not an explicit way of selecting this trait to be /// used for formatting, it is only if no other format is specified. +#[unstable = "I/O and core have yet to be reconciled"] pub trait Show for Sized? { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } -/// Format trait for the `b` character -pub trait Bool for Sized? { - /// Formats the value using the given formatter. - fn fmt(&self, &mut Formatter) -> Result; -} - -/// Format trait for the `c` character -pub trait Char for Sized? { - /// Formats the value using the given formatter. - fn fmt(&self, &mut Formatter) -> Result; -} - -/// Format trait for the `i` and `d` characters -pub trait Signed for Sized? { - /// Formats the value using the given formatter. - fn fmt(&self, &mut Formatter) -> Result; -} - -/// Format trait for the `u` character -pub trait Unsigned for Sized? { - /// Formats the value using the given formatter. - fn fmt(&self, &mut Formatter) -> Result; -} /// Format trait for the `o` character +#[unstable = "I/O and core have yet to be reconciled"] pub trait Octal for Sized? { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `t` character +#[unstable = "I/O and core have yet to be reconciled"] pub trait Binary for Sized? { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `x` character +#[unstable = "I/O and core have yet to be reconciled"] pub trait LowerHex for Sized? { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `X` character +#[unstable = "I/O and core have yet to be reconciled"] pub trait UpperHex for Sized? { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } -/// Format trait for the `s` character -pub trait String for Sized? { - /// Formats the value using the given formatter. - fn fmt(&self, &mut Formatter) -> Result; -} - /// Format trait for the `p` character +#[unstable = "I/O and core have yet to be reconciled"] pub trait Pointer for Sized? { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } -/// Format trait for the `f` character -pub trait Float for Sized? { - /// Formats the value using the given formatter. - fn fmt(&self, &mut Formatter) -> Result; -} - /// Format trait for the `e` character +#[unstable = "I/O and core have yet to be reconciled"] pub trait LowerExp for Sized? { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `E` character +#[unstable = "I/O and core have yet to be reconciled"] pub trait UpperExp for Sized? { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; @@ -271,6 +240,8 @@ static DEFAULT_ARGUMENT: rt::Argument<'static> = rt::Argument { /// /// * output - the buffer to write output to /// * args - the precompiled arguments generated by `format_args!` +#[experimental = "libcore and I/O have yet to be reconciled, and this is an \ + implementation detail which should not otherwise be exported"] pub fn write(output: &mut FormatWriter, args: &Arguments) -> Result { let mut formatter = Formatter { flags: 0, @@ -368,6 +339,7 @@ impl<'a> Formatter<'a> { /// /// This function will correctly account for the flags provided as well as /// the minimum width. It will not take precision into account. + #[unstable = "definition may change slightly over time"] pub fn pad_integral(&mut self, is_positive: bool, prefix: &str, @@ -440,6 +412,7 @@ impl<'a> Formatter<'a> { /// is longer than this length /// /// Notably this function ignored the `flag` parameters + #[unstable = "definition may change slightly over time"] pub fn pad(&mut self, s: &str) -> Result { // Make sure there's a fast path up front if self.width.is_none() && self.precision.is_none() { @@ -516,19 +489,48 @@ impl<'a> Formatter<'a> { /// Writes some data to the underlying buffer contained within this /// formatter. + #[unstable = "reconciling core and I/O may alter this definition"] pub fn write(&mut self, data: &[u8]) -> Result { self.buf.write(data) } /// Writes some formatted information into this instance + #[unstable = "reconciling core and I/O may alter this definition"] pub fn write_fmt(&mut self, fmt: &Arguments) -> Result { write(self.buf, fmt) } + + /// Flags for formatting (packed version of rt::Flag) + #[experimental = "return type may change and method was just created"] + pub fn flags(&self) -> uint { self.flags } + + /// Character used as 'fill' whenever there is alignment + #[unstable = "method was just created"] + pub fn fill(&self) -> char { self.fill } + + /// Flag indicating what form of alignment was requested + #[unstable = "method was just created"] + pub fn align(&self) -> rt::Alignment { self.align } + + /// Optionally specified integer width that the output should be + #[unstable = "method was just created"] + pub fn width(&self) -> Option<uint> { self.width } + + /// Optionally specified precision for numeric types + #[unstable = "method was just created"] + pub fn precision(&self) -> Option<uint> { self.precision } +} + +impl Show for Error { + fn fmt(&self, f: &mut Formatter) -> Result { + "an error occurred when formatting an argument".fmt(f) + } } /// This is a function which calls are emitted to by the compiler itself to /// create the Argument structures that are passed into the `format` function. #[doc(hidden)] #[inline] +#[experimental = "implementation detail of the `format_args!` macro"] pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result, t: &'a T) -> Argument<'a> { unsafe { @@ -542,15 +544,17 @@ pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result, /// When the compiler determines that the type of an argument *must* be a string /// (such as for select), then it invokes this method. #[doc(hidden)] #[inline] +#[experimental = "implementation detail of the `format_args!` macro"] pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> { - argument(String::fmt, s) + argument(Show::fmt, s) } /// When the compiler determines that the type of an argument *must* be a uint /// (such as for plural), then it invokes this method. #[doc(hidden)] #[inline] +#[experimental = "implementation detail of the `format_args!` macro"] pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> { - argument(Unsigned::fmt, s) + argument(Show::fmt, s) } // Implementations of the core formatting traits @@ -565,32 +569,26 @@ impl<'a> Show for &'a Show+'a { fn fmt(&self, f: &mut Formatter) -> Result { (*self).fmt(f) } } -impl Bool for bool { - fn fmt(&self, f: &mut Formatter) -> Result { - String::fmt(if *self { "true" } else { "false" }, f) - } -} - -impl<T: str::Str> String for T { +impl Show for bool { fn fmt(&self, f: &mut Formatter) -> Result { - f.pad(self.as_slice()) + Show::fmt(if *self { "true" } else { "false" }, f) } } -impl String for str { +impl Show for str { fn fmt(&self, f: &mut Formatter) -> Result { f.pad(self) } } -impl Char for char { +impl Show for char { fn fmt(&self, f: &mut Formatter) -> Result { use char::Char; let mut utf8 = [0u8, ..4]; let amt = self.encode_utf8(&mut utf8).unwrap_or(0); let s: &str = unsafe { mem::transmute(utf8[..amt]) }; - String::fmt(s, f) + Show::fmt(s, f) } } @@ -620,7 +618,7 @@ impl<'a, T> Pointer for &'a mut T { } macro_rules! floating(($ty:ident) => { - impl Float for $ty { + impl Show for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { use num::Float; @@ -688,19 +686,6 @@ floating!(f64) // Implementation of Show for various core types -macro_rules! delegate(($ty:ty to $other:ident) => { - impl Show for $ty { - fn fmt(&self, f: &mut Formatter) -> Result { - $other::fmt(self, f) - } - } -}) -delegate!(str to String) -delegate!(bool to Bool) -delegate!(char to Char) -delegate!(f32 to Float) -delegate!(f64 to Float) - impl<T> Show for *const T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 0a5af56217c..1c856a6e208 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -109,6 +109,7 @@ radix!(UpperHex, 16, "0x", x @ 0 ... 9 => b'0' + x, /// A radix with in the range of `2..36`. #[deriving(Clone, PartialEq)] +#[unstable = "may be renamed or move to a different module"] pub struct Radix { base: u8, } @@ -132,6 +133,7 @@ impl GenericRadix for Radix { } /// A helper type for formatting radixes. +#[unstable = "may be renamed or move to a different module"] pub struct RadixFmt<T, R>(T, R); /// Constructs a radix formatter in the range of `2..36`. @@ -142,6 +144,7 @@ pub struct RadixFmt<T, R>(T, R); /// use std::fmt::radix; /// assert_eq!(format!("{}", radix(55i, 36)), "1j".to_string()); /// ``` +#[unstable = "may be renamed or move to a different module"] pub fn radix<T>(x: T, base: u8) -> RadixFmt<T, Radix> { RadixFmt(x, Radix::new(base)) } @@ -167,7 +170,6 @@ macro_rules! int_base { macro_rules! integer { ($Int:ident, $Uint:ident) => { int_base!(Show for $Int as $Int -> Decimal) - int_base!(Signed for $Int as $Int -> Decimal) int_base!(Binary for $Int as $Uint -> Binary) int_base!(Octal for $Int as $Uint -> Octal) int_base!(LowerHex for $Int as $Uint -> LowerHex) @@ -175,7 +177,6 @@ macro_rules! integer { radix_fmt!($Int as $Int, fmt_int) int_base!(Show for $Uint as $Uint -> Decimal) - int_base!(Unsigned for $Uint as $Uint -> Decimal) int_base!(Binary for $Uint as $Uint -> Binary) int_base!(Octal for $Uint as $Uint -> Octal) int_base!(LowerHex for $Uint as $Uint -> LowerHex) diff --git a/src/libcore/fmt/rt.rs b/src/libcore/fmt/rt.rs index 0e8504e7ee5..145e78dc668 100644 --- a/src/libcore/fmt/rt.rs +++ b/src/libcore/fmt/rt.rs @@ -14,6 +14,8 @@ //! These definitions are similar to their `ct` equivalents, but differ in that //! these can be statically allocated and are slightly optimized for the runtime +#![experimental = "implementation detail of the `format_args!` macro"] + pub use self::Alignment::*; pub use self::Count::*; pub use self::Position::*; diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 9ba67bb2e47..9016f40b1b8 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -108,7 +108,10 @@ macro_rules! try( /// Writing a formatted string into a writer #[macro_export] macro_rules! write( - ($dst:expr, $($arg:tt)*) => (format_args_method!($dst, write_fmt, $($arg)*)) + ($dst:expr, $($arg:tt)*) => ({ + let dst = &mut *$dst; + format_args!(|args| { dst.write_fmt(args) }, $($arg)*) + }) ) /// Writing a formatted string plus a newline into a writer @@ -119,15 +122,5 @@ macro_rules! writeln( ) ) -/// Write some formatted data into a stream. -/// -/// Identical to the macro in `std::macros` -#[macro_export] -macro_rules! write( - ($dst:expr, $($arg:tt)*) => ({ - format_args_method!($dst, write_fmt, $($arg)*) - }) -) - #[macro_export] macro_rules! unreachable( () => (panic!("unreachable code")) ) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 0dc4fb83965..16798c039ba 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -227,52 +227,6 @@ //! ``` //! //! `try!` is imported by the prelude, and is available everywhere. -//! -//! # `Result` and `Option` -//! -//! The `Result` and [`Option`](../option/index.html) types are -//! similar and complementary: they are often employed to indicate a -//! lack of a return value; and they are trivially converted between -//! each other, so `Result`s are often handled by first converting to -//! `Option` with the [`ok`](type.Result.html#method.ok) and -//! [`err`](type.Result.html#method.ok) methods. -//! -//! Whereas `Option` only indicates the lack of a value, `Result` is -//! specifically for error reporting, and carries with it an error -//! value. Sometimes `Option` is used for indicating errors, but this -//! is only for simple cases and is generally discouraged. Even when -//! there is no useful error value to return, prefer `Result<T, ()>`. -//! -//! Converting to an `Option` with `ok()` to handle an error: -//! -//! ``` -//! use std::io::Timer; -//! let mut t = Timer::new().ok().expect("failed to create timer!"); -//! ``` -//! -//! # `Result` vs. `panic!` -//! -//! `Result` is for recoverable errors; `panic!` is for unrecoverable -//! errors. Callers should always be able to avoid panics if they -//! take the proper precautions, for example, calling `is_some()` -//! on an `Option` type before calling `unwrap`. -//! -//! The suitability of `panic!` as an error handling mechanism is -//! limited by Rust's lack of any way to "catch" and resume execution -//! from a thrown exception. Therefore using panics for error -//! handling requires encapsulating code that may panic in a task. -//! Calling the `panic!` macro, or invoking `panic!` indirectly should be -//! avoided as an error reporting strategy. Panics is only for -//! unrecoverable errors and a panicking task is typically the sign of -//! a bug. -//! -//! A module that instead returns `Results` is alerting the caller -//! that failure is possible, and providing precise control over how -//! it is handled. -//! -//! Furthermore, panics may not be recoverable at all, depending on -//! the context. The caller of `panic!` should assume that execution -//! will not resume after the panic, that a panic is catastrophic. #![stable] |
