<br><br><div class="gmail_quote">On Sat, Mar 27, 2010 at 03:34, strtr <span dir="ltr">&lt;<a href="mailto:strtr@spam.com">strtr@spam.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div><div></div><div class="h5">Ellery Newcomer Wrote:<br>
<br>
&gt; I just noticed that dup does not dup deep.<br>
&gt;<br>
&gt; In a two second search I couldn&#39;t find any reason for or against, but<br>
&gt; I&#39;d kinda like it if<br>
&gt;<br>
&gt; auto r2 = r.dup;<br>
&gt; r2[i][j] = 0;<br>
&gt; r[i][j] = 1;<br>
&gt; assert(r2[i][j] != r[i][j]);<br>
&gt;<br>
&gt; held.<br>
<br>
</div></div>There have been discussions about this before.<br>
Here is the first I found (couldn&#39;t find my own .ddup request :)<br>
<a href="http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&amp;article_id=12631" target="_blank">http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&amp;article_id=12631</a></blockquote>
<div> <br>I sent a proposal for deep dup a few hours after your discussion, bu no one commented on it. And now I can&#39;t find it... hmm. Maybe the mail didn&#39;t make it.<br></div></div><br>Anyway, here it is:<br><br>template TypeofDeepdup(T)<br>
{<br>    alias typeof(deepdup(T.init)) TypeofDeepdup;<br>}<br><br>ref Unqual!T deepdup(T)(T t) if (is(T == struct) &amp;&amp; !is(T.Types))<br>{<br>    staticMap!(TypeofDeepdup, typeof(t.tupleof)) tup;<br>    foreach(i,Type; tup) { tup[i] = deepdup(t.tupleof[i]);}<br>
    return Unqual!T(tup);<br>}<br><br>Tuple!(staticMap!(TypeofDeepdup, T.Types))<br>deepdup(T)(T t) if (is(T.Types)) // Tuples<br>{<br>    staticMap!(TypeofDeepdup, T.Types) tup;<br>    foreach(i,Type; tup) { tup[i] = deepdup(t.field[i]);}<br>
    return tuple(tup);<br>}<br><br>Unqual!T deepdup(T)(T t) if (is(T == class))<br>{<br>    staticMap!(TypeofDeepdup, typeof(t.tupleof)) tup;<br>    foreach(i,Type; tup) { tup[i] = deepdup(t.tupleof[i]);}<br>    return new Unqual!T(tup);<br>
}<br><br>TypeofDeepdup!(ElementType!T)[] deepdup(T)(T t) if (isDynamicArray!T)<br>{<br>    auto result = new TypeofDeepdup!(ElementType!T)[](t.length);<br>    foreach(i, elem; t) result[i] = deepdup(elem);<br>    return result;<br>
}<br><br>TypeofDeepdup!(ElementType!T)[T.length] deepdup(T)(T t) if (isStaticArray!T)<br>{<br>    TypeofDeepdup!(ElementType!T)[T.length] result = t;<br>    foreach(ref elem; result) elem = deepdup(elem);<br>    return result;<br>
}<br><br>TypeofDeepdup!T* deepdup(T)(T* t)<br>{<br>    return &amp;deepdup(*t);<br>}<br><br>Unqual!T deepdup(T)(T t) if (!is(T == struct) &amp;&amp; !is(T == class) &amp;&amp; !isArray!T &amp;&amp; !is(T.Types) &amp;&amp; !isPointer!T)<br>
{<br>    return cast(Unqual!T)t;<br>}<br><br>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).<br><br>Philippe<br>
<br>