On Thu, 27 Feb 2014 12:32:44 -0500, H. S. Teoh <[email protected]>
wrote:
Actually, now that I think about it, can't we just make ByLine lazily
constructed? It's already a wrapper around ByLineImpl anyway (since it's
being refcounted), so why not just make the wrapper create ByLineImpl
only when you actually attempt to use it? That would solve the problem:
you can call ByLine but it won't block until ByLineImpl is actually
created, which is the first time you call ByLine.empty.
I think this isn't any different than making ByLine.empty cache the first
line.
My solution is basically this:
struct LazyConstructedRange(R)
{
R r;
bool isConstructed = false;
R delegate() _ctor;
this(R delegate() ctor) {_ctor = ctor;}
ref R get() {
if(!isConstructed) { r = _ctor(); isConstructed = true;}
return r;
}
alias get this;
}
Basically, we're not constructing on first call to empty, but first call
to *anything*. Actually, this kind of a solution would be better that what
I came up with, because the object itself is a range instead of a delegate
(satisfies, for instance, isInputRange and isIterable, whereas the
delegate does not), and you don't need the static if like I wrote. Any
additional usage of the delegate in my original solution creates a copy of
the range, but the above would only construct it once.
-Steve