diff --git a/std/bitmanip.d b/std/bitmanip.d index 86df657e613..05c74b26b69 100644 --- a/std/bitmanip.d +++ b/std/bitmanip.d @@ -3773,57 +3773,6 @@ void append(T, Endian endianness = Endian.bigEndian, R)(R range, T value) } } -/** -Counts the number of trailing zeros in the binary representation of $(D value). -For signed integers, the sign bit is included in the count. -*/ -private uint countTrailingZeros(T)(T value) @nogc pure nothrow - if (isIntegral!T) -{ - import core.bitop : bsf; - // bsf doesn't give the correct result for 0. - if (!value) - return 8 * T.sizeof; - else - return bsf(value); -} - -/// -@safe unittest -{ - assert(countTrailingZeros(1) == 0); - assert(countTrailingZeros(0) == 32); - assert(countTrailingZeros(int.min) == 31); - assert(countTrailingZeros(256) == 8); -} - -@safe unittest -{ - import std.meta; - foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong)) - { - assert(countTrailingZeros(cast(T)0) == 8 * T.sizeof); - assert(countTrailingZeros(cast(T)1) == 0); - assert(countTrailingZeros(cast(T)2) == 1); - assert(countTrailingZeros(cast(T)3) == 0); - assert(countTrailingZeros(cast(T)4) == 2); - assert(countTrailingZeros(cast(T)5) == 0); - assert(countTrailingZeros(cast(T)64) == 6); - static if (isSigned!T) - { - assert(countTrailingZeros(cast(T)-1) == 0); - assert(countTrailingZeros(T.min) == 8 * T.sizeof - 1); - } - else - { - assert(countTrailingZeros(T.max) == 0); - } - } - assert(countTrailingZeros(1_000_000) == 6); - foreach (i; 0..63) - assert(countTrailingZeros(1UL << i) == i); -} - /** Counts the number of set bits in the binary representation of $(D value). For signed integers, the sign bit is included in the count. @@ -3914,9 +3863,14 @@ private struct BitsSet(T) this(T value, size_t startIndex = 0) { _value = value; - immutable n = countTrailingZeros(value); - _index = startIndex + n; - _value >>>= n; + // Further calculation is only valid and needed when the range is non-empty. + if (!_value) + return; + + import core.bitop : bsf; + immutable trailingZerosCount = bsf(value); + _value >>>= trailingZerosCount; + _index = startIndex + trailingZerosCount; } @property size_t front() @@ -3934,9 +3888,14 @@ private struct BitsSet(T) assert(_value, "Cannot call popFront on empty range."); _value >>>= 1; - immutable n = countTrailingZeros(_value); - _value >>>= n; - _index += n + 1; + // Further calculation is only valid and needed when the range is non-empty. + if (!_value) + return; + + import core.bitop : bsf; + immutable trailingZerosCount = bsf(_value); + _value >>>= trailingZerosCount; + _index += trailingZerosCount + 1; } @property auto save()