www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Tuple and tie?

reply "Remo" <remo4d gmail.com> writes:
How to make something that work like std::tie in D2 ?

Tuple!(float, float) sinCos(float n) {
   return tuple(cast(float)sin(n), cast(float)cos(n)); //please 
note cast(float)!
}

int main(string[] argv) {
  float s,c;
  tie!(s,c) = sinCos(3.0f);
}
Jul 08 2014
next sibling parent reply "Meta" <jared771 gmail.com> writes:
On Tuesday, 8 July 2014 at 17:42:00 UTC, Remo wrote:
 How to make something that work like std::tie in D2 ?

 Tuple!(float, float) sinCos(float n) {
   return tuple(cast(float)sin(n), cast(float)cos(n)); //please 
 note cast(float)!
 }

 int main(string[] argv) {
  float s,c;
  tie!(s,c) = sinCos(3.0f);
 }
alias tie = TypeTuple; int main(string[] argv) { float s,c; tie!(s,c) = sinCos(3.0f); }
Jul 08 2014
parent reply "Remo" <remo4d gmail.com> writes:
On Tuesday, 8 July 2014 at 18:29:40 UTC, Meta wrote:
 On Tuesday, 8 July 2014 at 17:42:00 UTC, Remo wrote:
 How to make something that work like std::tie in D2 ?

 Tuple!(float, float) sinCos(float n) {
  return tuple(cast(float)sin(n), cast(float)cos(n)); //please 
 note cast(float)!
 }

 int main(string[] argv) {
 float s,c;
 tie!(s,c) = sinCos(3.0f);
 }
alias tie = TypeTuple; int main(string[] argv) { float s,c; tie!(s,c) = sinCos(3.0f); }
Thanks ! This is easier as I was thinking :) Now I only need to be sure that this do not have unwanted side effects.
Jul 08 2014
parent reply "Meta" <jared771 gmail.com> writes:
On Tuesday, 8 July 2014 at 18:45:21 UTC, Remo wrote:
 On Tuesday, 8 July 2014 at 18:29:40 UTC, Meta wrote:
 On Tuesday, 8 July 2014 at 17:42:00 UTC, Remo wrote:
 How to make something that work like std::tie in D2 ?

 Tuple!(float, float) sinCos(float n) {
 return tuple(cast(float)sin(n), cast(float)cos(n)); //please 
 note cast(float)!
 }

 int main(string[] argv) {
 float s,c;
 tie!(s,c) = sinCos(3.0f);
 }
alias tie = TypeTuple; int main(string[] argv) { float s,c; tie!(s,c) = sinCos(3.0f); }
Thanks ! This is easier as I was thinking :) Now I only need to be sure that this do not have unwanted side effects.
It's fine. There's not much to TypeTuple; it's defined like this: alias TypeTuple(TList...) = alias TypeTuple = TList; Where TList is any number of... things. Types, variables, values, template names, etc. Therefore, `TypeTuple!(s, c)` at a low level it's more or less like the following: float s, c; s = sinCos(3.0f)[0]; c = sinCos(3.0f)[1]; Not that sinCos is called twice. It's only called once, and the result is distributed across s and c.
Jul 08 2014
parent reply "NCrashed . via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
Try this:
```
import std.typecons;
import std.typetuple;
import std.math;
import std.stdio;

auto tie(StoreElements...)(ref StoreElements stores)
{
alias Elements = staticMap!(Unqual, StoreElements);
 template toPointer(T)
{
alias toPointer = T*;
}
 struct Holder
{
alias StoreElementsPtrs = staticMap!(toPointer, StoreElements);
StoreElementsPtrs storePtrs;
 this(ref StoreElements stores)
{
foreach(i, _; StoreElements)
{
storePtrs[i] = &stores[i];
}
}
 void opAssign(Tuple!Elements values)
{
foreach(i, _; Elements)
{
*storePtrs[i] = values[i];
}
}
}
 return Holder(stores);
}

Tuple!(float, float) sinCos(float n)
{
return tuple(cast(float)sin(n), cast(float)cos(n)); //please note
cast(float)!
}

void main()
{
float s,c;
tie(s,c) = sinCos(3.0f);
writeln(s, " ", c);
}
```


2014-07-08 22:55 GMT+04:00 Meta via Digitalmars-d-learn <
digitalmars-d-learn puremagic.com>:

 On Tuesday, 8 July 2014 at 18:45:21 UTC, Remo wrote:

 On Tuesday, 8 July 2014 at 18:29:40 UTC, Meta wrote:

 On Tuesday, 8 July 2014 at 17:42:00 UTC, Remo wrote:

 How to make something that work like std::tie in D2 ?

 Tuple!(float, float) sinCos(float n) {
 return tuple(cast(float)sin(n), cast(float)cos(n)); //please note
 cast(float)!
 }

 int main(string[] argv) {
 float s,c;
 tie!(s,c) = sinCos(3.0f);
 }
