Bug 5489 – std.typecons tuples dynamically iterable

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-01-26T04:52:23Z
Last change time
2017-12-21T21:39:53Z
Keywords
pull
Assigned to
Seb
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2011-01-26T04:52:23Z
std.typecons tuples are not arrays, and their items don't need to be all of the same type. But in Python programming with tuples I have seen that once in a while it's useful to iterate on their items. Currently in D2 (DMD 2.051) you are allowed to iterate on tuple items, but this is a "static foreach": import std.stdio, std.typecons; void main() { auto t = tuple(1, 2, 3, 4); /*static*/ foreach (x; t.tupleof) writeln(x); } This is dynamic: import std.typecons, std.algorithm; void main() { auto t = tuple(1, 2, 3, 4); auto total = reduce!q{a + b}([t.tupleof]); assert(total == 10); } But in some situations with usage of zip and other things it's not handy to convert tuples in arrays in that way. So I'd like tuples made of the same type of items (castable) to be iterable (a "static if" disables the range protocol methods if std.traits.CommonType applied on the tuple items is void): import std.typecons, std.algorithm; void main() { auto t = tuple(1, 2, 3, 4); auto total = reduce!q{a + b}(t); assert(total == 10); } With sum() from bug 4725 it becomes: import std.typecons, std.algorithm; void main() { auto t = tuple(1, 2, 3, 4); auto total = reduce!sum(t); assert(total == 10); } Another hypotetical example usage: import std.typecons, std.algorithm, std.range; void main() { auto t1 = tuple(1, 2, 3, 4); auto t2 = tuple(10, 20, 30, 40); auto r = map!sum(zip(t1, t2)); assert(r == [11, 22, 33, 44]); } Equivalent Python2 working code: >>> t1 = (1, 2, 3, 4) >>> t2 = (10, 20, 30, 40) >>> map(sum, zip(t1, t2)) [11, 22, 33, 44]
Comment #1 by dhasenan — 2017-12-04T23:02:31Z
I just came across an instance of this: cartesianProduct( ["%a, ", "%A, ", ""], ["%d "], ["%b", "%B"], [" %Y %H:%M:%S "], ["%Z", "%z", "%.%.%.", "%.%.", "%."] ) .map!(x => joiner(x, "").array.to!string) .array I ended up using [x.tupleof], but it didn't occur to me that that was possible. I only found out about that by looking at this issue.
Comment #2 by greensunny12 — 2017-12-21T14:27:55Z
This already works if you combine .expand with std.range.only: ``` import std.algorithm, std.range, std.stdio, std.typecons; auto t = tuple(1, 2); t.expand.only.sum.writeln; ``` PR to add this as an example: https://github.com/dlang/phobos/pull/5953
Comment #3 by github-bugzilla — 2017-12-21T21:39:52Z
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/059be4da3afe87bff6c8c37186c8fdef271f3388 Fix Issue 5489 - std.typecons tuples dynamically iterable https://github.com/dlang/phobos/commit/0ba08bb6530ce84709f141645e2f6f28ab551813 Merge pull request #5953 from wilzbach/fix-5489 Fix Issue 5489 - std.typecons tuples dynamically iterable merged-on-behalf-of: MetaLang <[email protected]>