On Tuesday, 23 January 2018 at 14:17:26 UTC, Andrea Fontana wrote:
On Tuesday, 23 January 2018 at 12:39:12 UTC, Simen Kjærås wrote:
On Tuesday, 23 January 2018 at 12:12:42 UTC, Nicholas Wilson wrote:
On Tuesday, 23 January 2018 at 09:36:03 UTC, Simen Kjærås wrote:
Questions: Is a DIP required for this?

A DIP is required for language changes. So yes.

No language changes are proposed - this is all library code.

--
  Simen

It would be useful to have one or more short examples. Just to see what actually change in a common scenario.

Andrea

Your wish is my command. For the most part, the changes will require that instead of storing Unqual!Ts, use HeadMutable!Ts, and when assigning to a HeadMutable!T, remember to assign headMutable(rhs).

Here's a somewhat simplistic map function. As you can see, not a whole lot is changed - map passes head-mutable versions of its arguments to MapResult, and MapResult implements opHeadMutable(), otherwise everything is exactly as you'd expect.

import std.range;

auto map(alias fn, R)(R r) if (isInputRange!(HeadMutable!R))
{
    // Pass head-mutable versions to MapResult.
    return MapResult!(fn, HeadMutable!R)(headMutable(r));
}

struct MapResult(alias fn, R) if (isInputRange!R)
{
    R range;

    this(R rng)
    {
        range = rng;
    }

    @property
    auto front()
    {
        return fn(range.front);
    }

    void popFront()
    {
        range.popFront();
    }

    @property
    bool empty()
    {
        return range.empty;
    }

    // The only change to MapResult:
    auto opHeadMutable(this This)()
    {
        import std.traits : CopyTypeQualifiers;
return MapResult!(fn, HeadMutable!(CopyTypeQualifiers!(This, R)))(range);
    }
}


unittest
{
    import std.algorithm : equal;

    const a = [1,2,3,4].map!(v => v*2);
    assert(!isInputRange!(typeof(a)));

// Here, std.algorithm.map gives up, since a const MapResult is not // an input range, and calling Unqual on it doesn't give a sensible
    // result.
// HeadMutable makes this work, since the type system now knows how
    // to make a head-mutable version of the type.
    auto b = a.map!(v => v/2);

    assert(equal([1,2,3,4], b));
}

--
  Simen

Reply via email to