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.algorithm.mutation

This is a submodule ofstd.algorithm.It contains generic mutation algorithms.
Cheat Sheet
Function NameDescription
bringToFront Ifa = [1, 2, 3] andb = [4, 5, 6, 7],bringToFront(a, b) leavesa = [4, 5, 6] andb = [7, 1, 2, 3].
copy Copies a range to another. Ifa = [1, 2, 3] andb = new int[5], thencopy(a, b) leavesb = [1, 2, 3, 0, 0] and returnsb[3 .. $].
fill Fills a range with a pattern, e.g., ifa = new int[3], thenfill(a, 4) leavesa = [4, 4, 4] andfill(a, [3, 4]) leavesa = [3, 4, 3].
initializeAll Ifa = [1.2, 3.4], theninitializeAll(a) leavesa = [double.init, double.init].
movemove(a, b) movesa intob.move(a) readsa destructively when necessary.
moveEmplace Similar tomove but assumestarget is uninitialized.
moveAll Moves all elements from one range to another.
moveEmplaceAll Similar tomoveAll but assumes all elements intarget are uninitialized.
moveSome Moves as many elements as possible from one range to another.
moveEmplaceSome Similar tomoveSome but assumes all elements intarget are uninitialized.
remove Removes elements from a range in-place, and returns the shortened range.
reverse Ifa = [1, 2, 3],reverse(a) changes it to[3, 2, 1].
strip Strips all leading and trailing elements equal to a value, or that satisfy a predicate. Ifa = [1, 1, 0, 1, 1], thenstrip(a, 1) andstrip!(e => e == 1)(a) returns[0].
stripLeft Strips all leading elements equal to a value, or that satisfy a predicate. Ifa = [1, 1, 0, 1, 1], thenstripLeft(a, 1) andstripLeft!(e => e == 1)(a) returns[0, 1, 1].
stripRight Strips all trailing elements equal to a value, or that satisfy a predicate. Ifa = [1, 1, 0, 1, 1], thenstripRight(a, 1) andstripRight!(e => e == 1)(a) returns[1, 1, 0].
swap Swaps two values.
swapAt Swaps two values by indices.
swapRanges Swaps all elements of two ranges.
uninitializedFill Fills a range (assumed uninitialized) with a value.
License:
Boost License 1.0.
Authors:
Andrei Alexandrescu

Sourcestd/algorithm/mutation.d

size_tbringToFront(InputRange, ForwardRange)(InputRangefront, ForwardRangeback)
if (isInputRange!InputRange && isForwardRange!ForwardRange);
bringToFront takes two rangesfront andback, which maybe of different types. Considering the concatenation offront andback one unified range,bringToFront rotates that unifiedrange such that all elements inback are brought to the beginningof the unified range. The relative ordering of elements infrontandback, respectively, remains unchanged.
ThebringToFront function treats strings at the code unitlevel and it is not concerned with Unicode character integrity.bringToFront is designed as a function for moving elementsin ranges, not as a string function.
PerformsΟ(max(front.length, back.length)) evaluations ofswap.
ThebringToFront function can rotate elements in one buffer left or right, swapbuffers of equal length, and even move elements across disjointbuffers of different types and different lengths.

PreconditionsEitherfront andback are disjoint, orback isreachable fromfront andfront is not reachable fromback.

Parameters:
InputRangefrontaninput range
ForwardRangebackaforward range
Returns:
The number of elements brought to the front, i.e., the length ofback.
See Also:
Examples:
The simplest use ofbringToFront is for rotating elements in abuffer. For example:
auto arr = [4, 5, 6, 7, 1, 2, 3];auto p =bringToFront(arr[0 .. 4], arr[4 .. $]);writeln(p);// arr.length - 4writeln(arr);// [1, 2, 3, 4, 5, 6, 7]
Examples:
Thefront range may actually "step over" thebackrange. This is very useful with forward ranges that cannot computecomfortably right-bounded subranges likearr[0 .. 4] above. Inthe example below,r2 is a right subrange ofr1.
import std.algorithm.comparison : equal;import std.container : SList;import std.range.primitives : popFrontN;auto list = SList!(int)(4, 5, 6, 7, 1, 2, 3);auto r1 = list[];auto r2 = list[]; popFrontN(r2, 4);assert(equal(r2, [ 1, 2, 3 ]));bringToFront(r1, r2);assert(equal(list[], [ 1, 2, 3, 4, 5, 6, 7 ]));
Examples:
Elements can be swapped across ranges of different types:
import std.algorithm.comparison : equal;import std.container : SList;auto list = SList!(int)(4, 5, 6, 7);auto vec = [ 1, 2, 3 ];bringToFront(list[], vec);assert(equal(list[], [ 1, 2, 3, 4 ]));assert(equal(vec, [ 5, 6, 7 ]));
Examples:
Unicode integrity is not preserved:
import std.string : representation;auto ar = representation("a".dup);auto br = representation("ç".dup);bringToFront(ar, br);auto a =cast(char[]) ar;auto b =cast(char[]) br;// Illegal UTF-8writeln(a);// "\303"// Illegal UTF-8writeln(b);// "\247a"
TargetRangecopy(SourceRange, TargetRange)(SourceRangesource, TargetRangetarget)
if (isInputRange!SourceRange && isOutputRange!(TargetRange, ElementType!SourceRange));
Copies the content ofsource intotarget and returns theremaining (unfilled) part oftarget.

