www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 7666] New: A function to reverse the items of a tuple

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666

           Summary: A function to reverse the items of a tuple
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



In some situations I'd like a function to reverse a tuple:

reversed(tuple(a,b)) == reversed(tuple(b,a))
reversed(tuple(a,b,c)) == reversed(tuple(c,b,a))
reversed(tuple(a,b,c,d)) == reversed(tuple(d,c,b,a))


Once built-in associative arrays have a byPair() method, that returns a
2-tuple, a reversed(tuple(a,b)) is useful when you need the pairs in reversed
(value-key) order.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 07 2012
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com



15:07:05 PDT ---
First thing I could come up with, but it requires editing the Tuple!() struct.
A public alias is added in Tuple struct:

alias Reverse!fieldSpecs revFieldSpecs; 

And the internal FieldSpec struct is moved outside and made public. Then the
following is possible:


auto reversed(T)(T tup)
    if (isTuple!T)
{
    static string getMixin(T)()
    {
        string[] result;
        foreach (i; 0 .. T.Types.length)
        {
            result ~= xformat("tup.field[%d]", i);
        }

        return result.retro.join(", ");
    }

    static string getSpecs(T)()
    {
        string[] result;
        foreach (spec; T.revFieldSpecs)
        {
            result ~= spec.Type.stringof;
            result ~= xformat(`"%s"`, spec.name);
        }

        return result.join(", ");
    }

    enum str = xformat("return Tuple!(%s)(%s);", getSpecs!(T)(),
getMixin!(T)());
    mixin(str);
}

void main()
{
    alias Tuple!(int, "index", string, "value") Entry;
    Entry e;
    e.index = 4;
    e.value = "Hello";

    auto rev = reversed(e);
    assert(e.index == 4);
    assert(e.value == "Hello");
    writeln(e);
    writeln(rev);
}

Prints:
Tuple!(int,"index",string,"value")(4, "Hello")
Tuple!(string,"value",int,"index")("Hello", 4)

If there is a non-invasive way of doing this it would be welcome.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 27 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666


timon.gehr gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr gmx.ch




 ...
 
 If there is a non-invasive way of doing this it would be welcome.
import std.typecons, std.conv, std.range, std.algorithm; auto reversed(T)(T t) if(isTuple!T){ return mixin(`tuple(`~iota(T.length).retro.map!(a=>text("t[",a,"]")).join(",")~`)`); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 27 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666






 ...
 
 If there is a non-invasive way of doing this it would be welcome.
With field names: import std.typecons, std.conv, std.range, std.algorithm; auto reversed(T)(T t) if(isTuple!T){ static if(is(T X:Tuple!A,A...)) alias A Spec; static struct Local{ template Seq(T...){ alias T Seq; } template RevSpec(A...){ enum num=A.length>1&&!is(A[1])?2:1; static if(A.length) alias Seq!(RevSpec!(A[num..$]),A[0..num]) RevSpec; else alias A RevSpec; } } return mixin(`Tuple!(Local.RevSpec!Spec)(`~ iota(T.length).retro.map!(a=>text("t[",a,"]")).join(",")~ `)`); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 27 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666




16:54:02 PDT ---

 With field names
Interesting, the last time I saw this syntax: static if(is(T X : Tuple!A, A...)) alias A Spec; it was in the templates book (https://github.com/PhilippeSigaud/D-templates-tutorial), where Philippe mentions: <<beg quote For me, the main limitation is that template tuple parameters are not ac- cepted. Too bad. See, imagine you use std.typecons.Tuple a lot. At one point, you need a template to test if something is a Tuple!(T...) for some T which can be 0 or more types. Though luck, is is a bit of a letdown there, as you cannot do: template isTuple(T) { static if (is(T tup == Tuple!(InnerTypes), InnerTypes...)) { enum isTuple = true; } } end quote>> Maybe this was a compiler limitation in earlier versions. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 27 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666





 ...
 Maybe this was a compiler limitation in earlier versions.
Yup, Kenji Hara fixed that recently. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 27 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666




12:16:18 PDT ---
Got something better:

auto reversed(T)(T t)
    if (isTuple!T)
{
    static if (is(T : Tuple!A, A...))
        alias RevTypes = Reverse!A;

    Tuple!RevTypes result;
    auto tup = t.tupleof;
    result.tupleof = Reverse!tup;
    return result;
}

void main()
{
    auto tup = tuple(1, "2");
    assert(tup.reversed == tuple("2", 1));
}

I'll make a pull shortly.

P.S. this is a compile-error: Reverse!(t.tupleof)

Might be worth filing this as a bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 05 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull
         AssignedTo|nobody puremagic.com        |andrej.mitrovich gmail.com



12:22:29 PDT ---
https://github.com/D-Programming-Language/phobos/pull/1244

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 05 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666




Commits pushed to master at https://github.com/D-Programming-Language/phobos

https://github.com/D-Programming-Language/phobos/commit/cc7c5c5ed2b2e345a29f5e8a663db4556eb8819e
Fixes Issue 7666 - Implement function to reverse fields of a tuple.

https://github.com/D-Programming-Language/phobos/commit/5c2890f23eddb8ac72ed57e44e1c54b6f43593e1


Issue 7666 - Implement function to reverse fields of a tuple.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 05 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666


Andrei Alexandrescu <andrei erdani.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |andrei erdani.com
         Resolution|                            |FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 05 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |



13:12:05 PDT ---
So sorry about this, I completely forgot about the string specs feature of
Tuples. I guess I was a little sleepy. Will re-do a pull tomorrow.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 05 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666




13:16:29 PDT ---

 So sorry about this, I completely forgot about the string specs feature of
 Tuples. I guess I was a little sleepy. Will re-do a pull tomorrow.
Also as reported by Walter it seems we get frame pointer errors when trying to use it from within a unittest. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 05 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7666




01:07:30 PDT ---
https://github.com/D-Programming-Language/phobos/pull/1248

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 06 2013