various questions

Steven Schveighoffer schveiguy at yahoo.com
Thu Jul 29 10:30:04 PDT 2010


On Wed, 28 Jul 2010 14:52:11 -0400, Jason Spencer <spencer8 at 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


More information about the Digitalmars-d-learn mailing list