Preconditionstarget shall have enough room to accommodatethe entirety ofsource.

Parameters:
SourceRangesourceaninput range
TargetRangetargetan output range
Returns:
The unfilled part of target
Examples:
int[] a = [ 1, 5 ];int[] b = [ 9, 8 ];int[] buf =newint[](a.length + b.length + 10);auto rem = a.copy(buf);// copy a into bufrem = b.copy(rem);// copy b into remainder of bufwriteln(buf[0 .. a.length + b.length]);// [1, 5, 9, 8]assert(rem.length == 10);// unused slots in buf
Examples:
As long as the target range elements support assignment from sourcerange elements, different types of ranges are accepted:
float[] src = [ 1.0f, 5 ];double[] dest =newdouble[src.length];src.copy(dest);
Examples:
To copy at mostn elements from a range, you may want to usestd.range.take:
import std.range;int[] src = [ 1, 5, 8, 9, 10 ];auto dest =newint[](3);src.take(dest.length).copy(dest);writeln(dest);// [1, 5, 8]
Examples:
To copy just those elements from a range that satisfy a predicate,usefilter:
import std.algorithm.iteration : filter;int[] src = [ 1, 5, 8, 9, 10, 1, 2, 0 ];auto dest =newint[src.length];auto rem = src    .filter!(a => (a & 1) == 1)    .copy(dest);writeln(dest[0 .. $ - rem.length]);// [1, 5, 9, 1]
Examples:
std.range.retro can be used to achieve behavior similar toSTL'scopy_backward':
import std.algorithm, std.range;int[] src = [1, 2, 4];int[] dest = [0, 0, 0, 0, 0];src.retro.copy(dest.retro);writeln(dest);// [0, 0, 1, 2, 4]
voidfill(Range, Value)(auto ref Rangerange, auto ref Valuevalue)
if (isInputRange!Range && is(typeof(range.front =value)) || isSomeChar!Value && is(typeof(range[] =value)));

voidfill(InputRange, ForwardRange)(InputRangerange, ForwardRangefiller)
if (isInputRange!InputRange && (isForwardRange!ForwardRange || isInputRange!ForwardRange && isInfinite!ForwardRange) && is(typeof(InputRange.init.front = ForwardRange.init.front)));
Assignsvalue to each element of input rangerange.
Alternatively, instead of using a singlevalue to fill therange,afillerforward rangecan be provided. The length offiller andrange do not need to match, butfiller must not be empty.
Parameters:
RangerangeAninput range that exposes references to its elements and has assignable elements
ValuevalueAssigned to each element of range
ForwardRangefillerAforward range representing the fill pattern.
Throws:
Iffiller is empty.
See Also:
Examples:
int[] a = [ 1, 2, 3, 4 ];fill(a, 5);writeln(a);// [5, 5, 5, 5]
Examples:
int[] a = [ 1, 2, 3, 4, 5 ];int[] b = [ 8, 9 ];fill(a, b);writeln(a);// [8, 9, 8, 9, 8]
voidinitializeAll(Range)(Rangerange)
if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range && __traits(compiles, (){static ElementType!Range _;}));

voidinitializeAll(Range)(Rangerange)
if (is(Range == char[]) || is(Range == wchar[]));
Initializes all elements ofrange with their.init value.Assumes that the elements of the range are uninitialized.
This function is unavailable ifT is astruct andT.this() is annotatedwith@disable.
Parameters:
RangerangeAninput range that exposes references to its elements and has assignable elements
See Also:
Examples:
import core.stdc.stdlib : malloc, free;struct S{int a = 10;}auto s = (cast(S*) malloc(5 * S.sizeof))[0 .. 5];initializeAll(s);writeln(s);// [S(10), S(10), S(10), S(10), S(10)]scope(exit) free(s.ptr);
voidmove(T)(ref Tsource, ref Ttarget)
if (__traits(compiles,target = T.init));

