A Refcounted Array Type
Walter Bright via Digitalmars-d
digitalmars-d at puremagic.com
Mon Feb 23 14:15:46 PST 2015
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