www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Arrays as template parameters

reply "cal" <callumenator gmail.com> writes:
I have the following code (on dpaste, 
http://dpaste.dzfl.pl/636c04430a33):

enum : uint { a, b, c }
enum list = [a, b];

void foo(T...)()
{
   pragma(msg, T[0].length); // fine
   pragma(msg, T[0][0]);	    // fine
   pragma(msg, T[0][1]);	    // fine
	
   foreach(i; Iota!(0,T[0].length)) // fine
     pragma(msg, T[0][i]);

   //foreach(c; T[0]) // not fine
   //	pragma(msg, c);
}

template Iota(size_t i, size_t n)
{
   import std.typetuple : TypeTuple;
   static if (n == 0) alias TypeTuple!() Iota;
     else alias TypeTuple!(i, Iota!(i + 1, n - 1)) Iota;
}

void main()
{
   foo!list;
}

Just trying to pass a statically known array as a template 
parameter. The foreach marked 'not fine' doesn't work, saying c 
cannot be read at compile time, despite the length and all values 
being known at compile time. The foreach above it uses a template 
to generate a static tuple of indices, which are used to index 
into the array, which works but seems unnecessary.

Is there a better way to do this?
Jun 04 2014
parent "anonymous" <anonymous example.com> writes:
On Wednesday, 4 June 2014 at 23:25:13 UTC, cal wrote:
 I have the following code (on dpaste, 
 http://dpaste.dzfl.pl/636c04430a33):

 enum : uint { a, b, c }
 enum list = [a, b];

 void foo(T...)()
 {
   pragma(msg, T[0].length); // fine
   pragma(msg, T[0][0]);	    // fine
   pragma(msg, T[0][1]);	    // fine
 	
   foreach(i; Iota!(0,T[0].length)) // fine
     pragma(msg, T[0][i]);

   //foreach(c; T[0]) // not fine
   //	pragma(msg, c);
 }

 template Iota(size_t i, size_t n)
 {
   import std.typetuple : TypeTuple;
   static if (n == 0) alias TypeTuple!() Iota;
     else alias TypeTuple!(i, Iota!(i + 1, n - 1)) Iota;
 }

 void main()
 {
   foo!list;
 }

 Just trying to pass a statically known array as a template 
 parameter. The foreach marked 'not fine' doesn't work, saying c 
 cannot be read at compile time, despite the length and all 
 values being known at compile time. The foreach above it uses a 
 template to generate a static tuple of indices, which are used 
 to index into the array, which works but seems unnecessary.

 Is there a better way to do this?
The foreach itself does work. It's pragma(msg, c) that doesn't. That's because it's a run time foreach, so c is a run time variable which "cannot be read at compile time". We don't have an explicit static foreach. That's why you need that Iota template and can't use std.range.iota. Just like that, you'd have to construct a TypeTuple from the array to get a static foreach.
Jun 05 2014