www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - dup and arrays

reply 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
parent reply 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.
There have been discussions about this before. 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
parent 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.
There have been discussions about this before. 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