[phobos] phobos commit, revision 1670

Philippe Sigaud philippe.sigaud at gmail.com
Sat Jun 19 14:18:46 PDT 2010


Andrei:
>> this(U)(U another) if (is(U == Tuple!(V), V...)) { ... }

Sean:

> Is that 'is' syntax correct?


No, halas you can't put a V... inside an is expression. Only is(U ==
Tuple!V, V) is authorized.
To detect a Tuple, I use the following workaround: std.typecons.Tuple has a
.Types member, so test for it (and btw .Types will give you the V tuple):

this(U)(U another) if (is(U.Types)) // U is a Tuple

{
alias U.Types V;
...
}

also, testing for U.stringof beginning with "Tuple!("... But I don't like
this.


> I've got to say that tuples are proving to be both incredibly powerful and
> incredibly frustrating to work with.


Agreed.



> I'm still trying to sort out a working test to tell these two functions
> apart:
>
> void fnA(Tuple!int) {}
> void fnB(int) {}
>

Like this?



template isTuple(T)
{
    static if (is(T.Types))
        enum bool isTuple = true;
    else
        enum bool isTuple = false;
}

template InternalTypes(T) if (isTuple!T) // Gosh, I need it later, DMD
doesn't like some complex types expressions
{
    alias T.Types InternalTypes;
}

template isTupleFunction(alias fun)
{
    static if (ParameterTypeTuple!fun.length == 1 &&
isTuple!(ParameterTypeTuple!fun[0]))
        enum bool isTupleFunction = true;
    else
        enum bool isTupleFunction = false;
}


But you also need to test for fun to be a standard function.



>
> Alternately, a way to pass a Tuple!int to either one automatically would be
> even better.  Or instead, make Variant.convertsTo distinguish between the
> two.  Right now it doesn't.
>

One thing nice to know (sorry if that's common knowledge) is that you can
send a Tuple to a standard function by using its .field/.expand member.

int foo(int i, double d, string s) { return i*s.length;}

auto t = tuple(2, 3.14, "abc");

foo(t.expand); // 2*3


To automate the process, you can use a function adaptor:

/**
Transforms a tuple-taking function into a standard function.
*/
template untuplify(alias fun)
{
    static if (isTupleFunction!fun)
        ReturnType!fun untuplify(InternalTypes!(ParameterTypeTuple!fun[0])
args)
        {
            return fun(tuple(args));
        }
    else // consider fun to be a function, that should be tested
        alias fun untuplify;
}

/**
Transforms a standard function into a tuple-accepting one.
*/
template tuplify(alias fun)
{
    static if (isTupleFunction!fun)
        alias fun tuplify;
    else
        ReturnType!fun tuplify(Tuple!(ParameterTypeTuple!fun) args)
        {
            return fun(args.expand);
        }
}


It's too bad I have to use a secondary template like InternalTypes, but

    InternalTypes!(ParameterTypeTuple!fun[0])

is accepted, whereas

    ParameterTypeTuple!fun[0].Types

 is not.



 Philippe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/phobos/attachments/20100619/7183c1fb/attachment.html>


More information about the phobos mailing list