Merge pull request #838 from monarchdodra/fillv

fill(value) reimplementation
This commit is contained in:
Andrei Alexandrescu 2012-10-05 07:50:24 -07:00
commit b2101fe8b5

View file

@ -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