voidmove(T)(ref Tsource, ref Ttarget)
if (!__traits(compiles, imported!"std.traits".lvalueOf!T = T.init));

Tmove(T)(ref return scope Tsource);
Movessource intotarget, via a destructive copy when necessary.
IfT is a struct with a destructor or postblit defined, source is resetto its.init value after it is moved into target, otherwise it isleft unchanged.

PreconditionsIf source has internal pointers that point to itself and doesn't defineopPostMove, it cannot be moved, and will trigger an assertion failure.

Parameters:
TsourceData to copy.
TtargetWhere to copy into. The destructor, if any, is invoked before the copy is performed.
Examples:
For non-struct types,move just performstarget =source:
Object obj1 =new Object;Object obj2 = obj1;Object obj3;move(obj2, obj3);assert(obj3is obj1);// obj2 unchangedassert(obj2is obj1);
Examples:
// Structs without destructors are simply copiedstruct S1{int a = 1;int b = 2;}S1 s11 = { 10, 11 };S1 s12;move(s11, s12);writeln(s12);// S1(10, 11)writeln(s11);// s12// But structs with destructors or postblits are reset to their .init value// after copying to the target.struct S2{int a = 1;int b = 2;    ~this()purenothrow @safe @nogc { }}S2 s21 = { 3, 4 };S2 s22;move(s21, s22);writeln(s21);// S2(1, 2)writeln(s22);// S2(3, 4)
Examples:
Non-copyable structs can still be moved:
struct S{int a = 1;    @disablethis(this);    ~this()purenothrow @safe @nogc {}}S s1;s1.a = 2;S s2 =move(s1);writeln(s1.a);// 1writeln(s2.a);// 2
Examples:
opPostMove will be called if defined:
struct S{int a;void opPostMove(constref S old)    {        writeln(a);// old.a        a++;    }}S s1;s1.a = 41;S s2 =move(s1);writeln(s2.a);// 42
pure @system voidmoveEmplace(T)(ref Tsource, ref Ttarget);
Similar tomove but assumestarget is uninitialized. This is more efficient becausesource can be blitted overtarget without destroying or initializing it first.
Parameters:
Tsourcevalue to be moved into target
Ttargetuninitialized value to be filled by source
Examples:
staticstruct Foo{purenothrow @nogc:this(int* ptr) { _ptr = ptr; }    ~this() {if (_ptr) ++*_ptr; }int* _ptr;}int val;Foo foo1 =void;// uninitializedauto foo2 = Foo(&val);// initializedassert(foo2._ptris &val);// Using `move(foo2, foo1)` would have an undefined effect because it would destroy// the uninitialized foo1.// moveEmplace directly overwrites foo1 without destroying or initializing it first.moveEmplace(foo2, foo1);assert(foo1._ptris &val);assert(foo2._ptrisnull);writeln(val);// 0
InputRange2moveAll(InputRange1, InputRange2)(InputRange1src, InputRange2tgt)
if (isInputRange!InputRange1 && isInputRange!InputRange2 && is(typeof(move(src.front,tgt.front))));
Callsmove(a, b) for each elementa insrc and the correspondingelementb intgt, in increasing order.

PreconditionswalkLength(src) <= walkLength(tgt).This precondition will be asserted. If you cannot ensure there is enough room intgt to accommodate all ofsrc usemoveSome instead.

Parameters:
InputRange1srcAninput range with movable elements.
InputRange2tgtAninput range with elements that elements fromsrc can be moved into.
Returns:
The leftover portion oftgt after all elements fromsrc havebeen moved.
Examples:
int[3] a = [ 1, 2, 3 ];int[5] b;assert(moveAll(a[], b[])is b[3 .. $]);writeln(a[]);// b[0 .. 3]int[3] cmp = [ 1, 2, 3 ];writeln(a[]);// cmp[]
@system InputRange2moveEmplaceAll(InputRange1, InputRange2)(InputRange1src, InputRange2tgt)
if (isInputRange!InputRange1 && isInputRange!InputRange2 && is(typeof(moveEmplace(src.front,tgt.front))));
Similar tomoveAll but assumes all elements intgt are uninitialized. UsesmoveEmplace to move elements fromsrc over elements fromtgt.
Examples:
staticstruct Foo{    ~this()purenothrow @nogc {if (_ptr) ++*_ptr; }int* _ptr;}int[3] refs = [0, 1, 2];Foo[3]src = [Foo(&refs[0]), Foo(&refs[1]), Foo(&refs[2])];Foo[5] dst =void;auto tail =moveEmplaceAll(src[], dst[]);// move 3 value from src over dstassert(tail.length == 2);// returns remaining uninitialized valuesinitializeAll(tail);import std.algorithm.searching : all;assert(src[].all!(e => e._ptrisnull));assert(dst[0 .. 3].all!(e => e._ptr !isnull));
Tuple!(InputRange1, InputRange2)moveSome(InputRange1, InputRange2)(InputRange1src, InputRange2tgt)
if (isInputRange!InputRange1 && isInputRange!InputRange2 && is(typeof(move(src.front,tgt.front))));
Callsmove(a, b) for each elementa insrc and the correspondingelementb intgt, in increasing order, stopping when either range has beenexhausted.
Parameters:
InputRange1srcAninput range with movable elements.
InputRange2tgtAninput range with elements that elements fromsrc can be moved into.
Returns:
The leftover portions of the two ranges after one or the other of theranges have been exhausted.
Examples:
int[5] a = [ 1, 2, 3, 4, 5 ];int[3] b;assert(moveSome(a[], b[])[0]is a[3 .. $]);writeln(a[0 .. 3]);// bwriteln(a);// [1, 2, 3, 4, 5]
@system Tuple!(InputRange1, InputRange2)moveEmplaceSome(InputRange1, InputRange2)(InputRange1src, InputRange2tgt)
if (isInputRange!InputRange1 && isInputRange!InputRange2 && is(typeof(move(src.front,tgt.front))));
Same asmoveSome but assumes all elements intgt are uninitialized. UsesmoveEmplace to move elements fromsrc over elements fromtgt.
Examples:
staticstruct Foo{    ~this()purenothrow @nogc {if (_ptr) ++*_ptr; }int* _ptr;}int[4] refs = [0, 1, 2, 3];Foo[4]src = [Foo(&refs[0]), Foo(&refs[1]), Foo(&refs[2]), Foo(&refs[3])];Foo[3] dst =void;auto res =moveEmplaceSome(src[], dst[]);writeln(res.length);// 2import std.algorithm.searching : all;assert(src[0 .. 3].all!(e => e._ptrisnull));assert(src[3]._ptr !isnull);assert(dst[].all!(e => e._ptr !isnull));
enumSwapStrategy: int;
Defines the swapping strategy for algorithms that need to swapelements in a range (such as partition and sort). The strategyconcerns the swapping of elements that are not the core concern of thealgorithm. For example, consider an algorithm that sorts[ "abc","b", "aBc" ] according totoUpper(a) < toUpper(b). Thatalgorithm might choose to swap the two equivalent strings"abc"and"aBc". That does not affect the sorting since both["abc", "aBc", "b" ] and[ "aBc", "abc", "b" ] are validoutcomes.
Some situations require that the algorithm must NOT ever change therelative ordering of equivalent elements (in the example above, only[ "abc", "aBc", "b" ] would be the correct result). Suchalgorithms are calledstable. If the ordering algorithm may swapequivalent elements discretionarily, the ordering is calledunstable.
Yet another class of algorithms may choose an intermediate tradeoff bybeing stable only on a well-defined subrange of the range. There is noestablished terminology for such behavior; this library calls itsemistable.
Generally, thestable ordering strategy may be more costly intime and/or space than the other two because it imposes additionalconstraints. Similarly,semistable may be costlier thanunstable. As (semi-)stability is not needed very often, the orderingalgorithms in this module parameterized bySwapStrategy allchooseSwapStrategy.unstable as the default.
Examples:
int[] a = [0, 1, 2, 3];writeln(remove!(SwapStrategy.stable)(a, 1));// [0, 2, 3]a = [0, 1, 2, 3];writeln(remove!(SwapStrategy.unstable)(a, 1));// [0, 3, 2]
Examples:
import std.algorithm.sorting : partition;// Put stuff greater than 3 on the leftauto arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];writeln(partition!(a => a > 3,SwapStrategy.stable)(arr));// [1, 2, 3]writeln(arr);// [4, 5, 6, 7, 8, 9, 10, 1, 2, 3]arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];writeln(partition!(a => a > 3,SwapStrategy.semistable)(arr));// [2, 3, 1]writeln(arr);// [4, 5, 6, 7, 8, 9, 10, 2, 3, 1]arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];writeln(partition!(a => a > 3,SwapStrategy.unstable)(arr));// [3, 2, 1]writeln(arr);// [10, 9, 8, 4, 5, 6, 7, 3, 2, 1]
unstable
Allows freely swapping of elements as long as the output satisfies the algorithm's requirements.
semistable
In algorithms partitioning ranges in two, preserve relative ordering of elements only to the left of the partition point.
stable
Preserve the relative ordering of elements to the largest extent allowed by the algorithm's requirements.
Rangeremove(SwapStrategy s = SwapStrategy.stable, Range, Offset...)(Rangerange, Offsetoffset)
if (Offset.length >= 1 && allSatisfy!(isValidIntegralTuple, Offset));

Rangeremove(SwapStrategy s = SwapStrategy.stable, Range, Offset...)(Rangerange, Offsetoffset)
if (Offset.length >= 1 && !allSatisfy!(isValidIntegralTuple, Offset));
Eliminates elements at given offsets fromrange and returns the shortenedrange.
For example, here is how to remove a single element from an array:
import std.algorithm.mutation;string[] a = ["a","b","c","d" ];a = a.remove(1);// remove element at offset 1assert(a == ["a","c","d"]);
Note thatremove does not change the length of the original range directly;instead, it returns the shortened range. If its return value is not assigned tothe original range, the original range will retain its original length, thoughits contents will have changed:
import std.algorithm.mutation;int[] a = [ 3, 5, 7, 8 ];assert(remove(a, 1) == [ 3, 7, 8 ]);assert(a == [ 3, 7, 8, 8 ]);
The element at offset1 has been removed and the rest of the elements haveshifted up to fill its place, however, the original array remains of the samelength. This is because all functions instd.algorithm only changecontent, nottopology. The value8 is repeated becausemove wasinvoked to rearrange elements, and on integersmove simply copies the sourceto the destination. To replacea with the effect of the removal, simplyassign the slice returned byremove to it, as shown in the first example.

Removing multiple elements

Multiple indices can be passed intoremove. In that case,elements at the respective indices are all removed. The indices mustbe passed in increasing order, otherwise an exception occurs.
import std.algorithm.mutation;int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];assert(remove(a, 1, 3, 5) ==    [ 0, 2, 4, 6, 7, 8, 9, 10 ]);
Note that all indices refer to slots in theoriginal array, notin the array as it is being progressively shortened.
Tuples of two integral offsets can be supplied to remove a range of indices:
import std.algorithm.mutation, std.typecons;int[] a = [ 3, 4, 5, 6, 7];// remove elements at indices 1 and 2assert(remove(a, tuple(1, 3)) == [ 3, 6, 7 ]);
The tuple passes in a range closed to the left and open tothe right (consistent with built-in slices), e.g.tuple(1, 3)means indices1 and2 but not3.
Finally, any combination of integral offsets and tuples composed of two integraloffsets can be passed in:
import std.algorithm.mutation, std.typecons;int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];a =remove(a, 1, tuple(3, 5), 9);assert(a == [ 0, 2, 5, 6, 7, 8, 10 ]);
In this case, the slots at positions 1, 3, 4, and 9 are removed fromthe array.

Moving strategy

If the need is to remove some elements in the range but the order ofthe remaining elements does not have to be preserved, you may want topassSwapStrategy.unstable toremove.
import std.algorithm.mutation;int[] a = [ 0, 1, 2, 3 ];assert(remove!(SwapStrategy.unstable)(a, 1) == [ 0, 3, 2 ]);
In the case above, the element at slot1 is removed, but replacedwith the last element of the range. Taking advantage of the relaxationof the stability requirement,remove moved elements from the endof the array over the slots to be removed. This way there is less datamovement to be done which improves the execution time of the function.
remove works on bidirectional ranges that have assignablelvalue elements. The moving strategy is (listed from fastest to slowest):
  • Ifs == SwapStrategy.unstable && isRandomAccessRange!Range &&hasLength!Range && hasLvalueElements!Range, then elements are moved from theend of the range into the slots to be filled. In this case, the absoluteminimum of moves is performed.
  • Otherwise, ifs ==SwapStrategy.unstable && isBidirectionalRange!Range && hasLength!Range&& hasLvalueElements!Range, then elements are still moved from theend of the range, but time is spent on advancing between slots by repeatedcalls torange.popFront.
  • Otherwise, elements are movedincrementally towards the front ofrange; a given element is nevermoved several times, but more elements are moved than in the previouscases.
