I'm currently using these new implementations of core.lifetime.move

```d

        import core.stdc.string : memcpy;

        /++ Variant of `core.lifetime.move(source)` that uses `__rvalue`.

If `T` is a struct with a destructor or postblit defined, source is reset to its `.init` value after it is moved into target, otherwise it
        is left unchanged.

        See https://github.com/dlang/dmd/pull/20946/files.
         +/
/+TODO:ref+/ T move(T)(return scope ref T source) @trusted /+TODO:__rvalue+/ {
                static if (__traits(isStaticArray, T)) {
                        typeof(return) destination = void;
foreach (const i, ref e; source) // TODO: use single call to `moveEmplaceAll` // TODO: Replace with: new (destination[i]) typeof(T.init[i])(__rvalue(e)); // placement new
                                moveEmplace(e, destination[i]);
                        return destination;
                } else {
typeof(return) destination = __rvalue(source); // runs move constructors if present static if (is(T == struct) && (__traits(hasMember, T, "__xdtor") || __traits(hasMember, T, "__fieldPostblit"))) {
                                static immutable init = T.init;
                                memcpy(&source, &init, T.sizeof);
                        }
                        return destination;
                }
        }

/++ Variant of `core.lifetime.move(source, destination)` that uses `__rvalue`.

If `T` is a struct with a destructor or postblit defined, source is reset to its `.init` value after it is moved into target, otherwise it
        is left unchanged.
         +/
        void move(T)(ref T source, ref T destination) @trusted {
                static if (__traits(isStaticArray, T)) {
foreach (const i, ref e; source) // TODO: use single call to `moveAll`
                                move(e, destination[i]);
                } else {
destination = __rvalue(source); // runs move constructors if present static if (is(T == struct) && (__traits(hasMember, T, "__xdtor") || __traits(hasMember, T, "__fieldPostblit"))) {
                                static immutable init = T.init;
                                memcpy(&source, &init, T.sizeof);
                        }
                }

        }

/++ Variant of `core.lifetime.moveEmplace(source, destination)` that uses `__rvalue`.

If `T` is a struct with a destructor or postblit defined, source is reset to its `.init` value after it is moved into target, otherwise it
        is left unchanged.
         +/
        void moveEmplace(T)(ref T source, ref T destination) @system {
                static if (__traits(isStaticArray, T)) {
foreach (const i, ref e; source) // TODO: use single call to `moveEmplaceAll`
                                moveEmplace(e, destination[i]);
                } else {
memcpy(&destination, &source, T.sizeof); // TODO: Use `__rvalue` here?
                        static if (is(T == struct)) {
static if ((__traits(hasMember, T, "__xdtor") || __traits(hasMember, T, "__fieldPostblit"))) {
                                        static immutable init = T.init;
                                        memcpy(&source, &init, T.sizeof);
                                }
                        }
                }
        }
```

.

How can these be improved?

I'm asking because uncommenting the usages of placement new in the implementations triggers segmentation faults that I fail to understand the source of.

I also haven't found a way to qualify any of the overloads with `__rvalue`.

Reply via email to