Skip to content

Commit 42a4fb2

Browse files
committed
---
yaml --- r: 61417 b: refs/heads/try c: 08ef229 h: refs/heads/master i: 61415: 33f8c36 v: v3
1 parent b2c7099 commit 42a4fb2

File tree

3 files changed

+127
-188
lines changed

3 files changed

+127
-188
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2d28d645422c1617be58c8ca7ad9a457264ca850
5-
refs/heads/try: c99d1de85bcc7fff69b6ad4f3159fef8707d304b
5+
refs/heads/try: 08ef229a65cd7b8de27a5844eee3dce8c69aa846
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libcore/iter.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ much easier to implement.
4343
#[cfg(not(stage0))] use cmp::Ord;
4444
#[cfg(not(stage0))] use option::{Option, Some, None};
4545
#[cfg(not(stage0))] use vec::OwnedVector;
46+
#[cfg(not(stage0))] use num::{One, Zero};
47+
#[cfg(not(stage0))] use ops::{Add, Mul};
4648

4749
#[cfg(stage0)]
4850
pub trait Times {
@@ -212,6 +214,81 @@ pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
212214
result
213215
}
214216

217+
/**
218+
* Reduce an iterator to an accumulated value.
219+
*
220+
* # Example:
221+
*
222+
* ~~~~
223+
* assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
224+
* ~~~~
225+
*/
226+
#[cfg(not(stage0))]
227+
#[inline]
228+
pub fn fold<T, U>(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T {
229+
let mut result = start;
230+
for iter |x| {
231+
f(&mut result, x);
232+
}
233+
result
234+
}
235+
236+
/**
237+
* Reduce an iterator to an accumulated value.
238+
*
239+
* `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it
240+
* forces the iterator to yield borrowed pointers.
241+
*
242+
* # Example:
243+
*
244+
* ~~~~
245+
* fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
246+
* fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
247+
* }
248+
* ~~~~
249+
*/
250+
#[cfg(not(stage0))]
251+
#[inline]
252+
pub fn fold_ref<T, U>(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T {
253+
let mut result = start;
254+
for iter |x| {
255+
f(&mut result, x);
256+
}
257+
result
258+
}
259+
260+
/**
261+
* Return the sum of the items yielding by an iterator.
262+
*
263+
* # Example:
264+
*
265+
* ~~~~
266+
* let xs: ~[int] = ~[1, 2, 3, 4];
267+
* assert_eq!(do sum |f| { xs.each(f) }, 10);
268+
* ~~~~
269+
*/
270+
#[cfg(not(stage0))]
271+
#[inline(always)]
272+
pub fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
273+
fold_ref(Zero::zero::<T>(), iter, |a, x| *a = a.add(x))
274+
}
275+
276+
/**
277+
* Return the product of the items yielded by an iterator.
278+
*
279+
* # Example:
280+
*
281+
* ~~~~
282+
* let xs: ~[int] = ~[1, 2, 3, 4];
283+
* assert_eq!(do product |f| { xs.each(f) }, 24);
284+
* ~~~~
285+
*/
286+
#[cfg(not(stage0))]
287+
#[inline(always)]
288+
pub fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
289+
fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
290+
}
291+
215292
#[cfg(test)]
216293
mod tests {
217294
use super::*;
@@ -254,4 +331,33 @@ mod tests {
254331
let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
255332
assert_eq!(min(|f| xs.each(f)).unwrap(), &-5);
256333
}
334+
335+
#[test]
336+
fn test_fold() {
337+
assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
338+
}
339+
340+
#[test]
341+
fn test_sum() {
342+
let xs: ~[int] = ~[1, 2, 3, 4];
343+
assert_eq!(do sum |f| { xs.each(f) }, 10);
344+
}
345+
346+
#[test]
347+
fn test_empty_sum() {
348+
let xs: ~[int] = ~[];
349+
assert_eq!(do sum |f| { xs.each(f) }, 0);
350+
}
351+
352+
#[test]
353+
fn test_product() {
354+
let xs: ~[int] = ~[1, 2, 3, 4];
355+
assert_eq!(do product |f| { xs.each(f) }, 24);
356+
}
357+
358+
#[test]
359+
fn test_empty_product() {
360+
let xs: ~[int] = ~[];
361+
assert_eq!(do product |f| { xs.each(f) }, 1);
362+
}
257363
}

branches/try/src/libcore/vec.rs

