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.


Reply via email to