## digitalmars.D.learn - dup and arrays

• Ellery Newcomer (8/8) Mar 26 2010 I just noticed that dup does not dup deep.
• Philippe Sigaud (53/68) Mar 26 2010 I sent a proposal for deep dup a few hours after your discussion, bu no ...
Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
```I just noticed that dup does not dup deep.

In a two second search I couldn't find any reason for or against, but
I'd kinda like it if

auto r2 = r.dup;
r2[i][j] = 0;
r[i][j] = 1;
assert(r2[i][j] != r[i][j]);

held.
```
Mar 26 2010
strtr <strtr spam.com> writes:
```Ellery Newcomer Wrote:

I just noticed that dup does not dup deep.

In a two second search I couldn't find any reason for or against, but
I'd kinda like it if

auto r2 = r.dup;
r2[i][j] = 0;
r[i][j] = 1;
assert(r2[i][j] != r[i][j]);

held.

Here is the first I found (couldn't find my own .ddup request :)
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=12631
```
Mar 26 2010
Philippe Sigaud <philippe.sigaud gmail.com> writes:
```On Sat, Mar 27, 2010 at 03:34, strtr <strtr spam.com> wrote:

Ellery Newcomer Wrote:

I just noticed that dup does not dup deep.

In a two second search I couldn't find any reason for or against, but
I'd kinda like it if

auto r2 = r.dup;
r2[i][j] = 0;
r[i][j] = 1;
assert(r2[i][j] != r[i][j]);

held.

Here is the first I found (couldn't find my own .ddup request :)

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=12631

I sent a proposal for deep dup a few hours after your discussion, bu no one
commented on it. And now I can't find it... hmm. Maybe the mail didn't make
it.

Anyway, here it is:

template TypeofDeepdup(T)
{
alias typeof(deepdup(T.init)) TypeofDeepdup;
}

ref Unqual!T deepdup(T)(T t) if (is(T == struct) && !is(T.Types))
{
staticMap!(TypeofDeepdup, typeof(t.tupleof)) tup;
foreach(i,Type; tup) { tup[i] = deepdup(t.tupleof[i]);}
return Unqual!T(tup);
}

Tuple!(staticMap!(TypeofDeepdup, T.Types))
deepdup(T)(T t) if (is(T.Types)) // Tuples
{
staticMap!(TypeofDeepdup, T.Types) tup;
foreach(i,Type; tup) { tup[i] = deepdup(t.field[i]);}
return tuple(tup);
}

Unqual!T deepdup(T)(T t) if (is(T == class))
{
staticMap!(TypeofDeepdup, typeof(t.tupleof)) tup;
foreach(i,Type; tup) { tup[i] = deepdup(t.tupleof[i]);}
return new Unqual!T(tup);
}

TypeofDeepdup!(ElementType!T)[] deepdup(T)(T t) if (isDynamicArray!T)
{
auto result = new TypeofDeepdup!(ElementType!T)[](t.length);
foreach(i, elem; t) result[i] = deepdup(elem);
return result;
}

TypeofDeepdup!(ElementType!T)[T.length] deepdup(T)(T t) if (isStaticArray!T)
{
TypeofDeepdup!(ElementType!T)[T.length] result = t;
foreach(ref elem; result) elem = deepdup(elem);
return result;
}

TypeofDeepdup!T* deepdup(T)(T* t)
{
return &deepdup(*t);
}

Unqual!T deepdup(T)(T t) if (!is(T == struct) && !is(T == class) &&
!isArray!T && !is(T.Types) && !isPointer!T)
{
return cast(Unqual!T)t;
}

It seems to work well enough for my purposes, but still has some
limitations: for example, it unqualifies everything (no more const /
immutable after dupping).

Philippe
```
Mar 26 2010