On Wed, 28 Jul 2010 14:52:11 -0400, Jason Spencer <spenc...@sbcglobal.net> wrote:

I'm working on a program to do statistics on matrices of different sizes, and
I've run into a handful of situations where I just can't seem to find the
trick I need.  In general, I'm trying to make my functions work on static
arrays of the proper size, and template that up for the different sizes I need to support. I appeal to your experience and mercy on the various questions
below.  Any help on any point appreciated.

1.  How can I cast a single dimension dynamic array to a multi-dimension
static array?  I'm trying to do roughly the following:

   auto data = cast(float[100][100])std.file.read(fname, fsize);

which fails on the cast.  Is there any way to treat they memory returned
from read as a static array? If I want to avoid the copy, am I relegated back to pointers? Is there a cast path through a pointer that would work? I think I'm essentially asking if I can make a reference to a static array and assign that to the memory contained in a dynamic array. I have a suspicion about the
answer....

2. To work around 1., I've left one dimension of the cast floating. This
means to bind both dimensions in my template args, I can no longer use
type parameter inference, so I have to explicitly instantiate the template
with the static size, but pass in a type that's dynamic in one dimension.

That is the correct way to do this. std.file.read is reading data into a heap array. If you want to cast this into a static array that lives on the stack, you will end up copying the data from the heap to the stack. Essentially, you are asking the type system to ignore the fact that std.file.read may *not* read 100x100 floats, which is quite unsafe.

Another thing you can do:

float[100][100] data;
File f = File(fname);
enforce(std.file.rawRead(data[]).length == data.length);

Now, data should be filled in, and you haven't used the heap.

If I could solve that, then next I'd need to make this work:

U foo(T: U[C][R], U, size_t C, size_t R)(U[C][] data, size_t c, size_t r)
   {
      return data[r][c];
   }

   int[4][] data = [ [...] ];
   int bar = foo(data, 2, 3);

Extra points for that one!

That one will never work, because data's type does not include the main dimension, so it can't be decided at compile time.

-Steve

Reply via email to