Fantastic work, thanks! I'll look into more detail tomorrow, but it looks good so far. Just added a function helper and made the struct typed:
import std.array; import std.range; struct EquivalentElements(T) { T range; T front_; this(T range) { this.range = range; this.front_ = popEqualFront(this.range); } bool empty() { return front_.empty; } T front() { return front_; } void popFront() { this.front_ = popEqualFront(this.range); } private T popEqualFront(ref T range) { T front; if (!range.empty) { do { front ~= range[0]; range = range[1..$]; } while (!range.empty && (front[$-1] == range[0])); } return front; } } EquivalentElements!(Range) equivalentElements(Range)(Range r) { return typeof(return)(r); } // test void main() { foreach (elem; equivalentElements([1, 1, 2, 3, 4, 4])) { writeln(elem); } }