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