[Static if] replace overload constraints with static if (mutation.d)

This commit is contained in:
Sebastian Wilzbach 2017-02-18 03:47:16 +01:00
parent 78acf07136
commit c6819e2d6e

View file

@ -368,8 +368,10 @@ See_Also:
$(HTTP sgi.com/tech/stl/_copy.html, STL's _copy) $(HTTP sgi.com/tech/stl/_copy.html, STL's _copy)
*/ */
TargetRange copy(SourceRange, TargetRange)(SourceRange source, TargetRange target) 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 tlen = target.length;
const slen = source.length; const slen = source.length;
assert(tlen >= slen, assert(tlen >= slen,
@ -393,14 +395,9 @@ if (areCopyCompatibleArrays!(SourceRange, TargetRange))
target[0 .. slen] = source[]; target[0 .. slen] = source[];
return target[slen .. $]; return target[slen .. $];
} }
} }
else static if (isOutputRange!(TargetRange, ElementType!SourceRange))
/// ditto {
TargetRange copy(SourceRange, TargetRange)(SourceRange source, TargetRange target)
if (!areCopyCompatibleArrays!(SourceRange, TargetRange) &&
isInputRange!SourceRange &&
isOutputRange!(TargetRange, ElementType!SourceRange))
{
// Specialize for 2 random access ranges. // Specialize for 2 random access ranges.
// Typically 2 random access ranges are faster iterated by common // Typically 2 random access ranges are faster iterated by common
// index than by x.popFront(), y.popFront() pair // index than by x.popFront(), y.popFront() pair
@ -420,6 +417,13 @@ if (!areCopyCompatibleArrays!(SourceRange, TargetRange) &&
put(target, source); put(target, source);
return target; 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) $(LREF uninitializeFill)
*/ */
void initializeAll(Range)(Range range) 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 core.stdc.string : memset, memcpy;
import std.traits : hasElaborateAssign, isDynamicArray; import std.traits : hasElaborateAssign, isDynamicArray;
@ -888,14 +894,13 @@ if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range
} }
else else
fill(range, T.init); fill(range, T.init);
} }
else static if (is(Range == char[]) || is(Range == wchar[]))
/// ditto {
void initializeAll(Range)(Range range)
if (is(Range == char[]) || is(Range == wchar[]))
{
alias T = ElementEncodingType!Range; alias T = ElementEncodingType!Range;
range[] = T.init; range[] = T.init;
}
else static assert(0, "Range doesn't have assignable elements.");
} }
/// ///
@ -1745,12 +1750,13 @@ Returns:
Range remove Range remove
(SwapStrategy s = SwapStrategy.stable, Range, Offset...) (SwapStrategy s = SwapStrategy.stable, Range, Offset...)
(Range range, Offset offset) (Range range, Offset offset)
if (s != SwapStrategy.stable if (isBidirectionalRange!Range
&& isBidirectionalRange!Range
&& hasLvalueElements!Range && hasLvalueElements!Range
&& hasLength!Range && hasLength!Range
&& Offset.length >= 1) && Offset.length >= 1)
{ {
static if (s == SwapStrategy.unstable)
{
Tuple!(size_t, "pos", size_t, "len")[offset.length] blackouts; Tuple!(size_t, "pos", size_t, "len")[offset.length] blackouts;
foreach (i, v; offset) foreach (i, v; offset)
{ {
@ -1826,17 +1832,9 @@ if (s != SwapStrategy.stable
} }
return range; return range;
} }
else static if (s == SwapStrategy.stable)
/// Ditto {
Range remove
(SwapStrategy s = SwapStrategy.stable, Range, Offset...)
(Range range, Offset offset)
if (s == SwapStrategy.stable
&& isBidirectionalRange!Range
&& hasLvalueElements!Range
&& Offset.length >= 1)
{
auto result = range; auto result = range;
auto src = range, tgt = range; auto src = range, tgt = range;
size_t pos; size_t pos;
@ -1877,6 +1875,8 @@ if (s == SwapStrategy.stable
// leftover move // leftover move
moveAll(src, tgt); moveAll(src, tgt);
return result; 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 Reverses $(D r) in-place. Performs $(D r.length / 2) evaluations of $(D
swap). swap).
UTF sequences consisting of multiple code units are preserved properly.
Params: Params:
r = a $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives) 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: See_Also:
$(HTTP sgi.com/tech/stl/_reverse.html, STL's _reverse), $(REF retro, std,range) for a lazy reversed range view $(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) void reverse(Range)(Range r)
if (isBidirectionalRange!Range && !isRandomAccessRange!Range if (isBidirectionalRange!Range)
&& hasSwappableElements!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) while (!r.empty)
{ {
swap(r.front, r.back); swap(r.front, r.back);
@ -2150,6 +2170,29 @@ if (isBidirectionalRange!Range && !isRandomAccessRange!Range
if (r.empty) break; if (r.empty) break;
r.popBack(); 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 ]); assert(arr == [ 3, 2, 1 ]);
} }
///ditto ///
void reverse(Range)(Range r) @safe unittest
if (isRandomAccessRange!Range && hasLength!Range)
{ {
//swapAt is in fact the only way to swap non lvalue ranges char[] arr = "hello\U00010143\u0100\U00010143".dup;
immutable last = r.length-1; reverse(arr);
immutable steps = r.length/2; assert(arr == "\U00010143\u0100\U00010143olleh");
for (size_t i = 0; i < steps; i++)
{
r.swapAt(i, last-i);
}
} }
@safe unittest @safe unittest
@ -2188,51 +2226,6 @@ if (isRandomAccessRange!Range && hasLength!Range)
assert(range == [3, 2, 1]); 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 @safe unittest
{ {
void test(string a, string b) void test(string a, string b)