Parameters:
sa SwapStrategy to determine if the original order needs to be preserved
Rangerangeabidirectional range with a length member
Offsetoffsetwhich element(s) to remove
Returns:
A range containing elements ofrange with 1 or more elements removed.
Examples:
import std.typecons : tuple;auto a = [ 0, 1, 2, 3, 4, 5 ];writeln(remove!(SwapStrategy.stable)(a, 1));// [0, 2, 3, 4, 5]a = [ 0, 1, 2, 3, 4, 5 ];writeln(remove!(SwapStrategy.stable)(a, 1, 3));// [0, 2, 4, 5]a = [ 0, 1, 2, 3, 4, 5 ];writeln(remove!(SwapStrategy.stable)(a, 1, tuple(3, 6)));// [0, 2]a = [ 0, 1, 2, 3, 4, 5 ];writeln(remove!(SwapStrategy.unstable)(a, 1));// [0, 5, 2, 3, 4]a = [ 0, 1, 2, 3, 4, 5 ];writeln(remove!(SwapStrategy.unstable)(a, tuple(1, 4)));// [0, 5, 4]
Examples:
import std.typecons : tuple;// Delete an indexwriteln([4, 5, 6].remove(1));// [4, 6]// Delete multiple indiceswriteln([4, 5, 6, 7, 8].remove(1, 3));// [4, 6, 8]// Use an indices rangewriteln([4, 5, 6, 7, 8].remove(tuple(1, 3)));// [4, 7, 8]// Use an indices range and individual indiceswriteln([4, 5, 6, 7, 8].remove(0, tuple(1, 3), 4));// [7]
Examples:
SwapStrategy.unstable is faster, but doesn't guarantee the same order of the original array
writeln([5, 6, 7, 8].remove!(SwapStrategy.stable)(1));// [5, 7, 8]writeln([5, 6, 7, 8].remove!(SwapStrategy.unstable)(1));// [5, 8, 7]
Rangeremove(alias pred, SwapStrategy s = SwapStrategy.stable, Range)(Rangerange);
Reduces the length of thebidirectional rangerange by removingelements that satisfypred. Ifs = SwapStrategy.unstable,elements are moved from the right end of the range over the elementsto eliminate. Ifs = SwapStrategy.stable (the default),elements are moved progressively to front such that their relativeorder is preserved. Returns the filtered range.
Parameters:
Rangerangea bidirectional ranges with lvalue elements or mutable character arrays
Returns:
the range with all of the elements wherepred istrue removed
Examples:
staticimmutable base = [1, 2, 3, 2, 4, 2, 5, 2];int[] arr = base[].dup;// using a string-based predicatewriteln(remove!("a == 2")(arr));// [1, 3, 4, 5]// The original array contents have been modified,// so we need to reset it to its original state.// The length is unmodified however.arr[] = base[];// using a lambda predicatewriteln(remove!(a => a == 2)(arr));// [1, 3, 4, 5]
Rangereverse(Range)(Ranger)
if (isBidirectionalRange!Range && (hasSwappableElements!Range || hasAssignableElements!Range && hasLength!Range && isRandomAccessRange!Range || isNarrowString!Range && isAssignable!(ElementType!Range)));
Reversesr in-place. Performsr.length / 2 evaluations ofswap.UTF sequences consisting of multiple code units are preserved properly.
Parameters:
Rangerabidirectional range with either swappable elements, a random access range with a length member, or a narrow string
Returns:
r