Lines changed: 20 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,46 +1445,6 @@ pub fn reverse<T>(v: &mut [T]) {
14451445
}
14461446
}
14471447

1448-
/**
1449-
* Reverse part of a vector in place.
1450-
*
1451-
* Reverse the elements in the vector between `start` and `end - 1`.
1452-
*
1453-
* If either start or end do not represent valid positions in the vector, the
1454-
* vector is returned unchanged.
1455-
*
1456-
* # Arguments
1457-
*
1458-
* * `v` - The mutable vector to be modified
1459-
*
1460-
* * `start` - Index of the first element of the slice
1461-
*
1462-
* * `end` - Index one past the final element to be reversed.
1463-
*
1464-
* # Example
1465-
*
1466-
* Assume a mutable vector `v` contains `[1,2,3,4,5]`. After the call:
1467-
*
1468-
* ~~~
1469-
*
1470-
* reverse_part(v, 1, 4);
1471-
*
1472-
* ~~~
1473-
*
1474-
* `v` now contains `[1,4,3,2,5]`.
1475-
*/
1476-
pub fn reverse_part<T>(v: &mut [T], start: uint, end : uint) {
1477-
let sz = v.len();
1478-
if start >= sz || end > sz { return; }
1479-
let mut i = start;
1480-
let mut j = end - 1;
1481-
while i < j {
1482-
vec::swap(v, i, j);
1483-
i += 1;
1484-
j -= 1;
1485-
}
1486-
}
1487-
14881448
/// Returns a vector with the order of elements reversed
14891449
pub fn reversed<T:Copy>(v: &const [T]) -> ~[T] {
14901450
let mut rs: ~[T] = ~[];
@@ -1779,69 +1739,29 @@ pub fn each2_mut<U, T>(v1: &mut [U], v2: &mut [T], f: &fn(u: &mut U, t: &mut T)
17791739
*
17801740
* The total number of permutations produced is `len(v)!`. If `v` contains
17811741
* repeated elements, then some permutations are repeated.
1782-
*
1783-
* See [Algorithms to generate
1784-
* permutations](http://en.wikipedia.org/wiki/Permutation).
1785-
*
1786-
* # Arguments
1787-
*
1788-
* * `values` - A vector of values from which the permutations are
1789-
* chosen
1790-
*
1791-
* * `fun` - The function to iterate over the combinations
17921742
*/
1793-
pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) {
1794-
let length = values.len();
1795-
let mut permutation = vec::from_fn(length, |i| values[i]);
1796-
if length <= 1 {
1797-
fun(permutation);
1798-
return;
1799-
}
1800-
let mut indices = vec::from_fn(length, |i| i);
1801-
loop {
1802-
if !fun(permutation) { return; }
1803-
// find largest k such that indices[k] < indices[k+1]
1804-
// if no such k exists, all permutations have been generated
1805-
let mut k = length - 2;
1806-
while k > 0 && indices[k] >= indices[k+1] {
1807-
k -= 1;
1808-
}
1809-
if k == 0 && indices[0] > indices[1] { return; }
1810-
// find largest l such that indices[k] < indices[l]
1811-
// k+1 is guaranteed to be such
1812-
let mut l = length - 1;
1813-
while indices[k] >= indices[l] {
1814-
l -= 1;
1815-
}
1816-
// swap indices[k] and indices[l]; sort indices[k+1..]
1817-
// (they're just reversed)
1818-
vec::swap(indices, k, l);
1819-
reverse_part(indices, k+1, length);
1820-
// fixup permutation based on indices
1821-
for uint::range(k, length) |i| {
1822-
permutation[i] = values[indices[i]];
1743+
#[cfg(not(stage0))]
1744+
pub fn each_permutation<T:Copy>(v: &[T], put: &fn(ts: &[T]) -> bool) -> bool {
1745+
let ln = len(v);
1746+
if ln <= 1 {
1747+
put(v);
1748+
} else {
1749+
// This does not seem like the most efficient implementation. You
1750+
// could make far fewer copies if you put your mind to it.
1751+
let mut i = 0u;
1752+
while i < ln {
1753+
let elt = v[i];
1754+
let mut rest = slice(v, 0u, i).to_vec();
1755+
rest.push_all(const_slice(v, i+1u, ln));
1756+
for each_permutation(rest) |permutation| {
1757+
if !put(append(~[elt], permutation)) {
1758+
return false;
1759+
}
1760+
}
1761+
i += 1u;
18231762
}
18241763
}
1825-
}
1826-
1827-
/**
1828-
* Iterate over all permutations of vector `values`.
1829-
*
1830-
* This is an alternative to each_permutation that uses references to
1831-
* avoid copying the elements of the values vector.
1832-
*
1833-
* To avoid copying, the iterator will be passed a reference to a vector
1834-
* containing references to the elements in the original `values` vector.
1835-
*
1836-
* # Arguments
1837-
*
1838-
* * `values` - A vector of values from which the permutations are chosen
1839-
*
1840-
* * `fun` - The function to iterate over the permutations
1841-
*/
1842-
#[cfg(not(stage0))]
1843-
pub fn each_permutation_ref<T>(values : &[T], fun : &fn(perm : &[&T]) -> bool) {
1844-
each_permutation(vec::from_fn(values.len(), |i| &values[i]), fun);
1764+
return true;
18451765
}
18461766

18471767
/**
@@ -4810,93 +4730,6 @@ mod tests {
48104730
}
48114731
}
48124732

4813-
#[test]
4814-
fn test_reverse_part() {
4815-
let mut values = [1,2,3,4,5];
4816-
reverse_part(values,1,4);
4817-
assert_eq!(values, [1,4,3,2,5]);
4818-
}
4819-
4820-
#[test]
4821-
fn test_permutations0() {
4822-
let values = [];
4823-
let mut v : ~[~[int]] = ~[];
4824-
for each_permutation(values) |p| {
4825-
v.push(p.to_owned());
4826-
}
4827-
assert_eq!(v, ~[~[]]);
4828-
}
4829-
4830-
#[test]
4831-
fn test_permutations0_ref() {
4832-
let values = [];
4833-
let mut v : ~[~[int]] = ~[];
4834-
for each_permutation_ref(values) |p| {
4835-
v.push(p.to_owned());
4836-
}
4837-
assert_eq!(v, ~[~[]]);
4838-
}
4839-
4840-
#[test]
4841-
fn test_permutations1() {
4842-
let values = [1];
4843-
let mut v : ~[~[int]] = ~[];
4844-
for each_permutation(values) |p| {
4845-
v.push(p.to_owned());
4846-
}
4847-
assert_eq!(v, ~[~[1]]);
4848-
}
4849-
4850-
#[test]
4851-
fn test_permutations1_ref() {
4852-
let values = [1];
4853-
let mut v : ~[~[int]] = ~[];
4854-
for each_permutation_ref(values) |p| {
4855-
v.push(p.to_owned());
4856-
}
4857-
assert_eq!(v, ~[~[1]]);
4858-
}
4859-
4860-
#[test]
4861-
fn test_permutations2() {
4862-
let values = [1,2];
4863-
let mut v : ~[~[int]] = ~[];
4864-
for each_permutation(values) |p| {
4865-
v.push(p.to_owned());
4866-
}
4867-
assert_eq!(v, ~[~[1,2],~[2,1]]);
4868-
}
4869-
4870-
#[test]
4871-
fn test_permutations2_ref() {
4872-
let values = [1,2];
4873-
let mut v : ~[~[int]] = ~[];
4874-
for each_permutation_ref(values) |p| {
4875-
v.push(p.to_owned());
4876-
}
4877-
assert_eq!(v, ~[~[1,2],~[2,1]]);
4878-
}
4879-
4880-
#[test]
4881-
fn test_permutations3() {
4882-
let values = [1,2,3];
4883-
let mut v : ~[~[int]] = ~[];
4884-
for each_permutation(values) |p| {
4885-
v.push(p.to_owned());
4886-
}
4887-
assert_eq!(v, ~[~[1,2,3],~[1,3,2],~[2,1,3],~[2,3,1],~[3,1,2],~[3,2,1]]);
4888-
}
4889-
4890-
#[test]
4891-
fn test_permutations3_ref() {
4892-
let values = [1,2,3];
4893-
let mut v : ~[~[int]] = ~[];
4894-
for each_permutation_ref(values) |p| {
4895-
v.push(p.to_owned());
4896-
}
4897-
assert_eq!(v, ~[~[1,2,3],~[1,3,2],~[2,1,3],~[2,3,1],~[3,1,2],~[3,2,1]]);
4898-
}
4899-
49004733
#[test]
49014734
fn test_each_val() {
49024735
use old_iter::CopyableNonstrictIter;

0 commit comments

Comments
 (0)