Hi,
I would have thought that RefCounted!(T, RefCountedAutoInitialize.no) is to be used in place T* when I want reference counting instead of the usual garbage collection (or manual allocation). Perhaps this is wrong?
If I am correct what am I doing wrong here?
(Sorry for two space squashed style).
import std.stdio;
import std.typecons;
struct Node(T) {
RefCounted!(Node!T, RefCountedAutoInitialize.no) next;
T val;
}
struct List(T) {
RefCounted!(Node!T, RefCountedAutoInitialize.no) head;
bool empty() { return head.refCountedStore.isInitialized; }
T front() { return head.val; }
void popFront() { head = head.next; }
typeof(this) save() { return typeof(this)(head); }
}
void main() {
List!long l;
}
I also tried my own implementation but that is not working (since not everything is being freed) and probably
relies on undefined behavior with my casting away inout, which I did because
otherwise the compiler kept giving me errors about not being able to generate a copy constructor for List.
import std.stdio;
import core.stdc.stdlib;
private struct RefCountedPointer(T) {
static struct Payload(T) {
long cnt=1;
T val;
}
Payload!T* ptr;
this(T x) {
ptr = cast(Payload!T*) calloc(0,Payload!T.sizeof);
*ptr = Payload!T(1,x);
}
~this() {
if(ptr==null) { return; }
(*ptr).cnt--;
if((*ptr).cnt == 0) {
ptr.val.destroy();
free(ptr);
}
}
@disable this(ref return scope immutable(typeof(this)) rhs);
this(ref return scope inout(typeof(this)) rhs) {
ptr = cast(Payload!T*) rhs.ptr;
if(ptr==null) { return; }
ptr.cnt++;
}
void opAssign(typeof(this) rhs) {
if(this.ptr!=null) { (*this.ptr).cnt--; }
this.ptr = rhs.ptr;
if(this.ptr!=null) { (*this.ptr).cnt++; }
}
bool isNull() { return ptr==null; }
ref auto dref() { assert(!isNull); return (*ptr).val; }
}
private struct Node(T) {
RefCountedPointer!(Node!T) next;
T val;
}
struct List(T) {
private RefCountedPointer!(Node!T) head;
bool empty() { return head.isNull; }
T front() { return head.dref.val; }
void popFront() { head = head.dref.next; }
auto save() { return typeof(this)(head); }
auto insert(T x) {
head = RefCountedPointer!(Node!T)(Node!T(head,x));
}
}
void main() {
List!long list;
list.insert(8);
import std.stdio;
import core.stdc.stdlib;
private struct RefCountedPointer(T) {
static struct Payload(T) {
long cnt=1;
T val;
}
Payload!T* ptr;
this(T x) {
ptr = cast(Payload!T*) calloc(0,Payload!T.sizeof);
*ptr = Payload!T(1,x);
}
~this() {
if(ptr==null) { return; }
(*ptr).cnt--;
if((*ptr).cnt == 0) {
writeln("free");
ptr.val.destroy();
free(ptr);
}
}
@disable this(ref return scope immutable(typeof(this)) rhs);
this(ref return scope inout(typeof(this)) rhs) {
ptr = cast(Payload!T*) rhs.ptr;
if(ptr==null) { return; }
ptr.cnt++;
}
void opAssign(typeof(this) rhs) {
"here".writeln;
if(this.ptr!=null) { (*this.ptr).cnt--; }
this.ptr = rhs.ptr;
if(this.ptr!=null) { (*this.ptr).cnt++; }
}
bool isNull() { return ptr==null; }
ref auto dref() { assert(!isNull); return (*ptr).val; }
}
private struct Node(T) {
RefCountedPointer!(Node!T) next;
T val;
}
struct List(T) {
private RefCountedPointer!(Node!T) head;
bool empty() { return head.isNull; }
T front() { return head.dref.val; }
void popFront() { head = head.dref.next; }
auto save() { return typeof(this)(head); }
auto insert(T x) {
head = RefCountedPointer!(Node!T)(Node!T(head,x));
}
}
void main() {
List!long list;
list.insert(8);
import std.stdio;
import core.stdc.stdlib;
private struct RefCountedPointer(T) {
static struct Payload(T) {
long cnt=1;
T val;
}
Payload!T* ptr;
this(T x) {
ptr = cast(Payload!T*) calloc(0,Payload!T.sizeof);
*ptr = Payload!T(1,x);
}
~this() {
if(ptr==null) { return; }
(*ptr).cnt--;
if((*ptr).cnt == 0) {
writeln("free");
ptr.val.destroy();
free(ptr);
}
}
@disable this(ref return scope immutable(typeof(this)) rhs);
this(ref return scope inout(typeof(this)) rhs) {
ptr = cast(Payload!T*) rhs.ptr;
if(ptr==null) { return; }
ptr.cnt++;
}
void opAssign(typeof(this) rhs) {
"here".writeln;
if(this.ptr!=null) { (*this.ptr).cnt--; }
this.ptr = rhs.ptr;
if(this.ptr!=null) { (*this.ptr).cnt++; }
}
bool isNull() { return ptr==null; }
ref auto dref() { assert(!isNull); return (*ptr).val; }
}
private struct Node(T) {
RefCountedPointer!(Node!T) next;
T val;
}
struct List(T) {
private RefCountedPointer!(Node!T) head;
bool empty() { return head.isNull; }
T front() { return head.dref.val; }
void popFront() { head = head.dref.next; }
auto save() { return typeof(this)(head); }
auto insert(T x) {
head = RefCountedPointer!(Node!T)(Node!T(head,x));
}
}
void main() {
List!long list;
list.insert(8);
list.insert(7);
list.insert(6);
list.insert(5);
list.insert(4);
list.popFront;
list.writeln;
list.insert(4);
list.insert(3);
list.insert(2);
list.insert(1);
list.writeln;
}