NoteWhen passing a string with unicode modifiers on characters, such as\u0301, this function will not properly keep the position of the modifier. For example, reversingba\u0301d ("bád") will result in d\u0301ab ("d́ab") instead ofda\u0301b ("dáb").

See Also:
std.range.retro for a lazy reverse without changingr
Examples:
int[] arr = [ 1, 2, 3 ];writeln(arr.reverse);// [3, 2, 1]
Examples:
char[] arr ="hello\U00010143\u0100\U00010143".dup;writeln(arr.reverse);// "\U00010143\u0100\U00010143olleh"
Rangestrip(Range, E)(Rangerange, Eelement)
if (isBidirectionalRange!Range && is(typeof(range.front ==element) : bool));

Rangestrip(alias pred, Range)(Rangerange)
if (isBidirectionalRange!Range && is(typeof(pred(range.back)) : bool));

RangestripLeft(Range, E)(Rangerange, Eelement)
if (isInputRange!Range && is(typeof(range.front ==element) : bool));

RangestripLeft(alias pred, Range)(Rangerange)
if (isInputRange!Range && is(typeof(pred(range.front)) : bool));

RangestripRight(Range, E)(Rangerange, Eelement)
if (isBidirectionalRange!Range && is(typeof(range.back ==element) : bool));

