summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/tanya/algorithm/mutation.d50
1 files 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);
+}