On Wednesday, 8 February 2023 at 08:47:45 UTC, tsbockman wrote:
>(It may be possible to fix it with changes to std.algorithm.filter
, though.)
This compiles and runs without error for me:
void main() @safe {
auto mb = MBuf();
auto vr = VRes!X();
foreach(c; vr.errors)
mb.write(c);
}
struct X { }
struct MBuf {
const(ubyte)[] _bufferList;
void write(Buffers...)(Buffers buffers) {
foreach (buffer; buffers) { }
}
}
struct VErr { string m; }
struct VRes(Data) {
VErr[Data.tupleof.length] _errors;
auto errors() {
return _errors[].filter!(e => e.m);
}
}
auto filter(alias predicate, Element)(return Element[] range) {
static struct Filtered {
private Element[] range;
this(return inout(Element)[] range) scope inout pure @safe {
this.range = filterFront(range);
}
bool empty() scope const pure @safe {
return range.length == 0; }
ref inout(Element) front() scope inout pure @safe {
return range[0]; }
void popFront() scope pure @safe {
range = filterFront(range[1 .. $]); }
static inout(Element)[] filterFront(return inout(Element)[] range) pure @safe {
while(true) {
if(range.length == 0 || predicate(range[0]))
return range;
range = range[1 .. $];
}
}
}
return Filtered(range);
}
@safe unittest {
const int[8] ns = [ 0, 1, 2, 3, 4, 5, 6, 7 ];
const int[4] odds = [ 1, 3, 5, 7 ];
size_t o = 0;
foreach(n; ns.filter!(n => n % 2 == 1)) {
assert(o < odds.length);
assert(n == odds[o]);
++o;
}
assert(o == odds.length);
}
Perhaps there is a bug or unnecessary restriction somewhere in std.algorithm.filter
's API?