Movatterモバイル変換


[0]ホーム

URL:


D Logo
Menu
Search

Library Reference

version 2.111.0

overview

Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.Requires a signed-in GitHub account. This works well for small changes.If you'd like to make larger changes you may want to consider usinga local clone.

std.range.primitives

This module is a submodule ofstd.range.
It defines the bidirectional and forward range primitives for arrays:empty,front,back,popFront,popBack andsave.
It provides basic range functionality by defining several templates for testingwhether a given object is a range, and what kind of range it is:
isInputRangeTests if something is aninput range, defined to be something from which one can sequentially read data using the primitivesfront,popFront, andempty.
isOutputRangeTests if something is anoutput range, defined to be something to which one can sequentially write data using theput primitive.
isForwardRangeTests if something is aforward range, defined to be an input range with the additional capability that one can save one's current position with thesave primitive, thus allowing one to iterate over the same range multiple times.
isBidirectionalRangeTests if something is abidirectional range, that is, a forward range that allows reverse traversal using the primitives back andpopBack.
isRandomAccessRangeTests if something is arandom access range, which is a bidirectional range that also supports the array subscripting operation via the primitiveopIndex.
It also provides number of templates that test for various range capabilities:
hasMobileElementsTests if a given range's elements can be moved around using the primitivesmoveFront,moveBack, ormoveAt.
ElementTypeReturns the element type of a given range.
ElementEncodingTypeReturns the encoding element type of a given range.
hasSwappableElementsTests if a range is a forward range with swappable elements.
hasAssignableElementsTests if a range is a forward range with mutable elements.
hasLvalueElementsTests if a range is a forward range with elements that can be passed by reference and have their address taken.
hasLengthTests if a given range has thelength attribute.
isInfiniteTests if a given range is aninfinite range.
hasSlicingTests if a given range supports the array slicing operation R[x .. y].
Finally, it includes some convenience functions for manipulating ranges:
popFrontNAdvances a given range by up ton elements.
popBackNAdvances a given bidirectional range from the right by up ton elements.
popFrontExactlyAdvances a given range by up exactlyn elements.
popBackExactlyAdvances a given bidirectional range from the right by exactlyn elements.
moveFrontRemoves the front element of a range.
moveBackRemoves the back element of a bidirectional range.
moveAtRemoves thei'th element of a random-access range.
walkLengthComputes the length of any range in O(n) time.
putOutputs elemente to a range.

Sourcestd/range/primitives.d

License:
Boost License 1.0.
Authors:
Andrei Alexandrescu, David Simcha, andJonathan M Davis. Credit for some of the ideas in building this module goes toLeonardo Maffi.
enum boolisInputRange(R);

enum boolisInputRange(R, E);
Returnstrue ifR is an input range. An input range mustdefine the primitivesempty,popFront, andfront. Thefollowing code should compile for any input range.
R r;// can define a range objectif (r.empty) {}// can test for emptyr.popFront();// can invoke popFront()auto h = r.front;// can get the front of the range of non-void type
The following are rules of input ranges are assumed to hold true in allPhobos code. These rules are not checkable at compile-time, so not conformingto these rules when writing ranges or range based code will result inundefined behavior.
  • r.empty returnsfalse if and only if there is more data available in the range.
  • r.empty evaluated multiple times, without callingr.popFront, or otherwise mutating the range object or the underlying data, yields the same result for every evaluation.
  • r.front returns the current element in the range. It may return by value or by reference.
  • r.front can be legally evaluated if and only if evaluatingr.empty has, or would have, equaledfalse.
  • r.front evaluated multiple times, without callingr.popFront, or otherwise mutating the range object or the underlying data, yields the same result for every evaluation.
  • r.popFront advances to the next element in the range.
  • r.popFront can be called if and only if evaluatingr.empty has, or would have, equaledfalse.
Also, note that Phobos code assumes that the primitivesr.front andr.empty areΟ(1) time complexity wise or "cheap" in terms ofrunning time.Ο() statements in the documentation of range functionsare made with this assumption.
See Also:
The header ofstd.range for tutorials on ranges.
Parameters:
Rtype to be tested
Eif present, the elements of the range must bequalifier-convertible to this type
Returns:
true if R is an input range (possibly with element typeE),false if not
Examples:
struct A {}struct B{void popFront();    @propertybool empty();    @propertyint front();}staticassert(!isInputRange!A);staticassert(isInputRange!B);staticassert(isInputRange!(int[]));staticassert(isInputRange!(char[]));staticassert(!isInputRange!(char[4]));staticassert(isInputRange!(inout(int)[]));staticassert(!isInputRange!(int[], string));staticassert(isInputRange!(int[],int));staticassert(isInputRange!(int[],constint));staticassert(!isInputRange!(int[],immutableint));staticassert(!isInputRange!(const(int)[],int));staticassert(isInputRange!(const(int)[],constint));staticassert(!isInputRange!(const(int)[],immutableint));staticassert(!isInputRange!(immutable(int)[],int));staticassert(isInputRange!(immutable(int)[],constint));staticassert(isInputRange!(immutable(int)[],immutableint));staticstruct NotDefaultConstructible{    @disablethis();void popFront();    @propertybool empty();    @propertyint front();}staticassert(isInputRange!NotDefaultConstructible);staticstruct NotDefaultConstructibleOrCopyable{    @disablethis();    @disablethis(this);void popFront();    @propertybool empty();    @propertyint front();}staticassert(isInputRange!NotDefaultConstructibleOrCopyable);staticstruct Frontless{void popFront();    @propertybool empty();}staticassert(!isInputRange!Frontless);staticstruct VoidFront{void popFront();    @propertybool empty();void front();}staticassert(!isInputRange!VoidFront);
voidput(R, E)(ref Rr, Ee);
Outputse tor. The exact effect is dependent upon the twotypes. Several cases are accepted, as described below. The code snippetsare attempted in order, and the first to compile "wins" and getsevaluated.
In this table "doPut" is a method that placese intor, using thecorrect primitive:r.put(e) ifR definesput,r.front = eifr is an input range (followed byr.popFront()), orr(e)otherwise.
Code SnippetScenario
r.doPut(e);R specifically accepts anE.
r.doPut([ e ]);R specifically accepts anE[].
r.putChar(e);R accepts some form of string or character. put will transcode the charactere accordingly.
for (; !e.empty; e.popFront()) put(r, e.front);Copying rangeE intoR.

Tipput shouldnot be used "UFCS-style", e.g.r.put(e).Doing this may callR.put directly, by-passing any transformationfeature provided byRange.put.put(r, e) is prefered.

Examples:
When an output range'sput method only accepts elements of typeT, use the globalput to handle outputting aT[] to the range or vice-versa.
import std.traits : isSomeChar;staticstruct A{    string data;voidput(C)(C c)if (isSomeChar!C)    {        data ~= c;    }}staticassert(isOutputRange!(A,char));auto a = A();put(a,"Hello");writeln(a.data);// "Hello"
Examples:
put treats dynamic arrays as array slices, and will callpopFront on the slice after an element has been copied.
Be sure to save the position of the array before callingput.
int[] a = [1, 2, 3], b = [10, 20];auto c = a;put(a, b);writeln(c);// [10, 20, 3]// at this point, a was advanced twice, so it only contains// its last element while c represents the whole arraywriteln(a);// [3]
Examples:
It's also possible toput any width strings or characters into narrow strings -- put does the conversion for you.
Note that putting the same width character as the target buffer type isnothrow, but transcoding can throw astd.utf.UTFException.
// the elements must be mutable, so using string or const(char)[]// won't compilechar[] s1 =newchar[13];auto r1 = s1;put(r1,"Hello, World!"w);writeln(s1);// "Hello, World!"
enum boolisOutputRange(R, E);
Returnstrue ifR is an output range for elements of typeE. An output range is defined functionally as a range thatsupports the operationput(r, e) as defined above.
See Also:
The header ofstd.range for tutorials on ranges.
Examples:
void myprint(scopeconst(char)[] s) { }staticassert(isOutputRange!(typeof(&myprint),char));staticassert(isOutputRange!(char[],char));staticassert(isOutputRange!(dchar[],wchar));staticassert(isOutputRange!(dchar[],dchar));
enum boolisForwardRange(R);

enum boolisForwardRange(R, E);
Returnstrue ifR is a forward range. A forward range is aninput ranger that can save "checkpoints" by savingr.saveto another value of typeR. Notable examples of input ranges thatarenot forward ranges are file/socket ranges; copying such arange will not save the position in the stream, and they most likelyreuse an internal buffer as the entire stream does not sit inmemory. Subsequently, advancing either the original or the copy willadvance the stream, so the copies are not independent.
The following code should compile for any forward range.
staticassert(isInputRange!R);R r1;auto s1 = r1.save;staticassert(is(typeof(s1) == R));
Saving a range is not duplicating it; in the example above,r1andr2 still refer to the same underlying data. They justnavigate that data independently.
The semantics of a forward range (not checkable during compilation)are the same as for an input range, with the additional requirementthat backtracking must be possible by saving a copy of the rangeobject withsave and using it later.
save behaves in many ways like a copy constructor, and itsimplementation typically is done using copy construction.
The existence of a copy constructor, however, does not implythe range is a forward range. For example, a range that readsfrom a TTY consumes its input and cannot save its place andread it again, and so cannot be a forward range and cannothave asave function.
See Also:
The header ofstd.range for tutorials on ranges.
Parameters:
Rtype to be tested
Eif present, the elements of the range must bequalifier-convertible to this type
Returns:
true if R is a forward range (possibly with element typeE),false if not
Examples:
staticassert(!isForwardRange!(int));staticassert(isForwardRange!(int[]));staticassert(isForwardRange!(inout(int)[]));staticassert(isForwardRange!(int[],constint));staticassert(!isForwardRange!(int[],immutableint));staticassert(!isForwardRange!(const(int)[],int));staticassert(isForwardRange!(const(int)[],constint));staticassert(!isForwardRange!(const(int)[],immutableint));staticassert(!isForwardRange!(immutable(int)[],int));staticassert(isForwardRange!(immutable(int)[],constint));staticassert(isForwardRange!(immutable(int)[],immutableint));
enum boolisBidirectionalRange(R);

enum boolisBidirectionalRange(R, E);
Returnstrue ifR is a bidirectional range. A bidirectionalrange is a forward range that also offers the primitivesback andpopBack. The following code should compile for any bidirectionalrange.
The semantics of a bidirectional range (not checkable duringcompilation) are assumed to be the following (r is an object oftypeR):
  • r.back returns (possibly a reference to) the lastelement in the range. Callingr.back is allowed only if callingr.empty has, or would have, returnedfalse.
See Also:
The header ofstd.range for tutorials on ranges.
Parameters:
Rtype to be tested
Eif present, the elements of the range must bequalifier-convertible to this type
Returns:
true if R is a bidirectional range (possibly with element typeE),false if not
Examples:
alias R =int[];R r = [0,1];staticassert(isForwardRange!R);// is forward ranger.popBack();// can invoke popBackauto t = r.back;// can get the back of the rangeauto w = r.front;staticassert(is(typeof(t) ==typeof(w)));// same type for front and back// Checking the element typestaticassert(isBidirectionalRange!(int[],constint));staticassert(!isBidirectionalRange!(int[],immutableint));staticassert(!isBidirectionalRange!(const(int)[],int));staticassert(isBidirectionalRange!(const(int)[],constint));staticassert(!isBidirectionalRange!(const(int)[],immutableint));staticassert(!isBidirectionalRange!(immutable(int)[],int));staticassert(isBidirectionalRange!(immutable(int)[],constint));staticassert(isBidirectionalRange!(immutable(int)[],immutableint));
enum boolisRandomAccessRange(R);

enum boolisRandomAccessRange(R, E);
Returnstrue ifR is a random-access range. A random-accessrange is a bidirectional range that also offers the primitiveopIndex, OR an infinite forward range that offersopIndex. Ineither case, the range must either offerlength or beinfinite. The following code should compile for any random-accessrange.
The semantics of a random-access range (not checkable duringcompilation) are assumed to be the following (r is an object oftypeR):
  • r.opIndex(n) returns a reference to thenth element in the range.
Althoughchar[] andwchar[] (as well as their qualifiedversions includingstring andwstring) are arrays,isRandomAccessRange yieldsfalse for them because they usevariable-length encodings (UTF-8 and UTF-16 respectively). These typesare bidirectional ranges only.
See Also:
The header ofstd.range for tutorials on ranges.
Parameters:
Rtype to be tested
Eif present, the elements of the range must bequalifier-convertible to this type
Returns:
true if R is a random-access range (possibly with element typeE),false if not
Examples:
import std.traits : isAggregateType, isAutodecodableString;alias R =int[];// range is finite and bidirectional or infinite and forward.staticassert(isBidirectionalRange!R ||              isForwardRange!R && isInfinite!R);R r = [0,1];auto e = r[1];// can indexauto f = r.front;staticassert(is(typeof(e) ==typeof(f)));// same type for indexed and frontstaticassert(!(isAutodecodableString!R && !isAggregateType!R));// narrow strings cannot be indexed as rangesstaticassert(hasLength!R || isInfinite!R);// must have length or be infinite// $ must work as it does with arrays if opIndex works with $staticif (is(typeof(r[$]))){staticassert(is(typeof(f) ==typeof(r[$])));// $ - 1 doesn't make sense with infinite ranges but needs to work// with finite ones.staticif (!isInfinite!R)staticassert(is(typeof(f) ==typeof(r[$ - 1])));}// Checking the element typestaticassert(isRandomAccessRange!(int[],constint));staticassert(!isRandomAccessRange!(int[],immutableint));staticassert(!isRandomAccessRange!(const(int)[],int));staticassert(isRandomAccessRange!(const(int)[],constint));staticassert(!isRandomAccessRange!(const(int)[],immutableint));staticassert(!isRandomAccessRange!(immutable(int)[],int));staticassert(isRandomAccessRange!(immutable(int)[],constint));staticassert(isRandomAccessRange!(immutable(int)[],immutableint));
enum boolhasMobileElements(R);
Returnstrue iffR is an input range that supports themoveFront primitive, as well asmoveBack andmoveAt if it's abidirectional or random access range. These may be explicitly implemented, ormay work via the default behavior of the module level functionsmoveFrontand friends. The following code should compile for any rangewith mobile elements.
alias E = ElementType!R;R r;staticassert(isInputRange!R);staticassert(is(typeof(moveFront(r)) == E));staticif (isBidirectionalRange!R)staticassert(is(typeof(moveBack(r)) == E));staticif (isRandomAccessRange!R)staticassert(is(typeof(moveAt(r, 0)) == E));
Examples:
import std.algorithm.iteration : map;import std.range : iota, repeat;staticstruct HasPostblit{this(this) {}}auto nonMobile = map!"a"(repeat(HasPostblit.init));staticassert(!hasMobileElements!(typeof(nonMobile)));staticassert(hasMobileElements!(int[]));staticassert(hasMobileElements!(inout(int)[]));staticassert(hasMobileElements!(typeof(iota(1000))));staticassert(hasMobileElements!( string));staticassert(hasMobileElements!(dstring));staticassert(hasMobileElements!(char[]));staticassert(hasMobileElements!(dchar[]));
templateElementType(R)
The element type ofR.R does not have to be a range. Theelement type is determined as the type yielded byr.front for anobjectr of typeR. For example,ElementType!(T[]) isT ifT[] isn't a narrow string; if it is, the element type isdchar. IfR doesn't havefront,ElementType!R isvoid.
Examples:
import std.range : iota;// Standard arrays: returns the type of the elements of the arraystaticassert(is(ElementType!(int[]) ==int));// Accessing .front retrieves the decoded dcharstaticassert(is(ElementType!(char[])  ==dchar));// rvaluestaticassert(is(ElementType!(dchar[]) ==dchar));// lvalue// Dittostaticassert(is(ElementType!(string) ==dchar));staticassert(is(ElementType!(dstring) ==immutable(dchar)));// For ranges it gets the type of .front.auto range = iota(0, 10);staticassert(is(ElementType!(typeof(range)) ==int));
templateElementEncodingType(R)
The encoding element type ofR. For narrow strings (char[],wchar[] and their qualified variants includingstring andwstring),ElementEncodingType is the character type of thestring. For all other types,ElementEncodingType is the same asElementType.
Examples:
import std.range : iota;// internally the range stores the encoded typestaticassert(is(ElementEncodingType!(char[])  ==char));staticassert(is(ElementEncodingType!(wstring) ==immutable(wchar)));staticassert(is(ElementEncodingType!(byte[]) ==byte));auto range = iota(0, 10);staticassert(is(ElementEncodingType!(typeof(range)) ==int));
enum boolhasSwappableElements(R);
Returnstrue ifR is an input range and has swappableelements. The following code should compile for any rangewith swappable elements.
R r;staticassert(isInputRange!R);swap(r.front, r.front);staticif (isBidirectionalRange!R) swap(r.back, r.front);staticif (isRandomAccessRange!R) swap(r[0], r.front);
Examples:
staticassert(!hasSwappableElements!(constint[]));staticassert(!hasSwappableElements!(const(int)[]));staticassert(!hasSwappableElements!(inout(int)[]));staticassert(hasSwappableElements!(int[]));staticassert(!hasSwappableElements!( string));staticassert(!hasSwappableElements!(dstring));staticassert(!hasSwappableElements!(char[]));staticassert(hasSwappableElements!(dchar[]));
enum boolhasAssignableElements(R);
Returnstrue ifR is an input range and has mutableelements. The following code should compile for any rangewith assignable elements.
R r;staticassert(isInputRange!R);r.front = r.front;staticif (isBidirectionalRange!R) r.back = r.front;staticif (isRandomAccessRange!R) r[0] = r.front;
Examples:
staticassert(!hasAssignableElements!(constint[]));staticassert(!hasAssignableElements!(const(int)[]));staticassert(hasAssignableElements!(int[]));staticassert(!hasAssignableElements!(inout(int)[]));staticassert(!hasAssignableElements!( string));staticassert(!hasAssignableElements!(dstring));staticassert(!hasAssignableElements!(char[]));staticassert(hasAssignableElements!(dchar[]));
enum boolhasLvalueElements(R);
Tests whether the rangeR has lvalue elements. These are defined aselements that can be passed by reference and have their address taken.The following code should compile for any range with lvalue elements.
void passByRef(ref ElementType!R stuff);...staticassert(isInputRange!R);passByRef(r.front);staticif (isBidirectionalRange!R) passByRef(r.back);staticif (isRandomAccessRange!R) passByRef(r[0]);
templatehasLength(R)
Yieldstrue ifR has alength member that returns a value ofsize_ttype.R does not have to be a range. IfR is a range, algorithms in thestandard library are only guaranteed to supportlength with typesize_t.
Note thatlength is an optional primitive as no range must implement it. Someranges do not store their length explicitly, some cannot compute it withoutactually exhausting the range (e.g. socket streams), and some other ranges maybe infinite.
Although narrow string types (char[],wchar[], and their qualifiedderivatives) do define alength property,hasLength yieldsfalse for them.This is because a narrow string's length does not reflect the number ofcharacters, but instead the number of encoding units, and as such is not usefulwith range-oriented algorithms. To use strings as random-access ranges withlength, usestd.string.representation orstd.utf.byCodeUnit.
Examples:
staticassert(!hasLength!(char[]));staticassert(hasLength!(int[]));staticassert(hasLength!(inout(int)[]));struct A { size_t length() {return 0; } }struct B { @property size_t length() {return 0; } }staticassert(hasLength!(A));staticassert(hasLength!(B));
templateisInfinite(R)
Returnstrue ifR is an infinite input range. Aninfinite input range is an input range that has a statically-definedenumerated member calledempty that is alwaysfalse,for example:
struct MyInfiniteRange{enumbool empty =false;    ...}
Examples:
import std.range : Repeat;staticassert(!isInfinite!(int[]));staticassert(isInfinite!(Repeat!(int)));
enum boolhasSlicing(R);
Returnstrue ifR offers a slicing operator with integral boundariesthat returns a forward range type.
For finite ranges, the result ofopSlice must be of the same type as theoriginal range type. If the range definesopDollar, then it must supportsubtraction.
For infinite ranges, whennot usingopDollar, the result ofopSlicemay be a forward range of any type. However, when usingopDollar, the resultofopSlice must be of the same type as the original range type.
The following expression must be true forhasSlicing to betrue:
    isForwardRange!R    && !(isAutodecodableString!R && !isAggregateType!R)    &&is(typeof((R r) {return r[1 .. 1].length; } (R.init)) == size_t)    && (is(typeof(lvalueOf!R[1 .. 1]) == R) || isInfinite!R)    && (!is(typeof(lvalueOf!R[0 .. $])) ||is(typeof(lvalueOf!R[0 .. $]) == R))    && (!is(typeof(lvalueOf!R[0 .. $])) || isInfinite!R        ||is(typeof(lvalueOf!R[0 .. $ - 1]) == R))    &&is(typeof((ref R r)    {staticassert(isForwardRange!(typeof(r[1 .. 2])));    }));
