| Thread overview | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 08, 2014 Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
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 Re: Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Remo | 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 Re: Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Meta | 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 Re: Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Remo | 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 Re: Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Remo | 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 Re: Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Meta Attachments:
| 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 Re: Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to NCrashed . | 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 Re: Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to NCrashed | 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 Re: Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | 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 Re: Tuple and tie? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to anonymous | 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. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply