forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 4
/
rand.rs
143 lines (123 loc) · 3.19 KB
/
rand.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
Module: rand
Random number generation
*/
#[abi = "cdecl"]
native mod rustrt {
type rctx;
fn rand_new() -> rctx;
fn rand_next(c: rctx) -> u32;
fn rand_free(c: rctx);
}
/* Section: Types */
/*
Obj: rng
A random number generator
*/
iface rng {
/*
Method: next
Return the next random integer
*/
fn next() -> u32;
/*
Method: next_float
Return the next random float
*/
fn next_float() -> float;
/*
Method: gen_str
Return a random string composed of A-Z, a-z, 0-9.
*/
fn gen_str(len: uint) -> str;
/*
Method: gen_bytes
Return a random byte string.
*/
fn gen_bytes(len: uint) -> [u8];
}
resource rand_res(c: rustrt::rctx) { rustrt::rand_free(c); }
/* Section: Operations */
/*
Function: mk_rng
Create a random number generator
*/
fn mk_rng() -> rng {
impl of rng for @rand_res {
fn next() -> u32 { ret rustrt::rand_next(**self); }
fn next_float() -> float {
let u1 = rustrt::rand_next(**self) as float;
let u2 = rustrt::rand_next(**self) as float;
let u3 = rustrt::rand_next(**self) as float;
let scale = u32::max_value as float;
ret ((u1 / scale + u2) / scale + u3) / scale;
}
fn gen_str(len: uint) -> str {
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz" +
"0123456789";
let s = "";
let i = 0u;
while (i < len) {
let n = rustrt::rand_next(**self) as uint %
str::char_len(charset);
s = s + str::from_char(str::char_at(charset, n));
i += 1u;
}
s
}
fn gen_bytes(len: uint) -> [u8] {
let v = [];
let i = 0u;
while i < len {
let n = rustrt::rand_next(**self) as uint;
v += [(n % (u8::max_value as uint)) as u8];
i += 1u;
}
v
}
}
@rand_res(rustrt::rand_new()) as rng
}
#[cfg(test)]
mod tests {
#[test]
fn test() {
let r1: rand::rng = rand::mk_rng();
log(debug, r1.next());
log(debug, r1.next());
{
let r2 = rand::mk_rng();
log(debug, r1.next());
log(debug, r2.next());
log(debug, r1.next());
log(debug, r1.next());
log(debug, r2.next());
log(debug, r2.next());
log(debug, r1.next());
log(debug, r1.next());
log(debug, r1.next());
log(debug, r2.next());
log(debug, r2.next());
log(debug, r2.next());
}
log(debug, r1.next());
log(debug, r1.next());
}
#[test]
fn genstr() {
let r: rand::rng = rand::mk_rng();
log(debug, r.gen_str(10u));
log(debug, r.gen_str(10u));
log(debug, r.gen_str(10u));
assert(str::char_len(r.gen_str(10u)) == 10u);
assert(str::char_len(r.gen_str(16u)) == 16u);
}
}
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End: