When is copy assignment @safe to use when the left-hand-side is an undefined l-value?
Nordlöw
per.nordlow at gmail.com
Sat Mar 17 02:09:40 UTC 2018
Given an uninitialized (undefined content from, for instance,
malloc) value `x` of type `T`, when is it @safe to initalize `x`
with a simple assignment such as
x = y
in contrast to
emplace(&x, y);
?
My current guess is when
hasElaborateCopyConstructor!T
is `false`. Is this always correct?
I'm asking because I want the following function to work
correctly for all types including default-uncopyable container
types (that require explicit call to .dup)
private static void duplicateEmplace(T)(const scope ref T src,
scope ref T dst) @system
{
import std.conv : emplace;
import std.traits : hasElaborateCopyConstructor, isCopyable,
isBasicType;
static if (!hasElaborateCopyConstructor!T)
{
import std.traits : isInstanceOf;
static if (is(T == class) ||
is(T == string))
{
dst = cast(T)src;
}
else static if (isBasicType!T ||
isInstanceOf!(Nullable, T)) // `Nullable`
types cannot be emplaced
{
dst = src;
}
else
{
emplace(&dst, cast(Unqual!T)src);
}
}
else static if (__traits(hasMember, T, "dup"))
{
// TODO fix when emplace can handle uncopyable types
emplace(&dst);
dst = src.dup;
}
else
{
static assert(0, T.stringof ~ " is neither copyable or
dupable");
}
}
More information about the Digitalmars-d-learn
mailing list