Thread overview | |||||
---|---|---|---|---|---|
|
September 06, 2019 deep copying a struct | ||||
---|---|---|---|---|
| ||||
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 Re: deep copying a struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | 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 Re: deep copying a struct | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | 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.
|
Copyright © 1999-2021 by the D Language Foundation