Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 31, 2007 Help with Template Code | ||||
---|---|---|---|---|
| ||||
Hey all!
There's a particular problem I'm trying to solve using templates. I don't see a reason that the compiler couldn't do this, but I'm not certain I can do it with templates yet.
Here's a slightly simplified pseudo-code-ish version of what I want to do:
T inst(T : struct)(T.tupleof t);
Yes- this makes no sense, so let me describe. I want to create a templated
function wherein the template argument is a struct... OK, that's easy.
Next, I want the parameters of the function to be the types in the struct.
For example, if I have the following struct:
struct Foo {
int a;
float b;
}
then the following call:
Foo f = inst!(Foo)(5, 8.26)
would pass the Tuple!(int,float)(5, 8.26) into the inst function. No, it's
not OK to add stuff so the calling code, but the inst function can be as
ugly as necessary.
I feel like this should be possible, but I don't know how... Any ideas?
Thanks
--
~John Demme
me@teqdruid.com
http://www.teqdruid.com/
|
March 31, 2007 Re: Help with Template Code | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Demme | "John Demme" <me@teqdruid.com> wrote in message news:eukg7o$m31$1@digitalmars.com... > Hey all! > > There's a particular problem I'm trying to solve using templates. I don't see a reason that the compiler couldn't do this, but I'm not certain I can do it with templates yet. > > Here's a slightly simplified pseudo-code-ish version of what I want to do: > > T inst(T : struct)(T.tupleof t); > > Yes- this makes no sense, so let me describe. I want to create a > templated > function wherein the template argument is a struct... OK, that's easy. > Next, I want the parameters of the function to be the types in the struct. > For example, if I have the following struct: > struct Foo { > int a; > float b; > } > > then the following call: > Foo f = inst!(Foo)(5, 8.26) > would pass the Tuple!(int,float)(5, 8.26) into the inst function. No, > it's > not OK to add stuff so the calling code, but the inst function can be as > ugly as necessary. > > I feel like this should be possible, but I don't know how... Any ideas? > > Thanks > > -- > ~John Demme > me@teqdruid.com > http://www.teqdruid.com/ Wow! struct S { int x; float y; char[] z; static S opCall(typeof(S.tupleof) args) { S s; foreach(i, arg; args) s.tupleof[i] = arg; return s; } } void main() { S s = S(1, 2.3, "hi"); writefln(s.x); writefln(s.y); writefln(s.z); } I really didn't think I would be able to write that. |
March 31, 2007 Re: Help with Template Code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > "John Demme" <me@teqdruid.com> wrote in message news:eukg7o$m31$1@digitalmars.com... >> Hey all! >> >> There's a particular problem I'm trying to solve using templates. I don't see a reason that the compiler couldn't do this, but I'm not certain I can do it with templates yet. >> >> Here's a slightly simplified pseudo-code-ish version of what I want to do: >> >> T inst(T : struct)(T.tupleof t); >> >> Yes- this makes no sense, so let me describe. I want to create a >> templated >> function wherein the template argument is a struct... OK, that's easy. >> Next, I want the parameters of the function to be the types in the >> struct. For example, if I have the following struct: >> struct Foo { >> int a; >> float b; >> } >> >> then the following call: >> Foo f = inst!(Foo)(5, 8.26) >> would pass the Tuple!(int,float)(5, 8.26) into the inst function. No, >> it's >> not OK to add stuff so the calling code, but the inst function can be as >> ugly as necessary. >> >> I feel like this should be possible, but I don't know how... Any ideas? >> >> Thanks >> >> -- >> ~John Demme >> me@teqdruid.com >> http://www.teqdruid.com/ > > Wow! > > struct S > { > int x; > float y; > char[] z; > > static S opCall(typeof(S.tupleof) args) > { > S s; > > foreach(i, arg; args) > s.tupleof[i] = arg; > > return s; > } > } > > void main() > { > S s = S(1, 2.3, "hi"); > writefln(s.x); > writefln(s.y); > writefln(s.z); > } > > I really didn't think I would be able to write that. Ahh!!! typeof! That does it for me... much thanks. BTW, with your example above, you could probably turn that opCall into a mixin... It'd be a nice little mixin to have in Tango and/or Phobos. I've got one more template problem, but I'm pretty sure I can't do this. I now want to access the names of the struct's fields so that I could, for example, make a templated function that accepts a struct and prints name:value pairs for all the fields. Is there any way I can do this? (If so, I'm gonna be really, really impressed.) Thanks again -- ~John Demme me@teqdruid.com http://www.teqdruid.com/ |
March 31, 2007 Re: Help with Template Code | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Demme | John Demme wrote: > Jarrett Billingsley wrote: > >> "John Demme" <me@teqdruid.com> wrote in message news:eukg7o$m31$1@digitalmars.com... >>> Hey all! >>> >>> There's a particular problem I'm trying to solve using templates. I don't see a reason that the compiler couldn't do this, but I'm not certain I can do it with templates yet. >>> >>> Here's a slightly simplified pseudo-code-ish version of what I want to do: >>> >>> T inst(T : struct)(T.tupleof t); >>> >>> Yes- this makes no sense, so let me describe. I want to create a >>> templated >>> function wherein the template argument is a struct... OK, that's easy. >>> Next, I want the parameters of the function to be the types in the >>> struct. For example, if I have the following struct: >>> struct Foo { >>> int a; >>> float b; >>> } >>> >>> then the following call: >>> Foo f = inst!(Foo)(5, 8.26) >>> would pass the Tuple!(int,float)(5, 8.26) into the inst function. No, >>> it's >>> not OK to add stuff so the calling code, but the inst function can be as >>> ugly as necessary. >>> >>> I feel like this should be possible, but I don't know how... Any ideas? >>> >>> Thanks >>> >>> -- >>> ~John Demme >>> me@teqdruid.com >>> http://www.teqdruid.com/ >> Wow! >> >> struct S >> { >> int x; >> float y; >> char[] z; >> >> static S opCall(typeof(S.tupleof) args) >> { >> S s; >> >> foreach(i, arg; args) >> s.tupleof[i] = arg; >> >> return s; >> } >> } >> >> void main() >> { >> S s = S(1, 2.3, "hi"); >> writefln(s.x); >> writefln(s.y); >> writefln(s.z); >> } >> >> I really didn't think I would be able to write that. > > Ahh!!! typeof! That does it for me... much thanks. BTW, with your example above, you could probably turn that opCall into a mixin... It'd be a nice little mixin to have in Tango and/or Phobos. > > I've got one more template problem, but I'm pretty sure I can't do this. I now want to access the names of the struct's fields so that I could, for example, make a templated function that accepts a struct and prints name:value pairs for all the fields. Is there any way I can do this? (If so, I'm gonna be really, really impressed.) > > Thanks again Not directly. The way I'm going to solve this problem is to have a convention that any struct whose I want to be able to access by name should have a 'fieldsof' property. This will be a tuple of strings that name the fields in the order they appear in the struct. So, for your example: struct Foo { alias Tuple!("a","b") fieldsof; int a; float b; } In that case, Foo.fieldsof[i] is the name of the field Foo.tupleof[i]. Would be nice to have this built-in, but it's not a big drama. -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/ |
March 31, 2007 Re: Help with Template Code | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Demme | "John Demme" <me@teqdruid.com> wrote in message news:eukjpj$opg$1@digitalmars.com... >> >> Wow! >> >> struct S >> { >> int x; >> float y; >> char[] z; >> >> static S opCall(typeof(S.tupleof) args) >> { >> S s; >> >> foreach(i, arg; args) >> s.tupleof[i] = arg; >> >> return s; >> } >> } >> >> void main() >> { >> S s = S(1, 2.3, "hi"); >> writefln(s.x); >> writefln(s.y); >> writefln(s.z); >> } >> >> I really didn't think I would be able to write that. > > Ahh!!! typeof! That does it for me... much thanks. BTW, with your > example > above, you could probably turn that opCall into a mixin... It'd be a nice > little mixin to have in Tango and/or Phobos. template StructCtor(T) { static T opCall(typeof(T.tupleof) args) { T t; foreach(i, arg; args) t.tupleof[i] = arg; return t; } } struct s { int x; float y; char[] z; mixin StructCtor!(S); } |
March 31, 2007 Re: Help with Template Code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > "John Demme" <me@teqdruid.com> wrote in message news:eukjpj$opg$1@digitalmars.com... >> above, you could probably turn that opCall into a mixin... It'd be a nice >> little mixin to have in Tango and/or Phobos. > > template StructCtor(T) > { > static T opCall(typeof(T.tupleof) args) > { > T t; > > foreach(i, arg; args) > t.tupleof[i] = arg; > > return t; > } > } > > struct s > { > int x; > float y; > char[] z; > > mixin StructCtor!(S); > } Come on, we can do a bit better than that! --- template StructCtor() { static typeof(*this) opCall(typeof(typeof(*this).tupleof) args) { typeof(*this) t; foreach(i, arg; args) t.tupleof[i] = arg; return t; } } struct S { int x; float y; char[] z; mixin StructCtor; } --- There. Now you don't need to specify the type, and you get rid of the "!(S)" at point-of-use entirely. I didn't know you could omit !() from a template mixin statement until I tried it just now, by the way. Cool. |
March 31, 2007 Re: Help with Template Code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep wrote: > > > John Demme wrote: >> Jarrett Billingsley wrote: >> >>> "John Demme" <me@teqdruid.com> wrote in message news:eukg7o$m31$1@digitalmars.com... >>>> Hey all! >>>> >>>> There's a particular problem I'm trying to solve using templates. I don't see a reason that the compiler couldn't do this, but I'm not certain I can do it with templates yet. >>>> >>>> Here's a slightly simplified pseudo-code-ish version of what I want to do: >>>> >>>> T inst(T : struct)(T.tupleof t); >>>> >>>> Yes- this makes no sense, so let me describe. I want to create a >>>> templated >>>> function wherein the template argument is a struct... OK, that's easy. >>>> Next, I want the parameters of the function to be the types in the >>>> struct. For example, if I have the following struct: >>>> struct Foo { >>>> int a; >>>> float b; >>>> } >>>> >>>> then the following call: >>>> Foo f = inst!(Foo)(5, 8.26) >>>> would pass the Tuple!(int,float)(5, 8.26) into the inst function. No, >>>> it's >>>> not OK to add stuff so the calling code, but the inst function can be >>>> as ugly as necessary. >>>> >>>> I feel like this should be possible, but I don't know how... Any ideas? >>>> >>>> Thanks >>>> >>>> -- >>>> ~John Demme >>>> me@teqdruid.com >>>> http://www.teqdruid.com/ >>> Wow! >>> >>> struct S >>> { >>> int x; >>> float y; >>> char[] z; >>> >>> static S opCall(typeof(S.tupleof) args) >>> { >>> S s; >>> >>> foreach(i, arg; args) >>> s.tupleof[i] = arg; >>> >>> return s; >>> } >>> } >>> >>> void main() >>> { >>> S s = S(1, 2.3, "hi"); >>> writefln(s.x); >>> writefln(s.y); >>> writefln(s.z); >>> } >>> >>> I really didn't think I would be able to write that. >> >> Ahh!!! typeof! That does it for me... much thanks. BTW, with your example above, you could probably turn that opCall into a mixin... It'd be a nice little mixin to have in Tango and/or Phobos. >> >> I've got one more template problem, but I'm pretty sure I can't do this. I now want to access the names of the struct's fields so that I could, for example, make a templated function that accepts a struct and prints name:value pairs for all the fields. Is there any way I can do this? (If so, I'm gonna be really, really impressed.) >> >> Thanks again > > Not directly. The way I'm going to solve this problem is to have a convention that any struct whose I want to be able to access by name should have a 'fieldsof' property. This will be a tuple of strings that name the fields in the order they appear in the struct. So, for your example: > > struct Foo > { > alias Tuple!("a","b") fieldsof; > > int a; > float b; > } > > In that case, Foo.fieldsof[i] is the name of the field Foo.tupleof[i]. > > Would be nice to have this built-in, but it's not a big drama. > > -- Daniel > Yeah... I'm doing something similar now. I guess I'll stick with that. Thanks -- ~John Demme me@teqdruid.com http://www.teqdruid.com/ |
April 01, 2007 Re: Help with Template Code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frits van Bommel | "Frits van Bommel" <fvbommel@REMwOVExCAPSs.nl> wrote in message news:eum0c9$2b75$1@digitalmars.com... > > Come on, we can do a bit better than that! > --- > template StructCtor() > { > static typeof(*this) opCall(typeof(typeof(*this).tupleof) args) > { > typeof(*this) t; > > foreach(i, arg; args) > t.tupleof[i] = arg; > > return t; > } > } > > struct S > { > int x; > float y; > char[] z; > > mixin StructCtor; > } Ahh, I was hoping that was possible! |
April 01, 2007 Re: Help with Template Code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | On Sat, 31 Mar 2007 20:55:54 -0400, "Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote: >"Frits van Bommel" <fvbommel@REMwOVExCAPSs.nl> wrote in message news:eum0c9$2b75$1@digitalmars.com... >> >> Come on, we can do a bit better than that! >> --- >> template StructCtor() >> { >> static typeof(*this) opCall(typeof(typeof(*this).tupleof) args) >> { >> typeof(*this) t; >> >> foreach(i, arg; args) >> t.tupleof[i] = arg; >> >> return t; >> } >> } >> >> struct S >> { >> int x; >> float y; >> char[] z; >> >> mixin StructCtor; >> } > >Ahh, I was hoping that was possible! > Note that the mixin ctor is slower then manually coded one because of the loop. To improve performance, you could skip the struct initialization: template StructCtor() { static typeof(*this) opCall(typeof(typeof(*this).tupleof) args) { typeof(*this) t = void; foreach(i, arg; args) t.tupleof[i] = arg; return t; } } |
April 01, 2007 Re: Help with Template Code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samukha | "Max Samukha" <samukha@voliacable.com> wrote in message news:dopu039g3u5dtb0ubovm8c7ach304bdbb7@4ax.com... > Note that the mixin ctor is slower then manually coded one because of the loop. To improve performance, you could skip the struct initialization: That loop is unrolled at compile time since it's iterating over a tuple. It'll be just as fast as writing the initialization out line-by-line. But using =void is another nice optimization :) |
Copyright © 1999-2021 by the D Language Foundation