| ... | @@ -47,6 +47,19 @@ pub const Random = struct { | ... | @@ -47,6 +47,19 @@ pub const Random = struct { |
| 47 | return r.int(u1) != 0; | 47 | return r.int(u1) != 0; |
| 48 | } | 48 | } |
| 49 | | 49 | |
| | 50 | /// Returns a random value from an enum, evenly distributed. |
| | 51 | pub fn enumValue(r: *Random, comptime EnumType: type) EnumType { |
| | 52 | if (comptime !std.meta.trait.is(.Enum)(EnumType)) { |
| | 53 | @compileError("Random.enumValue requires an enum type, not a " ++ @typeName(EnumType)); |
| | 54 | } |
| | 55 | |
| | 56 | // We won't use int -> enum casting because enum elements can have |
| | 57 | // arbitrary values. Instead we'll randomly pick one of the type's values. |
| | 58 | const values = std.enums.values(EnumType); |
| | 59 | const index = r.uintLessThan(usize, values.len); |
| | 60 | return values[index]; |
| | 61 | } |
| | 62 | |
| 50 | /// Returns a random int `i` such that `0 <= i <= maxInt(T)`. | 63 | /// Returns a random int `i` such that `0 <= i <= maxInt(T)`. |
| 51 | /// `i` is evenly distributed. | 64 | /// `i` is evenly distributed. |
| 52 | pub fn int(r: *Random, comptime T: type) T { | 65 | pub fn int(r: *Random, comptime T: type) T { |
| ... | @@ -377,6 +390,23 @@ fn testRandomBoolean() !void { | ... | @@ -377,6 +390,23 @@ fn testRandomBoolean() !void { |
| 377 | try expect(r.random.boolean() == true); | 390 | try expect(r.random.boolean() == true); |
| 378 | } | 391 | } |
| 379 | | 392 | |
| | 393 | test "Random enum" { |
| | 394 | try testRandomEnumValue(); |
| | 395 | comptime try testRandomEnumValue(); |
| | 396 | } |
| | 397 | fn testRandomEnumValue() !void { |
| | 398 | const TestEnum = enum { |
| | 399 | First, |
| | 400 | Second, |
| | 401 | Third, |
| | 402 | }; |
| | 403 | var r = SequentialPrng.init(); |
| | 404 | r.next_value = 0; |
| | 405 | try expect(r.random.enumValue(TestEnum) == TestEnum.First); |
| | 406 | try expect(r.random.enumValue(TestEnum) == TestEnum.First); |
| | 407 | try expect(r.random.enumValue(TestEnum) == TestEnum.First); |
| | 408 | } |
| | 409 | |
| 380 | test "Random intLessThan" { | 410 | test "Random intLessThan" { |
| 381 | @setEvalBranchQuota(10000); | 411 | @setEvalBranchQuota(10000); |
| 382 | try testRandomIntLessThan(); | 412 | try testRandomIntLessThan(); |