😁
Try the 2nd usage, D is a very flexible language; moves towards
perfection!
```d
struct Sarma {
int i;
// mixin DownRange;
}
struct Foo(T) {
int[] array;
// 1. USAGE
auto opApply(scope int delegate(T) dg) {
foreach (ref e; array)
{
auto result = dg(T(e));
}
return 0;
}
auto opApply(scope // 2. USAGE
int delegate(size_t, int, ref int) dg) {
int count;
foreach (i, ref e; array)
{
e *= 15;
++count;
auto result = dg(i, count, e);
}
return 0;
}
}
import std.stdio;
void main()
{
auto foo = Foo!Sarma( [2, 4, 6] );
foreach (Sarma e; foo)
{
e.write(" ");
}
writeln;
foreach (i, s, ref e; foo)
{
s.writef!"counter = %s, ";
i.writeln(": ", e++);
}
foo.array.writeln;
}
template DownRange() {
bool empty() { return i <= 0; }
auto front() { return i; }
void popFront() { --i; }
}
```
It may be explained in specific documentation (on 12.11.11).
https://dlang.org/spec/statement.html#foreach_over_arrays
SDB@79