alias tie = TypeTuple; int main(string[] argv) { float s,c; tie!(s,c) = sinCos(3.0f); }
Thanks ! This is easier as I was thinking :) Now I only need to be sure that this do not have unwanted side effects.
It's fine. There's not much to TypeTuple; it's defined like this: alias TypeTuple(TList...) = alias TypeTuple = TList; Where TList is any number of... things. Types, variables, values, template names, etc. Therefore, `TypeTuple!(s, c)` at a low level it's more or less like the following: float s, c; s = sinCos(3.0f)[0]; c = sinCos(3.0f)[1]; Not that sinCos is called twice. It's only called once, and the result is distributed across s and c.
Jul 08 2014
parent "NCrashed" <NCrashed gmail.com> writes:
Sorry, some glitch with email answer.

The main difference between my solution and TypeTuple is that you 
can pass anonymous struct between other functions to use it later:
```
void foo(T)(T holder)
{
	holder = sinCos(3.0f);
}

void main()
{
	float s,c;
	foo(tie(s,c));
	writeln(s, " ", c);
}
```
Jul 08 2014
prev sibling parent reply "NCrashed" <NCrashed gmail.com> writes:
On Tuesday, 8 July 2014 at 17:42:00 UTC, Remo wrote:
 How to make something that work like std::tie in D2 ?

 Tuple!(float, float) sinCos(float n) {
   return tuple(cast(float)sin(n), cast(float)cos(n)); //please 
 note cast(float)!
 }

 int main(string[] argv) {
  float s,c;
  tie!(s,c) = sinCos(3.0f);
 }
Try the following approach: ``` import std.typecons; import std.typetuple; import std.math; import std.stdio; auto tie(StoreElements...)(ref StoreElements stores) { alias Elements = staticMap!(Unqual, StoreElements); template toPointer(T) { alias toPointer = T*; } struct Holder { alias StoreElementsPtrs = staticMap!(toPointer, StoreElements); StoreElementsPtrs storePtrs; this(ref StoreElements stores) { foreach(i, _; StoreElements) { storePtrs[i] = &stores[i]; } } void opAssign(Tuple!Elements values) { foreach(i, _; Elements) { *storePtrs[i] = values[i]; } } } return Holder(stores); } Tuple!(float, float) sinCos(float n) { return tuple(cast(float)sin(n), cast(float)cos(n)); //please note cast(float)! } void main() { float s,c; tie(s,c) = sinCos(3.0f); writeln(s, " ", c); } ```
Jul 08 2014
parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Tue, Jul 08, 2014 at 07:02:17PM +0000, NCrashed via Digitalmars-d-learn
wrote:
[...]
 auto tie(StoreElements...)(ref StoreElements stores)
[...] Here's my take on it, that doesn't need to use pointers: import std.typecons; template TypesOf(T...) { static if (T.length == 1) alias TypesOf = typeof(T[0]); else alias TypesOf = TypeTuple!(typeof(T[0]), TypesOf!(T[1..$])); } property void tie(T...)(Tuple!(TypesOf!T) t) { foreach (i, ref var; T) { T[i] = t[i]; } } Tuple!(int, string) func() { return tuple(1, "a"); } void main() { int x; string y; tie!(x,y) = func(); import std.stdio; writefln("%d %s", x, y); } It does involve some slightly more arcane template magic, though. ;-) Basically, the TypesOf template transforms a list of alias arguments into a list of the types of said arguments, so that we can match a list of variables to the Tuple that is to be assigned to them. This also (ab)uses the fact that assigning to a function call gets interpreted in this context as setting a global property, so there's no need to overload opAssign at all. (Arguably, this makes it more an insane hack than a clever solution!) T -- Once the bikeshed is up for painting, the rainbow won't suffice. -- Andrei Alexandrescu
Jul 08 2014
parent reply "anonymous" <anonymous example.com> writes:
On Tuesday, 8 July 2014 at 19:40:59 UTC, H. S. Teoh via
Digitalmars-d-learn wrote:
 	template TypesOf(T...)
 	{
 		static if (T.length == 1)
 			alias TypesOf = typeof(T[0]);
 		else
 			alias TypesOf = TypeTuple!(typeof(T[0]), TypesOf!(T[1..$]));
 	}
 	
 	 property void tie(T...)(Tuple!(TypesOf!T) t)
[...]
 It does involve some slightly more arcane template magic, 
 though. ;-)
 Basically, the TypesOf template transforms a list of alias 
 arguments
 into a list of the types of said arguments, so that we can 
 match a list
 of variables to the Tuple that is to be assigned to them.
typeof(T) would work, too.
Jul 08 2014
parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Tue, Jul 08, 2014 at 07:46:14PM +0000, anonymous via Digitalmars-d-learn
wrote:
 On Tuesday, 8 July 2014 at 19:40:59 UTC, H. S. Teoh via
 Digitalmars-d-learn wrote:
	template TypesOf(T...)
	{
		static if (T.length == 1)
			alias TypesOf = typeof(T[0]);
		else
			alias TypesOf = TypeTuple!(typeof(T[0]), TypesOf!(T[1..$]));
	}
	
	 property void tie(T...)(Tuple!(TypesOf!T) t)
[...]
It does involve some slightly more arcane template magic, though. ;-)
Basically, the TypesOf template transforms a list of alias arguments
into a list of the types of said arguments, so that we can match a
list of variables to the Tuple that is to be assigned to them.
typeof(T) would work, too.
You're right! Shows how much I don't know, I guess. :P T -- There's light at the end of the tunnel. It's the oncoming train.
Jul 08 2014