[Issue 23960] New: opApply and opApplyReverse should work with named mixin templates in aggregates
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sun Jun 4 09:19:46 UTC 2023
https://issues.dlang.org/show_bug.cgi?id=23960
Issue ID: 23960
Summary: opApply and opApplyReverse should work with named
mixin templates in aggregates
Product: D
Version: D2
Hardware: x86
OS: Linux
Status: NEW
Severity: enhancement
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: witold.baryluk+d at gmail.com
https://godbolt.org/z/9qcGnWz8G
template M(int value) {
int opApply(scope int delegate(ref int i) dg) {
int v = value;
return dg(v);
}
}
struct S {
mixin M!5 m1;
mixin M!6 m2;
}
void main() {
import std.stdio : writefln;
S s;
foreach (i; s.m1) {
writefln("%d", i);
}
}
should compile and print 5.
But it does not compile:
dmd 2.094:
<source>(16): Error: expression has no value
Compiler returned: 1
gdc trunk (14.0.0 20230530):
<source>:16:3: error: invalid 'foreach' aggregate 's.mixin M!5 m1;
' of type 'void'
16 | foreach (i; s.m1) {
| ^
Compiler returned: 1
I discovered this problem when implementing intrusive circular double-linked
list, which I have two per Node (each node is a member of two intrusive
circular double-linked lists, each with prev and next pointers), where I wanted
to use opApply and opApplyReverse to traverse each list independently on
demand. I am implementation DLX algorithm (Knuth's Algorithm X brute force
depth-first backtracking algorithm for finding solutions to exact cover problem
using dancing links technique).
For opApply, it can be worked around using a delegate:
void main() {
import std.stdio : writefln;
S s;
foreach (i; &s.m1.opApply) {
writefln("%d", i);
}
}
but one cannot use `foreach_revserse` on delegates, instead one needs to use
`foreach` with `&s.m1.opApplyReverse` which is less readable and restricts
usage. It also does not work well if there are many opApply and/or
opApplyReverse overloads, possibly templated, as then one cannot form delegate
without explicit instantiation.
Of course if there is only one unnamed mixin, it should be possible to still
use it via class/struct scope:
foreach (i; s), which will automatically find opApply
and if there are multiple, either ambiguity reported, or aliases uses to
provide an overload set. (This is already implemented in current D version).
--
More information about the Digitalmars-d-bugs
mailing list