How much r was actually advanced, which may be less than n if r did not have at least n elements.
int[] a = [ 1, 2, 3, 4, 5 ]; a.popFrontN(2); assert(a == [ 3, 4, 5 ]); a.popFrontN(7); assert(a == [ ]);
import std.algorithm.comparison : equal; import std.range : iota; auto LL = iota(1L, 7L); auto r = popFrontN(LL, 2); assert(equal(LL, [3L, 4L, 5L, 6L])); assert(r == 2);
int[] a = [ 1, 2, 3, 4, 5 ]; a.popBackN(2); assert(a == [ 1, 2, 3 ]); a.popBackN(7); assert(a == [ ]);
import std.algorithm.comparison : equal; import std.range : iota; auto LL = iota(1L, 7L); auto r = popBackN(LL, 2); assert(equal(LL, [1L, 2L, 3L, 4L])); assert(r == 2);
popFrontN eagerly advances r itself (not a copy) up to n times (by calling r.popFront). popFrontN takes r by ref, so it mutates the original range. Completes in O(1) steps for ranges that support slicing and have length. Completes in O(n) time for all other ranges.
popBackN behaves the same as popFrontN but instead removes elements from the back of the (bidirectional) range instead of the front.