basics
import nxt.dynamic_array : SA = DynamicArray; import std.traits : isIterable; import std.range.primitives : isInputRange; alias C = SA!int; auto cs = C([11, 13, 15, 17].s).intoUniqueRange; auto cs2 = cs.dup; assert(cs !is cs2); assert(cs == cs2); cs2.popFront(); assert(cs2.length == 3); assert(cs != cs2); static assert(isInputRange!(typeof(cs))); static assert(isIterable!(typeof(cs))); assert(!cs.empty); assert(cs.length == 4); assert(cs.front == 11); assert(cs.back == 17); cs.popFront(); assert(cs.length == 3); assert(cs.front == 13); assert(cs.back == 17); cs.popBack(); assert(cs.length == 2); assert(cs.front == 13); assert(cs.back == 15); assert(cs.frontPop() == 13); assert(cs.length == 1); assert(cs.front == 15); assert(cs.back == 15); assert(cs.backPop() == 15); assert(cs.length == 0); assert(cs.empty);
combined with Phobos ranges
import nxt.dynamic_array : SA = DynamicArray; alias C = SA!int; assert(C([11, 13, 15, 17].s) .intoUniqueRange() .filterUnique!(_ => _ != 11) .mapUnique!(_ => 2*_) .equal([2*13, 2*15, 2*17]));
A generator is a range which owns its state (typically a non-reference counted container).