diff --git a/std/algorithm/iteration.d b/std/algorithm/iteration.d index a5d1e51bd..4cbf903ee 100644 --- a/std/algorithm/iteration.d +++ b/std/algorithm/iteration.d @@ -6427,7 +6427,9 @@ $(DDSUBLINK spec/type,integer-promotions, integral promotion)). A seed may be passed to `sum`. Not only will this seed be used as an initial value, but its type will override all the above, and determine the algorithm -and precision used for summation. +and precision used for summation. If a seed is not passed, one is created with +the value of `typeof(r.front + r.front)(0)`, or `typeof(r.front + r.front).zero` +if no constructor exists that takes an int. Note that these specialized summing algorithms execute more primitive operations than vanilla summation. Therefore, if in certain cases maximum speed is required @@ -6449,10 +6451,15 @@ if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front))) alias Seed = typeof(E.init + 0.0); //biggest of double/real else alias Seed = typeof(r.front + r.front); - static assert(is(typeof(Unqual!Seed(0))), - "Could not initiate an initial value for " ~ (Unqual!Seed).stringof - ~ ". Please supply an initial value manually."); - return sum(r, Unqual!Seed(0)); + static if (is(typeof(Unqual!Seed(0)))) + enum seedValue = Unqual!Seed(0); + else static if (is(typeof({ Unqual!Seed tmp = Seed.zero; }))) + enum Unqual!Seed seedValue = Seed.zero; + else + static assert(false, + "Could not initiate an initial value for " ~ (Unqual!Seed).stringof + ~ ". Please supply an initial value manually."); + return sum(r, seedValue); } /// ditto auto sum(R, E)(R r, E seed) @@ -6693,6 +6700,13 @@ private auto sumKahan(Result, R)(Result result, R r) assert(repeat(1.0, n).sum == n); } +// Issue 19525 +@safe unittest +{ + import std.datetime : Duration, minutes; + assert([1.minutes].sum() == 1.minutes); +} + /** Finds the mean (colloquially known as the average) of a range.