June 04, 2023 [Issue 23960] New: opApply and opApplyReverse should work with named mixin templates in aggregates | ||||
---|---|---|---|---|
| ||||
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@puremagic.com Reporter: witold.baryluk+d@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). -- |
Copyright © 1999-2021 by the D Language Foundation