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