Movable resource handles
Matt Elkins via Digitalmars-d
digitalmars-d at puremagic.com
Wed Jan 27 19:02:34 PST 2016
On Thursday, 28 January 2016 at 00:14:18 UTC, ZombineDev wrote:
> On Wednesday, 27 January 2016 at 23:20:27 UTC, Matt Elkins
> wrote:
>> [...]
>
> In my project I have something like this:
>
> ```
> import std.experimental.allocator :
> make, dispose;
> import std.algorithm.mutation :
> move, moveEmplace;
>
> struct UniqueRef(T, alias allocator)
> {
> private T* handle;
>
> // I use a modified
> // version ofstd.typecons.Proxy.
> // Forwards most operations
> // except for opAssign to
> // *handle;
> mixin Proxy!handle;
>
> this(Args...)(auto ref Args args)
> {
> this.handle =
> allocator.make!T(args);
> }
>
> // Should work after Phobos PR 3956
> // is merged.
> // @disable this();
>
> // Necessarry to ensure unique
> // ownership.
> @disable this(this);
>
> // Steels the handle from
> // lvalues & rvalues
> void opAssign()
> (auto ref typeof(this) other)
> {
> destroy(this);
> this.handle =
> moveEmplace(other.handle);
> }
>
> ~this()
> {
> if (this.handle is null)
> return;
>
> allocator.dispose(this.handle);
> this.handle = null;
> }
> }
>
> // Initialation
> auto a = UniqueRed!int(41);
>
> // Transparent forwarding
> assert (a.handle !is null);
> assert (a == 41);
> assert (++a == 42);
>
> // Unique ownership
> // auto b = a; doesn't compile
>
> // Move semantics
> auto b = move(a);
> assert (b == 42);
> assert (a.handle is null);
>
> // Consumption
> void useHandle()
> (auto ref UniqueRef!int h)
> {
> UniqueRef!(int)[] arrayOfHandles =
> getArr();
>
> arrayOfHandles[0] = move(h);
> }
>
> // Transfer ownership
> useHandle(b);
>
> // Accepts rvalues
> useHandle(UniqueRef!int(7));
>
> void borrow(const ref UniqueRef!int h)
> {
> import std.stdio;
> int val = h + 0;
> writeln(val);
> }
>
> auto d = UniqueRef!int(12);
> borrow(d);
> assert (d.handle !is null);
>
> // and so on...
> ```
>
> I don't know if it's 100% memory safe, but for me it works good
> enough. Sorry if there are typos/mistakes, I'm writting on a
> phone.
Thanks for the response! I learned more about D just from
studying this example. However, I'm not sure that this works for
what I need. For example, if I want to move one of these handles
into an array:
///// Not sure how to tag this as a code block on the forum /////
alias UR = UniqueRef!(int, theAllocator);
auto a = UR(41);
UR[] handles;
// Both of the following lines yield:
// Error: ... UniqueRef is not copyable because it is annotated
with @disable
// handles ~= move(a);
// handles ~= a;
//// End code block ////
This is essentially the same error I get on my attempts to
implement these semantics, as well.
More information about the Digitalmars-d
mailing list