[Issue 14001] New: Optionally @nogc std.random.randomCover
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Sun Jan 18 05:25:00 PST 2015
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 at puremagic.com
Reporter: bearophile_hugs at 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.
--
More information about the Digitalmars-d-bugs
mailing list