Hi,
I was reading the source of std.algorithm cache and saw some code that didn't make sense to me with a comment indexing the bug report. Could anyone help to understand if this code is really necessary (meaning I have some misconception) or is it a work around a compiler bug. Here is the code simplified down as much as I could:
import std.range.primitives;
import std.traits;
struct _Cache(R)
{
private
{
alias UE = Unqual!(ElementType!R);
R source;
UE caches;
}
this(R range)
{
source = range;
if (!range.empty)
{
caches = source.front;
}/* else { //Uncomment "else" to fix broken version (see below)
caches = UE.init;
}*/
}
}
struct _ConstructorlessCache(R) {
private
{
alias UE = Unqual!(ElementType!R);
R source;
UE caches;
}
}
auto constructorlessCache(Range)(Range range) {
auto ret = _ConstructorlessCache!Range(range);
if (!range.empty)
{
ret.caches = range.front;
}
return ret;
}
auto cache(Range)(Range range) {
return _Cache!(Range)(range);
}
auto map(alias fun, Range)(Range range) {
return MapResult!(fun,Range)(range);
}
struct MapResult(alias fun, Range)
{
alias R = Unqual!Range;
R _input;
bool empty() { return _input.empty; }
auto ref front() { return fun(_input.front); }
}
void main() {
/* Won't compile unless part near top is uncommented. Gives:
onlineapp.d(21): Error: one path skips field `caches`
onlineapp.d(75): Error: template instance `onlineapp.cache!(MapResult!(__lambda1, int[]))` error instantiating
*/
//[1].map!(x=>[x].map!(y=>y)).cache;
//What seems to be essentially the same code compiles fine
[1].map!(x=>[x].map!(y=>y)).constructorlessCache;
}