Replace rotate with bringToFront

This commit is contained in:
Eugen Wissner 2021-06-04 09:37:50 +02:00
parent c15a8993ec
commit 0155039071
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 6 additions and 90 deletions

View File

@ -244,54 +244,3 @@ if (isInputRange!Range && hasLvalueElements!Range)
assert(counter == 2); assert(counter == 2);
} }
/**
* Rotates the elements of a union of two ranges.
*
* Performs a left rotation on the given ranges, as if it would be a signle
* range, so that [`front.front`, `back.front`$(RPAREN) is a valid range, that
* is $(D_PARAM back) would continue $(D_PARAM front).
*
* The elements are moved so, that the first element of $(D_PARAM back) becomes
* the first element of $(D_PARAM front) without changing the relative order of
* their elements.
*
* Params:
* Range = Range type.
* front = Left half.
* back = Right half.
*/
void rotate(Range)(Range front, Range back)
if (isForwardRange!Range && hasSwappableElements!Range)
{
auto next = back.save();
while (!front.empty && !next.empty && !sameHead(front, next))
{
tanya.memory.lifetime.swap(front.front, next.front);
front.popFront();
next.popFront();
if (next.empty)
{
next = back.save();
}
else if (front.empty)
{
front = back.save();
back = next.save();
}
}
}
///
@nogc nothrow pure @safe unittest
{
import std.algorithm.comparison : equal;
const int[7] expected = [1, 2, 3, 4, 5, 6, 7];
int[7] actual = [5, 6, 3, 4, 1, 2, 7];
rotate(actual[0 .. 2], actual[4 .. 6]);
assert(equal(actual[], expected[]));
}

View File

@ -17,6 +17,7 @@ module tanya.container.array;
import core.checkedint; import core.checkedint;
import std.algorithm.comparison; import std.algorithm.comparison;
import std.algorithm.iteration; import std.algorithm.iteration;
import std.algorithm.mutation : bringToFront;
import tanya.algorithm.mutation; import tanya.algorithm.mutation;
import tanya.memory.allocator; import tanya.memory.allocator;
import tanya.memory.lifetime; import tanya.memory.lifetime;
@ -815,7 +816,7 @@ struct Array(T)
const after = r.end - this.data; const after = r.end - this.data;
const inserted = insertBack(el); const inserted = insertBack(el);
rotate(this.data[after .. oldLength], this.data[oldLength .. length]); bringToFront(this.data[after .. oldLength], this.data[oldLength .. length]);
return inserted; return inserted;
} }
@ -854,7 +855,7 @@ struct Array(T)
{ {
moveBack(el); moveBack(el);
} }
rotate(this.data[offset .. oldLen], this.data[oldLen .. length]); bringToFront(this.data[offset .. oldLen], this.data[oldLen .. length]);
return 1; return 1;
} }
@ -910,7 +911,7 @@ struct Array(T)
{ {
moveBack(el); moveBack(el);
} }
rotate(this.data[offset .. oldLen], this.data[oldLen .. length]); bringToFront(this.data[offset .. oldLen], this.data[oldLen .. length]);
return 1; return 1;
} }

View File

@ -27,6 +27,7 @@
module tanya.container.string; module tanya.container.string;
import std.algorithm.comparison; import std.algorithm.comparison;
import std.algorithm.mutation : bringToFront;
import tanya.algorithm.mutation; import tanya.algorithm.mutation;
import tanya.hash.lookup; import tanya.hash.lookup;
import tanya.memory.allocator; import tanya.memory.allocator;
@ -1488,7 +1489,7 @@ struct String
const after = r.end - this.data; const after = r.end - this.data;
const inserted = insertBack(el); const inserted = insertBack(el);
rotate(this.data[after .. oldLength], this.data[oldLength .. length]); bringToFront(this.data[after .. oldLength], this.data[oldLength .. length]);
return inserted; return inserted;
} }

View File

@ -95,38 +95,3 @@ import tanya.test.stub;
NonCopyable[] nonCopyable; NonCopyable[] nonCopyable;
initializeAll(nonCopyable); initializeAll(nonCopyable);
} }
@nogc nothrow pure @safe unittest
{
import std.algorithm.comparison : equal;
const int[5] expected = [1, 2, 3, 4, 5];
int[5] actual = [4, 5, 1, 2, 3];
rotate(actual[0 .. 2], actual[2 .. $]);
assert(equal(actual[], expected[]));
}
// Doesn't cause an infinite loop if back is shorter than the front
@nogc nothrow pure @safe unittest
{
import std.algorithm.comparison : equal;
const int[5] expected = [1, 2, 3, 4, 5];
int[5] actual = [3, 4, 5, 1, 2];
rotate(actual[0 .. 3], actual[3 .. $]);
assert(equal(actual[], expected[]));
}
// Doesn't call .front on an empty front
@nogc nothrow pure @safe unittest
{
import std.algorithm.comparison : equal;
const int[2] expected = [2, 8];
int[2] actual = expected;
rotate(actual[0 .. 0], actual[]);
assert(equal(actual[], expected[]));
}