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