On Sunday, 31 January 2016 at 18:02:19 UTC, Matt Elkins wrote:
Here is the one I am using right now:

Actually, here is the whole module in case you are interested in the unittests/usage:

[code]
import std.algorithm;
import std.traits;

struct ResourceHandle(T, alias Deleter, T Default = T.init)
{
    // Constructors/Destructor
    this(in 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 T handle() const {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;
}

@nogc @safe nothrow unittest
{
    static uint destroyedCount;
    static uint lastDestroyed;
alias RH = ResourceHandle!(uint, (uint resource){if (resource != uint.init) {lastDestroyed = resource; ++destroyedCount;}});

    // Test basic resource cleanup
    assert(destroyedCount == 0);
    assert(lastDestroyed != 7);
    {auto handle0 = RH(7);}
    assert(destroyedCount == 1);
    assert(lastDestroyed == 7);

    // Test releasing
    {
        auto handle0 = RH(8);
        assert(handle0.handle == 8);
        assert(handle0.release() == 8);
        assert(handle0.handle == uint.init);
        assert(destroyedCount == 1);
        assert(lastDestroyed == 7);
    }
    assert(destroyedCount == 1);
    assert(lastDestroyed == 7);

    {
        // Test that copying and lvalue assignment are disabled
        auto handle0 = RH(5);
static assert (!__traits(compiles, {auto handle1 = handle0;})); static assert (!__traits(compiles, {RH handle1; handle1 = handle0;}));

        // Test that rvalue assignment works
        auto makeRH(uint value) {return RH(value);}
        handle0 = makeRH(3);
        assert(destroyedCount == 2);
        assert(lastDestroyed == 5);
    }
    assert(destroyedCount == 3);
    assert(lastDestroyed == 3);

    // Test setting in static array
    {
        RH[3] handles;
        handles[0] = RH(9);
        assert(destroyedCount == 3);
        assert(lastDestroyed == 3);
    }
    assert(destroyedCount == 4);
    assert(lastDestroyed == 9);

    // Test setting to resource directly
    {
        auto handle0 = RH(11);
        assert(destroyedCount == 4);
        assert(lastDestroyed == 9);
        assert(handle0.handle == 11);
        handle0.handle = 12;
        assert(destroyedCount == 5);
        assert(lastDestroyed == 11);
        assert(handle0.handle == 12);
    }
    assert(destroyedCount == 6);
    assert(lastDestroyed == 12);
}
[/code]

Reply via email to