Bug 12027 – Range of true bits for std.bitmanip.BitArray

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-01-29T08:24:00Z
Last change time
2014-03-01T13:47:50Z
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2014-01-29T08:24:12Z
std.bitmanip.BitArray is sometimes used to represent sparse sets. For this usage it's handy to be able to iterate only on the bits set to true. So I suggest to add a method that returns a range that yields the indexes of only the true bits. Probably it's not hard to create such range using std.range and std.algorithm, but a range implemented natively inside BitArray is probably faster (it can skip whole empty words, and skip the empty bits faster).
Comment #1 by peter.alexander.au — 2014-02-02T04:53:46Z
Comment #2 by bearophile_hugs — 2014-02-02T05:11:33Z
(In reply to comment #1) > https://github.com/D-Programming-Language/phobos/pull/1901 See also Issue 4717 and Issue 10239
Comment #3 by github-bugzilla — 2014-03-01T12:28:56Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/08820e2f146d7a7268f25fd130188929c62dd51c Fix Issue 12027 - Iterate set bits in BitArray. Also adds: - countTrailingZeros(v) - countBitsSet(v) - bitsSet(v) Notes: - There is a `popcnt` function in `core.bitops`, but it only works with `int`. - `bitsSet(v)` could be a bidirectional and possibly even random access range, but I'll leave that for future work for now. https://github.com/D-Programming-Language/phobos/commit/c78cfd97fba32893be2b3dd33425c0d8716409bd Merge pull request #1901 from Poita/bug12027 Fix Issue 12027 - Iterate set bits in BitArray.
Comment #4 by bearophile_hugs — 2014-03-01T12:48:48Z
(In reply to comment #3) > Also adds: > - countTrailingZeros(v) > - countBitsSet(v) > - bitsSet(v) Apparently only bitsSet is working for me: void main() { import std.stdio, std.bitmanip; BitArray b; b.init([0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0]); b.bitsSet.writeln; b.countTrailingZeros.writeln; b.countBitsSet.writeln; } It gives: test.d(7,6): Error: ScopeDsymbol test.__anonymous.__anonymous template std.bitmanip.countTrailingZeros(T)(T value) if (isIntegral!T) is private test.d(7,6): Error: template std.bitmanip.countTrailingZeros cannot deduce function from argument types !()(BitArray), candidates are: ..\dmd2\src\phobos\std\bitmanip.d(3440,14): std.bitmanip.countTrailingZeros(T)(T value) if (isIntegral!T) test.d(8,6): Error: ScopeDsymbol test.__anonymous.__anonymous template std.bitmanip.countBitsSet(T)(T value) if (isIntegral!T) is private test.d(8,6): Error: template std.bitmanip.countBitsSet cannot deduce function from argument types !()(BitArray), candidates are: ..\dmd2\src\phobos\std\bitmanip.d(3502,14): std.bitmanip.countBitsSet(T)(T value) if (isIntegral!T)
Comment #5 by peter.alexander.au — 2014-03-01T13:47:50Z
(In reply to comment #4) > (In reply to comment #3) > > > Also adds: > > - countTrailingZeros(v) > > - countBitsSet(v) > > - bitsSet(v) > > Apparently only bitsSet is working for me: countTrailingZeros and countBitsSet are only defined for built-in integral types at the moment. They were needed to implement bitsSet. However, I was persuaded to make them private because druntime defines popcnt and bsf, but not generically. @blackwhale argued that popcnt/bsf should be extended to be more generic in druntime, but I argued that druntime was for things only necessary for the D language to work, and these weren't necessary. We disagreed, so compromised and just marked them as private for now until we figure out how to resolve it. btw, bitsSet also works on built-in integers, e.g. 5.bitsSet.equal([0, 2]);