Is it possible to forward rvalues through variadic templates?
Having to "move" the value for every layer is suboptimal.
What am I doing wrong?

----------

import std.algorithm : move;

void foo(Unique!Handle uniq)
{
    auto val = uniq.extract;
    assert(val._fd == 1);
    val.close();
}

void foo(Unique!Handle uniq, string)
{
    auto val = uniq.extract;
    assert(val._fd == 1);
    val.close();
}

version (none)
{
    void bar(Args...)(Args args)
    {
        foo(move(args)); // cannot forward variadic arguments ???
    }
}
else
{
    void bar(A0)(A0 a0)
    {
        foo(move(a0));
    }

    void bar(A0, A1)(A0 a0, A1 a1)
    {
        foo(move(a0), move(a1));
    }
}

void main()
{
    Unique!Handle uniq;

    uniq = Unique!Handle(Handle(1));
    assert(uniq._obj._fd == 1);
    bar(move(uniq));
    assert(uniq._obj._fd == 0);
    uniq = Unique!Handle(Handle(1));
    assert(uniq._obj._fd == 1);
    bar(move(uniq), "other arg");
    assert(uniq._obj._fd == 0);
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

struct Handle
{
    this(int fd)
    {
        _fd = fd;
        assert(_fd);
    }

    void close()
    {
        _fd = 0;
    }

    ~this()
    {
        assert(!_fd);
    }

    int _fd;
}

struct Unique(T)
{
    this()(auto ref T val) if(!__traits(isRef, val))
    {
        move(val, _obj);
    }

    this()(auto ref Unique!T val) if(!__traits(isRef, val))
    {
        move(val._obj, _obj);
    }

    @disable this(this);

    void opAssign(Unique val)
    {
        move(val._obj, _obj);
    }

    @property T extract()
    {
        return move(_obj);
    }

private:
    T _obj;
}

Reply via email to