mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 06:30:28 +03:00
Unify all reverse overloads into one
This commit is contained in:
parent
3acaa9d53a
commit
f7b69b2f0a
1 changed files with 49 additions and 49 deletions
|
@ -78,7 +78,7 @@ T2=$(TR $(TDNW $(LREF $1)) $(TD $+))
|
|||
module std.algorithm.mutation;
|
||||
|
||||
import std.range.primitives;
|
||||
import std.traits : isArray, isBlitAssignable, isNarrowString, Unqual, isSomeChar;
|
||||
import std.traits : isArray, isAssignable, isBlitAssignable, isNarrowString, Unqual, isSomeChar;
|
||||
// FIXME
|
||||
import std.typecons; // : tuple, Tuple;
|
||||
|
||||
|
@ -2185,7 +2185,7 @@ Params:
|
|||
with either swappable elements, a random access range with a length member,
|
||||
or a narrow string
|
||||
|
||||
Returns: the reversed range
|
||||
Returns: `r`
|
||||
|
||||
Note:
|
||||
When passing a string with unicode modifiers on characters, such as `\u0301`,
|
||||
|
@ -2195,18 +2195,56 @@ Note:
|
|||
|
||||
See_Also: $(REF retro, std,range) for a lazy reverse without changing `r`
|
||||
*/
|
||||
auto reverse(Range)(Range r)
|
||||
if (isBidirectionalRange!Range && !isRandomAccessRange!Range
|
||||
&& hasSwappableElements!Range)
|
||||
Range reverse(Range)(Range r)
|
||||
if (isBidirectionalRange!Range &&
|
||||
(hasSwappableElements!Range ||
|
||||
(hasAssignableElements!Range && hasLength!Range && isRandomAccessRange!Range) ||
|
||||
(isNarrowString!Range && isAssignable!(ElementType!Range))))
|
||||
{
|
||||
while (!r.empty)
|
||||
static if (isRandomAccessRange!Range && hasLength!Range)
|
||||
{
|
||||
swap(r.front, r.back);
|
||||
r.popFront();
|
||||
if (r.empty) break;
|
||||
r.popBack();
|
||||
//swapAt is in fact the only way to swap non lvalue ranges
|
||||
immutable last = r.length - 1;
|
||||
immutable steps = r.length / 2;
|
||||
for (size_t i = 0; i < steps; i++)
|
||||
{
|
||||
r.swapAt(i, last - i);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
else static if (isNarrowString!Range && isAssignable!(ElementType!Range))
|
||||
{
|
||||
import std.string : representation;
|
||||
import std.utf : stride;
|
||||
|
||||
auto raw = representation(r);
|
||||
for (size_t i = 0; i < r.length;)
|
||||
{
|
||||
immutable step = stride(r, i);
|
||||
if (step > 1)
|
||||
{
|
||||
.reverse(raw[i .. i + step]);
|
||||
i += step;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
reverse(raw);
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!r.empty)
|
||||
{
|
||||
swap(r.front, r.back);
|
||||
r.popFront();
|
||||
if (r.empty) break;
|
||||
r.popBack();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -2216,20 +2254,6 @@ if (isBidirectionalRange!Range && !isRandomAccessRange!Range
|
|||
assert(arr.reverse == [ 3, 2, 1 ]);
|
||||
}
|
||||
|
||||
///ditto
|
||||
auto reverse(Range)(Range r)
|
||||
if (isRandomAccessRange!Range && hasLength!Range)
|
||||
{
|
||||
//swapAt is in fact the only way to swap non lvalue ranges
|
||||
immutable last = r.length-1;
|
||||
immutable steps = r.length/2;
|
||||
for (size_t i = 0; i < steps; i++)
|
||||
{
|
||||
r.swapAt(i, last-i);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
int[] range = null;
|
||||
|
@ -2244,30 +2268,6 @@ if (isRandomAccessRange!Range && hasLength!Range)
|
|||
assert(range.reverse == [3, 2, 1]);
|
||||
}
|
||||
|
||||
///ditto
|
||||
auto reverse(Char)(Char[] s)
|
||||
if (isNarrowString!(Char[]) && !is(Char == const) && !is(Char == immutable))
|
||||
{
|
||||
import std.string : representation;
|
||||
import std.utf : stride;
|
||||
|
||||
auto r = representation(s);
|
||||
for (size_t i = 0; i < s.length; )
|
||||
{
|
||||
immutable step = stride(s, i);
|
||||
if (step > 1)
|
||||
{
|
||||
.reverse(r[i .. i + step]);
|
||||
i += step;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return reverse(r);
|
||||
}
|
||||
|
||||
///
|
||||
@safe unittest
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue