mirror of
https://github.com/dlang/phobos.git
synced 2025-04-27 21:51:40 +03:00
Fix Issue 20548 - Use bit vector instead of bool[] in RandomCover when choices cannot be packed in a single word
This commit is contained in:
parent
3502f0a0ae
commit
9014d77ab0
1 changed files with 14 additions and 6 deletions
20
std/random.d
20
std/random.d
|
@ -2950,9 +2950,10 @@ do
|
|||
- bigger length means non-GC heap allocation(s) and dealloc. +/
|
||||
private struct RandomCoverChoices
|
||||
{
|
||||
private void* buffer;
|
||||
private size_t* buffer;
|
||||
private immutable size_t _length;
|
||||
private immutable bool hasPackedBits;
|
||||
private enum BITS_PER_WORD = typeof(buffer[0]).sizeof * 8;
|
||||
|
||||
void opAssign(T)(T) @disable;
|
||||
|
||||
|
@ -2963,8 +2964,9 @@ private struct RandomCoverChoices
|
|||
|
||||
if (!hasPackedBits && buffer !is null)
|
||||
{
|
||||
void* nbuffer = enforceMalloc(_length);
|
||||
buffer = memcpy(nbuffer, buffer, _length);
|
||||
const nBytesToAlloc = 8 * (_length / BITS_PER_WORD + int(_length % BITS_PER_WORD != 0));
|
||||
void* nbuffer = enforceMalloc(nBytesToAlloc);
|
||||
buffer = cast(size_t*) memcpy(nbuffer, buffer, nBytesToAlloc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2976,7 +2978,8 @@ private struct RandomCoverChoices
|
|||
hasPackedBits = _length <= size_t.sizeof * 8;
|
||||
if (!hasPackedBits)
|
||||
{
|
||||
buffer = enforceCalloc(numChoices, 1);
|
||||
const nWordsToAlloc = _length / BITS_PER_WORD + int(_length % BITS_PER_WORD != 0);
|
||||
buffer = cast(size_t*) enforceCalloc(nWordsToAlloc, BITS_PER_WORD / 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2993,8 +2996,9 @@ private struct RandomCoverChoices
|
|||
bool opIndex(size_t index) const pure nothrow @nogc @trusted
|
||||
{
|
||||
assert(index < _length);
|
||||
import core.bitop : bt;
|
||||
if (!hasPackedBits)
|
||||
return *((cast(bool*) buffer) + index);
|
||||
return cast(bool) bt(buffer, index);
|
||||
else
|
||||
return ((cast(size_t) buffer) >> index) & size_t(1);
|
||||
}
|
||||
|
@ -3004,7 +3008,11 @@ private struct RandomCoverChoices
|
|||
assert(index < _length);
|
||||
if (!hasPackedBits)
|
||||
{
|
||||
*((cast(bool*) buffer) + index) = value;
|
||||
import core.bitop : btr, bts;
|
||||
if (value)
|
||||
bts(buffer, index);
|
||||
else
|
||||
btr(buffer, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue