auto merge of #9115 : erickt/rust/master, r=erickt
This is a series of patches to modernize option and result. The highlights are: * rename `.unwrap_or_default(value)` and etc to `.unwrap_or(value)` * add `.unwrap_or_default()` that uses the `Default` trait * add `Default` implementations for vecs, HashMap, Option * add `Option.and(T) -> Option<T>`, `Option.and_then(&fn() -> Option<T>) -> Option<T>`, `Option.or(T) -> Option<T>`, and `Option.or_else(&fn() -> Option<T>) -> Option<T>` * add `option::ToOption`, `option::IntoOption`, `option::AsOption`, `result::ToResult`, `result::IntoResult`, `result::AsResult`, `either::ToEither`, and `either::IntoEither`, `either::AsEither` * renamed `Option::chain*` and `Result::chain*` to `and_then` and `or_else` to avoid the eventual collision with `Iterator.chain`. * Added a bunch of impls of `Default` * Added a `#[deriving(Default)]` syntax extension * Removed impls of `Zero` for `Option<T>` and vecs.
This commit is contained in:
commit
2aa578efd9
@ -1717,7 +1717,8 @@ Supported traits for `deriving` are:
|
||||
* `Clone` and `DeepClone`, to perform (deep) copies.
|
||||
* `IterBytes`, to iterate over the bytes in a data type.
|
||||
* `Rand`, to create a random instance of a data type.
|
||||
* `Zero`, to create an zero (or empty) instance of a data type.
|
||||
* `Default`, to create an empty instance of a data type.
|
||||
* `Zero`, to create an zero instance of a numeric data type.
|
||||
* `ToStr`, to convert to a string. For a type with this instance,
|
||||
`obj.to_str()` has similar output as `fmt!("%?", obj)`, but it differs in that
|
||||
each constituent field of the type must also implement `ToStr` and will have
|
||||
|
@ -2249,7 +2249,7 @@ enum ABC { A, B, C }
|
||||
|
||||
The full list of derivable traits is `Eq`, `TotalEq`, `Ord`,
|
||||
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`,
|
||||
`IterBytes`, `Rand`, `Zero`, and `ToStr`.
|
||||
`IterBytes`, `Rand`, `Default`, `Zero`, and `ToStr`.
|
||||
|
||||
# Crates and the module system
|
||||
|
||||
|
@ -309,7 +309,7 @@ pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName {
|
||||
let filename = path.filename();
|
||||
let p = path.pop();
|
||||
let dir = p.filename();
|
||||
fmt!("%s/%s", dir.unwrap_or_default(""), filename.unwrap_or_default(""))
|
||||
fmt!("%s/%s", dir.unwrap_or(""), filename.unwrap_or(""))
|
||||
}
|
||||
|
||||
test::DynTestName(fmt!("[%s] %s",
|
||||
|
@ -137,7 +137,17 @@ fn list_dir_sorted(path: &Path) -> ~[Path] {
|
||||
/**
|
||||
* A compiled Unix shell style pattern.
|
||||
*/
|
||||
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Zero)]
|
||||
#[cfg(stage0)]
|
||||
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)]
|
||||
pub struct Pattern {
|
||||
priv tokens: ~[PatternToken]
|
||||
}
|
||||
|
||||
/**
|
||||
* A compiled Unix shell style pattern.
|
||||
*/
|
||||
#[cfg(not(stage0))]
|
||||
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)]
|
||||
pub struct Pattern {
|
||||
priv tokens: ~[PatternToken]
|
||||
}
|
||||
@ -312,7 +322,7 @@ impl Pattern {
|
||||
let require_literal = |c| {
|
||||
(options.require_literal_separator && is_sep(c)) ||
|
||||
(options.require_literal_leading_dot && c == '.'
|
||||
&& is_sep(prev_char.unwrap_or_default('/')))
|
||||
&& is_sep(prev_char.unwrap_or('/')))
|
||||
};
|
||||
|
||||
for (ti, token) in self.tokens.slice_from(i).iter().enumerate() {
|
||||
@ -458,7 +468,37 @@ fn is_sep(c: char) -> bool {
|
||||
/**
|
||||
* Configuration options to modify the behaviour of `Pattern::matches_with(..)`
|
||||
*/
|
||||
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Zero)]
|
||||
#[cfg(stage0)]
|
||||
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes)]
|
||||
pub struct MatchOptions {
|
||||
|
||||
/**
|
||||
* Whether or not patterns should be matched in a case-sensitive manner. This
|
||||
* currently only considers upper/lower case relationships between ASCII characters,
|
||||
* but in future this might be extended to work with Unicode.
|
||||
*/
|
||||
case_sensitive: bool,
|
||||
|
||||
/**
|
||||
* If this is true then path-component separator characters (e.g. `/` on Posix)
|
||||
* must be matched by a literal `/`, rather than by `*` or `?` or `[...]`
|
||||
*/
|
||||
require_literal_separator: bool,
|
||||
|
||||
/**
|
||||
* If this is true then paths that contain components that start with a `.` will
|
||||
* not match unless the `.` appears literally in the pattern: `*`, `?` or `[...]`
|
||||
* will not match. This is useful because such files are conventionally considered
|
||||
* hidden on Unix systems and it might be desirable to skip them when listing files.
|
||||
*/
|
||||
require_literal_leading_dot: bool
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration options to modify the behaviour of `Pattern::matches_with(..)`
|
||||
*/
|
||||
#[cfg(not(stage0))]
|
||||
#[deriving(Clone, Eq, TotalEq, Ord, TotalOrd, IterBytes, Default)]
|
||||
pub struct MatchOptions {
|
||||
|
||||
/**
|
||||
|
@ -635,7 +635,7 @@ impl BigUint {
|
||||
|
||||
// Converts this BigUint into an int, unless it would overflow.
|
||||
pub fn to_int_opt(&self) -> Option<int> {
|
||||
self.to_uint_opt().chain(|n| {
|
||||
self.to_uint_opt().and_then(|n| {
|
||||
// If top bit of uint is set, it's too large to convert to
|
||||
// int.
|
||||
if (n >> (2*BigDigit::bits - 1) != 0) {
|
||||
@ -1221,7 +1221,7 @@ impl BigInt {
|
||||
match self.sign {
|
||||
Plus => self.data.to_int_opt(),
|
||||
Zero => Some(0),
|
||||
Minus => self.data.to_uint_opt().chain(|n| {
|
||||
Minus => self.data.to_uint_opt().and_then(|n| {
|
||||
let m: uint = 1 << (2*BigDigit::bits-1);
|
||||
if (n > m) {
|
||||
None
|
||||
|
@ -273,9 +273,9 @@ impl<T: FromStr + Clone + Integer + Ord>
|
||||
return None
|
||||
}
|
||||
let a_option: Option<T> = FromStr::from_str(split[0]);
|
||||
do a_option.chain |a| {
|
||||
do a_option.and_then |a| {
|
||||
let b_option: Option<T> = FromStr::from_str(split[1]);
|
||||
do b_option.chain |b| {
|
||||
do b_option.and_then |b| {
|
||||
Some(Ratio::new(a.clone(), b.clone()))
|
||||
}
|
||||
}
|
||||
@ -291,10 +291,10 @@ impl<T: FromStrRadix + Clone + Integer + Ord>
|
||||
} else {
|
||||
let a_option: Option<T> = FromStrRadix::from_str_radix(split[0],
|
||||
radix);
|
||||
do a_option.chain |a| {
|
||||
do a_option.and_then |a| {
|
||||
let b_option: Option<T> =
|
||||
FromStrRadix::from_str_radix(split[1], radix);
|
||||
do b_option.chain |b| {
|
||||
do b_option.and_then |b| {
|
||||
Some(Ratio::new(a.clone(), b.clone()))
|
||||
}
|
||||
}
|
||||
|
@ -442,21 +442,21 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||
},
|
||||
'c' => {
|
||||
parse_type(s, pos, 'a', &mut *tm)
|
||||
.chain(|pos| parse_char(s, pos, ' '))
|
||||
.chain(|pos| parse_type(s, pos, 'b', &mut *tm))
|
||||
.chain(|pos| parse_char(s, pos, ' '))
|
||||
.chain(|pos| parse_type(s, pos, 'e', &mut *tm))
|
||||
.chain(|pos| parse_char(s, pos, ' '))
|
||||
.chain(|pos| parse_type(s, pos, 'T', &mut *tm))
|
||||
.chain(|pos| parse_char(s, pos, ' '))
|
||||
.chain(|pos| parse_type(s, pos, 'Y', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ' '))
|
||||
.and_then(|pos| parse_type(s, pos, 'b', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ' '))
|
||||
.and_then(|pos| parse_type(s, pos, 'e', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ' '))
|
||||
.and_then(|pos| parse_type(s, pos, 'T', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ' '))
|
||||
.and_then(|pos| parse_type(s, pos, 'Y', &mut *tm))
|
||||
}
|
||||
'D' | 'x' => {
|
||||
parse_type(s, pos, 'm', &mut *tm)
|
||||
.chain(|pos| parse_char(s, pos, '/'))
|
||||
.chain(|pos| parse_type(s, pos, 'd', &mut *tm))
|
||||
.chain(|pos| parse_char(s, pos, '/'))
|
||||
.chain(|pos| parse_type(s, pos, 'y', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, '/'))
|
||||
.and_then(|pos| parse_type(s, pos, 'd', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, '/'))
|
||||
.and_then(|pos| parse_type(s, pos, 'y', &mut *tm))
|
||||
}
|
||||
'd' => match match_digits_in_range(s, pos, 2u, false, 1_i32,
|
||||
31_i32) {
|
||||
@ -475,10 +475,10 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||
}
|
||||
'F' => {
|
||||
parse_type(s, pos, 'Y', &mut *tm)
|
||||
.chain(|pos| parse_char(s, pos, '-'))
|
||||
.chain(|pos| parse_type(s, pos, 'm', &mut *tm))
|
||||
.chain(|pos| parse_char(s, pos, '-'))
|
||||
.chain(|pos| parse_type(s, pos, 'd', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, '-'))
|
||||
.and_then(|pos| parse_type(s, pos, 'm', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, '-'))
|
||||
.and_then(|pos| parse_type(s, pos, 'd', &mut *tm))
|
||||
}
|
||||
'H' => {
|
||||
match match_digits_in_range(s, pos, 2u, false, 0_i32, 23_i32) {
|
||||
@ -553,17 +553,17 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||
},
|
||||
'R' => {
|
||||
parse_type(s, pos, 'H', &mut *tm)
|
||||
.chain(|pos| parse_char(s, pos, ':'))
|
||||
.chain(|pos| parse_type(s, pos, 'M', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ':'))
|
||||
.and_then(|pos| parse_type(s, pos, 'M', &mut *tm))
|
||||
}
|
||||
'r' => {
|
||||
parse_type(s, pos, 'I', &mut *tm)
|
||||
.chain(|pos| parse_char(s, pos, ':'))
|
||||
.chain(|pos| parse_type(s, pos, 'M', &mut *tm))
|
||||
.chain(|pos| parse_char(s, pos, ':'))
|
||||
.chain(|pos| parse_type(s, pos, 'S', &mut *tm))
|
||||
.chain(|pos| parse_char(s, pos, ' '))
|
||||
.chain(|pos| parse_type(s, pos, 'p', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ':'))
|
||||
.and_then(|pos| parse_type(s, pos, 'M', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ':'))
|
||||
.and_then(|pos| parse_type(s, pos, 'S', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ' '))
|
||||
.and_then(|pos| parse_type(s, pos, 'p', &mut *tm))
|
||||
}
|
||||
'S' => {
|
||||
match match_digits_in_range(s, pos, 2u, false, 0_i32, 60_i32) {
|
||||
@ -578,10 +578,10 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||
//'s' {}
|
||||
'T' | 'X' => {
|
||||
parse_type(s, pos, 'H', &mut *tm)
|
||||
.chain(|pos| parse_char(s, pos, ':'))
|
||||
.chain(|pos| parse_type(s, pos, 'M', &mut *tm))
|
||||
.chain(|pos| parse_char(s, pos, ':'))
|
||||
.chain(|pos| parse_type(s, pos, 'S', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ':'))
|
||||
.and_then(|pos| parse_type(s, pos, 'M', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, ':'))
|
||||
.and_then(|pos| parse_type(s, pos, 'S', &mut *tm))
|
||||
}
|
||||
't' => parse_char(s, pos, '\t'),
|
||||
'u' => {
|
||||
@ -596,10 +596,10 @@ fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||
}
|
||||
'v' => {
|
||||
parse_type(s, pos, 'e', &mut *tm)
|
||||
.chain(|pos| parse_char(s, pos, '-'))
|
||||
.chain(|pos| parse_type(s, pos, 'b', &mut *tm))
|
||||
.chain(|pos| parse_char(s, pos, '-'))
|
||||
.chain(|pos| parse_type(s, pos, 'Y', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, '-'))
|
||||
.and_then(|pos| parse_type(s, pos, 'b', &mut *tm))
|
||||
.and_then(|pos| parse_char(s, pos, '-'))
|
||||
.and_then(|pos| parse_type(s, pos, 'Y', &mut *tm))
|
||||
}
|
||||
//'W' {}
|
||||
'w' => {
|
||||
|
@ -417,6 +417,13 @@ impl Uuid {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Uuid {
|
||||
/// Returns the nil UUID, which is all zeroes
|
||||
fn default() -> Uuid {
|
||||
Uuid::new_nil()
|
||||
}
|
||||
}
|
||||
|
||||
impl Zero for Uuid {
|
||||
/// Returns the nil UUID, which is all zeroes
|
||||
fn zero() -> Uuid {
|
||||
|
@ -681,9 +681,9 @@ pub fn build_session_options(binary: @str,
|
||||
link::output_type_bitcode
|
||||
} else { link::output_type_exe };
|
||||
let sysroot_opt = getopts::opt_maybe_str(matches, "sysroot").map_move(|m| @Path(m));
|
||||
let target = getopts::opt_maybe_str(matches, "target").unwrap_or_default(host_triple());
|
||||
let target_cpu = getopts::opt_maybe_str(matches, "target-cpu").unwrap_or_default(~"generic");
|
||||
let target_feature = getopts::opt_maybe_str(matches, "target-feature").unwrap_or_default(~"");
|
||||
let target = getopts::opt_maybe_str(matches, "target").unwrap_or(host_triple());
|
||||
let target_cpu = getopts::opt_maybe_str(matches, "target-cpu").unwrap_or(~"generic");
|
||||
let target_feature = getopts::opt_maybe_str(matches, "target-feature").unwrap_or(~"");
|
||||
let save_temps = getopts::opt_present(matches, "save-temps");
|
||||
let opt_level = {
|
||||
if (debugging_opts & session::no_opt) != 0 {
|
||||
@ -961,7 +961,7 @@ pub fn build_output_filenames(input: &input,
|
||||
if !linkage_metas.is_empty() {
|
||||
// But if a linkage meta is present, that overrides
|
||||
let maybe_name = linkage_metas.iter().find(|m| "name" == m.name());
|
||||
match maybe_name.chain(|m| m.value_str()) {
|
||||
match maybe_name.and_then(|m| m.value_str()) {
|
||||
Some(s) => stem = s,
|
||||
_ => ()
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ fn filter_view_item<'r>(cx: @Context, view_item: &'r ast::view_item)-> Option<&'
|
||||
|
||||
fn fold_mod(cx: @Context, m: &ast::_mod, fld: @fold::ast_fold) -> ast::_mod {
|
||||
let filtered_items = do m.items.iter().filter_map |a| {
|
||||
filter_item(cx, *a).chain(|x| fld.fold_item(x))
|
||||
filter_item(cx, *a).and_then(|x| fld.fold_item(x))
|
||||
}.collect();
|
||||
let filtered_view_items = do m.view_items.iter().filter_map |a| {
|
||||
do filter_view_item(cx, a).map_move |x| {
|
||||
@ -139,7 +139,7 @@ fn fold_block(
|
||||
fld: @fold::ast_fold
|
||||
) -> ast::Block {
|
||||
let resulting_stmts = do b.stmts.iter().filter_map |a| {
|
||||
filter_stmt(cx, *a).chain(|stmt| fld.fold_stmt(stmt))
|
||||
filter_stmt(cx, *a).and_then(|stmt| fld.fold_stmt(stmt))
|
||||
}.collect();
|
||||
let filtered_view_items = do b.view_items.iter().filter_map |a| {
|
||||
filter_view_item(cx, a).map(|x| fld.fold_view_item(*x))
|
||||
|
@ -184,7 +184,7 @@ fn visit_item(e: &Env, i: @ast::item) {
|
||||
ast::named => {
|
||||
let link_name = i.attrs.iter()
|
||||
.find(|at| "link_name" == at.name())
|
||||
.chain(|at| at.value_str());
|
||||
.and_then(|at| at.value_str());
|
||||
|
||||
let foreign_name = match link_name {
|
||||
Some(nn) => {
|
||||
|
@ -210,7 +210,7 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
|
||||
}
|
||||
|
||||
fn variant_disr_val(d: ebml::Doc) -> Option<ty::Disr> {
|
||||
do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
|
||||
do reader::maybe_get_doc(d, tag_disr_val).and_then |val_doc| {
|
||||
do reader::with_doc_data(val_doc) |data| { u64::parse_bytes(data, 10u) }
|
||||
}
|
||||
}
|
||||
|
@ -221,8 +221,7 @@ impl PrivacyVisitor {
|
||||
// If the method is a default method, we need to use the def_id of
|
||||
// the default implementation.
|
||||
// Having to do this this is really unfortunate.
|
||||
let method_id = ty::method(self.tcx, method_id).provided_source
|
||||
.unwrap_or_default(method_id);
|
||||
let method_id = ty::method(self.tcx, method_id).provided_source.unwrap_or(method_id);
|
||||
|
||||
if method_id.crate == LOCAL_CRATE {
|
||||
let is_private = self.method_is_private(span, method_id.node);
|
||||
|
@ -505,7 +505,7 @@ impl get_node_info for ast::Block {
|
||||
|
||||
impl get_node_info for Option<@ast::Expr> {
|
||||
fn info(&self) -> Option<NodeInfo> {
|
||||
self.chain_ref(|s| s.info())
|
||||
self.and_then_ref(|s| s.info())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,9 +50,9 @@ impl Value {
|
||||
/// must be the only user of this value, and there must not be any conditional
|
||||
/// branches between the store and the given block.
|
||||
pub fn get_dominating_store(self, bcx: @mut Block) -> Option<Value> {
|
||||
match self.get_single_user().chain(|user| user.as_store_inst()) {
|
||||
match self.get_single_user().and_then(|user| user.as_store_inst()) {
|
||||
Some(store) => {
|
||||
do store.get_parent().chain |store_bb| {
|
||||
do store.get_parent().and_then |store_bb| {
|
||||
let mut bb = BasicBlock(bcx.llbb);
|
||||
let mut ret = Some(store);
|
||||
while *bb != *store_bb {
|
||||
@ -150,7 +150,7 @@ impl Iterator<Value> for UserIterator {
|
||||
fn next(&mut self) -> Option<Value> {
|
||||
let current = self.next;
|
||||
|
||||
self.next = do current.chain |u| { u.get_next_use() };
|
||||
self.next = do current.and_then |u| { u.get_next_use() };
|
||||
|
||||
do current.map |u| { u.get_user() }
|
||||
}
|
||||
|
@ -745,7 +745,7 @@ pub fn ty_of_closure<AC:AstConv,RS:RegionScope + Clone + 'static>(
|
||||
RegionParamNames(bound_lifetime_names.clone()));
|
||||
|
||||
let input_tys = do decl.inputs.iter().enumerate().map |(i, a)| {
|
||||
let expected_arg_ty = do expected_sig.chain_ref |e| {
|
||||
let expected_arg_ty = do expected_sig.and_then_ref |e| {
|
||||
// no guarantee that the correct number of expected args
|
||||
// were supplied
|
||||
if i < e.inputs.len() {Some(e.inputs[i])} else {None}
|
||||
|
@ -173,7 +173,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::Pat, path: &ast::Path,
|
||||
fcx.write_error(pat.id);
|
||||
kind_name = "[error]";
|
||||
arg_types = (*subpats).clone()
|
||||
.unwrap_or_default(~[])
|
||||
.unwrap_or_default()
|
||||
.map(|_| ty::mk_err());
|
||||
}
|
||||
}
|
||||
@ -222,7 +222,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::Pat, path: &ast::Path,
|
||||
fcx.write_error(pat.id);
|
||||
kind_name = "[error]";
|
||||
arg_types = (*subpats).clone()
|
||||
.unwrap_or_default(~[])
|
||||
.unwrap_or_default()
|
||||
.map(|_| ty::mk_err());
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
// the trait `Combine` and contains methods for combining two
|
||||
// instances of various things and yielding a new instance. These
|
||||
// combiner methods always yield a `result<T>`---failure is propagated
|
||||
// upward using `chain()` methods. There is a lot of common code for
|
||||
// upward using `and_then()` methods. There is a lot of common code for
|
||||
// these operations, implemented as default methods on the `Combine`
|
||||
// trait.
|
||||
//
|
||||
@ -108,7 +108,7 @@ pub trait Combine {
|
||||
(Some(a), Some(b)) => {
|
||||
// FIXME(#5781) this should be eq_tys
|
||||
// eq_tys(self, a, b).then(|| Ok(Some(a)) )
|
||||
self.contratys(a, b).chain(|t| Ok(Some(t)))
|
||||
self.contratys(a, b).and_then(|t| Ok(Some(t)))
|
||||
}
|
||||
(None, Some(_)) |
|
||||
(Some(_), None) => {
|
||||
@ -162,13 +162,13 @@ pub trait Combine {
|
||||
}
|
||||
|
||||
ty::rv_covariant => {
|
||||
do this.regions(a_r, b_r).chain |r| {
|
||||
do this.regions(a_r, b_r).and_then |r| {
|
||||
Ok(ty::NonerasedRegions(opt_vec::with(r)))
|
||||
}
|
||||
}
|
||||
|
||||
ty::rv_contravariant => {
|
||||
do this.contraregions(a_r, b_r).chain |r| {
|
||||
do this.contraregions(a_r, b_r).and_then |r| {
|
||||
Ok(ty::NonerasedRegions(opt_vec::with(r)))
|
||||
}
|
||||
}
|
||||
@ -179,12 +179,12 @@ pub trait Combine {
|
||||
}
|
||||
}
|
||||
|
||||
do self.tps(as_.tps, bs.tps).chain |tps| {
|
||||
do self.self_tys(as_.self_ty, bs.self_ty).chain |self_ty| {
|
||||
do self.tps(as_.tps, bs.tps).and_then |tps| {
|
||||
do self.self_tys(as_.self_ty, bs.self_ty).and_then |self_ty| {
|
||||
do relate_region_params(self,
|
||||
generics,
|
||||
&as_.regions,
|
||||
&bs.regions).chain |regions| {
|
||||
&bs.regions).and_then |regions| {
|
||||
Ok(substs {
|
||||
regions: regions,
|
||||
self_ty: self_ty,
|
||||
@ -227,8 +227,8 @@ pub trait Combine {
|
||||
fn flds(&self, a: ty::field, b: ty::field) -> cres<ty::field> {
|
||||
if a.ident == b.ident {
|
||||
self.mts(&a.mt, &b.mt)
|
||||
.chain(|mt| Ok(ty::field {ident: a.ident, mt: mt}) )
|
||||
.chain_err(|e| Err(ty::terr_in_field(@e, a.ident)) )
|
||||
.and_then(|mt| Ok(ty::field {ident: a.ident, mt: mt}) )
|
||||
.or_else(|e| Err(ty::terr_in_field(@e, a.ident)) )
|
||||
} else {
|
||||
Err(ty::terr_record_fields(
|
||||
expected_found(self,
|
||||
@ -238,7 +238,7 @@ pub trait Combine {
|
||||
}
|
||||
|
||||
fn args(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
|
||||
do self.contratys(a, b).chain |t| {
|
||||
do self.contratys(a, b).and_then |t| {
|
||||
Ok(t)
|
||||
}
|
||||
}
|
||||
@ -274,7 +274,7 @@ pub trait Combine {
|
||||
|
||||
match (a, b) {
|
||||
(ty::vstore_slice(a_r), ty::vstore_slice(b_r)) => {
|
||||
do self.contraregions(a_r, b_r).chain |r| {
|
||||
do self.contraregions(a_r, b_r).and_then |r| {
|
||||
Ok(ty::vstore_slice(r))
|
||||
}
|
||||
}
|
||||
@ -299,7 +299,7 @@ pub trait Combine {
|
||||
|
||||
match (a, b) {
|
||||
(ty::RegionTraitStore(a_r), ty::RegionTraitStore(b_r)) => {
|
||||
do self.contraregions(a_r, b_r).chain |r| {
|
||||
do self.contraregions(a_r, b_r).and_then |r| {
|
||||
Ok(ty::RegionTraitStore(r))
|
||||
}
|
||||
}
|
||||
@ -357,7 +357,7 @@ pub fn expected_found<C:Combine,T>(
|
||||
pub fn eq_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> ures {
|
||||
let suber = this.sub();
|
||||
do this.infcx().try {
|
||||
do suber.tys(a, b).chain |_ok| {
|
||||
do suber.tys(a, b).and_then |_ok| {
|
||||
suber.contratys(a, b)
|
||||
}.to_ures()
|
||||
}
|
||||
@ -371,10 +371,10 @@ pub fn eq_regions<C:Combine>(this: &C, a: ty::Region, b: ty::Region)
|
||||
let sub = this.sub();
|
||||
do indent {
|
||||
this.infcx().try(|| {
|
||||
do sub.regions(a, b).chain |_r| {
|
||||
do sub.regions(a, b).and_then |_r| {
|
||||
sub.contraregions(a, b)
|
||||
}
|
||||
}).chain_err(|e| {
|
||||
}).or_else(|e| {
|
||||
// substitute a better error, but use the regions
|
||||
// found in the original error
|
||||
match e {
|
||||
@ -427,8 +427,8 @@ pub fn super_fn_sigs<C:Combine>(
|
||||
}
|
||||
|
||||
do argvecs(this, a.inputs, b.inputs)
|
||||
.chain |inputs| {
|
||||
do this.tys(a.output, b.output).chain |output| {
|
||||
.and_then |inputs| {
|
||||
do this.tys(a.output, b.output).and_then |output| {
|
||||
Ok(FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
|
||||
inputs: inputs.clone(),
|
||||
output: output})
|
||||
@ -508,7 +508,7 @@ pub fn super_tys<C:Combine>(
|
||||
&ty::ty_enum(b_id, ref b_substs))
|
||||
if a_id == b_id => {
|
||||
let type_def = ty::lookup_item_type(tcx, a_id);
|
||||
do this.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
|
||||
do this.substs(&type_def.generics, a_substs, b_substs).and_then |substs| {
|
||||
Ok(ty::mk_enum(tcx, a_id, substs))
|
||||
}
|
||||
}
|
||||
@ -517,9 +517,9 @@ pub fn super_tys<C:Combine>(
|
||||
&ty::ty_trait(b_id, ref b_substs, b_store, b_mutbl, b_bounds))
|
||||
if a_id == b_id && a_mutbl == b_mutbl => {
|
||||
let trait_def = ty::lookup_trait_def(tcx, a_id);
|
||||
do this.substs(&trait_def.generics, a_substs, b_substs).chain |substs| {
|
||||
do this.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
|
||||
do this.bounds(a_bounds, b_bounds).chain |bounds| {
|
||||
do this.substs(&trait_def.generics, a_substs, b_substs).and_then |substs| {
|
||||
do this.trait_stores(ty::terr_trait, a_store, b_store).and_then |s| {
|
||||
do this.bounds(a_bounds, b_bounds).and_then |bounds| {
|
||||
Ok(ty::mk_trait(tcx,
|
||||
a_id,
|
||||
substs.clone(),
|
||||
@ -534,25 +534,25 @@ pub fn super_tys<C:Combine>(
|
||||
(&ty::ty_struct(a_id, ref a_substs), &ty::ty_struct(b_id, ref b_substs))
|
||||
if a_id == b_id => {
|
||||
let type_def = ty::lookup_item_type(tcx, a_id);
|
||||
do this.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
|
||||
do this.substs(&type_def.generics, a_substs, b_substs).and_then |substs| {
|
||||
Ok(ty::mk_struct(tcx, a_id, substs))
|
||||
}
|
||||
}
|
||||
|
||||
(&ty::ty_box(ref a_mt), &ty::ty_box(ref b_mt)) => {
|
||||
do this.mts(a_mt, b_mt).chain |mt| {
|
||||
do this.mts(a_mt, b_mt).and_then |mt| {
|
||||
Ok(ty::mk_box(tcx, mt))
|
||||
}
|
||||
}
|
||||
|
||||
(&ty::ty_uniq(ref a_mt), &ty::ty_uniq(ref b_mt)) => {
|
||||
do this.mts(a_mt, b_mt).chain |mt| {
|
||||
do this.mts(a_mt, b_mt).and_then |mt| {
|
||||
Ok(ty::mk_uniq(tcx, mt))
|
||||
}
|
||||
}
|
||||
|
||||
(&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => {
|
||||
do this.mts(a_mt, b_mt).chain |mt| {
|
||||
do this.mts(a_mt, b_mt).and_then |mt| {
|
||||
Ok(ty::mk_ptr(tcx, mt))
|
||||
}
|
||||
}
|
||||
@ -564,15 +564,15 @@ pub fn super_tys<C:Combine>(
|
||||
}
|
||||
|
||||
(&ty::ty_evec(ref a_mt, vs_a), &ty::ty_evec(ref b_mt, vs_b)) => {
|
||||
do this.mts(a_mt, b_mt).chain |mt| {
|
||||
do this.vstores(ty::terr_vec, vs_a, vs_b).chain |vs| {
|
||||
do this.mts(a_mt, b_mt).and_then |mt| {
|
||||
do this.vstores(ty::terr_vec, vs_a, vs_b).and_then |vs| {
|
||||
Ok(ty::mk_evec(tcx, mt, vs))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(&ty::ty_estr(vs_a), &ty::ty_estr(vs_b)) => {
|
||||
do this.vstores(ty::terr_str, vs_a, vs_b).chain |vs| {
|
||||
do this.vstores(ty::terr_str, vs_a, vs_b).and_then |vs| {
|
||||
Ok(ty::mk_estr(tcx,vs))
|
||||
}
|
||||
}
|
||||
@ -581,7 +581,7 @@ pub fn super_tys<C:Combine>(
|
||||
if as_.len() == bs.len() {
|
||||
result::collect(as_.iter().zip(bs.iter())
|
||||
.map(|(a, b)| this.tys(*a, *b)))
|
||||
.chain(|ts| Ok(ty::mk_tup(tcx, ts)) )
|
||||
.and_then(|ts| Ok(ty::mk_tup(tcx, ts)) )
|
||||
} else {
|
||||
Err(ty::terr_tuple_size(
|
||||
expected_found(this, as_.len(), bs.len())))
|
||||
@ -589,13 +589,13 @@ pub fn super_tys<C:Combine>(
|
||||
}
|
||||
|
||||
(&ty::ty_bare_fn(ref a_fty), &ty::ty_bare_fn(ref b_fty)) => {
|
||||
do this.bare_fn_tys(a_fty, b_fty).chain |fty| {
|
||||
do this.bare_fn_tys(a_fty, b_fty).and_then |fty| {
|
||||
Ok(ty::mk_bare_fn(tcx, fty))
|
||||
}
|
||||
}
|
||||
|
||||
(&ty::ty_closure(ref a_fty), &ty::ty_closure(ref b_fty)) => {
|
||||
do this.closure_tys(a_fty, b_fty).chain |fty| {
|
||||
do this.closure_tys(a_fty, b_fty).and_then |fty| {
|
||||
Ok(ty::mk_closure(tcx, fty))
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ impl Combine for Glb {
|
||||
// If one side or both is immutable, we can use the GLB of
|
||||
// both sides but mutbl must be `MutImmutable`.
|
||||
(MutImmutable, MutImmutable) => {
|
||||
self.tys(a.ty, b.ty).chain(|t| {
|
||||
self.tys(a.ty, b.ty).and_then(|t| {
|
||||
Ok(ty::mt {ty: t, mutbl: MutImmutable})
|
||||
})
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ impl CombineFieldsLatticeMethods for CombineFields {
|
||||
(&Some(_), &None) => Ok((*a).clone()),
|
||||
(&None, &Some(_)) => Ok((*b).clone()),
|
||||
(&Some(ref v_a), &Some(ref v_b)) => {
|
||||
do lattice_op(self, v_a, v_b).chain |v| {
|
||||
do lattice_op(self, v_a, v_b).and_then |v| {
|
||||
Ok(Some(v))
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ impl Combine for Lub {
|
||||
let m = a.mutbl;
|
||||
match m {
|
||||
MutImmutable => {
|
||||
self.tys(a.ty, b.ty).chain(|t| Ok(ty::mt {ty: t, mutbl: m}) )
|
||||
self.tys(a.ty, b.ty).and_then(|t| Ok(ty::mt {ty: t, mutbl: m}) )
|
||||
}
|
||||
|
||||
MutMutable => {
|
||||
@ -70,7 +70,7 @@ impl Combine for Lub {
|
||||
eq_tys(self, a.ty, b.ty).then(|| {
|
||||
Ok(ty::mt {ty: a.ty, mutbl: m})
|
||||
})
|
||||
}).chain_err(|e| Err(e))
|
||||
}).or_else(|e| Err(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -451,7 +451,7 @@ trait then {
|
||||
impl then for ures {
|
||||
fn then<T:Clone>(&self, f: &fn() -> Result<T,ty::type_err>)
|
||||
-> Result<T,ty::type_err> {
|
||||
self.chain(|_i| f())
|
||||
self.and_then(|_i| f())
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,7 +474,7 @@ trait CresCompare<T> {
|
||||
|
||||
impl<T:Clone + Eq> CresCompare<T> for cres<T> {
|
||||
fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres<T> {
|
||||
do (*self).clone().chain |s| {
|
||||
do (*self).clone().and_then |s| {
|
||||
if s == t {
|
||||
(*self).clone()
|
||||
} else {
|
||||
|
@ -79,7 +79,7 @@ impl Combine for Sub {
|
||||
}
|
||||
MutImmutable => {
|
||||
// Otherwise we can be covariant:
|
||||
self.tys(a.ty, b.ty).chain(|_t| Ok(*a) )
|
||||
self.tys(a.ty, b.ty).and_then(|_t| Ok(*a) )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ impl RegionScope for MethodRscope {
|
||||
if !self.region_param_names.has_ident(id) {
|
||||
return RegionParamNames::undeclared_name(None);
|
||||
}
|
||||
do EmptyRscope.named_region(span, id).chain_err |_e| {
|
||||
do EmptyRscope.named_region(span, id).or_else |_e| {
|
||||
result::Err(RegionError {
|
||||
msg: ~"lifetime is not in scope",
|
||||
replacement: ty::re_bound(ty::br_self)
|
||||
@ -251,7 +251,7 @@ impl RegionScope for TypeRscope {
|
||||
}
|
||||
fn named_region(&self, span: Span, id: ast::Ident)
|
||||
-> Result<ty::Region, RegionError> {
|
||||
do EmptyRscope.named_region(span, id).chain_err |_e| {
|
||||
do EmptyRscope.named_region(span, id).or_else |_e| {
|
||||
result::Err(RegionError {
|
||||
msg: ~"only 'self is allowed as part of a type declaration",
|
||||
replacement: self.replacement()
|
||||
@ -310,7 +310,7 @@ impl RegionScope for BindingRscope {
|
||||
span: Span,
|
||||
id: ast::Ident) -> Result<ty::Region, RegionError>
|
||||
{
|
||||
do self.base.named_region(span, id).chain_err |_e| {
|
||||
do self.base.named_region(span, id).or_else |_e| {
|
||||
let result = ty::re_bound(ty::br_named(id));
|
||||
if self.region_param_names.has_ident(id) {
|
||||
result::Ok(result)
|
||||
|
@ -68,7 +68,7 @@ fn fold_crate(
|
||||
doc::CrateDoc {
|
||||
topmod: doc::ModDoc {
|
||||
item: doc::ItemDoc {
|
||||
name: attrs.name.clone().unwrap_or_default(doc.topmod.name_()),
|
||||
name: attrs.name.clone().unwrap_or(doc.topmod.name_()),
|
||||
.. doc.topmod.item.clone()
|
||||
},
|
||||
.. doc.topmod.clone()
|
||||
|
@ -138,18 +138,18 @@ fn config_from_opts(
|
||||
|
||||
let config = default_config(input_crate);
|
||||
let result = result::Ok(config);
|
||||
let result = do result.chain |config| {
|
||||
let result = do result.and_then |config| {
|
||||
let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
|
||||
let output_dir = output_dir.map_move(|s| Path(s));
|
||||
result::Ok(Config {
|
||||
output_dir: output_dir.unwrap_or_default(config.output_dir.clone()),
|
||||
output_dir: output_dir.unwrap_or(config.output_dir.clone()),
|
||||
.. config
|
||||
})
|
||||
};
|
||||
let result = do result.chain |config| {
|
||||
let result = do result.and_then |config| {
|
||||
let output_format = getopts::opt_maybe_str(matches, opt_output_format());
|
||||
do output_format.map_move_default(result::Ok(config.clone())) |output_format| {
|
||||
do parse_output_format(output_format).chain |output_format| {
|
||||
do parse_output_format(output_format).and_then |output_format| {
|
||||
result::Ok(Config {
|
||||
output_format: output_format,
|
||||
.. config.clone()
|
||||
@ -157,11 +157,11 @@ fn config_from_opts(
|
||||
}
|
||||
}
|
||||
};
|
||||
let result = do result.chain |config| {
|
||||
let result = do result.and_then |config| {
|
||||
let output_style =
|
||||
getopts::opt_maybe_str(matches, opt_output_style());
|
||||
do output_style.map_move_default(result::Ok(config.clone())) |output_style| {
|
||||
do parse_output_style(output_style).chain |output_style| {
|
||||
do parse_output_style(output_style).and_then |output_style| {
|
||||
result::Ok(Config {
|
||||
output_style: output_style,
|
||||
.. config.clone()
|
||||
@ -170,11 +170,11 @@ fn config_from_opts(
|
||||
}
|
||||
};
|
||||
let process_output = Cell::new(process_output);
|
||||
let result = do result.chain |config| {
|
||||
let result = do result.and_then |config| {
|
||||
let pandoc_cmd = getopts::opt_maybe_str(matches, opt_pandoc_cmd());
|
||||
let pandoc_cmd = maybe_find_pandoc(
|
||||
&config, pandoc_cmd, process_output.take());
|
||||
do pandoc_cmd.chain |pandoc_cmd| {
|
||||
do pandoc_cmd.and_then |pandoc_cmd| {
|
||||
result::Ok(Config {
|
||||
pandoc_cmd: pandoc_cmd,
|
||||
.. config.clone()
|
||||
|
@ -118,7 +118,7 @@ pub fn try_getting_local_version(local_path: &Path) -> Option<Version> {
|
||||
if !l.is_whitespace() {
|
||||
output = Some(l);
|
||||
}
|
||||
match output.chain(try_parsing_version) {
|
||||
match output.and_then(try_parsing_version) {
|
||||
Some(v) => return Some(v),
|
||||
None => ()
|
||||
}
|
||||
@ -158,7 +158,7 @@ pub fn try_getting_version(remote_path: &Path) -> Option<Version> {
|
||||
}
|
||||
}
|
||||
|
||||
output.chain(try_parsing_version)
|
||||
output.and_then(try_parsing_version)
|
||||
}
|
||||
else {
|
||||
None
|
||||
|
@ -45,7 +45,7 @@ pub fn capacity<T>(v: @[T]) -> uint {
|
||||
#[inline]
|
||||
pub fn build<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> @[A] {
|
||||
let mut vec = @[];
|
||||
unsafe { raw::reserve(&mut vec, size.unwrap_or_default(4)); }
|
||||
unsafe { raw::reserve(&mut vec, size.unwrap_or(4)); }
|
||||
builder(|x| unsafe { raw::push(&mut vec, x) });
|
||||
vec
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ Implementations of the following traits:
|
||||
* `Ord`
|
||||
* `TotalOrd`
|
||||
* `Eq`
|
||||
* `Default`
|
||||
* `Zero`
|
||||
|
||||
## Various functions to compare `bool`s
|
||||
@ -43,6 +44,7 @@ use to_str::ToStr;
|
||||
|
||||
#[cfg(not(test))] use cmp::{Eq, Ord, TotalOrd, Ordering};
|
||||
#[cfg(not(test))] use ops::Not;
|
||||
#[cfg(not(test))] use default::Default;
|
||||
#[cfg(not(test))] use num::Zero;
|
||||
|
||||
/**
|
||||
@ -323,6 +325,11 @@ impl Eq for bool {
|
||||
fn eq(&self, other: &bool) -> bool { (*self) == (*other) }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Default for bool {
|
||||
fn default() -> bool { false }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Zero for bool {
|
||||
fn zero() -> bool { false }
|
||||
|
@ -21,6 +21,7 @@ use str;
|
||||
#[cfg(test)] use str::OwnedStr;
|
||||
|
||||
#[cfg(not(test))] use cmp::{Eq, Ord};
|
||||
#[cfg(not(test))] use default::Default;
|
||||
#[cfg(not(test))] use num::Zero;
|
||||
|
||||
// UTF-8 ranges and tags for encoding characters
|
||||
@ -434,9 +435,18 @@ impl Ord for char {
|
||||
fn lt(&self, other: &char) -> bool { *self < *other }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Default for char {
|
||||
#[inline]
|
||||
fn default() -> char { '\x00' }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Zero for char {
|
||||
#[inline]
|
||||
fn zero() -> char { '\x00' }
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool { *self == '\x00' }
|
||||
}
|
||||
|
||||
|
@ -15,3 +15,15 @@ pub trait Default {
|
||||
/// Return the "default value" for a type.
|
||||
fn default() -> Self;
|
||||
}
|
||||
|
||||
impl<T: Default + 'static> Default for @mut T {
|
||||
fn default() -> @mut T { @mut Default::default() }
|
||||
}
|
||||
|
||||
impl<T: Default + 'static> Default for @T {
|
||||
fn default() -> @T { @Default::default() }
|
||||
}
|
||||
|
||||
impl<T: Default> Default for ~T {
|
||||
fn default() -> ~T { ~Default::default() }
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use option::{Some, None};
|
||||
use option;
|
||||
use clone::Clone;
|
||||
use container::Container;
|
||||
use cmp::Eq;
|
||||
@ -53,18 +54,6 @@ impl<L, R> Either<L, R> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a `Either` to a `Result`
|
||||
///
|
||||
/// Converts an `Either` type to a `Result` type, making the "right" choice
|
||||
/// an `Ok` result, and the "left" choice a `Err`
|
||||
#[inline]
|
||||
pub fn to_result(self) -> Result<R, L> {
|
||||
match self {
|
||||
Right(r) => result::Ok(r),
|
||||
Left(l) => result::Err(l)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks whether the given value is a `Left`
|
||||
#[inline]
|
||||
pub fn is_left(&self) -> bool {
|
||||
@ -116,6 +105,101 @@ impl<L, R> Either<L, R> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value to a `Either`
|
||||
pub trait ToEither<L, R> {
|
||||
/// Convert to the `either` type
|
||||
fn to_either(&self) -> Either<L, R>;
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value to a `Either`
|
||||
pub trait IntoEither<L, R> {
|
||||
/// Convert to the `either` type
|
||||
fn into_either(self) -> Either<L, R>;
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value to a `Either`
|
||||
pub trait AsEither<L, R> {
|
||||
/// Convert to the `either` type
|
||||
fn as_either<'a>(&'a self) -> Either<&'a L, &'a R>;
|
||||
}
|
||||
|
||||
impl<L, R: Clone> option::ToOption<R> for Either<L, R> {
|
||||
#[inline]
|
||||
fn to_option(&self)-> option::Option<R> {
|
||||
match *self {
|
||||
Left(_) => None,
|
||||
Right(ref r) => Some(r.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> option::IntoOption<R> for Either<L, R> {
|
||||
#[inline]
|
||||
fn into_option(self)-> option::Option<R> {
|
||||
match self {
|
||||
Left(_) => None,
|
||||
Right(r) => Some(r),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> option::AsOption<R> for Either<L, R> {
|
||||
#[inline]
|
||||
fn as_option<'a>(&'a self) -> option::Option<&'a R> {
|
||||
match *self {
|
||||
Left(_) => None,
|
||||
Right(ref r) => Some(r),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: Clone, R: Clone> result::ToResult<R, L> for Either<L, R> {
|
||||
#[inline]
|
||||
fn to_result(&self)-> result::Result<R, L> {
|
||||
match *self {
|
||||
Left(ref l) => result::Err(l.clone()),
|
||||
Right(ref r) => result::Ok(r.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> result::IntoResult<R, L> for Either<L, R> {
|
||||
#[inline]
|
||||
fn into_result(self)-> result::Result<R, L> {
|
||||
match self {
|
||||
Left(l) => result::Err(l),
|
||||
Right(r) => result::Ok(r),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> result::AsResult<R, L> for Either<L, R> {
|
||||
#[inline]
|
||||
fn as_result<'a>(&'a self) -> result::Result<&'a R, &'a L> {
|
||||
match *self {
|
||||
Left(ref l) => result::Err(l),
|
||||
Right(ref r) => result::Ok(r),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: Clone, R: Clone> ToEither<L, R> for Either<L, R> {
|
||||
fn to_either(&self) -> Either<L, R> { self.clone() }
|
||||
}
|
||||
|
||||
impl<L, R> IntoEither<L, R> for Either<L, R> {
|
||||
fn into_either(self) -> Either<L, R> { self }
|
||||
}
|
||||
|
||||
impl<L, R> AsEither<L, R> for Either<L, R> {
|
||||
fn as_either<'a>(&'a self) -> Either<&'a L, &'a R> {
|
||||
match *self {
|
||||
Left(ref l) => Left(l),
|
||||
Right(ref r) => Right(r),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator yielding the `Left` values of its source
|
||||
pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
|
||||
|
||||
@ -167,6 +251,11 @@ pub fn partition<L, R>(eithers: ~[Either<L, R>]) -> (~[L], ~[R]) {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use option::{IntoOption, ToOption, AsOption};
|
||||
use option;
|
||||
use result::{IntoResult, ToResult, AsResult};
|
||||
use result;
|
||||
|
||||
#[test]
|
||||
fn test_either_left() {
|
||||
let val = Left(10);
|
||||
@ -260,4 +349,87 @@ mod tests {
|
||||
assert_eq!(rights.len(), 0u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_option() {
|
||||
let right: Either<int, int> = Right(100);
|
||||
let left: Either<int, int> = Left(404);
|
||||
|
||||
assert_eq!(right.to_option(), option::Some(100));
|
||||
assert_eq!(left.to_option(), option::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_into_option() {
|
||||
let right: Either<int, int> = Right(100);
|
||||
let left: Either<int, int> = Left(404);
|
||||
|
||||
assert_eq!(right.into_option(), option::Some(100));
|
||||
assert_eq!(left.into_option(), option::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_as_option() {
|
||||
let right: Either<int, int> = Right(100);
|
||||
let left: Either<int, int> = Left(404);
|
||||
|
||||
assert_eq!(right.as_option().unwrap(), &100);
|
||||
assert_eq!(left.as_option(), option::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_result() {
|
||||
let right: Either<int, int> = Right(100);
|
||||
let left: Either<int, int> = Left(404);
|
||||
|
||||
assert_eq!(right.to_result(), result::Ok(100));
|
||||
assert_eq!(left.to_result(), result::Err(404));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_into_result() {
|
||||
let right: Either<int, int> = Right(100);
|
||||
let left: Either<int, int> = Left(404);
|
||||
|
||||
assert_eq!(right.into_result(), result::Ok(100));
|
||||
assert_eq!(left.into_result(), result::Err(404));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_as_result() {
|
||||
let right: Either<int, int> = Right(100);
|
||||
let left: Either<int, int> = Left(404);
|
||||
|
||||
let x = 100;
|
||||
assert_eq!(right.as_result(), result::Ok(&x));
|
||||
|
||||
let x = 404;
|
||||
assert_eq!(left.as_result(), result::Err(&x));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_either() {
|
||||
let right: Either<int, int> = Right(100);
|
||||
let left: Either<int, int> = Left(404);
|
||||
|
||||
assert_eq!(right.to_either(), Right(100));
|
||||
assert_eq!(left.to_either(), Left(404));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_into_either() {
|
||||
let right: Either<int, int> = Right(100);
|
||||
let left: Either<int, int> = Left(404);
|
||||
|
||||
assert_eq!(right.into_either(), Right(100));
|
||||
assert_eq!(left.into_either(), Left(404));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_as_either() {
|
||||
let right: Either<int, int> = Right(100);
|
||||
let left: Either<int, int> = Left(404);
|
||||
|
||||
assert_eq!(right.as_either().unwrap_right(), &100);
|
||||
assert_eq!(left.as_either().unwrap_left(), &404);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
|
||||
use clone::Clone;
|
||||
use cmp::{Eq, Equiv};
|
||||
use default::Default;
|
||||
use hash::Hash;
|
||||
use iter::{Iterator, FromIterator, Extendable};
|
||||
use iter::{FilterMap, Chain, Repeat, Zip};
|
||||
@ -622,6 +623,10 @@ impl<K: Eq + Hash, V> Extendable<(K, V)> for HashMap<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash, V> Default for HashMap<K, V> {
|
||||
fn default() -> HashMap<K, V> { HashMap::new() }
|
||||
}
|
||||
|
||||
/// An implementation of a hash set using the underlying representation of a
|
||||
/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
|
||||
/// requires that the elements implement the `Eq` and `Hash` traits.
|
||||
@ -781,6 +786,10 @@ impl<K: Eq + Hash> Extendable<K> for HashSet<K> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash> Default for HashSet<K> {
|
||||
fn default() -> HashSet<K> { HashSet::new() }
|
||||
}
|
||||
|
||||
// `Repeat` is used to feed the filter closure an explicit capture
|
||||
// of a reference to the other set
|
||||
/// Set operations iterator
|
||||
|
@ -1618,7 +1618,7 @@ impl<T:Writer> WriterUtil for T {
|
||||
}
|
||||
|
||||
pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
|
||||
mk_file_writer(path, flags).chain(|w| Ok(w))
|
||||
mk_file_writer(path, flags).and_then(|w| Ok(w))
|
||||
}
|
||||
|
||||
|
||||
@ -1779,7 +1779,7 @@ pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
|
||||
}
|
||||
|
||||
pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
|
||||
do read_whole_file(file).chain |bytes| {
|
||||
do read_whole_file(file).and_then |bytes| {
|
||||
if str::is_utf8(bytes) {
|
||||
Ok(str::from_utf8(bytes))
|
||||
} else {
|
||||
@ -1791,7 +1791,7 @@ pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
|
||||
// FIXME (#2004): implement this in a low-level way. Going through the
|
||||
// abstractions is pointless.
|
||||
pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
|
||||
do file_reader(file).chain |rdr| {
|
||||
do file_reader(file).and_then |rdr| {
|
||||
Ok(rdr.read_whole_stream())
|
||||
}
|
||||
}
|
||||
|
@ -1474,7 +1474,7 @@ pub struct Scan<'self, A, B, T, St> {
|
||||
impl<'self, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'self, A, B, T, St> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<B> {
|
||||
self.iter.next().chain(|a| (self.f)(&mut self.state, a))
|
||||
self.iter.next().and_then(|a| (self.f)(&mut self.state, a))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -1494,8 +1494,7 @@ pub struct FlatMap<'self, A, T, U> {
|
||||
priv backiter: Option<U>,
|
||||
}
|
||||
|
||||
impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
|
||||
FlatMap<'self, A, T, U> {
|
||||
impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'self, A, T, U> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<B> {
|
||||
loop {
|
||||
@ -1505,7 +1504,7 @@ impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
|
||||
}
|
||||
}
|
||||
match self.iter.next().map_move(|x| (self.f)(x)) {
|
||||
None => return self.backiter.chain_mut_ref(|it| it.next()),
|
||||
None => return self.backiter.and_then_mut_ref(|it| it.next()),
|
||||
next => self.frontiter = next,
|
||||
}
|
||||
}
|
||||
@ -1537,7 +1536,7 @@ impl<'self,
|
||||
}
|
||||
}
|
||||
match self.iter.next_back().map_move(|x| (self.f)(x)) {
|
||||
None => return self.frontiter.chain_mut_ref(|it| it.next_back()),
|
||||
None => return self.frontiter.and_then_mut_ref(|it| it.next_back()),
|
||||
next => self.backiter = next,
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#[allow(missing_doc)];
|
||||
#[allow(non_uppercase_statics)];
|
||||
|
||||
use default::Default;
|
||||
use libc::c_int;
|
||||
use num::{Zero, One, strconv};
|
||||
use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
|
||||
@ -237,6 +238,11 @@ impl Orderable for f32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for f32 {
|
||||
#[inline]
|
||||
fn default() -> f32 { 0.0 }
|
||||
}
|
||||
|
||||
impl Zero for f32 {
|
||||
#[inline]
|
||||
fn zero() -> f32 { 0.0 }
|
||||
|
@ -13,6 +13,7 @@
|
||||
#[allow(missing_doc)];
|
||||
#[allow(non_uppercase_statics)];
|
||||
|
||||
use default::Default;
|
||||
use libc::c_int;
|
||||
use num::{Zero, One, strconv};
|
||||
use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
|
||||
@ -260,6 +261,11 @@ impl Orderable for f64 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for f64 {
|
||||
#[inline]
|
||||
fn default() -> f64 { 0.0 }
|
||||
}
|
||||
|
||||
impl Zero for f64 {
|
||||
#[inline]
|
||||
fn zero() -> f64 { 0.0 }
|
||||
|
@ -23,6 +23,7 @@
|
||||
#[allow(missing_doc)];
|
||||
#[allow(non_uppercase_statics)];
|
||||
|
||||
use default::Default;
|
||||
use num::{Zero, One, strconv};
|
||||
use num::FPCategory;
|
||||
use num;
|
||||
@ -382,6 +383,11 @@ impl Orderable for float {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for float {
|
||||
#[inline]
|
||||
fn default() -> float { 0.0 }
|
||||
}
|
||||
|
||||
impl Zero for float {
|
||||
#[inline]
|
||||
fn zero() -> float { 0.0 }
|
||||
|
@ -16,6 +16,7 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
|
||||
|
||||
#[allow(non_uppercase_statics)];
|
||||
|
||||
use default::Default;
|
||||
use num::{ToStrRadix, FromStrRadix};
|
||||
use num::{CheckedDiv, Zero, One, strconv};
|
||||
use prelude::*;
|
||||
@ -167,6 +168,11 @@ impl Orderable for $T {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for $T {
|
||||
#[inline]
|
||||
fn default() -> $T { 0 }
|
||||
}
|
||||
|
||||
impl Zero for $T {
|
||||
#[inline]
|
||||
fn zero() -> $T { 0 }
|
||||
|
@ -16,6 +16,7 @@ macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated {
|
||||
|
||||
#[allow(non_uppercase_statics)];
|
||||
|
||||
use default::Default;
|
||||
use num::BitCount;
|
||||
use num::{ToStrRadix, FromStrRadix};
|
||||
use num::{CheckedDiv, Zero, One, strconv};
|
||||
@ -172,6 +173,11 @@ impl Orderable for $T {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for $T {
|
||||
#[inline]
|
||||
fn default() -> $T { 0 }
|
||||
}
|
||||
|
||||
impl Zero for $T {
|
||||
#[inline]
|
||||
fn zero() -> $T { 0 }
|
||||
|
@ -43,10 +43,13 @@ let unwrapped_msg = match msg {
|
||||
|
||||
use clone::Clone;
|
||||
use cmp::{Eq,Ord};
|
||||
use default::Default;
|
||||
use either;
|
||||
use util;
|
||||
use num::Zero;
|
||||
use iter;
|
||||
use iter::{Iterator, DoubleEndedIterator, ExactSize};
|
||||
use result;
|
||||
use str::{StrSlice, OwnedStr};
|
||||
use to_str::ToStr;
|
||||
use clone::DeepClone;
|
||||
@ -126,45 +129,64 @@ impl<T> Option<T> {
|
||||
#[inline]
|
||||
pub fn is_some(&self) -> bool { !self.is_none() }
|
||||
|
||||
/// Update an optional value by optionally running its content through a
|
||||
/// function that returns an option.
|
||||
/// Returns `None` if the option is `None`, otherwise returns `optb`.
|
||||
#[inline]
|
||||
pub fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
|
||||
pub fn and(self, optb: Option<T>) -> Option<T> {
|
||||
match self {
|
||||
Some(t) => f(t),
|
||||
None => None
|
||||
Some(_) => optb,
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the leftmost Some() value, or None if both are None.
|
||||
/// Returns `None` if the option is `None`, otherwise calls `f` with the
|
||||
/// wrapped value and returns the result.
|
||||
#[inline]
|
||||
pub fn or(self, optb: Option<T>) -> Option<T> {
|
||||
pub fn and_then<U>(self, f: &fn(T) -> Option<U>) -> Option<U> {
|
||||
match self {
|
||||
Some(opta) => Some(opta),
|
||||
_ => optb
|
||||
Some(x) => f(x),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Update an optional value by optionally running its content by reference
|
||||
/// through a function that returns an option.
|
||||
/// Returns `None` if the option is `None`, otherwise calls `f` with a
|
||||
/// reference to the wrapped value and returns the result.
|
||||
#[inline]
|
||||
pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>) -> Option<U> {
|
||||
pub fn and_then_ref<'a, U>(&'a self, f: &fn(&'a T) -> Option<U>) -> Option<U> {
|
||||
match *self {
|
||||
Some(ref x) => f(x),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
/// Update an optional value by optionally running its content by mut reference
|
||||
/// through a function that returns an option.
|
||||
/// Returns `None` if the option is `None`, otherwise calls `f` with a
|
||||
/// mutable reference to the wrapped value and returns the result.
|
||||
#[inline]
|
||||
pub fn chain_mut_ref<'a, U>(&'a mut self, f: &fn(x: &'a mut T) -> Option<U>) -> Option<U> {
|
||||
pub fn and_then_mut_ref<'a, U>(&'a mut self, f: &fn(&'a mut T) -> Option<U>) -> Option<U> {
|
||||
match *self {
|
||||
Some(ref mut x) => f(x),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the option if it contains a value, otherwise returns `optb`.
|
||||
#[inline]
|
||||
pub fn or(self, optb: Option<T>) -> Option<T> {
|
||||
match self {
|
||||
Some(_) => self,
|
||||
None => optb
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the option if it contains a value, otherwise calls `f` and
|
||||
/// returns the result.
|
||||
#[inline]
|
||||
pub fn or_else(self, f: &fn() -> Option<T>) -> Option<T> {
|
||||
match self {
|
||||
Some(_) => self,
|
||||
None => f(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Filters an optional value using given function.
|
||||
#[inline(always)]
|
||||
pub fn filtered(self, f: &fn(t: &T) -> bool) -> Option<T> {
|
||||
@ -332,13 +354,22 @@ impl<T> Option<T> {
|
||||
|
||||
/// Returns the contained value or a default
|
||||
#[inline]
|
||||
pub fn unwrap_or_default(self, def: T) -> T {
|
||||
pub fn unwrap_or(self, def: T) -> T {
|
||||
match self {
|
||||
Some(x) => x,
|
||||
None => def
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the contained value or computes it from a closure
|
||||
#[inline]
|
||||
pub fn unwrap_or_else(self, f: &fn() -> T) -> T {
|
||||
match self {
|
||||
Some(x) => x,
|
||||
None => f()
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies a function zero or more times until the result is `None`.
|
||||
#[inline]
|
||||
pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
|
||||
@ -349,6 +380,109 @@ impl<T> Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value to a `Option`
|
||||
pub trait ToOption<T> {
|
||||
/// Convert to the `option` type
|
||||
fn to_option(&self) -> Option<T>;
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value to a `Option`
|
||||
pub trait IntoOption<T> {
|
||||
/// Convert to the `option` type
|
||||
fn into_option(self) -> Option<T>;
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value to a `Option`
|
||||
pub trait AsOption<T> {
|
||||
/// Convert to the `option` type
|
||||
fn as_option<'a>(&'a self) -> Option<&'a T>;
|
||||
}
|
||||
|
||||
impl<T: Clone> ToOption<T> for Option<T> {
|
||||
#[inline]
|
||||
fn to_option(&self) -> Option<T> { self.clone() }
|
||||
}
|
||||
|
||||
impl<T> IntoOption<T> for Option<T> {
|
||||
#[inline]
|
||||
fn into_option(self) -> Option<T> { self }
|
||||
}
|
||||
|
||||
impl<T> AsOption<T> for Option<T> {
|
||||
#[inline]
|
||||
fn as_option<'a>(&'a self) -> Option<&'a T> {
|
||||
match *self {
|
||||
Some(ref x) => Some(x),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> result::ToResult<T, ()> for Option<T> {
|
||||
#[inline]
|
||||
fn to_result(&self) -> result::Result<T, ()> {
|
||||
match *self {
|
||||
Some(ref x) => result::Ok(x.clone()),
|
||||
None => result::Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> result::IntoResult<T, ()> for Option<T> {
|
||||
#[inline]
|
||||
fn into_result(self) -> result::Result<T, ()> {
|
||||
match self {
|
||||
Some(x) => result::Ok(x),
|
||||
None => result::Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> either::ToEither<(), T> for Option<T> {
|
||||
#[inline]
|
||||
fn to_either(&self) -> either::Either<(), T> {
|
||||
match *self {
|
||||
Some(ref x) => either::Right(x.clone()),
|
||||
None => either::Left(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> either::IntoEither<(), T> for Option<T> {
|
||||
#[inline]
|
||||
fn into_either(self) -> either::Either<(), T> {
|
||||
match self {
|
||||
Some(x) => either::Right(x),
|
||||
None => either::Left(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Option<T> {
|
||||
/// Returns the contained value or default (for this type)
|
||||
#[inline]
|
||||
pub fn unwrap_or_default(self) -> T {
|
||||
match self {
|
||||
Some(x) => x,
|
||||
None => Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns self or `Some`-wrapped default value
|
||||
#[inline]
|
||||
pub fn or_default(self) -> Option<T> {
|
||||
match self {
|
||||
None => Some(Default::default()),
|
||||
x => x,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for Option<T> {
|
||||
#[inline]
|
||||
fn default() -> Option<T> { None }
|
||||
}
|
||||
|
||||
impl<T:Zero> Option<T> {
|
||||
/// Returns the contained value or zero (for this type)
|
||||
#[inline]
|
||||
@ -369,11 +503,6 @@ impl<T:Zero> Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Zero for Option<T> {
|
||||
fn zero() -> Option<T> { None }
|
||||
fn is_zero(&self) -> bool { self.is_none() }
|
||||
}
|
||||
|
||||
/// An iterator that yields either one or zero elements
|
||||
#[deriving(Clone, DeepClone)]
|
||||
pub struct OptionIterator<A> {
|
||||
@ -407,6 +536,11 @@ impl<A> ExactSize<A> for OptionIterator<A> {}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use either::{IntoEither, ToEither};
|
||||
use either;
|
||||
use result::{IntoResult, ToResult};
|
||||
use result;
|
||||
use util;
|
||||
|
||||
#[test]
|
||||
@ -475,6 +609,50 @@ mod tests {
|
||||
let _y3 = y.take_unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.and(Some(2)), Some(2));
|
||||
assert_eq!(x.and(None), None);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.and(Some(2)), None);
|
||||
assert_eq!(x.and(None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and_then() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.and_then(|x| Some(x + 1)), Some(2));
|
||||
assert_eq!(x.and_then(|_| None::<int>), None);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.and_then(|x| Some(x + 1)), None);
|
||||
assert_eq!(x.and_then(|_| None::<int>), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.or(Some(2)), Some(1));
|
||||
assert_eq!(x.or(None), Some(1));
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.or(Some(2)), Some(2));
|
||||
assert_eq!(x.or(None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or_else() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.or_else(|| Some(2)), Some(1));
|
||||
assert_eq!(x.or_else(|| None), Some(1));
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.or_else(|| Some(2)), Some(2));
|
||||
assert_eq!(x.or_else(|| None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_while_some() {
|
||||
let mut i = 0;
|
||||
@ -489,6 +667,44 @@ mod tests {
|
||||
assert_eq!(i, 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap() {
|
||||
assert_eq!(Some(1).unwrap(), 1);
|
||||
assert_eq!(Some(~"hello").unwrap(), ~"hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_unwrap_fail1() {
|
||||
let x: Option<int> = None;
|
||||
x.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_unwrap_fail2() {
|
||||
let x: Option<~str> = None;
|
||||
x.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap_or() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.unwrap_or(2), 1);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.unwrap_or(2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap_or_else() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.unwrap_or_else(|| 2), 1);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.unwrap_or_else(|| 2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap_or_zero() {
|
||||
let some_stuff = Some(42);
|
||||
@ -566,4 +782,67 @@ mod tests {
|
||||
assert!(!x.mutate_default(0i, |i| i+1));
|
||||
assert_eq!(x, Some(0i));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_option() {
|
||||
let some: Option<int> = Some(100);
|
||||
let none: Option<int> = None;
|
||||
|
||||
assert_eq!(some.to_option(), Some(100));
|
||||
assert_eq!(none.to_option(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_into_option() {
|
||||
let some: Option<int> = Some(100);
|
||||
let none: Option<int> = None;
|
||||
|
||||
assert_eq!(some.into_option(), Some(100));
|
||||
assert_eq!(none.into_option(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_as_option() {
|
||||
let some: Option<int> = Some(100);
|
||||
let none: Option<int> = None;
|
||||
|
||||
assert_eq!(some.as_option().unwrap(), &100);
|
||||
assert_eq!(none.as_option(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_result() {
|
||||
let some: Option<int> = Some(100);
|
||||
let none: Option<int> = None;
|
||||
|
||||
assert_eq!(some.to_result(), result::Ok(100));
|
||||
assert_eq!(none.to_result(), result::Err(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_into_result() {
|
||||
let some: Option<int> = Some(100);
|
||||
let none: Option<int> = None;
|
||||
|
||||
assert_eq!(some.into_result(), result::Ok(100));
|
||||
assert_eq!(none.into_result(), result::Err(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_either() {
|
||||
let some: Option<int> = Some(100);
|
||||
let none: Option<int> = None;
|
||||
|
||||
assert_eq!(some.to_either(), either::Right(100));
|
||||
assert_eq!(none.to_either(), either::Left(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_into_either() {
|
||||
let some: Option<int> = Some(100);
|
||||
let none: Option<int> = None;
|
||||
|
||||
assert_eq!(some.into_either(), either::Right(100));
|
||||
assert_eq!(none.into_either(), either::Left(()));
|
||||
}
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ pub fn homedir() -> Option<Path> {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn secondary() -> Option<Path> {
|
||||
do getenv("USERPROFILE").chain |p| {
|
||||
do getenv("USERPROFILE").and_then |p| {
|
||||
if !p.is_empty() {
|
||||
Some(Path(p))
|
||||
} else {
|
||||
@ -611,7 +611,7 @@ pub fn tmpdir() -> Path {
|
||||
if cfg!(target_os = "android") {
|
||||
Path("/data/tmp")
|
||||
} else {
|
||||
getenv_nonempty("TMPDIR").unwrap_or_default(Path("/tmp"))
|
||||
getenv_nonempty("TMPDIR").unwrap_or(Path("/tmp"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -620,7 +620,7 @@ pub fn tmpdir() -> Path {
|
||||
getenv_nonempty("TMP").or(
|
||||
getenv_nonempty("TEMP").or(
|
||||
getenv_nonempty("USERPROFILE").or(
|
||||
getenv_nonempty("WINDIR")))).unwrap_or_default(Path("C:\\Windows"))
|
||||
getenv_nonempty("WINDIR")))).unwrap_or(Path("C:\\Windows"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ use cmp::Eq;
|
||||
use either;
|
||||
use iter::Iterator;
|
||||
use option::{None, Option, Some, OptionIterator};
|
||||
use option;
|
||||
use vec;
|
||||
use vec::OwnedVector;
|
||||
use to_str::ToStr;
|
||||
@ -36,18 +37,6 @@ pub enum Result<T, E> {
|
||||
}
|
||||
|
||||
impl<T, E: ToStr> Result<T, E> {
|
||||
/// Convert to the `either` type
|
||||
///
|
||||
/// `Ok` result variants are converted to `either::Right` variants, `Err`
|
||||
/// result variants are converted to `either::Left`.
|
||||
#[inline]
|
||||
pub fn to_either(self)-> either::Either<E, T>{
|
||||
match self {
|
||||
Ok(t) => either::Right(t),
|
||||
Err(e) => either::Left(e),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the value out of a successful result
|
||||
///
|
||||
/// # Failure
|
||||
@ -182,10 +171,22 @@ impl<T, E: ToStr> Result<T, E> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Call a method based on a previous result
|
||||
///
|
||||
/// If `self` is `Ok`, then `res` it is returned. If `self` is `Err`,
|
||||
/// then `self` is returned.
|
||||
#[inline]
|
||||
pub fn and(self, res: Result<T, E>) -> Result<T, E> {
|
||||
match self {
|
||||
Ok(_) => res,
|
||||
Err(_) => self,
|
||||
}
|
||||
}
|
||||
|
||||
/// Call a method based on a previous result
|
||||
///
|
||||
/// If `self` is `Ok` then the value is extracted and passed to `op`
|
||||
/// whereupon `op`s result is returned. if `self` is `Err` then it is
|
||||
/// whereupon `op`s result is returned. If `self` is `Err` then it is
|
||||
/// immediately returned. This function can be used to compose the results
|
||||
/// of two functions.
|
||||
///
|
||||
@ -195,13 +196,25 @@ impl<T, E: ToStr> Result<T, E> {
|
||||
/// Ok(parse_bytes(buf))
|
||||
/// };
|
||||
#[inline]
|
||||
pub fn chain<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
|
||||
pub fn and_then<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
|
||||
match self {
|
||||
Ok(t) => op(t),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
/// Call a method based on a previous result
|
||||
///
|
||||
/// If `self` is `Ok`, then `self` is returned. If `self` is `Err`
|
||||
/// then `res` is returned.
|
||||
#[inline]
|
||||
pub fn or(self, res: Result<T, E>) -> Result<T, E> {
|
||||
match self {
|
||||
Ok(_) => self,
|
||||
Err(_) => res,
|
||||
}
|
||||
}
|
||||
|
||||
/// Call a function based on a previous result
|
||||
///
|
||||
/// If `self` is `Err` then the value is extracted and passed to `op`
|
||||
@ -209,7 +222,7 @@ impl<T, E: ToStr> Result<T, E> {
|
||||
/// immediately returned. This function can be used to pass through a
|
||||
/// successful result while handling an error.
|
||||
#[inline]
|
||||
pub fn chain_err<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
|
||||
pub fn or_else<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
|
||||
match self {
|
||||
Ok(t) => Ok(t),
|
||||
Err(e) => op(e),
|
||||
@ -255,6 +268,104 @@ impl<T, E: Clone + ToStr> Result<T, E> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value to a `Result`
|
||||
pub trait ToResult<T, E> {
|
||||
/// Convert to the `result` type
|
||||
fn to_result(&self) -> Result<T, E>;
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value to a `Result`
|
||||
pub trait IntoResult<T, E> {
|
||||
/// Convert to the `result` type
|
||||
fn into_result(self) -> Result<T, E>;
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value to a `Result`
|
||||
pub trait AsResult<T, E> {
|
||||
/// Convert to the `result` type
|
||||
fn as_result<'a>(&'a self) -> Result<&'a T, &'a E>;
|
||||
}
|
||||
|
||||
impl<T: Clone, E> option::ToOption<T> for Result<T, E> {
|
||||
#[inline]
|
||||
fn to_option(&self)-> Option<T> {
|
||||
match *self {
|
||||
Ok(ref t) => Some(t.clone()),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> option::IntoOption<T> for Result<T, E> {
|
||||
#[inline]
|
||||
fn into_option(self)-> Option<T> {
|
||||
match self {
|
||||
Ok(t) => Some(t),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> option::AsOption<T> for Result<T, E> {
|
||||
#[inline]
|
||||
fn as_option<'a>(&'a self)-> Option<&'a T> {
|
||||
match *self {
|
||||
Ok(ref t) => Some(t),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone, E: Clone> ToResult<T, E> for Result<T, E> {
|
||||
#[inline]
|
||||
fn to_result(&self) -> Result<T, E> { self.clone() }
|
||||
}
|
||||
|
||||
impl<T, E> IntoResult<T, E> for Result<T, E> {
|
||||
#[inline]
|
||||
fn into_result(self) -> Result<T, E> { self }
|
||||
}
|
||||
|
||||
impl<T, E> AsResult<T, E> for Result<T, E> {
|
||||
#[inline]
|
||||
fn as_result<'a>(&'a self) -> Result<&'a T, &'a E> {
|
||||
match *self {
|
||||
Ok(ref t) => Ok(t),
|
||||
Err(ref e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone, E: Clone> either::ToEither<E, T> for Result<T, E> {
|
||||
#[inline]
|
||||
fn to_either(&self)-> either::Either<E, T> {
|
||||
match *self {
|
||||
Ok(ref t) => either::Right(t.clone()),
|
||||
Err(ref e) => either::Left(e.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> either::IntoEither<E, T> for Result<T, E> {
|
||||
#[inline]
|
||||
fn into_either(self)-> either::Either<E, T> {
|
||||
match self {
|
||||
Ok(t) => either::Right(t),
|
||||
Err(e) => either::Left(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> either::AsEither<E, T> for Result<T, E> {
|
||||
#[inline]
|
||||
fn as_either<'a>(&'a self)-> either::Either<&'a E, &'a T> {
|
||||
match *self {
|
||||
Ok(ref t) => either::Right(t),
|
||||
Err(ref e) => either::Left(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(missing_doc)]
|
||||
pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
|
||||
@ -334,27 +445,51 @@ pub fn fold_<T, E, Iter: Iterator<Result<T, E>>>(
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use either::{IntoEither, ToEither, AsEither};
|
||||
use either;
|
||||
use iter::range;
|
||||
use option::{IntoOption, ToOption, AsOption};
|
||||
use option;
|
||||
use str::OwnedStr;
|
||||
use vec::ImmutableVector;
|
||||
|
||||
pub fn op1() -> Result<int, ~str> { Ok(666) }
|
||||
|
||||
pub fn op2(i: int) -> Result<uint, ~str> {
|
||||
Ok(i as uint + 1u)
|
||||
}
|
||||
|
||||
pub fn op3() -> Result<int, ~str> { Err(~"sadface") }
|
||||
pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
|
||||
|
||||
#[test]
|
||||
pub fn chain_success() {
|
||||
assert_eq!(op1().chain(op2).unwrap(), 667u);
|
||||
pub fn test_and() {
|
||||
assert_eq!(op1().and(Ok(667)).unwrap(), 667);
|
||||
assert_eq!(op1().and(Err(~"bad")).unwrap_err(), ~"bad");
|
||||
|
||||
assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
|
||||
assert_eq!(op2().and(Err(~"bad")).unwrap_err(), ~"sadface");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn chain_failure() {
|
||||
assert_eq!(op3().chain( op2).unwrap_err(), ~"sadface");
|
||||
pub fn test_and_then() {
|
||||
assert_eq!(op1().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap(), 667);
|
||||
assert_eq!(op1().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"bad");
|
||||
|
||||
assert_eq!(op2().and_then(|i| Ok::<int, ~str>(i + 1)).unwrap_err(), ~"sadface");
|
||||
assert_eq!(op2().and_then(|_| Err::<int, ~str>(~"bad")).unwrap_err(), ~"sadface");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_or() {
|
||||
assert_eq!(op1().or(Ok(667)).unwrap(), 666);
|
||||
assert_eq!(op1().or(Err(~"bad")).unwrap(), 666);
|
||||
|
||||
assert_eq!(op2().or(Ok(667)).unwrap(), 667);
|
||||
assert_eq!(op2().or(Err(~"bad")).unwrap_err(), ~"bad");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_or_else() {
|
||||
assert_eq!(op1().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 666);
|
||||
assert_eq!(op1().or_else(|e| Err::<int, ~str>(e + "!")).unwrap(), 666);
|
||||
|
||||
assert_eq!(op2().or_else(|_| Ok::<int, ~str>(667)).unwrap(), 667);
|
||||
assert_eq!(op2().or_else(|e| Err::<int, ~str>(e + "!")).unwrap_err(), ~"sadface!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -412,15 +547,6 @@ mod tests {
|
||||
assert_eq!(*foo.get_ref(), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_either() {
|
||||
let r: Result<int, ()> = Ok(100);
|
||||
let err: Result<(), int> = Err(404);
|
||||
|
||||
assert_eq!(r.to_either(), either::Right(100));
|
||||
assert_eq!(err.to_either(), either::Left(404));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collect() {
|
||||
assert_eq!(collect(range(0, 0)
|
||||
@ -460,4 +586,88 @@ mod tests {
|
||||
.map(|f| (*f)())),
|
||||
Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_option() {
|
||||
let ok: Result<int, int> = Ok(100);
|
||||
let err: Result<int, int> = Err(404);
|
||||
|
||||
assert_eq!(ok.to_option(), option::Some(100));
|
||||
assert_eq!(err.to_option(), option::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_into_option() {
|
||||
let ok: Result<int, int> = Ok(100);
|
||||
let err: Result<int, int> = Err(404);
|
||||
|
||||
assert_eq!(ok.into_option(), option::Some(100));
|
||||
assert_eq!(err.into_option(), option::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_as_option() {
|
||||
let ok: Result<int, int> = Ok(100);
|
||||
let err: Result<int, int> = Err(404);
|
||||
|
||||
assert_eq!(ok.as_option().unwrap(), &100);
|
||||
assert_eq!(err.as_option(), option::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_result() {
|
||||
let ok: Result<int, int> = Ok(100);
|
||||
let err: Result<int, int> = Err(404);
|
||||
|
||||
assert_eq!(ok.to_result(), Ok(100));
|
||||
assert_eq!(err.to_result(), Err(404));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_into_result() {
|
||||
let ok: Result<int, int> = Ok(100);
|
||||
let err: Result<int, int> = Err(404);
|
||||
|
||||
assert_eq!(ok.into_result(), Ok(100));
|
||||
assert_eq!(err.into_result(), Err(404));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_as_result() {
|
||||
let ok: Result<int, int> = Ok(100);
|
||||
let err: Result<int, int> = Err(404);
|
||||
|
||||
let x = 100;
|
||||
assert_eq!(ok.as_result(), Ok(&x));
|
||||
|
||||
let x = 404;
|
||||
assert_eq!(err.as_result(), Err(&x));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_either() {
|
||||
let ok: Result<int, int> = Ok(100);
|
||||
let err: Result<int, int> = Err(404);
|
||||
|
||||
assert_eq!(ok.to_either(), either::Right(100));
|
||||
assert_eq!(err.to_either(), either::Left(404));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_into_either() {
|
||||
let ok: Result<int, int> = Ok(100);
|
||||
let err: Result<int, int> = Err(404);
|
||||
|
||||
assert_eq!(ok.into_either(), either::Right(100));
|
||||
assert_eq!(err.into_either(), either::Left(404));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_as_either() {
|
||||
let ok: Result<int, int> = Ok(100);
|
||||
let err: Result<int, int> = Err(404);
|
||||
|
||||
assert_eq!(ok.as_either().unwrap_right(), &100);
|
||||
assert_eq!(err.as_either().unwrap_left(), &404);
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ impl<'self> Parser<'self> {
|
||||
}
|
||||
|
||||
do self.read_atomically |p| {
|
||||
p.read_char().chain(|c| parse_digit(c, radix))
|
||||
p.read_char().and_then(|c| parse_digit(c, radix))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,5 +383,5 @@ mod test {
|
||||
#[test] fn iterbytes_compiles () {
|
||||
takes_iterbytes((3,4,5,false));
|
||||
}
|
||||
fn takes_iterbytes<T : IterBytes>(x : T) {}
|
||||
fn takes_iterbytes<T : IterBytes>(_x : T) {}
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ macro_rules! tuple_impls {
|
||||
pub mod inner {
|
||||
use clone::Clone;
|
||||
#[cfg(not(test))] use cmp::*;
|
||||
#[cfg(not(test))] use default::Default;
|
||||
#[cfg(not(test))] use num::Zero;
|
||||
|
||||
$(
|
||||
@ -172,6 +173,14 @@ macro_rules! tuple_impls {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<$($T:Default),+> Default for ($($T,)+) {
|
||||
#[inline]
|
||||
fn default() -> ($($T,)+) {
|
||||
($({ let x: $T = Default::default(); x},)+)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<$($T:Zero),+> Zero for ($($T,)+) {
|
||||
#[inline]
|
||||
|
@ -45,6 +45,12 @@ impl TotalEq for () {
|
||||
fn equals(&self, _other: &()) -> bool { true }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Default for () {
|
||||
#[inline]
|
||||
fn default() -> () { () }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Zero for () {
|
||||
#[inline]
|
||||
@ -52,8 +58,3 @@ impl Zero for () {
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool { true }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Default for () {
|
||||
fn default() -> () { () }
|
||||
}
|
||||
|
@ -104,9 +104,10 @@ use clone::{Clone, DeepClone};
|
||||
use container::{Container, Mutable};
|
||||
use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
|
||||
use cmp;
|
||||
use default::Default;
|
||||
use iter::*;
|
||||
use libc::c_void;
|
||||
use num::{Integer, Zero, CheckedAdd, Saturating};
|
||||
use num::{Integer, CheckedAdd, Saturating};
|
||||
use option::{None, Option, Some};
|
||||
use ptr::to_unsafe_ptr;
|
||||
use ptr;
|
||||
@ -205,7 +206,7 @@ pub fn with_capacity<T>(capacity: uint) -> ~[T] {
|
||||
*/
|
||||
#[inline]
|
||||
pub fn build<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> ~[A] {
|
||||
let mut vec = with_capacity(size.unwrap_or_default(4));
|
||||
let mut vec = with_capacity(size.unwrap_or(4));
|
||||
builder(|x| vec.push(x));
|
||||
vec
|
||||
}
|
||||
@ -2237,19 +2238,16 @@ impl<A: DeepClone> DeepClone for ~[A] {
|
||||
}
|
||||
|
||||
// This works because every lifetime is a sub-lifetime of 'static
|
||||
impl<'self, A> Zero for &'self [A] {
|
||||
fn zero() -> &'self [A] { &'self [] }
|
||||
fn is_zero(&self) -> bool { self.is_empty() }
|
||||
impl<'self, A> Default for &'self [A] {
|
||||
fn default() -> &'self [A] { &'self [] }
|
||||
}
|
||||
|
||||
impl<A> Zero for ~[A] {
|
||||
fn zero() -> ~[A] { ~[] }
|
||||
fn is_zero(&self) -> bool { self.len() == 0 }
|
||||
impl<A> Default for ~[A] {
|
||||
fn default() -> ~[A] { ~[] }
|
||||
}
|
||||
|
||||
impl<A> Zero for @[A] {
|
||||
fn zero() -> @[A] { @[] }
|
||||
fn is_zero(&self) -> bool { self.len() == 0 }
|
||||
impl<A> Default for @[A] {
|
||||
fn default() -> @[A] { @[] }
|
||||
}
|
||||
|
||||
macro_rules! iterator {
|
||||
@ -3588,13 +3586,12 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_zero() {
|
||||
use num::Zero;
|
||||
fn test_vec_default() {
|
||||
use default::Default;
|
||||
macro_rules! t (
|
||||
($ty:ty) => {{
|
||||
let v: $ty = Zero::zero();
|
||||
let v: $ty = Default::default();
|
||||
assert!(v.is_empty());
|
||||
assert!(v.is_zero());
|
||||
}}
|
||||
);
|
||||
|
||||
|
@ -187,12 +187,12 @@ pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str)
|
||||
-> Option<@str> {
|
||||
attrs.iter()
|
||||
.find(|at| name == at.name())
|
||||
.chain(|at| at.value_str())
|
||||
.and_then(|at| at.value_str())
|
||||
}
|
||||
|
||||
pub fn last_meta_item_value_str_by_name(items: &[@MetaItem], name: &str)
|
||||
-> Option<@str> {
|
||||
items.rev_iter().find(|mi| name == mi.name()).chain(|i| i.value_str())
|
||||
items.rev_iter().find(|mi| name == mi.name()).and_then(|i| i.value_str())
|
||||
}
|
||||
|
||||
/* Higher-level applications */
|
||||
|
79
src/libsyntax/ext/deriving/default.rs
Normal file
79
src/libsyntax/ext/deriving/default.rs
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use ast::{MetaItem, item, Expr};
|
||||
use codemap::Span;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
use std::vec;
|
||||
|
||||
pub fn expand_deriving_default(cx: @ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
in_items: ~[@item])
|
||||
-> ~[@item] {
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~["std", "default", "Default"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: "default",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: None,
|
||||
args: ~[],
|
||||
ret_ty: Self,
|
||||
const_nonmatching: false,
|
||||
combine_substructure: default_substructure
|
||||
},
|
||||
]
|
||||
};
|
||||
trait_def.expand(cx, span, mitem, in_items)
|
||||
}
|
||||
|
||||
fn default_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
let default_ident = ~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("default"),
|
||||
cx.ident_of("Default"),
|
||||
cx.ident_of("default")
|
||||
];
|
||||
let default_call = || {
|
||||
cx.expr_call_global(span, default_ident.clone(), ~[])
|
||||
};
|
||||
|
||||
return match *substr.fields {
|
||||
StaticStruct(_, ref summary) => {
|
||||
match *summary {
|
||||
Left(count) => {
|
||||
if count == 0 {
|
||||
cx.expr_ident(span, substr.type_ident)
|
||||
} else {
|
||||
let exprs = vec::from_fn(count, |_| default_call());
|
||||
cx.expr_call_ident(span, substr.type_ident, exprs)
|
||||
}
|
||||
}
|
||||
Right(ref fields) => {
|
||||
let default_fields = do fields.map |ident| {
|
||||
cx.field_imm(span, *ident, default_call())
|
||||
};
|
||||
cx.expr_struct_ident(span, substr.type_ident, default_fields)
|
||||
}
|
||||
}
|
||||
}
|
||||
StaticEnum(*) => {
|
||||
cx.span_fatal(span, "`Default` cannot be derived for enums, \
|
||||
only structs")
|
||||
}
|
||||
_ => cx.bug("Non-static method in `deriving(Default)`")
|
||||
};
|
||||
}
|
@ -31,6 +31,7 @@ pub mod decodable;
|
||||
pub mod rand;
|
||||
pub mod to_str;
|
||||
pub mod zero;
|
||||
pub mod default;
|
||||
|
||||
#[path="cmp/eq.rs"]
|
||||
pub mod eq;
|
||||
@ -97,6 +98,7 @@ pub fn expand_meta_deriving(cx: @ExtCtxt,
|
||||
|
||||
"ToStr" => expand!(to_str::expand_deriving_to_str),
|
||||
"Zero" => expand!(zero::expand_deriving_zero),
|
||||
"Default" => expand!(default::expand_deriving_default),
|
||||
|
||||
ref tname => {
|
||||
cx.span_err(titem.span, fmt!("unknown \
|
||||
|
@ -331,11 +331,18 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
|
||||
};
|
||||
|
||||
let maybe_it = match expanded {
|
||||
MRItem(it) => mark_item(it,fm).chain(|i| {fld.fold_item(i)}),
|
||||
MRExpr(_) => cx.span_fatal(pth.span,
|
||||
fmt!("expr macro in item position: %s", extnamestr)),
|
||||
MRAny(_, item_maker, _) => item_maker().chain(|i| {mark_item(i,fm)})
|
||||
.chain(|i| {fld.fold_item(i)}),
|
||||
MRItem(it) => {
|
||||
mark_item(it,fm)
|
||||
.and_then(|i| fld.fold_item(i))
|
||||
}
|
||||
MRExpr(_) => {
|
||||
cx.span_fatal(pth.span, fmt!("expr macro in item position: %s", extnamestr))
|
||||
}
|
||||
MRAny(_, item_maker, _) => {
|
||||
item_maker()
|
||||
.and_then(|i| mark_item(i,fm))
|
||||
.and_then(|i| fld.fold_item(i))
|
||||
}
|
||||
MRDef(ref mdef) => {
|
||||
// yikes... no idea how to apply the mark to this. I'm afraid
|
||||
// we're going to have to wait-and-see on this one.
|
||||
|
@ -140,6 +140,10 @@ impl<A:Eq> Eq for OptVec<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for OptVec<T> {
|
||||
fn default() -> OptVec<T> { Empty }
|
||||
}
|
||||
|
||||
pub struct OptVecIterator<'self, T> {
|
||||
priv iter: Option<VecIterator<'self, T>>
|
||||
}
|
||||
|
@ -802,7 +802,7 @@ impl Parser {
|
||||
*/
|
||||
|
||||
let opt_abis = self.parse_opt_abis();
|
||||
let abis = opt_abis.unwrap_or_default(AbiSet::Rust());
|
||||
let abis = opt_abis.unwrap_or(AbiSet::Rust());
|
||||
let purity = self.parse_unsafety();
|
||||
self.expect_keyword(keywords::Fn);
|
||||
let (decl, lifetimes) = self.parse_ty_fn_decl();
|
||||
@ -3461,7 +3461,7 @@ impl Parser {
|
||||
let ident = self.parse_ident();
|
||||
let opt_bounds = self.parse_optional_ty_param_bounds();
|
||||
// For typarams we don't care about the difference b/w "<T>" and "<T:>".
|
||||
let bounds = opt_bounds.unwrap_or_default(opt_vec::Empty);
|
||||
let bounds = opt_bounds.unwrap_or_default();
|
||||
ast::TyParam { ident: ident, id: ast::DUMMY_NODE_ID, bounds: bounds }
|
||||
}
|
||||
|
||||
@ -4363,7 +4363,7 @@ impl Parser {
|
||||
self.obsolete(*self.last_span, ObsoleteExternVisibility);
|
||||
}
|
||||
|
||||
let abis = opt_abis.unwrap_or_default(AbiSet::C());
|
||||
let abis = opt_abis.unwrap_or(AbiSet::C());
|
||||
|
||||
let (inner, next) = self.parse_inner_attrs_and_next();
|
||||
let m = self.parse_foreign_mod_items(sort, abis, next);
|
||||
@ -4640,7 +4640,7 @@ impl Parser {
|
||||
|
||||
if self.eat_keyword(keywords::Fn) {
|
||||
// EXTERN FUNCTION ITEM
|
||||
let abis = opt_abis.unwrap_or_default(AbiSet::C());
|
||||
let abis = opt_abis.unwrap_or(AbiSet::C());
|
||||
let (ident, item_, extra_attrs) =
|
||||
self.parse_item_fn(extern_fn, abis);
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
|
||||
|
@ -24,15 +24,13 @@ struct E { a: int, b: int }
|
||||
|
||||
#[deriving(Zero)]
|
||||
struct Lots {
|
||||
c: Option<util::NonCopyable>,
|
||||
d: u8,
|
||||
e: char,
|
||||
f: float,
|
||||
g: (f32, char),
|
||||
h: ~[util::NonCopyable],
|
||||
i: @mut (int, int),
|
||||
j: bool,
|
||||
k: (),
|
||||
h: @mut (int, int),
|
||||
i: bool,
|
||||
j: (),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
Loading…
Reference in New Issue
Block a user