Implemented elaborate copying support.

This commit is contained in:
uran 2014-05-06 16:07:51 +03:00
parent 0c40d1ea64
commit 254c27971d

View file

@ -187,7 +187,7 @@ private:
// the "handler" function below. // the "handler" function below.
enum OpID { getTypeInfo, get, compare, equals, testConversion, toString, enum OpID { getTypeInfo, get, compare, equals, testConversion, toString,
index, indexAssign, catAssign, copyOut, length, index, indexAssign, catAssign, copyOut, length,
apply, destruct } apply, postblit, destruct }
// state // state
ptrdiff_t function(OpID selector, ubyte[size]* store, void* data) fptr ptrdiff_t function(OpID selector, ubyte[size]* store, void* data) fptr
@ -224,6 +224,7 @@ private:
string * target = cast(string*) parm; string * target = cast(string*) parm;
*target = "<Uninitialized VariantN>"; *target = "<Uninitialized VariantN>";
break; break;
case OpID.postblit:
case OpID.destruct: case OpID.destruct:
break; break;
case OpID.get: case OpID.get:
@ -546,6 +547,13 @@ private:
} }
break; break;
case OpID.postblit:
static if (hasElaborateAssign!A)
{
typeid(A).postblit(zis);
}
break;
case OpID.destruct: case OpID.destruct:
static if (hasElaborateDestructor!A) static if (hasElaborateDestructor!A)
{ {
@ -570,6 +578,11 @@ public:
opAssign(value); opAssign(value);
} }
this(this)
{
fptr(OpID.postblit, &store, null);
}
~this() ~this()
{ {
fptr(OpID.destruct, &store, null); fptr(OpID.destruct, &store, null);
@ -611,6 +624,10 @@ public:
memcpy(&store, cast(const(void*)) &rhs, rhs.sizeof); memcpy(&store, cast(const(void*)) &rhs, rhs.sizeof);
else else
memcpy(&store, &rhs, rhs.sizeof); memcpy(&store, &rhs, rhs.sizeof);
static if (hasElaborateAssign!T)
{
typeid(T).postblit(&store);
}
} }
else else
{ {
@ -2260,28 +2277,45 @@ unittest
unittest unittest
{ {
// https://issues.dlang.org/show_bug.cgi?id=10194 // https://issues.dlang.org/show_bug.cgi?id=10194
// Also test for elaborate copying
static struct S static struct S
{ {
~this() @disable this();
this(int dummy)
{ {
++cnt; ++cnt;
} }
static size_t cnt;
this(this)
{
++cnt;
}
@disable S opAssign();
~this()
{
--cnt;
assert(cnt >= 0);
}
static int cnt = 0;
} }
Variant v;
// assigning a new value should destroy the existing one
{ {
v = S(); Variant v;
immutable n = S.cnt; {
v = S(0);
assert(S.cnt == 1);
}
assert(S.cnt == 1);
// assigning a new value should destroy the existing one
v = 0; v = 0;
assert(S.cnt == n + 1); assert(S.cnt == 0);
}
// destroying the variant should destroy it's current value // destroying the variant should destroy it's current value
{ v = S(0);
v = S(); assert(S.cnt == 1);
immutable n = S.cnt;
destroy(v);
assert(S.cnt == n + 1);
} }
assert(S.cnt == 0);
} }