## digitalmars.D.learn - Tuple and tie?

"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
"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
"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
"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
"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
"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
"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
"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
"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
"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