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
}
+/
}