digitalmars.D - std.typecons.Tuple and tuples
- bearophile (85/85) Aug 02 2010 I know that three ways to do something looks a bit too much, but I'd lik...
 - bearophile (3/5) Aug 02 2010 Sorry, I meant:
 - bearophile (5/5) Aug 03 2010 I have put this as two enhancement requests in Bugzilla, one is for a sm...
 
I know that three ways to do something looks a bit too much, but I'd like a
third way to build a std.typecons tuple: I like to give field names, but to
omit their types:
import std.typecons: Tuple;
import std.string: split;
import std.metastrings: Format, toStringNow;
// from dlibs1
template SeriesGen1(string txt, string separator, int max, int min=0) {
    static if (min > max)
        const SeriesGen1 = "";
    else static if (min == max)
        const SeriesGen1 = Format!(txt, toStringNow!(max));
    else
        const SeriesGen1 = SeriesGen1!(txt, separator, max-1, min) ~ separator ~
                           Format!(txt, toStringNow!(max));
}
// from dlibs1
template SeriesGen2(string txt, string separator, int max, int min=0) {
    static if (min > max)
        const SeriesGen2 = "";
    else static if (min == max)
        const SeriesGen2 = Format!(txt, toStringNow!(max),
                                        toStringNow!(max));
    else
        const SeriesGen2 = SeriesGen2!(txt, separator, max-1, min) ~ separator ~
                           Format!(txt, toStringNow!(max),
                                        toStringNow!(max));
}
// not sure about the ref return value
// can this be named just "Tuple"?
ref auto Tuple_(string names, T...)(T args)
  if (split(names).length == T.length) {
    enum string[] fieldNames = split(names);
    mixin("return Tuple!(" ~
           SeriesGen2!("T[%s], fieldNames[%s]", ", ", T.length-1) ~
           ")(" ~
           SeriesGen1!("args[%s]", ", ", T.length-1) ~
           ");"
         );
}
// demo --------------------
import std.stdio: writeln;
ref auto sqr2(int a, float b) {
    return Tuple_!q{x y}(a * a, b * b);
}
void main() {
    ///*
    with(sqr2(10, 5.5F)) {
        writeln(x, " ", y);
    } // test.d(...): Error: sqr2(10,5.5F) is not an lvalue
    //*/
    auto xy = sqr2(10, 5.5F);
    with(xy) {
        writeln(x, " ", y);
    }
    with(Tuple!(int, "a", float, "b")(10, 5.5F)) {
        writeln(a, " ", b);
    }
}
Can this Tuple!() overload the std.typecons.Tuple? (I have tried to integrate
it, but I have failed at my first quick attempt).
-------------
This is in std.file:
void getTimes(in char[] name, out d_time ftc, out d_time fta, out d_time ftm);
Introducing tuples more into Phobos it becomes:
Tuple!(d_time "ftc", d_time "fta", d_time "ftm") getTimes(in string name);
But then you have to use it for example like this:
void main() {
    auto t3 = getTimes("filename");
    with(t3) {
        writeln(ftc, " ", fta, " ", ftm);
    }
}
While adding a bit of syntax sugar to D it becomes:
void main() {
    // note: "fc" != "ftc"
    (d_time fc, d_time fa, d_time fm) = getTimes("filename");
}
That syntax sugar means something like:
void main() {
    auto __temp1 = getTimes("filename");
    d_time fc = __temp1.field[0];
    d_time fa = __temp1.field[1];
    d_time fm = __temp1.field[2];
}
I think that sugar doesn't clash with C syntax.
Bye,
bearophile
 Aug 02 2010
 ref auto Tuple_(string names, T...)(T args)
   if (split(names).length == T.length) {
Sorry, I meant:
ref auto Tuple_(string names, T...)(T args)
    if (T.length && split(names).length == T.length) {
 Aug 02 2010
I have put this as two enhancement requests in Bugzilla, one is for a small amount of code added to Phobos, the other is for some syntax sugar: http://d.puremagic.com/issues/show_bug.cgi?id=4577 http://d.puremagic.com/issues/show_bug.cgi?id=4579 Bye, bearophile
 Aug 03 2010








 
 
 
 bearophile <bearophileHUGS lycos.com>