|
| 1 | +use std; |
| 2 | +import std::vec; |
| 3 | +import std::rand; |
| 4 | +import std::option; |
| 5 | + |
| 6 | +// random uint less than n |
| 7 | +fn under(r : rand::rng, n : uint) -> uint { assert n != 0u; r.next() as uint % n } |
| 8 | + |
| 9 | +// random choice from a vec |
| 10 | +fn choice<T>(r : rand::rng, v : [T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] } |
| 11 | + |
| 12 | +// 1 in n chance of being true |
| 13 | +fn unlikely(r : rand::rng, n : uint) -> bool { under(r, n) == 0u } |
| 14 | + |
| 15 | +tag maybe_pointy { |
| 16 | + no_pointy; |
| 17 | + yes_pointy(@pointy); |
| 18 | +} |
| 19 | + |
| 20 | +type pointy = { |
| 21 | + mutable x : maybe_pointy, |
| 22 | + mutable y : maybe_pointy, |
| 23 | + mutable z : fn()->() |
| 24 | +}; |
| 25 | + |
| 26 | +iter allunder(n: uint) -> uint { |
| 27 | + let i: uint = 0u; |
| 28 | + while i < n { put i; i += 1u; } |
| 29 | +} |
| 30 | + |
| 31 | +fn nopT(_x : @pointy) { } |
| 32 | +fn nop() { } |
| 33 | + |
| 34 | +fn test_cycles(r : rand::rng) |
| 35 | +{ |
| 36 | + const max : uint = 10u; |
| 37 | + |
| 38 | + let v : [mutable @pointy] = [mutable]; |
| 39 | + for each i in allunder(max) { |
| 40 | + v += [mutable @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: nop }]; |
| 41 | + } |
| 42 | + |
| 43 | + for each i in allunder(max) { |
| 44 | + v[i].x = yes_pointy(v[under(r, max)]); |
| 45 | + v[i].y = yes_pointy(v[under(r, max)]); |
| 46 | + v[i].z = bind nopT(v[under(r, max)]); |
| 47 | + } |
| 48 | + |
| 49 | + // Drop refs one at a time |
| 50 | + for each i in allunder(max) { |
| 51 | + v[i] = @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: nop }; |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +fn main() |
| 56 | +{ |
| 57 | + let r = rand::mk_rng(); |
| 58 | + test_cycles(r); |
| 59 | +} |
0 commit comments