On Thursday, 27 February 2014 at 16:10:34 UTC, Adam D. Ruppe
wrote:
On Thursday, 27 February 2014 at 14:37:14 UTC, Szymon Gatner
wrote:
They actually don't have all the necessary features in D
afaiu. They do have value semantics but can't represent
uniqueness because of missing move d-tor.
struct MovingStruct {
@disable this(this);
typeof(this) release() {
auto p = this.payload;
this.payload = null;
return typeof(this)(p);
}
}
That does moving via an explicit release call which is
statically forced upon you by the disabled copy.
MovingStruct s = some_payload;
// MovingStruct s2 = s; // compile error
MovingStruct s2 = s.release;
assert(s.payload is null); // passes
assert(s2.payload is some_payload); // we good
You can also easily do structs with reference semantics:
struct RefStruct {
private struct Impl {
// implementation here
}
Impl* payload;
alias payload this;
}
RefStruct is now just a thin wrapper over a pointer and thus
inherits the pointer's semantics.
You can add a destructor to RefStruct to free it
deterministically with RAII as well. To avoid double free, you
can use the move technique or refcounting:
struct RefCountingStruct {
private struct Impl {
// implementation here
int refcount;
}
Impl* payload;
alias payload this;
@disable this(); // disable default constructor to force
factory
static RefCountingStruct create() {
RefCountingStruct t = void;
t.payload = new Impl();
t.payload.refcount = 1;
return t;
}
this(this) { if(payload !is null) payload.refcount++; }
~this() {
if(payload !is null) {
payload.refcount--;
if(payload.refcount == 0)
whatever_free(payload);
}
}
}
i wish my book was out but it is still only half done... but i
wrote a chapter with like eight different struct tricks like
this. structs rock.
Wow, that is pretty great stuff. Bit verbose, but gets the job
done. Is there a way to factor it out for reuse? As a mixin
probably? Thanks! Will surely try this. And I want your book.