On Monday, 24 April 2017 at 22:46:18 UTC, Andrei Alexandrescu wrote:
On 04/24/2017 04:23 PM, ag0aep6g wrote:
On 04/24/2017 08:48 PM, Stanislav Blinov wrote:
Speaking of const violation and UB, std.algorithm.mutation.move seems to
violate const without remorse:

Yup. Even in @safe code, which is a bug.
https://issues.dlang.org/show_bug.cgi?id=15315

Should fail in all situations, thanks for reporting.

So, basically any type with const/immutable members effectively becomes immovable?

There should be ways to do this easier, i.e. add a forward() function to std.algorithm.mutation. Contributions are welcome!

Ah, thanks for the hint. There actually is one in std.functional, but it's not designed to handle one-argument situations well (returns a tuple instead of forwarding the argument). This works:

import std.algorithm.mutation : move;

template forward(args...)
{
    import std.meta;

    static if (args.length)
    {
        static if (__traits(isRef, args[0]))
            alias fwd = args[0];
        else
            @property fwd() { return move(args[0]); }

        static if (args.length == 1)
            alias forward = fwd;
        else
            alias forward = AliasSeq!(fwd, forward!(args[1..$]));
    }
    else alias forward = AliasSeq!();
}

struct Y
{
    private X _x;
    this()(auto ref X x)
    {
        _x = forward!x;
    }
}

struct X {
    this(this) { writeln("copy"); }
}

void main()
{
    X x;
    Y y = x;        // outputs "copy"
    Y y2 = move(x); // moves, postblit not called
}

I'll make the PR.

Reply via email to