From 34866edf362698c01581850ffdf4aa87f9f08228 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 31 Oct 2012 16:02:16 -0700 Subject: [PATCH] libcore: Implement a memory-safe "each_val" for data in aliasable, mutable locations --- src/libcore/core.rs | 2 +- src/libcore/iter.rs | 7 +++++++ src/libcore/vec.rs | 31 +++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/libcore/core.rs b/src/libcore/core.rs index f9fbe7aa9292b..12a426261c49b 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -17,7 +17,7 @@ pub use vec::{ConstVector, CopyableVector, ImmutableVector}; pub use vec::{ImmutableEqVector, ImmutableCopyableVector}; pub use vec::{MutableVector, MutableCopyableVector}; pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter}; -pub use iter::{CopyableOrderedIter, Times}; +pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times}; pub use num::Num; pub use ptr::Ptr; pub use to_str::ToStr; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index bb28d0ef4fbac..d318c279999c2 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -46,6 +46,13 @@ pub trait CopyableOrderedIter { pure fn max() -> A; } +pub trait CopyableNonstrictIter { + // Like "each", but copies out the value. If the receiver is mutated while + // iterating over it, the semantics must not be memory-unsafe but are + // otherwise undefined. + pure fn each_val(&const self, f: &fn(A) -> bool); +} + // A trait for sequences that can be by imperatively pushing elements // onto them. pub trait Buildable { diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 24a44c591c1b6..6cbf8ca91fd63 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -2020,6 +2020,37 @@ impl &[A]: iter::CopyableOrderedIter { pure fn min() -> A { iter::min(&self) } pure fn max() -> A { iter::max(&self) } } + +impl &[A] : iter::CopyableNonstrictIter { + pure fn each_val(&const self, f: fn(A) -> bool) { + let mut i = 0; + while i < self.len() { + if !f(copy self[i]) { break; } + i += 1; + } + } +} + +impl ~[A] : iter::CopyableNonstrictIter { + pure fn each_val(&const self, f: fn(A) -> bool) { + let mut i = 0; + while i < self.len() { + if !f(copy self[i]) { break; } + i += 1; + } + } +} + +impl @[A] : iter::CopyableNonstrictIter { + pure fn each_val(&const self, f: fn(A) -> bool) { + let mut i = 0; + while i < self.len() { + if !f(copy self[i]) { break; } + i += 1; + } + } +} + // ___________________________________________________________________________ #[cfg(test)]