BitArray/BitFields - Resumed and polishing

Era Scarecrow rtcvb32 at yahoo.com
Thu Jan 3 02:20:41 PST 2013


On Thursday, 3 January 2013 at 07:57:46 UTC, Dmitry Olshansky 
wrote:
> 1/3/2013 6:05 AM, Era Scarecrow wrote:

> Hm, I'd think that having Slice type be:
>
> BitArraySlice{
> BitArray* bp;
> size_t start, end;
> // all else forwards to the pointed array
> }
> should work avoiding the most of code duplication. With any 
> luck inliner will expand all of this wrapping. To enable bulk 
> mode operations:
>
> void opOpSliceAssign(BitArraySlice rhs)
> {//has all the data to do it
>    bulkOp(bp, start, end, rhs.bp, rhs.start, rhs.end);
> }
>
> then it's a question of bit of refactoring & tweaking of array 
> bulks ops.
>
> Then the only problem left is slice invalidation and original 
> array going out of scope.

  I know we've had this discussion before. So let's assume you do 
slicing this way. So what happens when...

  BitArray ba = [0,1,1,0];

  ba = ba[1 .. $-1]; // ba is not a BitArraySlice

  Suddenly it won't work and slicing is only a range and can only 
be used in foreach. Correct? You could do appending but likely it 
would require two functions in the original code (one for a 
BitArray and one for a slice). It it supports a opAssign to 
handle that now you have to take care of all opAssign's as well 
(like C++, once you handle one portion of it and opCast, you 
handle them all).

>> Does that mean we might be able to drop opApply? Hmmm... 
>> Depends on if we have enough implemented so the range accepts 
>> it. I'll glance over std.range.
>
> Yes, it's got to be a range to work like this and then opApply 
> is useless.

  Maybe. Foreach if I remember right worked three different ways, 
and selected whichever one worked. opApply, front/pop/empty, and 
array (opIndex access). If enough is implemented that it 
recognizes it as an array then opApply can be removed.

  A quick tests shows that currently isn't the case.

>> Really depends on the use case. I'm guessing there's enough 
>> call for the 64bit small packed bitarray that justifies it, 
>> otherwise it would be better to throw it out. As you mention 
>> later, separating them does seem like a better idea.
>
> I've meant the fact that it has to preserve current std lib 
> behavior *and* has small string optimization that makes it 
> overly painful and partially defeats the optimization (by 
> requiring pointless compact->big conversions on slice etc.).

  We could always 'dup' on slice instead, but then you can't use 
references on it, at which point it's a value type. Hmmm. Being a 
pure value type then a separate range makes more sense to use.

>> hmmm.. Either would need some code duplication, or template to 
>> turn off/swap small string optimization. But separating them 
>> does seem like a good idea.
>
> I'd expect a fair chunk of code to be split off into free 
> functions, then both containers would make use of them.
>
> Now note that there is also std.container Array!bool that has 
> reference semantics and got to be doing bit packing... it could 
> potentially take place of big BitArray mentioned.

  I'm aware of the container version, and overall if it can just 
replace BitArray as it is, then we might consider only worrying 
about a compact version, at which point it would become a 
template... Might start seeing BitArray!1024  in places (or 
BitString!1024 ?).


More information about the Digitalmars-d-learn mailing list