Jump to page: 1 2
Thread overview
Help with Template Code
Mar 31, 2007
John Demme
Mar 31, 2007
John Demme
Mar 31, 2007
Daniel Keep
Mar 31, 2007
John Demme
Mar 31, 2007
Frits van Bommel
Apr 01, 2007
Max Samukha
Apr 01, 2007
Max Samukha
Apr 01, 2007
Frits van Bommel
Apr 01, 2007
Max Samukha
Apr 01, 2007
Frits van Bommel
Apr 02, 2007
Max Samukha
March 31, 2007
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
"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
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

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


« First   ‹ Prev
1 2