On Thursday, 4 February 2016 at 01:26:55 UTC, Andrei Alexandrescu wrote:
On 02/03/2016 07:48 PM, Matt Elkins wrote:
This [apparent] lack of clean move semantics

I very much wish there was a quick summary. I figure you've seen std.algorithm.move. What's missing? -- Andrei

Apologies, should have summarized. The issue I've been focused on has been emulating C++'s std::unique_ptr for the purposes of handling system resources which need explicit cleanup and which are not copyable (or for which I want to disallow copying for whatever reason). I want to still be able to move around my handles to these resources, so long as the single-owner aspect is maintained, and I want the wrapper to have minimal overhead (so for example std.typecons.Unique is out, since it appears to require the heap one way or another); in essence, I want std::unique_ptr. It is quite possible that this is doable, but if so the solution eludes me. Here is what I have so far:

[code]
import std.algorithm;

struct ResourceHandle(T, alias Deleter, T Default = T.init)
{
    // Constructors/Destructor
    this(T handle) {m_handle = handle;}
    @disable this(this);
    ~this() {Deleter(m_handle);}

    // Operators
    @disable void opAssign(ref ResourceHandle lvalue);
ref ResourceHandle opAssign(ResourceHandle rvalue) {swap(m_handle, rvalue.m_handle); return this;}

    // Methods
    @property inout(T) handle() inout {return m_handle;}
@property T handle(T handle) {Deleter(m_handle); m_handle = handle; return m_handle;} T release() {T result = m_handle; m_handle = Default; return result;}

    private:
        T m_handle = Default;
}
[/code]

This seems to cover most of my bases, but I still can't do things like this:

[code]
unittest
{
    alias RH = ResourceHandle!(uint, (uint) {});
    RH[] handles;
handles ~= RH(5); // Compile error: ResourceHandle is not copyable because it is annotated with @disable
}
[/code]

One person on the forums suggested that this might be a compiler bug (and referred me to a maybe-related bug report from 2011), but it also might not. This seems to have similar practical functionality to std::auto_ptr; works reasonably well for passing around individual instances, but gets iffy when you want to put it into a container. Incidentally, I -am- able to do this:

[code]
unittest
{
    alias RH = ResourceHandle!(uint, (uint) {});

    RH[] handles;
    ++handles.length;
    handles[$ - 1] = RH(5);
}
[/code]

This has become my effective workaround, but it isn't terribly clean and may not scale to other kinds of data structures (or it may, haven't thought it through). Of course, I'm a D newbie and could well just not be seeing the right way to define ResourceHandle.

Sorry for all the C++ allusions to explain my intent. Then again, I'm not terribly worried that the author of MC++D won't follow them :).

Reply via email to