import std.range: isInputRange;
struct Difference(alias pred = "a", R1, R2)
if (isInputRange!R1 && isInputRange!R2)
import std.range: ElementType;
import std.functional: unaryFun, binaryFun;
enum isUnary = is(typeof(unaryFun!pred(ElementType!R1.init)));
alias transform = unaryFun!pred;
alias compare = binaryFun!"a == b";
alias transform = unaryFun!"a";
alias compare = binaryFun!pred;
private void moveToNextElement() {
import std.traits: TemplateOf;
import std.range: SortedRange;
enum r1Sorted = __traits(isSame, TemplateOf!(R1), SortedRange);
enum r2Sorted = __traits(isSame, TemplateOf!(R2), SortedRange);
static if (r1Sorted && r2Sorted)
bool empty() @property { return true; }
auto front() @property { return 0; }
auto difference(alias pred = "a", R1, R2)(R1 r1, R2 r2)
if (isInputRange!R1 && isInputRange!R2)
import std.range: ElementType;
import std.algorithm: sort;
import std.traits: TemplateOf;
= is(TemplateOf!(typeof(r1)) == SortedRange);
= is(TemplateOf!(typeof(r2)) == SortedRange);
return Difference!(pred, typeof(i1), typeof(i2))(i1, i2);
[1, 2, 3].difference([1, 2, 3]).writeln;