www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Access template parameters at runtime

reply "Henning Pohl" <henning still-hidden.de> writes:
A struct is meant to take only integers as parameters:

struct SomeStruct(intergers...) {
     int opIndex(size_t idx) /* ... */ {
         return integers[idx]; // Error ...
     }
}

alias SomeStruct!(1, 2, 3) ss;


But it results in:
Error: undefined identifier integers, did you mean tuple 
intergers?


How can this problem be solved?
Aug 10 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/10/12 9:55 AM, Henning Pohl wrote:
 A struct is meant to take only integers as parameters:

 struct SomeStruct(intergers...) {
 int opIndex(size_t idx) /* ... */ {
 return integers[idx]; // Error ...
 }
 }

 alias SomeStruct!(1, 2, 3) ss;


 But it results in:
 Error: undefined identifier integers, did you mean tuple intergers?


 How can this problem be solved?

By fixing the typo? Andrei
Aug 10 2012
parent reply travert phare.normalesup.org (Christophe Travert) writes:
"Henning Pohl" , dans le message (digitalmars.D:174569), a écrit :
 On Friday, 10 August 2012 at 14:10:38 UTC, Vladimir Panteleev 
 wrote:
 On Friday, 10 August 2012 at 14:10:02 UTC, Vladimir Panteleev
 wrote:
 On Friday, 10 August 2012 at 14:05:16 UTC, Henning Pohl wrote:
 Oups, sorry, imagine there isn't one.

 So the error is: variable idx cannot be read at compile time.

You can't index a tuple during compilation.

Sorry, meant to say - during runtime.

Thats it, thank you :]

Note that if your design makes that you must have a tuple, you may build the array at compile time, so that you can index it at run time.
Aug 10 2012
next sibling parent travert phare.normalesup.org (Christophe Travert) writes:
"Henning Pohl" , dans le message (digitalmars.D:174572), a écrit :
 That is what I was trying first, but I could not make it work. 
 Maybe you can show me how it's done?

For example: import std.stdio; template TupleToArray(T...) { static if (T.length == 1) { enum TupleToArray = [T[0]]; } else { enum TupleToArray = TupleToArray!(T[0..$-1]) ~ T[$-1]; } } void main() { alias TupleToArray!(1, 2, 3) oneTwoThree; foreach (i; 0..3) writeln(oneTwoThree[i]); } output: 1 2 3 TupleToArray should have proper check to make clean code. There must be something like that somewhere in phobos, or it should be added. -- Christophe
Aug 10 2012
prev sibling next sibling parent Denis Shelomovskij <verylonglogin.reg gmail.com> writes:
10.08.2012 19:26, David Nadlinger пишет:
 Just use the compiler tuple inside an array literal, like this:
 [integers]. It will auto-expand, just when passing it to a method.

And if it's impossible/undesirable to create an array, you can do this: --- foreach(i, t; your_tuple) if(i == idx) return t; // or do something else assert(0); --- -- Денис В. Шеломовский Denis V. Shelomovskij
Aug 10 2012
prev sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 11-Aug-12 00:58, Andrej Mitrovic wrote:
 On 8/10/12, jerro <a a.com> wrote:
 This would be one way to do it:

On 8/10/12, Christophe Travert <travert phare.normalesup.org> wrote:
 For example:

Guys I think you're overcomplecating it, you can just do: struct SomeStruct(integers...) { enum ints = [integers]; int opIndex(size_t idx) /* ... */ { return ints[idx]; } } enum or static both work.

Internally identical to: int opIndex(size_t idx) { return [integers][idx]; } Allocates on every call or not? I've no idea maybe Kenji fixed this already. -- Dmitry Olshansky
Aug 10 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/10/2012 11:09 PM, Dmitry Olshansky wrote:
 On 11-Aug-12 00:58, Andrej Mitrovic wrote:
 On 8/10/12, jerro <a a.com> wrote:
 This would be one way to do it:

On 8/10/12, Christophe Travert <travert phare.normalesup.org> wrote:
 For example:

Guys I think you're overcomplecating it, you can just do: struct SomeStruct(integers...) { enum ints = [integers]; int opIndex(size_t idx) /* ... */ { return ints[idx]; } } enum or static both work.

Internally identical to: int opIndex(size_t idx) { return [integers][idx]; } Allocates on every call or not? I've no idea maybe Kenji fixed this already. -- Dmitry Olshansky

Still allocates in 2.060. static is the keyword of choice.
Aug 10 2012
prev sibling next sibling parent "Henning Pohl" <henning still-hidden.de> writes:
On Friday, 10 August 2012 at 14:02:08 UTC, Andrei Alexandrescu 
wrote:
 On 8/10/12 9:55 AM, Henning Pohl wrote:
 A struct is meant to take only integers as parameters:

 struct SomeStruct(intergers...) {
 int opIndex(size_t idx) /* ... */ {
 return integers[idx]; // Error ...
 }
 }

 alias SomeStruct!(1, 2, 3) ss;


 But it results in:
 Error: undefined identifier integers, did you mean tuple 
 intergers?


 How can this problem be solved?