Examples:
import std.range : takeExactly;staticassert(hasSlicing!(int[]));staticassert(hasSlicing!(const(int)[]));staticassert(!hasSlicing!(constint[]));staticassert(hasSlicing!(inout(int)[]));staticassert(!hasSlicing!(inoutint []));staticassert(hasSlicing!(immutable(int)[]));staticassert(!hasSlicing!(immutableint[]));staticassert(!hasSlicing!string);staticassert(hasSlicing!dstring);enum rangeFuncs ="@property int front();" ~"void popFront();" ~"@property bool empty();" ~"@property auto save() { return this; }" ~"@property size_t length();";struct A {mixin(rangeFuncs);int opSlice(size_t, size_t); }struct B {mixin(rangeFuncs); B opSlice(size_t, size_t); }struct C {mixin(rangeFuncs); @disablethis(); C opSlice(size_t, size_t); }struct D {mixin(rangeFuncs);int[] opSlice(size_t, size_t); }staticassert(!hasSlicing!(A));staticassert(hasSlicing!(B));staticassert(hasSlicing!(C));staticassert(!hasSlicing!(D));struct InfOnes{enum empty =false;void popFront() {}    @propertyint front() {return 1; }    @property InfOnes save() {returnthis; }auto opSlice(size_t i, size_t j) {return takeExactly(this, j - i); }auto opSlice(size_t i, Dollar d) {returnthis; }struct Dollar {}    Dollar opDollar()const {return Dollar.init; }}staticassert(hasSlicing!InfOnes);
autowalkLength(Range)(Rangerange)
if (isInputRange!Range && !isInfinite!Range);

