Auto recursive function

Ignacious via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Jan 11 16:30:33 PST 2017


On Wednesday, 11 January 2017 at 19:23:10 UTC, Razvan Nitu wrote:
> Hi,
>
> I am currently trying to create a function 
> makeMultidimensionalArray which allocates memory for a 
> multidimensional array. It is very similar with [1],
> the difference being that it is uninitialized. Here is the code:
>
> auto makeMultidimensionalArray(T, Allocator)(auto ref Allocator 
> alloc, size_t[] lengths)
> {
>     if (lengths.length == 1)
>     {
>         return makeArray!T(alloc, lengths[0]);
>     }
>     else
>     {
>         alias E = typeof(makeMultidimensionalArray!T(alloc, 
> lengths[1..$]));
>         auto ret = makeArray!E(alloc, lengths[0]);
>         foreach (ref e; ret)
>             e = makeMultidimensionalArray!T(alloc, 
> lengths[1..$]);
>         return ret;
>     }
> }
>
> The lengths[] specifies the lengths for each dimension. The 
> problem with this code is that auto is going to be evaluated to 
> T[] for the first time and when it
> recurs, creating T[][] I get the error "mismatched function 
> return type inference of T[][] and T[]". Is there a way to 
> surpass that? I saw that in [1]
> the recursive call is done by prefixing the function name with 
> a '.'; I tried that but it doesn't work. I must be missing 
> something, any ideas?
>
> Thanks,
> RazvanN
>
> [1] 
> https://github.com/dlang/phobos/blob/master/std/experimental/ndslice/slice.d#L834


If you change the return type to a void* your code basically 
works.


void* makeMultidimensionalArray(T, Allocator)(auto ref Allocator 
alloc, size_t[] lengths)
{
     if (lengths.length == 1)
     {
		int x = 0x01FEEF01;
         return cast(void*)makeArray!T(alloc, lengths[0], x);
     }
     else
     {
         alias E = typeof(makeMultidimensionalArray!T(alloc, 
lengths[1..$]));

         auto ret = makeArray!E(alloc, lengths[0]);
         foreach (ref e; ret)
             e = makeMultidimensionalArray!T(alloc, lengths[1..$]);
         return cast(void*)ret;
     }
}

The problem is that then you need to cast back and that 
essentially results in the original problem. Can be done but 
probably gonna have to use string mixins.


More information about the Digitalmars-d-learn mailing list