digitalmars.D.bugs - [Issue 14001] New: Optionally nogc std.random.randomCover
- via Digitalmars-d-bugs (84/84) Jan 18 2015 https://issues.dlang.org/show_bug.cgi?id=14001
https://issues.dlang.org/show_bug.cgi?id=14001 Issue ID: 14001 Summary: Optionally nogc std.random.randomCover Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: Phobos Assignee: nobody puremagic.com Reporter: bearophile_hugs eml.cc This is part of randomCover code: struct RandomCover(Range, UniformRNG = void) if (isRandomAccessRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void))) { private Range _input; private bool[] _chosen; private size_t _current; private size_t _alreadyChosen = 0; static if (is(UniformRNG == void)) { this(Range input) { _input = input; _chosen.length = _input.length; if (_chosen.length == 0) { _alreadyChosen = 1; } } } ... auto randomCover(Range, UniformRNG)(Range r, auto ref UniformRNG rng) if (isRandomAccessRange!Range && isUniformRNG!UniformRNG) { return RandomCover!(Range, UniformRNG)(r, rng); } auto randomCover(Range)(Range r) if (isRandomAccessRange!Range) { return RandomCover!(Range, void)(r); } Currently randomCover can't be nogc because of the random generator, but also because of that allocation of _chosen inside the struct constructor. To solve this problem I suggest to remove the allocation of _chosen from the struct constructor and move it inside the helper functions. And then add two more overloads for the helper functions, something like this: auto randomCover(Range, UniformRNG)(Range r, auto ref UniformRNG rng) if (isRandomAccessRange!Range && isUniformRNG!UniformRNG) { return RandomCover!(Range, UniformRNG)(r, rng, new bool[r.length]); } auto randomCover(Range)(Range r) if (isRandomAccessRange!Range) { return RandomCover!(Range, void)(r, new bool[r.length]); } auto randomCover(Range, UniformRNG)(Range r, auto ref UniformRNG rng, bool[] buf) nogc if (isRandomAccessRange!Range && isUniformRNG!UniformRNG) { if (buf.length < r.length) { // Is this correct in presence of chaining? static immutable err = new Error("Not sufficient 'buf' size"); throw err; } return RandomCover!(Range, UniformRNG)(r, rng, buf[0 .. r.length]); } auto randomCover(Range)(Range r, bool[] buf) nogc if (isRandomAccessRange!Range) { if (buf.length < r.length) { static immutable err = new Error("Not sufficient 'buf' size"); throw err; } return RandomCover!(Range, void)(r, buf[0 .. r.length]); } The two more overloads take an extra "buf" input, that will be used by the RandomCover. If the buf is not long enough, an error is raised. Optionally randomCover could take a std.bitmanip.BitArray instead. --
Jan 18 2015