mirror of
https://github.com/dlang/phobos.git
synced 2025-05-02 16:10:45 +03:00
Merge pull request #838 from monarchdodra/fillv
fill(value) reimplementation
This commit is contained in:
commit
b2101fe8b5
1 changed files with 43 additions and 21 deletions
|
@ -868,7 +868,7 @@ unittest
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fills a range with a value.
|
Fills $(D range) with a $(D filler).
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
----
|
----
|
||||||
|
@ -878,32 +878,21 @@ assert(a == [ 5, 5, 5, 5 ]);
|
||||||
----
|
----
|
||||||
*/
|
*/
|
||||||
void fill(Range, Value)(Range range, Value filler)
|
void fill(Range, Value)(Range range, Value filler)
|
||||||
if (isInputRange!Range && is(typeof(range.front = filler)))
|
if (isInputRange!Range && is(typeof(range.front = filler)))
|
||||||
{
|
{
|
||||||
alias ElementType!Range T;
|
static if (is(typeof(range[] = filler)))
|
||||||
static if (hasElaborateCopyConstructor!T || !isDynamicArray!Range)
|
|
||||||
{
|
{
|
||||||
for (; !range.empty; range.popFront())
|
range[] = filler;
|
||||||
{
|
}
|
||||||
range.front = filler;
|
else static if (is(typeof(range[] = T(filler))))
|
||||||
}
|
{
|
||||||
|
range[] = T(filler);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (range.empty) return;
|
for ( ; !range.empty; range.popFront() )
|
||||||
// Range is a dynamic array of bald values, just fill memory
|
|
||||||
// Can't use memcpy or memmove coz ranges overlap
|
|
||||||
range.front = filler;
|
|
||||||
auto bytesToFill = T.sizeof * (range.length - 1);
|
|
||||||
auto bytesFilled = T.sizeof;
|
|
||||||
while (bytesToFill)
|
|
||||||
{
|
{
|
||||||
auto fillNow = min(bytesToFill, bytesFilled);
|
range.front = filler;
|
||||||
memcpy(cast(void*) range.ptr + bytesFilled,
|
|
||||||
cast(void*) range.ptr,
|
|
||||||
fillNow);
|
|
||||||
bytesToFill -= fillNow;
|
|
||||||
bytesFilled += fillNow;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -933,6 +922,39 @@ unittest
|
||||||
foreach(value;range.arr)
|
foreach(value;range.arr)
|
||||||
assert(value == filler);
|
assert(value == filler);
|
||||||
}
|
}
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
//ER8638_1 IS_NOT self assignable
|
||||||
|
static struct ER8638_1
|
||||||
|
{
|
||||||
|
void opAssign(int){}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ER8638_1 IS self assignable
|
||||||
|
static struct ER8638_2
|
||||||
|
{
|
||||||
|
void opAssign(ER8638_2){}
|
||||||
|
void opAssign(int){}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto er8638_1 = new ER8638_1[](10);
|
||||||
|
auto er8638_2 = new ER8638_2[](10);
|
||||||
|
er8638_1.fill(5); //generic case
|
||||||
|
er8638_2.fill(5); //opSlice(T.init) case
|
||||||
|
}
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
{
|
||||||
|
int[] a = [1, 2, 3];
|
||||||
|
immutable(int) b = 0;
|
||||||
|
static assert(__traits(compiles, a.fill(b)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
double[] a = [1, 2, 3];
|
||||||
|
immutable(int) b = 0;
|
||||||
|
static assert(__traits(compiles, a.fill(b)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fills $(D range) with a pattern copied from $(D filler). The length of
|
Fills $(D range) with a pattern copied from $(D filler). The length of
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue