On Friday, 13 October 2017 at 19:28:03 UTC, Steven Schveighoffer wrote:

This wouldn't help, sum is in phobos, Duration in druntime.

The answer is that sum shouldn't be too clever. IMO, initializing to 0 should be only done if the type's .init value doesn't match 0. Since only floating points and char/wchar/dchar do this, just do the Seed(0) for those, else use Seed.init.

I take the last part back a bit. Some custom types may default to NaN-like values, so Seed(0) is necessary.

What should happen is that sum should test if Seed(0) is viable, and if not, use Seed.init.

-Steve

Ah, I see. Something like:

private enum bool canZeroConstruct(R) = is(typeof(R(0)) == R);

auto sum(R)(R r)
if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front)))
{
    import std.algorithm : sum;
    alias E = Unqual!(ElementType!R);
    static if (isFloatingPoint!E)
alias Seed = typeof(E.init + 0.0); //biggest of double/real
    else
        alias Seed = typeof(r.front + r.front);
    static if (canZeroConstruct!E)
        return sum(r, Unqual!Seed(0));
    else
        return sum(r, Unqual!Seed.init);
}

Reply via email to