diff --git a/source/tanya/algorithm/mutation.d b/source/tanya/algorithm/mutation.d index 698dfdf..0076486 100644 --- a/source/tanya/algorithm/mutation.d +++ b/source/tanya/algorithm/mutation.d @@ -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); +}