March 17, 2018 When is copy assignment @safe to use when the left-hand-side is an undefined l-value? | ||||
---|---|---|---|---|
| ||||
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"); } } |
Copyright © 1999-2021 by the D Language Foundation