autowalkLength(Range)(Rangerange, const size_tupTo)
if (isInputRange!Range);
This is a best-effort implementation oflength for any kind ofrange.
IfhasLength!Range, simply returnsrange.length withoutcheckingupTo (when specified).
Otherwise, walks the range through its length and returns the numberof elements seen. PerformesΟ(n) evaluations ofrange.emptyandrange.popFront(), wheren is the effective length ofrange.
TheupTo parameter is useful to "cut the losses" in casethe interest is in seeing whether the range has at least some numberof elements. If the parameterupTo is specified, stops ifupTo steps have been taken and returnsupTo.
Infinite ranges are compatible, provided the parameterupTo isspecified, in which case the implementation simply returns upTo.
Examples:
import std.range : iota;writeln(10.iota.walkLength);// 10// iota has a length function, and therefore the// doesn't have to be walked, and the upTo// parameter is ignoredwriteln(10.iota.walkLength(5));// 10
size_tpopFrontN(Range)(ref Ranger, size_tn)
if (isInputRange!Range);

size_tpopBackN(Range)(ref Ranger, size_tn)
if (isBidirectionalRange!Range);
popFrontN eagerly advancesr itself (not a copy) up ton times (by callingr.popFront).popFrontN takesr byref, so it mutates the original range. Completes inΟ(1) steps for ranges that support slicing and have length. Completes inΟ(n) time for all other ranges.
popBackN behaves the same aspopFrontN but instead removes elements from the back of the (bidirectional) range instead of the front.
Returns:
How muchr was actually advanced, which may be less thann ifr did not have at leastn elements.
See Also:
Examples:
int[] a = [ 1, 2, 3, 4, 5 ];a.popFrontN(2);writeln(a);// [3, 4, 5]a.popFrontN(7);writeln(a);// []
Examples:
import std.algorithm.comparison : equal;import std.range : iota;auto LL = iota(1L, 7L);autor =popFrontN(LL, 2);assert(equal(LL, [3L, 4L, 5L, 6L]));writeln(r);// 2
Examples:
int[] a = [ 1, 2, 3, 4, 5 ];a.popBackN(2);writeln(a);// [1, 2, 3]a.popBackN(7);writeln(a);// []
Examples:
import std.algorithm.comparison : equal;import std.range : iota;auto LL = iota(1L, 7L);autor =popBackN(LL, 2);assert(equal(LL, [1L, 2L, 3L, 4L]));writeln(r);// 2
voidpopFrontExactly(Range)(ref Ranger, size_tn)
if (isInputRange!Range);

voidpopBackExactly(Range)(ref Ranger, size_tn)
if (isBidirectionalRange!Range);
Eagerly advancesr itself (not a copy) exactlyn times (by callingr.popFront).popFrontExactly takesr byref, so it mutates the original range. Completes inΟ(1) steps for ranges that support slicing, and have either length or are infinite. Completes inΟ(n) time for all other ranges.

NoteUnlikepopFrontN,popFrontExactly will assume that the range holds at leastn elements. This makespopFrontExactly faster thanpopFrontN, but it also means that ifrange does not contain at leastn elements, it will attempt to callpopFront on an empty range, which is undefined behavior. So, only usepopFrontExactly when it is guaranteed thatrange holds at leastn elements.

popBackExactly will behave the same but instead removes elements from the back of the (bidirectional) range instead of the front.

See Also:
Examples:
import std.algorithm.comparison : equal;import std.algorithm.iteration : filterBidirectional;auto a = [1, 2, 3];a.popFrontExactly(1);writeln(a);// [2, 3]a.popBackExactly(1);writeln(a);// [2]string s ="日本語";s.popFrontExactly(1);writeln(s);// "本語"s.popBackExactly(1);writeln(s);// "本"auto bd = filterBidirectional!"true"([1, 2, 3]);bd.popFrontExactly(1);assert(bd.equal([2, 3]));bd.popBackExactly(1);assert(bd.equal([2]));
ElementType!RmoveFront(R)(Rr);
Moves the front ofr out and returns it.
Ifr.front is a struct with a destructor or copy constructor defined, it is reset to its.init value after its value is moved. Otherwise, it is left unchanged.
In either case,r.front is left in a destroyable state that does not allocate any resources.
Examples:
auto a = [ 1, 2, 3 ];writeln(moveFront(a));// 1writeln(a.length);// 3// define a perfunctory input rangestruct InputRange{enumbool empty =false;enumint front = 7;void popFront() {}intmoveFront() {return 43; }}InputRanger;// calls r.moveFrontwriteln(moveFront(r));// 43
ElementType!RmoveBack(R)(Rr);
Moves the back ofr out and returns it. Leavesr.back in a destroyable state that does not allocate any resources (usually equal to its.init value).
Examples:
struct TestRange{int payload = 5;    @propertybool empty() {returnfalse; }    @property TestRange save() {returnthis; }    @propertyrefint front()return {return payload; }    @propertyrefint back()return {return payload; }void popFront() { }void popBack() { }}staticassert(isBidirectionalRange!TestRange);TestRanger;auto x =moveBack(r);writeln(x);// 5
ElementType!RmoveAt(R)(Rr, size_ti);
Moves element at indexi ofr out and returns it. Leaves r[i] in a destroyable state that does not allocate any resources (usually equal to its.init value).
Examples:
auto a = [1,2,3,4];foreach (idx, it; a){    writeln(it);// moveAt(a, idx)}
@property boolempty(T)(auto ref scope Ta)
if (is(typeof(a.length) : size_t));
Implements the range interface primitiveempty for types thatobeyhasLength property and for narrow strings. Due to thefact that nonmember functions can be called with the first argumentusing the dot notation,a.empty is equivalent toempty(a).
Examples:
autoa = [ 1, 2, 3 ];assert(!a.empty);assert(a[3 .. $].empty);int[string] b;assert(b.empty);b["zero"] = 0;assert(!b.empty);
pure nothrow @nogc @property @safe inout(T)[]save(T)(return scope inout(T)[]a);
Implements the range interface primitivesave for built-inarrays. Due to the fact that nonmember functions can be called withthe first argument using the dot notation,array.save isequivalent tosave(array). The function does not duplicate thecontent of the array, it simply returns its argument.
Examples:
autoa = [ 1, 2, 3 ];auto b =a.save;assert(bisa);
pure nothrow @nogc @safe voidpopFront(T)(ref scope inout(T)[]a)
if (!isAutodecodableString!(T[]) && !is(T[] == void[]));

pure nothrow @trusted voidpopFront(C)(ref scope inout(C)[]str)
if (isAutodecodableString!(C[]));
Implements the range interface primitivepopFront for built-inarrays. Due to the fact that nonmember functions can be called withthe first argument using the dot notation,array.popFront isequivalent topopFront(array). Fornarrow strings,popFront automatically advances to the nextcodepoint.
Examples:
autoa = [ 1, 2, 3 ];a.popFront();writeln(a);// [2, 3]
pure nothrow @nogc @safe voidpopBack(T)(ref scope inout(T)[]a)
if (!isAutodecodableString!(T[]) && !is(T[] == void[]));

pure @safe voidpopBack(T)(ref scope inout(T)[]a)
if (isAutodecodableString!(T[]));
Implements the range interface primitivepopBack for built-inarrays. Due to the fact that nonmember functions can be called withthe first argument using the dot notation,array.popBack isequivalent topopBack(array). Fornarrow strings,popFront automatically eliminates the lastcode point.
Examples:
autoa = [ 1, 2, 3 ];a.popBack();writeln(a);// [1, 2]
enum boolautodecodeStrings;

EXPERIMENTALto try out removing autodecoding, set the versionNoAutodecodeStrings. Most things are expected to fail with this versioncurrently.

pure nothrow @nogc @property ref @safe inout(T)front(T)(return scope inout(T)[]a)
if (!isAutodecodableString!(T[]) && !is(T[] == void[]));

pure @property @safe dcharfront(T)(scope const(T)[]a)
if (isAutodecodableString!(T[]));
Implements the range interface primitivefront for built-inarrays. Due to the fact that nonmember functions can be called withthe first argument using the dot notation,array.front isequivalent tofront(array). Fornarrow strings,front automatically returns the firstcode point as adchar.
Examples:
int[]a = [ 1, 2, 3 ];writeln(a.front);// 1
pure nothrow @nogc @property ref @safe inout(T)back(T)(return scope inout(T)[]a)
if (!isAutodecodableString!(T[]) && !is(T[] == void[]));

pure @property @safe dcharback(T)(scope const(T)[]a)
if (isAutodecodableString!(T[]));
Implements the range interface primitiveback for built-inarrays. Due to the fact that nonmember functions can be called withthe first argument using the dot notation,array.back isequivalent toback(array). Fornarrow strings,back automatically returns the lastcode point as adchar.
Examples:
int[]a = [ 1, 2, 3 ];writeln(a.back);// 3a.back += 4;writeln(a.back);// 7
Copyright © 1999-2025 by theD Language Foundation | Page generated byDdoc on Sun Jul 13 01:05:00 2025

[8]ページ先頭

©2009-2025 Movatter.jp