RangestripRight(alias pred, Range)(Rangerange)
if (isBidirectionalRange!Range && is(typeof(pred(range.back)) : bool));
The strip group of functions allow stripping of either leading, trailing, or both leading and trailing elements.
ThestripLeft function will strip thefront of the range, thestripRight function will strip theback of the range, while thestrip function will strip both thefront andback of the range.
Note that thestrip andstripRight functions require the range to be aBidirectionalRange range.
All of these functions come in two varieties: one takes a target element, where the range will be stripped as long as this element can be found. The other takes a lambda predicate, where the range will be stripped as long as the predicate returns true.
Parameters:
Rangerangeabidirectional range orinput range
Eelementthe elements to remove
Returns:
a Range with all of range except element at the start and end
Examples:
Strip leading and trailing elements equal to the target element.
writeln("  foobar  ".strip(' '));// "foobar"writeln("00223.444500".strip('0'));// "223.4445"writeln("ëëêéüŗōpéêëë".strip('ë'));// "êéüŗōpéê"writeln([1, 1, 0, 1, 1].strip(1));// [0]writeln([0.0, 0.01, 0.01, 0.0].strip(0).length);// 2
Examples:
Strip leading and trailing elements while the predicate returns true.
writeln("  foobar  ".strip!(a => a == ' ')());// "foobar"writeln("00223.444500".strip!(a => a == '0')());// "223.4445"writeln("ëëêéüŗōpéêëë".strip!(a => a == 'ë')());// "êéüŗōpéê"writeln([1, 1, 0, 1, 1].strip!(a => a == 1)());// [0]writeln([0.0, 0.01, 0.5, 0.6, 0.01, 0.0].strip!(a => a < 0.4)().length);// 2
Examples:
Strip leading elements equal to the target element.
writeln("  foobar  ".stripLeft(' '));// "foobar  "writeln("00223.444500".stripLeft('0'));// "223.444500"writeln("ůůűniçodêéé".stripLeft('ů'));// "űniçodêéé"writeln([1, 1, 0, 1, 1].stripLeft(1));// [0, 1, 1]writeln([0.0, 0.01, 0.01, 0.0].stripLeft(0).length);// 3
Examples:
Strip leading elements while the predicate returns true.
writeln("  foobar  ".stripLeft!(a => a == ' ')());// "foobar  "writeln("00223.444500".stripLeft!(a => a == '0')());// "223.444500"writeln("ůůűniçodêéé".stripLeft!(a => a == 'ů')());// "űniçodêéé"writeln([1, 1, 0, 1, 1].stripLeft!(a => a == 1)());// [0, 1, 1]writeln([0.0, 0.01, 0.10, 0.5, 0.6].stripLeft!(a => a < 0.4)().length);// 2
Examples:
Strip trailing elements equal to the target element.
writeln("  foobar  ".stripRight(' '));// "  foobar"writeln("00223.444500".stripRight('0'));// "00223.4445"writeln("ùniçodêéé".stripRight('é'));// "ùniçodê"writeln([1, 1, 0, 1, 1].stripRight(1));// [1, 1, 0]writeln([0.0, 0.01, 0.01, 0.0].stripRight(0).length);// 3
Examples:
Strip trailing elements while the predicate returns true.
writeln("  foobar  ".stripRight!(a => a == ' ')());// "  foobar"writeln("00223.444500".stripRight!(a => a == '0')());// "00223.4445"writeln("ùniçodêéé".stripRight!(a => a == 'é')());// "ùniçodê"writeln([1, 1, 0, 1, 1].stripRight!(a => a == 1)());// [1, 1, 0]writeln([0.0, 0.01, 0.10, 0.5, 0.6].stripRight!(a => a > 0.4)().length);// 3
voidswap(T)(ref Tlhs, ref Trhs)
if (is(typeof(lhs.proxySwap(rhs))));

