Thread overview
deep copying a struct
Sep 06, 2019
aliak
Sep 06, 2019
aliak
Sep 06, 2019
Paul Backus
September 06, 2019
Are there any library APIs that allow this:

struct S {
    int[] arr;
}

void main() {
    const a = S([1,2,3]);
    S b = a.copy; // deep dup/copy
}


I'd also like to avoid implementing a copy constructor for each type.
September 06, 2019
On Friday, 6 September 2019 at 10:37:16 UTC, aliak wrote:
> Are there any library APIs that allow this:

I just put this together. Any holes other the AA related ones?

Will it work with classes?

auto dupDeep(T)(ref T thing) {
    import std.range: ElementType;
    import std.traits: hasAliasing, Unqual, isArray;

    static if (isArray!T) {
        Unqual!(ElementType!T)[] copy;
        foreach (elem; thing) {
            copy ~= elem.dupDeep;
        }
    } else static if (hasAliasing!T) {
        Unqual!T copy;
        foreach (i, field; thing.tupleof) {
            copy.tupleof[i] = field.dupDeep;
        }
    } else {
        Unqual!T copy;
        copy = thing;
    }
    return copy;
}

September 06, 2019
On Friday, 6 September 2019 at 10:52:43 UTC, aliak wrote:
> On Friday, 6 September 2019 at 10:37:16 UTC, aliak wrote:
>> Are there any library APIs that allow this:
>
> I just put this together. Any holes other the AA related ones?

string a = "hello";
string b = a.dupDeep;
// Error: cannot implicitly convert expression dupDeep(a)
// of type dchar[] to string

Using `ElementType` means you get bitten by autodecoding. Since you know it's specifically an array, and not just any range, you can use `typeof(thing[0])` instead.

---

struct S { immutable int i; }
S a = S(123);
S b = a.dupDeep;
// Error: cannot modify struct instance `copy` of type `S`
// because it contains `const` or `immutable` members

I think the only way to make this work in the general case is with cooperation from the types, since the only way to initialize an `immutable` member is in a constructor. If you don't care about that, though, you can just slap an `if (isAssignable!(Unqual!T))` template constraint on the whole thing.