www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - deep copying a struct

reply aliak <something something.com> writes:
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.
Sep 06 2019
parent reply aliak <something something.com> writes:
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; }
Sep 06 2019
parent Paul Backus <snarwin gmail.com> writes:
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.
Sep 06 2019