On Sunday, 31 January 2016 at 19:34:43 UTC, maik klein wrote:
I recently asked a question about ownership semantics in D
https://stackoverflow.com/questions/35115702/how-do-i-express-ownership-semantics-in-d
But a few minutes ago I found an answer on SO that could
potentially explain a lot.
http://stackoverflow.com/a/35114945/944430
Sadly it has some pseudo code in it so I implemented it with
std.experimental.allocator
struct UniquePtr(T) {
import std.experimental.allocator;
private T* ptr = null;
@disable this(this); // This disables both copy
construction and opAssign
this(Args...)(auto ref Args args){
ptr = theAllocator.make!T(args);
}
~this() {
theAllocator.dispose(ptr);
}
inout(T)* get() inout {
return ptr;
}
// Move operations
this(UniquePtr!T that) {
this.ptr = that.ptr;
that.ptr = null;
}
ref UniquePtr!T opAssign(UniquePtr!T that) { // Notice no
"ref" on "that"
import std.algorithm.mutation;
swap(this.ptr, that.ptr); // We change it anyways,
because it's a temporary
return this;
}
}
Is this code correct? One problem that I have is
UniquePtr!int[int] map;
will result in a memory exception and I have no idea why.
Interesting. It is something in the dispose, because I changed
the destructor to:
[code]
~this()
{
writeln("Disposing ", ptr, " for this ", &this);
theAllocator.dispose(ptr);
writeln("Disposed ", ptr, " for this ", &this);
}
[/code]
And I only get the disposing line, not the disposed.
I tried taking my ResourceHandle struct that I pasted to you in
the other thread earlier and doing the same operation with it (I
had to change a const to inout and remove an extraneous 'in'
marker to make it compile):
[code]
alias RH = ResourceHandle!(int*, (int* ptr)
{theAllocator.dispose(ptr);});
RH[int] otherMap;
otherMap[3] = RH(theAllocator.make!int(5));
[/code]
and I get the same invalid memory operation. With either class, I
avoid the error if I use a stack member or a static array, but
with the associative array or just a dynamic array I get the
problem.
To see it in a dynamic array:
[code]
auto map = new UniquePtr!int[1];
map[0] = UniquePtr!int(5);
[/code]
Not sure what it is...still playing with it.