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

Reply via email to