Copying array with const correctness
Vindex9
tech.vindex at gmail.com
Wed Oct 8 07:46:32 UTC 2025
On Wednesday, 8 October 2025 at 02:58:15 UTC, Steven
Schveighoffer wrote:
> My attempt:
>
> ```d
> import std.traits;
>
> inout(T)[] copyArray(T)(inout(T)[] arr) {
> alias M = Unqual!T;
> ```
Unfortunately, `Unqual` in your code doesn't do anything - the
type `M` remains `T`. Apparently, some strange things are
happening inside the template when it comes to constness.
Sometimes you need to return an array from a const method. You
don't want modifications to the returned array to affect the
state of the struct, but at the same time, you want to freely
manipulate the consents of that array. That's why removing
constness is important to me. However, it seems that making a
recursive copy isn't necessary: when it comes to strings, we
don't need to turn a `string` into a `char[]`. As s way out, we
can simply avoid removing constness from `immutable` data. It
seems I have managed to reach the goal without resorting to
explicit conversions.
```d
import std.stdio;
T[] copyArray(T)(inout(T)[] arr) {
T[] result;
result.length = arr.length;
static if(is(T == U[], U) && !is(T == immutable(Y)[], Y)) {
foreach(i, ref v; result) {
v = copyArray(arr[i]);
}
} else {
foreach(i, ref v; result) {
T middle = arr[i];
v = middle;
}
}
return result;
}
struct S {
int x;
bool[] a;
this(ref return scope const S rhs) {
this.x = rhs.x;
this.a = rhs.a.dup;
}
}
void main() {
const string[] arr1d = ["ABC", "DEF"]; //
const(const(immutable(char)[])[])
writeln(typeid(arr1d));
auto res1 = copyArray(arr1d);
writeln(typeid(res1)); // immutable(char)[][]
const string[][] arr2d = [["ABC", "DEF"], ["GHI", "JKL"]];
writeln(typeid(arr2d)); //
const(const(const(immutable(char)[])[])[])
auto res2 = copyArray(arr2d);
writeln(typeid(res2)); // immutable(char)[][][]
const S[] structArr = [S(8, [true, false]), S(9, [false,
true])];
writeln(typeid(structArr)); // const(const(onlineapp.S)[])
auto structArrCopy = copyArray(structArr);
writeln(structArrCopy);
writeln(typeid(structArrCopy)); // onlineapp.S[]
const int[][] intArr = [[1, 2], [3, 4]];
writeln(typeid(intArr)); // const(const(const(int)[])[])
auto intArrCopy = copyArray(intArr);
writeln(intArrCopy);
writeln(typeid(intArrCopy)); // int[][]
}
```
Thank you, Steve.
More information about the Digitalmars-d-learn
mailing list