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