mirror of
https://github.com/dlang/phobos.git
synced 2025-04-30 15:10:46 +03:00
[Static if] replace overload constraints with static if (mutation.d)
This commit is contained in:
parent
78acf07136
commit
c6819e2d6e
1 changed files with 260 additions and 267 deletions
|
@ -368,8 +368,10 @@ See_Also:
|
|||
$(HTTP sgi.com/tech/stl/_copy.html, STL's _copy)
|
||||
*/
|
||||
TargetRange copy(SourceRange, TargetRange)(SourceRange source, TargetRange target)
|
||||
if (areCopyCompatibleArrays!(SourceRange, TargetRange))
|
||||
if (isInputRange!SourceRange)
|
||||
{
|
||||
static if (areCopyCompatibleArrays!(SourceRange, TargetRange))
|
||||
{
|
||||
const tlen = target.length;
|
||||
const slen = source.length;
|
||||
assert(tlen >= slen,
|
||||
|
@ -393,14 +395,9 @@ if (areCopyCompatibleArrays!(SourceRange, TargetRange))
|
|||
target[0 .. slen] = source[];
|
||||
return target[slen .. $];
|
||||
}
|
||||
}
|
||||
|
||||
/// ditto
|
||||
TargetRange copy(SourceRange, TargetRange)(SourceRange source, TargetRange target)
|
||||
if (!areCopyCompatibleArrays!(SourceRange, TargetRange) &&
|
||||
isInputRange!SourceRange &&
|
||||
isOutputRange!(TargetRange, ElementType!SourceRange))
|
||||
{
|
||||
}
|
||||
else static if (isOutputRange!(TargetRange, ElementType!SourceRange))
|
||||
{
|
||||
// Specialize for 2 random access ranges.
|
||||
// Typically 2 random access ranges are faster iterated by common
|
||||
// index than by x.popFront(), y.popFront() pair
|
||||
|
@ -420,6 +417,13 @@ if (!areCopyCompatibleArrays!(SourceRange, TargetRange) &&
|
|||
put(target, source);
|
||||
return target;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
enum msg = "TargetRange is neither copy-compatible with the SourceRange" ~
|
||||
"nor an OutputRange with the same ElementType.";
|
||||
static assert(0, msg);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -843,8 +847,10 @@ See_Also:
|
|||
$(LREF uninitializeFill)
|
||||
*/
|
||||
void initializeAll(Range)(Range range)
|
||||
if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range)
|
||||
if (isInputRange!Range)
|
||||
{
|
||||
static if (hasLvalueElements!Range && hasAssignableElements!Range)
|
||||
{
|
||||
import core.stdc.string : memset, memcpy;
|
||||
import std.traits : hasElaborateAssign, isDynamicArray;
|
||||
|
||||
|
@ -888,14 +894,13 @@ if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range
|
|||
}
|
||||
else
|
||||
fill(range, T.init);
|
||||
}
|
||||
|
||||
/// ditto
|
||||
void initializeAll(Range)(Range range)
|
||||
if (is(Range == char[]) || is(Range == wchar[]))
|
||||
{
|
||||
}
|
||||
else static if (is(Range == char[]) || is(Range == wchar[]))
|
||||
{
|
||||
alias T = ElementEncodingType!Range;
|
||||
range[] = T.init;
|
||||
}
|
||||
else static assert(0, "Range doesn't have assignable elements.");
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -1745,12 +1750,13 @@ Returns:
|
|||
Range remove
|
||||
(SwapStrategy s = SwapStrategy.stable, Range, Offset...)
|
||||
(Range range, Offset offset)
|
||||
if (s != SwapStrategy.stable
|
||||
&& isBidirectionalRange!Range
|
||||
if (isBidirectionalRange!Range
|
||||
&& hasLvalueElements!Range
|
||||
&& hasLength!Range
|
||||
&& Offset.length >= 1)
|
||||
{
|
||||
static if (s == SwapStrategy.unstable)
|
||||
{
|
||||
Tuple!(size_t, "pos", size_t, "len")[offset.length] blackouts;
|
||||
foreach (i, v; offset)
|
||||
{
|
||||
|
@ -1826,17 +1832,9 @@ if (s != SwapStrategy.stable
|
|||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
/// Ditto
|
||||
Range remove
|
||||
(SwapStrategy s = SwapStrategy.stable, Range, Offset...)
|
||||
(Range range, Offset offset)
|
||||
if (s == SwapStrategy.stable
|
||||
&& isBidirectionalRange!Range
|
||||
&& hasLvalueElements!Range
|
||||
&& Offset.length >= 1)
|
||||
{
|
||||
}
|
||||
else static if (s == SwapStrategy.stable)
|
||||
{
|
||||
auto result = range;
|
||||
auto src = range, tgt = range;
|
||||
size_t pos;
|
||||
|
@ -1877,6 +1875,8 @@ if (s == SwapStrategy.stable
|
|||
// leftover move
|
||||
moveAll(src, tgt);
|
||||
return result;
|
||||
}
|
||||
else static assert(0, "SwapStrategy.semistable is not supported.");
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -2132,17 +2132,37 @@ if (isBidirectionalRange!Range
|
|||
/**
|
||||
Reverses $(D r) in-place. Performs $(D r.length / 2) evaluations of $(D
|
||||
swap).
|
||||
UTF sequences consisting of multiple code units are preserved properly.
|
||||
|
||||
Params:
|
||||
r = a $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives)
|
||||
with swappable elements or a random access range with a length member
|
||||
with swappable elements, a random access range with a length member or a
|
||||
narrow string.
|
||||
|
||||
See_Also:
|
||||
$(HTTP sgi.com/tech/stl/_reverse.html, STL's _reverse), $(REF retro, std,range) for a lazy reversed range view
|
||||
|
||||
Bugs:
|
||||
When passing a sting with unicode modifiers on characters, such as $(D \u0301),
|
||||
this function will not properly keep the position of the modifier. For example,
|
||||
reversing $(D ba\u0301d) ("bád") will result in d\u0301ab ("d́ab") instead of
|
||||
$(D da\u0301b) ("dáb").
|
||||
*/
|
||||
void reverse(Range)(Range r)
|
||||
if (isBidirectionalRange!Range && !isRandomAccessRange!Range
|
||||
&& hasSwappableElements!Range)
|
||||
if (isBidirectionalRange!Range)
|
||||
{
|
||||
static if (isRandomAccessRange!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);
|
||||
}
|
||||
}
|
||||
else static if (hasSwappableElements!Range)
|
||||
{
|
||||
while (!r.empty)
|
||||
{
|
||||
swap(r.front, r.back);
|
||||
|
@ -2150,6 +2170,29 @@ if (isBidirectionalRange!Range && !isRandomAccessRange!Range
|
|||
if (r.empty) break;
|
||||
r.popBack();
|
||||
}
|
||||
}
|
||||
else static if (isNarrowString!Range && !is(ElementType!Range == const) && !is(ElementType!Range == immutable))
|
||||
{
|
||||
import std.string : representation;
|
||||
import std.utf : stride;
|
||||
|
||||
auto repr = representation(r);
|
||||
for (size_t i = 0; i < r.length; )
|
||||
{
|
||||
immutable step = stride(r, i);
|
||||
if (step > 1)
|
||||
{
|
||||
.reverse(repr[i .. i + step]);
|
||||
i += step;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
reverse(repr);
|
||||
}
|
||||
else static assert(0, "Range is neither RandomAccess, has swappable elements nor a narrow string.");
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -2160,17 +2203,12 @@ if (isBidirectionalRange!Range && !isRandomAccessRange!Range
|
|||
assert(arr == [ 3, 2, 1 ]);
|
||||
}
|
||||
|
||||
///ditto
|
||||
void reverse(Range)(Range r)
|
||||
if (isRandomAccessRange!Range && hasLength!Range)
|
||||
///
|
||||
@safe unittest
|
||||
{
|
||||
//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);
|
||||
}
|
||||
char[] arr = "hello\U00010143\u0100\U00010143".dup;
|
||||
reverse(arr);
|
||||
assert(arr == "\U00010143\u0100\U00010143olleh");
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
|
@ -2188,51 +2226,6 @@ if (isRandomAccessRange!Range && hasLength!Range)
|
|||
assert(range == [3, 2, 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
Reverses $(D r) in-place, where $(D r) is a narrow string (having
|
||||
elements of type $(D char) or $(D wchar)). UTF sequences consisting of
|
||||
multiple code units are preserved properly.
|
||||
|
||||
Params:
|
||||
s = a narrow string
|
||||
|
||||
Bugs:
|
||||
When passing a sting with unicode modifiers on characters, such as $(D \u0301),
|
||||
this function will not properly keep the position of the modifier. For example,
|
||||
reversing $(D ba\u0301d) ("bád") will result in d\u0301ab ("d́ab") instead of
|
||||
$(D da\u0301b) ("dáb").
|
||||
*/
|
||||
void 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;
|
||||
}
|
||||
}
|
||||
reverse(r);
|
||||
}
|
||||
|
||||
///
|
||||
@safe unittest
|
||||
{
|
||||
char[] arr = "hello\U00010143\u0100\U00010143".dup;
|
||||
reverse(arr);
|
||||
assert(arr == "\U00010143\u0100\U00010143olleh");
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
void test(string a, string b)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue