Fix moveEmplace not being pure

This commit is contained in:
Eugen Wissner 2017-11-01 12:30:27 +01:00
parent 09b6655b9a
commit 392cdcf192
1 changed files with 46 additions and 4 deletions

View File

@ -54,17 +54,24 @@ body
static if (hasElaborateCopyConstructor!T || hasElaborateDestructor!T)
{
static const T init = T.init;
static if (isNested!T)
{
// Don't override the context pointer.
enum size_t size = T.sizeof - (void*).sizeof;
copy((cast(void*) &init)[0 .. size], (&source)[0 .. 1]);
}
else
{
copy((&init)[0 .. 1], (&source)[0 .. 1]);
enum size_t size = T.sizeof;
}
const(void)[] init = typeid(T).initializer();
if (init.ptr is null)
{
fill!0((cast(void*) &source)[0 .. size]);
}
else
{
copy(init[0 .. size], (&source)[0 .. 1]);
}
}
}
@ -95,6 +102,33 @@ body
assert(x2 == 5);
}
// Is pure.
@nogc nothrow pure @system unittest
{
struct S
{
this(this)
{
}
}
S source, target = void;
static assert(is(typeof({ moveEmplace(source, target); })));
}
// Moves nested.
@nogc nothrow pure @system unittest
{
struct Nested
{
void method() @nogc nothrow pure @safe
{
}
}
Nested source, target = void;
moveEmplace(source, target);
assert(source == target);
}
/**
* Moves $(D_PARAM source) into $(D_PARAM target) assuming that
* $(D_PARAM target) isn't initialized.
@ -162,3 +196,11 @@ T move(T)(ref T source)
assert(x2 == 5);
assert(move(x2) == 5);
}
// Moves if source is target.
@nogc nothrow pure @safe unittest
{
int x = 5;
move(x, x);
assert(x == 5);
}