So I thought this might work:

struct MaybeEmpty(R) if (isInputRange!R) {
  private bool _isEmpty;
  private R    _input;

  alias _input this;

  this(bool isEmpty, R input) {
    _input = input;
    _isEmpty = isEmpty;
  }

  @property bool empty() {
    return _isEmpty || _input.empty;
  }
}

auto maybeEmpty(R)(bool empty, R input = R.init) if (isInputRange!R) {
  return MaybeEmpty!R(empty, input);
}

It's kind of ugly, but it can be used like:

  auto a = maybeEmpty!MyRange(true);
  auto b = maybeEmpty!MyRange(false, actualRange);
  static assert(is(typeof(a) == typeof(b)));

However, it fails the input range test:

static assert(isInputRange!MyRange); //pass
static assert(isInputRange!(typeof(a))); // fail

But it seems to be something weird with cross-module template instantiation. If I replace `import std.range` with a copy-paste of `isInputRange`, the above passes.

Either that or I'm doing something stupid because I'vebeen staring at this too long.

I'm wondering if the isInputRange thing is a bug, so here's a gist if anyone wants to play with it:
https://gist.github.com/rcorre/7a62395c53baf3c0bfbc

Reply via email to