Error on recursive alias

Johan Mollevik lijat.REMOVE.me at gmail.com
Sun Aug 25 10:33:33 PDT 2013


Ali Çehreli wrote:

> On 08/25/2013 09:23 AM, Johan Mollevik wrote:
> 
>  > Hmm, your solution does not work with static arrays it seems, will 
se
>  > if I can sort that out
> 
> Probably due to the fact that static arrays cannot be InputRanges
> because they cannot lose elements by popFront(). A slice to the 
entire
> array is an InputRange though:
> 
>      foreach (e; myStaticArray)      // compilation error
> 
>      foreach (e; myStaticArray[])    // works
> 
> Ali

I accutally got my original code to work just now. I made a mistake 
when translating typeof(T[0]) into more modern code. That caused 
supprising errors.

Pasting the code bellow if anyone is interested (can probably be 
shortened), thanks for the help and quick response.


import std.traits;
import std.conv;
import std.metastrings;

template Tuple(T...)
{
        alias T Tuple;
}
template opApplyType(T)
{
        static if(isArray!T)
                alias Tuple!(size_t,ForeachType!T) opApplyType;
        else static if(isAssociativeArray!T)
                alias Tuple!(typeof(T.keys)[0],typeof(T.values)[0]) 
opApplyType;
        else static if(hasMember!(T,"opApply"))
                alias ParameterTypeTuple!(typeof(&T.opApply)) 
opApplyType;
}
template foreachType(T)
{
        static if(is(opApplyType!(T) V))
        {    
                static if(is(opApplyType!(V[$-1])))
                        alias Tuple!(V[0..$-1],foreachType!(V[$-1])) 
foreachType;
                else 
                        alias V foreachType;
        }    
        else 
        {    
                pragma(msg,"Failed to resolve type ");
                static assert(0,opApplyType!(T));
        }    
}
template DgArgs(T...)
{
        static if(T.length)
                const char[] DgArgs="ref "~T[0].stringof~","~DgArgs!
(T[1..$]);
        else 
                const char[] DgArgs="";
}
template DgType(T...)
{
        mixin("alias int delegate("~DgArgs!(T)~") Type;");
}
template opApplyParams(int i)
{
        static if(i==0)
                const char[] opApplyParams="";
        else 
                const char[] 
opApplyParams=",p"~to!string(i)~opApplyParams!(i-1);
}
template opApplyRest(int i)
{
        const char[] opApplyRest="foreach(p"~opApplyParams!
(i)~";opApplyN(v))"
                                ~"\n\tif(auto r=dg(i,p"~opApplyParams!
(i)~"))"
                                ~"\n\t\treturn r;";
}
struct opApplyContext(T)
{
        alias foreachType!(T) FT;
        mixin DgType!(FT) DG;
        T* a;
        int opApply(DG.Type dg)
        {
                //consider recursive mixin of delegate function
                //writefln("Begin opApplyN: ",DG.Type.stringof);
                static if(isArray!T)
                {
                        //pragma(msg,"array");
                        static if(is(opApplyType!(typeof((*a)[0])) V))
                        {
                                //pragma(msg,"branch");
                                foreach(i,v;*a)
                                {
                                        //pragma(msg,V.stringof);
                                        //pragma(msg,DG.Type.stringof);
                                        //pragma(msg,typeof(&opApplyN(v).opApply).stringof);
                                        //pragma(msg,opApplyRest!
(FT.length-2));
                                        mixin(opApplyRest!
(FT.length-2));
                                }
                        }
                        else
                        {
                                //pragma(msg,"leaf");
                                foreach(i,v;*a)
                                        if(auto r=dg(i,v))
                                                return r;
                        }
                }
                else static if(isAssociativeArray!(T))
                {
                        pragma(msg,"hash");
                        static assert(0,"Not Implemented");
                }
                else static if(hasMember!(T,"opApply"))
                {
                        pragma(msg,"opApply");
                        static assert(0,"Not Implemented");
                }
                else
                {
                        pragma(msg,"else");
                        static assert(0,"Not Implemented");
                }
                return 0;
        }
}
opApplyContext!(T) opApplyN(T)(T c)
{
        opApplyContext!(T) t;
        t.a=&c;
        return t;
}
opApplyContext!(T) opApplyN(T:T*)(T* c)
{
        opApplyContext!(T) t;
        t.a=c;
        return t;
}





More information about the Digitalmars-d-learn mailing list