dup and arrays

Philippe Sigaud philippe.sigaud at gmail.com
Fri Mar 26 23:19:37 PDT 2010


On Sat, Mar 27, 2010 at 03:34, strtr <strtr at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d-learn/attachments/20100327/0aa3c613/attachment.html>


More information about the Digitalmars-d-learn mailing list