By fixing the typo? Andrei

Oups, sorry, imagine there isn't one. So the error is: variable idx cannot be read at compile time.
Aug 10 2012
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Friday, 10 August 2012 at 14:05:16 UTC, Henning Pohl wrote:
 Oups, sorry, imagine there isn't one.

 So the error is: variable idx cannot be read at compile time.

You can't index a tuple during compilation. You need to use an array: struct SomeStruct(alias integers) { int opIndex(size_t idx) { return integers[idx]; } } alias SomeStruct!([1, 2, 3]) ss;
Aug 10 2012
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Friday, 10 August 2012 at 14:10:02 UTC, Vladimir Panteleev
wrote:
 On Friday, 10 August 2012 at 14:05:16 UTC, Henning Pohl wrote:
 Oups, sorry, imagine there isn't one.

 So the error is: variable idx cannot be read at compile time.

You can't index a tuple during compilation.

Sorry, meant to say - during runtime.
Aug 10 2012
prev sibling next sibling parent "Henning Pohl" <henning still-hidden.de> writes:
On Friday, 10 August 2012 at 14:10:38 UTC, Vladimir Panteleev 
wrote:
 On Friday, 10 August 2012 at 14:10:02 UTC, Vladimir Panteleev
 wrote:
 On Friday, 10 August 2012 at 14:05:16 UTC, Henning Pohl wrote:
 Oups, sorry, imagine there isn't one.

 So the error is: variable idx cannot be read at compile time.

You can't index a tuple during compilation.

Sorry, meant to say - during runtime.

Thats it, thank you :]
Aug 10 2012
prev sibling next sibling parent "Henning Pohl" <henning still-hidden.de> writes:
On Friday, 10 August 2012 at 14:35:29 UTC, 
travert phare.normalesup.org (Christophe Travert) wrote:
 "Henning Pohl" , dans le message (digitalmars.D:174569), a 
 écrit :
 On Friday, 10 August 2012 at 14:10:38 UTC, Vladimir Panteleev 
 wrote:
 On Friday, 10 August 2012 at 14:10:02 UTC, Vladimir Panteleev
 wrote:
 On Friday, 10 August 2012 at 14:05:16 UTC, Henning Pohl 
 wrote:
 Oups, sorry, imagine there isn't one.

 So the error is: variable idx cannot be read at compile 
 time.

You can't index a tuple during compilation.

Sorry, meant to say - during runtime.

Thats it, thank you :]

Note that if your design makes that you must have a tuple, you may build the array at compile time, so that you can index it at run time.

That is what I was trying first, but I could not make it work. Maybe you can show me how it's done?
Aug 10 2012
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Friday, 10 August 2012 at 14:42:24 UTC, Henning Pohl wrote:
 That is what I was trying first, but I could not make it work. 
 Maybe you can show me how it's done?

Just use the compiler tuple inside an array literal, like this: [integers]. It will auto-expand, just when passing it to a method. David
Aug 10 2012
prev sibling next sibling parent "jerro" <a a.com> writes:
 Note that if your design makes that you must have a tuple, you 
 may build
 the array at compile time, so that you can index it at run 
 time.

That is what I was trying first, but I could not make it work. Maybe you can show me how it's done?

This would be one way to do it: auto staticArray(Elements...)(Elements elements) { alias Elements[0] E; E[Elements.length] r; foreach(i, _; elements) r[i] = elements[i]; return r; } struct SomeStruct(integers...) { enum arr = staticArray(integers); int opIndex(size_t idx){ return arr[idx]; } }
Aug 10 2012
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Friday, 10 August 2012 at 15:26:51 UTC, David Nadlinger wrote:
 It will auto-expand, just when passing it to a method.

Darn, that should have been: »just like when …« David
Aug 10 2012
prev sibling next sibling parent "Henning Pohl" <henning still-hidden.de> writes:
Great, thank you :]

The solution provided by David seems to be shortest. You can even 
pass the ints directly.
Aug 10 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/10/12, jerro <a a.com> wrote:
 This would be one way to do it:

On 8/10/12, Christophe Travert <travert phare.normalesup.org> wrote:
 For example:

Guys I think you're overcomplecating it, you can just do: struct SomeStruct(integers...) { enum ints = [integers]; int opIndex(size_t idx) /* ... */ { return ints[idx]; } } enum or static both work.
Aug 10 2012
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/10/12, Dmitry Olshansky <dmitry.olsh gmail.com> wrote:
 Internally identical to:

 int opIndex(size_t idx)
 {
 	return [integers][idx];
 }

 Allocates on every call or not? I've no idea maybe Kenji fixed this
 already.

t's easy to check, add "writeln(&ints[idx]);" in opIndex and index [0] several times. If the addresses change it means it allocates. It does allocate every time when it's an enum but not if it's static.
Aug 10 2012