Remove all unstable deprecated functionality
This commit removes all unstable and deprecated functions in the standard library. A release was recently cut (1.3) which makes this a good time for some spring cleaning of the deprecated functions.
This commit is contained in:
parent
d07d465cf6
commit
8d90d3f368
125 changed files with 1681 additions and 15526 deletions
|
@ -395,46 +395,6 @@ def emit_conversions_module(f, to_upper, to_lower, to_title):
|
|||
is_pub=False, t_type = t_type, pfun=pfun)
|
||||
f.write("}\n\n")
|
||||
|
||||
def emit_grapheme_module(f, grapheme_table, grapheme_cats):
|
||||
f.write("""pub mod grapheme {
|
||||
use core::slice::SliceExt;
|
||||
pub use self::GraphemeCat::*;
|
||||
use core::result::Result::{Ok, Err};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum GraphemeCat {
|
||||
""")
|
||||
for cat in grapheme_cats + ["Any"]:
|
||||
f.write(" GC_" + cat + ",\n")
|
||||
f.write(""" }
|
||||
|
||||
fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat {
|
||||
use core::cmp::Ordering::{Equal, Less, Greater};
|
||||
match r.binary_search_by(|&(lo, hi, _)| {
|
||||
if lo <= c && c <= hi { Equal }
|
||||
else if hi < c { Less }
|
||||
else { Greater }
|
||||
}) {
|
||||
Ok(idx) => {
|
||||
let (_, _, cat) = r[idx];
|
||||
cat
|
||||
}
|
||||
Err(_) => GC_Any
|
||||
}
|
||||
}
|
||||
|
||||
pub fn grapheme_category(c: char) -> GraphemeCat {
|
||||
bsearch_range_value_table(c, grapheme_cat_table)
|
||||
}
|
||||
|
||||
""")
|
||||
|
||||
emit_table(f, "grapheme_cat_table", grapheme_table, "&'static [(char, char, GraphemeCat)]",
|
||||
pfun=lambda x: "(%s,%s,GC_%s)" % (escape_char(x[0]), escape_char(x[1]), x[2]),
|
||||
is_pub=False)
|
||||
f.write("}\n")
|
||||
|
||||
def emit_charwidth_module(f, width_table):
|
||||
f.write("pub mod charwidth {\n")
|
||||
f.write(" use core::option::Option;\n")
|
||||
|
@ -497,79 +457,6 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
|
|||
canon_comp_keys = canon_comp.keys()
|
||||
canon_comp_keys.sort()
|
||||
|
||||
f.write("pub mod normalization {\n")
|
||||
|
||||
def mkdata_fun(table):
|
||||
def f(char):
|
||||
data = "(%s,&[" % escape_char(char)
|
||||
first = True
|
||||
for d in table[char]:
|
||||
if not first:
|
||||
data += ","
|
||||
first = False
|
||||
data += escape_char(d)
|
||||
data += "])"
|
||||
return data
|
||||
return f
|
||||
|
||||
f.write(" // Canonical decompositions\n")
|
||||
emit_table(f, "canonical_table", canon_keys, "&'static [(char, &'static [char])]",
|
||||
pfun=mkdata_fun(canon))
|
||||
|
||||
f.write(" // Compatibility decompositions\n")
|
||||
emit_table(f, "compatibility_table", compat_keys, "&'static [(char, &'static [char])]",
|
||||
pfun=mkdata_fun(compat))
|
||||
|
||||
def comp_pfun(char):
|
||||
data = "(%s,&[" % escape_char(char)
|
||||
canon_comp[char].sort(lambda x, y: x[0] - y[0])
|
||||
first = True
|
||||
for pair in canon_comp[char]:
|
||||
if not first:
|
||||
data += ","
|
||||
first = False
|
||||
data += "(%s,%s)" % (escape_char(pair[0]), escape_char(pair[1]))
|
||||
data += "])"
|
||||
return data
|
||||
|
||||
f.write(" // Canonical compositions\n")
|
||||
emit_table(f, "composition_table", canon_comp_keys,
|
||||
"&'static [(char, &'static [(char, char)])]", pfun=comp_pfun)
|
||||
|
||||
f.write("""
|
||||
fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
|
||||
use core::cmp::Ordering::{Equal, Less, Greater};
|
||||
use core::slice::SliceExt;
|
||||
use core::result::Result::{Ok, Err};
|
||||
match r.binary_search_by(|&(lo, hi, _)| {
|
||||
if lo <= c && c <= hi { Equal }
|
||||
else if hi < c { Less }
|
||||
else { Greater }
|
||||
}) {
|
||||
Ok(idx) => {
|
||||
let (_, _, result) = r[idx];
|
||||
result
|
||||
}
|
||||
Err(_) => 0
|
||||
}
|
||||
}\n
|
||||
""")
|
||||
|
||||
emit_table(f, "combining_class_table", combine, "&'static [(char, char, u8)]", is_pub=False,
|
||||
pfun=lambda x: "(%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2]))
|
||||
|
||||
f.write(""" #[deprecated(reason = "use the crates.io `unicode-normalization` lib instead",
|
||||
since = "1.0.0")]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality will be moved to crates.io")]
|
||||
pub fn canonical_combining_class(c: char) -> u8 {
|
||||
bsearch_range_value_table(c, combining_class_table)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
""")
|
||||
|
||||
def remove_from_wtable(wtable, val):
|
||||
wtable_out = []
|
||||
while wtable:
|
||||
|
@ -649,53 +536,3 @@ pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
|
|||
# normalizations and conversions module
|
||||
emit_norm_module(rf, canon_decomp, compat_decomp, combines, norm_props)
|
||||
emit_conversions_module(rf, to_upper, to_lower, to_title)
|
||||
|
||||
### character width module
|
||||
width_table = []
|
||||
for zwcat in ["Me", "Mn", "Cf"]:
|
||||
width_table.extend(map(lambda (lo, hi): (lo, hi, 0, 0), gencats[zwcat]))
|
||||
width_table.append((4448, 4607, 0, 0))
|
||||
|
||||
# get widths, except those that are explicitly marked zero-width above
|
||||
ea_widths = load_east_asian_width(["W", "F", "A"], ["Me", "Mn", "Cf"])
|
||||
# these are doublewidth
|
||||
for dwcat in ["W", "F"]:
|
||||
width_table.extend(map(lambda (lo, hi): (lo, hi, 2, 2), ea_widths[dwcat]))
|
||||
width_table.extend(map(lambda (lo, hi): (lo, hi, 1, 2), ea_widths["A"]))
|
||||
|
||||
width_table.sort(key=lambda w: w[0])
|
||||
|
||||
# soft hyphen is not zero width in preformatted text; it's used to indicate
|
||||
# a hyphen inserted to facilitate a linebreak.
|
||||
width_table = remove_from_wtable(width_table, 173)
|
||||
|
||||
# optimize the width table by collapsing adjacent entities when possible
|
||||
width_table = optimize_width_table(width_table)
|
||||
emit_charwidth_module(rf, width_table)
|
||||
|
||||
### grapheme cluster module
|
||||
# from http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Break_Property_Values
|
||||
grapheme_cats = load_properties("auxiliary/GraphemeBreakProperty.txt", [])
|
||||
|
||||
# Control
|
||||
# Note 1:
|
||||
# This category also includes Cs (surrogate codepoints), but Rust's `char`s are
|
||||
# Unicode Scalar Values only, and surrogates are thus invalid `char`s.
|
||||
# Thus, we have to remove Cs from the Control category
|
||||
# Note 2:
|
||||
# 0x0a and 0x0d (CR and LF) are not in the Control category for Graphemes.
|
||||
# However, the Graphemes iterator treats these as a special case, so they
|
||||
# should be included in grapheme_cats["Control"] for our implementation.
|
||||
grapheme_cats["Control"] = group_cat(list(
|
||||
(set(ungroup_cat(grapheme_cats["Control"]))
|
||||
| set(ungroup_cat(grapheme_cats["CR"]))
|
||||
| set(ungroup_cat(grapheme_cats["LF"])))
|
||||
- set(ungroup_cat([surrogate_codepoints]))))
|
||||
del(grapheme_cats["CR"])
|
||||
del(grapheme_cats["LF"])
|
||||
|
||||
grapheme_table = []
|
||||
for cat in grapheme_cats:
|
||||
grapheme_table.extend([(x, y, cat) for (x, y) in grapheme_cats[cat]])
|
||||
grapheme_table.sort(key=lambda w: w[0])
|
||||
emit_grapheme_module(rf, grapheme_table, grapheme_cats.keys())
|
||||
|
|
|
@ -272,18 +272,6 @@ impl<T: ?Sized> Arc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the number of weak references to this value.
|
||||
#[inline]
|
||||
#[unstable(feature = "arc_counts")]
|
||||
#[deprecated(since = "1.2.0", reason = "renamed to Arc::weak_count")]
|
||||
pub fn weak_count<T: ?Sized>(this: &Arc<T>) -> usize { Arc::weak_count(this) }
|
||||
|
||||
/// Get the number of strong references to this value.
|
||||
#[inline]
|
||||
#[unstable(feature = "arc_counts")]
|
||||
#[deprecated(since = "1.2.0", reason = "renamed to Arc::strong_count")]
|
||||
pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { Arc::strong_count(this) }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Clone for Arc<T> {
|
||||
/// Makes a clone of the `Arc<T>`.
|
||||
|
@ -484,13 +472,6 @@ impl<T: ?Sized> Arc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "arc_unique")]
|
||||
#[deprecated(since = "1.2", reason = "use Arc::get_mut instead")]
|
||||
pub fn get_mut<T: ?Sized>(this: &mut Arc<T>) -> Option<&mut T> {
|
||||
Arc::get_mut(this)
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Drop for Arc<T> {
|
||||
/// Drops the `Arc<T>`.
|
||||
|
@ -860,7 +841,7 @@ mod tests {
|
|||
use std::sync::atomic::Ordering::{Acquire, SeqCst};
|
||||
use std::thread;
|
||||
use std::vec::Vec;
|
||||
use super::{Arc, Weak, get_mut, weak_count, strong_count};
|
||||
use super::{Arc, Weak};
|
||||
use std::sync::Mutex;
|
||||
|
||||
struct Canary(*mut atomic::AtomicUsize);
|
||||
|
@ -898,43 +879,39 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_arc_get_mut() {
|
||||
unsafe {
|
||||
let mut x = Arc::new(3);
|
||||
*get_mut(&mut x).unwrap() = 4;
|
||||
assert_eq!(*x, 4);
|
||||
let y = x.clone();
|
||||
assert!(get_mut(&mut x).is_none());
|
||||
drop(y);
|
||||
assert!(get_mut(&mut x).is_some());
|
||||
let _w = x.downgrade();
|
||||
assert!(get_mut(&mut x).is_none());
|
||||
}
|
||||
let mut x = Arc::new(3);
|
||||
*Arc::get_mut(&mut x).unwrap() = 4;
|
||||
assert_eq!(*x, 4);
|
||||
let y = x.clone();
|
||||
assert!(Arc::get_mut(&mut x).is_none());
|
||||
drop(y);
|
||||
assert!(Arc::get_mut(&mut x).is_some());
|
||||
let _w = x.downgrade();
|
||||
assert!(Arc::get_mut(&mut x).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cowarc_clone_make_unique() {
|
||||
unsafe {
|
||||
let mut cow0 = Arc::new(75);
|
||||
let mut cow1 = cow0.clone();
|
||||
let mut cow2 = cow1.clone();
|
||||
let mut cow0 = Arc::new(75);
|
||||
let mut cow1 = cow0.clone();
|
||||
let mut cow2 = cow1.clone();
|
||||
|
||||
assert!(75 == *Arc::make_unique(&mut cow0));
|
||||
assert!(75 == *Arc::make_unique(&mut cow1));
|
||||
assert!(75 == *Arc::make_unique(&mut cow2));
|
||||
assert!(75 == *Arc::make_unique(&mut cow0));
|
||||
assert!(75 == *Arc::make_unique(&mut cow1));
|
||||
assert!(75 == *Arc::make_unique(&mut cow2));
|
||||
|
||||
*Arc::make_unique(&mut cow0) += 1;
|
||||
*Arc::make_unique(&mut cow1) += 2;
|
||||
*Arc::make_unique(&mut cow2) += 3;
|
||||
*Arc::make_unique(&mut cow0) += 1;
|
||||
*Arc::make_unique(&mut cow1) += 2;
|
||||
*Arc::make_unique(&mut cow2) += 3;
|
||||
|
||||
assert!(76 == *cow0);
|
||||
assert!(77 == *cow1);
|
||||
assert!(78 == *cow2);
|
||||
assert!(76 == *cow0);
|
||||
assert!(77 == *cow1);
|
||||
assert!(78 == *cow2);
|
||||
|
||||
// none should point to the same backing memory
|
||||
assert!(*cow0 != *cow1);
|
||||
assert!(*cow0 != *cow2);
|
||||
assert!(*cow1 != *cow2);
|
||||
}
|
||||
// none should point to the same backing memory
|
||||
assert!(*cow0 != *cow1);
|
||||
assert!(*cow0 != *cow2);
|
||||
assert!(*cow1 != *cow2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -947,9 +924,7 @@ mod tests {
|
|||
assert!(75 == *cow1);
|
||||
assert!(75 == *cow2);
|
||||
|
||||
unsafe {
|
||||
*Arc::make_unique(&mut cow0) += 1;
|
||||
}
|
||||
*Arc::make_unique(&mut cow0) += 1;
|
||||
|
||||
assert!(76 == *cow0);
|
||||
assert!(75 == *cow1);
|
||||
|
@ -970,9 +945,7 @@ mod tests {
|
|||
assert!(75 == *cow0);
|
||||
assert!(75 == *cow1_weak.upgrade().unwrap());
|
||||
|
||||
unsafe {
|
||||
*Arc::make_unique(&mut cow0) += 1;
|
||||
}
|
||||
*Arc::make_unique(&mut cow0) += 1;
|
||||
|
||||
assert!(76 == *cow0);
|
||||
assert!(cow1_weak.upgrade().is_none());
|
||||
|
@ -1028,40 +1001,40 @@ mod tests {
|
|||
#[test]
|
||||
fn test_strong_count() {
|
||||
let a = Arc::new(0u32);
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(Arc::strong_count(&a) == 1);
|
||||
let w = a.downgrade();
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(Arc::strong_count(&a) == 1);
|
||||
let b = w.upgrade().expect("");
|
||||
assert!(strong_count(&b) == 2);
|
||||
assert!(strong_count(&a) == 2);
|
||||
assert!(Arc::strong_count(&b) == 2);
|
||||
assert!(Arc::strong_count(&a) == 2);
|
||||
drop(w);
|
||||
drop(a);
|
||||
assert!(strong_count(&b) == 1);
|
||||
assert!(Arc::strong_count(&b) == 1);
|
||||
let c = b.clone();
|
||||
assert!(strong_count(&b) == 2);
|
||||
assert!(strong_count(&c) == 2);
|
||||
assert!(Arc::strong_count(&b) == 2);
|
||||
assert!(Arc::strong_count(&c) == 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weak_count() {
|
||||
let a = Arc::new(0u32);
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(weak_count(&a) == 0);
|
||||
assert!(Arc::strong_count(&a) == 1);
|
||||
assert!(Arc::weak_count(&a) == 0);
|
||||
let w = a.downgrade();
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(weak_count(&a) == 1);
|
||||
assert!(Arc::strong_count(&a) == 1);
|
||||
assert!(Arc::weak_count(&a) == 1);
|
||||
let x = w.clone();
|
||||
assert!(weak_count(&a) == 2);
|
||||
assert!(Arc::weak_count(&a) == 2);
|
||||
drop(w);
|
||||
drop(x);
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(weak_count(&a) == 0);
|
||||
assert!(Arc::strong_count(&a) == 1);
|
||||
assert!(Arc::weak_count(&a) == 0);
|
||||
let c = a.clone();
|
||||
assert!(strong_count(&a) == 2);
|
||||
assert!(weak_count(&a) == 0);
|
||||
assert!(Arc::strong_count(&a) == 2);
|
||||
assert!(Arc::weak_count(&a) == 0);
|
||||
let d = c.downgrade();
|
||||
assert!(weak_count(&c) == 1);
|
||||
assert!(strong_count(&c) == 2);
|
||||
assert!(Arc::weak_count(&c) == 1);
|
||||
assert!(Arc::strong_count(&c) == 2);
|
||||
|
||||
drop(a);
|
||||
drop(c);
|
||||
|
|
|
@ -86,7 +86,6 @@ use core::raw::{TraitObject};
|
|||
#[lang = "exchange_heap"]
|
||||
#[unstable(feature = "box_heap",
|
||||
reason = "may be renamed; uncertain about custom allocator design")]
|
||||
#[allow(deprecated)]
|
||||
pub const HEAP: ExchangeHeapSingleton =
|
||||
ExchangeHeapSingleton { _force_singleton: () };
|
||||
|
||||
|
@ -254,31 +253,6 @@ impl<T : ?Sized> Box<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Consumes the `Box`, returning the wrapped raw pointer.
|
||||
///
|
||||
/// After call to this function, caller is responsible for the memory
|
||||
/// previously managed by `Box`, in particular caller should properly
|
||||
/// destroy `T` and release memory. The proper way to do it is to
|
||||
/// convert pointer back to `Box` with `Box::from_raw` function, because
|
||||
/// `Box` does not specify, how memory is allocated.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// #![feature(box_raw)]
|
||||
///
|
||||
/// use std::boxed;
|
||||
///
|
||||
/// let seventeen = Box::new(17u32);
|
||||
/// let raw = boxed::into_raw(seventeen);
|
||||
/// let boxed_again = unsafe { Box::from_raw(raw) };
|
||||
/// ```
|
||||
#[unstable(feature = "box_raw", reason = "may be renamed")]
|
||||
#[deprecated(since = "1.2.0", reason = "renamed to Box::into_raw")]
|
||||
#[inline]
|
||||
pub fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T {
|
||||
Box::into_raw(b)
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Default> Default for Box<T> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
#![feature(core_slice_ext)]
|
||||
#![feature(core_str_ext)]
|
||||
|
||||
#![cfg_attr(test, feature(test, alloc, rustc_private, box_raw))]
|
||||
#![cfg_attr(test, feature(test, rustc_private, box_raw))]
|
||||
#![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
|
||||
feature(libc))]
|
||||
|
||||
|
|
|
@ -338,84 +338,6 @@ impl<T: ?Sized> Rc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the number of weak references to this value.
|
||||
#[inline]
|
||||
#[unstable(feature = "rc_counts")]
|
||||
#[deprecated(since = "1.2.0", reason = "renamed to Rc::weak_count")]
|
||||
pub fn weak_count<T: ?Sized>(this: &Rc<T>) -> usize { Rc::weak_count(this) }
|
||||
|
||||
/// Get the number of strong references to this value.
|
||||
#[inline]
|
||||
#[unstable(feature = "rc_counts")]
|
||||
#[deprecated(since = "1.2.0", reason = "renamed to Rc::strong_count")]
|
||||
pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { Rc::strong_count(this) }
|
||||
|
||||
/// Returns true if there are no other `Rc` or `Weak<T>` values that share the
|
||||
/// same inner value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(rc_unique)]
|
||||
///
|
||||
/// use std::rc;
|
||||
/// use std::rc::Rc;
|
||||
///
|
||||
/// let five = Rc::new(5);
|
||||
///
|
||||
/// rc::is_unique(&five);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "rc_unique")]
|
||||
#[deprecated(since = "1.2.0", reason = "renamed to Rc::is_unique")]
|
||||
pub fn is_unique<T>(rc: &Rc<T>) -> bool { Rc::is_unique(rc) }
|
||||
|
||||
/// Unwraps the contained value if the `Rc<T>` is unique.
|
||||
///
|
||||
/// If the `Rc<T>` is not unique, an `Err` is returned with the same `Rc<T>`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(rc_unique)]
|
||||
///
|
||||
/// use std::rc::{self, Rc};
|
||||
///
|
||||
/// let x = Rc::new(3);
|
||||
/// assert_eq!(rc::try_unwrap(x), Ok(3));
|
||||
///
|
||||
/// let x = Rc::new(4);
|
||||
/// let _y = x.clone();
|
||||
/// assert_eq!(rc::try_unwrap(x), Err(Rc::new(4)));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "rc_unique")]
|
||||
#[deprecated(since = "1.2.0", reason = "renamed to Rc::try_unwrap")]
|
||||
pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> { Rc::try_unwrap(rc) }
|
||||
|
||||
/// Returns a mutable reference to the contained value if the `Rc<T>` is unique.
|
||||
///
|
||||
/// Returns `None` if the `Rc<T>` is not unique.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(rc_unique)]
|
||||
///
|
||||
/// use std::rc::{self, Rc};
|
||||
///
|
||||
/// let mut x = Rc::new(3);
|
||||
/// *rc::get_mut(&mut x).unwrap() = 4;
|
||||
/// assert_eq!(*x, 4);
|
||||
///
|
||||
/// let _y = x.clone();
|
||||
/// assert!(rc::get_mut(&mut x).is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "rc_unique")]
|
||||
#[deprecated(since = "1.2.0", reason = "renamed to Rc::get_mut")]
|
||||
pub fn get_mut<T>(rc: &mut Rc<T>) -> Option<&mut T> { Rc::get_mut(rc) }
|
||||
|
||||
impl<T: Clone> Rc<T> {
|
||||
/// Make a mutable reference from the given `Rc<T>`.
|
||||
///
|
||||
|
@ -922,7 +844,7 @@ impl<T: ?Sized> RcBoxPtr<T> for Weak<T> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Rc, Weak, weak_count, strong_count};
|
||||
use super::{Rc, Weak};
|
||||
use std::boxed::Box;
|
||||
use std::cell::RefCell;
|
||||
use std::option::Option;
|
||||
|
@ -990,74 +912,74 @@ mod tests {
|
|||
#[test]
|
||||
fn is_unique() {
|
||||
let x = Rc::new(3);
|
||||
assert!(super::is_unique(&x));
|
||||
assert!(Rc::is_unique(&x));
|
||||
let y = x.clone();
|
||||
assert!(!super::is_unique(&x));
|
||||
assert!(!Rc::is_unique(&x));
|
||||
drop(y);
|
||||
assert!(super::is_unique(&x));
|
||||
assert!(Rc::is_unique(&x));
|
||||
let w = x.downgrade();
|
||||
assert!(!super::is_unique(&x));
|
||||
assert!(!Rc::is_unique(&x));
|
||||
drop(w);
|
||||
assert!(super::is_unique(&x));
|
||||
assert!(Rc::is_unique(&x));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_strong_count() {
|
||||
let a = Rc::new(0u32);
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(Rc::strong_count(&a) == 1);
|
||||
let w = a.downgrade();
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(Rc::strong_count(&a) == 1);
|
||||
let b = w.upgrade().expect("upgrade of live rc failed");
|
||||
assert!(strong_count(&b) == 2);
|
||||
assert!(strong_count(&a) == 2);
|
||||
assert!(Rc::strong_count(&b) == 2);
|
||||
assert!(Rc::strong_count(&a) == 2);
|
||||
drop(w);
|
||||
drop(a);
|
||||
assert!(strong_count(&b) == 1);
|
||||
assert!(Rc::strong_count(&b) == 1);
|
||||
let c = b.clone();
|
||||
assert!(strong_count(&b) == 2);
|
||||
assert!(strong_count(&c) == 2);
|
||||
assert!(Rc::strong_count(&b) == 2);
|
||||
assert!(Rc::strong_count(&c) == 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weak_count() {
|
||||
let a = Rc::new(0u32);
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(weak_count(&a) == 0);
|
||||
assert!(Rc::strong_count(&a) == 1);
|
||||
assert!(Rc::weak_count(&a) == 0);
|
||||
let w = a.downgrade();
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(weak_count(&a) == 1);
|
||||
assert!(Rc::strong_count(&a) == 1);
|
||||
assert!(Rc::weak_count(&a) == 1);
|
||||
drop(w);
|
||||
assert!(strong_count(&a) == 1);
|
||||
assert!(weak_count(&a) == 0);
|
||||
assert!(Rc::strong_count(&a) == 1);
|
||||
assert!(Rc::weak_count(&a) == 0);
|
||||
let c = a.clone();
|
||||
assert!(strong_count(&a) == 2);
|
||||
assert!(weak_count(&a) == 0);
|
||||
assert!(Rc::strong_count(&a) == 2);
|
||||
assert!(Rc::weak_count(&a) == 0);
|
||||
drop(c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_unwrap() {
|
||||
let x = Rc::new(3);
|
||||
assert_eq!(super::try_unwrap(x), Ok(3));
|
||||
assert_eq!(Rc::try_unwrap(x), Ok(3));
|
||||
let x = Rc::new(4);
|
||||
let _y = x.clone();
|
||||
assert_eq!(super::try_unwrap(x), Err(Rc::new(4)));
|
||||
assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4)));
|
||||
let x = Rc::new(5);
|
||||
let _w = x.downgrade();
|
||||
assert_eq!(super::try_unwrap(x), Err(Rc::new(5)));
|
||||
assert_eq!(Rc::try_unwrap(x), Err(Rc::new(5)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_mut() {
|
||||
let mut x = Rc::new(3);
|
||||
*super::get_mut(&mut x).unwrap() = 4;
|
||||
*Rc::get_mut(&mut x).unwrap() = 4;
|
||||
assert_eq!(*x, 4);
|
||||
let y = x.clone();
|
||||
assert!(super::get_mut(&mut x).is_none());
|
||||
assert!(Rc::get_mut(&mut x).is_none());
|
||||
drop(y);
|
||||
assert!(super::get_mut(&mut x).is_some());
|
||||
assert!(Rc::get_mut(&mut x).is_some());
|
||||
let _w = x.downgrade();
|
||||
assert!(super::get_mut(&mut x).is_none());
|
||||
assert!(Rc::get_mut(&mut x).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1145,18 +1145,6 @@ impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
|
|||
}
|
||||
|
||||
impl<'a, K: Ord, V> Entry<'a, K, V> {
|
||||
#[unstable(feature = "entry",
|
||||
reason = "will soon be replaced by or_insert")]
|
||||
#[deprecated(since = "1.0",
|
||||
reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
|
||||
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
|
||||
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
|
||||
match self {
|
||||
Occupied(entry) => Ok(entry.into_mut()),
|
||||
Vacant(entry) => Err(entry),
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
/// Ensures a value is in the entry by inserting the default if empty, and returns
|
||||
/// a mutable reference to the value in the entry.
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
#![feature(core_slice_ext)]
|
||||
#![feature(core_str_ext)]
|
||||
#![feature(heap_api)]
|
||||
#![feature(iter_cmp)]
|
||||
#![feature(iter_idx)]
|
||||
#![feature(iter_order)]
|
||||
#![feature(iter_arith)]
|
||||
#![feature(iter_arith)]
|
||||
|
@ -58,7 +56,6 @@
|
|||
#![feature(unsafe_no_drop_flag, filling_drop)]
|
||||
#![feature(utf8_error)]
|
||||
#![cfg_attr(test, feature(rand, test))]
|
||||
#![cfg_attr(not(test), feature(str_words))]
|
||||
|
||||
#![feature(no_std)]
|
||||
#![no_std]
|
||||
|
@ -70,10 +67,6 @@ extern crate alloc;
|
|||
#[cfg(test)] extern crate test;
|
||||
|
||||
pub use binary_heap::BinaryHeap;
|
||||
#[allow(deprecated)]
|
||||
pub use bit_vec::BitVec;
|
||||
#[allow(deprecated)]
|
||||
pub use bit_set::BitSet;
|
||||
pub use btree_map::BTreeMap;
|
||||
pub use btree_set::BTreeSet;
|
||||
pub use linked_list::LinkedList;
|
||||
|
@ -81,8 +74,6 @@ pub use enum_set::EnumSet;
|
|||
pub use vec_deque::VecDeque;
|
||||
pub use string::String;
|
||||
pub use vec::Vec;
|
||||
#[allow(deprecated)]
|
||||
pub use vec_map::VecMap;
|
||||
|
||||
// Needed for the vec! macro
|
||||
pub use alloc::boxed;
|
||||
|
@ -91,7 +82,6 @@ pub use alloc::boxed;
|
|||
mod macros;
|
||||
|
||||
pub mod binary_heap;
|
||||
mod bit;
|
||||
mod btree;
|
||||
pub mod borrow;
|
||||
pub mod enum_set;
|
||||
|
@ -103,21 +93,6 @@ pub mod str;
|
|||
pub mod string;
|
||||
pub mod vec;
|
||||
pub mod vec_deque;
|
||||
#[allow(deprecated)]
|
||||
pub mod vec_map;
|
||||
|
||||
#[unstable(feature = "bitvec", reason = "RFC 509")]
|
||||
pub mod bit_vec {
|
||||
#![allow(deprecated)]
|
||||
pub use bit::{BitVec, Iter};
|
||||
}
|
||||
|
||||
#[unstable(feature = "bitset", reason = "RFC 509")]
|
||||
pub mod bit_set {
|
||||
#![allow(deprecated)]
|
||||
pub use bit::{BitSet, Union, Intersection, Difference, SymmetricDifference};
|
||||
pub use bit::SetIter as Iter;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub mod btree_map {
|
||||
|
|
|
@ -98,14 +98,13 @@ use core::option::Option::{self, Some, None};
|
|||
use core::ptr;
|
||||
use core::result::Result;
|
||||
use core::slice as core_slice;
|
||||
use self::Direction::*;
|
||||
|
||||
use borrow::{Borrow, BorrowMut, ToOwned};
|
||||
use vec::Vec;
|
||||
|
||||
pub use core::slice::{Chunks, Windows};
|
||||
pub use core::slice::{Iter, IterMut};
|
||||
pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split};
|
||||
pub use core::slice::{SplitMut, ChunksMut, Split};
|
||||
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
|
||||
pub use core::slice::{bytes, mut_ref_slice, ref_slice};
|
||||
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
|
||||
|
@ -141,8 +140,6 @@ mod hack {
|
|||
use string::ToString;
|
||||
use vec::Vec;
|
||||
|
||||
use super::{ElementSwaps, Permutations};
|
||||
|
||||
pub fn into_vec<T>(mut b: Box<[T]>) -> Vec<T> {
|
||||
unsafe {
|
||||
let xs = Vec::from_raw_parts(b.as_mut_ptr(), b.len(), b.len());
|
||||
|
@ -151,76 +148,12 @@ mod hack {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub fn permutations<T>(s: &[T]) -> Permutations<T> where T: Clone {
|
||||
Permutations{
|
||||
swaps: ElementSwaps::new(s.len()),
|
||||
v: to_vec(s),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_vec<T>(s: &[T]) -> Vec<T> where T: Clone {
|
||||
let mut vector = Vec::with_capacity(s.len());
|
||||
vector.push_all(s);
|
||||
vector
|
||||
}
|
||||
|
||||
// NB we can remove this hack if we move this test to libcollectionstest -
|
||||
// but that can't be done right now because the test needs access to the
|
||||
// private fields of Permutations
|
||||
#[test]
|
||||
fn test_permutations() {
|
||||
{
|
||||
let v: [i32; 0] = [];
|
||||
let mut it = permutations(&v);
|
||||
let (min_size, max_opt) = it.size_hint();
|
||||
assert_eq!(min_size, 1);
|
||||
assert_eq!(max_opt.unwrap(), 1);
|
||||
assert_eq!(it.next(), Some(to_vec(&v)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
{
|
||||
let v = ["Hello".to_string()];
|
||||
let mut it = permutations(&v);
|
||||
let (min_size, max_opt) = it.size_hint();
|
||||
assert_eq!(min_size, 1);
|
||||
assert_eq!(max_opt.unwrap(), 1);
|
||||
assert_eq!(it.next(), Some(to_vec(&v)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
{
|
||||
let v = [1, 2, 3];
|
||||
let mut it = permutations(&v);
|
||||
let (min_size, max_opt) = it.size_hint();
|
||||
assert_eq!(min_size, 3*2);
|
||||
assert_eq!(max_opt.unwrap(), 3*2);
|
||||
assert_eq!(it.next().unwrap(), [1,2,3]);
|
||||
assert_eq!(it.next().unwrap(), [1,3,2]);
|
||||
assert_eq!(it.next().unwrap(), [3,1,2]);
|
||||
let (min_size, max_opt) = it.size_hint();
|
||||
assert_eq!(min_size, 3);
|
||||
assert_eq!(max_opt.unwrap(), 3);
|
||||
assert_eq!(it.next().unwrap(), [3,2,1]);
|
||||
assert_eq!(it.next().unwrap(), [2,3,1]);
|
||||
assert_eq!(it.next().unwrap(), [2,1,3]);
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
{
|
||||
// check that we have N! permutations
|
||||
let v = ['A', 'B', 'C', 'D', 'E', 'F'];
|
||||
let mut amt = 0;
|
||||
let mut it = permutations(&v);
|
||||
let (min_size, max_opt) = it.size_hint();
|
||||
for _perm in it.by_ref() {
|
||||
amt += 1;
|
||||
}
|
||||
assert_eq!(amt, it.swaps.swaps_made);
|
||||
assert_eq!(amt, min_size);
|
||||
assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
|
||||
assert_eq!(amt, max_opt.unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Allocating extension methods for slices.
|
||||
|
@ -280,14 +213,6 @@ impl<T> [T] {
|
|||
core_slice::SliceExt::first_mut(self)
|
||||
}
|
||||
|
||||
/// Returns all but the first element of a slice.
|
||||
#[unstable(feature = "slice_extras", reason = "likely to be renamed")]
|
||||
#[deprecated(since = "1.3.0", reason = "superseded by split_first")]
|
||||
#[inline]
|
||||
pub fn tail(&self) -> &[T] {
|
||||
core_slice::SliceExt::tail(self)
|
||||
}
|
||||
|
||||
/// Returns the first and all the rest of the elements of a slice.
|
||||
#[unstable(feature = "slice_splits", reason = "new API")]
|
||||
#[inline]
|
||||
|
@ -295,14 +220,6 @@ impl<T> [T] {
|
|||
core_slice::SliceExt::split_first(self)
|
||||
}
|
||||
|
||||
/// Returns all but the first element of a mutable slice
|
||||
#[unstable(feature = "slice_extras", reason = "likely to be renamed or removed")]
|
||||
#[deprecated(since = "1.3.0", reason = "superseded by split_first_mut")]
|
||||
#[inline]
|
||||
pub fn tail_mut(&mut self) -> &mut [T] {
|
||||
core_slice::SliceExt::tail_mut(self)
|
||||
}
|
||||
|
||||
/// Returns the first and all the rest of the elements of a slice.
|
||||
#[unstable(feature = "slice_splits", reason = "new API")]
|
||||
#[inline]
|
||||
|
@ -310,14 +227,6 @@ impl<T> [T] {
|
|||
core_slice::SliceExt::split_first_mut(self)
|
||||
}
|
||||
|
||||
/// Returns all but the last element of a slice.
|
||||
#[unstable(feature = "slice_extras", reason = "likely to be renamed")]
|
||||
#[deprecated(since = "1.3.0", reason = "superseded by split_last")]
|
||||
#[inline]
|
||||
pub fn init(&self) -> &[T] {
|
||||
core_slice::SliceExt::init(self)
|
||||
}
|
||||
|
||||
/// Returns the last and all the rest of the elements of a slice.
|
||||
#[unstable(feature = "slice_splits", reason = "new API")]
|
||||
#[inline]
|
||||
|
@ -326,14 +235,6 @@ impl<T> [T] {
|
|||
|
||||
}
|
||||
|
||||
/// Returns all but the last element of a mutable slice
|
||||
#[unstable(feature = "slice_extras", reason = "likely to be renamed or removed")]
|
||||
#[deprecated(since = "1.3.0", reason = "superseded by split_last_mut")]
|
||||
#[inline]
|
||||
pub fn init_mut(&mut self) -> &mut [T] {
|
||||
core_slice::SliceExt::init_mut(self)
|
||||
}
|
||||
|
||||
/// Returns the last and all the rest of the elements of a slice.
|
||||
#[unstable(feature = "slice_splits", since = "1.3.0")]
|
||||
#[inline]
|
||||
|
@ -760,22 +661,6 @@ impl<T> [T] {
|
|||
core_slice::SliceExt::ends_with(self, needle)
|
||||
}
|
||||
|
||||
/// Find the first index containing a matching value.
|
||||
#[unstable(feature = "slice_position_elem")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "less idiomatic than .iter().position()")]
|
||||
pub fn position_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
|
||||
core_slice::SliceExt::position_elem(self, t)
|
||||
}
|
||||
|
||||
/// Find the last index containing a matching value.
|
||||
#[unstable(feature = "slice_position_elem")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "less idiomatic than .iter().rev().position()")]
|
||||
pub fn rposition_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
|
||||
core_slice::SliceExt::rposition_elem(self, t)
|
||||
}
|
||||
|
||||
/// Binary search a sorted slice for a given element.
|
||||
///
|
||||
/// If the value is found then `Ok` is returned, containing the
|
||||
|
@ -881,95 +766,6 @@ impl<T> [T] {
|
|||
merge_sort(self, compare)
|
||||
}
|
||||
|
||||
/// Creates an iterator that yields every possible permutation of the
|
||||
/// vector in succession.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(permutations)]
|
||||
///
|
||||
/// let v = [1, 2, 3];
|
||||
/// let mut perms = v.permutations();
|
||||
///
|
||||
/// for p in perms {
|
||||
/// println!("{:?}", p);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Iterating through permutations one by one.
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(permutations)]
|
||||
///
|
||||
/// let v = [1, 2, 3];
|
||||
/// let mut perms = v.permutations();
|
||||
///
|
||||
/// assert_eq!(Some(vec![1, 2, 3]), perms.next());
|
||||
/// assert_eq!(Some(vec![1, 3, 2]), perms.next());
|
||||
/// assert_eq!(Some(vec![3, 1, 2]), perms.next());
|
||||
/// ```
|
||||
#[allow(deprecated)]
|
||||
#[unstable(feature = "permutations")]
|
||||
#[deprecated(since = "1.2.0", reason = "not clear this should be in the stdlib")]
|
||||
#[inline]
|
||||
pub fn permutations(&self) -> Permutations<T> where T: Clone {
|
||||
// NB see hack module in this file
|
||||
hack::permutations(self)
|
||||
}
|
||||
|
||||
/// Mutates the slice to the next lexicographic permutation.
|
||||
///
|
||||
/// Returns `true` if successful and `false` if the slice is at the
|
||||
/// last-ordered permutation.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(permutations)]
|
||||
///
|
||||
/// let v: &mut [_] = &mut [0, 1, 2];
|
||||
/// v.next_permutation();
|
||||
/// let b: &mut [_] = &mut [0, 2, 1];
|
||||
/// assert!(v == b);
|
||||
/// v.next_permutation();
|
||||
/// let b: &mut [_] = &mut [1, 0, 2];
|
||||
/// assert!(v == b);
|
||||
/// ```
|
||||
#[allow(deprecated)]
|
||||
#[unstable(feature = "permutations",
|
||||
reason = "uncertain if this merits inclusion in std")]
|
||||
#[deprecated(since = "1.2.0", reason = "not clear this should be in the stdlib")]
|
||||
pub fn next_permutation(&mut self) -> bool where T: Ord {
|
||||
core_slice::SliceExt::next_permutation(self)
|
||||
}
|
||||
|
||||
/// Mutates the slice to the previous lexicographic permutation.
|
||||
///
|
||||
/// Returns `true` if successful and `false` if the slice is at the
|
||||
/// first-ordered permutation.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(permutations)]
|
||||
///
|
||||
/// let v: &mut [_] = &mut [1, 0, 2];
|
||||
/// v.prev_permutation();
|
||||
/// let b: &mut [_] = &mut [0, 2, 1];
|
||||
/// assert!(v == b);
|
||||
/// v.prev_permutation();
|
||||
/// let b: &mut [_] = &mut [0, 1, 2];
|
||||
/// assert!(v == b);
|
||||
/// ```
|
||||
#[allow(deprecated)]
|
||||
#[unstable(feature = "permutations",
|
||||
reason = "uncertain if this merits inclusion in std")]
|
||||
#[deprecated(since = "1.2.0", reason = "not clear this should be in the stdlib")]
|
||||
pub fn prev_permutation(&mut self) -> bool where T: Ord {
|
||||
core_slice::SliceExt::prev_permutation(self)
|
||||
}
|
||||
|
||||
/// Copies as many elements from `src` as it can into `self` (the
|
||||
/// shorter of `self.len()` and `src.len()`). Returns the number
|
||||
/// of elements copied.
|
||||
|
@ -994,41 +790,6 @@ impl<T> [T] {
|
|||
core_slice::SliceExt::clone_from_slice(self, src)
|
||||
}
|
||||
|
||||
/// Consumes `src` and moves as many elements as it can into `self`
|
||||
/// from the range [start,end).
|
||||
///
|
||||
/// Returns the number of elements copied (the shorter of `self.len()`
|
||||
/// and `end - start`).
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * src - A mutable vector of `T`
|
||||
/// * start - The index into `src` to start copying from
|
||||
/// * end - The index into `src` to stop copying from
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(move_from)]
|
||||
///
|
||||
/// let mut a = [1, 2, 3, 4, 5];
|
||||
/// let b = vec![6, 7, 8];
|
||||
/// let num_moved = a.move_from(b, 0, 3);
|
||||
/// assert_eq!(num_moved, 3);
|
||||
/// assert!(a == [6, 7, 8, 4, 5]);
|
||||
/// ```
|
||||
#[unstable(feature = "move_from",
|
||||
reason = "uncertain about this API approach")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "unclear that it must belong in the standard library")]
|
||||
#[inline]
|
||||
pub fn move_from(&mut self, mut src: Vec<T>, start: usize, end: usize) -> usize {
|
||||
for (a, b) in self.iter_mut().zip(&mut src[start .. end]) {
|
||||
mem::swap(a, b);
|
||||
}
|
||||
cmp::min(self.len(), end-start)
|
||||
}
|
||||
|
||||
/// Copies `self` into a new `Vec`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
|
@ -1120,45 +881,6 @@ impl<T: Clone, V: Borrow<[T]>> SliceConcatExt<T> for [V] {
|
|||
}
|
||||
}
|
||||
|
||||
/// An iterator that yields the element swaps needed to produce
|
||||
/// a sequence of all possible permutations for an indexed sequence of
|
||||
/// elements. Each permutation is only a single swap apart.
|
||||
///
|
||||
/// The Steinhaus-Johnson-Trotter algorithm is used.
|
||||
///
|
||||
/// Generates even and odd permutations alternately.
|
||||
///
|
||||
/// The last generated swap is always (0, 1), and it returns the
|
||||
/// sequence to its initial order.
|
||||
#[allow(deprecated)]
|
||||
#[unstable(feature = "permutations")]
|
||||
#[derive(Clone)]
|
||||
#[deprecated(since = "1.2.0", reason = "not clear this should be in the stdlib")]
|
||||
pub struct ElementSwaps {
|
||||
sdir: Vec<SizeDirection>,
|
||||
/// If `true`, emit the last swap that returns the sequence to initial
|
||||
/// state.
|
||||
emit_reset: bool,
|
||||
swaps_made : usize,
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl ElementSwaps {
|
||||
/// Creates an `ElementSwaps` iterator for a sequence of `length` elements.
|
||||
#[unstable(feature = "permutations")]
|
||||
#[deprecated(since = "1.2.0", reason = "not clear this should be in the stdlib")]
|
||||
pub fn new(length: usize) -> ElementSwaps {
|
||||
// Initialize `sdir` with a direction that position should move in
|
||||
// (all negative at the beginning) and the `size` of the
|
||||
// element (equal to the original index).
|
||||
ElementSwaps{
|
||||
emit_reset: true,
|
||||
sdir: (0..length).map(|i| SizeDirection{ size: i, dir: Neg }).collect(),
|
||||
swaps_made: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Standard trait implementations for slices
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1187,120 +909,6 @@ impl<T: Clone> ToOwned for [T] {
|
|||
fn to_owned(&self) -> Vec<T> { panic!("not available with cfg(test)") }
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Direction { Pos, Neg }
|
||||
|
||||
/// An `Index` and `Direction` together.
|
||||
#[derive(Copy, Clone)]
|
||||
struct SizeDirection {
|
||||
size: usize,
|
||||
dir: Direction,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
impl Iterator for ElementSwaps {
|
||||
type Item = (usize, usize);
|
||||
|
||||
// #[inline]
|
||||
fn next(&mut self) -> Option<(usize, usize)> {
|
||||
fn new_pos_wrapping(i: usize, s: Direction) -> usize {
|
||||
i.wrapping_add(match s { Pos => 1, Neg => !0 /* aka -1 */ })
|
||||
}
|
||||
|
||||
fn new_pos(i: usize, s: Direction) -> usize {
|
||||
match s { Pos => i + 1, Neg => i - 1 }
|
||||
}
|
||||
|
||||
// Find the index of the largest mobile element:
|
||||
// The direction should point into the vector, and the
|
||||
// swap should be with a smaller `size` element.
|
||||
let max = self.sdir.iter().cloned().enumerate()
|
||||
.filter(|&(i, sd)|
|
||||
new_pos_wrapping(i, sd.dir) < self.sdir.len() &&
|
||||
self.sdir[new_pos(i, sd.dir)].size < sd.size)
|
||||
.max_by(|&(_, sd)| sd.size);
|
||||
match max {
|
||||
Some((i, sd)) => {
|
||||
let j = new_pos(i, sd.dir);
|
||||
self.sdir.swap(i, j);
|
||||
|
||||
// Swap the direction of each larger SizeDirection
|
||||
for x in &mut self.sdir {
|
||||
if x.size > sd.size {
|
||||
x.dir = match x.dir { Pos => Neg, Neg => Pos };
|
||||
}
|
||||
}
|
||||
self.swaps_made += 1;
|
||||
Some((i, j))
|
||||
},
|
||||
None => if self.emit_reset {
|
||||
self.emit_reset = false;
|
||||
if self.sdir.len() > 1 {
|
||||
// The last swap
|
||||
self.swaps_made += 1;
|
||||
Some((0, 1))
|
||||
} else {
|
||||
// Vector is of the form [] or [x], and the only permutation is itself
|
||||
self.swaps_made += 1;
|
||||
Some((0,0))
|
||||
}
|
||||
} else { None }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
// For a vector of size n, there are exactly n! permutations.
|
||||
let n: usize = (2..self.sdir.len() + 1).product();
|
||||
(n - self.swaps_made, Some(n - self.swaps_made))
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that uses `ElementSwaps` to iterate through
|
||||
/// all possible permutations of a vector.
|
||||
///
|
||||
/// The first iteration yields a clone of the vector as it is,
|
||||
/// then each successive element is the vector with one
|
||||
/// swap applied.
|
||||
///
|
||||
/// Generates even and odd permutations alternately.
|
||||
#[unstable(feature = "permutations")]
|
||||
#[deprecated(since = "1.2.0", reason = "not clear this should be in the stdlib")]
|
||||
#[allow(deprecated)]
|
||||
pub struct Permutations<T> {
|
||||
swaps: ElementSwaps,
|
||||
v: Vec<T>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "permutations", reason = "trait is unstable")]
|
||||
#[allow(deprecated)]
|
||||
impl<T: Clone> Iterator for Permutations<T> {
|
||||
type Item = Vec<T>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Vec<T>> {
|
||||
match self.swaps.next() {
|
||||
None => None,
|
||||
Some((0,0)) => Some(self.v.clone()),
|
||||
Some((a, b)) => {
|
||||
let elt = self.v.clone();
|
||||
self.v.swap(a, b);
|
||||
Some(elt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.swaps.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Sorting
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
// It's cleaner to just turn off the unused_imports warning than to fix them.
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use self::RecompositionState::*;
|
||||
use self::DecompositionType::*;
|
||||
|
||||
use core::clone::Clone;
|
||||
use core::iter::{Iterator, Extend};
|
||||
use core::option::Option::{self, Some, None};
|
||||
|
@ -49,7 +46,7 @@ pub use core::str::{Matches, RMatches};
|
|||
pub use core::str::{MatchIndices, RMatchIndices};
|
||||
pub use core::str::{from_utf8, Chars, CharIndices, Bytes};
|
||||
pub use core::str::{from_utf8_unchecked, ParseBoolError};
|
||||
pub use rustc_unicode::str::{SplitWhitespace, Words, Graphemes, GraphemeIndices};
|
||||
pub use rustc_unicode::str::{SplitWhitespace};
|
||||
pub use core::str::pattern;
|
||||
|
||||
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
||||
|
@ -104,230 +101,6 @@ impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
|||
}
|
||||
}
|
||||
|
||||
// Helper functions used for Unicode normalization
|
||||
fn canonical_sort(comb: &mut [(char, u8)]) {
|
||||
let len = comb.len();
|
||||
for i in 0..len {
|
||||
let mut swapped = false;
|
||||
for j in 1..len-i {
|
||||
let class_a = comb[j-1].1;
|
||||
let class_b = comb[j].1;
|
||||
if class_a != 0 && class_b != 0 && class_a > class_b {
|
||||
comb.swap(j-1, j);
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
if !swapped { break; }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum DecompositionType {
|
||||
Canonical,
|
||||
Compatible
|
||||
}
|
||||
|
||||
/// External iterator for a string decomposition's characters.
|
||||
///
|
||||
/// For use with the `std::iter` module.
|
||||
#[allow(deprecated)]
|
||||
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
|
||||
since = "1.0.0")]
|
||||
#[derive(Clone)]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality may be replaced with a more generic \
|
||||
unicode crate on crates.io")]
|
||||
pub struct Decompositions<'a> {
|
||||
kind: DecompositionType,
|
||||
iter: Chars<'a>,
|
||||
buffer: Vec<(char, u8)>,
|
||||
sorted: bool
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> Iterator for Decompositions<'a> {
|
||||
type Item = char;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<char> {
|
||||
match self.buffer.first() {
|
||||
Some(&(c, 0)) => {
|
||||
self.sorted = false;
|
||||
self.buffer.remove(0);
|
||||
return Some(c);
|
||||
}
|
||||
Some(&(c, _)) if self.sorted => {
|
||||
self.buffer.remove(0);
|
||||
return Some(c);
|
||||
}
|
||||
_ => self.sorted = false
|
||||
}
|
||||
|
||||
if !self.sorted {
|
||||
for ch in self.iter.by_ref() {
|
||||
let buffer = &mut self.buffer;
|
||||
let sorted = &mut self.sorted;
|
||||
{
|
||||
let callback = |d| {
|
||||
let class =
|
||||
rustc_unicode::char::canonical_combining_class(d);
|
||||
if class == 0 && !*sorted {
|
||||
canonical_sort(buffer);
|
||||
*sorted = true;
|
||||
}
|
||||
buffer.push((d, class));
|
||||
};
|
||||
match self.kind {
|
||||
Canonical => {
|
||||
rustc_unicode::char::decompose_canonical(ch, callback)
|
||||
}
|
||||
Compatible => {
|
||||
rustc_unicode::char::decompose_compatible(ch, callback)
|
||||
}
|
||||
}
|
||||
}
|
||||
if *sorted {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !self.sorted {
|
||||
canonical_sort(&mut self.buffer);
|
||||
self.sorted = true;
|
||||
}
|
||||
|
||||
if self.buffer.is_empty() {
|
||||
None
|
||||
} else {
|
||||
match self.buffer.remove(0) {
|
||||
(c, 0) => {
|
||||
self.sorted = false;
|
||||
Some(c)
|
||||
}
|
||||
(c, _) => Some(c),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let (lower, _) = self.iter.size_hint();
|
||||
(lower, None)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum RecompositionState {
|
||||
Composing,
|
||||
Purging,
|
||||
Finished
|
||||
}
|
||||
|
||||
/// External iterator for a string recomposition's characters.
|
||||
///
|
||||
/// For use with the `std::iter` module.
|
||||
#[allow(deprecated)]
|
||||
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
|
||||
since = "1.0.0")]
|
||||
#[derive(Clone)]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality may be replaced with a more generic \
|
||||
unicode crate on crates.io")]
|
||||
pub struct Recompositions<'a> {
|
||||
iter: Decompositions<'a>,
|
||||
state: RecompositionState,
|
||||
buffer: VecDeque<char>,
|
||||
composee: Option<char>,
|
||||
last_ccc: Option<u8>
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> Iterator for Recompositions<'a> {
|
||||
type Item = char;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<char> {
|
||||
loop {
|
||||
match self.state {
|
||||
Composing => {
|
||||
for ch in self.iter.by_ref() {
|
||||
let ch_class = rustc_unicode::char::canonical_combining_class(ch);
|
||||
if self.composee.is_none() {
|
||||
if ch_class != 0 {
|
||||
return Some(ch);
|
||||
}
|
||||
self.composee = Some(ch);
|
||||
continue;
|
||||
}
|
||||
let k = self.composee.clone().unwrap();
|
||||
|
||||
match self.last_ccc {
|
||||
None => {
|
||||
match rustc_unicode::char::compose(k, ch) {
|
||||
Some(r) => {
|
||||
self.composee = Some(r);
|
||||
continue;
|
||||
}
|
||||
None => {
|
||||
if ch_class == 0 {
|
||||
self.composee = Some(ch);
|
||||
return Some(k);
|
||||
}
|
||||
self.buffer.push_back(ch);
|
||||
self.last_ccc = Some(ch_class);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(l_class) => {
|
||||
if l_class >= ch_class {
|
||||
// `ch` is blocked from `composee`
|
||||
if ch_class == 0 {
|
||||
self.composee = Some(ch);
|
||||
self.last_ccc = None;
|
||||
self.state = Purging;
|
||||
return Some(k);
|
||||
}
|
||||
self.buffer.push_back(ch);
|
||||
self.last_ccc = Some(ch_class);
|
||||
continue;
|
||||
}
|
||||
match rustc_unicode::char::compose(k, ch) {
|
||||
Some(r) => {
|
||||
self.composee = Some(r);
|
||||
continue;
|
||||
}
|
||||
None => {
|
||||
self.buffer.push_back(ch);
|
||||
self.last_ccc = Some(ch_class);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.state = Finished;
|
||||
if self.composee.is_some() {
|
||||
return self.composee.take();
|
||||
}
|
||||
}
|
||||
Purging => {
|
||||
match self.buffer.pop_front() {
|
||||
None => self.state = Composing,
|
||||
s => return s
|
||||
}
|
||||
}
|
||||
Finished => {
|
||||
match self.buffer.pop_front() {
|
||||
None => return self.composee.take(),
|
||||
s => return s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// External iterator for a string's UTF16 codeunits.
|
||||
///
|
||||
/// For use with the `std::iter` module.
|
||||
|
@ -408,28 +181,6 @@ impl str {
|
|||
core_str::StrExt::is_empty(self)
|
||||
}
|
||||
|
||||
/// Returns a string's displayed width in columns.
|
||||
///
|
||||
/// Control characters have zero width.
|
||||
///
|
||||
/// `is_cjk` determines behavior for characters in the Ambiguous category:
|
||||
/// if `is_cjk` is
|
||||
/// `true`, these are 2 columns wide; otherwise, they are 1.
|
||||
/// In CJK locales, `is_cjk` should be
|
||||
/// `true`, else it should be `false`.
|
||||
/// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
|
||||
/// recommends that these
|
||||
/// characters be treated as 1 column (i.e., `is_cjk = false`) if the
|
||||
/// locale is unknown.
|
||||
#[deprecated(reason = "use the crates.io `unicode-width` library instead",
|
||||
since = "1.0.0")]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality may only be provided by libunicode")]
|
||||
#[inline]
|
||||
pub fn width(&self, is_cjk: bool) -> usize {
|
||||
UnicodeStr::width(self, is_cjk)
|
||||
}
|
||||
|
||||
/// Checks that `index`-th byte lies at the start and/or end of a
|
||||
/// UTF-8 code point sequence.
|
||||
///
|
||||
|
@ -530,42 +281,6 @@ impl str {
|
|||
core_str::StrExt::slice_mut_unchecked(self, begin, end)
|
||||
}
|
||||
|
||||
/// Returns a slice of the string from the range [`begin`..`end`) where indices
|
||||
/// are counted in code points.
|
||||
///
|
||||
/// That is, start at the `begin`-th code point of the string and continue
|
||||
/// to the `end`-th code point. This does not detect or handle edge cases
|
||||
/// such as leaving a combining character as the first `char` of the
|
||||
/// string.
|
||||
///
|
||||
/// Due to the design of UTF-8, this operation is `O(end)`. Use slicing
|
||||
/// syntax if you want to use `O(1)` byte indices instead.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `begin` > `end` or the either `begin` or `end` are beyond the
|
||||
/// last character of the string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(slice_chars)]
|
||||
///
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.slice_chars(0, 4), "Löwe");
|
||||
/// assert_eq!(s.slice_chars(5, 7), "老虎");
|
||||
/// ```
|
||||
#[unstable(feature = "slice_chars",
|
||||
reason = "may have yet to prove its worth")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "can be implemented with char_indices and \
|
||||
hasn't seen enough use to justify inclusion")]
|
||||
#[inline]
|
||||
pub fn slice_chars(&self, begin: usize, end: usize) -> &str {
|
||||
core_str::StrExt::slice_chars(self, begin, end)
|
||||
}
|
||||
|
||||
/// Given a byte position, return the next code point and its index.
|
||||
///
|
||||
/// This can be used to iterate over the Unicode code points of a string.
|
||||
|
@ -603,8 +318,8 @@ impl str {
|
|||
/// 6: V
|
||||
/// 7: i
|
||||
/// 8: e
|
||||
/// 9: ̣
|
||||
/// 11: ̂
|
||||
/// 9:
|
||||
/// 11:
|
||||
/// 13: t
|
||||
/// 14:
|
||||
/// 15: N
|
||||
|
@ -662,8 +377,8 @@ impl str {
|
|||
/// 16: N
|
||||
/// 15:
|
||||
/// 14: t
|
||||
/// 13: ̂
|
||||
/// 11: ̣
|
||||
/// 13:
|
||||
/// 11:
|
||||
/// 9: e
|
||||
/// 8: i
|
||||
/// 7: V
|
||||
|
@ -880,30 +595,6 @@ impl str {
|
|||
UnicodeStr::split_whitespace(self)
|
||||
}
|
||||
|
||||
/// An iterator over the non-empty substrings of `self` which contain no whitespace,
|
||||
/// and which are separated by any amount of whitespace.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(str_words)]
|
||||
/// #![allow(deprecated)]
|
||||
///
|
||||
/// let some_words = " Mary had\ta\u{2009}little \n\t lamb";
|
||||
/// let v: Vec<&str> = some_words.words().collect();
|
||||
///
|
||||
/// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
|
||||
/// ```
|
||||
#[deprecated(reason = "words() will be removed. Use split_whitespace() instead",
|
||||
since = "1.1.0")]
|
||||
#[unstable(feature = "str_words",
|
||||
reason = "the precise algorithm to use is unclear")]
|
||||
#[allow(deprecated)]
|
||||
#[inline]
|
||||
pub fn words(&self) -> Words {
|
||||
UnicodeStr::words(self)
|
||||
}
|
||||
|
||||
/// An iterator over the lines of a string, separated by `\n`.
|
||||
///
|
||||
/// This does not include the empty string after a trailing `\n`.
|
||||
|
@ -959,135 +650,6 @@ impl str {
|
|||
core_str::StrExt::lines_any(self)
|
||||
}
|
||||
|
||||
/// Returns an iterator over the string in Unicode Normalization Form D
|
||||
/// (canonical decomposition).
|
||||
#[allow(deprecated)]
|
||||
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
|
||||
since = "1.0.0")]
|
||||
#[inline]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality may be replaced with a more generic \
|
||||
unicode crate on crates.io")]
|
||||
pub fn nfd_chars(&self) -> Decompositions {
|
||||
Decompositions {
|
||||
iter: self[..].chars(),
|
||||
buffer: Vec::new(),
|
||||
sorted: false,
|
||||
kind: Canonical
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over the string in Unicode Normalization Form KD
|
||||
/// (compatibility decomposition).
|
||||
#[allow(deprecated)]
|
||||
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
|
||||
since = "1.0.0")]
|
||||
#[inline]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality may be replaced with a more generic \
|
||||
unicode crate on crates.io")]
|
||||
pub fn nfkd_chars(&self) -> Decompositions {
|
||||
Decompositions {
|
||||
iter: self[..].chars(),
|
||||
buffer: Vec::new(),
|
||||
sorted: false,
|
||||
kind: Compatible
|
||||
}
|
||||
}
|
||||
|
||||
/// An Iterator over the string in Unicode Normalization Form C
|
||||
/// (canonical decomposition followed by canonical composition).
|
||||
#[allow(deprecated)]
|
||||
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
|
||||
since = "1.0.0")]
|
||||
#[inline]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality may be replaced with a more generic \
|
||||
unicode crate on crates.io")]
|
||||
pub fn nfc_chars(&self) -> Recompositions {
|
||||
Recompositions {
|
||||
iter: self.nfd_chars(),
|
||||
state: Composing,
|
||||
buffer: VecDeque::new(),
|
||||
composee: None,
|
||||
last_ccc: None
|
||||
}
|
||||
}
|
||||
|
||||
/// An Iterator over the string in Unicode Normalization Form KC
|
||||
/// (compatibility decomposition followed by canonical composition).
|
||||
#[allow(deprecated)]
|
||||
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
|
||||
since = "1.0.0")]
|
||||
#[inline]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality may be replaced with a more generic \
|
||||
unicode crate on crates.io")]
|
||||
pub fn nfkc_chars(&self) -> Recompositions {
|
||||
Recompositions {
|
||||
iter: self.nfkd_chars(),
|
||||
state: Composing,
|
||||
buffer: VecDeque::new(),
|
||||
composee: None,
|
||||
last_ccc: None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over the [grapheme clusters][graphemes] of `self`.
|
||||
///
|
||||
/// [graphemes]: http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
|
||||
///
|
||||
/// If `is_extended` is true, the iterator is over the
|
||||
/// *extended grapheme clusters*;
|
||||
/// otherwise, the iterator is over the *legacy grapheme clusters*.
|
||||
/// [UAX#29](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
|
||||
/// recommends extended grapheme cluster boundaries for general processing.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(unicode, core)]
|
||||
///
|
||||
/// let gr1 = "a\u{310}e\u{301}o\u{308}\u{332}".graphemes(true).collect::<Vec<&str>>();
|
||||
/// let b: &[_] = &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"];
|
||||
///
|
||||
/// assert_eq!(&gr1[..], b);
|
||||
///
|
||||
/// let gr2 = "a\r\nb🇷🇺🇸🇹".graphemes(true).collect::<Vec<&str>>();
|
||||
/// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"];
|
||||
///
|
||||
/// assert_eq!(&gr2[..], b);
|
||||
/// ```
|
||||
#[deprecated(reason = "use the crates.io `unicode-segmentation` library instead",
|
||||
since = "1.0.0")]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality may only be provided by libunicode")]
|
||||
pub fn graphemes(&self, is_extended: bool) -> Graphemes {
|
||||
UnicodeStr::graphemes(self, is_extended)
|
||||
}
|
||||
|
||||
/// Returns an iterator over the grapheme clusters of `self` and their
|
||||
/// byte offsets. See
|
||||
/// `graphemes()` for more information.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(unicode, core)]
|
||||
///
|
||||
/// let gr_inds = "a̐éö̲\r\n".grapheme_indices(true).collect::<Vec<(usize, &str)>>();
|
||||
/// let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
|
||||
///
|
||||
/// assert_eq!(&gr_inds[..], b);
|
||||
/// ```
|
||||
#[deprecated(reason = "use the crates.io `unicode-segmentation` library instead",
|
||||
since = "1.0.0")]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality may only be provided by libunicode")]
|
||||
pub fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
|
||||
UnicodeStr::grapheme_indices(self, is_extended)
|
||||
}
|
||||
|
||||
/// Returns an iterator of `u16` over the string encoded as UTF-16.
|
||||
#[unstable(feature = "str_utf16",
|
||||
reason = "this functionality may only be provided by libunicode")]
|
||||
|
@ -1678,33 +1240,6 @@ impl str {
|
|||
core_str::StrExt::rmatch_indices(self, pat)
|
||||
}
|
||||
|
||||
/// Returns the byte offset of an inner slice relative to an enclosing
|
||||
/// outer slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `inner` is not a direct slice contained within self.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(subslice_offset)]
|
||||
///
|
||||
/// let string = "a\nb\nc";
|
||||
/// let lines: Vec<&str> = string.lines().collect();
|
||||
///
|
||||
/// assert!(string.subslice_offset(lines[0]) == 0); // &"a"
|
||||
/// assert!(string.subslice_offset(lines[1]) == 2); // &"b"
|
||||
/// assert!(string.subslice_offset(lines[2]) == 4); // &"c"
|
||||
/// ```
|
||||
#[unstable(feature = "subslice_offset",
|
||||
reason = "awaiting convention about comparability of arbitrary slices")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "replaced with other pattern-related methods")]
|
||||
pub fn subslice_offset(&self, inner: &str) -> usize {
|
||||
core_str::StrExt::subslice_offset(self, inner)
|
||||
}
|
||||
|
||||
/// Returns a `&str` with leading and trailing whitespace removed.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
|
@ -82,24 +82,6 @@ impl String {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a new string buffer from the given string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(collections)]
|
||||
///
|
||||
/// let s = String::from("hello");
|
||||
/// assert_eq!(&s[..], "hello");
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "collections", reason = "use `String::from` instead")]
|
||||
#[deprecated(since = "1.2.0", reason = "use `String::from` instead")]
|
||||
#[cfg(not(test))]
|
||||
pub fn from_str(string: &str) -> String {
|
||||
String { vec: <[_]>::to_vec(string.as_bytes()) }
|
||||
}
|
||||
|
||||
// HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
|
||||
// required for this method definition, is not available. Since we don't
|
||||
// require this method for testing purposes, I'll just stub it
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
//! let v = vec![0; 10]; // ten zeroes
|
||||
//! ```
|
||||
//!
|
||||
//! You can `push` values onto the end of a vector (which will grow the vector as needed):
|
||||
//! You can `push` values onto the end of a vector (which will grow the vector
|
||||
//! as needed):
|
||||
//!
|
||||
//! ```
|
||||
//! let mut v = vec![1, 2];
|
||||
|
@ -66,7 +67,6 @@ use core::fmt;
|
|||
use core::hash::{self, Hash};
|
||||
use core::intrinsics::{arith_offset, assume, drop_in_place};
|
||||
use core::iter::FromIterator;
|
||||
use core::marker::PhantomData;
|
||||
use core::mem;
|
||||
use core::ops::{Index, IndexMut, Deref};
|
||||
use core::ops;
|
||||
|
@ -177,12 +177,13 @@ impl<T> Vec<T> {
|
|||
|
||||
/// Constructs a new, empty `Vec<T>` with the specified capacity.
|
||||
///
|
||||
/// The vector will be able to hold exactly `capacity` elements without reallocating. If
|
||||
/// `capacity` is 0, the vector will not allocate.
|
||||
/// The vector will be able to hold exactly `capacity` elements without
|
||||
/// reallocating. If `capacity` is 0, the vector will not allocate.
|
||||
///
|
||||
/// It is important to note that this function does not specify the *length* of the returned
|
||||
/// vector, but only the *capacity*. (For an explanation of the difference between length and
|
||||
/// capacity, see the main `Vec<T>` docs above, 'Capacity and reallocation'.)
|
||||
/// It is important to note that this function does not specify the *length*
|
||||
/// of the returned vector, but only the *capacity*. (For an explanation of
|
||||
/// the difference between length and capacity, see the main `Vec<T>` docs
|
||||
/// above, 'Capacity and reallocation'.)
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -260,24 +261,6 @@ impl<T> Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a vector by copying the elements from a raw pointer.
|
||||
///
|
||||
/// This function will copy `elts` contiguous elements starting at `ptr`
|
||||
/// into a new allocation owned by the returned `Vec<T>`. The elements of
|
||||
/// the buffer are copied into the vector without cloning, as if
|
||||
/// `ptr::read()` were called on them.
|
||||
#[inline]
|
||||
#[unstable(feature = "vec_from_raw_buf",
|
||||
reason = "may be better expressed via composition")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "use slice::from_raw_parts + .to_vec() instead")]
|
||||
pub unsafe fn from_raw_buf(ptr: *const T, elts: usize) -> Vec<T> {
|
||||
let mut dst = Vec::with_capacity(elts);
|
||||
dst.set_len(elts);
|
||||
ptr::copy_nonoverlapping(ptr, dst.as_mut_ptr(), elts);
|
||||
dst
|
||||
}
|
||||
|
||||
/// Returns the number of elements the vector can hold without
|
||||
/// reallocating.
|
||||
///
|
||||
|
@ -597,7 +580,8 @@ impl<T> Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Removes the last element from a vector and returns it, or `None` if it is empty.
|
||||
/// Removes the last element from a vector and returns it, or `None` if it
|
||||
/// is empty.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -755,210 +739,6 @@ impl<T> Vec<T> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
|
||||
/// Converts a `Vec<T>` to a `Vec<U>` where `T` and `U` have the same
|
||||
/// size and in case they are not zero-sized the same minimal alignment.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `T` and `U` have differing sizes or are not zero-sized and
|
||||
/// have differing minimal alignments.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(map_in_place)]
|
||||
///
|
||||
/// let v = vec![0, 1, 2];
|
||||
/// let w = v.map_in_place(|i| i + 3);
|
||||
/// assert_eq!(&w[..], &[3, 4, 5]);
|
||||
///
|
||||
/// #[derive(PartialEq, Debug)]
|
||||
/// struct Newtype(u8);
|
||||
/// let bytes = vec![0x11, 0x22];
|
||||
/// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x));
|
||||
/// assert_eq!(&newtyped_bytes[..], &[Newtype(0x11), Newtype(0x22)]);
|
||||
/// ```
|
||||
#[unstable(feature = "map_in_place",
|
||||
reason = "API may change to provide stronger guarantees")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "unclear that the API is strong enough and did \
|
||||
not proven itself")]
|
||||
pub fn map_in_place<U, F>(self, mut f: F) -> Vec<U> where F: FnMut(T) -> U {
|
||||
// FIXME: Assert statically that the types `T` and `U` have the same
|
||||
// size.
|
||||
assert!(mem::size_of::<T>() == mem::size_of::<U>());
|
||||
|
||||
let mut vec = self;
|
||||
|
||||
if mem::size_of::<T>() != 0 {
|
||||
// FIXME: Assert statically that the types `T` and `U` have the
|
||||
// same minimal alignment in case they are not zero-sized.
|
||||
|
||||
// These asserts are necessary because the `align_of` of the
|
||||
// types are passed to the allocator by `Vec`.
|
||||
assert!(mem::align_of::<T>() == mem::align_of::<U>());
|
||||
|
||||
// This `as isize` cast is safe, because the size of the elements of the
|
||||
// vector is not 0, and:
|
||||
//
|
||||
// 1) If the size of the elements in the vector is 1, the `isize` may
|
||||
// overflow, but it has the correct bit pattern so that the
|
||||
// `.offset()` function will work.
|
||||
//
|
||||
// Example:
|
||||
// Address space 0x0-0xF.
|
||||
// `u8` array at: 0x1.
|
||||
// Size of `u8` array: 0x8.
|
||||
// Calculated `offset`: -0x8.
|
||||
// After `array.offset(offset)`: 0x9.
|
||||
// (0x1 + 0x8 = 0x1 - 0x8)
|
||||
//
|
||||
// 2) If the size of the elements in the vector is >1, the `usize` ->
|
||||
// `isize` conversion can't overflow.
|
||||
let offset = vec.len() as isize;
|
||||
let start = vec.as_mut_ptr();
|
||||
|
||||
let mut pv = PartialVecNonZeroSized {
|
||||
vec: vec,
|
||||
|
||||
start_t: start,
|
||||
// This points inside the vector, as the vector has length
|
||||
// `offset`.
|
||||
end_t: unsafe { start.offset(offset) },
|
||||
start_u: start as *mut U,
|
||||
end_u: start as *mut U,
|
||||
|
||||
_marker: PhantomData,
|
||||
};
|
||||
// start_t
|
||||
// start_u
|
||||
// |
|
||||
// +-+-+-+-+-+-+
|
||||
// |T|T|T|...|T|
|
||||
// +-+-+-+-+-+-+
|
||||
// | |
|
||||
// end_u end_t
|
||||
|
||||
while pv.end_u as *mut T != pv.end_t {
|
||||
unsafe {
|
||||
// start_u start_t
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// |U|...|U|T|T|...|T|
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// end_u end_t
|
||||
|
||||
let t = ptr::read(pv.start_t);
|
||||
// start_u start_t
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// |U|...|U|X|T|...|T|
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// end_u end_t
|
||||
// We must not panic here, one cell is marked as `T`
|
||||
// although it is not `T`.
|
||||
|
||||
pv.start_t = pv.start_t.offset(1);
|
||||
// start_u start_t
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// |U|...|U|X|T|...|T|
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// end_u end_t
|
||||
// We may panic again.
|
||||
|
||||
// The function given by the user might panic.
|
||||
let u = f(t);
|
||||
|
||||
ptr::write(pv.end_u, u);
|
||||
// start_u start_t
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// |U|...|U|U|T|...|T|
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// end_u end_t
|
||||
// We should not panic here, because that would leak the `U`
|
||||
// pointed to by `end_u`.
|
||||
|
||||
pv.end_u = pv.end_u.offset(1);
|
||||
// start_u start_t
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// |U|...|U|U|T|...|T|
|
||||
// +-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// end_u end_t
|
||||
// We may panic again.
|
||||
}
|
||||
}
|
||||
|
||||
// start_u start_t
|
||||
// | |
|
||||
// +-+-+-+-+-+-+
|
||||
// |U|...|U|U|U|
|
||||
// +-+-+-+-+-+-+
|
||||
// |
|
||||
// end_t
|
||||
// end_u
|
||||
// Extract `vec` and prevent the destructor of
|
||||
// `PartialVecNonZeroSized` from running. Note that none of the
|
||||
// function calls can panic, thus no resources can be leaked (as the
|
||||
// `vec` member of `PartialVec` is the only one which holds
|
||||
// allocations -- and it is returned from this function. None of
|
||||
// this can panic.
|
||||
unsafe {
|
||||
let vec_len = pv.vec.len();
|
||||
let vec_cap = pv.vec.capacity();
|
||||
let vec_ptr = pv.vec.as_mut_ptr() as *mut U;
|
||||
mem::forget(pv);
|
||||
Vec::from_raw_parts(vec_ptr, vec_len, vec_cap)
|
||||
}
|
||||
} else {
|
||||
// Put the `Vec` into the `PartialVecZeroSized` structure and
|
||||
// prevent the destructor of the `Vec` from running. Since the
|
||||
// `Vec` contained zero-sized objects, it did not allocate, so we
|
||||
// are not leaking memory here.
|
||||
let mut pv = PartialVecZeroSized::<T,U> {
|
||||
num_t: vec.len(),
|
||||
num_u: 0,
|
||||
marker: PhantomData,
|
||||
};
|
||||
mem::forget(vec);
|
||||
|
||||
while pv.num_t != 0 {
|
||||
unsafe {
|
||||
// Create a `T` out of thin air and decrement `num_t`. This
|
||||
// must not panic between these steps, as otherwise a
|
||||
// destructor of `T` which doesn't exist runs.
|
||||
let t = mem::uninitialized();
|
||||
pv.num_t -= 1;
|
||||
|
||||
// The function given by the user might panic.
|
||||
let u = f(t);
|
||||
|
||||
// Forget the `U` and increment `num_u`. This increment
|
||||
// cannot overflow the `usize` as we only do this for a
|
||||
// number of times that fits into a `usize` (and start with
|
||||
// `0`). Again, we should not panic between these steps.
|
||||
mem::forget(u);
|
||||
pv.num_u += 1;
|
||||
}
|
||||
}
|
||||
// Create a `Vec` from our `PartialVecZeroSized` and make sure the
|
||||
// destructor of the latter will not run. None of this can panic.
|
||||
let mut result = Vec::new();
|
||||
unsafe {
|
||||
result.set_len(pv.num_u);
|
||||
mem::forget(pv);
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
/// Splits the collection into two at the given index.
|
||||
///
|
||||
/// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
|
||||
|
@ -1081,9 +861,9 @@ impl<T: Clone> Vec<T> {
|
|||
for i in 0..other.len() {
|
||||
let len = self.len();
|
||||
|
||||
// Unsafe code so this can be optimised to a memcpy (or something similarly
|
||||
// fast) when T is Copy. LLVM is easily confused, so any extra operations
|
||||
// during the loop can prevent this optimisation.
|
||||
// Unsafe code so this can be optimised to a memcpy (or something
|
||||
// similarly fast) when T is Copy. LLVM is easily confused, so any
|
||||
// extra operations during the loop can prevent this optimisation.
|
||||
unsafe {
|
||||
ptr::write(
|
||||
self.get_unchecked_mut(len),
|
||||
|
@ -1424,7 +1204,7 @@ impl<T> IntoIterator for Vec<T> {
|
|||
};
|
||||
let buf = ptr::read(&self.buf);
|
||||
mem::forget(self);
|
||||
IntoIter { buf: buf, ptr: begin, end: end }
|
||||
IntoIter { _buf: buf, ptr: begin, end: end }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1608,14 +1388,12 @@ impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T: 'a> IntoCow<'a, [T]> for Vec<T> where T: Clone {
|
||||
fn into_cow(self) -> Cow<'a, [T]> {
|
||||
Cow::Owned(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T> IntoCow<'a, [T]> for &'a [T] where T: Clone {
|
||||
fn into_cow(self) -> Cow<'a, [T]> {
|
||||
Cow::Borrowed(self)
|
||||
|
@ -1629,7 +1407,7 @@ impl<'a, T> IntoCow<'a, [T]> for &'a [T] where T: Clone {
|
|||
/// An iterator that moves out of a vector.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct IntoIter<T> {
|
||||
buf: RawVec<T>,
|
||||
_buf: RawVec<T>,
|
||||
ptr: *const T,
|
||||
end: *const T
|
||||
}
|
||||
|
@ -1637,21 +1415,6 @@ pub struct IntoIter<T> {
|
|||
unsafe impl<T: Send> Send for IntoIter<T> { }
|
||||
unsafe impl<T: Sync> Sync for IntoIter<T> { }
|
||||
|
||||
impl<T> IntoIter<T> {
|
||||
#[inline]
|
||||
/// Drops all items that have not yet been moved and returns the empty vector.
|
||||
#[unstable(feature = "iter_to_vec")]
|
||||
#[deprecated(since = "1.3.0", reason = "replaced by drain()")]
|
||||
pub fn into_inner(mut self) -> Vec<T> {
|
||||
unsafe {
|
||||
for _x in self.by_ref() { }
|
||||
let buf = ptr::read(&self.buf);
|
||||
mem::forget(self);
|
||||
Vec { buf: buf, len: 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> Iterator for IntoIter<T> {
|
||||
type Item = T;
|
||||
|
@ -1800,77 +1563,3 @@ impl<'a, T> Drop for Drain<'a, T> {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Partial vec, used for map_in_place
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// An owned, partially type-converted vector of elements with non-zero size.
|
||||
///
|
||||
/// `T` and `U` must have the same, non-zero size. They must also have the same
|
||||
/// alignment.
|
||||
///
|
||||
/// When the destructor of this struct runs, all `U`s from `start_u` (incl.) to
|
||||
/// `end_u` (excl.) and all `T`s from `start_t` (incl.) to `end_t` (excl.) are
|
||||
/// destructed. Additionally the underlying storage of `vec` will be freed.
|
||||
struct PartialVecNonZeroSized<T,U> {
|
||||
vec: Vec<T>,
|
||||
|
||||
start_u: *mut U,
|
||||
end_u: *mut U,
|
||||
start_t: *mut T,
|
||||
end_t: *mut T,
|
||||
|
||||
_marker: PhantomData<U>,
|
||||
}
|
||||
|
||||
/// An owned, partially type-converted vector of zero-sized elements.
|
||||
///
|
||||
/// When the destructor of this struct runs, all `num_t` `T`s and `num_u` `U`s
|
||||
/// are destructed.
|
||||
struct PartialVecZeroSized<T,U> {
|
||||
num_t: usize,
|
||||
num_u: usize,
|
||||
marker: PhantomData<::core::cell::Cell<(T,U)>>,
|
||||
}
|
||||
|
||||
impl<T,U> Drop for PartialVecNonZeroSized<T,U> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// `vec` hasn't been modified until now. As it has a length
|
||||
// currently, this would run destructors of `T`s which might not be
|
||||
// there. So at first, set `vec`s length to `0`. This must be done
|
||||
// at first to remain memory-safe as the destructors of `U` or `T`
|
||||
// might cause unwinding where `vec`s destructor would be executed.
|
||||
self.vec.set_len(0);
|
||||
|
||||
// We have instances of `U`s and `T`s in `vec`. Destruct them.
|
||||
while self.start_u != self.end_u {
|
||||
let _ = ptr::read(self.start_u); // Run a `U` destructor.
|
||||
self.start_u = self.start_u.offset(1);
|
||||
}
|
||||
while self.start_t != self.end_t {
|
||||
let _ = ptr::read(self.start_t); // Run a `T` destructor.
|
||||
self.start_t = self.start_t.offset(1);
|
||||
}
|
||||
// After this destructor ran, the destructor of `vec` will run,
|
||||
// deallocating the underlying memory.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T,U> Drop for PartialVecZeroSized<T,U> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// Destruct the instances of `T` and `U` this struct owns.
|
||||
while self.num_t != 0 {
|
||||
let _: T = mem::uninitialized(); // Run a `T` destructor.
|
||||
self.num_t -= 1;
|
||||
}
|
||||
while self.num_u != 0 {
|
||||
let _: U = mem::uninitialized(); // Run a `U` destructor.
|
||||
self.num_u -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use core::iter::{self, repeat, FromIterator, RandomAccessIterator};
|
||||
use core::iter::{self, repeat, FromIterator};
|
||||
use core::ops::{Index, IndexMut};
|
||||
use core::ptr;
|
||||
use core::slice;
|
||||
|
@ -1522,26 +1522,6 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T> RandomAccessIterator for Iter<'a, T> {
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
let (len, _) = self.size_hint();
|
||||
len
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, j: usize) -> Option<&'a T> {
|
||||
if j >= self.indexable() {
|
||||
None
|
||||
} else {
|
||||
let idx = wrap_index(self.tail.wrapping_add(j), self.ring.len());
|
||||
unsafe { Some(self.ring.get_unchecked(idx)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `VecDeque` mutable iterator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct IterMut<'a, T:'a> {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,12 +0,0 @@
|
|||
// Copyright 2012-2014 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.
|
||||
|
||||
mod set;
|
||||
mod vec;
|
|
@ -1,520 +0,0 @@
|
|||
// Copyright 2012-2014 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 std::cmp::Ordering::{Equal, Greater, Less};
|
||||
use std::collections::{BitSet, BitVec};
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_show() {
|
||||
let mut s = BitSet::new();
|
||||
s.insert(1);
|
||||
s.insert(10);
|
||||
s.insert(50);
|
||||
s.insert(2);
|
||||
assert_eq!("{1, 2, 10, 50}", format!("{:?}", s));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_from_usizes() {
|
||||
let usizes = vec![0, 2, 2, 3];
|
||||
let a: BitSet = usizes.into_iter().collect();
|
||||
let mut b = BitSet::new();
|
||||
b.insert(0);
|
||||
b.insert(2);
|
||||
b.insert(3);
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_iterator() {
|
||||
let usizes = vec![0, 2, 2, 3];
|
||||
let bit_vec: BitSet = usizes.into_iter().collect();
|
||||
|
||||
let idxs: Vec<_> = bit_vec.iter().collect();
|
||||
assert_eq!(idxs, [0, 2, 3]);
|
||||
|
||||
let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect();
|
||||
let real: Vec<_> = (0..10000).step_by(2).collect();
|
||||
|
||||
let idxs: Vec<_> = long.iter().collect();
|
||||
assert_eq!(idxs, real);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_frombit_vec_init() {
|
||||
let bools = [true, false];
|
||||
let lengths = [10, 64, 100];
|
||||
for &b in &bools {
|
||||
for &l in &lengths {
|
||||
let bitset = BitSet::from_bit_vec(BitVec::from_elem(l, b));
|
||||
assert_eq!(bitset.contains(&1), b);
|
||||
assert_eq!(bitset.contains(&(l-1)), b);
|
||||
assert!(!bitset.contains(&l));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_masking() {
|
||||
let b = BitVec::from_elem(140, true);
|
||||
let mut bs = BitSet::from_bit_vec(b);
|
||||
assert!(bs.contains(&139));
|
||||
assert!(!bs.contains(&140));
|
||||
assert!(bs.insert(150));
|
||||
assert!(!bs.contains(&140));
|
||||
assert!(!bs.contains(&149));
|
||||
assert!(bs.contains(&150));
|
||||
assert!(!bs.contains(&151));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_basic() {
|
||||
let mut b = BitSet::new();
|
||||
assert!(b.insert(3));
|
||||
assert!(!b.insert(3));
|
||||
assert!(b.contains(&3));
|
||||
assert!(b.insert(4));
|
||||
assert!(!b.insert(4));
|
||||
assert!(b.contains(&3));
|
||||
assert!(b.insert(400));
|
||||
assert!(!b.insert(400));
|
||||
assert!(b.contains(&400));
|
||||
assert_eq!(b.len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_intersection() {
|
||||
let mut a = BitSet::new();
|
||||
let mut b = BitSet::new();
|
||||
|
||||
assert!(a.insert(11));
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(77));
|
||||
assert!(a.insert(103));
|
||||
assert!(a.insert(5));
|
||||
|
||||
assert!(b.insert(2));
|
||||
assert!(b.insert(11));
|
||||
assert!(b.insert(77));
|
||||
assert!(b.insert(5));
|
||||
assert!(b.insert(3));
|
||||
|
||||
let expected = [3, 5, 11, 77];
|
||||
let actual: Vec<_> = a.intersection(&b).collect();
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_difference() {
|
||||
let mut a = BitSet::new();
|
||||
let mut b = BitSet::new();
|
||||
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(5));
|
||||
assert!(a.insert(200));
|
||||
assert!(a.insert(500));
|
||||
|
||||
assert!(b.insert(3));
|
||||
assert!(b.insert(200));
|
||||
|
||||
let expected = [1, 5, 500];
|
||||
let actual: Vec<_> = a.difference(&b).collect();
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_symmetric_difference() {
|
||||
let mut a = BitSet::new();
|
||||
let mut b = BitSet::new();
|
||||
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(5));
|
||||
assert!(a.insert(9));
|
||||
assert!(a.insert(11));
|
||||
|
||||
assert!(b.insert(3));
|
||||
assert!(b.insert(9));
|
||||
assert!(b.insert(14));
|
||||
assert!(b.insert(220));
|
||||
|
||||
let expected = [1, 5, 11, 14, 220];
|
||||
let actual: Vec<_> = a.symmetric_difference(&b).collect();
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_union() {
|
||||
let mut a = BitSet::new();
|
||||
let mut b = BitSet::new();
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(5));
|
||||
assert!(a.insert(9));
|
||||
assert!(a.insert(11));
|
||||
assert!(a.insert(160));
|
||||
assert!(a.insert(19));
|
||||
assert!(a.insert(24));
|
||||
assert!(a.insert(200));
|
||||
|
||||
assert!(b.insert(1));
|
||||
assert!(b.insert(5));
|
||||
assert!(b.insert(9));
|
||||
assert!(b.insert(13));
|
||||
assert!(b.insert(19));
|
||||
|
||||
let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
|
||||
let actual: Vec<_> = a.union(&b).collect();
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_subset() {
|
||||
let mut set1 = BitSet::new();
|
||||
let mut set2 = BitSet::new();
|
||||
|
||||
assert!(set1.is_subset(&set2)); // {} {}
|
||||
set2.insert(100);
|
||||
assert!(set1.is_subset(&set2)); // {} { 1 }
|
||||
set2.insert(200);
|
||||
assert!(set1.is_subset(&set2)); // {} { 1, 2 }
|
||||
set1.insert(200);
|
||||
assert!(set1.is_subset(&set2)); // { 2 } { 1, 2 }
|
||||
set1.insert(300);
|
||||
assert!(!set1.is_subset(&set2)); // { 2, 3 } { 1, 2 }
|
||||
set2.insert(300);
|
||||
assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3 }
|
||||
set2.insert(400);
|
||||
assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3, 4 }
|
||||
set2.remove(&100);
|
||||
assert!(set1.is_subset(&set2)); // { 2, 3 } { 2, 3, 4 }
|
||||
set2.remove(&300);
|
||||
assert!(!set1.is_subset(&set2)); // { 2, 3 } { 2, 4 }
|
||||
set1.remove(&300);
|
||||
assert!(set1.is_subset(&set2)); // { 2 } { 2, 4 }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_is_disjoint() {
|
||||
let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01000000]));
|
||||
let c = BitSet::new();
|
||||
let d = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00110000]));
|
||||
|
||||
assert!(!a.is_disjoint(&d));
|
||||
assert!(!d.is_disjoint(&a));
|
||||
|
||||
assert!(a.is_disjoint(&b));
|
||||
assert!(a.is_disjoint(&c));
|
||||
assert!(b.is_disjoint(&a));
|
||||
assert!(b.is_disjoint(&c));
|
||||
assert!(c.is_disjoint(&a));
|
||||
assert!(c.is_disjoint(&b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_union_with() {
|
||||
//a should grow to include larger elements
|
||||
let mut a = BitSet::new();
|
||||
a.insert(0);
|
||||
let mut b = BitSet::new();
|
||||
b.insert(5);
|
||||
let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
|
||||
a.union_with(&b);
|
||||
assert_eq!(a, expected);
|
||||
|
||||
// Standard
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
|
||||
let c = a.clone();
|
||||
a.union_with(&b);
|
||||
b.union_with(&c);
|
||||
assert_eq!(a.len(), 4);
|
||||
assert_eq!(b.len(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_intersect_with() {
|
||||
// Explicitly 0'ed bits
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
|
||||
let c = a.clone();
|
||||
a.intersect_with(&b);
|
||||
b.intersect_with(&c);
|
||||
assert!(a.is_empty());
|
||||
assert!(b.is_empty());
|
||||
|
||||
// Uninitialized bits should behave like 0's
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
let mut b = BitSet::new();
|
||||
let c = a.clone();
|
||||
a.intersect_with(&b);
|
||||
b.intersect_with(&c);
|
||||
assert!(a.is_empty());
|
||||
assert!(b.is_empty());
|
||||
|
||||
// Standard
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
|
||||
let c = a.clone();
|
||||
a.intersect_with(&b);
|
||||
b.intersect_with(&c);
|
||||
assert_eq!(a.len(), 2);
|
||||
assert_eq!(b.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_difference_with() {
|
||||
// Explicitly 0'ed bits
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
|
||||
let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
a.difference_with(&b);
|
||||
assert!(a.is_empty());
|
||||
|
||||
// Uninitialized bits should behave like 0's
|
||||
let mut a = BitSet::new();
|
||||
let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11111111]));
|
||||
a.difference_with(&b);
|
||||
assert!(a.is_empty());
|
||||
|
||||
// Standard
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
|
||||
let c = a.clone();
|
||||
a.difference_with(&b);
|
||||
b.difference_with(&c);
|
||||
assert_eq!(a.len(), 1);
|
||||
assert_eq!(b.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_symmetric_difference_with() {
|
||||
//a should grow to include larger elements
|
||||
let mut a = BitSet::new();
|
||||
a.insert(0);
|
||||
a.insert(1);
|
||||
let mut b = BitSet::new();
|
||||
b.insert(1);
|
||||
b.insert(5);
|
||||
let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
|
||||
a.symmetric_difference_with(&b);
|
||||
assert_eq!(a, expected);
|
||||
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
let b = BitSet::new();
|
||||
let c = a.clone();
|
||||
a.symmetric_difference_with(&b);
|
||||
assert_eq!(a, c);
|
||||
|
||||
// Standard
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11100010]));
|
||||
let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101010]));
|
||||
let c = a.clone();
|
||||
a.symmetric_difference_with(&b);
|
||||
b.symmetric_difference_with(&c);
|
||||
assert_eq!(a.len(), 2);
|
||||
assert_eq!(b.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_eq() {
|
||||
let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
|
||||
let c = BitSet::new();
|
||||
|
||||
assert!(a == a);
|
||||
assert!(a != b);
|
||||
assert!(a != c);
|
||||
assert!(b == b);
|
||||
assert!(b == c);
|
||||
assert!(c == c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_cmp() {
|
||||
let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
|
||||
let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
|
||||
let c = BitSet::new();
|
||||
|
||||
assert_eq!(a.cmp(&b), Greater);
|
||||
assert_eq!(a.cmp(&c), Greater);
|
||||
assert_eq!(b.cmp(&a), Less);
|
||||
assert_eq!(b.cmp(&c), Equal);
|
||||
assert_eq!(c.cmp(&a), Less);
|
||||
assert_eq!(c.cmp(&b), Equal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_remove() {
|
||||
let mut a = BitSet::new();
|
||||
|
||||
assert!(a.insert(1));
|
||||
assert!(a.remove(&1));
|
||||
|
||||
assert!(a.insert(100));
|
||||
assert!(a.remove(&100));
|
||||
|
||||
assert!(a.insert(1000));
|
||||
assert!(a.remove(&1000));
|
||||
a.shrink_to_fit();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_clone() {
|
||||
let mut a = BitSet::new();
|
||||
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(100));
|
||||
assert!(a.insert(1000));
|
||||
|
||||
let mut b = a.clone();
|
||||
|
||||
assert!(a == b);
|
||||
|
||||
assert!(b.remove(&1));
|
||||
assert!(a.contains(&1));
|
||||
|
||||
assert!(a.remove(&1000));
|
||||
assert!(b.contains(&1000));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_append() {
|
||||
let mut a = BitSet::new();
|
||||
a.insert(2);
|
||||
a.insert(6);
|
||||
|
||||
let mut b = BitSet::new();
|
||||
b.insert(1);
|
||||
b.insert(3);
|
||||
b.insert(6);
|
||||
|
||||
a.append(&mut b);
|
||||
|
||||
assert_eq!(a.len(), 4);
|
||||
assert_eq!(b.len(), 0);
|
||||
assert!(b.capacity() >= 6);
|
||||
|
||||
assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b01110010])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_split_off() {
|
||||
// Split at 0
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
|
||||
0b00110011, 0b01101011, 0b10101101]));
|
||||
|
||||
let b = a.split_off(0);
|
||||
|
||||
assert_eq!(a.len(), 0);
|
||||
assert_eq!(b.len(), 21);
|
||||
|
||||
assert_eq!(b, BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
|
||||
0b00110011, 0b01101011, 0b10101101])));
|
||||
|
||||
// Split behind last element
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
|
||||
0b00110011, 0b01101011, 0b10101101]));
|
||||
|
||||
let b = a.split_off(50);
|
||||
|
||||
assert_eq!(a.len(), 21);
|
||||
assert_eq!(b.len(), 0);
|
||||
|
||||
assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
|
||||
0b00110011, 0b01101011, 0b10101101])));
|
||||
|
||||
// Split at arbitrary element
|
||||
let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
|
||||
0b00110011, 0b01101011, 0b10101101]));
|
||||
|
||||
let b = a.split_off(34);
|
||||
|
||||
assert_eq!(a.len(), 12);
|
||||
assert_eq!(b.len(), 9);
|
||||
|
||||
assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010,
|
||||
0b00110011, 0b01000000])));
|
||||
assert_eq!(b, BitSet::from_bit_vec(BitVec::from_bytes(&[0, 0, 0, 0,
|
||||
0b00101011, 0b10101101])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_set_extend_ref() {
|
||||
let mut a = BitSet::new();
|
||||
a.insert(3);
|
||||
|
||||
a.extend(&[5, 7, 10]);
|
||||
|
||||
assert_eq!(a.len(), 4);
|
||||
assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b00010101,0b00100000])));
|
||||
|
||||
let mut b = BitSet::new();
|
||||
b.insert(11);
|
||||
b.insert(15);
|
||||
|
||||
a.extend(&b);
|
||||
|
||||
assert_eq!(a.len(), 6);
|
||||
assert_eq!(a, BitSet::from_bit_vec(BitVec::from_bytes(&[0b00010101,0b00110001])));
|
||||
}
|
||||
|
||||
mod bench {
|
||||
use std::collections::{BitSet, BitVec};
|
||||
use std::__rand::{Rng, thread_rng, ThreadRng};
|
||||
use std::u32;
|
||||
|
||||
use test::{Bencher, black_box};
|
||||
|
||||
const BENCH_BITS : usize = 1 << 14;
|
||||
|
||||
fn rng() -> ThreadRng {
|
||||
thread_rng()
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_bit_vecset_small(b: &mut Bencher) {
|
||||
let mut r = rng();
|
||||
let mut bit_vec = BitSet::new();
|
||||
b.iter(|| {
|
||||
for _ in 0..100 {
|
||||
bit_vec.insert((r.next_u32() as usize) % u32::BITS);
|
||||
}
|
||||
black_box(&bit_vec);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_bit_vecset_big(b: &mut Bencher) {
|
||||
let mut r = rng();
|
||||
let mut bit_vec = BitSet::new();
|
||||
b.iter(|| {
|
||||
for _ in 0..100 {
|
||||
bit_vec.insert((r.next_u32() as usize) % BENCH_BITS);
|
||||
}
|
||||
black_box(&bit_vec);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_bit_vecset_iter(b: &mut Bencher) {
|
||||
let bit_vec = BitSet::from_bit_vec(BitVec::from_fn(BENCH_BITS,
|
||||
|idx| {idx % 3 == 0}));
|
||||
b.iter(|| {
|
||||
let mut sum = 0;
|
||||
for idx in &bit_vec {
|
||||
sum += idx as usize;
|
||||
}
|
||||
sum
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,881 +0,0 @@
|
|||
// Copyright 2012-2014 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 std::collections::BitVec;
|
||||
use std::u32;
|
||||
|
||||
#[test]
|
||||
fn test_to_str() {
|
||||
let zerolen = BitVec::new();
|
||||
assert_eq!(format!("{:?}", zerolen), "");
|
||||
|
||||
let eightbits = BitVec::from_elem(8, false);
|
||||
assert_eq!(format!("{:?}", eightbits), "00000000")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_0_elements() {
|
||||
let act = BitVec::new();
|
||||
let exp = Vec::new();
|
||||
assert!(act.eq_vec(&exp));
|
||||
assert!(act.none() && act.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_1_element() {
|
||||
let mut act = BitVec::from_elem(1, false);
|
||||
assert!(act.eq_vec(&[false]));
|
||||
assert!(act.none() && !act.all());
|
||||
act = BitVec::from_elem(1, true);
|
||||
assert!(act.eq_vec(&[true]));
|
||||
assert!(!act.none() && act.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_2_elements() {
|
||||
let mut b = BitVec::from_elem(2, false);
|
||||
b.set(0, true);
|
||||
b.set(1, false);
|
||||
assert_eq!(format!("{:?}", b), "10");
|
||||
assert!(!b.none() && !b.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_10_elements() {
|
||||
let mut act;
|
||||
// all 0
|
||||
|
||||
act = BitVec::from_elem(10, false);
|
||||
assert!((act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false])));
|
||||
assert!(act.none() && !act.all());
|
||||
// all 1
|
||||
|
||||
act = BitVec::from_elem(10, true);
|
||||
assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true])));
|
||||
assert!(!act.none() && act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(10, false);
|
||||
act.set(0, true);
|
||||
act.set(1, true);
|
||||
act.set(2, true);
|
||||
act.set(3, true);
|
||||
act.set(4, true);
|
||||
assert!((act.eq_vec(&[true, true, true, true, true, false, false, false, false, false])));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(10, false);
|
||||
act.set(5, true);
|
||||
act.set(6, true);
|
||||
act.set(7, true);
|
||||
act.set(8, true);
|
||||
act.set(9, true);
|
||||
assert!((act.eq_vec(&[false, false, false, false, false, true, true, true, true, true])));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(10, false);
|
||||
act.set(0, true);
|
||||
act.set(3, true);
|
||||
act.set(6, true);
|
||||
act.set(9, true);
|
||||
assert!((act.eq_vec(&[true, false, false, true, false, false, true, false, false, true])));
|
||||
assert!(!act.none() && !act.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_31_elements() {
|
||||
let mut act;
|
||||
// all 0
|
||||
|
||||
act = BitVec::from_elem(31, false);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false]));
|
||||
assert!(act.none() && !act.all());
|
||||
// all 1
|
||||
|
||||
act = BitVec::from_elem(31, true);
|
||||
assert!(act.eq_vec(
|
||||
&[true, true, true, true, true, true, true, true, true, true, true, true, true,
|
||||
true, true, true, true, true, true, true, true, true, true, true, true, true,
|
||||
true, true, true, true, true]));
|
||||
assert!(!act.none() && act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(31, false);
|
||||
act.set(0, true);
|
||||
act.set(1, true);
|
||||
act.set(2, true);
|
||||
act.set(3, true);
|
||||
act.set(4, true);
|
||||
act.set(5, true);
|
||||
act.set(6, true);
|
||||
act.set(7, true);
|
||||
assert!(act.eq_vec(
|
||||
&[true, true, true, true, true, true, true, true, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false]));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(31, false);
|
||||
act.set(16, true);
|
||||
act.set(17, true);
|
||||
act.set(18, true);
|
||||
act.set(19, true);
|
||||
act.set(20, true);
|
||||
act.set(21, true);
|
||||
act.set(22, true);
|
||||
act.set(23, true);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, true, true, true, true, true, true, true, true,
|
||||
false, false, false, false, false, false, false]));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(31, false);
|
||||
act.set(24, true);
|
||||
act.set(25, true);
|
||||
act.set(26, true);
|
||||
act.set(27, true);
|
||||
act.set(28, true);
|
||||
act.set(29, true);
|
||||
act.set(30, true);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, true, true, true, true, true, true, true]));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(31, false);
|
||||
act.set(3, true);
|
||||
act.set(17, true);
|
||||
act.set(30, true);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, true, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, true, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, true]));
|
||||
assert!(!act.none() && !act.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_32_elements() {
|
||||
let mut act;
|
||||
// all 0
|
||||
|
||||
act = BitVec::from_elem(32, false);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false]));
|
||||
assert!(act.none() && !act.all());
|
||||
// all 1
|
||||
|
||||
act = BitVec::from_elem(32, true);
|
||||
assert!(act.eq_vec(
|
||||
&[true, true, true, true, true, true, true, true, true, true, true, true, true,
|
||||
true, true, true, true, true, true, true, true, true, true, true, true, true,
|
||||
true, true, true, true, true, true]));
|
||||
assert!(!act.none() && act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(32, false);
|
||||
act.set(0, true);
|
||||
act.set(1, true);
|
||||
act.set(2, true);
|
||||
act.set(3, true);
|
||||
act.set(4, true);
|
||||
act.set(5, true);
|
||||
act.set(6, true);
|
||||
act.set(7, true);
|
||||
assert!(act.eq_vec(
|
||||
&[true, true, true, true, true, true, true, true, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false]));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(32, false);
|
||||
act.set(16, true);
|
||||
act.set(17, true);
|
||||
act.set(18, true);
|
||||
act.set(19, true);
|
||||
act.set(20, true);
|
||||
act.set(21, true);
|
||||
act.set(22, true);
|
||||
act.set(23, true);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, true, true, true, true, true, true, true, true,
|
||||
false, false, false, false, false, false, false, false]));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(32, false);
|
||||
act.set(24, true);
|
||||
act.set(25, true);
|
||||
act.set(26, true);
|
||||
act.set(27, true);
|
||||
act.set(28, true);
|
||||
act.set(29, true);
|
||||
act.set(30, true);
|
||||
act.set(31, true);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, true, true, true, true, true, true, true, true]));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(32, false);
|
||||
act.set(3, true);
|
||||
act.set(17, true);
|
||||
act.set(30, true);
|
||||
act.set(31, true);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, true, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, true, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, true, true]));
|
||||
assert!(!act.none() && !act.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_33_elements() {
|
||||
let mut act;
|
||||
// all 0
|
||||
|
||||
act = BitVec::from_elem(33, false);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false]));
|
||||
assert!(act.none() && !act.all());
|
||||
// all 1
|
||||
|
||||
act = BitVec::from_elem(33, true);
|
||||
assert!(act.eq_vec(
|
||||
&[true, true, true, true, true, true, true, true, true, true, true, true, true,
|
||||
true, true, true, true, true, true, true, true, true, true, true, true, true,
|
||||
true, true, true, true, true, true, true]));
|
||||
assert!(!act.none() && act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(33, false);
|
||||
act.set(0, true);
|
||||
act.set(1, true);
|
||||
act.set(2, true);
|
||||
act.set(3, true);
|
||||
act.set(4, true);
|
||||
act.set(5, true);
|
||||
act.set(6, true);
|
||||
act.set(7, true);
|
||||
assert!(act.eq_vec(
|
||||
&[true, true, true, true, true, true, true, true, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false]));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(33, false);
|
||||
act.set(16, true);
|
||||
act.set(17, true);
|
||||
act.set(18, true);
|
||||
act.set(19, true);
|
||||
act.set(20, true);
|
||||
act.set(21, true);
|
||||
act.set(22, true);
|
||||
act.set(23, true);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, true, true, true, true, true, true, true, true,
|
||||
false, false, false, false, false, false, false, false, false]));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(33, false);
|
||||
act.set(24, true);
|
||||
act.set(25, true);
|
||||
act.set(26, true);
|
||||
act.set(27, true);
|
||||
act.set(28, true);
|
||||
act.set(29, true);
|
||||
act.set(30, true);
|
||||
act.set(31, true);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, true, true, true, true, true, true, true, true, false]));
|
||||
assert!(!act.none() && !act.all());
|
||||
// mixed
|
||||
|
||||
act = BitVec::from_elem(33, false);
|
||||
act.set(3, true);
|
||||
act.set(17, true);
|
||||
act.set(30, true);
|
||||
act.set(31, true);
|
||||
act.set(32, true);
|
||||
assert!(act.eq_vec(
|
||||
&[false, false, false, true, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, true, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, true, true, true]));
|
||||
assert!(!act.none() && !act.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_equal_differing_sizes() {
|
||||
let v0 = BitVec::from_elem(10, false);
|
||||
let v1 = BitVec::from_elem(11, false);
|
||||
assert!(v0 != v1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_equal_greatly_differing_sizes() {
|
||||
let v0 = BitVec::from_elem(10, false);
|
||||
let v1 = BitVec::from_elem(110, false);
|
||||
assert!(v0 != v1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_equal_sneaky_small() {
|
||||
let mut a = BitVec::from_elem(1, false);
|
||||
a.set(0, true);
|
||||
|
||||
let mut b = BitVec::from_elem(1, true);
|
||||
b.set(0, true);
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_equal_sneaky_big() {
|
||||
let mut a = BitVec::from_elem(100, false);
|
||||
for i in 0..100 {
|
||||
a.set(i, true);
|
||||
}
|
||||
|
||||
let mut b = BitVec::from_elem(100, true);
|
||||
for i in 0..100 {
|
||||
b.set(i, true);
|
||||
}
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_bytes() {
|
||||
let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
|
||||
let str = concat!("10110110", "00000000", "11111111");
|
||||
assert_eq!(format!("{:?}", bit_vec), str);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_bytes() {
|
||||
let mut bv = BitVec::from_elem(3, true);
|
||||
bv.set(1, false);
|
||||
assert_eq!(bv.to_bytes(), [0b10100000]);
|
||||
|
||||
let mut bv = BitVec::from_elem(9, false);
|
||||
bv.set(2, true);
|
||||
bv.set(8, true);
|
||||
assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_bools() {
|
||||
let bools = vec![true, false, true, true];
|
||||
let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
|
||||
assert_eq!(format!("{:?}", bit_vec), "1011");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_bools() {
|
||||
let bools = vec![false, false, true, false, false, true, true, false];
|
||||
assert_eq!(BitVec::from_bytes(&[0b00100110]).iter().collect::<Vec<bool>>(), bools);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_iterator() {
|
||||
let bools = vec![true, false, true, true];
|
||||
let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
|
||||
|
||||
assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), bools);
|
||||
|
||||
let long: Vec<_> = (0..10000).map(|i| i % 2 == 0).collect();
|
||||
let bit_vec: BitVec = long.iter().map(|n| *n).collect();
|
||||
assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), long)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_small_difference() {
|
||||
let mut b1 = BitVec::from_elem(3, false);
|
||||
let mut b2 = BitVec::from_elem(3, false);
|
||||
b1.set(0, true);
|
||||
b1.set(1, true);
|
||||
b2.set(1, true);
|
||||
b2.set(2, true);
|
||||
assert!(b1.difference(&b2));
|
||||
assert!(b1[0]);
|
||||
assert!(!b1[1]);
|
||||
assert!(!b1[2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_big_difference() {
|
||||
let mut b1 = BitVec::from_elem(100, false);
|
||||
let mut b2 = BitVec::from_elem(100, false);
|
||||
b1.set(0, true);
|
||||
b1.set(40, true);
|
||||
b2.set(40, true);
|
||||
b2.set(80, true);
|
||||
assert!(b1.difference(&b2));
|
||||
assert!(b1[0]);
|
||||
assert!(!b1[40]);
|
||||
assert!(!b1[80]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_small_clear() {
|
||||
let mut b = BitVec::from_elem(14, true);
|
||||
assert!(!b.none() && b.all());
|
||||
b.clear();
|
||||
assert!(b.none() && !b.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_big_clear() {
|
||||
let mut b = BitVec::from_elem(140, true);
|
||||
assert!(!b.none() && b.all());
|
||||
b.clear();
|
||||
assert!(b.none() && !b.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_lt() {
|
||||
let mut a = BitVec::from_elem(5, false);
|
||||
let mut b = BitVec::from_elem(5, false);
|
||||
|
||||
assert!(!(a < b) && !(b < a));
|
||||
b.set(2, true);
|
||||
assert!(a < b);
|
||||
a.set(3, true);
|
||||
assert!(a < b);
|
||||
a.set(2, true);
|
||||
assert!(!(a < b) && b < a);
|
||||
b.set(0, true);
|
||||
assert!(a < b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
let mut a = BitVec::from_elem(5, false);
|
||||
let mut b = BitVec::from_elem(5, false);
|
||||
|
||||
assert!(a <= b && a >= b);
|
||||
a.set(1, true);
|
||||
assert!(a > b && a >= b);
|
||||
assert!(b < a && b <= a);
|
||||
b.set(1, true);
|
||||
b.set(2, true);
|
||||
assert!(b > a && b >= a);
|
||||
assert!(a < b && a <= b);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_small_bit_vec_tests() {
|
||||
let v = BitVec::from_bytes(&[0]);
|
||||
assert!(!v.all());
|
||||
assert!(!v.any());
|
||||
assert!(v.none());
|
||||
|
||||
let v = BitVec::from_bytes(&[0b00010100]);
|
||||
assert!(!v.all());
|
||||
assert!(v.any());
|
||||
assert!(!v.none());
|
||||
|
||||
let v = BitVec::from_bytes(&[0xFF]);
|
||||
assert!(v.all());
|
||||
assert!(v.any());
|
||||
assert!(!v.none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_big_bit_vec_tests() {
|
||||
let v = BitVec::from_bytes(&[ // 88 bits
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0]);
|
||||
assert!(!v.all());
|
||||
assert!(!v.any());
|
||||
assert!(v.none());
|
||||
|
||||
let v = BitVec::from_bytes(&[ // 88 bits
|
||||
0, 0, 0b00010100, 0,
|
||||
0, 0, 0, 0b00110100,
|
||||
0, 0, 0]);
|
||||
assert!(!v.all());
|
||||
assert!(v.any());
|
||||
assert!(!v.none());
|
||||
|
||||
let v = BitVec::from_bytes(&[ // 88 bits
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF]);
|
||||
assert!(v.all());
|
||||
assert!(v.any());
|
||||
assert!(!v.none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_push_pop() {
|
||||
let mut s = BitVec::from_elem(5 * u32::BITS - 2, false);
|
||||
assert_eq!(s.len(), 5 * u32::BITS - 2);
|
||||
assert_eq!(s[5 * u32::BITS - 3], false);
|
||||
s.push(true);
|
||||
s.push(true);
|
||||
assert_eq!(s[5 * u32::BITS - 2], true);
|
||||
assert_eq!(s[5 * u32::BITS - 1], true);
|
||||
// Here the internal vector will need to be extended
|
||||
s.push(false);
|
||||
assert_eq!(s[5 * u32::BITS], false);
|
||||
s.push(false);
|
||||
assert_eq!(s[5 * u32::BITS + 1], false);
|
||||
assert_eq!(s.len(), 5 * u32::BITS + 2);
|
||||
// Pop it all off
|
||||
assert_eq!(s.pop(), Some(false));
|
||||
assert_eq!(s.pop(), Some(false));
|
||||
assert_eq!(s.pop(), Some(true));
|
||||
assert_eq!(s.pop(), Some(true));
|
||||
assert_eq!(s.len(), 5 * u32::BITS - 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_truncate() {
|
||||
let mut s = BitVec::from_elem(5 * u32::BITS, true);
|
||||
|
||||
assert_eq!(s, BitVec::from_elem(5 * u32::BITS, true));
|
||||
assert_eq!(s.len(), 5 * u32::BITS);
|
||||
s.truncate(4 * u32::BITS);
|
||||
assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
|
||||
assert_eq!(s.len(), 4 * u32::BITS);
|
||||
// Truncating to a size > s.len() should be a noop
|
||||
s.truncate(5 * u32::BITS);
|
||||
assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
|
||||
assert_eq!(s.len(), 4 * u32::BITS);
|
||||
s.truncate(3 * u32::BITS - 10);
|
||||
assert_eq!(s, BitVec::from_elem(3 * u32::BITS - 10, true));
|
||||
assert_eq!(s.len(), 3 * u32::BITS - 10);
|
||||
s.truncate(0);
|
||||
assert_eq!(s, BitVec::from_elem(0, true));
|
||||
assert_eq!(s.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_reserve() {
|
||||
let mut s = BitVec::from_elem(5 * u32::BITS, true);
|
||||
// Check capacity
|
||||
assert!(s.capacity() >= 5 * u32::BITS);
|
||||
s.reserve(2 * u32::BITS);
|
||||
assert!(s.capacity() >= 7 * u32::BITS);
|
||||
s.reserve(7 * u32::BITS);
|
||||
assert!(s.capacity() >= 12 * u32::BITS);
|
||||
s.reserve_exact(7 * u32::BITS);
|
||||
assert!(s.capacity() >= 12 * u32::BITS);
|
||||
s.reserve(7 * u32::BITS + 1);
|
||||
assert!(s.capacity() >= 12 * u32::BITS + 1);
|
||||
// Check that length hasn't changed
|
||||
assert_eq!(s.len(), 5 * u32::BITS);
|
||||
s.push(true);
|
||||
s.push(false);
|
||||
s.push(true);
|
||||
assert_eq!(s[5 * u32::BITS - 1], true);
|
||||
assert_eq!(s[5 * u32::BITS - 0], true);
|
||||
assert_eq!(s[5 * u32::BITS + 1], false);
|
||||
assert_eq!(s[5 * u32::BITS + 2], true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_grow() {
|
||||
let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010]);
|
||||
bit_vec.grow(32, true);
|
||||
assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
|
||||
0xFF, 0xFF, 0xFF, 0xFF]));
|
||||
bit_vec.grow(64, false);
|
||||
assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
|
||||
bit_vec.grow(16, true);
|
||||
assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_extend() {
|
||||
let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
|
||||
let ext = BitVec::from_bytes(&[0b01001001, 0b10010010, 0b10111101]);
|
||||
bit_vec.extend(&ext);
|
||||
assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111,
|
||||
0b01001001, 0b10010010, 0b10111101]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vecextend_ref() {
|
||||
let mut bv = BitVec::from_bytes(&[0b10100011]);
|
||||
bv.extend(&[true, false, true]);
|
||||
|
||||
assert_eq!(bv.len(), 11);
|
||||
assert!(bv.eq_vec(&[true, false, true, false, false, false, true, true,
|
||||
true, false, true]));
|
||||
|
||||
let bw = BitVec::from_bytes(&[0b00010001]);
|
||||
bv.extend(&bw);
|
||||
|
||||
assert_eq!(bv.len(), 19);
|
||||
assert!(bv.eq_vec(&[true, false, true, false, false, false, true, true,
|
||||
true, false, true, false, false, false, true, false,
|
||||
false, false, true]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_append() {
|
||||
// Append to BitVec that holds a multiple of u32::BITS bits
|
||||
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011]);
|
||||
let mut b = BitVec::new();
|
||||
b.push(false);
|
||||
b.push(true);
|
||||
b.push(true);
|
||||
|
||||
a.append(&mut b);
|
||||
|
||||
assert_eq!(a.len(), 35);
|
||||
assert_eq!(b.len(), 0);
|
||||
assert!(b.capacity() >= 3);
|
||||
|
||||
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
|
||||
false, false, false, true, false, false, true, false,
|
||||
true, false, false, true, false, false, true, false,
|
||||
false, false, true, true, false, false, true, true,
|
||||
false, true, true]));
|
||||
|
||||
// Append to arbitrary BitVec
|
||||
let mut a = BitVec::new();
|
||||
a.push(true);
|
||||
a.push(false);
|
||||
|
||||
let mut b = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]);
|
||||
|
||||
a.append(&mut b);
|
||||
|
||||
assert_eq!(a.len(), 42);
|
||||
assert_eq!(b.len(), 0);
|
||||
assert!(b.capacity() >= 40);
|
||||
|
||||
assert!(a.eq_vec(&[true, false, true, false, true, false, false, false,
|
||||
false, false, false, false, false, true, false, false,
|
||||
true, false, true, false, false, true, false, false,
|
||||
true, false, false, false, true, true, false, false,
|
||||
true, true, true, false, false, true, false, true,
|
||||
false, true]));
|
||||
|
||||
// Append to empty BitVec
|
||||
let mut a = BitVec::new();
|
||||
let mut b = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]);
|
||||
|
||||
a.append(&mut b);
|
||||
|
||||
assert_eq!(a.len(), 40);
|
||||
assert_eq!(b.len(), 0);
|
||||
assert!(b.capacity() >= 40);
|
||||
|
||||
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
|
||||
false, false, false, true, false, false, true, false,
|
||||
true, false, false, true, false, false, true, false,
|
||||
false, false, true, true, false, false, true, true,
|
||||
true, false, false, true, false, true, false, true]));
|
||||
|
||||
// Append empty BitVec
|
||||
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]);
|
||||
let mut b = BitVec::new();
|
||||
|
||||
a.append(&mut b);
|
||||
|
||||
assert_eq!(a.len(), 40);
|
||||
assert_eq!(b.len(), 0);
|
||||
|
||||
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
|
||||
false, false, false, true, false, false, true, false,
|
||||
true, false, false, true, false, false, true, false,
|
||||
false, false, true, true, false, false, true, true,
|
||||
true, false, false, true, false, true, false, true]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_vec_split_off() {
|
||||
// Split at 0
|
||||
let mut a = BitVec::new();
|
||||
a.push(true);
|
||||
a.push(false);
|
||||
a.push(false);
|
||||
a.push(true);
|
||||
|
||||
let b = a.split_off(0);
|
||||
|
||||
assert_eq!(a.len(), 0);
|
||||
assert_eq!(b.len(), 4);
|
||||
|
||||
assert!(b.eq_vec(&[true, false, false, true]));
|
||||
|
||||
// Split at last bit
|
||||
a.truncate(0);
|
||||
a.push(true);
|
||||
a.push(false);
|
||||
a.push(false);
|
||||
a.push(true);
|
||||
|
||||
let b = a.split_off(4);
|
||||
|
||||
assert_eq!(a.len(), 4);
|
||||
assert_eq!(b.len(), 0);
|
||||
|
||||
assert!(a.eq_vec(&[true, false, false, true]));
|
||||
|
||||
// Split at block boundary
|
||||
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b11110011]);
|
||||
|
||||
let b = a.split_off(32);
|
||||
|
||||
assert_eq!(a.len(), 32);
|
||||
assert_eq!(b.len(), 8);
|
||||
|
||||
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
|
||||
false, false, false, true, false, false, true, false,
|
||||
true, false, false, true, false, false, true, false,
|
||||
false, false, true, true, false, false, true, true]));
|
||||
assert!(b.eq_vec(&[true, true, true, true, false, false, true, true]));
|
||||
|
||||
// Don't split at block boundary
|
||||
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011,
|
||||
0b01101011, 0b10101101]);
|
||||
|
||||
let b = a.split_off(13);
|
||||
|
||||
assert_eq!(a.len(), 13);
|
||||
assert_eq!(b.len(), 35);
|
||||
|
||||
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
|
||||
false, false, false, true, false]));
|
||||
assert!(b.eq_vec(&[false, true, false, true, false, false, true, false,
|
||||
false, true, false, false, false, true, true, false,
|
||||
false, true, true, false, true, true, false, true,
|
||||
false, true, true, true, false, true, false, true,
|
||||
true, false, true]));
|
||||
}
|
||||
|
||||
mod bench {
|
||||
use std::collections::BitVec;
|
||||
use std::u32;
|
||||
use std::__rand::{Rng, thread_rng, ThreadRng};
|
||||
|
||||
use test::{Bencher, black_box};
|
||||
|
||||
const BENCH_BITS : usize = 1 << 14;
|
||||
|
||||
fn rng() -> ThreadRng {
|
||||
thread_rng()
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_usize_small(b: &mut Bencher) {
|
||||
let mut r = rng();
|
||||
let mut bit_vec = 0 as usize;
|
||||
b.iter(|| {
|
||||
for _ in 0..100 {
|
||||
bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS);
|
||||
}
|
||||
black_box(&bit_vec);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_bit_set_big_fixed(b: &mut Bencher) {
|
||||
let mut r = rng();
|
||||
let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
|
||||
b.iter(|| {
|
||||
for _ in 0..100 {
|
||||
bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true);
|
||||
}
|
||||
black_box(&bit_vec);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_bit_set_big_variable(b: &mut Bencher) {
|
||||
let mut r = rng();
|
||||
let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
|
||||
b.iter(|| {
|
||||
for _ in 0..100 {
|
||||
bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
|
||||
}
|
||||
black_box(&bit_vec);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_bit_set_small(b: &mut Bencher) {
|
||||
let mut r = rng();
|
||||
let mut bit_vec = BitVec::from_elem(u32::BITS, false);
|
||||
b.iter(|| {
|
||||
for _ in 0..100 {
|
||||
bit_vec.set((r.next_u32() as usize) % u32::BITS, true);
|
||||
}
|
||||
black_box(&bit_vec);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_bit_vec_big_union(b: &mut Bencher) {
|
||||
let mut b1 = BitVec::from_elem(BENCH_BITS, false);
|
||||
let b2 = BitVec::from_elem(BENCH_BITS, false);
|
||||
b.iter(|| {
|
||||
b1.union(&b2)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_bit_vec_small_iter(b: &mut Bencher) {
|
||||
let bit_vec = BitVec::from_elem(u32::BITS, false);
|
||||
b.iter(|| {
|
||||
let mut sum = 0;
|
||||
for _ in 0..10 {
|
||||
for pres in &bit_vec {
|
||||
sum += pres as usize;
|
||||
}
|
||||
}
|
||||
sum
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_bit_vec_big_iter(b: &mut Bencher) {
|
||||
let bit_vec = BitVec::from_elem(BENCH_BITS, false);
|
||||
b.iter(|| {
|
||||
let mut sum = 0;
|
||||
for pres in &bit_vec {
|
||||
sum += pres as usize;
|
||||
}
|
||||
sum
|
||||
})
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use std::hash::{SipHasher, self};
|
||||
|
||||
#[test]
|
||||
fn test_clone_eq() {
|
||||
|
@ -34,7 +33,7 @@ fn test_hash() {
|
|||
y.insert(2);
|
||||
y.insert(1);
|
||||
|
||||
assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
|
||||
assert!(::hash(&x) == ::hash(&y));
|
||||
}
|
||||
|
||||
struct Counter<'a, 'b> {
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
#![feature(ascii)]
|
||||
#![feature(append)]
|
||||
#![feature(bitset)]
|
||||
#![feature(bitvec)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(btree_range)]
|
||||
#![feature(collections)]
|
||||
|
@ -21,24 +19,14 @@
|
|||
#![feature(deque_extras)]
|
||||
#![feature(drain)]
|
||||
#![feature(enumset)]
|
||||
#![feature(hash_default)]
|
||||
#![feature(into_cow)]
|
||||
#![feature(iter_idx)]
|
||||
#![feature(iter_order)]
|
||||
#![feature(iter_arith)]
|
||||
#![feature(iter_to_vec)]
|
||||
#![feature(map_in_place)]
|
||||
#![feature(move_from)]
|
||||
#![feature(num_bits_bytes)]
|
||||
#![feature(pattern)]
|
||||
#![feature(permutations)]
|
||||
#![feature(rand)]
|
||||
#![feature(range_inclusive)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(slice_bytes)]
|
||||
#![feature(slice_chars)]
|
||||
#![feature(slice_splits)]
|
||||
#![feature(slice_position_elem)]
|
||||
#![feature(split_off)]
|
||||
#![feature(step_by)]
|
||||
#![feature(str_char)]
|
||||
|
@ -47,16 +35,11 @@
|
|||
#![feature(str_split_at)]
|
||||
#![feature(str_utf16)]
|
||||
#![feature(box_str)]
|
||||
#![feature(subslice_offset)]
|
||||
#![feature(test)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unicode)]
|
||||
#![feature(vec_deque_retain)]
|
||||
#![feature(vec_from_raw_buf)]
|
||||
#![feature(vec_push_all)]
|
||||
#![feature(vecmap)]
|
||||
|
||||
#![allow(deprecated)]
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
|
||||
|
@ -64,10 +47,11 @@ extern crate collections;
|
|||
extern crate test;
|
||||
extern crate rustc_unicode;
|
||||
|
||||
use std::hash::{Hash, Hasher, SipHasher};
|
||||
|
||||
#[cfg(test)] #[macro_use] mod bench;
|
||||
|
||||
mod binary_heap;
|
||||
mod bit;
|
||||
mod btree;
|
||||
mod enum_set;
|
||||
mod fmt;
|
||||
|
@ -76,5 +60,10 @@ mod slice;
|
|||
mod str;
|
||||
mod string;
|
||||
mod vec_deque;
|
||||
mod vec_map;
|
||||
mod vec;
|
||||
|
||||
fn hash<T: Hash>(t: &T) -> u64 {
|
||||
let mut s = SipHasher::new();
|
||||
t.hash(&mut s);
|
||||
s.finish()
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
use std::collections::LinkedList;
|
||||
use std::hash::{SipHasher, self};
|
||||
|
||||
use test;
|
||||
|
||||
|
@ -257,7 +256,7 @@ fn test_hash() {
|
|||
let mut x = LinkedList::new();
|
||||
let mut y = LinkedList::new();
|
||||
|
||||
assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
|
||||
assert!(::hash(&x) == ::hash(&y));
|
||||
|
||||
x.push_back(1);
|
||||
x.push_back(2);
|
||||
|
@ -267,7 +266,7 @@ fn test_hash() {
|
|||
y.push_front(2);
|
||||
y.push_front(1);
|
||||
|
||||
assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
|
||||
assert!(::hash(&x) == ::hash(&y));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -10,11 +10,9 @@
|
|||
|
||||
use std::cmp::Ordering::{Equal, Greater, Less};
|
||||
use std::default::Default;
|
||||
use std::iter::RandomAccessIterator;
|
||||
use std::mem;
|
||||
use std::__rand::{Rng, thread_rng};
|
||||
use std::rc::Rc;
|
||||
use std::slice::ElementSwaps;
|
||||
|
||||
fn square(n: usize) -> usize { n * n }
|
||||
|
||||
|
@ -366,97 +364,6 @@ fn test_retain() {
|
|||
assert_eq!(v, [1, 3, 5]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_element_swaps() {
|
||||
let mut v = [1, 2, 3];
|
||||
for (i, (a, b)) in ElementSwaps::new(v.len()).enumerate() {
|
||||
v.swap(a, b);
|
||||
match i {
|
||||
0 => assert!(v == [1, 3, 2]),
|
||||
1 => assert!(v == [3, 1, 2]),
|
||||
2 => assert!(v == [3, 2, 1]),
|
||||
3 => assert!(v == [2, 3, 1]),
|
||||
4 => assert!(v == [2, 1, 3]),
|
||||
5 => assert!(v == [1, 2, 3]),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lexicographic_permutations() {
|
||||
let v : &mut[_] = &mut[1, 2, 3, 4, 5];
|
||||
assert!(v.prev_permutation() == false);
|
||||
assert!(v.next_permutation());
|
||||
let b: &mut[_] = &mut[1, 2, 3, 5, 4];
|
||||
assert!(v == b);
|
||||
assert!(v.prev_permutation());
|
||||
let b: &mut[_] = &mut[1, 2, 3, 4, 5];
|
||||
assert!(v == b);
|
||||
assert!(v.next_permutation());
|
||||
assert!(v.next_permutation());
|
||||
let b: &mut[_] = &mut[1, 2, 4, 3, 5];
|
||||
assert!(v == b);
|
||||
assert!(v.next_permutation());
|
||||
let b: &mut[_] = &mut[1, 2, 4, 5, 3];
|
||||
assert!(v == b);
|
||||
|
||||
let v : &mut[_] = &mut[1, 0, 0, 0];
|
||||
assert!(v.next_permutation() == false);
|
||||
assert!(v.prev_permutation());
|
||||
let b: &mut[_] = &mut[0, 1, 0, 0];
|
||||
assert!(v == b);
|
||||
assert!(v.prev_permutation());
|
||||
let b: &mut[_] = &mut[0, 0, 1, 0];
|
||||
assert!(v == b);
|
||||
assert!(v.prev_permutation());
|
||||
let b: &mut[_] = &mut[0, 0, 0, 1];
|
||||
assert!(v == b);
|
||||
assert!(v.prev_permutation() == false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lexicographic_permutations_empty_and_short() {
|
||||
let empty : &mut[i32] = &mut[];
|
||||
assert!(empty.next_permutation() == false);
|
||||
let b: &mut[i32] = &mut[];
|
||||
assert!(empty == b);
|
||||
assert!(empty.prev_permutation() == false);
|
||||
assert!(empty == b);
|
||||
|
||||
let one_elem : &mut[_] = &mut[4];
|
||||
assert!(one_elem.prev_permutation() == false);
|
||||
let b: &mut[_] = &mut[4];
|
||||
assert!(one_elem == b);
|
||||
assert!(one_elem.next_permutation() == false);
|
||||
assert!(one_elem == b);
|
||||
|
||||
let two_elem : &mut[_] = &mut[1, 2];
|
||||
assert!(two_elem.prev_permutation() == false);
|
||||
let b : &mut[_] = &mut[1, 2];
|
||||
let c : &mut[_] = &mut[2, 1];
|
||||
assert!(two_elem == b);
|
||||
assert!(two_elem.next_permutation());
|
||||
assert!(two_elem == c);
|
||||
assert!(two_elem.next_permutation() == false);
|
||||
assert!(two_elem == c);
|
||||
assert!(two_elem.prev_permutation());
|
||||
assert!(two_elem == b);
|
||||
assert!(two_elem.prev_permutation() == false);
|
||||
assert!(two_elem == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_position_elem() {
|
||||
assert!([].position_elem(&1).is_none());
|
||||
|
||||
let v1 = vec![1, 2, 3, 3, 2, 5];
|
||||
assert_eq!(v1.position_elem(&1), Some(0));
|
||||
assert_eq!(v1.position_elem(&2), Some(1));
|
||||
assert_eq!(v1.position_elem(&5), Some(5));
|
||||
assert!(v1.position_elem(&4).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_binary_search() {
|
||||
assert_eq!([1,2,3,4,5].binary_search(&5).ok(), Some(4));
|
||||
|
@ -668,21 +575,6 @@ fn test_slice_2() {
|
|||
assert_eq!(v[1], 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_permute_fail() {
|
||||
let v: [(Box<_>, Rc<_>); 4] =
|
||||
[(box 0, Rc::new(0)), (box 0, Rc::new(0)),
|
||||
(box 0, Rc::new(0)), (box 0, Rc::new(0))];
|
||||
let mut i = 0;
|
||||
for _ in v.permutations() {
|
||||
if i == 2 {
|
||||
panic!()
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_total_ord() {
|
||||
let c = &[1, 2, 3];
|
||||
|
@ -715,44 +607,6 @@ fn test_iterator() {
|
|||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_iterator() {
|
||||
let xs = [1, 2, 5, 10, 11];
|
||||
let mut it = xs.iter();
|
||||
|
||||
assert_eq!(it.indexable(), 5);
|
||||
assert_eq!(it.idx(0).unwrap(), &1);
|
||||
assert_eq!(it.idx(2).unwrap(), &5);
|
||||
assert_eq!(it.idx(4).unwrap(), &11);
|
||||
assert!(it.idx(5).is_none());
|
||||
|
||||
assert_eq!(it.next().unwrap(), &1);
|
||||
assert_eq!(it.indexable(), 4);
|
||||
assert_eq!(it.idx(0).unwrap(), &2);
|
||||
assert_eq!(it.idx(3).unwrap(), &11);
|
||||
assert!(it.idx(4).is_none());
|
||||
|
||||
assert_eq!(it.next().unwrap(), &2);
|
||||
assert_eq!(it.indexable(), 3);
|
||||
assert_eq!(it.idx(1).unwrap(), &10);
|
||||
assert!(it.idx(3).is_none());
|
||||
|
||||
assert_eq!(it.next().unwrap(), &5);
|
||||
assert_eq!(it.indexable(), 2);
|
||||
assert_eq!(it.idx(1).unwrap(), &11);
|
||||
|
||||
assert_eq!(it.next().unwrap(), &10);
|
||||
assert_eq!(it.indexable(), 1);
|
||||
assert_eq!(it.idx(0).unwrap(), &11);
|
||||
assert!(it.idx(1).is_none());
|
||||
|
||||
assert_eq!(it.next().unwrap(), &11);
|
||||
assert_eq!(it.indexable(), 0);
|
||||
assert!(it.idx(0).is_none());
|
||||
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter_size_hints() {
|
||||
let mut xs = [1, 2, 5, 10, 11];
|
||||
|
@ -933,15 +787,6 @@ fn test_windowsator() {
|
|||
|
||||
let wins: &[&[_]] = &[&[3,4], &[2,3], &[1,2]];
|
||||
assert_eq!(v.windows(2).rev().collect::<Vec<&[_]>>(), wins);
|
||||
let mut it = v.windows(2);
|
||||
assert_eq!(it.indexable(), 3);
|
||||
let win: &[_] = &[1,2];
|
||||
assert_eq!(it.idx(0).unwrap(), win);
|
||||
let win: &[_] = &[2,3];
|
||||
assert_eq!(it.idx(1).unwrap(), win);
|
||||
let win: &[_] = &[3,4];
|
||||
assert_eq!(it.idx(2).unwrap(), win);
|
||||
assert_eq!(it.idx(3), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -966,16 +811,6 @@ fn test_chunksator() {
|
|||
|
||||
let chunks: &[&[_]] = &[&[5], &[3,4], &[1,2]];
|
||||
assert_eq!(v.chunks(2).rev().collect::<Vec<_>>(), chunks);
|
||||
let mut it = v.chunks(2);
|
||||
assert_eq!(it.indexable(), 3);
|
||||
|
||||
let chunk: &[_] = &[1,2];
|
||||
assert_eq!(it.idx(0).unwrap(), chunk);
|
||||
let chunk: &[_] = &[3,4];
|
||||
assert_eq!(it.idx(1).unwrap(), chunk);
|
||||
let chunk: &[_] = &[5];
|
||||
assert_eq!(it.idx(2).unwrap(), chunk);
|
||||
assert_eq!(it.idx(3), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -985,26 +820,6 @@ fn test_chunksator_0() {
|
|||
let _it = v.chunks(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_move_from() {
|
||||
let mut a = [1,2,3,4,5];
|
||||
let b = vec![6,7,8];
|
||||
assert_eq!(a.move_from(b, 0, 3), 3);
|
||||
assert!(a == [6,7,8,4,5]);
|
||||
let mut a = [7,2,8,1];
|
||||
let b = vec![3,1,4,1,5,9];
|
||||
assert_eq!(a.move_from(b, 0, 6), 4);
|
||||
assert!(a == [3,1,4,1]);
|
||||
let mut a = [1,2,3,4];
|
||||
let b = vec![5,6,7,8,9,0];
|
||||
assert_eq!(a.move_from(b, 2, 3), 1);
|
||||
assert!(a == [7,2,3,4]);
|
||||
let mut a = [1,2,3,4,5];
|
||||
let b = vec![5,6,7,8,9,0];
|
||||
assert_eq!(a[2..4].move_from(b,1,6), 2);
|
||||
assert!(a == [1,2,6,7,5]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reverse_part() {
|
||||
let mut values = [1,2,3,4,5];
|
||||
|
@ -1324,7 +1139,6 @@ fn test_box_slice_clone_panics() {
|
|||
}
|
||||
|
||||
mod bench {
|
||||
use std::iter::repeat;
|
||||
use std::{mem, ptr};
|
||||
use std::__rand::{Rng, thread_rng};
|
||||
|
||||
|
|
|
@ -19,36 +19,6 @@ fn test_le() {
|
|||
assert!("foo" != "bar");
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[test]
|
||||
fn test_len() {
|
||||
assert_eq!("".len(), 0);
|
||||
assert_eq!("hello world".len(), 11);
|
||||
assert_eq!("\x63".len(), 1);
|
||||
assert_eq!("\u{a2}".len(), 2);
|
||||
assert_eq!("\u{3c0}".len(), 2);
|
||||
assert_eq!("\u{2620}".len(), 3);
|
||||
assert_eq!("\u{1d11e}".len(), 4);
|
||||
|
||||
assert_eq!("".chars().count(), 0);
|
||||
assert_eq!("hello world".chars().count(), 11);
|
||||
assert_eq!("\x63".chars().count(), 1);
|
||||
assert_eq!("\u{a2}".chars().count(), 1);
|
||||
assert_eq!("\u{3c0}".chars().count(), 1);
|
||||
assert_eq!("\u{2620}".chars().count(), 1);
|
||||
assert_eq!("\u{1d11e}".chars().count(), 1);
|
||||
assert_eq!("ประเทศไทย中华Việt Nam".chars().count(), 19);
|
||||
|
||||
assert_eq!("hello".width(false), 10);
|
||||
assert_eq!("hello".width(true), 10);
|
||||
assert_eq!("\0\0\0\0\0".width(false), 0);
|
||||
assert_eq!("\0\0\0\0\0".width(true), 0);
|
||||
assert_eq!("".width(false), 0);
|
||||
assert_eq!("".width(true), 0);
|
||||
assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(false), 4);
|
||||
assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(true), 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find() {
|
||||
assert_eq!("hello".find('l'), Some(2));
|
||||
|
@ -117,19 +87,6 @@ fn test_find_str() {
|
|||
assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_slice_chars() {
|
||||
fn t(a: &str, b: &str, start: usize) {
|
||||
assert_eq!(a.slice_chars(start, start + b.chars().count()), b);
|
||||
}
|
||||
t("", "", 0);
|
||||
t("hello", "llo", 2);
|
||||
t("hello", "el", 1);
|
||||
t("αβλ", "β", 1);
|
||||
t("αβλ", "", 3);
|
||||
assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
|
||||
}
|
||||
|
||||
fn s(x: &str) -> String { x.to_string() }
|
||||
|
||||
macro_rules! test_concat {
|
||||
|
@ -598,29 +555,6 @@ fn test_as_ptr() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subslice_offset() {
|
||||
let a = "kernelsprite";
|
||||
let b = &a[7..a.len()];
|
||||
let c = &a[0..a.len() - 6];
|
||||
assert_eq!(a.subslice_offset(b), 7);
|
||||
assert_eq!(a.subslice_offset(c), 0);
|
||||
|
||||
let string = "a\nb\nc";
|
||||
let lines: Vec<&str> = string.lines().collect();
|
||||
assert_eq!(string.subslice_offset(lines[0]), 0);
|
||||
assert_eq!(string.subslice_offset(lines[1]), 2);
|
||||
assert_eq!(string.subslice_offset(lines[2]), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_subslice_offset_2() {
|
||||
let a = "alchemiter";
|
||||
let b = "cruxtruder";
|
||||
a.subslice_offset(b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vec_str_conversions() {
|
||||
let s1: String = String::from("All mimsy were the borogoves");
|
||||
|
@ -977,88 +911,6 @@ fn test_split_whitespace() {
|
|||
assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[test]
|
||||
fn test_nfd_chars() {
|
||||
macro_rules! t {
|
||||
($input: expr, $expected: expr) => {
|
||||
assert_eq!($input.nfd_chars().collect::<String>(), $expected);
|
||||
}
|
||||
}
|
||||
t!("abc", "abc");
|
||||
t!("\u{1e0b}\u{1c4}", "d\u{307}\u{1c4}");
|
||||
t!("\u{2026}", "\u{2026}");
|
||||
t!("\u{2126}", "\u{3a9}");
|
||||
t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
|
||||
t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
|
||||
t!("a\u{301}", "a\u{301}");
|
||||
t!("\u{301}a", "\u{301}a");
|
||||
t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
|
||||
t!("\u{ac1c}", "\u{1100}\u{1162}");
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[test]
|
||||
fn test_nfkd_chars() {
|
||||
macro_rules! t {
|
||||
($input: expr, $expected: expr) => {
|
||||
assert_eq!($input.nfkd_chars().collect::<String>(), $expected);
|
||||
}
|
||||
}
|
||||
t!("abc", "abc");
|
||||
t!("\u{1e0b}\u{1c4}", "d\u{307}DZ\u{30c}");
|
||||
t!("\u{2026}", "...");
|
||||
t!("\u{2126}", "\u{3a9}");
|
||||
t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
|
||||
t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
|
||||
t!("a\u{301}", "a\u{301}");
|
||||
t!("\u{301}a", "\u{301}a");
|
||||
t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
|
||||
t!("\u{ac1c}", "\u{1100}\u{1162}");
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[test]
|
||||
fn test_nfc_chars() {
|
||||
macro_rules! t {
|
||||
($input: expr, $expected: expr) => {
|
||||
assert_eq!($input.nfc_chars().collect::<String>(), $expected);
|
||||
}
|
||||
}
|
||||
t!("abc", "abc");
|
||||
t!("\u{1e0b}\u{1c4}", "\u{1e0b}\u{1c4}");
|
||||
t!("\u{2026}", "\u{2026}");
|
||||
t!("\u{2126}", "\u{3a9}");
|
||||
t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
|
||||
t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
|
||||
t!("a\u{301}", "\u{e1}");
|
||||
t!("\u{301}a", "\u{301}a");
|
||||
t!("\u{d4db}", "\u{d4db}");
|
||||
t!("\u{ac1c}", "\u{ac1c}");
|
||||
t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[test]
|
||||
fn test_nfkc_chars() {
|
||||
macro_rules! t {
|
||||
($input: expr, $expected: expr) => {
|
||||
assert_eq!($input.nfkc_chars().collect::<String>(), $expected);
|
||||
}
|
||||
}
|
||||
t!("abc", "abc");
|
||||
t!("\u{1e0b}\u{1c4}", "\u{1e0b}D\u{17d}");
|
||||
t!("\u{2026}", "...");
|
||||
t!("\u{2126}", "\u{3a9}");
|
||||
t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
|
||||
t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
|
||||
t!("a\u{301}", "\u{e1}");
|
||||
t!("\u{301}a", "\u{301}a");
|
||||
t!("\u{d4db}", "\u{d4db}");
|
||||
t!("\u{ac1c}", "\u{ac1c}");
|
||||
t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lines() {
|
||||
let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
|
||||
|
@ -1070,417 +922,6 @@ fn test_lines() {
|
|||
assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[test]
|
||||
fn test_graphemes() {
|
||||
use std::iter::order;
|
||||
|
||||
// official Unicode test data
|
||||
// from http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
|
||||
let test_same: [(_, &[_]); 325] = [
|
||||
("\u{20}\u{20}", &["\u{20}", "\u{20}"]),
|
||||
("\u{20}\u{308}\u{20}", &["\u{20}\u{308}", "\u{20}"]),
|
||||
("\u{20}\u{D}", &["\u{20}", "\u{D}"]),
|
||||
("\u{20}\u{308}\u{D}", &["\u{20}\u{308}", "\u{D}"]),
|
||||
("\u{20}\u{A}", &["\u{20}", "\u{A}"]),
|
||||
("\u{20}\u{308}\u{A}", &["\u{20}\u{308}", "\u{A}"]),
|
||||
("\u{20}\u{1}", &["\u{20}", "\u{1}"]),
|
||||
("\u{20}\u{308}\u{1}", &["\u{20}\u{308}", "\u{1}"]),
|
||||
("\u{20}\u{300}", &["\u{20}\u{300}"]),
|
||||
("\u{20}\u{308}\u{300}", &["\u{20}\u{308}\u{300}"]),
|
||||
("\u{20}\u{1100}", &["\u{20}", "\u{1100}"]),
|
||||
("\u{20}\u{308}\u{1100}", &["\u{20}\u{308}", "\u{1100}"]),
|
||||
("\u{20}\u{1160}", &["\u{20}", "\u{1160}"]),
|
||||
("\u{20}\u{308}\u{1160}", &["\u{20}\u{308}", "\u{1160}"]),
|
||||
("\u{20}\u{11A8}", &["\u{20}", "\u{11A8}"]),
|
||||
("\u{20}\u{308}\u{11A8}", &["\u{20}\u{308}", "\u{11A8}"]),
|
||||
("\u{20}\u{AC00}", &["\u{20}", "\u{AC00}"]),
|
||||
("\u{20}\u{308}\u{AC00}", &["\u{20}\u{308}", "\u{AC00}"]),
|
||||
("\u{20}\u{AC01}", &["\u{20}", "\u{AC01}"]),
|
||||
("\u{20}\u{308}\u{AC01}", &["\u{20}\u{308}", "\u{AC01}"]),
|
||||
("\u{20}\u{1F1E6}", &["\u{20}", "\u{1F1E6}"]),
|
||||
("\u{20}\u{308}\u{1F1E6}", &["\u{20}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{20}\u{378}", &["\u{20}", "\u{378}"]),
|
||||
("\u{20}\u{308}\u{378}", &["\u{20}\u{308}", "\u{378}"]),
|
||||
("\u{D}\u{20}", &["\u{D}", "\u{20}"]),
|
||||
("\u{D}\u{308}\u{20}", &["\u{D}", "\u{308}", "\u{20}"]),
|
||||
("\u{D}\u{D}", &["\u{D}", "\u{D}"]),
|
||||
("\u{D}\u{308}\u{D}", &["\u{D}", "\u{308}", "\u{D}"]),
|
||||
("\u{D}\u{A}", &["\u{D}\u{A}"]),
|
||||
("\u{D}\u{308}\u{A}", &["\u{D}", "\u{308}", "\u{A}"]),
|
||||
("\u{D}\u{1}", &["\u{D}", "\u{1}"]),
|
||||
("\u{D}\u{308}\u{1}", &["\u{D}", "\u{308}", "\u{1}"]),
|
||||
("\u{D}\u{300}", &["\u{D}", "\u{300}"]),
|
||||
("\u{D}\u{308}\u{300}", &["\u{D}", "\u{308}\u{300}"]),
|
||||
("\u{D}\u{903}", &["\u{D}", "\u{903}"]),
|
||||
("\u{D}\u{1100}", &["\u{D}", "\u{1100}"]),
|
||||
("\u{D}\u{308}\u{1100}", &["\u{D}", "\u{308}", "\u{1100}"]),
|
||||
("\u{D}\u{1160}", &["\u{D}", "\u{1160}"]),
|
||||
("\u{D}\u{308}\u{1160}", &["\u{D}", "\u{308}", "\u{1160}"]),
|
||||
("\u{D}\u{11A8}", &["\u{D}", "\u{11A8}"]),
|
||||
("\u{D}\u{308}\u{11A8}", &["\u{D}", "\u{308}", "\u{11A8}"]),
|
||||
("\u{D}\u{AC00}", &["\u{D}", "\u{AC00}"]),
|
||||
("\u{D}\u{308}\u{AC00}", &["\u{D}", "\u{308}", "\u{AC00}"]),
|
||||
("\u{D}\u{AC01}", &["\u{D}", "\u{AC01}"]),
|
||||
("\u{D}\u{308}\u{AC01}", &["\u{D}", "\u{308}", "\u{AC01}"]),
|
||||
("\u{D}\u{1F1E6}", &["\u{D}", "\u{1F1E6}"]),
|
||||
("\u{D}\u{308}\u{1F1E6}", &["\u{D}", "\u{308}", "\u{1F1E6}"]),
|
||||
("\u{D}\u{378}", &["\u{D}", "\u{378}"]),
|
||||
("\u{D}\u{308}\u{378}", &["\u{D}", "\u{308}", "\u{378}"]),
|
||||
("\u{A}\u{20}", &["\u{A}", "\u{20}"]),
|
||||
("\u{A}\u{308}\u{20}", &["\u{A}", "\u{308}", "\u{20}"]),
|
||||
("\u{A}\u{D}", &["\u{A}", "\u{D}"]),
|
||||
("\u{A}\u{308}\u{D}", &["\u{A}", "\u{308}", "\u{D}"]),
|
||||
("\u{A}\u{A}", &["\u{A}", "\u{A}"]),
|
||||
("\u{A}\u{308}\u{A}", &["\u{A}", "\u{308}", "\u{A}"]),
|
||||
("\u{A}\u{1}", &["\u{A}", "\u{1}"]),
|
||||
("\u{A}\u{308}\u{1}", &["\u{A}", "\u{308}", "\u{1}"]),
|
||||
("\u{A}\u{300}", &["\u{A}", "\u{300}"]),
|
||||
("\u{A}\u{308}\u{300}", &["\u{A}", "\u{308}\u{300}"]),
|
||||
("\u{A}\u{903}", &["\u{A}", "\u{903}"]),
|
||||
("\u{A}\u{1100}", &["\u{A}", "\u{1100}"]),
|
||||
("\u{A}\u{308}\u{1100}", &["\u{A}", "\u{308}", "\u{1100}"]),
|
||||
("\u{A}\u{1160}", &["\u{A}", "\u{1160}"]),
|
||||
("\u{A}\u{308}\u{1160}", &["\u{A}", "\u{308}", "\u{1160}"]),
|
||||
("\u{A}\u{11A8}", &["\u{A}", "\u{11A8}"]),
|
||||
("\u{A}\u{308}\u{11A8}", &["\u{A}", "\u{308}", "\u{11A8}"]),
|
||||
("\u{A}\u{AC00}", &["\u{A}", "\u{AC00}"]),
|
||||
("\u{A}\u{308}\u{AC00}", &["\u{A}", "\u{308}", "\u{AC00}"]),
|
||||
("\u{A}\u{AC01}", &["\u{A}", "\u{AC01}"]),
|
||||
("\u{A}\u{308}\u{AC01}", &["\u{A}", "\u{308}", "\u{AC01}"]),
|
||||
("\u{A}\u{1F1E6}", &["\u{A}", "\u{1F1E6}"]),
|
||||
("\u{A}\u{308}\u{1F1E6}", &["\u{A}", "\u{308}", "\u{1F1E6}"]),
|
||||
("\u{A}\u{378}", &["\u{A}", "\u{378}"]),
|
||||
("\u{A}\u{308}\u{378}", &["\u{A}", "\u{308}", "\u{378}"]),
|
||||
("\u{1}\u{20}", &["\u{1}", "\u{20}"]),
|
||||
("\u{1}\u{308}\u{20}", &["\u{1}", "\u{308}", "\u{20}"]),
|
||||
("\u{1}\u{D}", &["\u{1}", "\u{D}"]),
|
||||
("\u{1}\u{308}\u{D}", &["\u{1}", "\u{308}", "\u{D}"]),
|
||||
("\u{1}\u{A}", &["\u{1}", "\u{A}"]),
|
||||
("\u{1}\u{308}\u{A}", &["\u{1}", "\u{308}", "\u{A}"]),
|
||||
("\u{1}\u{1}", &["\u{1}", "\u{1}"]),
|
||||
("\u{1}\u{308}\u{1}", &["\u{1}", "\u{308}", "\u{1}"]),
|
||||
("\u{1}\u{300}", &["\u{1}", "\u{300}"]),
|
||||
("\u{1}\u{308}\u{300}", &["\u{1}", "\u{308}\u{300}"]),
|
||||
("\u{1}\u{903}", &["\u{1}", "\u{903}"]),
|
||||
("\u{1}\u{1100}", &["\u{1}", "\u{1100}"]),
|
||||
("\u{1}\u{308}\u{1100}", &["\u{1}", "\u{308}", "\u{1100}"]),
|
||||
("\u{1}\u{1160}", &["\u{1}", "\u{1160}"]),
|
||||
("\u{1}\u{308}\u{1160}", &["\u{1}", "\u{308}", "\u{1160}"]),
|
||||
("\u{1}\u{11A8}", &["\u{1}", "\u{11A8}"]),
|
||||
("\u{1}\u{308}\u{11A8}", &["\u{1}", "\u{308}", "\u{11A8}"]),
|
||||
("\u{1}\u{AC00}", &["\u{1}", "\u{AC00}"]),
|
||||
("\u{1}\u{308}\u{AC00}", &["\u{1}", "\u{308}", "\u{AC00}"]),
|
||||
("\u{1}\u{AC01}", &["\u{1}", "\u{AC01}"]),
|
||||
("\u{1}\u{308}\u{AC01}", &["\u{1}", "\u{308}", "\u{AC01}"]),
|
||||
("\u{1}\u{1F1E6}", &["\u{1}", "\u{1F1E6}"]),
|
||||
("\u{1}\u{308}\u{1F1E6}", &["\u{1}", "\u{308}", "\u{1F1E6}"]),
|
||||
("\u{1}\u{378}", &["\u{1}", "\u{378}"]),
|
||||
("\u{1}\u{308}\u{378}", &["\u{1}", "\u{308}", "\u{378}"]),
|
||||
("\u{300}\u{20}", &["\u{300}", "\u{20}"]),
|
||||
("\u{300}\u{308}\u{20}", &["\u{300}\u{308}", "\u{20}"]),
|
||||
("\u{300}\u{D}", &["\u{300}", "\u{D}"]),
|
||||
("\u{300}\u{308}\u{D}", &["\u{300}\u{308}", "\u{D}"]),
|
||||
("\u{300}\u{A}", &["\u{300}", "\u{A}"]),
|
||||
("\u{300}\u{308}\u{A}", &["\u{300}\u{308}", "\u{A}"]),
|
||||
("\u{300}\u{1}", &["\u{300}", "\u{1}"]),
|
||||
("\u{300}\u{308}\u{1}", &["\u{300}\u{308}", "\u{1}"]),
|
||||
("\u{300}\u{300}", &["\u{300}\u{300}"]),
|
||||
("\u{300}\u{308}\u{300}", &["\u{300}\u{308}\u{300}"]),
|
||||
("\u{300}\u{1100}", &["\u{300}", "\u{1100}"]),
|
||||
("\u{300}\u{308}\u{1100}", &["\u{300}\u{308}", "\u{1100}"]),
|
||||
("\u{300}\u{1160}", &["\u{300}", "\u{1160}"]),
|
||||
("\u{300}\u{308}\u{1160}", &["\u{300}\u{308}", "\u{1160}"]),
|
||||
("\u{300}\u{11A8}", &["\u{300}", "\u{11A8}"]),
|
||||
("\u{300}\u{308}\u{11A8}", &["\u{300}\u{308}", "\u{11A8}"]),
|
||||
("\u{300}\u{AC00}", &["\u{300}", "\u{AC00}"]),
|
||||
("\u{300}\u{308}\u{AC00}", &["\u{300}\u{308}", "\u{AC00}"]),
|
||||
("\u{300}\u{AC01}", &["\u{300}", "\u{AC01}"]),
|
||||
("\u{300}\u{308}\u{AC01}", &["\u{300}\u{308}", "\u{AC01}"]),
|
||||
("\u{300}\u{1F1E6}", &["\u{300}", "\u{1F1E6}"]),
|
||||
("\u{300}\u{308}\u{1F1E6}", &["\u{300}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{300}\u{378}", &["\u{300}", "\u{378}"]),
|
||||
("\u{300}\u{308}\u{378}", &["\u{300}\u{308}", "\u{378}"]),
|
||||
("\u{903}\u{20}", &["\u{903}", "\u{20}"]),
|
||||
("\u{903}\u{308}\u{20}", &["\u{903}\u{308}", "\u{20}"]),
|
||||
("\u{903}\u{D}", &["\u{903}", "\u{D}"]),
|
||||
("\u{903}\u{308}\u{D}", &["\u{903}\u{308}", "\u{D}"]),
|
||||
("\u{903}\u{A}", &["\u{903}", "\u{A}"]),
|
||||
("\u{903}\u{308}\u{A}", &["\u{903}\u{308}", "\u{A}"]),
|
||||
("\u{903}\u{1}", &["\u{903}", "\u{1}"]),
|
||||
("\u{903}\u{308}\u{1}", &["\u{903}\u{308}", "\u{1}"]),
|
||||
("\u{903}\u{300}", &["\u{903}\u{300}"]),
|
||||
("\u{903}\u{308}\u{300}", &["\u{903}\u{308}\u{300}"]),
|
||||
("\u{903}\u{1100}", &["\u{903}", "\u{1100}"]),
|
||||
("\u{903}\u{308}\u{1100}", &["\u{903}\u{308}", "\u{1100}"]),
|
||||
("\u{903}\u{1160}", &["\u{903}", "\u{1160}"]),
|
||||
("\u{903}\u{308}\u{1160}", &["\u{903}\u{308}", "\u{1160}"]),
|
||||
("\u{903}\u{11A8}", &["\u{903}", "\u{11A8}"]),
|
||||
("\u{903}\u{308}\u{11A8}", &["\u{903}\u{308}", "\u{11A8}"]),
|
||||
("\u{903}\u{AC00}", &["\u{903}", "\u{AC00}"]),
|
||||
("\u{903}\u{308}\u{AC00}", &["\u{903}\u{308}", "\u{AC00}"]),
|
||||
("\u{903}\u{AC01}", &["\u{903}", "\u{AC01}"]),
|
||||
("\u{903}\u{308}\u{AC01}", &["\u{903}\u{308}", "\u{AC01}"]),
|
||||
("\u{903}\u{1F1E6}", &["\u{903}", "\u{1F1E6}"]),
|
||||
("\u{903}\u{308}\u{1F1E6}", &["\u{903}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{903}\u{378}", &["\u{903}", "\u{378}"]),
|
||||
("\u{903}\u{308}\u{378}", &["\u{903}\u{308}", "\u{378}"]),
|
||||
("\u{1100}\u{20}", &["\u{1100}", "\u{20}"]),
|
||||
("\u{1100}\u{308}\u{20}", &["\u{1100}\u{308}", "\u{20}"]),
|
||||
("\u{1100}\u{D}", &["\u{1100}", "\u{D}"]),
|
||||
("\u{1100}\u{308}\u{D}", &["\u{1100}\u{308}", "\u{D}"]),
|
||||
("\u{1100}\u{A}", &["\u{1100}", "\u{A}"]),
|
||||
("\u{1100}\u{308}\u{A}", &["\u{1100}\u{308}", "\u{A}"]),
|
||||
("\u{1100}\u{1}", &["\u{1100}", "\u{1}"]),
|
||||
("\u{1100}\u{308}\u{1}", &["\u{1100}\u{308}", "\u{1}"]),
|
||||
("\u{1100}\u{300}", &["\u{1100}\u{300}"]),
|
||||
("\u{1100}\u{308}\u{300}", &["\u{1100}\u{308}\u{300}"]),
|
||||
("\u{1100}\u{1100}", &["\u{1100}\u{1100}"]),
|
||||
("\u{1100}\u{308}\u{1100}", &["\u{1100}\u{308}", "\u{1100}"]),
|
||||
("\u{1100}\u{1160}", &["\u{1100}\u{1160}"]),
|
||||
("\u{1100}\u{308}\u{1160}", &["\u{1100}\u{308}", "\u{1160}"]),
|
||||
("\u{1100}\u{11A8}", &["\u{1100}", "\u{11A8}"]),
|
||||
("\u{1100}\u{308}\u{11A8}", &["\u{1100}\u{308}", "\u{11A8}"]),
|
||||
("\u{1100}\u{AC00}", &["\u{1100}\u{AC00}"]),
|
||||
("\u{1100}\u{308}\u{AC00}", &["\u{1100}\u{308}", "\u{AC00}"]),
|
||||
("\u{1100}\u{AC01}", &["\u{1100}\u{AC01}"]),
|
||||
("\u{1100}\u{308}\u{AC01}", &["\u{1100}\u{308}", "\u{AC01}"]),
|
||||
("\u{1100}\u{1F1E6}", &["\u{1100}", "\u{1F1E6}"]),
|
||||
("\u{1100}\u{308}\u{1F1E6}", &["\u{1100}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{1100}\u{378}", &["\u{1100}", "\u{378}"]),
|
||||
("\u{1100}\u{308}\u{378}", &["\u{1100}\u{308}", "\u{378}"]),
|
||||
("\u{1160}\u{20}", &["\u{1160}", "\u{20}"]),
|
||||
("\u{1160}\u{308}\u{20}", &["\u{1160}\u{308}", "\u{20}"]),
|
||||
("\u{1160}\u{D}", &["\u{1160}", "\u{D}"]),
|
||||
("\u{1160}\u{308}\u{D}", &["\u{1160}\u{308}", "\u{D}"]),
|
||||
("\u{1160}\u{A}", &["\u{1160}", "\u{A}"]),
|
||||
("\u{1160}\u{308}\u{A}", &["\u{1160}\u{308}", "\u{A}"]),
|
||||
("\u{1160}\u{1}", &["\u{1160}", "\u{1}"]),
|
||||
("\u{1160}\u{308}\u{1}", &["\u{1160}\u{308}", "\u{1}"]),
|
||||
("\u{1160}\u{300}", &["\u{1160}\u{300}"]),
|
||||
("\u{1160}\u{308}\u{300}", &["\u{1160}\u{308}\u{300}"]),
|
||||
("\u{1160}\u{1100}", &["\u{1160}", "\u{1100}"]),
|
||||
("\u{1160}\u{308}\u{1100}", &["\u{1160}\u{308}", "\u{1100}"]),
|
||||
("\u{1160}\u{1160}", &["\u{1160}\u{1160}"]),
|
||||
("\u{1160}\u{308}\u{1160}", &["\u{1160}\u{308}", "\u{1160}"]),
|
||||
("\u{1160}\u{11A8}", &["\u{1160}\u{11A8}"]),
|
||||
("\u{1160}\u{308}\u{11A8}", &["\u{1160}\u{308}", "\u{11A8}"]),
|
||||
("\u{1160}\u{AC00}", &["\u{1160}", "\u{AC00}"]),
|
||||
("\u{1160}\u{308}\u{AC00}", &["\u{1160}\u{308}", "\u{AC00}"]),
|
||||
("\u{1160}\u{AC01}", &["\u{1160}", "\u{AC01}"]),
|
||||
("\u{1160}\u{308}\u{AC01}", &["\u{1160}\u{308}", "\u{AC01}"]),
|
||||
("\u{1160}\u{1F1E6}", &["\u{1160}", "\u{1F1E6}"]),
|
||||
("\u{1160}\u{308}\u{1F1E6}", &["\u{1160}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{1160}\u{378}", &["\u{1160}", "\u{378}"]),
|
||||
("\u{1160}\u{308}\u{378}", &["\u{1160}\u{308}", "\u{378}"]),
|
||||
("\u{11A8}\u{20}", &["\u{11A8}", "\u{20}"]),
|
||||
("\u{11A8}\u{308}\u{20}", &["\u{11A8}\u{308}", "\u{20}"]),
|
||||
("\u{11A8}\u{D}", &["\u{11A8}", "\u{D}"]),
|
||||
("\u{11A8}\u{308}\u{D}", &["\u{11A8}\u{308}", "\u{D}"]),
|
||||
("\u{11A8}\u{A}", &["\u{11A8}", "\u{A}"]),
|
||||
("\u{11A8}\u{308}\u{A}", &["\u{11A8}\u{308}", "\u{A}"]),
|
||||
("\u{11A8}\u{1}", &["\u{11A8}", "\u{1}"]),
|
||||
("\u{11A8}\u{308}\u{1}", &["\u{11A8}\u{308}", "\u{1}"]),
|
||||
("\u{11A8}\u{300}", &["\u{11A8}\u{300}"]),
|
||||
("\u{11A8}\u{308}\u{300}", &["\u{11A8}\u{308}\u{300}"]),
|
||||
("\u{11A8}\u{1100}", &["\u{11A8}", "\u{1100}"]),
|
||||
("\u{11A8}\u{308}\u{1100}", &["\u{11A8}\u{308}", "\u{1100}"]),
|
||||
("\u{11A8}\u{1160}", &["\u{11A8}", "\u{1160}"]),
|
||||
("\u{11A8}\u{308}\u{1160}", &["\u{11A8}\u{308}", "\u{1160}"]),
|
||||
("\u{11A8}\u{11A8}", &["\u{11A8}\u{11A8}"]),
|
||||
("\u{11A8}\u{308}\u{11A8}", &["\u{11A8}\u{308}", "\u{11A8}"]),
|
||||
("\u{11A8}\u{AC00}", &["\u{11A8}", "\u{AC00}"]),
|
||||
("\u{11A8}\u{308}\u{AC00}", &["\u{11A8}\u{308}", "\u{AC00}"]),
|
||||
("\u{11A8}\u{AC01}", &["\u{11A8}", "\u{AC01}"]),
|
||||
("\u{11A8}\u{308}\u{AC01}", &["\u{11A8}\u{308}", "\u{AC01}"]),
|
||||
("\u{11A8}\u{1F1E6}", &["\u{11A8}", "\u{1F1E6}"]),
|
||||
("\u{11A8}\u{308}\u{1F1E6}", &["\u{11A8}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{11A8}\u{378}", &["\u{11A8}", "\u{378}"]),
|
||||
("\u{11A8}\u{308}\u{378}", &["\u{11A8}\u{308}", "\u{378}"]),
|
||||
("\u{AC00}\u{20}", &["\u{AC00}", "\u{20}"]),
|
||||
("\u{AC00}\u{308}\u{20}", &["\u{AC00}\u{308}", "\u{20}"]),
|
||||
("\u{AC00}\u{D}", &["\u{AC00}", "\u{D}"]),
|
||||
("\u{AC00}\u{308}\u{D}", &["\u{AC00}\u{308}", "\u{D}"]),
|
||||
("\u{AC00}\u{A}", &["\u{AC00}", "\u{A}"]),
|
||||
("\u{AC00}\u{308}\u{A}", &["\u{AC00}\u{308}", "\u{A}"]),
|
||||
("\u{AC00}\u{1}", &["\u{AC00}", "\u{1}"]),
|
||||
("\u{AC00}\u{308}\u{1}", &["\u{AC00}\u{308}", "\u{1}"]),
|
||||
("\u{AC00}\u{300}", &["\u{AC00}\u{300}"]),
|
||||
("\u{AC00}\u{308}\u{300}", &["\u{AC00}\u{308}\u{300}"]),
|
||||
("\u{AC00}\u{1100}", &["\u{AC00}", "\u{1100}"]),
|
||||
("\u{AC00}\u{308}\u{1100}", &["\u{AC00}\u{308}", "\u{1100}"]),
|
||||
("\u{AC00}\u{1160}", &["\u{AC00}\u{1160}"]),
|
||||
("\u{AC00}\u{308}\u{1160}", &["\u{AC00}\u{308}", "\u{1160}"]),
|
||||
("\u{AC00}\u{11A8}", &["\u{AC00}\u{11A8}"]),
|
||||
("\u{AC00}\u{308}\u{11A8}", &["\u{AC00}\u{308}", "\u{11A8}"]),
|
||||
("\u{AC00}\u{AC00}", &["\u{AC00}", "\u{AC00}"]),
|
||||
("\u{AC00}\u{308}\u{AC00}", &["\u{AC00}\u{308}", "\u{AC00}"]),
|
||||
("\u{AC00}\u{AC01}", &["\u{AC00}", "\u{AC01}"]),
|
||||
("\u{AC00}\u{308}\u{AC01}", &["\u{AC00}\u{308}", "\u{AC01}"]),
|
||||
("\u{AC00}\u{1F1E6}", &["\u{AC00}", "\u{1F1E6}"]),
|
||||
("\u{AC00}\u{308}\u{1F1E6}", &["\u{AC00}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{AC00}\u{378}", &["\u{AC00}", "\u{378}"]),
|
||||
("\u{AC00}\u{308}\u{378}", &["\u{AC00}\u{308}", "\u{378}"]),
|
||||
("\u{AC01}\u{20}", &["\u{AC01}", "\u{20}"]),
|
||||
("\u{AC01}\u{308}\u{20}", &["\u{AC01}\u{308}", "\u{20}"]),
|
||||
("\u{AC01}\u{D}", &["\u{AC01}", "\u{D}"]),
|
||||
("\u{AC01}\u{308}\u{D}", &["\u{AC01}\u{308}", "\u{D}"]),
|
||||
("\u{AC01}\u{A}", &["\u{AC01}", "\u{A}"]),
|
||||
("\u{AC01}\u{308}\u{A}", &["\u{AC01}\u{308}", "\u{A}"]),
|
||||
("\u{AC01}\u{1}", &["\u{AC01}", "\u{1}"]),
|
||||
("\u{AC01}\u{308}\u{1}", &["\u{AC01}\u{308}", "\u{1}"]),
|
||||
("\u{AC01}\u{300}", &["\u{AC01}\u{300}"]),
|
||||
("\u{AC01}\u{308}\u{300}", &["\u{AC01}\u{308}\u{300}"]),
|
||||
("\u{AC01}\u{1100}", &["\u{AC01}", "\u{1100}"]),
|
||||
("\u{AC01}\u{308}\u{1100}", &["\u{AC01}\u{308}", "\u{1100}"]),
|
||||
("\u{AC01}\u{1160}", &["\u{AC01}", "\u{1160}"]),
|
||||
("\u{AC01}\u{308}\u{1160}", &["\u{AC01}\u{308}", "\u{1160}"]),
|
||||
("\u{AC01}\u{11A8}", &["\u{AC01}\u{11A8}"]),
|
||||
("\u{AC01}\u{308}\u{11A8}", &["\u{AC01}\u{308}", "\u{11A8}"]),
|
||||
("\u{AC01}\u{AC00}", &["\u{AC01}", "\u{AC00}"]),
|
||||
("\u{AC01}\u{308}\u{AC00}", &["\u{AC01}\u{308}", "\u{AC00}"]),
|
||||
("\u{AC01}\u{AC01}", &["\u{AC01}", "\u{AC01}"]),
|
||||
("\u{AC01}\u{308}\u{AC01}", &["\u{AC01}\u{308}", "\u{AC01}"]),
|
||||
("\u{AC01}\u{1F1E6}", &["\u{AC01}", "\u{1F1E6}"]),
|
||||
("\u{AC01}\u{308}\u{1F1E6}", &["\u{AC01}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{AC01}\u{378}", &["\u{AC01}", "\u{378}"]),
|
||||
("\u{AC01}\u{308}\u{378}", &["\u{AC01}\u{308}", "\u{378}"]),
|
||||
("\u{1F1E6}\u{20}", &["\u{1F1E6}", "\u{20}"]),
|
||||
("\u{1F1E6}\u{308}\u{20}", &["\u{1F1E6}\u{308}", "\u{20}"]),
|
||||
("\u{1F1E6}\u{D}", &["\u{1F1E6}", "\u{D}"]),
|
||||
("\u{1F1E6}\u{308}\u{D}", &["\u{1F1E6}\u{308}", "\u{D}"]),
|
||||
("\u{1F1E6}\u{A}", &["\u{1F1E6}", "\u{A}"]),
|
||||
("\u{1F1E6}\u{308}\u{A}", &["\u{1F1E6}\u{308}", "\u{A}"]),
|
||||
("\u{1F1E6}\u{1}", &["\u{1F1E6}", "\u{1}"]),
|
||||
("\u{1F1E6}\u{308}\u{1}", &["\u{1F1E6}\u{308}", "\u{1}"]),
|
||||
("\u{1F1E6}\u{300}", &["\u{1F1E6}\u{300}"]),
|
||||
("\u{1F1E6}\u{308}\u{300}", &["\u{1F1E6}\u{308}\u{300}"]),
|
||||
("\u{1F1E6}\u{1100}", &["\u{1F1E6}", "\u{1100}"]),
|
||||
("\u{1F1E6}\u{308}\u{1100}", &["\u{1F1E6}\u{308}", "\u{1100}"]),
|
||||
("\u{1F1E6}\u{1160}", &["\u{1F1E6}", "\u{1160}"]),
|
||||
("\u{1F1E6}\u{308}\u{1160}", &["\u{1F1E6}\u{308}", "\u{1160}"]),
|
||||
("\u{1F1E6}\u{11A8}", &["\u{1F1E6}", "\u{11A8}"]),
|
||||
("\u{1F1E6}\u{308}\u{11A8}", &["\u{1F1E6}\u{308}", "\u{11A8}"]),
|
||||
("\u{1F1E6}\u{AC00}", &["\u{1F1E6}", "\u{AC00}"]),
|
||||
("\u{1F1E6}\u{308}\u{AC00}", &["\u{1F1E6}\u{308}", "\u{AC00}"]),
|
||||
("\u{1F1E6}\u{AC01}", &["\u{1F1E6}", "\u{AC01}"]),
|
||||
("\u{1F1E6}\u{308}\u{AC01}", &["\u{1F1E6}\u{308}", "\u{AC01}"]),
|
||||
("\u{1F1E6}\u{1F1E6}", &["\u{1F1E6}\u{1F1E6}"]),
|
||||
("\u{1F1E6}\u{308}\u{1F1E6}", &["\u{1F1E6}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{1F1E6}\u{378}", &["\u{1F1E6}", "\u{378}"]),
|
||||
("\u{1F1E6}\u{308}\u{378}", &["\u{1F1E6}\u{308}", "\u{378}"]),
|
||||
("\u{378}\u{20}", &["\u{378}", "\u{20}"]),
|
||||
("\u{378}\u{308}\u{20}", &["\u{378}\u{308}", "\u{20}"]),
|
||||
("\u{378}\u{D}", &["\u{378}", "\u{D}"]),
|
||||
("\u{378}\u{308}\u{D}", &["\u{378}\u{308}", "\u{D}"]),
|
||||
("\u{378}\u{A}", &["\u{378}", "\u{A}"]),
|
||||
("\u{378}\u{308}\u{A}", &["\u{378}\u{308}", "\u{A}"]),
|
||||
("\u{378}\u{1}", &["\u{378}", "\u{1}"]),
|
||||
("\u{378}\u{308}\u{1}", &["\u{378}\u{308}", "\u{1}"]),
|
||||
("\u{378}\u{300}", &["\u{378}\u{300}"]),
|
||||
("\u{378}\u{308}\u{300}", &["\u{378}\u{308}\u{300}"]),
|
||||
("\u{378}\u{1100}", &["\u{378}", "\u{1100}"]),
|
||||
("\u{378}\u{308}\u{1100}", &["\u{378}\u{308}", "\u{1100}"]),
|
||||
("\u{378}\u{1160}", &["\u{378}", "\u{1160}"]),
|
||||
("\u{378}\u{308}\u{1160}", &["\u{378}\u{308}", "\u{1160}"]),
|
||||
("\u{378}\u{11A8}", &["\u{378}", "\u{11A8}"]),
|
||||
("\u{378}\u{308}\u{11A8}", &["\u{378}\u{308}", "\u{11A8}"]),
|
||||
("\u{378}\u{AC00}", &["\u{378}", "\u{AC00}"]),
|
||||
("\u{378}\u{308}\u{AC00}", &["\u{378}\u{308}", "\u{AC00}"]),
|
||||
("\u{378}\u{AC01}", &["\u{378}", "\u{AC01}"]),
|
||||
("\u{378}\u{308}\u{AC01}", &["\u{378}\u{308}", "\u{AC01}"]),
|
||||
("\u{378}\u{1F1E6}", &["\u{378}", "\u{1F1E6}"]),
|
||||
("\u{378}\u{308}\u{1F1E6}", &["\u{378}\u{308}", "\u{1F1E6}"]),
|
||||
("\u{378}\u{378}", &["\u{378}", "\u{378}"]),
|
||||
("\u{378}\u{308}\u{378}", &["\u{378}\u{308}", "\u{378}"]),
|
||||
("\u{61}\u{1F1E6}\u{62}", &["\u{61}", "\u{1F1E6}", "\u{62}"]),
|
||||
("\u{1F1F7}\u{1F1FA}", &["\u{1F1F7}\u{1F1FA}"]),
|
||||
("\u{1F1F7}\u{1F1FA}\u{1F1F8}", &["\u{1F1F7}\u{1F1FA}\u{1F1F8}"]),
|
||||
("\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}",
|
||||
&["\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}"]),
|
||||
("\u{1F1F7}\u{1F1FA}\u{200B}\u{1F1F8}\u{1F1EA}",
|
||||
&["\u{1F1F7}\u{1F1FA}", "\u{200B}", "\u{1F1F8}\u{1F1EA}"]),
|
||||
("\u{1F1E6}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{1F1E7}\u{1F1E8}"]),
|
||||
("\u{1F1E6}\u{200D}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{200D}",
|
||||
"\u{1F1E7}\u{1F1E8}"]),
|
||||
("\u{1F1E6}\u{1F1E7}\u{200D}\u{1F1E8}",
|
||||
&["\u{1F1E6}\u{1F1E7}\u{200D}", "\u{1F1E8}"]),
|
||||
("\u{20}\u{200D}\u{646}", &["\u{20}\u{200D}", "\u{646}"]),
|
||||
("\u{646}\u{200D}\u{20}", &["\u{646}\u{200D}", "\u{20}"]),
|
||||
];
|
||||
|
||||
let test_diff: [(_, &[_], &[_]); 23] = [
|
||||
("\u{20}\u{903}", &["\u{20}\u{903}"], &["\u{20}", "\u{903}"]), ("\u{20}\u{308}\u{903}",
|
||||
&["\u{20}\u{308}\u{903}"], &["\u{20}\u{308}", "\u{903}"]), ("\u{D}\u{308}\u{903}",
|
||||
&["\u{D}", "\u{308}\u{903}"], &["\u{D}", "\u{308}", "\u{903}"]), ("\u{A}\u{308}\u{903}",
|
||||
&["\u{A}", "\u{308}\u{903}"], &["\u{A}", "\u{308}", "\u{903}"]), ("\u{1}\u{308}\u{903}",
|
||||
&["\u{1}", "\u{308}\u{903}"], &["\u{1}", "\u{308}", "\u{903}"]), ("\u{300}\u{903}",
|
||||
&["\u{300}\u{903}"], &["\u{300}", "\u{903}"]), ("\u{300}\u{308}\u{903}",
|
||||
&["\u{300}\u{308}\u{903}"], &["\u{300}\u{308}", "\u{903}"]), ("\u{903}\u{903}",
|
||||
&["\u{903}\u{903}"], &["\u{903}", "\u{903}"]), ("\u{903}\u{308}\u{903}",
|
||||
&["\u{903}\u{308}\u{903}"], &["\u{903}\u{308}", "\u{903}"]), ("\u{1100}\u{903}",
|
||||
&["\u{1100}\u{903}"], &["\u{1100}", "\u{903}"]), ("\u{1100}\u{308}\u{903}",
|
||||
&["\u{1100}\u{308}\u{903}"], &["\u{1100}\u{308}", "\u{903}"]), ("\u{1160}\u{903}",
|
||||
&["\u{1160}\u{903}"], &["\u{1160}", "\u{903}"]), ("\u{1160}\u{308}\u{903}",
|
||||
&["\u{1160}\u{308}\u{903}"], &["\u{1160}\u{308}", "\u{903}"]), ("\u{11A8}\u{903}",
|
||||
&["\u{11A8}\u{903}"], &["\u{11A8}", "\u{903}"]), ("\u{11A8}\u{308}\u{903}",
|
||||
&["\u{11A8}\u{308}\u{903}"], &["\u{11A8}\u{308}", "\u{903}"]), ("\u{AC00}\u{903}",
|
||||
&["\u{AC00}\u{903}"], &["\u{AC00}", "\u{903}"]), ("\u{AC00}\u{308}\u{903}",
|
||||
&["\u{AC00}\u{308}\u{903}"], &["\u{AC00}\u{308}", "\u{903}"]), ("\u{AC01}\u{903}",
|
||||
&["\u{AC01}\u{903}"], &["\u{AC01}", "\u{903}"]), ("\u{AC01}\u{308}\u{903}",
|
||||
&["\u{AC01}\u{308}\u{903}"], &["\u{AC01}\u{308}", "\u{903}"]), ("\u{1F1E6}\u{903}",
|
||||
&["\u{1F1E6}\u{903}"], &["\u{1F1E6}", "\u{903}"]), ("\u{1F1E6}\u{308}\u{903}",
|
||||
&["\u{1F1E6}\u{308}\u{903}"], &["\u{1F1E6}\u{308}", "\u{903}"]), ("\u{378}\u{903}",
|
||||
&["\u{378}\u{903}"], &["\u{378}", "\u{903}"]), ("\u{378}\u{308}\u{903}",
|
||||
&["\u{378}\u{308}\u{903}"], &["\u{378}\u{308}", "\u{903}"]),
|
||||
];
|
||||
|
||||
for &(s, g) in &test_same[..] {
|
||||
// test forward iterator
|
||||
assert!(order::equals(s.graphemes(true), g.iter().cloned()));
|
||||
assert!(order::equals(s.graphemes(false), g.iter().cloned()));
|
||||
|
||||
// test reverse iterator
|
||||
assert!(order::equals(s.graphemes(true).rev(), g.iter().rev().cloned()));
|
||||
assert!(order::equals(s.graphemes(false).rev(), g.iter().rev().cloned()));
|
||||
}
|
||||
|
||||
for &(s, gt, gf) in &test_diff {
|
||||
// test forward iterator
|
||||
assert!(order::equals(s.graphemes(true), gt.iter().cloned()));
|
||||
assert!(order::equals(s.graphemes(false), gf.iter().cloned()));
|
||||
|
||||
// test reverse iterator
|
||||
assert!(order::equals(s.graphemes(true).rev(), gt.iter().rev().cloned()));
|
||||
assert!(order::equals(s.graphemes(false).rev(), gf.iter().rev().cloned()));
|
||||
}
|
||||
|
||||
// test the indices iterators
|
||||
let s = "a̐éö̲\r\n";
|
||||
let gr_inds = s.grapheme_indices(true).collect::<Vec<(usize, &str)>>();
|
||||
let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
|
||||
assert_eq!(gr_inds, b);
|
||||
let gr_inds = s.grapheme_indices(true).rev().collect::<Vec<(usize, &str)>>();
|
||||
let b: &[_] = &[(11, "\r\n"), (6, "ö̲"), (3, "é"), (0, "a̐")];
|
||||
assert_eq!(gr_inds, b);
|
||||
let mut gr_inds_iter = s.grapheme_indices(true);
|
||||
{
|
||||
let gr_inds = gr_inds_iter.by_ref();
|
||||
let e1 = gr_inds.size_hint();
|
||||
assert_eq!(e1, (1, Some(13)));
|
||||
let c = gr_inds.count();
|
||||
assert_eq!(c, 4);
|
||||
}
|
||||
let e2 = gr_inds_iter.size_hint();
|
||||
assert_eq!(e2, (0, Some(0)));
|
||||
|
||||
// make sure the reverse iterator does the right thing with "\n" at beginning of string
|
||||
let s = "\n\r\n\r";
|
||||
let gr = s.graphemes(true).rev().collect::<Vec<&str>>();
|
||||
let b: &[_] = &["\r", "\r\n", "\n"];
|
||||
assert_eq!(gr, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splitator() {
|
||||
fn t(s: &str, sep: &str, u: &[&str]) {
|
||||
|
|
|
@ -254,23 +254,6 @@ fn test_zip_unzip() {
|
|||
assert_eq!((3, 6), (left[2], right[2]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsafe_ptrs() {
|
||||
unsafe {
|
||||
// Test on-stack copy-from-buf.
|
||||
let a = [1, 2, 3];
|
||||
let ptr = a.as_ptr();
|
||||
let b = Vec::from_raw_buf(ptr, 3);
|
||||
assert_eq!(b, [1, 2, 3]);
|
||||
|
||||
// Test on-heap copy-from-buf.
|
||||
let c = vec![1, 2, 3, 4, 5];
|
||||
let ptr = c.as_ptr();
|
||||
let d = Vec::from_raw_buf(ptr, 5);
|
||||
assert_eq!(d, [1, 2, 3, 4, 5]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_truncate_drop() {
|
||||
static mut drops: u32 = 0;
|
||||
|
@ -323,7 +306,7 @@ fn test_index_out_of_bounds() {
|
|||
#[should_panic]
|
||||
fn test_slice_out_of_bounds_1() {
|
||||
let x = vec![1, 2, 3, 4, 5];
|
||||
&x[-1..];
|
||||
&x[!0..];
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -337,7 +320,7 @@ fn test_slice_out_of_bounds_2() {
|
|||
#[should_panic]
|
||||
fn test_slice_out_of_bounds_3() {
|
||||
let x = vec![1, 2, 3, 4, 5];
|
||||
&x[-1..4];
|
||||
&x[!0..4];
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -361,67 +344,6 @@ fn test_swap_remove_empty() {
|
|||
vec.swap_remove(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_move_iter_unwrap() {
|
||||
let mut vec = Vec::with_capacity(7);
|
||||
vec.push(1);
|
||||
vec.push(2);
|
||||
let ptr = vec.as_ptr();
|
||||
vec = vec.into_iter().into_inner();
|
||||
assert_eq!(vec.as_ptr(), ptr);
|
||||
assert_eq!(vec.capacity(), 7);
|
||||
assert_eq!(vec.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_map_in_place_incompatible_types_fail() {
|
||||
let v = vec![0, 1, 2];
|
||||
v.map_in_place(|_| ());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_map_in_place() {
|
||||
let v = vec![0, 1, 2];
|
||||
assert_eq!(v.map_in_place(|i: u32| i as i32 - 1), [-1, 0, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_map_in_place_zero_sized() {
|
||||
let v = vec![(), ()];
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct ZeroSized;
|
||||
assert_eq!(v.map_in_place(|_| ZeroSized), [ZeroSized, ZeroSized]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_map_in_place_zero_drop_count() {
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
struct Nothing;
|
||||
impl Drop for Nothing { fn drop(&mut self) { } }
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
struct ZeroSized;
|
||||
impl Drop for ZeroSized {
|
||||
fn drop(&mut self) {
|
||||
DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
const NUM_ELEMENTS: usize = 2;
|
||||
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
let v = repeat(Nothing).take(NUM_ELEMENTS).collect::<Vec<_>>();
|
||||
|
||||
DROP_COUNTER.store(0, Ordering::Relaxed);
|
||||
|
||||
let v = v.map_in_place(|_| ZeroSized);
|
||||
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
|
||||
drop(v);
|
||||
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), NUM_ELEMENTS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_move_items() {
|
||||
let vec = vec![1, 2, 3];
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::{SipHasher, self};
|
||||
|
||||
use test;
|
||||
|
||||
|
@ -603,7 +602,7 @@ fn test_hash() {
|
|||
y.push_back(2);
|
||||
y.push_back(3);
|
||||
|
||||
assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
|
||||
assert!(::hash(&x) == ::hash(&y));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,526 +0,0 @@
|
|||
// Copyright 2012-2014 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 std::collections::VecMap;
|
||||
use std::collections::vec_map::Entry::{Occupied, Vacant};
|
||||
use std::hash::{SipHasher, hash};
|
||||
|
||||
#[test]
|
||||
fn test_get_mut() {
|
||||
let mut m = VecMap::new();
|
||||
assert!(m.insert(1, 12).is_none());
|
||||
assert!(m.insert(2, 8).is_none());
|
||||
assert!(m.insert(5, 14).is_none());
|
||||
let new = 100;
|
||||
match m.get_mut(&5) {
|
||||
None => panic!(), Some(x) => *x = new
|
||||
}
|
||||
assert_eq!(m.get(&5), Some(&new));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_len() {
|
||||
let mut map = VecMap::new();
|
||||
assert_eq!(map.len(), 0);
|
||||
assert!(map.is_empty());
|
||||
assert!(map.insert(5, 20).is_none());
|
||||
assert_eq!(map.len(), 1);
|
||||
assert!(!map.is_empty());
|
||||
assert!(map.insert(11, 12).is_none());
|
||||
assert_eq!(map.len(), 2);
|
||||
assert!(!map.is_empty());
|
||||
assert!(map.insert(14, 22).is_none());
|
||||
assert_eq!(map.len(), 3);
|
||||
assert!(!map.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clear() {
|
||||
let mut map = VecMap::new();
|
||||
assert!(map.insert(5, 20).is_none());
|
||||
assert!(map.insert(11, 12).is_none());
|
||||
assert!(map.insert(14, 22).is_none());
|
||||
map.clear();
|
||||
assert!(map.is_empty());
|
||||
assert!(map.get(&5).is_none());
|
||||
assert!(map.get(&11).is_none());
|
||||
assert!(map.get(&14).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert() {
|
||||
let mut m = VecMap::new();
|
||||
assert_eq!(m.insert(1, 2), None);
|
||||
assert_eq!(m.insert(1, 3), Some(2));
|
||||
assert_eq!(m.insert(1, 4), Some(3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove() {
|
||||
let mut m = VecMap::new();
|
||||
m.insert(1, 2);
|
||||
assert_eq!(m.remove(&1), Some(2));
|
||||
assert_eq!(m.remove(&1), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys() {
|
||||
let mut map = VecMap::new();
|
||||
map.insert(1, 'a');
|
||||
map.insert(2, 'b');
|
||||
map.insert(3, 'c');
|
||||
let keys: Vec<_> = map.keys().collect();
|
||||
assert_eq!(keys.len(), 3);
|
||||
assert!(keys.contains(&1));
|
||||
assert!(keys.contains(&2));
|
||||
assert!(keys.contains(&3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_values() {
|
||||
let mut map = VecMap::new();
|
||||
map.insert(1, 'a');
|
||||
map.insert(2, 'b');
|
||||
map.insert(3, 'c');
|
||||
let values: Vec<_> = map.values().cloned().collect();
|
||||
assert_eq!(values.len(), 3);
|
||||
assert!(values.contains(&'a'));
|
||||
assert!(values.contains(&'b'));
|
||||
assert!(values.contains(&'c'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator() {
|
||||
let mut m = VecMap::new();
|
||||
|
||||
assert!(m.insert(0, 1).is_none());
|
||||
assert!(m.insert(1, 2).is_none());
|
||||
assert!(m.insert(3, 5).is_none());
|
||||
assert!(m.insert(6, 10).is_none());
|
||||
assert!(m.insert(10, 11).is_none());
|
||||
|
||||
let mut it = m.iter();
|
||||
assert_eq!(it.size_hint(), (0, Some(11)));
|
||||
assert_eq!(it.next().unwrap(), (0, &1));
|
||||
assert_eq!(it.size_hint(), (0, Some(10)));
|
||||
assert_eq!(it.next().unwrap(), (1, &2));
|
||||
assert_eq!(it.size_hint(), (0, Some(9)));
|
||||
assert_eq!(it.next().unwrap(), (3, &5));
|
||||
assert_eq!(it.size_hint(), (0, Some(7)));
|
||||
assert_eq!(it.next().unwrap(), (6, &10));
|
||||
assert_eq!(it.size_hint(), (0, Some(4)));
|
||||
assert_eq!(it.next().unwrap(), (10, &11));
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_size_hints() {
|
||||
let mut m = VecMap::new();
|
||||
|
||||
assert!(m.insert(0, 1).is_none());
|
||||
assert!(m.insert(1, 2).is_none());
|
||||
assert!(m.insert(3, 5).is_none());
|
||||
assert!(m.insert(6, 10).is_none());
|
||||
assert!(m.insert(10, 11).is_none());
|
||||
|
||||
assert_eq!(m.iter().size_hint(), (0, Some(11)));
|
||||
assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
|
||||
assert_eq!(m.iter_mut().size_hint(), (0, Some(11)));
|
||||
assert_eq!(m.iter_mut().rev().size_hint(), (0, Some(11)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_iterator() {
|
||||
let mut m = VecMap::new();
|
||||
|
||||
assert!(m.insert(0, 1).is_none());
|
||||
assert!(m.insert(1, 2).is_none());
|
||||
assert!(m.insert(3, 5).is_none());
|
||||
assert!(m.insert(6, 10).is_none());
|
||||
assert!(m.insert(10, 11).is_none());
|
||||
|
||||
for (k, v) in &mut m {
|
||||
*v += k as isize;
|
||||
}
|
||||
|
||||
let mut it = m.iter();
|
||||
assert_eq!(it.next().unwrap(), (0, &1));
|
||||
assert_eq!(it.next().unwrap(), (1, &3));
|
||||
assert_eq!(it.next().unwrap(), (3, &8));
|
||||
assert_eq!(it.next().unwrap(), (6, &16));
|
||||
assert_eq!(it.next().unwrap(), (10, &21));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev_iterator() {
|
||||
let mut m = VecMap::new();
|
||||
|
||||
assert!(m.insert(0, 1).is_none());
|
||||
assert!(m.insert(1, 2).is_none());
|
||||
assert!(m.insert(3, 5).is_none());
|
||||
assert!(m.insert(6, 10).is_none());
|
||||
assert!(m.insert(10, 11).is_none());
|
||||
|
||||
let mut it = m.iter().rev();
|
||||
assert_eq!(it.next().unwrap(), (10, &11));
|
||||
assert_eq!(it.next().unwrap(), (6, &10));
|
||||
assert_eq!(it.next().unwrap(), (3, &5));
|
||||
assert_eq!(it.next().unwrap(), (1, &2));
|
||||
assert_eq!(it.next().unwrap(), (0, &1));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_rev_iterator() {
|
||||
let mut m = VecMap::new();
|
||||
|
||||
assert!(m.insert(0, 1).is_none());
|
||||
assert!(m.insert(1, 2).is_none());
|
||||
assert!(m.insert(3, 5).is_none());
|
||||
assert!(m.insert(6, 10).is_none());
|
||||
assert!(m.insert(10, 11).is_none());
|
||||
|
||||
for (k, v) in m.iter_mut().rev() {
|
||||
*v += k as isize;
|
||||
}
|
||||
|
||||
let mut it = m.iter();
|
||||
assert_eq!(it.next().unwrap(), (0, &1));
|
||||
assert_eq!(it.next().unwrap(), (1, &3));
|
||||
assert_eq!(it.next().unwrap(), (3, &8));
|
||||
assert_eq!(it.next().unwrap(), (6, &16));
|
||||
assert_eq!(it.next().unwrap(), (10, &21));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_move_iter() {
|
||||
let mut m: VecMap<Box<_>> = VecMap::new();
|
||||
m.insert(1, box 2);
|
||||
let mut called = false;
|
||||
for (k, v) in m {
|
||||
assert!(!called);
|
||||
called = true;
|
||||
assert_eq!(k, 1);
|
||||
assert_eq!(v, box 2);
|
||||
}
|
||||
assert!(called);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drain_iterator() {
|
||||
let mut map = VecMap::new();
|
||||
map.insert(1, "a");
|
||||
map.insert(3, "c");
|
||||
map.insert(2, "b");
|
||||
|
||||
let vec: Vec<_> = map.drain().collect();
|
||||
|
||||
assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
|
||||
assert_eq!(map.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_append() {
|
||||
let mut a = VecMap::new();
|
||||
a.insert(1, "a");
|
||||
a.insert(2, "b");
|
||||
a.insert(3, "c");
|
||||
|
||||
let mut b = VecMap::new();
|
||||
b.insert(3, "d"); // Overwrite element from a
|
||||
b.insert(4, "e");
|
||||
b.insert(5, "f");
|
||||
|
||||
a.append(&mut b);
|
||||
|
||||
assert_eq!(a.len(), 5);
|
||||
assert_eq!(b.len(), 0);
|
||||
// Capacity shouldn't change for possible reuse
|
||||
assert!(b.capacity() >= 4);
|
||||
|
||||
assert_eq!(a[1], "a");
|
||||
assert_eq!(a[2], "b");
|
||||
assert_eq!(a[3], "d");
|
||||
assert_eq!(a[4], "e");
|
||||
assert_eq!(a[5], "f");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_off() {
|
||||
// Split within the key range
|
||||
let mut a = VecMap::new();
|
||||
a.insert(1, "a");
|
||||
a.insert(2, "b");
|
||||
a.insert(3, "c");
|
||||
a.insert(4, "d");
|
||||
|
||||
let b = a.split_off(3);
|
||||
|
||||
assert_eq!(a.len(), 2);
|
||||
assert_eq!(b.len(), 2);
|
||||
|
||||
assert_eq!(a[1], "a");
|
||||
assert_eq!(a[2], "b");
|
||||
|
||||
assert_eq!(b[3], "c");
|
||||
assert_eq!(b[4], "d");
|
||||
|
||||
// Split at 0
|
||||
a.clear();
|
||||
a.insert(1, "a");
|
||||
a.insert(2, "b");
|
||||
a.insert(3, "c");
|
||||
a.insert(4, "d");
|
||||
|
||||
let b = a.split_off(0);
|
||||
|
||||
assert_eq!(a.len(), 0);
|
||||
assert_eq!(b.len(), 4);
|
||||
assert_eq!(b[1], "a");
|
||||
assert_eq!(b[2], "b");
|
||||
assert_eq!(b[3], "c");
|
||||
assert_eq!(b[4], "d");
|
||||
|
||||
// Split behind max_key
|
||||
a.clear();
|
||||
a.insert(1, "a");
|
||||
a.insert(2, "b");
|
||||
a.insert(3, "c");
|
||||
a.insert(4, "d");
|
||||
|
||||
let b = a.split_off(5);
|
||||
|
||||
assert_eq!(a.len(), 4);
|
||||
assert_eq!(b.len(), 0);
|
||||
assert_eq!(a[1], "a");
|
||||
assert_eq!(a[2], "b");
|
||||
assert_eq!(a[3], "c");
|
||||
assert_eq!(a[4], "d");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let mut map = VecMap::new();
|
||||
let empty = VecMap::<i32>::new();
|
||||
|
||||
map.insert(1, 2);
|
||||
map.insert(3, 4);
|
||||
|
||||
let map_str = format!("{:?}", map);
|
||||
assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
|
||||
assert_eq!(format!("{:?}", empty), "{}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let mut a = VecMap::new();
|
||||
|
||||
a.insert(1, 'x');
|
||||
a.insert(4, 'y');
|
||||
a.insert(6, 'z');
|
||||
|
||||
assert!(a.clone() == a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq() {
|
||||
let mut a = VecMap::new();
|
||||
let mut b = VecMap::new();
|
||||
|
||||
assert!(a == b);
|
||||
assert!(a.insert(0, 5).is_none());
|
||||
assert!(a != b);
|
||||
assert!(b.insert(0, 4).is_none());
|
||||
assert!(a != b);
|
||||
assert!(a.insert(5, 19).is_none());
|
||||
assert!(a != b);
|
||||
assert!(!b.insert(0, 5).is_none());
|
||||
assert!(a != b);
|
||||
assert!(b.insert(5, 19).is_none());
|
||||
assert!(a == b);
|
||||
|
||||
a = VecMap::new();
|
||||
b = VecMap::with_capacity(1);
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lt() {
|
||||
let mut a = VecMap::new();
|
||||
let mut b = VecMap::new();
|
||||
|
||||
assert!(!(a < b) && !(b < a));
|
||||
assert!(b.insert(2, 5).is_none());
|
||||
assert!(a < b);
|
||||
assert!(a.insert(2, 7).is_none());
|
||||
assert!(!(a < b) && b < a);
|
||||
assert!(b.insert(1, 0).is_none());
|
||||
assert!(b < a);
|
||||
assert!(a.insert(0, 6).is_none());
|
||||
assert!(a < b);
|
||||
assert!(a.insert(6, 2).is_none());
|
||||
assert!(a < b && !(b < a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
let mut a = VecMap::new();
|
||||
let mut b = VecMap::new();
|
||||
|
||||
assert!(a <= b && a >= b);
|
||||
assert!(a.insert(1, 1).is_none());
|
||||
assert!(a > b && a >= b);
|
||||
assert!(b < a && b <= a);
|
||||
assert!(b.insert(2, 2).is_none());
|
||||
assert!(b > a && b >= a);
|
||||
assert!(a < b && a <= b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash() {
|
||||
let mut x = VecMap::new();
|
||||
let mut y = VecMap::new();
|
||||
|
||||
assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
|
||||
x.insert(1, 'a');
|
||||
x.insert(2, 'b');
|
||||
x.insert(3, 'c');
|
||||
|
||||
y.insert(3, 'c');
|
||||
y.insert(2, 'b');
|
||||
y.insert(1, 'a');
|
||||
|
||||
assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
|
||||
|
||||
x.insert(1000, 'd');
|
||||
x.remove(&1000);
|
||||
|
||||
assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_iter() {
|
||||
let xs = vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
|
||||
|
||||
let map: VecMap<_> = xs.iter().cloned().collect();
|
||||
|
||||
for &(k, v) in &xs {
|
||||
assert_eq!(map.get(&k), Some(&v));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_index() {
|
||||
let mut map = VecMap::new();
|
||||
|
||||
map.insert(1, 2);
|
||||
map.insert(2, 1);
|
||||
map.insert(3, 4);
|
||||
|
||||
assert_eq!(map[3], 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_index_nonexistent() {
|
||||
let mut map = VecMap::new();
|
||||
|
||||
map.insert(1, 2);
|
||||
map.insert(2, 1);
|
||||
map.insert(3, 4);
|
||||
|
||||
map[4];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_entry(){
|
||||
let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
|
||||
|
||||
let mut map: VecMap<_> = xs.iter().cloned().collect();
|
||||
|
||||
// Existing key (insert)
|
||||
match map.entry(1) {
|
||||
Vacant(_) => unreachable!(),
|
||||
Occupied(mut view) => {
|
||||
assert_eq!(view.get(), &10);
|
||||
assert_eq!(view.insert(100), 10);
|
||||
}
|
||||
}
|
||||
assert_eq!(map.get(&1).unwrap(), &100);
|
||||
assert_eq!(map.len(), 6);
|
||||
|
||||
|
||||
// Existing key (update)
|
||||
match map.entry(2) {
|
||||
Vacant(_) => unreachable!(),
|
||||
Occupied(mut view) => {
|
||||
let v = view.get_mut();
|
||||
*v *= 10;
|
||||
}
|
||||
}
|
||||
assert_eq!(map.get(&2).unwrap(), &200);
|
||||
assert_eq!(map.len(), 6);
|
||||
|
||||
// Existing key (take)
|
||||
match map.entry(3) {
|
||||
Vacant(_) => unreachable!(),
|
||||
Occupied(view) => {
|
||||
assert_eq!(view.remove(), 30);
|
||||
}
|
||||
}
|
||||
assert_eq!(map.get(&3), None);
|
||||
assert_eq!(map.len(), 5);
|
||||
|
||||
|
||||
// Inexistent key (insert)
|
||||
match map.entry(10) {
|
||||
Occupied(_) => unreachable!(),
|
||||
Vacant(view) => {
|
||||
assert_eq!(*view.insert(1000), 1000);
|
||||
}
|
||||
}
|
||||
assert_eq!(map.get(&10).unwrap(), &1000);
|
||||
assert_eq!(map.len(), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend_ref() {
|
||||
let mut a = VecMap::new();
|
||||
a.insert(1, "one");
|
||||
let mut b = VecMap::new();
|
||||
b.insert(2, "two");
|
||||
b.insert(3, "three");
|
||||
|
||||
a.extend(&b);
|
||||
|
||||
assert_eq!(a.len(), 3);
|
||||
assert_eq!(a[&1], "one");
|
||||
assert_eq!(a[&2], "two");
|
||||
assert_eq!(a[&3], "three");
|
||||
}
|
||||
|
||||
mod bench {
|
||||
use std::collections::VecMap;
|
||||
|
||||
map_insert_rand_bench!{insert_rand_100, 100, VecMap}
|
||||
map_insert_rand_bench!{insert_rand_10_000, 10_000, VecMap}
|
||||
|
||||
map_insert_seq_bench!{insert_seq_100, 100, VecMap}
|
||||
map_insert_seq_bench!{insert_seq_10_000, 10_000, VecMap}
|
||||
|
||||
map_find_rand_bench!{find_rand_100, 100, VecMap}
|
||||
map_find_rand_bench!{find_rand_10_000, 10_000, VecMap}
|
||||
|
||||
map_find_seq_bench!{find_seq_100, 100, VecMap}
|
||||
map_find_seq_bench!{find_seq_10_000, 10_000, VecMap}
|
||||
}
|
|
@ -546,20 +546,6 @@ impl<'b, T: ?Sized> Deref for Ref<'b, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Copies a `Ref`.
|
||||
///
|
||||
/// The `RefCell` is already immutably borrowed, so this cannot fail.
|
||||
///
|
||||
/// A `Clone` implementation would interfere with the widespread
|
||||
/// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
|
||||
#[deprecated(since = "1.2.0", reason = "moved to a `Ref::clone` associated function")]
|
||||
#[unstable(feature = "core",
|
||||
reason = "likely to be moved to a method, pending language changes")]
|
||||
#[inline]
|
||||
pub fn clone_ref<'b, T:Clone>(orig: &Ref<'b, T>) -> Ref<'b, T> {
|
||||
Ref::clone(orig)
|
||||
}
|
||||
|
||||
impl<'b, T: ?Sized> Ref<'b, T> {
|
||||
/// Copies a `Ref`.
|
||||
///
|
||||
|
@ -799,14 +785,7 @@ impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
|
|||
#[lang = "unsafe_cell"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct UnsafeCell<T: ?Sized> {
|
||||
/// Wrapped value
|
||||
///
|
||||
/// This field should not be accessed directly, it is made public for static
|
||||
/// initializers.
|
||||
#[deprecated(since = "1.2.0", reason = "use `get` to access the wrapped \
|
||||
value or `new` to initialize `UnsafeCell` in statics")]
|
||||
#[unstable(feature = "core")]
|
||||
pub value: T,
|
||||
value: T,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> !Sync for UnsafeCell<T> {}
|
||||
|
@ -828,7 +807,6 @@ impl<T> UnsafeCell<T> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub const fn new(value: T) -> UnsafeCell<T> {
|
||||
#![allow(deprecated)]
|
||||
UnsafeCell { value: value }
|
||||
}
|
||||
|
||||
|
@ -851,7 +829,6 @@ impl<T> UnsafeCell<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn into_inner(self) -> T {
|
||||
#![allow(deprecated)]
|
||||
self.value
|
||||
}
|
||||
}
|
||||
|
@ -871,9 +848,6 @@ impl<T: ?Sized> UnsafeCell<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn get(&self) -> *mut T {
|
||||
// FIXME(#23542) Replace with type ascription.
|
||||
#![allow(trivial_casts)]
|
||||
#![allow(deprecated)]
|
||||
&self.value as *const T as *mut T
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ use self::Ordering::*;
|
|||
|
||||
use mem;
|
||||
use marker::Sized;
|
||||
use option::Option::{self, Some, None};
|
||||
use option::Option::{self, Some};
|
||||
|
||||
/// Trait for equality comparisons which are [partial equivalence
|
||||
/// relations](http://en.wikipedia.org/wiki/Partial_equivalence_relation).
|
||||
|
@ -381,78 +381,6 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
|
|||
if v2 >= v1 { v2 } else { v1 }
|
||||
}
|
||||
|
||||
/// Compare and return the minimum of two values if there is one.
|
||||
///
|
||||
/// Returns the first argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_partial)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(Some(1), cmp::partial_min(1, 2));
|
||||
/// assert_eq!(Some(2), cmp::partial_min(2, 2));
|
||||
/// ```
|
||||
///
|
||||
/// When comparison is impossible:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_partial)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// let result = cmp::partial_min(std::f64::NAN, 1.0);
|
||||
/// assert_eq!(result, None);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_partial")]
|
||||
#[deprecated(since = "1.3.0", reason = "has not proven itself worthwhile")]
|
||||
pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
|
||||
match v1.partial_cmp(&v2) {
|
||||
Some(Less) | Some(Equal) => Some(v1),
|
||||
Some(Greater) => Some(v2),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
/// Compare and return the maximum of two values if there is one.
|
||||
///
|
||||
/// Returns the second argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_partial)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(Some(2), cmp::partial_max(1, 2));
|
||||
/// assert_eq!(Some(2), cmp::partial_max(2, 2));
|
||||
/// ```
|
||||
///
|
||||
/// When comparison is impossible:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_partial)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// let result = cmp::partial_max(std::f64::NAN, 1.0);
|
||||
/// assert_eq!(result, None);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_partial")]
|
||||
#[deprecated(since = "1.3.0", reason = "has not proven itself worthwhile")]
|
||||
pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
|
||||
match v1.partial_cmp(&v2) {
|
||||
Some(Equal) | Some(Less) => Some(v2),
|
||||
Some(Greater) => Some(v1),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
|
||||
mod impls {
|
||||
use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering};
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
//! # Examples
|
||||
//!
|
||||
//! ```rust
|
||||
//! #![feature(hash_default)]
|
||||
//!
|
||||
//! use std::hash::{hash, Hash, SipHasher};
|
||||
//! use std::hash::{Hash, SipHasher, Hasher};
|
||||
//!
|
||||
//! #[derive(Hash)]
|
||||
//! struct Person {
|
||||
|
@ -30,16 +28,20 @@
|
|||
//! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
|
||||
//! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
|
||||
//!
|
||||
//! assert!(hash::<_, SipHasher>(&person1) != hash::<_, SipHasher>(&person2));
|
||||
//! assert!(hash(&person1) != hash(&person2));
|
||||
//!
|
||||
//! fn hash<T: Hash>(t: &T) -> u64 {
|
||||
//! let mut s = SipHasher::new();
|
||||
//! t.hash(&mut s);
|
||||
//! s.finish()
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! If you need more control over how a value is hashed, you need to implement
|
||||
//! the trait `Hash`:
|
||||
//!
|
||||
//! ```rust
|
||||
//! #![feature(hash_default)]
|
||||
//!
|
||||
//! use std::hash::{hash, Hash, Hasher, SipHasher};
|
||||
//! use std::hash::{Hash, Hasher, SipHasher};
|
||||
//!
|
||||
//! struct Person {
|
||||
//! id: u32,
|
||||
|
@ -57,7 +59,13 @@
|
|||
//! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
|
||||
//! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
|
||||
//!
|
||||
//! assert_eq!(hash::<_, SipHasher>(&person1), hash::<_, SipHasher>(&person2));
|
||||
//! assert_eq!(hash(&person1), hash(&person2));
|
||||
//!
|
||||
//! fn hash<T: Hash>(t: &T) -> u64 {
|
||||
//! let mut s = SipHasher::new();
|
||||
//! t.hash(&mut s);
|
||||
//! s.finish()
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -165,21 +173,6 @@ pub trait Hasher {
|
|||
fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) }
|
||||
}
|
||||
|
||||
/// Hash a value with the default SipHasher algorithm (two initial keys of 0).
|
||||
///
|
||||
/// The specified value will be hashed with this hasher and then the resulting
|
||||
/// hash will be returned.
|
||||
#[unstable(feature = "hash_default",
|
||||
reason = "not the most ergonomic interface unless `H` is defaulted \
|
||||
to SipHasher, but perhaps not ready to commit to that")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "has yet to prove itself useful")]
|
||||
pub fn hash<T: Hash, H: Hasher + Default>(value: &T) -> u64 {
|
||||
let mut h: H = Default::default();
|
||||
value.hash(&mut h);
|
||||
h.finish()
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod impls {
|
||||
|
|
|
@ -56,9 +56,6 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
#[allow(deprecated)]
|
||||
use self::MinMaxResult::*;
|
||||
|
||||
use clone::Clone;
|
||||
use cmp;
|
||||
use cmp::{Ord, PartialOrd, PartialEq};
|
||||
|
@ -445,7 +442,6 @@ pub trait Iterator {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
|
||||
where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option<B>,
|
||||
{
|
||||
|
@ -806,89 +802,6 @@ pub trait Iterator {
|
|||
.map(|(_, x)| x)
|
||||
}
|
||||
|
||||
/// `min_max` finds the minimum and maximum elements in the iterator.
|
||||
///
|
||||
/// The return type `MinMaxResult` is an enum of three variants:
|
||||
///
|
||||
/// - `NoElements` if the iterator is empty.
|
||||
/// - `OneElement(x)` if the iterator has exactly one element.
|
||||
/// - `MinMax(x, y)` is returned otherwise, where `x <= y`. Two
|
||||
/// values are equal if and only if there is more than one
|
||||
/// element in the iterator and all elements are equal.
|
||||
///
|
||||
/// On an iterator of length `n`, `min_max` does `1.5 * n` comparisons,
|
||||
/// and so is faster than calling `min` and `max` separately which does `2 *
|
||||
/// n` comparisons.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_min_max)]
|
||||
///
|
||||
/// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax};
|
||||
///
|
||||
/// let a: [i32; 0] = [];
|
||||
/// assert_eq!(a.iter().min_max(), NoElements);
|
||||
///
|
||||
/// let a = [1];
|
||||
/// assert_eq!(a.iter().min_max(), OneElement(&1));
|
||||
///
|
||||
/// let a = [1, 2, 3, 4, 5];
|
||||
/// assert_eq!(a.iter().min_max(), MinMax(&1, &5));
|
||||
///
|
||||
/// let a = [1, 1, 1, 1];
|
||||
/// assert_eq!(a.iter().min_max(), MinMax(&1, &1));
|
||||
/// ```
|
||||
#[unstable(feature = "iter_min_max",
|
||||
reason = "return type may change or may wish to have a closure \
|
||||
based version as well")]
|
||||
#[deprecated(since = "1.3.0", reason = "has not proven itself")]
|
||||
#[allow(deprecated)]
|
||||
fn min_max(mut self) -> MinMaxResult<Self::Item> where Self: Sized, Self::Item: Ord
|
||||
{
|
||||
let (mut min, mut max) = match self.next() {
|
||||
None => return NoElements,
|
||||
Some(x) => {
|
||||
match self.next() {
|
||||
None => return OneElement(x),
|
||||
Some(y) => if x <= y {(x, y)} else {(y, x)}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
loop {
|
||||
// `first` and `second` are the two next elements we want to look
|
||||
// at. We first compare `first` and `second` (#1). The smaller one
|
||||
// is then compared to current minimum (#2). The larger one is
|
||||
// compared to current maximum (#3). This way we do 3 comparisons
|
||||
// for 2 elements.
|
||||
let first = match self.next() {
|
||||
None => break,
|
||||
Some(x) => x
|
||||
};
|
||||
let second = match self.next() {
|
||||
None => {
|
||||
if first < min {
|
||||
min = first;
|
||||
} else if first >= max {
|
||||
max = first;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Some(x) => x
|
||||
};
|
||||
if first <= second {
|
||||
if first < min { min = first }
|
||||
if second >= max { max = second }
|
||||
} else {
|
||||
if second < min { min = second }
|
||||
if first >= max { max = first }
|
||||
}
|
||||
}
|
||||
|
||||
MinMax(min, max)
|
||||
}
|
||||
|
||||
/// Returns the element that gives the maximum value from the
|
||||
/// specified function.
|
||||
///
|
||||
|
@ -1046,22 +959,6 @@ pub trait Iterator {
|
|||
Cycle{orig: self.clone(), iter: self}
|
||||
}
|
||||
|
||||
/// Use an iterator to reverse a container in place.
|
||||
#[unstable(feature = "core",
|
||||
reason = "uncertain about placement or widespread use")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "not performant enough to justify inclusion")]
|
||||
fn reverse_in_place<'a, T: 'a>(&mut self) where
|
||||
Self: Sized + Iterator<Item=&'a mut T> + DoubleEndedIterator
|
||||
{
|
||||
loop {
|
||||
match (self.next(), self.next_back()) {
|
||||
(Some(x), Some(y)) => mem::swap(x, y),
|
||||
_ => break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterates over the entire iterator, summing up all the elements
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -1229,29 +1126,6 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
|
|||
fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() }
|
||||
}
|
||||
|
||||
/// An object implementing random access indexing by `usize`
|
||||
///
|
||||
/// A `RandomAccessIterator` should be either infinite or a
|
||||
/// `DoubleEndedIterator`. Calling `next()` or `next_back()` on a
|
||||
/// `RandomAccessIterator` reduces the indexable range accordingly. That is,
|
||||
/// `it.idx(1)` will become `it.idx(0)` after `it.next()` is called.
|
||||
#[unstable(feature = "iter_idx",
|
||||
reason = "not widely used, may be better decomposed into Index \
|
||||
and ExactSizeIterator")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "trait has not proven itself as a widely useful \
|
||||
abstraction for iterators, and more time may be needed \
|
||||
for iteration on the design")]
|
||||
#[allow(deprecated)]
|
||||
pub trait RandomAccessIterator: Iterator {
|
||||
/// Returns the number of indexable elements. At most `std::usize::MAX`
|
||||
/// elements are indexable, even if the iterator represents a longer range.
|
||||
fn indexable(&self) -> usize;
|
||||
|
||||
/// Returns an element at an index, or `None` if the index is out of bounds
|
||||
fn idx(&mut self, index: usize) -> Option<Self::Item>;
|
||||
}
|
||||
|
||||
/// An iterator that knows its exact length
|
||||
///
|
||||
/// This trait is a helper for iterators like the vector iterator, so that
|
||||
|
@ -1321,78 +1195,6 @@ impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator {
|
|||
fn next_back(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next() }
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<I> RandomAccessIterator for Rev<I>
|
||||
where I: DoubleEndedIterator + RandomAccessIterator
|
||||
{
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize { self.iter.indexable() }
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<<I as Iterator>::Item> {
|
||||
let amt = self.indexable();
|
||||
if amt > index {
|
||||
self.iter.idx(amt - index - 1)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `MinMaxResult` is an enum returned by `min_max`. See `Iterator::min_max` for
|
||||
/// more detail.
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[unstable(feature = "iter_min_max",
|
||||
reason = "unclear whether such a fine-grained result is widely useful")]
|
||||
#[deprecated(since = "1.3.0", reason = "has not proven itself")]
|
||||
#[allow(deprecated)]
|
||||
pub enum MinMaxResult<T> {
|
||||
/// Empty iterator
|
||||
NoElements,
|
||||
|
||||
/// Iterator with one element, so the minimum and maximum are the same
|
||||
OneElement(T),
|
||||
|
||||
/// More than one element in the iterator, the first element is not larger
|
||||
/// than the second
|
||||
MinMax(T, T)
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_min_max", reason = "type is unstable")]
|
||||
#[deprecated(since = "1.3.0", reason = "has not proven itself")]
|
||||
#[allow(deprecated)]
|
||||
impl<T: Clone> MinMaxResult<T> {
|
||||
/// `into_option` creates an `Option` of type `(T,T)`. The returned `Option`
|
||||
/// has variant `None` if and only if the `MinMaxResult` has variant
|
||||
/// `NoElements`. Otherwise variant `Some(x,y)` is returned where `x <= y`.
|
||||
/// If `MinMaxResult` has variant `OneElement(x)`, performing this operation
|
||||
/// will make one clone of `x`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_min_max)]
|
||||
///
|
||||
/// use std::iter::MinMaxResult::{self, NoElements, OneElement, MinMax};
|
||||
///
|
||||
/// let r: MinMaxResult<i32> = NoElements;
|
||||
/// assert_eq!(r.into_option(), None);
|
||||
///
|
||||
/// let r = OneElement(1);
|
||||
/// assert_eq!(r.into_option(), Some((1, 1)));
|
||||
///
|
||||
/// let r = MinMax(1, 2);
|
||||
/// assert_eq!(r.into_option(), Some((1, 2)));
|
||||
/// ```
|
||||
pub fn into_option(self) -> Option<(T,T)> {
|
||||
match self {
|
||||
NoElements => None,
|
||||
OneElement(x) => Some((x.clone(), x)),
|
||||
MinMax(x, y) => Some((x, y))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that clones the elements of an underlying iterator
|
||||
#[stable(feature = "iter_cloned", since = "1.1.0")]
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
|
@ -1430,22 +1232,6 @@ impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
|
|||
where I: ExactSizeIterator<Item=&'a T>, T: Clone
|
||||
{}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<'a, I, T: 'a> RandomAccessIterator for Cloned<I>
|
||||
where I: RandomAccessIterator<Item=&'a T>, T: Clone
|
||||
{
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
self.it.indexable()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<T> {
|
||||
self.it.idx(index).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that repeats endlessly
|
||||
#[derive(Clone)]
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
|
@ -1478,34 +1264,6 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<I> RandomAccessIterator for Cycle<I> where
|
||||
I: Clone + RandomAccessIterator,
|
||||
{
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
if self.orig.indexable() > 0 {
|
||||
usize::MAX
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<<I as Iterator>::Item> {
|
||||
let liter = self.iter.indexable();
|
||||
let lorig = self.orig.indexable();
|
||||
if lorig == 0 {
|
||||
None
|
||||
} else if index < liter {
|
||||
self.iter.idx(index)
|
||||
} else {
|
||||
self.orig.idx((index - liter) % lorig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that strings two iterators together
|
||||
#[derive(Clone)]
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
|
@ -1593,29 +1351,6 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<A, B> RandomAccessIterator for Chain<A, B> where
|
||||
A: RandomAccessIterator,
|
||||
B: RandomAccessIterator<Item = A::Item>,
|
||||
{
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
let (a, b) = (self.a.indexable(), self.b.indexable());
|
||||
a.saturating_add(b)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<A::Item> {
|
||||
let len = self.a.indexable();
|
||||
if index < len {
|
||||
self.a.idx(index)
|
||||
} else {
|
||||
self.b.idx(index - len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that iterates two other iterators simultaneously
|
||||
#[derive(Clone)]
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
|
@ -1682,27 +1417,6 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<A, B> RandomAccessIterator for Zip<A, B> where
|
||||
A: RandomAccessIterator,
|
||||
B: RandomAccessIterator
|
||||
{
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
cmp::min(self.a.indexable(), self.b.indexable())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<(A::Item, B::Item)> {
|
||||
self.a.idx(index).and_then(|x| {
|
||||
self.b.idx(index).and_then(|y| {
|
||||
Some((x, y))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that maps the values of `iter` with `f`
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1737,22 +1451,6 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<B, I: RandomAccessIterator, F> RandomAccessIterator for Map<I, F> where
|
||||
F: FnMut(I::Item) -> B,
|
||||
{
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
self.iter.indexable()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<B> {
|
||||
self.iter.idx(index).map(|a| (self.f)(a))
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that filters the elements of `iter` with `predicate`
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1912,23 +1610,6 @@ impl<I> DoubleEndedIterator for Enumerate<I> where
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<I> RandomAccessIterator for Enumerate<I> where I: RandomAccessIterator {
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
self.iter.indexable()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<(usize, <I as Iterator>::Item)> {
|
||||
// Can safely add, `ExactSizeIterator` (ancestor of
|
||||
// `RandomAccessIterator`) promises that the number of elements fits
|
||||
// into a `usize`.
|
||||
self.iter.idx(index).map(|a| (self.count + index, a))
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator with a `peek()` that returns an optional reference to the next element.
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -2163,24 +1844,6 @@ impl<I> Iterator for Skip<I> where I: Iterator {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<I> RandomAccessIterator for Skip<I> where I: RandomAccessIterator{
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
self.iter.indexable().saturating_sub(self.n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<<I as Iterator>::Item> {
|
||||
if index >= self.indexable() {
|
||||
None
|
||||
} else {
|
||||
self.iter.idx(index + self.n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<I> ExactSizeIterator for Skip<I> where I: ExactSizeIterator {}
|
||||
|
||||
|
@ -2236,24 +1899,6 @@ impl<I> Iterator for Take<I> where I: Iterator{
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<I> RandomAccessIterator for Take<I> where I: RandomAccessIterator{
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
cmp::min(self.iter.indexable(), self.n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<<I as Iterator>::Item> {
|
||||
if index >= self.n {
|
||||
None
|
||||
} else {
|
||||
self.iter.idx(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
|
||||
|
||||
|
@ -2262,16 +1907,10 @@ impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
|
|||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(Clone)]
|
||||
#[allow(deprecated)]
|
||||
pub struct Scan<I, St, F> {
|
||||
iter: I,
|
||||
f: F,
|
||||
|
||||
/// The current internal state to be passed to the closure next.
|
||||
#[unstable(feature = "scan_state",
|
||||
reason = "public fields are otherwise rare in the stdlib")]
|
||||
#[deprecated(since = "1.3.0", reason = "unclear whether this is necessary")]
|
||||
pub state: St,
|
||||
state: St,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -2282,7 +1921,6 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where
|
|||
type Item = B;
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn next(&mut self) -> Option<B> {
|
||||
self.iter.next().and_then(|a| (self.f)(&mut self.state, a))
|
||||
}
|
||||
|
@ -2440,37 +2078,9 @@ impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator {
|
|||
}
|
||||
}
|
||||
|
||||
// Allow RandomAccessIterators to be fused without affecting random-access behavior
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<I> RandomAccessIterator for Fuse<I> where I: RandomAccessIterator {
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
self.iter.indexable()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<<I as Iterator>::Item> {
|
||||
self.iter.idx(index)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<I> ExactSizeIterator for Fuse<I> where I: ExactSizeIterator {}
|
||||
|
||||
impl<I> Fuse<I> {
|
||||
/// Resets the `Fuse` such that the next call to `.next()` or
|
||||
/// `.next_back()` will call the underlying iterator again even if it
|
||||
/// previously returned `None`.
|
||||
#[inline]
|
||||
#[unstable(feature = "iter_reset_fuse", reason = "seems marginal")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "unusual for adaptors to have one-off methods")]
|
||||
pub fn reset_fuse(&mut self) {
|
||||
self.done = false
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that calls a function with a reference to each
|
||||
/// element before yielding it.
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
|
@ -2519,104 +2129,6 @@ impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<I: RandomAccessIterator, F> RandomAccessIterator for Inspect<I, F>
|
||||
where F: FnMut(&I::Item),
|
||||
{
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
self.iter.indexable()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<I::Item> {
|
||||
let element = self.iter.idx(index);
|
||||
self.do_inspect(element)
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that passes mutable state to a closure and yields the result.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// An iterator that yields sequential Fibonacci numbers, and stops on overflow.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_unfold)]
|
||||
/// use std::iter::Unfold;
|
||||
///
|
||||
/// // This iterator will yield up to the last Fibonacci number before the max
|
||||
/// // value of `u32`. You can simply change `u32` to `u64` in this line if
|
||||
/// // you want higher values than that.
|
||||
/// let mut fibonacci = Unfold::new((Some(0u32), Some(1u32)),
|
||||
/// |&mut (ref mut x2, ref mut x1)| {
|
||||
/// // Attempt to get the next Fibonacci number
|
||||
/// // `x1` will be `None` if previously overflowed.
|
||||
/// let next = match (*x2, *x1) {
|
||||
/// (Some(x2), Some(x1)) => x2.checked_add(x1),
|
||||
/// _ => None,
|
||||
/// };
|
||||
///
|
||||
/// // Shift left: ret <- x2 <- x1 <- next
|
||||
/// let ret = *x2;
|
||||
/// *x2 = *x1;
|
||||
/// *x1 = next;
|
||||
///
|
||||
/// ret
|
||||
/// });
|
||||
///
|
||||
/// for i in fibonacci {
|
||||
/// println!("{}", i);
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "iter_unfold")]
|
||||
#[derive(Clone)]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "has not gained enough traction to retain its position \
|
||||
in the standard library")]
|
||||
#[allow(deprecated)]
|
||||
pub struct Unfold<St, F> {
|
||||
f: F,
|
||||
/// Internal state that will be passed to the closure on the next iteration
|
||||
#[unstable(feature = "iter_unfold")]
|
||||
pub state: St,
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_unfold")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "has not gained enough traction to retain its position \
|
||||
in the standard library")]
|
||||
#[allow(deprecated)]
|
||||
impl<A, St, F> Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
|
||||
/// Creates a new iterator with the specified closure as the "iterator
|
||||
/// function" and an initial state to eventually pass to the closure
|
||||
#[inline]
|
||||
pub fn new(initial_state: St, f: F) -> Unfold<St, F> {
|
||||
Unfold {
|
||||
f: f,
|
||||
state: initial_state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
|
||||
type Item = A;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> {
|
||||
(self.f)(&mut self.state)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
// no possible known bounds at this point
|
||||
(0, None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Objects that can be stepped over in both directions.
|
||||
///
|
||||
/// The `steps_between` function provides a way to efficiently compare
|
||||
|
@ -2759,7 +2271,6 @@ impl<A: Step> RangeFrom<A> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<A: Step> ops::Range<A> {
|
||||
/// Creates an iterator with the same range, but stepping by the
|
||||
/// given amount at each iteration.
|
||||
|
@ -2892,7 +2403,6 @@ impl<A> DoubleEndedIterator for RangeInclusive<A> where
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::Range<A>> {
|
||||
type Item = A;
|
||||
|
||||
|
@ -2937,7 +2447,6 @@ macro_rules! range_exact_iter_impl {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
impl<A: Step + One> Iterator for ops::Range<A> where
|
||||
for<'a> &'a A: Add<&'a A, Output = A>
|
||||
{
|
||||
|
@ -2968,7 +2477,6 @@ impl<A: Step + One> Iterator for ops::Range<A> where
|
|||
range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
|
||||
for<'a> &'a A: Add<&'a A, Output = A>,
|
||||
for<'a> &'a A: Sub<&'a A, Output = A>
|
||||
|
@ -2985,7 +2493,6 @@ impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
impl<A: Step + One> Iterator for ops::RangeFrom<A> where
|
||||
for<'a> &'a A: Add<&'a A, Output = A>
|
||||
{
|
||||
|
@ -3022,56 +2529,6 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
|
|||
fn next_back(&mut self) -> Option<A> { Some(self.element.clone()) }
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<A: Clone> RandomAccessIterator for Repeat<A> {
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize { usize::MAX }
|
||||
#[inline]
|
||||
fn idx(&mut self, _: usize) -> Option<A> { Some(self.element.clone()) }
|
||||
}
|
||||
|
||||
type IterateState<T, F> = (F, Option<T>, bool);
|
||||
|
||||
/// An iterator that repeatedly applies a given function, starting
|
||||
/// from a given seed value.
|
||||
#[unstable(feature = "iter_iterate")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "has not gained enough traction to retain its position \
|
||||
in the standard library")]
|
||||
#[allow(deprecated)]
|
||||
pub type Iterate<T, F> = Unfold<IterateState<T, F>, fn(&mut IterateState<T, F>) -> Option<T>>;
|
||||
|
||||
/// Creates a new iterator that produces an infinite sequence of
|
||||
/// repeated applications of the given function `f`.
|
||||
#[unstable(feature = "iter_iterate")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "has not gained enough traction to retain its position \
|
||||
in the standard library")]
|
||||
#[allow(deprecated)]
|
||||
pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where
|
||||
T: Clone,
|
||||
F: FnMut(T) -> T,
|
||||
{
|
||||
fn next<T, F>(st: &mut IterateState<T, F>) -> Option<T> where
|
||||
T: Clone,
|
||||
F: FnMut(T) -> T,
|
||||
{
|
||||
let &mut (ref mut f, ref mut val, ref mut first) = st;
|
||||
if *first {
|
||||
*first = false;
|
||||
} else if let Some(x) = val.take() {
|
||||
*val = Some((*f)(x))
|
||||
}
|
||||
val.clone()
|
||||
}
|
||||
|
||||
// coerce to a fn pointer
|
||||
let next: fn(&mut IterateState<T,F>) -> Option<T> = next;
|
||||
|
||||
Unfold::new((f, Some(seed), true), next)
|
||||
}
|
||||
|
||||
/// Creates a new iterator that endlessly repeats the element `elt`.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
|
|
@ -218,18 +218,6 @@ unsafe impl Sync for .. { }
|
|||
impl<T> !Sync for *const T { }
|
||||
impl<T> !Sync for *mut T { }
|
||||
|
||||
/// A type which is considered "not POD", meaning that it is not
|
||||
/// implicitly copyable. This is typically embedded in other types to
|
||||
/// ensure that they are never copied, even if they lack a destructor.
|
||||
#[unstable(feature = "core",
|
||||
reason = "likely to change with new variance strategy")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "structs are by default not copyable")]
|
||||
#[lang = "no_copy_bound"]
|
||||
#[allow(deprecated)]
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct NoCopy;
|
||||
|
||||
macro_rules! impls{
|
||||
($t: ident) => (
|
||||
impl<T:?Sized> Hash for $t<T> {
|
||||
|
@ -419,7 +407,6 @@ mod impls {
|
|||
#[rustc_reflect_like]
|
||||
#[unstable(feature = "reflect_marker",
|
||||
reason = "requires RFC and more experience")]
|
||||
#[allow(deprecated)]
|
||||
#[rustc_on_unimplemented = "`{Self}` does not implement `Any`; \
|
||||
ensure all type parameters are bounded by `Any`"]
|
||||
pub trait Reflect {}
|
||||
|
|
|
@ -558,33 +558,3 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
|
|||
#![allow(trivial_casts)]
|
||||
ptr::read(src as *const T as *const U)
|
||||
}
|
||||
|
||||
/// Transforms lifetime of the second pointer to match the first.
|
||||
#[inline]
|
||||
#[unstable(feature = "copy_lifetime",
|
||||
reason = "this function may be removed in the future due to its \
|
||||
questionable utility")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "unclear that this function buys more safety and \
|
||||
lifetimes are generally not handled as such in unsafe \
|
||||
code today")]
|
||||
pub unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
|
||||
ptr: &T) -> &'a T {
|
||||
transmute(ptr)
|
||||
}
|
||||
|
||||
/// Transforms lifetime of the second mutable pointer to match the first.
|
||||
#[inline]
|
||||
#[unstable(feature = "copy_lifetime",
|
||||
reason = "this function may be removed in the future due to its \
|
||||
questionable utility")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "unclear that this function buys more safety and \
|
||||
lifetimes are generally not handled as such in unsafe \
|
||||
code today")]
|
||||
pub unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
|
||||
ptr: &mut T)
|
||||
-> &'a mut T
|
||||
{
|
||||
transmute(ptr)
|
||||
}
|
||||
|
|
|
@ -80,12 +80,6 @@ pub mod consts {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const PI: f32 = 3.14159265358979323846264338327950288_f32;
|
||||
|
||||
/// pi * 2.0
|
||||
#[unstable(feature = "float_consts",
|
||||
reason = "unclear naming convention/usefulness")]
|
||||
#[deprecated(since = "1.2.0", reason = "unclear on usefulness")]
|
||||
pub const PI_2: f32 = 6.28318530717958647692528676655900576_f32;
|
||||
|
||||
/// pi/2.0
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
|
||||
|
|
|
@ -80,12 +80,6 @@ pub mod consts {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const PI: f64 = 3.14159265358979323846264338327950288_f64;
|
||||
|
||||
/// pi * 2.0
|
||||
#[unstable(feature = "float_consts",
|
||||
reason = "unclear naming convention/usefulness")]
|
||||
#[deprecated(since = "1.2.0", reason = "unclear on usefulness")]
|
||||
pub const PI_2: f64 = 6.28318530717958647692528676655900576_f64;
|
||||
|
||||
/// pi/2.0
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64;
|
||||
|
|
|
@ -136,7 +136,6 @@ macro_rules! int_impl {
|
|||
/// assert_eq!(u32::from_str_radix("A", 16), Ok(10));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
|
||||
from_str_radix(src, radix)
|
||||
}
|
||||
|
@ -691,7 +690,6 @@ macro_rules! uint_impl {
|
|||
/// `Err(ParseIntError)` if the string did not represent a valid number.
|
||||
/// Otherwise, `Ok(n)` where `n` is the integer represented by `src`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
|
||||
from_str_radix(src, radix)
|
||||
}
|
||||
|
@ -1395,7 +1393,6 @@ macro_rules! from_str_float_impl {
|
|||
/// number. Otherwise, `Ok(n)` where `n` is the floating-point
|
||||
/// number represented by `src`.
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn from_str(src: &str) -> Result<Self, ParseFloatError> {
|
||||
Self::from_str_radix(src, 10)
|
||||
}
|
||||
|
@ -1408,7 +1405,6 @@ from_str_float_impl!(f64);
|
|||
macro_rules! from_str_radix_int_impl {
|
||||
($($t:ty)*) => {$(
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
impl FromStr for $t {
|
||||
type Err = ParseIntError;
|
||||
fn from_str(src: &str) -> Result<Self, ParseIntError> {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
#![allow(deprecated)]
|
||||
#![unstable(feature = "wrapping", reason = "may be removed or relocated")]
|
||||
|
||||
use super::Wrapping;
|
||||
|
|
|
@ -123,27 +123,6 @@ pub unsafe fn read<T>(src: *const T) -> T {
|
|||
tmp
|
||||
}
|
||||
|
||||
/// Reads the value from `src` and nulls it out without dropping it.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This is unsafe for the same reasons that `read` is unsafe.
|
||||
#[inline(always)]
|
||||
#[unstable(feature = "read_and_zero",
|
||||
reason = "may play a larger role in std::ptr future extensions")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "a \"zero value\" will soon not actually exist for all \
|
||||
types once dynamic drop has been implemented")]
|
||||
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
||||
// Copy the data out from `dest`:
|
||||
let tmp = read(&*dest);
|
||||
|
||||
// Now zero out `dest`:
|
||||
write_bytes(dest, 0, 1);
|
||||
|
||||
tmp
|
||||
}
|
||||
|
||||
/// Variant of read_and_zero that writes the specific drop-flag byte
|
||||
/// (which may be more appropriate than zero).
|
||||
#[inline(always)]
|
||||
|
|
|
@ -234,7 +234,7 @@ use self::Result::{Ok, Err};
|
|||
use clone::Clone;
|
||||
use fmt;
|
||||
use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator};
|
||||
use ops::{FnMut, FnOnce};
|
||||
use ops::FnOnce;
|
||||
use option::Option::{self, None, Some};
|
||||
use slice;
|
||||
|
||||
|
@ -957,35 +957,3 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FromIterator
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Performs a fold operation over the result values from an iterator.
|
||||
///
|
||||
/// If an `Err` is encountered, it is immediately returned.
|
||||
/// Otherwise, the folded value is returned.
|
||||
#[inline]
|
||||
#[unstable(feature = "result_fold",
|
||||
reason = "unclear if this function should exist")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "has not seen enough usage to justify its position in \
|
||||
the standard library")]
|
||||
pub fn fold<T,
|
||||
V,
|
||||
E,
|
||||
F: FnMut(V, T) -> V,
|
||||
Iter: Iterator<Item=Result<T, E>>>(
|
||||
iterator: Iter,
|
||||
mut init: V,
|
||||
mut f: F)
|
||||
-> Result<V, E> {
|
||||
for t in iterator {
|
||||
match t {
|
||||
Ok(v) => init = f(init, v),
|
||||
Err(u) => return Err(u)
|
||||
}
|
||||
}
|
||||
Ok(init)
|
||||
}
|
||||
|
|
|
@ -826,27 +826,6 @@ impl<'a, T> Clone for Iter<'a, T> {
|
|||
fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } }
|
||||
}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T> RandomAccessIterator for Iter<'a, T> {
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
let (exact, _) = self.size_hint();
|
||||
exact
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<&'a T> {
|
||||
unsafe {
|
||||
if index < self.indexable() {
|
||||
Some(slice_ref!(self.ptr.offset(index as isize)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Mutable slice iterator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct IterMut<'a, T: 'a> {
|
||||
|
@ -1199,24 +1178,6 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, T> ExactSizeIterator for Windows<'a, T> {}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T> RandomAccessIterator for Windows<'a, T> {
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
self.size_hint().0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<&'a [T]> {
|
||||
if index + self.size > self.v.len() {
|
||||
None
|
||||
} else {
|
||||
Some(&self.v[index .. index+self.size])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over a slice in (non-overlapping) chunks (`size` elements at a
|
||||
/// time).
|
||||
///
|
||||
|
@ -1287,28 +1248,6 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, T> ExactSizeIterator for Chunks<'a, T> {}
|
||||
|
||||
#[unstable(feature = "iter_idx", reason = "trait is experimental")]
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T> RandomAccessIterator for Chunks<'a, T> {
|
||||
#[inline]
|
||||
fn indexable(&self) -> usize {
|
||||
self.v.len()/self.size + if self.v.len() % self.size != 0 { 1 } else { 0 }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn idx(&mut self, index: usize) -> Option<&'a [T]> {
|
||||
if index < self.indexable() {
|
||||
let lo = index * self.size;
|
||||
let mut hi = lo + self.size;
|
||||
if hi < lo || hi > self.v.len() { hi = self.v.len(); }
|
||||
|
||||
Some(&self.v[lo..hi])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over a slice in (non-overlapping) mutable chunks (`size`
|
||||
/// elements at a time). When the slice len is not evenly divided by the chunk
|
||||
/// size, the last slice of the iteration will be the remainder.
|
||||
|
@ -1439,37 +1378,6 @@ pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
|
|||
mem::transmute(RawSlice { data: p, len: len })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn check_types<T,U>() {
|
||||
assert!(mem::size_of::<T>() == mem::size_of::<U>());
|
||||
assert!(mem::align_of::<T>() % mem::align_of::<U>() == 0)
|
||||
}
|
||||
|
||||
/// Reinterprets a slice of one type as a slice of another type.
|
||||
///
|
||||
/// Both types have to have the same size and the type that is converted to
|
||||
/// must have equal or less restrictive alignment.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This functions panics if the above preconditions about the types are not
|
||||
/// met.
|
||||
#[inline]
|
||||
unsafe fn transmute<T,U>(slice: &[T]) -> &[U] {
|
||||
check_types::<T,U>();
|
||||
from_raw_parts(slice.as_ptr() as *const U, slice.len())
|
||||
}
|
||||
|
||||
/// Reinterprets a mutable slice of one type as a mutable slice of another
|
||||
/// type.
|
||||
///
|
||||
/// Equivalent of `slice::transmute` for mutable slices.
|
||||
#[inline]
|
||||
unsafe fn transmute_mut<T,U>(slice: &mut [T]) -> &mut [U] {
|
||||
check_types::<T,U>();
|
||||
from_raw_parts_mut(slice.as_mut_ptr() as *mut U, slice.len())
|
||||
}
|
||||
|
||||
//
|
||||
// Submodules
|
||||
//
|
||||
|
@ -1579,51 +1487,3 @@ impl<T: PartialOrd> PartialOrd for [T] {
|
|||
order::gt(self.iter(), other.iter())
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension methods for slices containing integers.
|
||||
#[unstable(feature = "int_slice")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "has not seen much usage and may want to live in the \
|
||||
standard library now that most slice methods are \
|
||||
on an inherent implementation block")]
|
||||
pub trait IntSliceExt<U, S> {
|
||||
/// Converts the slice to an immutable slice of unsigned integers with the same width.
|
||||
fn as_unsigned<'a>(&'a self) -> &'a [U];
|
||||
/// Converts the slice to an immutable slice of signed integers with the same width.
|
||||
fn as_signed<'a>(&'a self) -> &'a [S];
|
||||
|
||||
/// Converts the slice to a mutable slice of unsigned integers with the same width.
|
||||
fn as_unsigned_mut<'a>(&'a mut self) -> &'a mut [U];
|
||||
/// Converts the slice to a mutable slice of signed integers with the same width.
|
||||
fn as_signed_mut<'a>(&'a mut self) -> &'a mut [S];
|
||||
}
|
||||
|
||||
macro_rules! impl_int_slice {
|
||||
($u:ty, $s:ty, $t:ty) => {
|
||||
#[unstable(feature = "int_slice")]
|
||||
#[allow(deprecated)]
|
||||
impl IntSliceExt<$u, $s> for [$t] {
|
||||
#[inline]
|
||||
fn as_unsigned(&self) -> &[$u] { unsafe { transmute(self) } }
|
||||
#[inline]
|
||||
fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } }
|
||||
#[inline]
|
||||
fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute_mut(self) } }
|
||||
#[inline]
|
||||
fn as_signed_mut(&mut self) -> &mut [$s] { unsafe { transmute_mut(self) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_int_slices {
|
||||
($u:ty, $s:ty) => {
|
||||
impl_int_slice! { $u, $s, $u }
|
||||
impl_int_slice! { $u, $s, $s }
|
||||
}
|
||||
}
|
||||
|
||||
impl_int_slices! { u8, i8 }
|
||||
impl_int_slices! { u16, i16 }
|
||||
impl_int_slices! { u32, i32 }
|
||||
impl_int_slices! { u64, i64 }
|
||||
impl_int_slices! { usize, isize }
|
||||
|
|
|
@ -211,31 +211,3 @@ fn test_len_utf16() {
|
|||
assert!('\u{a66e}'.len_utf16() == 1);
|
||||
assert!('\u{1f4a9}'.len_utf16() == 2);
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[test]
|
||||
fn test_width() {
|
||||
assert_eq!('\x00'.width(false),Some(0));
|
||||
assert_eq!('\x00'.width(true),Some(0));
|
||||
|
||||
assert_eq!('\x0A'.width(false),None);
|
||||
assert_eq!('\x0A'.width(true),None);
|
||||
|
||||
assert_eq!('w'.width(false),Some(1));
|
||||
assert_eq!('w'.width(true),Some(1));
|
||||
|
||||
assert_eq!('h'.width(false),Some(2));
|
||||
assert_eq!('h'.width(true),Some(2));
|
||||
|
||||
assert_eq!('\u{AD}'.width(false),Some(1));
|
||||
assert_eq!('\u{AD}'.width(true),Some(1));
|
||||
|
||||
assert_eq!('\u{1160}'.width(false),Some(0));
|
||||
assert_eq!('\u{1160}'.width(true),Some(0));
|
||||
|
||||
assert_eq!('\u{a1}'.width(false),Some(1));
|
||||
assert_eq!('\u{a1}'.width(true),Some(2));
|
||||
|
||||
assert_eq!('\u{300}'.width(false),Some(0));
|
||||
assert_eq!('\u{300}'.width(true),Some(0));
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::cmp::{partial_min, partial_max};
|
||||
use core::cmp::Ordering::{Less, Greater, Equal};
|
||||
|
||||
#[test]
|
||||
|
@ -42,72 +41,6 @@ fn test_ordering_order() {
|
|||
assert_eq!(Greater.cmp(&Less), Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_partial_min() {
|
||||
use core::f64::NAN;
|
||||
let data_integer = [
|
||||
// a, b, result
|
||||
(0, 0, Some(0)),
|
||||
(1, 0, Some(0)),
|
||||
(0, 1, Some(0)),
|
||||
(-1, 0, Some(-1)),
|
||||
(0, -1, Some(-1))
|
||||
];
|
||||
|
||||
let data_float = [
|
||||
// a, b, result
|
||||
(0.0f64, 0.0f64, Some(0.0f64)),
|
||||
(1.0f64, 0.0f64, Some(0.0f64)),
|
||||
(0.0f64, 1.0f64, Some(0.0f64)),
|
||||
(-1.0f64, 0.0f64, Some(-1.0f64)),
|
||||
(0.0f64, -1.0f64, Some(-1.0f64)),
|
||||
(NAN, NAN, None),
|
||||
(NAN, 1.0f64, None),
|
||||
(1.0f64, NAN, None)
|
||||
];
|
||||
|
||||
for &(a, b, result) in &data_integer {
|
||||
assert!(partial_min(a, b) == result);
|
||||
}
|
||||
|
||||
for &(a, b, result) in &data_float {
|
||||
assert!(partial_min(a, b) == result);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_partial_max() {
|
||||
use core::f64::NAN;
|
||||
let data_integer = [
|
||||
// a, b, result
|
||||
(0, 0, Some(0)),
|
||||
(1, 0, Some(1)),
|
||||
(0, 1, Some(1)),
|
||||
(-1, 0, Some(0)),
|
||||
(0, -1, Some(0))
|
||||
];
|
||||
|
||||
let data_float = [
|
||||
// a, b, result
|
||||
(0.0f64, 0.0f64, Some(0.0f64)),
|
||||
(1.0f64, 0.0f64, Some(1.0f64)),
|
||||
(0.0f64, 1.0f64, Some(1.0f64)),
|
||||
(-1.0f64, 0.0f64, Some(0.0f64)),
|
||||
(0.0f64, -1.0f64, Some(0.0f64)),
|
||||
(NAN, NAN, None),
|
||||
(NAN, 1.0f64, None),
|
||||
(1.0f64, NAN, None)
|
||||
];
|
||||
|
||||
for &(a, b, result) in &data_integer {
|
||||
assert!(partial_max(a, b) == result);
|
||||
}
|
||||
|
||||
for &(a, b, result) in &data_float {
|
||||
assert!(partial_max(a, b) == result);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_defined_eq() {
|
||||
// Our type.
|
||||
|
|
|
@ -36,7 +36,9 @@ impl Hasher for MyHasher {
|
|||
#[test]
|
||||
fn test_writer_hasher() {
|
||||
fn hash<T: Hash>(t: &T) -> u64 {
|
||||
::std::hash::hash::<_, MyHasher>(t)
|
||||
let mut s = MyHasher { hash: 0 };
|
||||
t.hash(&mut s);
|
||||
s.finish()
|
||||
}
|
||||
|
||||
assert_eq!(hash(&()), 0);
|
||||
|
@ -102,7 +104,9 @@ impl Hash for Custom {
|
|||
#[test]
|
||||
fn test_custom_state() {
|
||||
fn hash<T: Hash>(t: &T) -> u64 {
|
||||
::std::hash::hash::<_, CustomHasher>(t)
|
||||
let mut c = CustomHasher { output: 0 };
|
||||
t.hash(&mut c);
|
||||
c.finish()
|
||||
}
|
||||
|
||||
assert_eq!(hash(&Custom { hash: 5 }), 5);
|
||||
|
|
|
@ -10,10 +10,8 @@
|
|||
|
||||
use core::iter::*;
|
||||
use core::iter::order::*;
|
||||
use core::iter::MinMaxResult::*;
|
||||
use core::{i8, i16, isize};
|
||||
use core::usize;
|
||||
use core::cmp;
|
||||
|
||||
use test::Bencher;
|
||||
|
||||
|
@ -451,27 +449,6 @@ fn test_inspect() {
|
|||
assert_eq!(&xs[..], &ys[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unfoldr() {
|
||||
fn count(st: &mut usize) -> Option<usize> {
|
||||
if *st < 10 {
|
||||
let ret = Some(*st);
|
||||
*st += 1;
|
||||
ret
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let it = Unfold::new(0, count);
|
||||
let mut i = 0;
|
||||
for counted in it {
|
||||
assert_eq!(counted, i);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cycle() {
|
||||
let cycle_len = 3;
|
||||
|
@ -781,28 +758,6 @@ fn test_rposition_panic() {
|
|||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
fn check_randacc_iter<A, T>(a: T, len: usize) where
|
||||
A: PartialEq,
|
||||
T: Clone + RandomAccessIterator + Iterator<Item=A>,
|
||||
{
|
||||
let mut b = a.clone();
|
||||
assert_eq!(len, b.indexable());
|
||||
let mut n = 0;
|
||||
for (i, elt) in a.enumerate() {
|
||||
assert!(Some(elt) == b.idx(i));
|
||||
n += 1;
|
||||
}
|
||||
assert_eq!(n, len);
|
||||
assert!(None == b.idx(n));
|
||||
// call recursively to check after picking off an element
|
||||
if len > 0 {
|
||||
b.next();
|
||||
check_randacc_iter(b, len-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_flat_map() {
|
||||
let u = [0,1];
|
||||
|
@ -820,101 +775,6 @@ fn test_double_ended_flat_map() {
|
|||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_chain() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let ys = [7, 9, 11];
|
||||
let mut it = xs.iter().chain(&ys);
|
||||
assert_eq!(it.idx(0).unwrap(), &1);
|
||||
assert_eq!(it.idx(5).unwrap(), &7);
|
||||
assert_eq!(it.idx(7).unwrap(), &11);
|
||||
assert!(it.idx(8).is_none());
|
||||
|
||||
it.next();
|
||||
it.next();
|
||||
it.next_back();
|
||||
|
||||
assert_eq!(it.idx(0).unwrap(), &3);
|
||||
assert_eq!(it.idx(4).unwrap(), &9);
|
||||
assert!(it.idx(6).is_none());
|
||||
|
||||
check_randacc_iter(it, xs.len() + ys.len() - 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_enumerate() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
check_randacc_iter(xs.iter().enumerate(), xs.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_rev() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
check_randacc_iter(xs.iter().rev(), xs.len());
|
||||
let mut it = xs.iter().rev();
|
||||
it.next();
|
||||
it.next_back();
|
||||
it.next();
|
||||
check_randacc_iter(it, xs.len() - 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_zip() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let ys = [7, 9, 11];
|
||||
check_randacc_iter(xs.iter().zip(&ys), cmp::min(xs.len(), ys.len()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_take() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let empty: &[isize] = &[];
|
||||
check_randacc_iter(xs.iter().take(3), 3);
|
||||
check_randacc_iter(xs.iter().take(20), xs.len());
|
||||
check_randacc_iter(xs.iter().take(0), 0);
|
||||
check_randacc_iter(empty.iter().take(2), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_skip() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let empty: &[isize] = &[];
|
||||
check_randacc_iter(xs.iter().skip(2), xs.len() - 2);
|
||||
check_randacc_iter(empty.iter().skip(2), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_inspect() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
|
||||
// test .map and .inspect that don't implement Clone
|
||||
let mut it = xs.iter().inspect(|_| {});
|
||||
assert_eq!(xs.len(), it.indexable());
|
||||
for (i, elt) in xs.iter().enumerate() {
|
||||
assert_eq!(Some(elt), it.idx(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_map() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
|
||||
let mut it = xs.iter().cloned();
|
||||
assert_eq!(xs.len(), it.indexable());
|
||||
for (i, elt) in xs.iter().enumerate() {
|
||||
assert_eq!(Some(*elt), it.idx(i));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_cycle() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let empty: &[isize] = &[];
|
||||
check_randacc_iter(xs.iter().cycle().take(27), 27);
|
||||
check_randacc_iter(empty.iter().cycle(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_range() {
|
||||
assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
|
||||
|
@ -984,13 +844,6 @@ fn test_range_step() {
|
|||
assert_eq!((isize::MIN..isize::MAX).step_by(1).size_hint(), (usize::MAX, Some(usize::MAX)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reverse() {
|
||||
let mut ys = [1, 2, 3, 4, 5];
|
||||
ys.iter_mut().reverse_in_place();
|
||||
assert!(ys == [5, 4, 3, 2, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peekable_is_empty() {
|
||||
let a = [1];
|
||||
|
@ -1000,45 +853,6 @@ fn test_peekable_is_empty() {
|
|||
assert!( it.is_empty() );
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_max() {
|
||||
let v: [isize; 0] = [];
|
||||
assert_eq!(v.iter().min_max(), NoElements);
|
||||
|
||||
let v = [1];
|
||||
assert!(v.iter().min_max() == OneElement(&1));
|
||||
|
||||
let v = [1, 2, 3, 4, 5];
|
||||
assert!(v.iter().min_max() == MinMax(&1, &5));
|
||||
|
||||
let v = [1, 2, 3, 4, 5, 6];
|
||||
assert!(v.iter().min_max() == MinMax(&1, &6));
|
||||
|
||||
let v = [1, 1, 1, 1];
|
||||
assert!(v.iter().min_max() == MinMax(&1, &1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_max_result() {
|
||||
let r: MinMaxResult<isize> = NoElements;
|
||||
assert_eq!(r.into_option(), None);
|
||||
|
||||
let r = OneElement(1);
|
||||
assert_eq!(r.into_option(), Some((1,1)));
|
||||
|
||||
let r = MinMax(1,2);
|
||||
assert_eq!(r.into_option(), Some((1,2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterate() {
|
||||
let mut it = iterate(1, |x| x * 2);
|
||||
assert_eq!(it.next(), Some(1));
|
||||
assert_eq!(it.next(), Some(2));
|
||||
assert_eq!(it.next(), Some(4));
|
||||
assert_eq!(it.next(), Some(8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeat() {
|
||||
let mut it = repeat(42);
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#![feature(borrow_state)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cell_extras)]
|
||||
#![feature(cmp_partial)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(core)]
|
||||
#![feature(core_float)]
|
||||
|
@ -20,18 +19,10 @@
|
|||
#![feature(float_from_str_radix)]
|
||||
#![feature(flt2dec)]
|
||||
#![feature(fmt_radix)]
|
||||
#![feature(hash_default)]
|
||||
#![feature(hasher_write)]
|
||||
#![feature(iter_arith)]
|
||||
#![feature(iter_arith)]
|
||||
#![feature(iter_cmp)]
|
||||
#![feature(iter_empty)]
|
||||
#![feature(iter_idx)]
|
||||
#![feature(iter_iterate)]
|
||||
#![feature(iter_min_max)]
|
||||
#![feature(iter_once)]
|
||||
#![feature(iter_order)]
|
||||
#![feature(iter_unfold)]
|
||||
#![feature(libc)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(num_bits_bytes)]
|
||||
|
|
|
@ -539,16 +539,6 @@ pub fn opt(short_name: &str,
|
|||
}
|
||||
}
|
||||
|
||||
impl Fail {
|
||||
/// Convert a `Fail` enum into an error string.
|
||||
#[unstable(feature = "rustc_private")]
|
||||
#[deprecated(since = "1.0.0",
|
||||
reason = "use `fmt::Display` (`{}` format specifier)")]
|
||||
pub fn to_err_msg(self) -> String {
|
||||
self.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Fail {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
#![feature(vec_push_all)]
|
||||
#![feature(wrapping)]
|
||||
#![feature(cell_extras)]
|
||||
#![feature(page_size)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
|
||||
#![allow(trivial_casts)]
|
||||
|
|
|
@ -99,7 +99,6 @@ impl<'a> PluginLoader<'a> {
|
|||
}
|
||||
|
||||
// Dynamically link a registrar function into the compiler process.
|
||||
#[allow(deprecated)] // until #23197
|
||||
fn dylink_registrar(&mut self,
|
||||
span: Span,
|
||||
path: PathBuf,
|
||||
|
|
|
@ -75,24 +75,28 @@ pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
|
|||
rv
|
||||
}
|
||||
|
||||
// Memory reporting
|
||||
#[cfg(unix)]
|
||||
fn get_resident() -> Option<usize> {
|
||||
get_proc_self_statm_field(1)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn get_resident() -> Option<usize> {
|
||||
get_working_set_size()
|
||||
}
|
||||
|
||||
// Like std::macros::try!, but for Option<>.
|
||||
macro_rules! option_try(
|
||||
($e:expr) => (match $e { Some(e) => e, None => return None })
|
||||
);
|
||||
|
||||
// Memory reporting
|
||||
#[cfg(unix)]
|
||||
fn get_resident() -> Option<usize> {
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
||||
let field = 1;
|
||||
let mut f = option_try!(File::open("/proc/self/statm").ok());
|
||||
let mut contents = String::new();
|
||||
option_try!(f.read_to_string(&mut contents).ok());
|
||||
let s = option_try!(contents.split_whitespace().nth(field));
|
||||
let npages = option_try!(s.parse::<usize>().ok());
|
||||
Some(npages * 4096)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn get_working_set_size() -> Option<usize> {
|
||||
fn get_resident() -> Option<usize> {
|
||||
use libc::{BOOL, DWORD, HANDLE, SIZE_T, GetCurrentProcess};
|
||||
use std::mem;
|
||||
#[repr(C)] #[allow(non_snake_case)]
|
||||
|
@ -123,22 +127,6 @@ fn get_working_set_size() -> Option<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(windows, allow(dead_code))]
|
||||
#[allow(deprecated)]
|
||||
fn get_proc_self_statm_field(field: usize) -> Option<usize> {
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
||||
assert!(cfg!(unix));
|
||||
|
||||
let mut f = option_try!(File::open("/proc/self/statm").ok());
|
||||
let mut contents = String::new();
|
||||
option_try!(f.read_to_string(&mut contents).ok());
|
||||
let s = option_try!(contents.split_whitespace().nth(field));
|
||||
let npages = option_try!(s.parse::<usize>().ok());
|
||||
Some(npages * ::std::env::page_size())
|
||||
}
|
||||
|
||||
pub fn indent<R, F>(op: F) -> R where
|
||||
R: Debug,
|
||||
F: FnOnce() -> R,
|
||||
|
|
|
@ -75,7 +75,6 @@ impl TempDir {
|
|||
/// deleted once the returned wrapper is destroyed.
|
||||
///
|
||||
/// If no directory can be created, `Err` is returned.
|
||||
#[allow(deprecated)]
|
||||
pub fn new(prefix: &str) -> io::Result<TempDir> {
|
||||
TempDir::new_in(&env::temp_dir(), prefix)
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#![feature(no_std)]
|
||||
#![no_std]
|
||||
#![unstable(feature = "rustc_private")]
|
||||
#![cfg_attr(test, feature(hash_default))]
|
||||
|
||||
//! A typesafe bitmask flag generator.
|
||||
|
||||
|
@ -293,7 +292,7 @@ macro_rules! bitflags {
|
|||
#[cfg(test)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
mod tests {
|
||||
use std::hash::{self, SipHasher};
|
||||
use std::hash::{Hasher, Hash, SipHasher};
|
||||
use std::option::Option::{Some, None};
|
||||
|
||||
bitflags! {
|
||||
|
@ -487,9 +486,15 @@ mod tests {
|
|||
fn test_hash() {
|
||||
let mut x = Flags::empty();
|
||||
let mut y = Flags::empty();
|
||||
assert!(hash::hash::<Flags, SipHasher>(&x) == hash::hash::<Flags, SipHasher>(&y));
|
||||
assert!(hash(&x) == hash(&y));
|
||||
x = Flags::all();
|
||||
y = Flags::FlagABC;
|
||||
assert!(hash::hash::<Flags, SipHasher>(&x) == hash::hash::<Flags, SipHasher>(&y));
|
||||
assert!(hash(&x) == hash(&y));
|
||||
}
|
||||
|
||||
fn hash<T: Hash>(t: &T) -> u64 {
|
||||
let mut s = SipHasher::new();
|
||||
t.hash(&mut s);
|
||||
s.finish()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
//! Use the former for unit-like structs and the latter for structs with
|
||||
//! a `pub fn new()`.
|
||||
|
||||
// BitSet
|
||||
#![allow(deprecated)]
|
||||
|
||||
use metadata::{csearch, decoder};
|
||||
use middle::{cfg, def, infer, pat_util, stability, traits};
|
||||
use middle::subst::Substs;
|
||||
|
@ -41,7 +38,7 @@ use rustc::ast_map;
|
|||
use util::nodemap::{FnvHashMap, FnvHashSet, NodeSet};
|
||||
use lint::{Level, Context, LintPass, LintArray, Lint};
|
||||
|
||||
use std::collections::{HashSet, BitSet};
|
||||
use std::collections::HashSet;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::{cmp, slice};
|
||||
use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
|
||||
|
@ -2170,7 +2167,7 @@ impl LintPass for UnconditionalRecursion {
|
|||
let mut work_queue = vec![cfg.entry];
|
||||
let mut reached_exit_without_self_call = false;
|
||||
let mut self_call_spans = vec![];
|
||||
let mut visited = BitSet::new();
|
||||
let mut visited = HashSet::new();
|
||||
|
||||
while let Some(idx) = work_queue.pop() {
|
||||
if idx == cfg.exit {
|
||||
|
|
|
@ -703,7 +703,6 @@ impl<'v> Visitor<'v> for PathCollector {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub fn process_crate(tcx: &ty::ctxt,
|
||||
analysis: &ty::CrateAnalysis,
|
||||
odir: Option<&Path>) {
|
||||
|
|
|
@ -32,16 +32,12 @@
|
|||
use core::char::CharExt as C;
|
||||
use core::option::Option::{self, Some, None};
|
||||
use core::iter::Iterator;
|
||||
use tables::{derived_property, property, general_category, conversions, charwidth};
|
||||
use tables::{derived_property, property, general_category, conversions};
|
||||
|
||||
// stable reexports
|
||||
pub use core::char::{MAX, from_u32, from_u32_unchecked, from_digit, EscapeUnicode, EscapeDefault};
|
||||
|
||||
// unstable reexports
|
||||
#[allow(deprecated)]
|
||||
pub use normalize::{decompose_canonical, decompose_compatible, compose};
|
||||
#[allow(deprecated)]
|
||||
pub use tables::normalization::canonical_combining_class;
|
||||
pub use tables::UNICODE_VERSION;
|
||||
|
||||
/// An iterator over the lowercase mapping of a given character, returned from
|
||||
|
@ -502,22 +498,4 @@ impl char {
|
|||
pub fn to_uppercase(self) -> ToUppercase {
|
||||
ToUppercase(CaseMappingIter::new(conversions::to_upper(self)))
|
||||
}
|
||||
|
||||
/// Returns this character's displayed width in columns, or `None` if it is a
|
||||
/// control character other than `'\x00'`.
|
||||
///
|
||||
/// `is_cjk` determines behavior for characters in the Ambiguous category:
|
||||
/// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
|
||||
/// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
|
||||
/// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
|
||||
/// recommends that these characters be treated as 1 column (i.e.,
|
||||
/// `is_cjk` = `false`) if the context cannot be reliably determined.
|
||||
#[deprecated(reason = "use the crates.io `unicode-width` library instead",
|
||||
since = "1.0.0")]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "needs expert opinion. is_cjk flag stands out as ugly")]
|
||||
#[inline]
|
||||
pub fn width(self, is_cjk: bool) -> Option<usize> {
|
||||
charwidth::width(self, is_cjk)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,18 +37,16 @@
|
|||
#![feature(core_char_ext)]
|
||||
#![feature(core_slice_ext)]
|
||||
#![feature(core_str_ext)]
|
||||
#![feature(iter_arith)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(no_std)]
|
||||
#![feature(staged_api)]
|
||||
|
||||
mod normalize;
|
||||
mod tables;
|
||||
mod u_str;
|
||||
pub mod char;
|
||||
|
||||
pub mod str {
|
||||
pub use u_str::{UnicodeStr, SplitWhitespace, Words, Graphemes, GraphemeIndices};
|
||||
pub use u_str::{UnicodeStr, SplitWhitespace};
|
||||
pub use u_str::{utf8_char_width, is_utf16, Utf16Items, Utf16Item};
|
||||
pub use u_str::{utf16_items, Utf16Encoder};
|
||||
}
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
// Copyright 2012-2014 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.
|
||||
|
||||
//! Functions for computing canonical and compatible decompositions for Unicode characters.
|
||||
|
||||
use core::cmp::Ordering::{Equal, Less, Greater};
|
||||
use core::ops::FnMut;
|
||||
use core::option::Option;
|
||||
use core::option::Option::{Some, None};
|
||||
use core::slice::SliceExt;
|
||||
use core::result::Result::{Ok, Err};
|
||||
use tables::normalization::{canonical_table, compatibility_table, composition_table};
|
||||
|
||||
fn bsearch_table<T>(c: char, r: &'static [(char, &'static [T])]) -> Option<&'static [T]> {
|
||||
match r.binary_search_by(|&(val, _)| {
|
||||
if c == val { Equal }
|
||||
else if val < c { Less }
|
||||
else { Greater }
|
||||
}) {
|
||||
Ok(idx) => {
|
||||
let (_, result) = r[idx];
|
||||
Some(result)
|
||||
}
|
||||
Err(_) => None
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute canonical Unicode decomposition for character
|
||||
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
|
||||
since = "1.0.0")]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality will be moved to crates.io")]
|
||||
pub fn decompose_canonical<F>(c: char, mut i: F) where F: FnMut(char) { d(c, &mut i, false); }
|
||||
|
||||
/// Compute canonical or compatible Unicode decomposition for character
|
||||
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
|
||||
since = "1.0.0")]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality will be moved to crates.io")]
|
||||
pub fn decompose_compatible<F>(c: char, mut i: F) where F: FnMut(char) { d(c, &mut i, true); }
|
||||
|
||||
// FIXME(#19596) This is a workaround, we should use `F` instead of `&mut F`
|
||||
fn d<F>(c: char, i: &mut F, k: bool) where F: FnMut(char) {
|
||||
// 7-bit ASCII never decomposes
|
||||
if c <= '\x7f' { (*i)(c); return; }
|
||||
|
||||
// Perform decomposition for Hangul
|
||||
if (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) {
|
||||
decompose_hangul(c, i);
|
||||
return;
|
||||
}
|
||||
|
||||
// First check the canonical decompositions
|
||||
match bsearch_table(c, canonical_table) {
|
||||
Some(canon) => {
|
||||
for x in canon {
|
||||
d(*x, i, k);
|
||||
}
|
||||
return;
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
|
||||
// Bottom out if we're not doing compat.
|
||||
if !k { (*i)(c); return; }
|
||||
|
||||
// Then check the compatibility decompositions
|
||||
match bsearch_table(c, compatibility_table) {
|
||||
Some(compat) => {
|
||||
for x in compat {
|
||||
d(*x, i, k);
|
||||
}
|
||||
return;
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
|
||||
// Finally bottom out.
|
||||
(*i)(c);
|
||||
}
|
||||
|
||||
#[deprecated(reason = "use the crates.io `unicode-normalization` library instead",
|
||||
since = "1.0.0")]
|
||||
#[unstable(feature = "unicode",
|
||||
reason = "this functionality will be moved to crates.io")]
|
||||
pub fn compose(a: char, b: char) -> Option<char> {
|
||||
compose_hangul(a, b).or_else(|| {
|
||||
match bsearch_table(a, composition_table) {
|
||||
None => None,
|
||||
Some(candidates) => {
|
||||
match candidates.binary_search_by(|&(val, _)| {
|
||||
if b == val { Equal }
|
||||
else if val < b { Less }
|
||||
else { Greater }
|
||||
}) {
|
||||
Ok(idx) => {
|
||||
let (_, result) = candidates[idx];
|
||||
Some(result)
|
||||
}
|
||||
Err(_) => None
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Constants from Unicode 6.3.0 Section 3.12 Conjoining Jamo Behavior
|
||||
const S_BASE: u32 = 0xAC00;
|
||||
const L_BASE: u32 = 0x1100;
|
||||
const V_BASE: u32 = 0x1161;
|
||||
const T_BASE: u32 = 0x11A7;
|
||||
const L_COUNT: u32 = 19;
|
||||
const V_COUNT: u32 = 21;
|
||||
const T_COUNT: u32 = 28;
|
||||
const N_COUNT: u32 = (V_COUNT * T_COUNT);
|
||||
const S_COUNT: u32 = (L_COUNT * N_COUNT);
|
||||
|
||||
// FIXME(#19596) This is a workaround, we should use `F` instead of `&mut F`
|
||||
// Decompose a precomposed Hangul syllable
|
||||
#[inline(always)]
|
||||
fn decompose_hangul<F>(s: char, f: &mut F) where F: FnMut(char) {
|
||||
use core::char::from_u32_unchecked;
|
||||
let si = s as u32 - S_BASE;
|
||||
let li = si / N_COUNT;
|
||||
unsafe {
|
||||
(*f)(from_u32_unchecked(L_BASE + li));
|
||||
|
||||
let vi = (si % N_COUNT) / T_COUNT;
|
||||
(*f)(from_u32_unchecked(V_BASE + vi));
|
||||
|
||||
let ti = si % T_COUNT;
|
||||
if ti > 0 {
|
||||
(*f)(from_u32_unchecked(T_BASE + ti));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compose a pair of Hangul Jamo
|
||||
#[inline(always)]
|
||||
fn compose_hangul(a: char, b: char) -> Option<char> {
|
||||
use core::char::from_u32_unchecked;
|
||||
let l = a as u32;
|
||||
let v = b as u32;
|
||||
// Compose an LPart and a VPart
|
||||
if L_BASE <= l && l < (L_BASE + L_COUNT) && V_BASE <= v && v < (V_BASE + V_COUNT) {
|
||||
let r = S_BASE + (l - L_BASE) * N_COUNT + (v - V_BASE) * T_COUNT;
|
||||
return unsafe { Some(from_u32_unchecked(r)) };
|
||||
}
|
||||
// Compose an LVPart and a TPart
|
||||
if S_BASE <= l && l <= (S_BASE+S_COUNT-T_COUNT) && T_BASE <= v && v < (T_BASE+T_COUNT) {
|
||||
let r = l + (v - T_BASE);
|
||||
return unsafe { Some(from_u32_unchecked(r)) };
|
||||
}
|
||||
None
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -13,22 +13,11 @@
|
|||
//! This module provides functionality to `str` that requires the Unicode methods provided by the
|
||||
//! unicode parts of the CharExt trait.
|
||||
|
||||
use self::GraphemeState::*;
|
||||
|
||||
use core::char;
|
||||
use core::cmp;
|
||||
use core::iter::Filter;
|
||||
use core::slice;
|
||||
use core::str::Split;
|
||||
|
||||
use tables::grapheme::GraphemeCat;
|
||||
|
||||
#[deprecated(reason = "struct Words is being replaced by struct SplitWhitespace",
|
||||
since = "1.1.0")]
|
||||
#[unstable(feature = "str_words",
|
||||
reason = "words() will be replaced by split_whitespace() in 1.1.0")]
|
||||
pub type Words<'a> = SplitWhitespace<'a>;
|
||||
|
||||
/// An iterator over the non-whitespace substrings of a string,
|
||||
/// separated by any amount of whitespace.
|
||||
#[stable(feature = "split_whitespace", since = "1.1.0")]
|
||||
|
@ -39,36 +28,15 @@ pub struct SplitWhitespace<'a> {
|
|||
/// Methods for Unicode string slices
|
||||
#[allow(missing_docs)] // docs in libcollections
|
||||
pub trait UnicodeStr {
|
||||
fn graphemes<'a>(&'a self, is_extended: bool) -> Graphemes<'a>;
|
||||
fn grapheme_indices<'a>(&'a self, is_extended: bool) -> GraphemeIndices<'a>;
|
||||
#[allow(deprecated)]
|
||||
fn words<'a>(&'a self) -> Words<'a>;
|
||||
fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
|
||||
fn is_whitespace(&self) -> bool;
|
||||
fn is_alphanumeric(&self) -> bool;
|
||||
fn width(&self, is_cjk: bool) -> usize;
|
||||
fn trim<'a>(&'a self) -> &'a str;
|
||||
fn trim_left<'a>(&'a self) -> &'a str;
|
||||
fn trim_right<'a>(&'a self) -> &'a str;
|
||||
}
|
||||
|
||||
impl UnicodeStr for str {
|
||||
#[inline]
|
||||
fn graphemes(&self, is_extended: bool) -> Graphemes {
|
||||
Graphemes { string: self, extended: is_extended, cat: None, catb: None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
|
||||
GraphemeIndices { start_offset: self.as_ptr() as usize, iter: self.graphemes(is_extended) }
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[inline]
|
||||
fn words(&self) -> Words {
|
||||
self.split_whitespace()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn split_whitespace(&self) -> SplitWhitespace {
|
||||
fn is_not_empty(s: &&str) -> bool { !s.is_empty() }
|
||||
|
@ -86,12 +54,6 @@ impl UnicodeStr for str {
|
|||
#[inline]
|
||||
fn is_alphanumeric(&self) -> bool { self.chars().all(|c| c.is_alphanumeric()) }
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[inline]
|
||||
fn width(&self, is_cjk: bool) -> usize {
|
||||
self.chars().map(|c| c.width(is_cjk).unwrap_or(0)).sum()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn trim(&self) -> &str {
|
||||
self.trim_matches(|c: char| c.is_whitespace())
|
||||
|
@ -108,264 +70,6 @@ impl UnicodeStr for str {
|
|||
}
|
||||
}
|
||||
|
||||
/// External iterator for grapheme clusters and byte offsets.
|
||||
#[derive(Clone)]
|
||||
pub struct GraphemeIndices<'a> {
|
||||
start_offset: usize,
|
||||
iter: Graphemes<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for GraphemeIndices<'a> {
|
||||
type Item = (usize, &'a str);
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<(usize, &'a str)> {
|
||||
self.iter.next().map(|s| (s.as_ptr() as usize - self.start_offset, s))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DoubleEndedIterator for GraphemeIndices<'a> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<(usize, &'a str)> {
|
||||
self.iter.next_back().map(|s| (s.as_ptr() as usize - self.start_offset, s))
|
||||
}
|
||||
}
|
||||
|
||||
/// External iterator for a string's
|
||||
/// [grapheme clusters](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries).
|
||||
#[derive(Clone)]
|
||||
pub struct Graphemes<'a> {
|
||||
string: &'a str,
|
||||
extended: bool,
|
||||
cat: Option<GraphemeCat>,
|
||||
catb: Option<GraphemeCat>,
|
||||
}
|
||||
|
||||
// state machine for cluster boundary rules
|
||||
#[derive(PartialEq,Eq)]
|
||||
enum GraphemeState {
|
||||
Start,
|
||||
FindExtend,
|
||||
HangulL,
|
||||
HangulLV,
|
||||
HangulLVT,
|
||||
Regional,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Graphemes<'a> {
|
||||
type Item = &'a str;
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let slen = self.string.len();
|
||||
(cmp::min(slen, 1), Some(slen))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a str> {
|
||||
use tables::grapheme as gr;
|
||||
if self.string.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut take_curr = true;
|
||||
let mut idx = 0;
|
||||
let mut state = Start;
|
||||
let mut cat = gr::GC_Any;
|
||||
for (curr, ch) in self.string.char_indices() {
|
||||
idx = curr;
|
||||
|
||||
// retrieve cached category, if any
|
||||
// We do this because most of the time we would end up
|
||||
// looking up each character twice.
|
||||
cat = match self.cat {
|
||||
None => gr::grapheme_category(ch),
|
||||
_ => self.cat.take().unwrap()
|
||||
};
|
||||
|
||||
if match cat {
|
||||
gr::GC_Extend => true,
|
||||
gr::GC_SpacingMark if self.extended => true,
|
||||
_ => false
|
||||
} {
|
||||
state = FindExtend; // rule GB9/GB9a
|
||||
continue;
|
||||
}
|
||||
|
||||
state = match state {
|
||||
Start if '\r' == ch => {
|
||||
let slen = self.string.len();
|
||||
let nidx = idx + 1;
|
||||
if nidx != slen && self.string.char_at(nidx) == '\n' {
|
||||
idx = nidx; // rule GB3
|
||||
}
|
||||
break; // rule GB4
|
||||
}
|
||||
Start => match cat {
|
||||
gr::GC_Control => break,
|
||||
gr::GC_L => HangulL,
|
||||
gr::GC_LV | gr::GC_V => HangulLV,
|
||||
gr::GC_LVT | gr::GC_T => HangulLVT,
|
||||
gr::GC_Regional_Indicator => Regional,
|
||||
_ => FindExtend
|
||||
},
|
||||
FindExtend => { // found non-extending when looking for extending
|
||||
take_curr = false;
|
||||
break;
|
||||
},
|
||||
HangulL => match cat { // rule GB6: L x (L|V|LV|LVT)
|
||||
gr::GC_L => continue,
|
||||
gr::GC_LV | gr::GC_V => HangulLV,
|
||||
gr::GC_LVT => HangulLVT,
|
||||
_ => {
|
||||
take_curr = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
HangulLV => match cat { // rule GB7: (LV|V) x (V|T)
|
||||
gr::GC_V => continue,
|
||||
gr::GC_T => HangulLVT,
|
||||
_ => {
|
||||
take_curr = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
HangulLVT => match cat { // rule GB8: (LVT|T) x T
|
||||
gr::GC_T => continue,
|
||||
_ => {
|
||||
take_curr = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
Regional => match cat { // rule GB8a
|
||||
gr::GC_Regional_Indicator => continue,
|
||||
_ => {
|
||||
take_curr = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.cat = if take_curr {
|
||||
idx = idx + self.string.char_at(idx).len_utf8();
|
||||
None
|
||||
} else {
|
||||
Some(cat)
|
||||
};
|
||||
|
||||
let retstr = &self.string[..idx];
|
||||
self.string = &self.string[idx..];
|
||||
Some(retstr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DoubleEndedIterator for Graphemes<'a> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a str> {
|
||||
use tables::grapheme as gr;
|
||||
if self.string.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut take_curr = true;
|
||||
let mut idx = self.string.len();
|
||||
let mut previdx = idx;
|
||||
let mut state = Start;
|
||||
let mut cat = gr::GC_Any;
|
||||
for (curr, ch) in self.string.char_indices().rev() {
|
||||
previdx = idx;
|
||||
idx = curr;
|
||||
|
||||
// cached category, if any
|
||||
cat = match self.catb {
|
||||
None => gr::grapheme_category(ch),
|
||||
_ => self.catb.take().unwrap()
|
||||
};
|
||||
|
||||
// a matching state machine that runs *backwards* across an input string
|
||||
// note that this has some implications for the Hangul matching, since
|
||||
// we now need to know what the rightward letter is:
|
||||
//
|
||||
// Right to left, we have:
|
||||
// L x L
|
||||
// V x (L|V|LV)
|
||||
// T x (V|T|LV|LVT)
|
||||
// HangulL means the letter to the right is L
|
||||
// HangulLV means the letter to the right is V
|
||||
// HangulLVT means the letter to the right is T
|
||||
state = match state {
|
||||
Start if '\n' == ch => {
|
||||
if idx > 0 && '\r' == self.string.char_at_reverse(idx) {
|
||||
idx -= 1; // rule GB3
|
||||
}
|
||||
break; // rule GB4
|
||||
},
|
||||
Start | FindExtend => match cat {
|
||||
gr::GC_Extend => FindExtend,
|
||||
gr::GC_SpacingMark if self.extended => FindExtend,
|
||||
gr::GC_L | gr::GC_LV | gr::GC_LVT => HangulL,
|
||||
gr::GC_V => HangulLV,
|
||||
gr::GC_T => HangulLVT,
|
||||
gr::GC_Regional_Indicator => Regional,
|
||||
gr::GC_Control => {
|
||||
take_curr = Start == state;
|
||||
break;
|
||||
},
|
||||
_ => break
|
||||
},
|
||||
HangulL => match cat { // char to right is an L
|
||||
gr::GC_L => continue, // L x L is the only legal match
|
||||
_ => {
|
||||
take_curr = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
HangulLV => match cat { // char to right is a V
|
||||
gr::GC_V => continue, // V x V, right char is still V
|
||||
gr::GC_L | gr::GC_LV => HangulL, // (L|V) x V, right char is now L
|
||||
_ => {
|
||||
take_curr = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
HangulLVT => match cat { // char to right is a T
|
||||
gr::GC_T => continue, // T x T, right char is still T
|
||||
gr::GC_V => HangulLV, // V x T, right char is now V
|
||||
gr::GC_LV | gr::GC_LVT => HangulL, // (LV|LVT) x T, right char is now L
|
||||
_ => {
|
||||
take_curr = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
Regional => match cat { // rule GB8a
|
||||
gr::GC_Regional_Indicator => continue,
|
||||
_ => {
|
||||
take_curr = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.catb = if take_curr {
|
||||
None
|
||||
} else {
|
||||
idx = previdx;
|
||||
Some(cat)
|
||||
};
|
||||
|
||||
let retstr = &self.string[idx..];
|
||||
self.string = &self.string[..idx];
|
||||
Some(retstr)
|
||||
}
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/html/rfc3629
|
||||
static UTF8_CHAR_WIDTH: [u8; 256] = [
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
|
|
|
@ -354,7 +354,6 @@ fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
|
|||
/// generated from the cleaned AST of the crate.
|
||||
///
|
||||
/// This form of input will run all of the plug/cleaning passes
|
||||
#[allow(deprecated)] // for old Path in plugin manager
|
||||
fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matches) -> Output {
|
||||
let mut default_passes = !matches.opt_present("no-defaults");
|
||||
let mut passes = matches.opt_strs("passes");
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(deprecated)] // old path, used for compatibility with dynamic lib
|
||||
|
||||
use clean;
|
||||
|
||||
use std::dynamic_lib as dl;
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// VecMap
|
||||
#![allow(deprecated)]
|
||||
|
||||
//! Implementations of serialization for structures found in libcollections
|
||||
|
||||
use std::usize;
|
||||
|
@ -19,7 +16,7 @@ use std::hash::Hash;
|
|||
use std::collections::hash_state::HashState;
|
||||
|
||||
use {Decodable, Encodable, Decoder, Encoder};
|
||||
use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet, VecMap};
|
||||
use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use collections::enum_set::{EnumSet, CLike};
|
||||
|
||||
impl<
|
||||
|
@ -228,29 +225,3 @@ impl<T, S> Decodable for HashSet<T, S>
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Encodable> Encodable for VecMap<V> {
|
||||
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
|
||||
e.emit_map(self.len(), |e| {
|
||||
for (i, (key, val)) in self.iter().enumerate() {
|
||||
try!(e.emit_map_elt_key(i, |e| key.encode(e)));
|
||||
try!(e.emit_map_elt_val(i, |e| val.encode(e)));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Decodable> Decodable for VecMap<V> {
|
||||
fn decode<D: Decoder>(d: &mut D) -> Result<VecMap<V>, D::Error> {
|
||||
d.read_map(|d, len| {
|
||||
let mut map = VecMap::new();
|
||||
for i in 0..len {
|
||||
let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
|
||||
let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
|
||||
map.insert(key, val);
|
||||
}
|
||||
Ok(map)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1552,7 +1552,6 @@ impl<T: Iterator<Item=char>> Parser<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)] // possible resolve bug is mapping these to traits
|
||||
fn parse_u64(&mut self) -> Result<u64, ParserError> {
|
||||
let mut accum = 0u64;
|
||||
let last_accum = 0; // necessary to detect overflow.
|
||||
|
|
|
@ -36,7 +36,6 @@ Core encoding and decoding interfaces.
|
|||
#![feature(staged_api)]
|
||||
#![feature(str_char)]
|
||||
#![feature(unicode)]
|
||||
#![feature(vecmap)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
|
||||
// test harness access
|
||||
|
|
|
@ -17,24 +17,6 @@ use prelude::v1::*;
|
|||
use mem;
|
||||
use ops::Range;
|
||||
|
||||
/// Extension methods for ASCII-subset only operations on owned strings
|
||||
#[unstable(feature = "owned_ascii_ext",
|
||||
reason = "would prefer to do this in a more general way")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "hasn't yet proved essential to be in the standard library")]
|
||||
#[allow(deprecated)]
|
||||
pub trait OwnedAsciiExt {
|
||||
/// Converts the string to ASCII upper case:
|
||||
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
|
||||
/// but non-ASCII letters are unchanged.
|
||||
fn into_ascii_uppercase(self) -> Self;
|
||||
|
||||
/// Converts the string to ASCII lower case:
|
||||
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
|
||||
/// but non-ASCII letters are unchanged.
|
||||
fn into_ascii_lowercase(self) -> Self;
|
||||
}
|
||||
|
||||
/// Extension methods for ASCII-subset only operations on string slices.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait AsciiExt {
|
||||
|
@ -169,15 +151,19 @@ impl AsciiExt for str {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn to_ascii_uppercase(&self) -> String {
|
||||
self.to_string().into_ascii_uppercase()
|
||||
let mut bytes = self.as_bytes().to_vec();
|
||||
bytes.make_ascii_uppercase();
|
||||
// make_ascii_uppercase() preserves the UTF-8 invariant.
|
||||
unsafe { String::from_utf8_unchecked(bytes) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn to_ascii_lowercase(&self) -> String {
|
||||
self.to_string().into_ascii_lowercase()
|
||||
let mut bytes = self.as_bytes().to_vec();
|
||||
bytes.make_ascii_lowercase();
|
||||
// make_ascii_uppercase() preserves the UTF-8 invariant.
|
||||
unsafe { String::from_utf8_unchecked(bytes) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -196,21 +182,6 @@ impl AsciiExt for str {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl OwnedAsciiExt for String {
|
||||
#[inline]
|
||||
fn into_ascii_uppercase(self) -> String {
|
||||
// Vec<u8>::into_ascii_uppercase() preserves the UTF-8 invariant.
|
||||
unsafe { String::from_utf8_unchecked(self.into_bytes().into_ascii_uppercase()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn into_ascii_lowercase(self) -> String {
|
||||
// Vec<u8>::into_ascii_lowercase() preserves the UTF-8 invariant.
|
||||
unsafe { String::from_utf8_unchecked(self.into_bytes().into_ascii_lowercase()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsciiExt for [u8] {
|
||||
type Owned = Vec<u8>;
|
||||
|
@ -220,15 +191,17 @@ impl AsciiExt for [u8] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn to_ascii_uppercase(&self) -> Vec<u8> {
|
||||
self.to_vec().into_ascii_uppercase()
|
||||
let mut me = self.to_vec();
|
||||
me.make_ascii_uppercase();
|
||||
return me
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn to_ascii_lowercase(&self) -> Vec<u8> {
|
||||
self.to_vec().into_ascii_lowercase()
|
||||
let mut me = self.to_vec();
|
||||
me.make_ascii_lowercase();
|
||||
return me
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -252,21 +225,6 @@ impl AsciiExt for [u8] {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl OwnedAsciiExt for Vec<u8> {
|
||||
#[inline]
|
||||
fn into_ascii_uppercase(mut self) -> Vec<u8> {
|
||||
self.make_ascii_uppercase();
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn into_ascii_lowercase(mut self) -> Vec<u8> {
|
||||
self.make_ascii_lowercase();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsciiExt for u8 {
|
||||
type Owned = u8;
|
||||
|
@ -522,35 +480,6 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_ascii_uppercase() {
|
||||
assert_eq!(("url()URL()uRl()ürl".to_string()).into_ascii_uppercase(),
|
||||
"URL()URL()URL()üRL".to_string());
|
||||
assert_eq!(("hıKß".to_string()).into_ascii_uppercase(), "HıKß");
|
||||
|
||||
for i in 0..501 {
|
||||
let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
|
||||
else { i };
|
||||
assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_uppercase(),
|
||||
(from_u32(upper).unwrap()).to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_ascii_lowercase() {
|
||||
assert_eq!(("url()URL()uRl()Ürl".to_string()).into_ascii_lowercase(),
|
||||
"url()url()url()Ürl");
|
||||
// Dotted capital I, Kelvin sign, Sharp S.
|
||||
assert_eq!(("HİKß".to_string()).into_ascii_lowercase(), "hİKß");
|
||||
|
||||
for i in 0..501 {
|
||||
let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
|
||||
else { i };
|
||||
assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_lowercase(),
|
||||
(from_u32(lower).unwrap()).to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_make_ascii_lower_case() {
|
||||
macro_rules! test {
|
||||
|
|
|
@ -24,7 +24,7 @@ use mem::{self, replace};
|
|||
use ops::{Deref, FnMut, FnOnce, Index};
|
||||
use option::Option::{self, Some, None};
|
||||
use rand::{self, Rng};
|
||||
use result::Result::{self, Ok, Err};
|
||||
use result::Result;
|
||||
|
||||
use super::table::{
|
||||
self,
|
||||
|
@ -1482,18 +1482,6 @@ impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
|
|||
}
|
||||
|
||||
impl<'a, K, V> Entry<'a, K, V> {
|
||||
#[unstable(feature = "entry",
|
||||
reason = "will soon be replaced by or_insert")]
|
||||
#[deprecated(since = "1.0",
|
||||
reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
|
||||
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
|
||||
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
|
||||
match self {
|
||||
Occupied(entry) => Ok(entry.into_mut()),
|
||||
Vacant(entry) => Err(entry),
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
/// Ensures a value is in the entry by inserting the default if empty, and returns
|
||||
/// a mutable reference to the value in the entry.
|
||||
|
@ -1610,7 +1598,7 @@ pub struct RandomState {
|
|||
impl RandomState {
|
||||
/// Constructs a new `RandomState` that is initialized with random keys.
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
#[allow(deprecated)] // rand
|
||||
pub fn new() -> RandomState {
|
||||
let mut r = rand::thread_rng();
|
||||
RandomState { k0: r.gen(), k1: r.gen() }
|
||||
|
|
|
@ -385,11 +385,11 @@
|
|||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
pub use core_collections::Bound;
|
||||
pub use core_collections::{BinaryHeap, BitVec, BitSet, BTreeMap, BTreeSet};
|
||||
pub use core_collections::{LinkedList, VecDeque, VecMap};
|
||||
pub use core_collections::{BinaryHeap, BTreeMap, BTreeSet};
|
||||
pub use core_collections::{LinkedList, VecDeque};
|
||||
|
||||
pub use core_collections::{binary_heap, bit_vec, bit_set, btree_map, btree_set};
|
||||
pub use core_collections::{linked_list, vec_deque, vec_map};
|
||||
pub use core_collections::{binary_heap, btree_map, btree_set};
|
||||
pub use core_collections::{linked_list, vec_deque};
|
||||
|
||||
pub use self::hash_map::HashMap;
|
||||
pub use self::hash_set::HashSet;
|
||||
|
|
|
@ -23,7 +23,6 @@ use ffi::{OsStr, OsString};
|
|||
use fmt;
|
||||
use io;
|
||||
use path::{Path, PathBuf};
|
||||
use sync::atomic::{AtomicIsize, Ordering};
|
||||
use sync::StaticMutex;
|
||||
use sys::os as os_imp;
|
||||
|
||||
|
@ -474,30 +473,6 @@ pub fn current_exe() -> io::Result<PathBuf> {
|
|||
os_imp::current_exe()
|
||||
}
|
||||
|
||||
static EXIT_STATUS: AtomicIsize = AtomicIsize::new(0);
|
||||
|
||||
/// Sets the process exit code
|
||||
///
|
||||
/// Sets the exit code returned by the process if all supervised threads
|
||||
/// terminate successfully (without panicking). If the current root thread panics
|
||||
/// and is supervised by the scheduler then any user-specified exit status is
|
||||
/// ignored and the process exits with the default panic status.
|
||||
///
|
||||
/// Note that this is not synchronized against modifications of other threads.
|
||||
#[unstable(feature = "exit_status", reason = "managing the exit status may change")]
|
||||
#[deprecated(since = "1.2.0", reason = "use process::exit instead")]
|
||||
pub fn set_exit_status(code: i32) {
|
||||
EXIT_STATUS.store(code as isize, Ordering::SeqCst)
|
||||
}
|
||||
|
||||
/// Fetches the process's current exit code. This defaults to 0 and can change
|
||||
/// by calling `set_exit_status`.
|
||||
#[unstable(feature = "exit_status", reason = "managing the exit status may change")]
|
||||
#[deprecated(since = "1.2.0", reason = "use process::exit instead")]
|
||||
pub fn get_exit_status() -> i32 {
|
||||
EXIT_STATUS.load(Ordering::SeqCst) as i32
|
||||
}
|
||||
|
||||
/// An iterator over the arguments of a process, yielding a `String` value
|
||||
/// for each argument.
|
||||
///
|
||||
|
@ -588,14 +563,6 @@ impl ExactSizeIterator for ArgsOs {
|
|||
fn len(&self) -> usize { self.inner.len() }
|
||||
}
|
||||
|
||||
/// Returns the page size of the current architecture in bytes.
|
||||
#[unstable(feature = "page_size", reason = "naming and/or location may change")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "hasn't seen enough usage to justify inclusion")]
|
||||
pub fn page_size() -> usize {
|
||||
os_imp::page_size()
|
||||
}
|
||||
|
||||
/// Constants associated with the current target
|
||||
#[stable(feature = "env", since = "1.0.0")]
|
||||
pub mod consts {
|
||||
|
|
|
@ -468,6 +468,7 @@ mod tests {
|
|||
use super::*;
|
||||
use libc;
|
||||
use borrow::Cow::{Borrowed, Owned};
|
||||
use hash::{SipHasher, Hash, Hasher};
|
||||
|
||||
#[test]
|
||||
fn c_to_rust() {
|
||||
|
@ -545,15 +546,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn equal_hash() {
|
||||
use hash;
|
||||
|
||||
let data = b"123\xE2\xFA\xA6\0";
|
||||
let ptr = data.as_ptr() as *const libc::c_char;
|
||||
let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) };
|
||||
|
||||
let cstr_hash = hash::hash::<_, hash::SipHasher>(&cstr);
|
||||
let cstring_hash =
|
||||
hash::hash::<_, hash::SipHasher>(&CString::new(&data[..data.len() - 1]).unwrap());
|
||||
let mut s = SipHasher::new_with_keys(0, 0);
|
||||
cstr.hash(&mut s);
|
||||
let cstr_hash = s.finish();
|
||||
let mut s = SipHasher::new_with_keys(0, 0);
|
||||
CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s);
|
||||
let cstring_hash = s.finish();
|
||||
|
||||
assert_eq!(cstr_hash, cstring_hash);
|
||||
}
|
||||
|
|
|
@ -1216,23 +1216,6 @@ impl PathExt for Path {
|
|||
}
|
||||
}
|
||||
|
||||
/// Changes the timestamps for a file's last modification and access time.
|
||||
///
|
||||
/// The file at the path specified will have its last access time set to
|
||||
/// `accessed` and its modification time set to `modified`. The times specified
|
||||
/// should be in milliseconds.
|
||||
#[unstable(feature = "fs_time",
|
||||
reason = "the argument type of u64 is not quite appropriate for \
|
||||
this function and may change if the standard library \
|
||||
gains a type to represent a moment in time")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "will never be stabilized as-is and its replacement will \
|
||||
likely have a totally new API")]
|
||||
pub fn set_file_times<P: AsRef<Path>>(path: P, accessed: u64,
|
||||
modified: u64) -> io::Result<()> {
|
||||
fs_imp::utimes(path.as_ref(), accessed, modified)
|
||||
}
|
||||
|
||||
/// Changes the permissions found on a file or a directory.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -2049,44 +2032,6 @@ mod tests {
|
|||
assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utime() {
|
||||
let tmpdir = tmpdir();
|
||||
let path = tmpdir.join("a");
|
||||
check!(File::create(&path));
|
||||
// These numbers have to be bigger than the time in the day to account
|
||||
// for timezones Windows in particular will fail in certain timezones
|
||||
// with small enough values
|
||||
check!(fs::set_file_times(&path, 100_000, 200_000));
|
||||
|
||||
check(&check!(path.metadata()));
|
||||
|
||||
#[cfg(unix)]
|
||||
fn check(metadata: &fs::Metadata) {
|
||||
use os::unix::prelude::*;
|
||||
assert_eq!(metadata.atime(), 100);
|
||||
assert_eq!(metadata.atime_nsec(), 0);
|
||||
assert_eq!(metadata.mtime(), 200);
|
||||
assert_eq!(metadata.mtime_nsec(), 0);
|
||||
}
|
||||
#[cfg(windows)]
|
||||
fn check(metadata: &fs::Metadata) {
|
||||
use os::windows::prelude::*;
|
||||
assert_eq!(metadata.last_access_time(), 100_000 * 10_000);
|
||||
assert_eq!(metadata.last_write_time(), 200_000 * 10_000);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utime_noexist() {
|
||||
let tmpdir = tmpdir();
|
||||
|
||||
match fs::set_file_times(&tmpdir.join("a"), 100, 200) {
|
||||
Ok(..) => panic!(),
|
||||
Err(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn binary_file() {
|
||||
let mut bytes = [0; 1024];
|
||||
|
|
|
@ -785,129 +785,11 @@ impl<W: Read + Write> Read for InternalBufWriter<W> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Wraps a Stream and buffers input and output to and from it.
|
||||
///
|
||||
/// It can be excessively inefficient to work directly with a `Read+Write`. For
|
||||
/// example, every call to `read` or `write` on `TcpStream` results in a system
|
||||
/// call. A `BufStream` keeps in memory buffers of data, making large,
|
||||
/// infrequent calls to `read` and `write` on the underlying `Read+Write`.
|
||||
///
|
||||
/// The output buffer will be written out when this stream is dropped.
|
||||
#[unstable(feature = "buf_stream",
|
||||
reason = "unsure about semantics of buffering two directions, \
|
||||
leading to issues like #17136")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "use the crates.io `bufstream` crate instead")]
|
||||
pub struct BufStream<S: Write> {
|
||||
inner: BufReader<InternalBufWriter<S>>
|
||||
}
|
||||
|
||||
#[unstable(feature = "buf_stream",
|
||||
reason = "unsure about semantics of buffering two directions, \
|
||||
leading to issues like #17136")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "use the crates.io `bufstream` crate instead")]
|
||||
#[allow(deprecated)]
|
||||
impl<S: Read + Write> BufStream<S> {
|
||||
/// Creates a new buffered stream with explicitly listed capacities for the
|
||||
/// reader/writer buffer.
|
||||
pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
|
||||
-> BufStream<S> {
|
||||
let writer = BufWriter::with_capacity(writer_cap, inner);
|
||||
let internal_writer = InternalBufWriter(writer);
|
||||
let reader = BufReader::with_capacity(reader_cap, internal_writer);
|
||||
BufStream { inner: reader }
|
||||
}
|
||||
|
||||
/// Creates a new buffered stream with the default reader/writer buffer
|
||||
/// capacities.
|
||||
pub fn new(inner: S) -> BufStream<S> {
|
||||
BufStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, inner)
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying stream.
|
||||
pub fn get_ref(&self) -> &S {
|
||||
let InternalBufWriter(ref w) = self.inner.inner;
|
||||
w.get_ref()
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the underlying stream.
|
||||
///
|
||||
/// It is inadvisable to read directly from or write directly to the
|
||||
/// underlying stream.
|
||||
pub fn get_mut(&mut self) -> &mut S {
|
||||
let InternalBufWriter(ref mut w) = self.inner.inner;
|
||||
w.get_mut()
|
||||
}
|
||||
|
||||
/// Unwraps this `BufStream`, returning the underlying stream.
|
||||
///
|
||||
/// The internal write buffer is written out before returning the stream.
|
||||
/// Any leftover data in the read buffer is lost.
|
||||
pub fn into_inner(self) -> Result<S, IntoInnerError<BufStream<S>>> {
|
||||
let BufReader { inner: InternalBufWriter(w), buf, pos, cap } = self.inner;
|
||||
w.into_inner().map_err(|IntoInnerError(w, e)| {
|
||||
IntoInnerError(BufStream {
|
||||
inner: BufReader { inner: InternalBufWriter(w), buf: buf, pos: pos, cap: cap },
|
||||
}, e)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "buf_stream",
|
||||
reason = "unsure about semantics of buffering two directions, \
|
||||
leading to issues like #17136")]
|
||||
#[allow(deprecated)]
|
||||
impl<S: Read + Write> BufRead for BufStream<S> {
|
||||
fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
|
||||
fn consume(&mut self, amt: usize) { self.inner.consume(amt) }
|
||||
}
|
||||
|
||||
#[unstable(feature = "buf_stream",
|
||||
reason = "unsure about semantics of buffering two directions, \
|
||||
leading to issues like #17136")]
|
||||
#[allow(deprecated)]
|
||||
impl<S: Read + Write> Read for BufStream<S> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "buf_stream",
|
||||
reason = "unsure about semantics of buffering two directions, \
|
||||
leading to issues like #17136")]
|
||||
#[allow(deprecated)]
|
||||
impl<S: Read + Write> Write for BufStream<S> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.inner.inner.get_mut().write(buf)
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.inner.inner.get_mut().flush()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "buf_stream",
|
||||
reason = "unsure about semantics of buffering two directions, \
|
||||
leading to issues like #17136")]
|
||||
#[allow(deprecated)]
|
||||
impl<S: Write> fmt::Debug for BufStream<S> where S: fmt::Debug {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let reader = &self.inner;
|
||||
let writer = &self.inner.inner.0;
|
||||
fmt.debug_struct("BufStream")
|
||||
.field("stream", &writer.inner)
|
||||
.field("write_buffer", &format_args!("{}/{}", writer.buf.len(), writer.buf.capacity()))
|
||||
.field("read_buffer",
|
||||
&format_args!("{}/{}", reader.cap - reader.pos, reader.buf.len()))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::v1::*;
|
||||
use io::prelude::*;
|
||||
use io::{self, BufReader, BufWriter, BufStream, Cursor, LineWriter, SeekFrom};
|
||||
use io::{self, BufReader, BufWriter, Cursor, LineWriter, SeekFrom};
|
||||
use test;
|
||||
|
||||
/// A dummy reader intended at testing short-reads propagation.
|
||||
|
@ -1078,27 +960,6 @@ mod tests {
|
|||
assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
|
||||
}
|
||||
|
||||
// This is just here to make sure that we don't infinite loop in the
|
||||
// newtype struct autoderef weirdness
|
||||
#[test]
|
||||
fn test_buffered_stream() {
|
||||
struct S;
|
||||
|
||||
impl Write for S {
|
||||
fn write(&mut self, b: &[u8]) -> io::Result<usize> { Ok(b.len()) }
|
||||
fn flush(&mut self) -> io::Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
impl Read for S {
|
||||
fn read(&mut self, _: &mut [u8]) -> io::Result<usize> { Ok(0) }
|
||||
}
|
||||
|
||||
let mut stream = BufStream::new(S);
|
||||
assert_eq!(stream.read(&mut [0; 10]).unwrap(), 0);
|
||||
stream.write(&[0; 10]).unwrap();
|
||||
stream.flush().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_until() {
|
||||
let inner: &[u8] = &[0, 1, 2, 1, 0];
|
||||
|
@ -1230,12 +1091,4 @@ mod tests {
|
|||
BufWriter::new(io::sink())
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_buffered_stream(b: &mut test::Bencher) {
|
||||
let mut buf = Cursor::new(Vec::new());
|
||||
b.iter(|| {
|
||||
BufStream::new(&mut buf);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,7 +255,7 @@ use string::String;
|
|||
use str;
|
||||
use vec::Vec;
|
||||
|
||||
pub use self::buffered::{BufReader, BufWriter, BufStream, LineWriter};
|
||||
pub use self::buffered::{BufReader, BufWriter, LineWriter};
|
||||
pub use self::buffered::IntoInnerError;
|
||||
pub use self::cursor::Cursor;
|
||||
pub use self::error::{Result, Error, ErrorKind};
|
||||
|
|
|
@ -360,8 +360,6 @@ mod uint_macros;
|
|||
|
||||
pub mod ascii;
|
||||
|
||||
pub mod thunk;
|
||||
|
||||
/* Common traits */
|
||||
|
||||
pub mod num;
|
||||
|
|
|
@ -128,26 +128,6 @@ impl TcpStream {
|
|||
self.0.duplicate().map(TcpStream)
|
||||
}
|
||||
|
||||
/// Sets the nodelay flag on this connection to the boolean specified.
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "available through the `net2` crate on crates.io")]
|
||||
#[unstable(feature = "tcp_extras", reason = "available externally")]
|
||||
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
|
||||
self.0.set_nodelay(nodelay)
|
||||
}
|
||||
|
||||
/// Sets the keepalive timeout to the timeout specified.
|
||||
///
|
||||
/// If the value specified is `None`, then the keepalive flag is cleared on
|
||||
/// this connection. Otherwise, the keepalive timeout will be set to the
|
||||
/// specified time, in seconds.
|
||||
#[unstable(feature = "tcp_extras", reason = "available externally")]
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "available through the `net2` crate on crates.io")]
|
||||
pub fn set_keepalive(&self, seconds: Option<u32>) -> io::Result<()> {
|
||||
self.0.set_keepalive(seconds)
|
||||
}
|
||||
|
||||
/// Sets the read timeout to the timeout specified.
|
||||
///
|
||||
/// If the value specified is `None`, then `read` calls will block
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
use fmt;
|
||||
use io::{self, Error, ErrorKind};
|
||||
use net::{ToSocketAddrs, SocketAddr, IpAddr};
|
||||
use net::{ToSocketAddrs, SocketAddr};
|
||||
use sys_common::net as net_imp;
|
||||
use sys_common::{AsInner, FromInner, IntoInner};
|
||||
use time::Duration;
|
||||
|
@ -95,56 +95,6 @@ impl UdpSocket {
|
|||
self.0.duplicate().map(UdpSocket)
|
||||
}
|
||||
|
||||
/// Sets the broadcast flag on or off.
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "available through the `net2` crate on crates.io")]
|
||||
#[unstable(feature = "udp_extras", reason = "available externally")]
|
||||
pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
|
||||
self.0.set_broadcast(on)
|
||||
}
|
||||
|
||||
/// Sets the multicast loop flag to the specified value.
|
||||
///
|
||||
/// This lets multicast packets loop back to local sockets (if enabled)
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "available through the `net2` crate on crates.io")]
|
||||
#[unstable(feature = "udp_extras", reason = "available externally")]
|
||||
pub fn set_multicast_loop(&self, on: bool) -> io::Result<()> {
|
||||
self.0.set_multicast_loop(on)
|
||||
}
|
||||
|
||||
/// Joins a multicast IP address (becomes a member of it).
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "available through the `net2` crate on crates.io")]
|
||||
#[unstable(feature = "udp_extras", reason = "available externally")]
|
||||
pub fn join_multicast(&self, multi: &IpAddr) -> io::Result<()> {
|
||||
self.0.join_multicast(multi)
|
||||
}
|
||||
|
||||
/// Leaves a multicast IP address (drops membership from it).
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "available through the `net2` crate on crates.io")]
|
||||
#[unstable(feature = "udp_extras", reason = "available externally")]
|
||||
pub fn leave_multicast(&self, multi: &IpAddr) -> io::Result<()> {
|
||||
self.0.leave_multicast(multi)
|
||||
}
|
||||
|
||||
/// Sets the multicast TTL.
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "available through the `net2` crate on crates.io")]
|
||||
#[unstable(feature = "udp_extras", reason = "available externally")]
|
||||
pub fn set_multicast_time_to_live(&self, ttl: i32) -> io::Result<()> {
|
||||
self.0.multicast_time_to_live(ttl)
|
||||
}
|
||||
|
||||
/// Sets this socket's TTL.
|
||||
#[deprecated(since = "1.3.0",
|
||||
reason = "available through the `net2` crate on crates.io")]
|
||||
#[unstable(feature = "udp_extras", reason = "available externally")]
|
||||
pub fn set_time_to_live(&self, ttl: i32) -> io::Result<()> {
|
||||
self.0.time_to_live(ttl)
|
||||
}
|
||||
|
||||
/// Sets the read timeout to the timeout specified.
|
||||
///
|
||||
/// If the value specified is `None`, then `read` calls will block
|
||||
|
|
|
@ -1751,7 +1751,6 @@ mod tests {
|
|||
use super::consts;
|
||||
|
||||
let pi: f32 = consts::PI;
|
||||
let two_pi: f32 = consts::PI_2;
|
||||
let frac_pi_2: f32 = consts::FRAC_PI_2;
|
||||
let frac_pi_3: f32 = consts::FRAC_PI_3;
|
||||
let frac_pi_4: f32 = consts::FRAC_PI_4;
|
||||
|
@ -1768,7 +1767,6 @@ mod tests {
|
|||
let ln_2: f32 = consts::LN_2;
|
||||
let ln_10: f32 = consts::LN_10;
|
||||
|
||||
assert_approx_eq!(two_pi, 2f32 * pi);
|
||||
assert_approx_eq!(frac_pi_2, pi / 2f32);
|
||||
assert_approx_eq!(frac_pi_3, pi / 3f32);
|
||||
assert_approx_eq!(frac_pi_4, pi / 4f32);
|
||||
|
|
|
@ -1651,7 +1651,6 @@ mod tests {
|
|||
fn test_real_consts() {
|
||||
use super::consts;
|
||||
let pi: f64 = consts::PI;
|
||||
let two_pi: f64 = consts::PI_2;
|
||||
let frac_pi_2: f64 = consts::FRAC_PI_2;
|
||||
let frac_pi_3: f64 = consts::FRAC_PI_3;
|
||||
let frac_pi_4: f64 = consts::FRAC_PI_4;
|
||||
|
@ -1668,7 +1667,6 @@ mod tests {
|
|||
let ln_2: f64 = consts::LN_2;
|
||||
let ln_10: f64 = consts::LN_10;
|
||||
|
||||
assert_approx_eq!(two_pi, 2.0 * pi);
|
||||
assert_approx_eq!(frac_pi_2, pi / 2f64);
|
||||
assert_approx_eq!(frac_pi_3, pi / 3f64);
|
||||
assert_approx_eq!(frac_pi_4, pi / 4f64);
|
||||
|
|
|
@ -59,7 +59,6 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
|
|||
use prelude::v1::*;
|
||||
|
||||
use mem;
|
||||
use env;
|
||||
use rt;
|
||||
use sys_common::thread_info::{self, NewThread};
|
||||
use thread::Thread;
|
||||
|
@ -105,9 +104,7 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
|
|||
if failed {
|
||||
rt::DEFAULT_ERROR_CODE
|
||||
} else {
|
||||
#[allow(deprecated)]
|
||||
fn exit_status() -> isize { env::get_exit_status() as isize }
|
||||
exit_status()
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,231 +0,0 @@
|
|||
// 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.
|
||||
|
||||
//! A type representing values that may be computed concurrently and operations
|
||||
//! for working with them.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```
|
||||
//! #![feature(future)]
|
||||
//!
|
||||
//! use std::sync::Future;
|
||||
//!
|
||||
//! // a fake, for now
|
||||
//! fn fib(n: u32) -> u32 { 42 };
|
||||
//!
|
||||
//! let mut delayed_fib = Future::spawn(move || fib(5000));
|
||||
//!
|
||||
//! // do stuff...
|
||||
//!
|
||||
//! println!("fib(5000) = {}", delayed_fib.get())
|
||||
//! ```
|
||||
|
||||
#![allow(missing_docs)]
|
||||
#![unstable(feature = "future",
|
||||
reason = "futures as-is have yet to be deeply reevaluated with recent \
|
||||
core changes to Rust's synchronization story, and will likely \
|
||||
become stable in the future but are unstable until that time")]
|
||||
#![deprecated(since = "1.2.0",
|
||||
reason = "implementation does not match the quality of the \
|
||||
standard library and this will likely be prototyped \
|
||||
outside in crates.io first")]
|
||||
#![allow(deprecated)]
|
||||
|
||||
use core::mem::replace;
|
||||
|
||||
use boxed::Box;
|
||||
use self::FutureState::*;
|
||||
use sync::mpsc::{Receiver, channel};
|
||||
use thunk::Thunk;
|
||||
use thread;
|
||||
|
||||
/// A type encapsulating the result of a computation which may not be complete
|
||||
pub struct Future<A> {
|
||||
state: FutureState<A>,
|
||||
}
|
||||
|
||||
enum FutureState<A> {
|
||||
Pending(Thunk<'static,(),A>),
|
||||
Evaluating,
|
||||
Forced(A)
|
||||
}
|
||||
|
||||
/// Methods on the `future` type
|
||||
impl<A:Clone> Future<A> {
|
||||
pub fn get(&mut self) -> A {
|
||||
//! Get the value of the future.
|
||||
(*(self.get_ref())).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> Future<A> {
|
||||
/// Gets the value from this future, forcing evaluation.
|
||||
pub fn into_inner(mut self) -> A {
|
||||
self.get_ref();
|
||||
let state = replace(&mut self.state, Evaluating);
|
||||
match state {
|
||||
Forced(v) => v,
|
||||
_ => panic!( "Logic error." ),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ref<'a>(&'a mut self) -> &'a A {
|
||||
/*!
|
||||
* Executes the future's closure and then returns a reference
|
||||
* to the result. The reference lasts as long as
|
||||
* the future.
|
||||
*/
|
||||
match self.state {
|
||||
Forced(ref v) => return v,
|
||||
Evaluating => panic!("Recursive forcing of future!"),
|
||||
Pending(_) => {
|
||||
match replace(&mut self.state, Evaluating) {
|
||||
Forced(_) | Evaluating => panic!("Logic error."),
|
||||
Pending(f) => {
|
||||
self.state = Forced(f());
|
||||
self.get_ref()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_value(val: A) -> Future<A> {
|
||||
/*!
|
||||
* Create a future from a value.
|
||||
*
|
||||
* The value is immediately available and calling `get` later will
|
||||
* not block.
|
||||
*/
|
||||
|
||||
Future {state: Forced(val)}
|
||||
}
|
||||
|
||||
pub fn from_fn<F>(f: F) -> Future<A>
|
||||
where F : FnOnce() -> A, F : Send + 'static
|
||||
{
|
||||
/*!
|
||||
* Create a future from a function.
|
||||
*
|
||||
* The first time that the value is requested it will be retrieved by
|
||||
* calling the function. Note that this function is a local
|
||||
* function. It is not spawned into another task.
|
||||
*/
|
||||
|
||||
Future {state: Pending(Box::new(f))}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A:Send+'static> Future<A> {
|
||||
pub fn from_receiver(rx: Receiver<A>) -> Future<A> {
|
||||
/*!
|
||||
* Create a future from a port
|
||||
*
|
||||
* The first time that the value is requested the task will block
|
||||
* waiting for the result to be received on the port.
|
||||
*/
|
||||
|
||||
Future::from_fn(move || {
|
||||
rx.recv().unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn spawn<F>(blk: F) -> Future<A>
|
||||
where F : FnOnce() -> A, F : Send + 'static
|
||||
{
|
||||
/*!
|
||||
* Create a future from a unique closure.
|
||||
*
|
||||
* The closure will be run in a new task and its result used as the
|
||||
* value of the future.
|
||||
*/
|
||||
|
||||
let (tx, rx) = channel();
|
||||
|
||||
thread::spawn(move || {
|
||||
// Don't panic if the other end has hung up
|
||||
let _ = tx.send(blk());
|
||||
});
|
||||
|
||||
Future::from_receiver(rx)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::v1::*;
|
||||
use sync::mpsc::channel;
|
||||
use sync::Future;
|
||||
use thread;
|
||||
|
||||
#[test]
|
||||
fn test_from_value() {
|
||||
let mut f = Future::from_value("snail".to_string());
|
||||
assert_eq!(f.get(), "snail");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_receiver() {
|
||||
let (tx, rx) = channel();
|
||||
tx.send("whale".to_string()).unwrap();
|
||||
let mut f = Future::from_receiver(rx);
|
||||
assert_eq!(f.get(), "whale");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_fn() {
|
||||
let mut f = Future::from_fn(move|| "brail".to_string());
|
||||
assert_eq!(f.get(), "brail");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_interface_get() {
|
||||
let mut f = Future::from_value("fail".to_string());
|
||||
assert_eq!(f.get(), "fail");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_interface_unwrap() {
|
||||
let f = Future::from_value("fail".to_string());
|
||||
assert_eq!(f.into_inner(), "fail");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_ref_method() {
|
||||
let mut f = Future::from_value(22);
|
||||
assert_eq!(*f.get_ref(), 22);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_spawn() {
|
||||
let mut f = Future::spawn(move|| "bale".to_string());
|
||||
assert_eq!(f.get(), "bale");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_future_panic() {
|
||||
let mut f = Future::spawn(move|| panic!());
|
||||
let _x: String = f.get();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sendable_future() {
|
||||
let expected = "schlorf";
|
||||
let (tx, rx) = channel();
|
||||
let f = Future::spawn(move|| { expected });
|
||||
let _t = thread::spawn(move|| {
|
||||
let mut f = f;
|
||||
tx.send(f.get()).unwrap();
|
||||
});
|
||||
assert_eq!(rx.recv().unwrap(), expected);
|
||||
}
|
||||
}
|
|
@ -30,14 +30,10 @@ pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
|
|||
pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
|
||||
pub use self::semaphore::{Semaphore, SemaphoreGuard};
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub use self::future::Future;
|
||||
|
||||
pub mod mpsc;
|
||||
|
||||
mod barrier;
|
||||
mod condvar;
|
||||
mod future;
|
||||
mod mutex;
|
||||
mod once;
|
||||
mod rwlock;
|
||||
|
|
|
@ -186,42 +186,6 @@ impl TcpStream {
|
|||
|
||||
pub fn into_socket(self) -> Socket { self.inner }
|
||||
|
||||
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
|
||||
setsockopt(&self.inner, libc::IPPROTO_TCP, libc::TCP_NODELAY,
|
||||
nodelay as c_int)
|
||||
}
|
||||
|
||||
pub fn set_keepalive(&self, seconds: Option<u32>) -> io::Result<()> {
|
||||
let ret = setsockopt(&self.inner, libc::SOL_SOCKET, libc::SO_KEEPALIVE,
|
||||
seconds.is_some() as c_int);
|
||||
match seconds {
|
||||
Some(n) => ret.and_then(|()| self.set_tcp_keepalive(n)),
|
||||
None => ret,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
fn set_tcp_keepalive(&self, seconds: u32) -> io::Result<()> {
|
||||
setsockopt(&self.inner, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE,
|
||||
seconds as c_int)
|
||||
}
|
||||
#[cfg(any(target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "linux"))]
|
||||
fn set_tcp_keepalive(&self, seconds: u32) -> io::Result<()> {
|
||||
setsockopt(&self.inner, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE,
|
||||
seconds as c_int)
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "linux")))]
|
||||
fn set_tcp_keepalive(&self, _seconds: u32) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.inner.set_timeout(dur, libc::SO_RCVTIMEO)
|
||||
}
|
||||
|
@ -431,65 +395,6 @@ impl UdpSocket {
|
|||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
|
||||
setsockopt(&self.inner, libc::SOL_SOCKET, libc::SO_BROADCAST,
|
||||
on as c_int)
|
||||
}
|
||||
|
||||
pub fn set_multicast_loop(&self, on: bool) -> io::Result<()> {
|
||||
setsockopt(&self.inner, libc::IPPROTO_IP,
|
||||
libc::IP_MULTICAST_LOOP, on as c_int)
|
||||
}
|
||||
|
||||
pub fn join_multicast(&self, multi: &IpAddr) -> io::Result<()> {
|
||||
match *multi {
|
||||
IpAddr::V4(..) => {
|
||||
self.set_membership(multi, libc::IP_ADD_MEMBERSHIP)
|
||||
}
|
||||
IpAddr::V6(..) => {
|
||||
self.set_membership(multi, libc::IPV6_ADD_MEMBERSHIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn leave_multicast(&self, multi: &IpAddr) -> io::Result<()> {
|
||||
match *multi {
|
||||
IpAddr::V4(..) => {
|
||||
self.set_membership(multi, libc::IP_DROP_MEMBERSHIP)
|
||||
}
|
||||
IpAddr::V6(..) => {
|
||||
self.set_membership(multi, libc::IPV6_DROP_MEMBERSHIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn set_membership(&self, addr: &IpAddr, opt: c_int) -> io::Result<()> {
|
||||
match *addr {
|
||||
IpAddr::V4(ref addr) => {
|
||||
let mreq = libc::ip_mreq {
|
||||
imr_multiaddr: *addr.as_inner(),
|
||||
// interface == INADDR_ANY
|
||||
imr_interface: libc::in_addr { s_addr: 0x0 },
|
||||
};
|
||||
setsockopt(&self.inner, libc::IPPROTO_IP, opt, mreq)
|
||||
}
|
||||
IpAddr::V6(ref addr) => {
|
||||
let mreq = libc::ip6_mreq {
|
||||
ipv6mr_multiaddr: *addr.as_inner(),
|
||||
ipv6mr_interface: 0,
|
||||
};
|
||||
setsockopt(&self.inner, libc::IPPROTO_IPV6, opt, mreq)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn multicast_time_to_live(&self, ttl: i32) -> io::Result<()> {
|
||||
setsockopt(&self.inner, libc::IPPROTO_IP, libc::IP_MULTICAST_TTL,
|
||||
ttl as c_int)
|
||||
}
|
||||
|
||||
pub fn time_to_live(&self, ttl: i32) -> io::Result<()> {
|
||||
setsockopt(&self.inner, libc::IPPROTO_IP, libc::IP_TTL, ttl as c_int)
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<UdpSocket> {
|
||||
self.inner.duplicate().map(|s| UdpSocket { inner: s })
|
||||
}
|
||||
|
|
|
@ -180,10 +180,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn is_mutex() {
|
||||
let m = ReentrantMutex::new(RefCell::new(0));
|
||||
let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
|
||||
let m2 = m.clone();
|
||||
let lock = m.lock().unwrap();
|
||||
let handle = thread::scoped(|| {
|
||||
let lock = m.lock().unwrap();
|
||||
let child = thread::spawn(move || {
|
||||
let lock = m2.lock().unwrap();
|
||||
assert_eq!(*lock.borrow(), 4950);
|
||||
});
|
||||
for i in 0..100 {
|
||||
|
@ -191,20 +192,19 @@ mod tests {
|
|||
*lock.borrow_mut() += i;
|
||||
}
|
||||
drop(lock);
|
||||
drop(handle);
|
||||
child.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trylock_works() {
|
||||
let m = ReentrantMutex::new(());
|
||||
let m = Arc::new(ReentrantMutex::new(()));
|
||||
let m2 = m.clone();
|
||||
let lock = m.try_lock().unwrap();
|
||||
let lock2 = m.try_lock().unwrap();
|
||||
{
|
||||
thread::scoped(|| {
|
||||
let lock = m.try_lock();
|
||||
assert!(lock.is_err());
|
||||
});
|
||||
}
|
||||
thread::spawn(move || {
|
||||
let lock = m2.try_lock();
|
||||
assert!(lock.is_err());
|
||||
}).join().unwrap();
|
||||
let lock3 = m.try_lock().unwrap();
|
||||
}
|
||||
|
||||
|
|
|
@ -509,13 +509,6 @@ pub fn lstat(p: &Path) -> io::Result<FileAttr> {
|
|||
Ok(FileAttr { stat: stat })
|
||||
}
|
||||
|
||||
pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> {
|
||||
let p = try!(cstr(p));
|
||||
let buf = [super::ms_to_timeval(atime), super::ms_to_timeval(mtime)];
|
||||
try!(cvt(unsafe { c::utimes(p.as_ptr(), buf.as_ptr()) }));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
|
||||
let path = try!(CString::new(p.as_os_str().as_bytes()));
|
||||
let mut buf = vec![0u8; 16 * 1024];
|
||||
|
|
|
@ -82,7 +82,6 @@ pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
|
||||
where T: One + PartialEq + Neg<Output=T>, F: FnMut() -> T
|
||||
{
|
||||
|
@ -93,10 +92,3 @@ pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ms_to_timeval(ms: u64) -> libc::timeval {
|
||||
libc::timeval {
|
||||
tv_sec: (ms / 1000) as libc::time_t,
|
||||
tv_usec: ((ms % 1000) * 1000) as libc::suseconds_t,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -571,19 +571,6 @@ pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> {
|
||||
let atime = super::ms_to_filetime(atime);
|
||||
let mtime = super::ms_to_filetime(mtime);
|
||||
|
||||
let mut o = OpenOptions::new();
|
||||
o.write(true);
|
||||
let f = try!(File::open(p, &o));
|
||||
try!(cvt(unsafe {
|
||||
c::SetFileTime(f.handle.raw(), 0 as *const _, &atime, &mtime)
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_path(f: &File) -> io::Result<PathBuf> {
|
||||
super::fill_utf16_buf(|buf, sz| unsafe {
|
||||
c::GetFinalPathNameByHandleW(f.handle.raw(), buf, sz,
|
||||
|
|
|
@ -174,13 +174,3 @@ fn dur2timeout(dur: Duration) -> libc::DWORD {
|
|||
}
|
||||
}).unwrap_or(libc::INFINITE)
|
||||
}
|
||||
|
||||
fn ms_to_filetime(ms: u64) -> libc::FILETIME {
|
||||
// A FILETIME is a count of 100 nanosecond intervals, so we multiply by
|
||||
// 10000 b/c there are 10000 intervals in 1 ms
|
||||
let ms = ms * 10000;
|
||||
libc::FILETIME {
|
||||
dwLowDateTime: ms as u32,
|
||||
dwHighDateTime: (ms >> 32) as u32,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
|
|||
}
|
||||
|
||||
/// Provides the functionality of `cvt` for a closure.
|
||||
#[allow(deprecated)]
|
||||
pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
|
||||
where F: FnMut() -> T, T: One + Neg<Output=T> + PartialEq
|
||||
{
|
||||
|
|
|
@ -21,7 +21,6 @@ use fmt;
|
|||
use io;
|
||||
use libc::types::os::arch::extra::LPWCH;
|
||||
use libc::{self, c_int, c_void};
|
||||
use mem;
|
||||
use ops::Range;
|
||||
use os::windows::ffi::EncodeWide;
|
||||
use path::{self, PathBuf};
|
||||
|
@ -334,14 +333,6 @@ pub fn args() -> Args {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn page_size() -> usize {
|
||||
unsafe {
|
||||
let mut info = mem::zeroed();
|
||||
libc::GetSystemInfo(&mut info);
|
||||
return info.dwPageSize as usize;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn temp_dir() -> PathBuf {
|
||||
super::fill_utf16_buf(|buf, sz| unsafe {
|
||||
c::GetTempPathW(sz, buf)
|
||||
|
|
|
@ -253,36 +253,6 @@ impl Builder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Spawns a new child thread that must be joined within a given
|
||||
/// scope, and returns a `JoinGuard`.
|
||||
///
|
||||
/// The join guard can be used to explicitly join the child thread (via
|
||||
/// `join`), returning `Result<T>`, or it will implicitly join the child
|
||||
/// upon being dropped. Because the child thread may refer to data on the
|
||||
/// current thread's stack (hence the "scoped" name), it cannot be detached;
|
||||
/// it *must* be joined before the relevant stack frame is popped. See the
|
||||
/// documentation on `thread::scoped` for additional details.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Unlike the `scoped` free function, this method yields an
|
||||
/// `io::Result` to capture any failure to create the thread at
|
||||
/// the OS level.
|
||||
#[unstable(feature = "scoped",
|
||||
reason = "memory unsafe if destructor is avoided, see #24292")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "this unsafe API is unlikely to ever be stabilized \
|
||||
in this form")]
|
||||
pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
|
||||
T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
|
||||
{
|
||||
unsafe {
|
||||
self.spawn_inner(Box::new(f)).map(|inner| {
|
||||
JoinGuard { inner: inner, _marker: PhantomData }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NB: this function is unsafe as the lifetime parameter of the code to run
|
||||
// in the new thread is not tied into the return value, and the return
|
||||
// value must not outlast that lifetime.
|
||||
|
@ -346,50 +316,6 @@ pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
|
|||
Builder::new().spawn(f).unwrap()
|
||||
}
|
||||
|
||||
/// Spawns a new *scoped* thread, returning a `JoinGuard` for it.
|
||||
///
|
||||
/// The `spawn` method does not allow the child and parent threads to
|
||||
/// share any stack data, since that is not safe in general. However,
|
||||
/// `scoped` makes it possible to share the parent's stack by forcing
|
||||
/// a join before any relevant stack frames are popped:
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(scoped)]
|
||||
///
|
||||
/// use std::thread;
|
||||
///
|
||||
/// let guard = thread::scoped(move || {
|
||||
/// // some work here
|
||||
/// });
|
||||
///
|
||||
/// // do some other work in the meantime
|
||||
/// let output = guard.join();
|
||||
/// ```
|
||||
///
|
||||
/// The `scoped` function doesn't return a `Thread` directly; instead, it
|
||||
/// returns a *join guard*. The join guard can be used to explicitly join
|
||||
/// the child thread (via `join`), returning `Result<T>`, or it will
|
||||
/// implicitly join the child upon being dropped. Because the child thread
|
||||
/// may refer to data on the current thread's stack (hence the "scoped"
|
||||
/// name), it cannot be detached; it *must* be joined before the relevant
|
||||
/// stack frame is popped.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the OS fails to create a thread; use `Builder::scoped`
|
||||
/// to recover from such errors.
|
||||
#[unstable(feature = "scoped",
|
||||
reason = "memory unsafe if destructor is avoided, see #24292")]
|
||||
#[deprecated(since = "1.2.0",
|
||||
reason = "this unsafe API is unlikely to ever be stabilized \
|
||||
in this form")]
|
||||
#[allow(deprecated)]
|
||||
pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
|
||||
T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
|
||||
{
|
||||
Builder::new().scoped(f).unwrap()
|
||||
}
|
||||
|
||||
/// Gets a handle to the thread that invokes it.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn current() -> Thread {
|
||||
|
@ -769,7 +695,6 @@ mod tests {
|
|||
use result;
|
||||
use super::{Builder};
|
||||
use thread;
|
||||
use thunk::Thunk;
|
||||
use time::Duration;
|
||||
use u32;
|
||||
|
||||
|
@ -785,9 +710,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_named_thread() {
|
||||
Builder::new().name("ada lovelace".to_string()).scoped(move|| {
|
||||
Builder::new().name("ada lovelace".to_string()).spawn(move|| {
|
||||
assert!(thread::current().name().unwrap() == "ada lovelace".to_string());
|
||||
}).unwrap().join();
|
||||
}).unwrap().join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -799,13 +724,6 @@ mod tests {
|
|||
rx.recv().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_join_success() {
|
||||
assert!(thread::scoped(move|| -> String {
|
||||
"Success!".to_string()
|
||||
}).join() == "Success!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_join_panic() {
|
||||
match thread::spawn(move|| {
|
||||
|
@ -816,26 +734,6 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scoped_success() {
|
||||
let res = thread::scoped(move|| -> String {
|
||||
"Success!".to_string()
|
||||
}).join();
|
||||
assert!(res == "Success!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_scoped_panic() {
|
||||
thread::scoped(|| panic!()).join();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_scoped_implicit_panic() {
|
||||
let _ = thread::scoped(|| panic!());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_spawn_sched() {
|
||||
use clone::Clone;
|
||||
|
@ -870,7 +768,7 @@ mod tests {
|
|||
rx.recv().unwrap();
|
||||
}
|
||||
|
||||
fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
|
||||
fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Box<Fn() + Send>) {
|
||||
let (tx, rx) = channel();
|
||||
|
||||
let x: Box<_> = box 1;
|
||||
|
@ -917,7 +815,7 @@ mod tests {
|
|||
// (well, it would if the constant were 8000+ - I lowered it to be more
|
||||
// valgrind-friendly. try this at home, instead..!)
|
||||
const GENERATIONS: u32 = 16;
|
||||
fn child_no(x: u32) -> Thunk<'static> {
|
||||
fn child_no(x: u32) -> Box<Fn() + Send> {
|
||||
return Box::new(move|| {
|
||||
if x < GENERATIONS {
|
||||
thread::spawn(move|| child_no(x+1)());
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Because this module is temporary...
|
||||
#![allow(missing_docs)]
|
||||
#![unstable(feature = "thunk")]
|
||||
#![deprecated(since = "1.2.0", reason = "use FnBox instead")]
|
||||
|
||||
use alloc::boxed::{Box, FnBox};
|
||||
use core::marker::Send;
|
||||
|
||||
pub type Thunk<'a, A=(), R=()> =
|
||||
Box<FnBox<A,Output=R> + Send + 'a>;
|
||||
|
|
@ -92,14 +92,6 @@ impl Duration {
|
|||
#[stable(feature = "duration", since = "1.3.0")]
|
||||
pub fn as_secs(&self) -> u64 { self.secs }
|
||||
|
||||
#[deprecated(reason = "renamed to `as_secs`", since = "1.3.0")]
|
||||
#[unstable(feature = "duration_deprecated")]
|
||||
/// Returns the number of whole seconds represented by this duration.
|
||||
///
|
||||
/// The extra precision represented by this duration is ignored (e.g. extra
|
||||
/// nanoseconds are not represented in the returned value).
|
||||
pub fn secs(&self) -> u64 { self.as_secs() }
|
||||
|
||||
/// Returns the nanosecond precision represented by this duration.
|
||||
///
|
||||
/// This method does **not** return the length of the duration when
|
||||
|
@ -107,15 +99,6 @@ impl Duration {
|
|||
/// fractional portion of a second (e.g. it is less than one billion).
|
||||
#[stable(feature = "duration", since = "1.3.0")]
|
||||
pub fn subsec_nanos(&self) -> u32 { self.nanos }
|
||||
|
||||
#[deprecated(reason = "renamed to `subsec_nanos`", since = "1.3.0")]
|
||||
#[unstable(feature = "duration_deprecated")]
|
||||
/// Returns the nanosecond precision represented by this duration.
|
||||
///
|
||||
/// This method does **not** return the length of the duration when
|
||||
/// represented by nanoseconds. The returned number always represents a
|
||||
/// fractional portion of a second (e.g. it is less than one billion).
|
||||
pub fn extra_nanos(&self) -> u32 { self.subsec_nanos() }
|
||||
}
|
||||
|
||||
impl Add for Duration {
|
||||
|
|
|
@ -10,9 +10,6 @@
|
|||
|
||||
// Functions dealing with attributes and meta items
|
||||
|
||||
// BitSet
|
||||
#![allow(deprecated)]
|
||||
|
||||
pub use self::StabilityLevel::*;
|
||||
pub use self::ReprAttr::*;
|
||||
pub use self::IntType::*;
|
||||
|
@ -28,20 +25,33 @@ use parse::token;
|
|||
use ptr::P;
|
||||
|
||||
use std::cell::{RefCell, Cell};
|
||||
use std::collections::BitSet;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt;
|
||||
|
||||
thread_local! { static USED_ATTRS: RefCell<BitSet> = RefCell::new(BitSet::new()) }
|
||||
thread_local! {
|
||||
static USED_ATTRS: RefCell<Vec<u64>> = RefCell::new(Vec::new())
|
||||
}
|
||||
|
||||
pub fn mark_used(attr: &Attribute) {
|
||||
let AttrId(id) = attr.node.id;
|
||||
USED_ATTRS.with(|slot| slot.borrow_mut().insert(id));
|
||||
USED_ATTRS.with(|slot| {
|
||||
let idx = (id / 64) as usize;
|
||||
let shift = id % 64;
|
||||
if slot.borrow().len() <= idx {
|
||||
slot.borrow_mut().resize(idx + 1, 0);
|
||||
}
|
||||
slot.borrow_mut()[idx] |= 1 << shift;
|
||||
});
|
||||
}
|
||||
|
||||
pub fn is_used(attr: &Attribute) -> bool {
|
||||
let AttrId(id) = attr.node.id;
|
||||
USED_ATTRS.with(|slot| slot.borrow().contains(&id))
|
||||
USED_ATTRS.with(|slot| {
|
||||
let idx = (id / 64) as usize;
|
||||
let shift = id % 64;
|
||||
slot.borrow().get(idx).map(|bits| bits & (1 << shift) != 0)
|
||||
.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
pub trait AttrMetaMethods {
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![feature(associated_consts)]
|
||||
#![feature(bitset)]
|
||||
#![feature(drain)]
|
||||
#![feature(filling_drop)]
|
||||
#![feature(libc)]
|
||||
|
@ -38,6 +37,7 @@
|
|||
#![feature(str_escape)]
|
||||
#![feature(unicode)]
|
||||
#![feature(vec_push_all)]
|
||||
#![feature(vec_resize)]
|
||||
|
||||
extern crate fmt_macros;
|
||||
extern crate serialize;
|
||||
|
|
|
@ -17,7 +17,6 @@ extern crate collections;
|
|||
extern crate rand;
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::BitSet;
|
||||
use std::collections::HashSet;
|
||||
use std::hash::Hash;
|
||||
use std::env;
|
||||
|
@ -53,11 +52,6 @@ impl<T: Ord> MutableSet<T> for BTreeSet<T> {
|
|||
fn remove(&mut self, k: &T) -> bool { self.remove(k) }
|
||||
fn contains(&self, k: &T) -> bool { self.contains(k) }
|
||||
}
|
||||
impl MutableSet<usize> for BitSet {
|
||||
fn insert(&mut self, k: usize) { self.insert(k); }
|
||||
fn remove(&mut self, k: &usize) -> bool { self.remove(k) }
|
||||
fn contains(&self, k: &usize) -> bool { self.contains(k) }
|
||||
}
|
||||
|
||||
impl Results {
|
||||
pub fn bench_int<T:MutableSet<usize>,
|
||||
|
@ -218,11 +212,4 @@ fn main() {
|
|||
});
|
||||
write_results("collections::BTreeSet", &results);
|
||||
}
|
||||
|
||||
{
|
||||
let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
|
||||
let mut results = empty_results();
|
||||
results.bench_int(&mut rng, num_keys, max, || BitSet::new());
|
||||
write_results("collections::bit_vec::BitSet", &results);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
|
||||
// no-pretty-expanded FIXME #15189
|
||||
|
||||
#![feature(duration, duration_span, future)]
|
||||
#![feature(duration_span)]
|
||||
|
||||
use std::env;
|
||||
use std::sync::{Arc, Future, Mutex, Condvar};
|
||||
use std::sync::{Arc, Mutex, Condvar};
|
||||
use std::time::Duration;
|
||||
use std::thread;
|
||||
|
||||
// A poor man's pipe.
|
||||
type pipe = Arc<(Mutex<Vec<usize>>, Condvar)>;
|
||||
|
@ -89,7 +90,7 @@ fn main() {
|
|||
//println!("spawning %?", i);
|
||||
let (new_chan, num_port) = init();
|
||||
let num_chan_2 = num_chan.clone();
|
||||
let new_future = Future::spawn(move|| {
|
||||
let new_future = thread::spawn(move|| {
|
||||
thread_ring(i, msg_per_task, num_chan_2, num_port)
|
||||
});
|
||||
futures.push(new_future);
|
||||
|
@ -100,8 +101,8 @@ fn main() {
|
|||
thread_ring(0, msg_per_task, num_chan, num_port);
|
||||
|
||||
// synchronize
|
||||
for f in &mut futures {
|
||||
f.get()
|
||||
for f in futures {
|
||||
f.join().unwrap()
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -40,9 +40,7 @@
|
|||
|
||||
// ignore-android: FIXME(#10393) hangs without output
|
||||
|
||||
#![feature(box_syntax, owned_ascii_ext, vec_push_all)]
|
||||
|
||||
use std::ascii::OwnedAsciiExt;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
|
@ -146,11 +144,11 @@ impl Table {
|
|||
fn search_remainder<C:TableCallback>(item: &mut Entry, key: Code, c: C) {
|
||||
match item.next {
|
||||
None => {
|
||||
let mut entry: Box<_> = box Entry {
|
||||
let mut entry = Box::new(Entry {
|
||||
code: key,
|
||||
count: 0,
|
||||
next: None,
|
||||
};
|
||||
});
|
||||
c.f(&mut *entry);
|
||||
item.next = Some(entry);
|
||||
}
|
||||
|
@ -170,11 +168,11 @@ impl Table {
|
|||
|
||||
{
|
||||
if self.items[index as usize].is_none() {
|
||||
let mut entry: Box<_> = box Entry {
|
||||
let mut entry = Box::new(Entry {
|
||||
code: key,
|
||||
count: 0,
|
||||
next: None,
|
||||
};
|
||||
});
|
||||
c.f(&mut *entry);
|
||||
self.items[index as usize] = Some(entry);
|
||||
return;
|
||||
|
@ -285,13 +283,16 @@ fn print_occurrences(frequencies: &mut Table, occurrence: &'static str) {
|
|||
}
|
||||
|
||||
fn get_sequence<R: BufRead>(r: &mut R, key: &str) -> Vec<u8> {
|
||||
let mut res = Vec::new();
|
||||
let mut res = Vec::<u8>::new();
|
||||
for l in r.lines().map(|l| l.unwrap())
|
||||
.skip_while(|l| key != &l[..key.len()]).skip(1)
|
||||
{
|
||||
res.push_all(l.trim().as_bytes());
|
||||
res.extend(l.trim().as_bytes());
|
||||
}
|
||||
res.into_ascii_uppercase()
|
||||
for s in &mut res {
|
||||
*s = s.to_ascii_uppercase();
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
// ignore-android: FIXME(#10393) hangs without output
|
||||
|
||||
#![feature(libc, scoped)]
|
||||
#![feature(libc)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
|
@ -195,11 +195,12 @@ fn reverse_complement(seq: &mut [u8], tables: &Tables) {
|
|||
|
||||
/// Executes a closure in parallel over the given iterator over mutable slice.
|
||||
/// The closure `f` is run in parallel with an element of `iter`.
|
||||
// FIXME: replace with thread::scoped when it exists again
|
||||
fn parallel<I: Iterator, F>(iter: I, ref f: F)
|
||||
where I::Item: Send,
|
||||
F: Fn(I::Item) + Sync, {
|
||||
iter.map(|x| {
|
||||
thread::scoped(move || f(x))
|
||||
f(x)
|
||||
}).collect::<Vec<_>>();
|
||||
}
|
||||
|
||||
|
|
|
@ -114,11 +114,10 @@ fn parallel<'a,T, F>(v: &mut [T], ref f: F)
|
|||
where T: Send + Sync + 'a,
|
||||
F: Fn(usize, &mut [T]) + Sync + 'a {
|
||||
// FIXME: pick a more appropriate parallel factor
|
||||
// FIXME: replace with thread::scoped when it exists again
|
||||
let parallelism = 4;
|
||||
let size = v.len() / parallelism + 1;
|
||||
v.chunks_mut(size).enumerate().map(|(i, chunk)| {
|
||||
thread::scoped(move|| {
|
||||
f(i * size, chunk)
|
||||
})
|
||||
f(i * size, chunk)
|
||||
}).collect::<Vec<_>>();
|
||||
}
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
// Microbenchmark for the smallintmap library
|
||||
|
||||
#![feature(vecmap, duration, duration_span)]
|
||||
|
||||
use std::collections::VecMap;
|
||||
use std::env;
|
||||
use std::time::Duration;
|
||||
|
||||
fn append_sequential(min: usize, max: usize, map: &mut VecMap<usize>) {
|
||||
for i in min..max {
|
||||
map.insert(i, i + 22);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_sequential(min: usize, max: usize, map: &VecMap<usize>) {
|
||||
for i in min..max {
|
||||
assert_eq!(map[i], i + 22);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = env::args();
|
||||
let args = if env::var_os("RUST_BENCH").is_some() {
|
||||
vec!("".to_string(), "100000".to_string(), "100".to_string())
|
||||
} else if args.len() <= 1 {
|
||||
vec!("".to_string(), "10000".to_string(), "50".to_string())
|
||||
} else {
|
||||
args.collect()
|
||||
};
|
||||
let max = args[1].parse::<usize>().unwrap();
|
||||
let rep = args[2].parse::<usize>().unwrap();
|
||||
|
||||
let mut checkf = Duration::new(0, 0);
|
||||
let mut appendf = Duration::new(0, 0);
|
||||
|
||||
for _ in 0..rep {
|
||||
let mut map = VecMap::new();
|
||||
let d1 = Duration::span(|| append_sequential(0, max, &mut map));
|
||||
let d2 = Duration::span(|| check_sequential(0, max, &map));
|
||||
|
||||
checkf = checkf + d2;
|
||||
appendf = appendf + d1;
|
||||
}
|
||||
|
||||
let maxf = max as f64;
|
||||
|
||||
println!("insert(): {:?} seconds\n", checkf);
|
||||
println!(" : {} op/s\n", maxf / checkf.as_secs() as f64);
|
||||
println!("get() : {:?} seconds\n", appendf);
|
||||
println!(" : {} op/s\n", maxf / appendf.as_secs() as f64);
|
||||
}
|
|
@ -10,14 +10,11 @@
|
|||
|
||||
// Ensure that moves out of static items is forbidden
|
||||
|
||||
use std::marker;
|
||||
|
||||
struct Foo {
|
||||
foo: isize,
|
||||
nocopy: marker::NoCopy
|
||||
}
|
||||
|
||||
static BAR: Foo = Foo{foo: 5, nocopy: marker::NoCopy};
|
||||
static BAR: Foo = Foo { foo: 5 };
|
||||
|
||||
|
||||
fn test(f: Foo) {
|
||||
|
|
|
@ -11,11 +11,8 @@
|
|||
// Issue 4691: Ensure that functional-struct-update can only copy, not
|
||||
// move, when the struct implements Drop.
|
||||
|
||||
// NoCopy
|
||||
use std::marker::NoCopy as NP;
|
||||
|
||||
|
||||
struct S { a: isize, np: NP }
|
||||
struct B;
|
||||
struct S { a: isize, b: B }
|
||||
impl Drop for S { fn drop(&mut self) { } }
|
||||
|
||||
struct T { a: isize, mv: Box<isize> }
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright 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 std::sync::Future;
|
||||
|
||||
fn main() {
|
||||
let f = Future::from_value(());
|
||||
let g = f;
|
||||
f.into_inner(); //~ ERROR use of moved value
|
||||
}
|
|
@ -10,17 +10,11 @@
|
|||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(std_misc, libc)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
use std::thunk::Thunk;
|
||||
|
||||
fn foo(_: Thunk) {}
|
||||
fn foo(_: Box<FnMut()>) {}
|
||||
|
||||
fn main() {
|
||||
foo(loop {
|
||||
unsafe { libc::exit(0 as libc::c_int); }
|
||||
std::process::exit(0);
|
||||
});
|
||||
2_usize + (loop {});
|
||||
//~^ ERROR E0277
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue