Bug 23319 – std.range.Generator does not work with non-mutable elements
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P3
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-09-02T16:44:38Z
Last change time
2022-12-05T14:24:45Z
Keywords
pull
Assigned to
No Owner
Creator
Ali Cehreli
Comments
Comment #0 by acehreli — 2022-09-02T16:44:38Z
The following code is expected to work at least with types having no indirections e.g. the value of an enum.
And it should work for immutable as well.
import std.range : generate;
void main() {
generate!(() => const(int)(42));
}
/usr/include/dlang/dmd/std/range/package.d(3808): Error: cannot modify `const` expression `this.elem_`
/usr/include/dlang/dmd/std/range/package.d(3767): Error: template instance `std.range.primitives.isInputRange!(Generator!(function () pure nothrow @nogc @safe => 42))` error instantiating
/usr/include/dlang/dmd/std/range/package.d(3767): while evaluating: `static assert(isInputRange!(Generator!(function () pure nothrow @nogc @safe => 42)))`
/usr/include/dlang/dmd/std/range/package.d(3723): Error: template instance `std.range.Generator!(function () pure nothrow @nogc @safe => 42)` error instantiating
A fix would be to use Unqual inside std.range.Generator (but of course guarding with std.traits.hasIndirections first):
Unqual!(ReturnType!fun) elem_;
Comment #1 by salihdb — 2022-12-05T01:25:33Z
This can be an alternative:
template gen (alias fn) {
struct GenRes { //
import std.traits;
ReturnType!fn func;
enum empty = false;
auto front() { return func; }
void popFront() { func = fn(); }
}
GenRes gen() {
auto gen = GenRes();
gen.popFront();
return gen;
}
} unittest {
import std.range, std.random : uniform;
import std.stdio;
enum E : char { False = 48, True }
auto r = gen!(function char() => uniform!E);
r.take(12).writefln!"[%s]";
}
Sources:
https://forum.dlang.org/post/[email protected]https://forum.dlang.org/post/[email protected]
Comment #2 by acehreli — 2022-12-05T01:37:51Z
Thank you for an alternative but it has the same limitation, right?
gen!(() => const(int)(42));
deneme.d(4431): Error: cannot modify `const` expression `this.func`
deneme.d(4448): Error: template instance `deneme.gen!(function () pure nothrow @nogc @safe => 42)` error instantiating
Line 4431 is this one:
void popFront() { func = fn(); }
Please note that this bug report is about std.range.Generator. No hand-written code can magically fix it.
Comment #3 by dlang-bot — 2022-12-05T12:43:20Z
@RazvanN7 created dlang/phobos pull request #8644 "Fix Issue 23319 - std.range.Generator does not work with non-mutable elements" fixing this issue:
- Fix Issue 23319 - std.range.Generator does not work with non-mutable elements
https://github.com/dlang/phobos/pull/8644
Comment #4 by dlang-bot — 2022-12-05T14:24:45Z
dlang/phobos pull request #8644 "Fix Issue 23319 - std.range.Generator does not work with non-mutable elements" was merged into master:
- af267271c6fb4c203435ae8e4d45cf9edde9df5e by RazvanN7:
Fix Issue 23319 - std.range.Generator does not work with non-mutable elements
https://github.com/dlang/phobos/pull/8644