Skip to content

Commit d6a3c5e

Browse files
authored
Make sum work with const slices (#455)
* Make sum work with const slices * Update Summator.put to be implicitly convertible to const, meaning it can allow immutable too * Address sum review, make separate overloads for non-mutable Range * Fixup sum with const ranges
1 parent d20245f commit d6a3c5e

File tree

1 file changed

+83
-5
lines changed

1 file changed

+83
-5
lines changed

source/mir/math/sum.d

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,7 @@ template sum(F, Summation summation = Summation.appropriate)
17431743
{
17441744
///
17451745
template sum(Range)
1746-
if (isIterable!Range)
1746+
if (isIterable!Range && isMutable!Range)
17471747
{
17481748
import core.lifetime: move;
17491749

@@ -1826,6 +1826,23 @@ template sum(F, Summation summation = Summation.appropriate)
18261826
}
18271827
}
18281828

1829+
///
1830+
template sum(Range)
1831+
if (isIterable!Range && !isMutable!Range)
1832+
{
1833+
///
1834+
F sum(Range r)
1835+
{
1836+
return .sum!(F, summation)(r.lightConst);
1837+
}
1838+
1839+
///
1840+
F sum(Range r, F seed)
1841+
{
1842+
return .sum!(F, summation)(r.lightConst, seed);
1843+
}
1844+
}
1845+
18291846
///
18301847
F sum(scope const F[] r...)
18311848
{
@@ -1847,19 +1864,35 @@ template sum(Summation summation = Summation.appropriate)
18471864
{
18481865
///
18491866
sumType!Range sum(Range)(Range r)
1850-
if (isIterable!Range)
1867+
if (isIterable!Range && isMutable!Range)
18511868
{
18521869
import core.lifetime: move;
18531870
alias F = typeof(return);
1854-
return .sum!(F, ResolveSummationType!(summation, Range, F))(r.move);
1871+
alias s = .sum!(F, ResolveSummationType!(summation, Range, F));
1872+
return s(r.move);
18551873
}
18561874

18571875
///
18581876
F sum(Range, F)(Range r, F seed)
1859-
if (isIterable!Range)
1877+
if (isIterable!Range && isMutable!Range)
18601878
{
18611879
import core.lifetime: move;
1862-
return .sum!(F, ResolveSummationType!(summation, Range, F))(r.move, seed);
1880+
alias s = .sum!(F, ResolveSummationType!(summation, Range, F));
1881+
return s(r.move, seed);
1882+
}
1883+
1884+
///
1885+
sumType!Range sum(Range)(Range r)
1886+
if (isIterable!Range && !isMutable!Range)
1887+
{
1888+
return .sum!(typeof(return), summation)(r.lightConst);
1889+
}
1890+
1891+
///
1892+
F sum(Range, F)(Range r, F seed)
1893+
if (isIterable!Range && !isMutable!Range)
1894+
{
1895+
return .sum!(F, summation)(r.lightConst, seed);
18631896
}
18641897

18651898
///
@@ -2112,6 +2145,51 @@ unittest
21122145
}
21132146
}
21142147

2148+
// Confirm sum works for Slice!(const(double)*, 1))
2149+
version(mir_test)
2150+
@safe pure nothrow
2151+
unittest
2152+
{
2153+
import mir.ndslice.slice: sliced;
2154+
double[] x = [1.0, 2, 3];
2155+
auto y = x.sliced;
2156+
auto z = y.toConst;
2157+
assert(z.sum == 6);
2158+
assert(z.sum(0.0) == 6);
2159+
assert(z.sum!double == 6);
2160+
assert(z.sum!double(0.0) == 6);
2161+
}
2162+
2163+
// Confirm sum works for const(Slice!(double*, 1))
2164+
version(mir_test)
2165+
@safe pure nothrow
2166+
unittest
2167+
{
2168+
import mir.ndslice.slice: sliced;
2169+
double[] x = [1.0, 2, 3];
2170+
auto y = x.sliced;
2171+
const z = y;
2172+
assert(z.sum == 6);
2173+
assert(z.sum(0.0) == 6);
2174+
assert(z.sum!double == 6);
2175+
assert(z.sum!double(0.0) == 6);
2176+
}
2177+
2178+
// Confirm sum works for const(Slice!(const(double)*, 1))
2179+
version(mir_test)
2180+
@safe pure nothrow
2181+
unittest
2182+
{
2183+
import mir.ndslice.slice: sliced;
2184+
double[] x = [1.0, 2, 3];
2185+
auto y = x.sliced;
2186+
const z = y.toConst;
2187+
assert(z.sum == 6);
2188+
assert(z.sum(0.0) == 6);
2189+
assert(z.sum!double == 6);
2190+
assert(z.sum!double(0.0) == 6);
2191+
}
2192+
21152193
package(mir)
21162194
template ResolveSummationType(Summation summation, Range, F)
21172195
{

0 commit comments

Comments
 (0)