import std.stdio;
import std.conv : to;
class Ref(T) {
private:
T _obj;
public:
this(T obj) {
assert(obj !is null);
this._obj = obj;
}
invariant() {
assert(obj !is null);
}
@property
inout(T) GetObj() inout {
return this._obj;
}
alias GetObj this;
}
mixin template TRef(Type) {
private:
Ref!(Type) _reference;
void InitRef() {
this._reference = new Ref!(Type)(this);
}
public:
@property
inout(Ref!(Type)) GetRef() inout {
return this._reference;
}
}
class Foo {
private:
string _msg;
public:
mixin TRef!(Foo);
alias GetRef this;
this(string msg) {
InitRef();
this.Set(msg);
}
void Set(string msg) {
this._msg = msg;
}
void echo() const {
writeln(this._msg);
}
}
void foo(Foo f) {
f.echo();
}
void bar(Ref!(Foo) rf) {
rf.echo();
writeln("----");
Foo f = rf;
f.echo();
}
void main() {
Foo f = new Foo("foobar");
foo(f);
bar(f);
}