pure nothrow @nogc @trusted voidswap(T)(ref Tlhs, ref Trhs)
if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs))));
Swapslhs andrhs. The instanceslhs andrhs are moved inmemory, without ever callingopAssign, nor any other function.Tneed not be assignable at all to be swapped.
Iflhs andrhs reference the same instance, then nothing is done.
lhs andrhs must be mutable. IfT is a struct or union, thenits fields must also all be (recursively) mutable.
Parameters:
TlhsData to be swapped withrhs.
TrhsData to be swapped withlhs.
Examples:
// Swapping POD (plain old data) types:int a = 42, b = 34;swap(a, b);assert(a == 34 && b == 42);// Swapping structs with indirection:staticstruct S {int x;char c;int[] y; }S s1 = { 0, 'z', [ 1, 2 ] };S s2 = { 42, 'a', [ 4, 6 ] };swap(s1, s2);writeln(s1.x);// 42writeln(s1.c);// 'a'writeln(s1.y);// [4, 6]writeln(s2.x);// 0writeln(s2.c);// 'z'writeln(s2.y);// [1, 2]// Immutables cannot be swapped:immutableint imm1 = 1, imm2 = 2;staticassert(!__traits(compiles,swap(imm1, imm2)));int c = imm1 + 0;int d = imm2 + 0;swap(c, d);writeln(c);// 2writeln(d);// 1
Examples:
// Non-copyable types can still be swapped.staticstruct NoCopy{this(this) {assert(0); }int n;    string s;}NoCopy nc1, nc2;nc1.n = 127; nc1.s ="abc";nc2.n = 513; nc2.s ="uvwxyz";swap(nc1, nc2);assert(nc1.n == 513 && nc1.s =="uvwxyz");assert(nc2.n == 127 && nc2.s =="abc");swap(nc1, nc1);swap(nc2, nc2);assert(nc1.n == 513 && nc1.s =="uvwxyz");assert(nc2.n == 127 && nc2.s =="abc");// Types containing non-copyable fields can also be swapped.staticstruct NoCopyHolder{    NoCopy noCopy;}NoCopyHolder h1, h2;h1.noCopy.n = 31; h1.noCopy.s ="abc";h2.noCopy.n = 65; h2.noCopy.s =null;swap(h1, h2);assert(h1.noCopy.n == 65 && h1.noCopy.s ==null);assert(h2.noCopy.n == 31 && h2.noCopy.s =="abc");swap(h1, h1);swap(h2, h2);assert(h1.noCopy.n == 65 && h1.noCopy.s ==null);assert(h2.noCopy.n == 31 && h2.noCopy.s =="abc");// Const types cannot be swapped.const NoCopy const1, const2;assert(const1.n == 0 && const2.n == 0);staticassert(!__traits(compiles,swap(const1, const2)));
voidswapAt(R)(auto ref Rr, size_ti1, size_ti2);
Swaps two elements in-place of a ranger,specified by their indicesi1 andi2.
Parameters:
Rra range with swappable elements
size_ti1first index
size_ti2second index
Examples:
import std.algorithm.comparison : equal;auto a = [1, 2, 3];a.swapAt(1, 2);assert(a.equal([1, 3, 2]));
Tuple!(InputRange1, InputRange2)swapRanges(InputRange1, InputRange2)(InputRange1r1, InputRange2r2)
if (hasSwappableElements!InputRange1 && hasSwappableElements!InputRange2 && is(ElementType!InputRange1 == ElementType!InputRange2));
Swaps all elements ofr1 with successive elements inr2.Returns a tuple containing the remainder portions ofr1 andr2 that were not swapped (one of them will be empty). The ranges maybe of different types but must have the same element type and supportswapping.
Parameters:
InputRange1r1aninput range with swappable elements
InputRange2r2aninput range with swappable elements
Returns:
Tuple containing the remainder portions of r1 and r2 that were not swapped
Examples:
import std.range : empty;int[] a = [ 100, 101, 102, 103 ];int[] b = [ 0, 1, 2, 3 ];auto c =swapRanges(a[1 .. 3], b[2 .. 4]);assert(c[0].empty && c[1].empty);writeln(a);// [100, 2, 3, 103]writeln(b);// [0, 1, 101, 102]
voiduninitializedFill(Range, Value)(Rangerange, Valuevalue)
if (isInputRange!Range && hasLvalueElements!Range && is(typeof(range.front =value)));
Initializes each element ofrange withvalue.Assumes that the elements of the range are uninitialized.This is of interest for structs thatdefine copy constructors (for all other types,fill anduninitializedFill are equivalent).
Parameters:
RangerangeAninput range that exposes references to its elements and has assignable elements
ValuevalueAssigned to each element of range
See Also:
Examples:
import core.stdc.stdlib : malloc, free;auto s = (cast(int*) malloc(5 *int.sizeof))[0 .. 5];uninitializedFill(s, 42);writeln(s);// [42, 42, 42, 42, 42]scope(exit) free(s.ptr);
Copyright © 1999-2025 by theD Language Foundation | Page generated byDdoc on Fri Oct 10 22:10:22 2025

[8]ページ先頭

©2009-2025 Movatter.jp