std.algorithm.mutation
This is a submodule of std.algorithm. It contains generic mutation algorithms.
Copyright
Types 1
Defines the swapping strategy for algorithms that need to swap elements in a range (such as partition and sort). The strategy concerns the swapping of elements that are not the core concern of the algorithm. For example, consider an algorithm that sorts [ "abc", "b", "aBc" ] according to toUpper(a) < toUpper(b). That algorithm 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 valid outcomes.
Some situations require that the algorithm must NOT ever change the relative ordering of equivalent elements (in the example above, only [ "abc", "aBc", "b" ] would be the correct result). Such algorithms are called stable. If the ordering algorithm may swap equivalent elements discretionarily, the ordering is called unstable.
Yet another class of algorithms may choose an intermediate tradeoff by being stable only on a well-defined subrange of the range. There is no established terminology for such behavior; this library calls it semistable.
Generally, the stable ordering strategy may be more costly in time and/or space than the other two because it imposes additional constraints. Similarly, semistable may be costlier than unstable. As (semi-)stability is not needed very often, the ordering algorithms in this module parameterized by SwapStrategy all choose SwapStrategy.unstable as the default.
Functions 43
size_t bringToFront(InputRange, ForwardRange)(InputRange front, ForwardRange back) if (isInputRange!InputRange && isForwardRange!ForwardRange)`bringToFront` takes two ranges `front` and `back`, which may be of different types. Considering the concatenation of `front` and `back` one unified range, `bringToFront` rotates that unified range...size_t bringToFrontImpl(InputRange, ForwardRange)(InputRange front, ForwardRange back) if (isInputRange!InputRange && isForwardRange!ForwardRange)TargetRange copy(SourceRange, TargetRange)(SourceRange source, TargetRange target) if (isInputRange!SourceRange && isOutputRange!(TargetRange, ElementType!SourceRange))Copies the content of `source` into `target` and returns the remaining (unfilled) part of `target`.void fill(Range, Value)(auto ref Range range, auto ref Value value) if ((isInputRange!Range && is(typeof(range.front = value)) ||
isSomeChar!Value && is(typeof(range[] = value))))Assigns `value` to each element of input range `range`.void fill(InputRange, ForwardRange)(InputRange range, ForwardRange filler) if (isInputRange!InputRange
&& (isForwardRange!ForwardRange
|| (isInputRange!ForwardRange && isInfinite!ForwardRange))
&& is(typeof(InputRange.init.front = ForwardRange.init.front)))dittovoid initializeAll(Range)(Range range) if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range
&& __traits(compiles, { static ElementType!Range _; }))Initializes all elements of `range` with their `.init` value. Assumes that the elements of the range are uninitialized.void move(T)(ref T source, ref T target) if (__traits(compiles, target = T.init))Moves `source` into `target`, via a destructive copy when necessary.void moveEmplace(T)(ref T source, ref T target) pure @systemSimilar to move but assumes `target` is uninitialized. This is more efficient because `source` can be blitted over `target` without destroying or initializing it first.InputRange2 moveAll(InputRange1, InputRange2)(InputRange1 src, InputRange2 tgt) if (isInputRange!InputRange1 && isInputRange!InputRange2
&& is(typeof(move(src.front, tgt.front))))Calls `move(a, b)` for each element `a` in `src` and the corresponding element `b` in `tgt`, in increasing order.InputRange2 moveEmplaceAll(InputRange1, InputRange2)(InputRange1 src, InputRange2 tgt) if (isInputRange!InputRange1 && isInputRange!InputRange2
&& is(typeof(moveEmplace(src.front, tgt.front)))) @systemSimilar to moveAll but assumes all elements in `tgt` are uninitialized. Uses moveEmplace to move elements from `src` over elements from `tgt`.InputRange2 moveAllImpl(alias moveOp, InputRange1, InputRange2)(
ref InputRange1 src, ref InputRange2 tgt)Tuple!(InputRange1, InputRange2) moveSome(InputRange1, InputRange2)(InputRange1 src, InputRange2 tgt) if (isInputRange!InputRange1 && isInputRange!InputRange2
&& is(typeof(move(src.front, tgt.front))))Calls `move(a, b)` for each element `a` in `src` and the corresponding element `b` in `tgt`, in increasing order, stopping when either range has been exhausted.Tuple!(InputRange1, InputRange2) moveEmplaceSome(InputRange1, InputRange2)(InputRange1 src, InputRange2 tgt) if (isInputRange!InputRange1 && isInputRange!InputRange2
&& is(typeof(move(src.front, tgt.front)))) @systemSame as moveSome but assumes all elements in `tgt` are uninitialized. Uses moveEmplace to move elements from `src` over elements from `tgt`.Tuple!(InputRange1, InputRange2) moveSomeImpl(alias moveOp, InputRange1, InputRange2)(
ref InputRange1 src, ref InputRange2 tgt)Range remove(SwapStrategy s = SwapStrategy.stable, Range, Offset ...)(Range range, Offset offset) if (Offset.length >= 1 && allSatisfy!(isValidIntegralTuple, Offset))Eliminates elements at given offsets from `range` and returns the shortened range.Range remove(SwapStrategy s = SwapStrategy.stable, Range, Offset ...)(Range range, Offset offset) if (Offset.length >= 1 && !allSatisfy!(isValidIntegralTuple, Offset))Range remove(alias pred, SwapStrategy s = SwapStrategy.stable, Range)(Range range)Reduces the length of the bidirectional range `range` by removing elements that satisfy `pred`. If `s = SwapStrategy.unstable`, elements are moved from the right end of the range over the elements ...Range removePredString(alias pred, SwapStrategy s = SwapStrategy.stable, Range)(Range range)Range reverse(Range)(Range r) if (isBidirectionalRange!Range &&
(hasSwappableElements!Range ||
(hasAssignableElements!Range && hasLength!Range && isRandomAccessRange!Range) ||
(isNarrowString!Range && isAssignable!(ElementType!Range))))Reverses `r` in-place. Performs `r.length / 2` evaluations of `swap`. UTF sequences consisting of multiple code units are preserved properly.Range strip(Range, E)(Range range, E element) if (isBidirectionalRange!Range && is(typeof(range.front == element) : bool))The strip group of functions allow stripping of either leading, trailing, or both leading and trailing elements.Range strip(alias pred, Range)(Range range) if (isBidirectionalRange!Range && is(typeof(pred(range.back)) : bool))dittoRange stripLeft(Range, E)(Range range, E element) if (isInputRange!Range && is(typeof(range.front == element) : bool))dittoRange stripLeft(alias pred, Range)(Range range) if (isInputRange!Range && is(typeof(pred(range.front)) : bool))dittoRange stripRight(Range, E)(Range range, E element) if (isBidirectionalRange!Range && is(typeof(range.back == element) : bool))dittoRange stripRight(alias pred, Range)(Range range) if (isBidirectionalRange!Range && is(typeof(pred(range.back)) : bool))dittovoid swap(T)(ref T lhs, ref T rhs) if (is(typeof(lhs.proxySwap(rhs))))Swaps `lhs` and `rhs`. The instances `lhs` and `rhs` are moved in memory, without ever calling `opAssign`, nor any other function. `T` need not be assignable at all to be swapped.void swap(T)(ref T lhs, ref T rhs) if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs)))) @trusted pure nothrow @nogcdittovoid swapAt(R)(auto ref R r, size_t i1, size_t i2)Swaps two elements in-place of a range `r`, specified by their indices `i1` and `i2`.Tuple!(InputRange1, InputRange2) swapRanges(InputRange1, InputRange2)(InputRange1 r1, InputRange2 r2) if (hasSwappableElements!InputRange1 && hasSwappableElements!InputRange2
&& is(ElementType!InputRange1 == ElementType!InputRange2))Swaps all elements of `r1` with successive elements in `r2`. Returns a tuple containing the remainder portions of `r1` and r2 that were not swapped (one of them will be empty). The ranges may be of...void uninitializedFill(Range, Value)(Range range, Value value) if (isInputRange!Range && hasLvalueElements!Range && is(typeof(range.front = value)))Initializes each element of `range` with `value`. Assumes that the elements of the range are uninitialized. This is of interest for structs that define copy constructors (for all other types, fill ...Variables 1
areCopyCompatibleArrays = isArray!T1 && isArray!T2 && is(typeof(T2.init[] = T1.init[]))Templates 2
if (!__traits(compiles, imported!"std.traits".lvalueOf!T = T.init))ditto