mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
Implement Phobos side of DIP1014
This commit is contained in:
parent
6010a7ccde
commit
4be9b5f59f
2 changed files with 68 additions and 3 deletions
|
@ -1046,8 +1046,8 @@ to its `.init` value after it is moved into target, otherwise it is
|
|||
left unchanged.
|
||||
|
||||
Preconditions:
|
||||
If source has internal pointers that point to itself, it cannot be moved, and
|
||||
will trigger an assertion failure.
|
||||
If source has internal pointers that point to itself and doesn't define
|
||||
opPostMove, it cannot be moved, and will trigger an assertion failure.
|
||||
|
||||
Params:
|
||||
source = Data to copy.
|
||||
|
@ -1198,6 +1198,24 @@ pure nothrow @safe @nogc unittest
|
|||
assert(s2.a == 2);
|
||||
}
|
||||
|
||||
/// `opPostMove` will be called if defined:
|
||||
pure nothrow @safe @nogc unittest
|
||||
{
|
||||
struct S
|
||||
{
|
||||
int a;
|
||||
void opPostMove(const ref S old)
|
||||
{
|
||||
assert(a == old.a);
|
||||
a++;
|
||||
}
|
||||
}
|
||||
S s1;
|
||||
s1.a = 41;
|
||||
S s2 = move(s1);
|
||||
assert(s2.a == 42);
|
||||
}
|
||||
|
||||
private void trustedMoveImpl(T)(ref T source, ref T target) @trusted
|
||||
{
|
||||
moveImpl(source, target);
|
||||
|
@ -1379,12 +1397,14 @@ void moveEmplace(T)(ref T source, ref T target) @system
|
|||
import core.stdc.string : memcpy, memset;
|
||||
import std.traits : hasAliasing, hasElaborateAssign,
|
||||
hasElaborateCopyConstructor, hasElaborateDestructor,
|
||||
hasElaborateMove,
|
||||
isAssignable, isStaticArray;
|
||||
|
||||
static if (!is(T == class) && hasAliasing!T) if (!__ctfe)
|
||||
{
|
||||
import std.exception : doesPointTo;
|
||||
assert(!doesPointTo(source, source), "Cannot move object with internal pointer.");
|
||||
assert(!(doesPointTo(source, source) && !hasElaborateMove!T),
|
||||
"Cannot move object with internal pointer unless `opPostMove` is defined.");
|
||||
}
|
||||
|
||||
static if (is(T == struct))
|
||||
|
@ -1396,6 +1416,9 @@ void moveEmplace(T)(ref T source, ref T target) @system
|
|||
else
|
||||
target = source;
|
||||
|
||||
static if (hasElaborateMove!T)
|
||||
__move_post_blt(target, source);
|
||||
|
||||
// If the source defines a destructor or a postblit hook, we must obliterate the
|
||||
// object in order to avoid double freeing and undue aliasing
|
||||
static if (hasElaborateDestructor!T || hasElaborateCopyConstructor!T)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue