BitArray new design - slice problems

Dmitry Olshansky dmitry.olsh at gmail.com
Thu Jan 17 10:12:27 PST 2013


17-Jan-2013 07:53, Era Scarecrow пишет:
>   Well got a few curious problems. Slicing doesn't seem it wants to work
> as a separate type and can cause problems.
>
>   Let's take an example. Say our slice is..
>
>    struct BitArraySlice {
>      BitArray* ba;
>      ulong start, end;
>    }
>
>   Now how much does it depend on the bitarray that it's pointing to? If
> it is a wrapper then we have a problem with range checks which should be
> legal.
>
>    BitArray x = BitArray(100); //100 elements
>
>    auto sl = x[50 .. 100];
>    x.length = 50;

Well, the slice was invalidated by shrinking an array. I don't expect 
the below to work.

>    sl[0] = true; //out of range! BitArray valid from 0-49, not 50-100
>

The good part is that error can be detected easily. In c++ for instance 
it typically isn't.

The harder problem is what to do when the original BitArray goes out of 
scope. I guess in case of storage allocated on heap it should work but 
if on the stack it shouldn't (and can't).

>   That much is sorta easy to fix with a separate opIndex (and fixed
> sizes), but it's possible to re-slice the dynamic array to make it
> smaller. So even if we have opIndex allow out of ranges...
>
>    struct BitArray {
>      size_t[] store; //storage
>      ubyte start, end;
>    }
>
>    BitArray x = BitArray(100); //100 elements
>    auto sl = x[50 .. 100];
>
>    //likely does x.store[] = x.store[0 .. 2];
>    //due to compact 1 byte offsets to determine end of bitarray.
>    x.length = 50;
>
>    sl[0] = true; //ok, 0-64 valid on 32bit machines
>    sl[32] = true; //out of range! 82 past not within 0-63
>

That's why it's far better to allow slices to be invalidated depending 
on the length parameter of BitArray pointed by. Compact array do weird 
things in the previous version too.

>
>   So let's take the slice and give it the address of the storage
> instead, other than it could point to a local variable it will work; But
> now I have basically two definitions of bitarray, one that can be a
> range/slice while the other that manages the memory and binary operators.
>
>    struct BitArraySlice {
>      //same as BitArray now, what advantage does this give?
>      size_t[] store;
>      ulong start, end;
>    }
>
>   Seems like making the slices a separate entity is going to cause more
> problems (Not that they can't be solved but the advantages seem
> smaller); Plus there's issues trying to get immutable/idup working.
>

Slices are ranges and thus are converted to array via std.array.array, 
nothing to invent or re-implement.

>   Thoughts? Feedback? I'm about ready to drop this and resume my
> previous version and enhance it with recent experiences.

Feel free to do it how you see it. It's just that I think the semantics 
of the previous version can't be improved to a consistent state.

-- 
Dmitry Olshansky


More information about the Digitalmars-d-learn mailing list