digitalmars.D.learn - ref tuples
- Brad Anderson (9/9) Jul 02 2013 C++11's std::tuple includes a function std::tie that takes
- Artur Skawina (5/15) Jul 03 2013 Well, aliases can be used to get a similar effect.
- Dicebot (3/7) Jul 03 2013 Which is actually already in Phobos:
- Brad Anderson (3/23) Jul 03 2013 That won't work. a and b aren't held as references (also you
- Artur Skawina (5/24) Jul 03 2013 Try it...
- Brad Anderson (24/54) Jul 03 2013 Huh, I had no idea you could do something like that. I stand
- Artur Skawina (43/91) Jul 03 2013 D does not yet have proper ref types, which means a lot of things
- Simen Kjaeraas (7/16) Jul 03 2013 Not that I know of. But, Philippe Sigaud's dranges[1] library includes
C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple?
Jul 02 2013
On 07/03/13 02:22, Brad Anderson wrote:C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple?Well, aliases can be used to get a similar effect. template tie(A...) { alias tie = A; } tie!(a, b) = tuple(1, 2); artur
Jul 03 2013
On Wednesday, 3 July 2013 at 11:54:39 UTC, Artur Skawina wrote:Well, aliases can be used to get a similar effect. template tie(A...) { alias tie = A; } tie!(a, b) = tuple(1, 2); arturWhich is actually already in Phobos: TypeTuple!(a, b) = tuple(1, 2);
Jul 03 2013
On Wednesday, 3 July 2013 at 11:54:39 UTC, Artur Skawina wrote:On 07/03/13 02:22, Brad Anderson wrote:That won't work. a and b aren't held as references (also you passed them as type parameters :P).C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple?Well, aliases can be used to get a similar effect. template tie(A...) { alias tie = A; } tie!(a, b) = tuple(1, 2); artur
Jul 03 2013
On 07/03/13 18:29, Brad Anderson wrote:On Wednesday, 3 July 2013 at 11:54:39 UTC, Artur Skawina wrote:Try it... And, yes, the fact that 'A...' template parms accept symbols is not exactly obvious. But it's much more useful that way. arturOn 07/03/13 02:22, Brad Anderson wrote:That won't work. a and b aren't held as references (also you passed them as type parameters :P).C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple?Well, aliases can be used to get a similar effect. template tie(A...) { alias tie = A; } tie!(a, b) = tuple(1, 2);
Jul 03 2013
On Wednesday, 3 July 2013 at 16:35:18 UTC, Artur Skawina wrote:On 07/03/13 18:29, Brad Anderson wrote:Huh, I had no idea you could do something like that. I stand corrected. Thanks. That does get tie = working but doesn't work if you want to pass it around which is actually more at the heart of what I'm interested in. To get straight to the point, I was playing around with implementing bearophile's enumerate() feature request (something I've wanted myself). Both his posted solution [1] and my own quick testing hack (auto enumerate(Range)(Range r) { return zip(sequence!"n"(), r); }) lose the ability to do ref elements in foreach that can modify the source range: --- auto a = ["a", "b", "c"]; foreach(i, ref item; a.enumerate()) item = to!string(i); assert(a == ["0", "1", "2"]); // fails, a is still ["a", "b", "c"] --- They don't work because both the tuples he returns from front and the tuples zip creates aren't references to the originals so you are just changing the copy stored in the tuple. Something like "alias RefIntTuple = Tuple!(ref int, ref int);" gives a compiler error (Error: expression expected, not 'ref'). 1. http://d.puremagic.com/issues/show_bug.cgi?id=5550#c2On Wednesday, 3 July 2013 at 11:54:39 UTC, Artur Skawina wrote:Try it... And, yes, the fact that 'A...' template parms accept symbols is not exactly obvious. But it's much more useful that way. arturOn 07/03/13 02:22, Brad Anderson wrote:That won't work. a and b aren't held as references (also you passed them as type parameters :P).C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple?Well, aliases can be used to get a similar effect. template tie(A...) { alias tie = A; } tie!(a, b) = tuple(1, 2);
Jul 03 2013
On 07/03/13 19:10, Brad Anderson wrote:On Wednesday, 3 July 2013 at 16:35:18 UTC, Artur Skawina wrote:D does not yet have proper ref types, which means a lot of things are not possible, at least not directly. And a lot of hacks are required to achieve certain effects. Anyway, the following seems to work - it's bearophiles code from the mentioned bugzilla entry with some tweaks. It's dirty enough, so I shouldn't be posting this on a 'learn' ML... It's meant more as an illustration of the language deficiencies. Please do not use anything like this. :) import std.stdio, std.algorithm, std.range, std.typecons, std.traits, std.array; struct RefHack(T) { T* ptr; ref get() property { return *ptr; } alias get this; } auto refHack(T)(ref T a) { return RefHack!T(&a); } struct Enumerate(R) { R r; int i; property bool empty() { return r.empty; } property Tuple!(typeof(this.i), typeof(refHack(r.front))) front() { return typeof(return)(i, refHack(r.front)); } void popFront() { this.r.popFront(); this.i++; } } Enumerate!R enumerate(R)(R range, int start=0) if (isInputRange!R) { return Enumerate!R(range, start); } void main() { auto flags = [0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1]; flags.enumerate(2).filter!q{!a[1]}().map!q{a[0]}().writeln(); { import std.conv; auto a = ["a", "b", "c"]; foreach(i, ref item; a.enumerate()) item = to!string(i); assert(a == ["0", "1", "2"]); } } arturOn 07/03/13 18:29, Brad Anderson wrote:Huh, I had no idea you could do something like that. I stand corrected. Thanks. That does get tie = working but doesn't work if you want to pass it around which is actually more at the heart of what I'm interested in. To get straight to the point, I was playing around with implementing bearophile's enumerate() feature request (something I've wanted myself). Both his posted solution [1] and my own quick testing hack (auto enumerate(Range)(Range r) { return zip(sequence!"n"(), r); }) lose the ability to do ref elements in foreach that can modify the source range: --- auto a = ["a", "b", "c"]; foreach(i, ref item; a.enumerate()) item = to!string(i); assert(a == ["0", "1", "2"]); // fails, a is still ["a", "b", "c"] --- They don't work because both the tuples he returns from front and the tuples zip creates aren't references to the originals so you are just changing the copy stored in the tuple. Something like "alias RefIntTuple = Tuple!(ref int, ref int);" gives a compiler error (Error: expression expected, not 'ref'). 1. http://d.puremagic.com/issues/show_bug.cgi?id=5550#c2On Wednesday, 3 July 2013 at 11:54:39 UTC, Artur Skawina wrote:Try it... And, yes, the fact that 'A...' template parms accept symbols is not exactly obvious. But it's much more useful that way. arturOn 07/03/13 02:22, Brad Anderson wrote:That won't work. a and b aren't held as references (also you passed them as type parameters :P).C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple?Well, aliases can be used to get a similar effect. template tie(A...) { alias tie = A; } tie!(a, b) = tuple(1, 2);
Jul 03 2013
On 2013-07-03, 02:22, Brad Anderson wrote:C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple?Not that I know of. But, Philippe Sigaud's dranges[1] library includes a RefTuple[2], which should do what you want. [1]: https://github.com/dawgfoto/dranges/ [2]: https://github.com/dawgfoto/dranges/blob/master/reftuple.d -- Simen
Jul 03 2013