Thread overview
Tuple and tie?
Jul 08, 2014
Remo
Jul 08, 2014
Meta
Jul 08, 2014
Remo
Jul 08, 2014
Meta
Jul 08, 2014
NCrashed .
Jul 08, 2014
NCrashed
Jul 08, 2014
NCrashed
Jul 08, 2014
H. S. Teoh
Jul 08, 2014
anonymous
Jul 08, 2014
H. S. Teoh
July 08, 2014
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);
}
July 08, 2014
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);
}
July 08, 2014
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.

July 08, 2014
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.
July 08, 2014
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);
}
```
July 08, 2014
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.
>


July 08, 2014
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);
}
```
July 08, 2014
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
July 08, 2014
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.
July 08, 2014
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.