From 392cdcf192a386c88c3d64d2a3903dd9a1d8d8e8 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Wed, 1 Nov 2017 12:30:27 +0100 Subject: [PATCH] Fix moveEmplace not being pure --- source/tanya/algorithm/mutation.d | 50 ++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) 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); +}