A Refcounted Array Type

ponce via Digitalmars-d digitalmars-d at puremagic.com
Tue Feb 24 03:14:58 PST 2015


Does DIP25 means we can turn resources into RC types and be done 
with non-deterministic destructor calls by the GC, without using 
RefCounted or Unique?

On Monday, 23 February 2015 at 22:15:54 UTC, Walter Bright wrote:
> This is pretty straightforward. More could be done:
>
> 1. small array optimization
> 2. support for ranges as constructor args
> 3. present a range interface
> 4. support for malloc/free instead of GC
> 5. bounds checking
> 6. the array[] and the count could be allocated together
> 7. array[] could be just a pointer
>
> but the basic idea is there, I didn't want to hide it behind 
> all the other flesh a professional type would have.
>
> Note the return in opIndex(). This is DIP25 at work!
>
> Compile:
>     dmd rcarray -unittest -main -dip25
>
> ===========================================
>
> struct RCArray(E) {
>
>     this(E[] a)
>     {
>         array = a.dup;
>         start = 0;
>         end = a.length;
>         count = new int;
>         *count = 1;
>     }
>
>     ~this()
>     {
>         if (count && --*count == 0)
>             delete array;
>     }
>
>     this(this)
>     {
>         if (count)
>             ++*count;
>     }
>
>     size_t length()
>     {
>         return end - start;
>     }
>
>     ref E opIndex(size_t i) return // here's the magic
>     {
>         return array[start + i];
>     }
>
>     RCArray opSlice(size_t lwr, size_t upr)
>     {
>         RCArray result = this;
>         result.start = start + lwr;
>         result.end = start + upr;
>         return result;
>     }
>
>   private:
>     E[] array;
>     size_t start, end;
>     int* count;
> }
>
> unittest
> {
>     static int[3] s = [7, 6, 4];
>     auto r = RCArray!int(s);
>     assert(r.length == 3);
>     assert(r[0] == 7);
>     assert(r[1] == 6);
>     assert(r[2] == 4);
>     assert(*r.count == 1);
>
>     {
>         auto r2 = r;
>         assert(r2[0] == 7);
>         assert(r2[1] == 6);
>         assert(r2[2] == 4);
>         assert(*r.count == 2);
>
>         r[1] = 3;
>         assert(r2[0] == 7);
>         assert(r2[1] == 3);
>         assert(r2[2] == 4);
>     }
>     assert(*r.count == 1);
>
>     auto r3 = r[1 .. 3];
>     r[2] = 9;
>     assert(r3[0] == 3);
>     assert(r3[1] == 9);
>
>   /+
>     ref int test(ref RCArray!int rr)
>     {
>         return rr[1]; // this gives error
>     }
>    +/
> }



More information about the Digitalmars-d mailing list