According to #7887, we've decided to use the syntax of `fn map<U>(f: &fn(&T) -> U) -> U`, which passes a reference to the closure, and to `fn map_move<U>(f: &fn(T) -> U) -> U` which moves the value into the closure. This PR adds these `.map_move()` functions to `Option` and `Result`.
In addition, it has these other minor features:
* Replaces a couple uses of `option.get()`, `result.get()`, and `result.get_err()` with `option.unwrap()`, `result.unwrap()`, and `result.unwrap_err()`. (See #8268 and #8288 for a more thorough adaptation of this functionality.
* Removes `option.take_map()` and `option.take_map_default()`. These two functions can be easily written as `.take().map_move(...)`.
* Adds a better error message to `result.unwrap()` and `result.unwrap_err()`.
~~~
# use std::task;
# fn sleep_forever() { loop { task::yield() } }
-# fn wait_for_a_while() { do 1000.times { task::yield() } }
+# fn wait_for_a_while() { for _ in range(0, 1000u) { task::yield() } }
# do task::try::<int> {
do task::spawn_supervised {
do task::spawn_supervised {
~~~
# use std::task;
# fn random() -> uint { 100 }
-# fn sleep_for(i: uint) { do i.times { task::yield() } }
+# fn sleep_for(i: uint) { for _ in range(0, i) { task::yield() } }
# do task::try::<()> {
let (time1, time2) = (random(), random());
do task::spawn_unlinked {
impl Drop for TimeBomb {
fn drop(&self) {
- do self.explosivity.times {
+ for _ in range(0, self.explosivity) {
println("blam!");
}
}
+++ /dev/null
-// 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.
-
-/*! Composable internal iterators
-
-Internal iterators are functions implementing the protocol used by the `for` loop.
-
-An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal
-breaking out of iteration. The adaptors in the module work with any such iterator, not just ones
-tied to specific traits. For example:
-
-~~~ {.rust}
-println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
-~~~
-
-An external iterator object implementing the interface in the `iterator` module can be used as an
-internal iterator by calling the `advance` method. For example:
-
-~~~ {.rust}
-let xs = [0u, 1, 2, 3, 4, 5];
-let ys = [30, 40, 50, 60];
-let mut it = xs.iter().chain(ys.iter());
-for &x: &uint in it {
- println(x.to_str());
-}
-~~~
-
-Internal iterators provide a subset of the functionality of an external iterator. It's not possible
-to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often
-much easier to implement.
-
-*/
-
-use std::vec;
-use std::cmp::Ord;
-use std::option::{Option, Some, None};
-use std::num::{One, Zero};
-use std::ops::{Add, Mul};
-
-#[allow(missing_doc)]
-pub trait FromIter<T> {
- /// Build a container with elements from an internal iterator.
- ///
- /// # Example:
- ///
- /// ~~~ {.rust}
- /// let xs = ~[1, 2, 3];
- /// let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) };
- /// assert_eq!(xs, ys);
- /// ~~~
- pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self;
-}
-
-/**
- * Return true if `predicate` is true for any values yielded by an internal iterator.
- *
- * Example:
- *
- * ~~~ {.rust}
- * let xs = ~[1u, 2, 3, 4, 5];
- * assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f)));
- * assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f)));
- * ~~~
- */
-#[inline]
-pub fn any<T>(predicate: &fn(T) -> bool,
- iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
- do iter |x| {
- predicate(x)
- }
-}
-
-/**
- * Return true if `predicate` is true for all values yielded by an internal iterator.
- *
- * # Example:
- *
- * ~~~ {.rust}
- * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
- * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
- * ~~~
- */
-#[inline]
-pub fn all<T>(predicate: &fn(T) -> bool,
- iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
- // If we ever break, iter will return false, so this will only return true
- // if predicate returns true for everything.
- iter(|x| predicate(x))
-}
-
-/**
- * Return the first element where `predicate` returns `true`. Return `None` if no element is found.
- *
- * # Example:
- *
- * ~~~ {.rust}
- * let xs = ~[1u, 2, 3, 4, 5, 6];
- * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4);
- * ~~~
- */
-#[inline]
-pub fn find<T>(predicate: &fn(&T) -> bool,
- iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
- let mut ret = None;
- do iter |x| {
- if predicate(&x) {
- ret = Some(x);
- false
- } else { true }
- };
- ret
-}
-
-/**
- * Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
- *
- * # Example:
- *
- * ~~~ {.rust}
- * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
- * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15);
- * ~~~
- */
-#[inline]
-pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
- let mut result = None;
- do iter |x| {
- match result {
- Some(ref mut y) => {
- if x > *y {
- *y = x;
- }
- }
- None => result = Some(x)
- }
- true
- };
- result
-}
-
-/**
- * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
- *
- * # Example:
- *
- * ~~~ {.rust}
- * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
- * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5);
- * ~~~
- */
-#[inline]
-pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
- let mut result = None;
- do iter |x| {
- match result {
- Some(ref mut y) => {
- if x < *y {
- *y = x;
- }
- }
- None => result = Some(x)
- }
- true
- };
- result
-}
-
-/**
- * Reduce an iterator to an accumulated value.
- *
- * # Example:
- *
- * ~~~ {.rust}
- * assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
- * ~~~
- */
-#[inline]
-pub fn fold<T, U>(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T {
- let mut result = start;
- do iter |x| {
- f(&mut result, x);
- true
- };
- result
-}
-
-/**
- * Reduce an iterator to an accumulated value.
- *
- * `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it
- * forces the iterator to yield borrowed pointers.
- *
- * # Example:
- *
- * ~~~ {.rust}
- * fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
- * fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
- * }
- * ~~~
- */
-#[inline]
-pub fn fold_ref<T, U>(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T {
- let mut result = start;
- do iter |x| {
- f(&mut result, x);
- true
- };
- result
-}
-
-/**
- * Return the sum of the items yielding by an iterator.
- *
- * # Example:
- *
- * ~~~ {.rust}
- * let xs: ~[int] = ~[1, 2, 3, 4];
- * assert_eq!(do sum |f| { xs.iter().advance(f) }, 10);
- * ~~~
- */
-#[inline]
-pub fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
- fold_ref(Zero::zero::<T>(), iter, |a, x| *a = a.add(x))
-}
-
-/**
- * Return the product of the items yielded by an iterator.
- *
- * # Example:
- *
- * ~~~ {.rust}
- * let xs: ~[int] = ~[1, 2, 3, 4];
- * assert_eq!(do product |f| { xs.iter().advance(f) }, 24);
- * ~~~
- */
-#[inline]
-pub fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
- fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
-}
-
-impl<T> FromIter<T> for ~[T]{
- #[inline]
- pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
- let mut v = ~[];
- do iter |x| { v.push(x); true };
- v
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use prelude::*;
-
- use int;
- use uint;
-
- #[test]
- fn test_from_iter() {
- let xs = ~[1, 2, 3];
- let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) };
- assert_eq!(xs, ys);
- }
-
- #[test]
- fn test_any() {
- let xs = ~[1u, 2, 3, 4, 5];
- assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f)));
- assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f)));
- }
-
- #[test]
- fn test_all() {
- assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f)));
- assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f)));
- }
-
- #[test]
- fn test_find() {
- let xs = ~[1u, 2, 3, 4, 5, 6];
- assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4);
- }
-
- #[test]
- fn test_max() {
- let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
- assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15);
- }
-
- #[test]
- fn test_min() {
- let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
- assert_eq!(min(|f| xs.iter().advance(f)).unwrap(), &-5);
- }
-
- #[test]
- fn test_fold() {
- assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
- }
-
- #[test]
- fn test_sum() {
- let xs: ~[int] = ~[1, 2, 3, 4];
- assert_eq!(do sum |f| { xs.iter().advance(f) }, 10);
- }
-
- #[test]
- fn test_empty_sum() {
- let xs: ~[int] = ~[];
- assert_eq!(do sum |f| { xs.iter().advance(f) }, 0);
- }
-
- #[test]
- fn test_product() {
- let xs: ~[int] = ~[1, 2, 3, 4];
- assert_eq!(do product |f| { xs.iter().advance(f) }, 24);
- }
-
- #[test]
- fn test_empty_product() {
- let xs: ~[int] = ~[];
- assert_eq!(do product |f| { xs.iter().advance(f) }, 1);
- }
-}
let u: ~[int] = deq.iter().transform(|&x| x).collect();
assert_eq!(u, v);
- let mut seq = iterator::Counter::new(0u, 2).take_(256);
+ let mut seq = iterator::count(0u, 2).take_(256);
let deq: RingBuf<uint> = seq.collect();
for (i, &x) in deq.iter().enumerate() {
assert_eq!(2*i, x);
let offset = get_param(decl, first_real_arg + 1);
Ret(bcx, GEP(bcx, ptr, [offset]));
}
+ "offset_inbounds" => {
+ let ptr = get_param(decl, first_real_arg);
+ let offset = get_param(decl, first_real_arg + 1);
+ Ret(bcx, InBoundsGEP(bcx, ptr, [offset]));
+ }
"memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32),
"memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64),
"memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32),
"visit_tydesc" | "forget" | "frame_address" |
"morestack_addr" => 0,
- "offset" | "memcpy32" | "memcpy64" | "memmove32" | "memmove64" |
+ "offset" | "offset_inbounds" |
+ "memcpy32" | "memcpy64" | "memmove32" | "memmove64" |
"memset32" | "memset64" => use_repr,
"sqrtf32" | "sqrtf64" | "powif32" | "powif64" |
mutbl: ast::m_imm
}))
}
+ "offset_inbounds" => {
+ (1,
+ ~[
+ ty::mk_ptr(tcx, ty::mt {
+ ty: param(ccx, 0),
+ mutbl: ast::m_imm
+ }),
+ ty::mk_int()
+ ],
+ ty::mk_ptr(tcx, ty::mt {
+ ty: param(ccx, 0),
+ mutbl: ast::m_imm
+ }))
+ }
"memcpy32" => {
(1,
~[
let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc);
write_markdown(doc, writer_factory);
// We expect two pages to have been written
- do 2.times {
+ for _ in range(0, 2u) {
po.recv();
}
}
~"#[link(name = \"core\")]; mod a { }");
let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc);
write_markdown(doc, writer_factory);
- do 2.times {
+ for _ in range(0, 2u) {
let (page, markdown) = po.recv();
match page {
doc::CratePage(_) => {
}
}
- #[cfg(not(target_word_size = "32"))]
+ // FIXME: #7220 rusti on 32bit mac doesn't work.
+ // FIXME: #7641 rusti on 32bit linux cross compile doesn't work
+ // FIXME: #7115 re-enable once LLVM has been upgraded
+ #[cfg(thiswillneverbeacfgflag)]
fn run_program(prog: &str) {
let mut r = repl();
for cmd in prog.split_iter('\n') {
"the command '%s' failed", cmd);
}
}
- // FIXME: #7220 rusti on 32bit mac doesn't work
- // FIXME: #7641 rusti on 32bit linux cross compile doesn't work
- #[cfg(target_word_size = "32")]
fn run_program(_: &str) {}
#[test]
run_program("let a = 3;");
}
- #[test]
+ #[test] #[ignore]
fn new_tasks() {
+ // XXX: can't spawn new tasks because the JIT code is cleaned up
+ // after the main function is done.
run_program("
- use std::task::try;
- try( || println(\"Please don't segfault\") );
- do try { println(\"Please?\"); }
+ spawn( || println(\"Please don't segfault\") );
+ do spawn { println(\"Please?\"); }
");
}
/// ~~~ {.rust}
/// let xs = [2u, 3];
/// let ys = [0u, 1, 0, 1, 2];
- /// let mut it = xs.iter().flat_map_(|&x| Counter::new(0u, 1).take_(x));
+ /// let mut it = xs.iter().flat_map_(|&x| count(0u, 1).take_(x));
/// // Check that `it` has the same elements as `ys`
/// let mut i = 0;
/// for x: uint in it {
/// ~~~ {.rust}
/// use std::iterator::Counter;
///
- /// for i in Counter::new(0, 10) {
+ /// for i in count(0, 10) {
/// printfln!("%d", i);
/// }
/// ~~~
/// use std::iterator::Counter;
///
/// fn factorial(n: uint) -> uint {
- /// Counter::new(1u, 1).take_while(|&i| i <= n).product()
+ /// count(1u, 1).take_while(|&i| i <= n).product()
/// }
/// assert!(factorial(0) == 1);
/// assert!(factorial(1) == 1);
/// # Example
///
/// ~~~ {.rust}
- /// let a = Counter::new(1,1).take_(1);
+ /// let a = count(1,1).take_(1);
/// let mut cy = a.cycle();
/// assert_eq!(cy.next(), Some(1));
/// assert_eq!(cy.next(), Some(1));
impl<A, T: Iterator<A>> Iterator<A> for Take<T> {
#[inline]
fn next(&mut self) -> Option<A> {
- let next = self.iter.next();
if self.n != 0 {
self.n -= 1;
- next
+ self.iter.next()
} else {
None
}
step: A
}
-impl<A> Counter<A> {
- /// Creates a new counter with the specified start/step
- #[inline]
- pub fn new(start: A, step: A) -> Counter<A> {
- Counter{state: start, step: step}
- }
+/// Creates a new counter with the specified start/step
+#[inline]
+pub fn count<A>(start: A, step: A) -> Counter<A> {
+ Counter{state: start, step: step}
}
/// A range of numbers from [0, N)
#[test]
fn test_counter_from_iter() {
- let mut it = Counter::new(0, 5).take_(10);
+ let mut it = count(0, 5).take_(10);
let xs: ~[int] = FromIterator::from_iterator(&mut it);
assert_eq!(xs, ~[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
}
}
assert_eq!(i, expected.len());
- let ys = Counter::new(30u, 10).take_(4);
+ let ys = count(30u, 10).take_(4);
let mut it = xs.iter().transform(|&x| x).chain_(ys);
let mut i = 0;
for x in it {
#[test]
fn test_filter_map() {
- let mut it = Counter::new(0u, 1u).take_(10)
+ let mut it = count(0u, 1u).take_(10)
.filter_map(|x| if x.is_even() { Some(x*x) } else { None });
assert_eq!(it.collect::<~[uint]>(), ~[0*0, 2*2, 4*4, 6*6, 8*8]);
}
fn test_iterator_flat_map() {
let xs = [0u, 3, 6];
let ys = [0u, 1, 2, 3, 4, 5, 6, 7, 8];
- let mut it = xs.iter().flat_map_(|&x| Counter::new(x, 1).take_(3));
+ let mut it = xs.iter().flat_map_(|&x| count(x, 1).take_(3));
let mut i = 0;
for x in it {
assert_eq!(x, ys[i]);
#[test]
fn test_cycle() {
let cycle_len = 3;
- let it = Counter::new(0u, 1).take_(cycle_len).cycle();
+ let it = count(0u, 1).take_(cycle_len).cycle();
assert_eq!(it.size_hint(), (uint::max_value, None));
for (i, x) in it.take_(100).enumerate() {
assert_eq!(i % cycle_len, x);
}
- let mut it = Counter::new(0u, 1).take_(0).cycle();
+ let mut it = count(0u, 1).take_(0).cycle();
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next(), None);
}
#[test]
fn test_iterator_size_hint() {
- let c = Counter::new(0, 1);
+ let c = count(0, 1);
let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let v2 = &[10, 11, 12];
let vi = v.iter();
pub use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
pub use hash::Hash;
pub use iter::Times;
+pub use iterator::Extendable;
pub use iterator::{Iterator, IteratorUtil, DoubleEndedIterator, DoubleEndedIteratorUtil};
pub use iterator::{ClonableIterator, OrdIterator};
pub use num::{Num, NumCast};
pub use ptr::RawPtr;
pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr, ToBytesConsume};
pub use str::{Str, StrVector, StrSlice, OwnedStr, NullTerminatedStr};
-pub use from_str::{FromStr};
+pub use from_str::FromStr;
pub use to_bytes::IterBytes;
pub use to_str::{ToStr, ToStrConsume};
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
fn is_not_null(&self) -> bool;
unsafe fn to_option(&self) -> Option<&T>;
fn offset(&self, count: int) -> Self;
+ unsafe fn offset_inbounds(self, count: int) -> Self;
}
/// Extension methods for immutable pointers
/// Calculates the offset from a pointer.
#[inline]
fn offset(&self, count: int) -> *T { offset(*self, count) }
+
+ /// Calculates the offset from a pointer. The offset *must* be in-bounds of
+ /// the object, or one-byte-past-the-end.
+ #[inline]
+ #[cfg(stage0)]
+ unsafe fn offset_inbounds(self, count: int) -> *T {
+ intrinsics::offset(self, count)
+ }
+
+ /// Calculates the offset from a pointer. The offset *must* be in-bounds of
+ /// the object, or one-byte-past-the-end.
+ #[inline]
+ #[cfg(not(stage0))]
+ unsafe fn offset_inbounds(self, count: int) -> *T {
+ intrinsics::offset_inbounds(self, count)
+ }
}
/// Extension methods for mutable pointers
/// Calculates the offset from a mutable pointer.
#[inline]
fn offset(&self, count: int) -> *mut T { mut_offset(*self, count) }
+
+ /// Calculates the offset from a pointer. The offset *must* be in-bounds of
+ /// the object, or one-byte-past-the-end. An arithmetic overflow is also
+ /// undefined behaviour.
+ ///
+ /// This method should be preferred over `offset` when the guarantee can be
+ /// satisfied, to enable better optimization.
+ #[inline]
+ #[cfg(stage0)]
+ unsafe fn offset_inbounds(self, count: int) -> *mut T {
+ intrinsics::offset(self as *T, count) as *mut T
+ }
+
+ /// Calculates the offset from a pointer. The offset *must* be in-bounds of
+ /// the object, or one-byte-past-the-end. An arithmetic overflow is also
+ /// undefined behaviour.
+ ///
+ /// This method should be preferred over `offset` when the guarantee can be
+ /// satisfied, to enable better optimization.
+ #[inline]
+ #[cfg(not(stage0))]
+ unsafe fn offset_inbounds(self, count: int) -> *mut T {
+ intrinsics::offset_inbounds(self as *T, count) as *mut T
+ }
}
// Equality for pointers
fn test_add() {
#[allow(unnecessary_allocation)];
macro_rules! t (
- ($s1:expr, $s2:expr, $e:expr) => {
- assert_eq!($s1 + $s2, $e);
- assert_eq!($s1.to_owned() + $s2, $e);
- assert_eq!($s1.to_managed() + $s2, $e);
- }
+ ($s1:expr, $s2:expr, $e:expr) => { {
+ let s1 = $s1;
+ let s2 = $s2;
+ let e = $e;
+ assert_eq!(s1 + s2, e.to_owned());
+ assert_eq!(s1.to_owned() + s2, e.to_owned());
+ assert_eq!(s1.to_managed() + s2, e.to_owned());
+ } }
);
- t!("foo", "bar", ~"foobar");
- t!("foo", @"bar", ~"foobar");
- t!("foo", ~"bar", ~"foobar");
- t!("ศไทย中", "华Việt Nam", ~"ศไทย中华Việt Nam");
- t!("ศไทย中", @"华Việt Nam", ~"ศไทย中华Việt Nam");
- t!("ศไทย中", ~"华Việt Nam", ~"ศไทย中华Việt Nam");
+ t!("foo", "bar", "foobar");
+ t!("foo", @"bar", "foobar");
+ t!("foo", ~"bar", "foobar");
+ t!("ศไทย中", "华Việt Nam", "ศไทย中华Việt Nam");
+ t!("ศไทย中", @"华Việt Nam", "ศไทย中华Việt Nam");
+ t!("ศไทย中", ~"华Việt Nam", "ศไทย中华Việt Nam");
}
#[test]
/// Get the address of the `__morestack` stack growth function.
pub fn morestack_addr() -> *();
- /// Adjust a pointer by an offset.
+ /// Calculates the offset from a pointer.
///
/// This is implemented as an intrinsic to avoid converting to and from an
/// integer, since the conversion would throw away aliasing information.
pub fn offset<T>(dst: *T, offset: int) -> *T;
+ /// Calculates the offset from a pointer. The offset *must* be in-bounds of
+ /// the object, or one-byte-past-the-end. An arithmetic overflow is also
+ /// undefined behaviour.
+ ///
+ /// This intrinsic should be preferred over `offset` when the guarantee can
+ /// be satisfied, to enable better optimization.
+ #[cfg(not(stage0))]
+ pub fn offset_inbounds<T>(dst: *T, offset: int) -> *T;
+
/// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32);
fn iter(self) -> VecIterator<'self, T> {
unsafe {
let p = vec::raw::to_ptr(self);
- VecIterator{ptr: p,
- end: (p as uint + self.len() *
- sys::nonzero_size_of::<T>()) as *T,
- lifetime: cast::transmute(p)}
+ if sys::size_of::<T>() == 0 {
+ VecIterator{ptr: p,
+ end: (p as uint + self.len()) as *T,
+ lifetime: cast::transmute(p)}
+ } else {
+ VecIterator{ptr: p,
+ end: p.offset_inbounds(self.len() as int),
+ lifetime: cast::transmute(p)}
+ }
}
}
fn mut_iter(self) -> VecMutIterator<'self, T> {
unsafe {
let p = vec::raw::to_mut_ptr(self);
- VecMutIterator{ptr: p,
- end: (p as uint + self.len() *
- sys::nonzero_size_of::<T>()) as *mut T,
- lifetime: cast::transmute(p)}
+ if sys::size_of::<T>() == 0 {
+ VecMutIterator{ptr: p,
+ end: (p as uint + self.len()) as *mut T,
+ lifetime: cast::transmute(p)}
+ } else {
+ VecMutIterator{ptr: p,
+ end: p.offset_inbounds(self.len() as int),
+ lifetime: cast::transmute(p)}
+ }
}
}
// same pointer.
cast::transmute(self.ptr as uint + 1)
} else {
- self.ptr.offset(1)
+ self.ptr.offset_inbounds(1)
};
Some(cast::transmute(old))
// See above for why 'ptr.offset' isn't used
cast::transmute(self.end as uint - 1)
} else {
- self.end.offset(-1)
+ self.end.offset_inbounds(-1)
};
Some(cast::transmute(self.end))
}
{
let mut set = f();
do timed(&mut self.random_ints) {
- do num_keys.times {
+ for _ in range(0, num_keys) {
set.insert((rng.next() as uint) % rand_cap);
}
}
{
let mut set = f();
do timed(&mut self.random_strings) {
- do num_keys.times {
+ for _ in range(0, num_keys) {
let s = uint::to_str(rng.next() as uint);
set.insert(s);
}
let symbols = [" ", "░", "▒", "▓", "█", "█"];
let mut pixels = [0f32, ..256*256];
let n2d = ~Noise2DContext::new();
- do 100.times {
+ for _ in range(0, 100u) {
for y in range(0, 256) {
for x in range(0, 256) {
let v = n2d.get(
let mut creatures_met = 0;
// set up meetings...
- do nn.times {
+ for _ in range(0, nn) {
let fst_creature: CreatureInfo = from_creatures.recv();
let snd_creature: CreatureInfo = from_creatures.recv();
let chars_left = n % LINE_LEN;
let mut buf = [0, ..LINE_LEN + 1];
- do lines.times {
+ for _ in range(0, lines) {
for i in range(0u, LINE_LEN) {
buf[i] = self.nextc();
}
fn unpack(&self, frame: i32) -> ~str {
let mut key = **self;
let mut result = ~[];
- do (frame as uint).times {
+ for _ in range(0, frame) {
result.push(unpack_symbol((key as u8) & 3));
key >>= 2;
}
let mut code = Code(0);
// Pull first frame.
- do (frame as uint).times {
+ for _ in range(0, frame) {
code = code.push_char(input[0]);
input = next_char(input);
}
fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: i32) {
let mut d = [ 0.0, ..3 ];
- do (steps as uint).times {
+ for _ in range(0, steps) {
for i in range(0u, N_BODIES) {
for j in range(i + 1, N_BODIES) {
d[0] = bodies[i].x[0] - bodies[j].x[0];
let mut u = vec::from_elem(n, 1f64);
let mut v = u.clone();
let mut tmp = u.clone();
- do 8.times {
+ for _ in range(0, 8u) {
mult_AtAv(u, v, tmp);
mult_AtAv(v, u, tmp);
}
}
fn run(repeat: int, depth: int) {
- do (repeat as uint).times {
+ for _ in range(0, repeat) {
info!("starting %.4f", precise_time_s());
do task::try {
recurse_or_fail(depth, None)
let (po, ch) = stream();
let ch = SharedChan::new(ch);
- do num_tasks.times {
+ for _ in range(0, num_tasks) {
let ch = ch.clone();
do task::spawn { // linked
ch.send(());
}
}
error!("Grandchild group getting started");
- do num_tasks.times {
+ for _ in range(0, num_tasks) {
// Make sure all above children are fully spawned; i.e., enlisted in
// their ancestor groups.
po.recv();
+++ /dev/null
-// 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.
-
-// xfail-test FIXME #7307
-// xfail-fast
-
-extern mod extra;
-use extra::oldmap::*;
-
-class cat : map<int, bool> {
- priv {
- // Yes, you can have negative meows
- let mut meows : int;
- fn meow() {
- self.meows += 1;
- error!("Meow %d", self.meows);
- if self.meows % 5 == 0 {
- self.how_hungry += 1;
- }
- }
- }
-
- let mut how_hungry : int;
- let name : str;
-
- new(in_x : int, in_y : int, in_name: str)
- { self.meows = in_x; self.how_hungry = in_y; self.name = in_name; }
-
- fn speak() { self.meow(); }
-
- fn eat() -> bool {
- if self.how_hungry > 0 {
- error!("OM NOM NOM");
- self.how_hungry -= 2;
- return true;
- }
- else {
- error!("Not hungry!");
- return false;
- }
- }
-
- fn size() -> uint { self.meows as uint }
- fn insert(+k: int, +v: bool) -> bool {
- if v { self.meows += k; } else { self.meows -= k; };
- true
- }
- fn contains_key(&&k: int) -> bool { k <= self.meows }
- fn get(&&k:int) -> bool { k <= self.meows }
- fn [](&&k:int) -> bool { k <= self.meows }
- fn find(&&k:int) -> Option<bool> { Some(self.get(k)) }
- fn remove(&&k:int) -> Option<bool> { self.meows -= k; Some(true) }
- fn each(f: &fn(&&int, &&bool) -> bool) {
- let mut n = num::abs(self.meows);
- while n > 0 {
- if !f(n, true) { break; }
- n -= 1;
- }
- }
- fn each_key(&&f: &fn(&&int) -> bool) {
- for self.each |k, _v| { if !f(k) { break; } again;};
- }
- fn each_value(&&f: &fn(&&bool) -> bool) {
- for self.each |_k, v| { if !f(v) { break; } again;};
- }
- fn clear() { }
-}
-
-pub fn main() {
- let nyan : cat = cat(0, 2, "nyan");
- for _ in range(1u, 5u) { nyan.speak(); }
- // cat returns true if uint input is greater than
- // the number of meows so far
- assert!((nyan.get(1)));
- assert!((!nyan.get(10)));
-}
+++ /dev/null
-// 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.
-
-// xfail-test FIXME #7305
-
-extern mod extra;
-use extra::oldmap::*;
-use vec::*;
-use dvec::{dvec, extensions};
-
-enum furniture { chair, couch, bed }
-enum body_part { finger, toe, nose, ear }
-
-trait noisy {
- fn speak() -> int;
-}
-
-trait scratchy {
- fn scratch() -> Option<furniture>;
-}
-
-trait bitey {
- fn bite() -> body_part;
-}
-
-fn vec_includes<T>(xs: ~[T], x: T) -> bool {
- for each(xs) |y| { if y == x { return true; }}
- return false;
-}
-
-// vtables other than the 1st one don't seem to work
-class cat : noisy, scratchy, bitey {
- priv {
- let meows : @mut uint;
- let scratched : dvec<furniture>;
- let bite_counts : hashmap<body_part, uint>;
-
- fn meow() -> uint {
- info!("Meow: %u", *self.meows);
- *self.meows += 1u;
- if *self.meows % 5u == 0u {
- *self.how_hungry += 1;
- }
- *self.meows
- }
- }
-
- let how_hungry : @mut int;
- let name : str;
-
- new(in_x : uint, in_y : int, in_name: str)
- { self.meows = @mut in_x; self.how_hungry = @mut in_y;
- self.name = in_name; self.scratched = dvec();
- let hsher: hashfn<body_part> = |p| int::hash(p as int);
- let eqer : eqfn<body_part> = |p, q| p == q;
- let t : hashmap<body_part, uint> =
- hashmap::<body_part, uint>(hsher, eqer);
- self.bite_counts = t;
- do iter(~[finger, toe, nose, ear]) |p| {
- self.bite_counts.insert(p, 0u);
- };
- }
-
- fn speak() -> int { self.meow() as int }
- fn meow_count() -> uint { *self.meows }
- fn scratch() -> Option<furniture> {
- let all = ~[chair, couch, bed];
- log(error, self.scratched);
- let mut rslt = None;
- for each(all) |thing| { if !self.scratched.contains(thing) {
- self.scratched.push(thing);
- return Some(thing); }}
- rslt
- }
- fn bite() -> body_part {
- error!("In bite()");
- let all = ~[toe, nose, ear];
- let mut min = finger;
- do iter(all) |next| {
- info!("min = %?", min);
- if self.bite_counts.get(next) < self.bite_counts.get(min) {
- min = next;
- }};
- self.bite_counts.insert(min, self.bite_counts.get(min) + 1u);
- info!("Bit %?", min);
- min
- }
-}
-
-fn annoy_neighbors<T:noisy>(critter: T) {
- for i in range(0u, 10u) {
- let what = critter.speak();
- info!("%u %d", i, what);
- }
-}
-
-fn bite_everything<T:bitey>(critter: T) -> bool {
- let mut left : ~[body_part] = ~[finger, toe, nose, ear];
- while left.len() > 0u {
- let part = critter.bite();
- info!("%? %?", left, part);
- if vec_includes(left, part) {
- left = vec::filter(left, |p| p != part );
- }
- else {
- return false;
- }
- }
- true
-}
-
-fn scratched_something<T:scratchy>(critter: T) -> bool {
- option::is_some(critter.scratch())
-}
-
-pub fn main() {
- let nyan : cat = cat(0u, 2, "nyan");
- annoy_neighbors(nyan as noisy);
- assert_eq!(nyan.meow_count(), 10u);
- assert!((bite_everything(nyan as bitey)));
- assert!((scratched_something(nyan as scratchy)));
-}
sum(y)
}
-/* FIXME #7304
-fn sum_const(y: &const [int]) -> int {
- sum(y)
-}
-*/
-
pub fn main() {}
-/* FIXME #7302
-fn foo(v: &const [uint]) -> ~[uint] {
- v.to_owned()
-}
-*/
-
fn bar(v: &mut [uint]) -> ~[uint] {
v.to_owned()
}
pub fn main() {
let mut the_vec = ~[1u, 2, 3, 100];
-// assert_eq!(the_vec.clone(), foo(the_vec));
assert_eq!(the_vec.clone(), bar(the_vec));
assert_eq!(the_vec.clone(), bip(the_vec));
}
fn get(self) -> int;
}
-// FIXME #7302: Note: impl on a slice
+// Note: impl on a slice; we're checking that the pointers below
+// correctly get borrowed to `&`. (similar to impling for `int`, with
+// `&self` instead of `self`.)
impl<'self> get for &'self int {
fn get(self) -> int {
return *self;
info!("y=%d", y);
assert_eq!(y, 6);
- let x = ~6;
- let y = x.get();
- info!("y=%d", y);
- assert_eq!(y, 6);
-
let x = &6;
let y = x.get();
info!("y=%d", y);