Hi again,

I'm trying to do variadic parameter processing, and I have the following function that works fine:

  static bool same(T1, T2)(){
    pragma(msg, "same? "~T1.stringof~" "~T2.stringof);
    return is(immutable(T1)==immutable(T2));
  }

  Btn btn(T...)(string params, T args){
    enum captureIntID = true,
         captureBoolEnabled = true,
         captureFunct = true;

Args r; //Arg is a struct to store all the possible parameters in runtime
    static foreach(a; args){
      //process id parameter
           static if(same!(typeof(a), id)) r.id = a.val;
else static if(captureIntID && (same!(typeof(a), int) || same!(typeof(a), uint))) r.id = a;

      //process enabled/disabled
else static if(same!(typeof(a), enabled )) r.enabled = a.val; else static if(same!(typeof(a), disabled)) r.enabled = !a.val; else static if(captureBoolEnabled && same!(typeof(a), bool) ) r.enabled = a;

      //process data events
else static if(same!(typeof(a), onClick )) r.events.onClick = a.f; else static if(same!(typeof(a), onPress )) r.events.onPress = a.f; else static if(same!(typeof(a), onRelease)) r.events.onRelease = a.f; else static if(same!(typeof(a), onChange )) r.events.onChange = a.f; else static if(same!(typeof(a), onTrue )) r.events.onTrue = a.f; else static if(same!(typeof(a), onFalse )) r.events.onFalse = a.f; else static if(same!(typeof(a), onBool )) r.events.onBool = a.f; else static if(typeof(a).stringof.startsWith("void delegate()" )) r.events.onClick = a; else static if(typeof(a).stringof.startsWith("void delegate(bool)")) r.events.onBool = a;

else static assert(false, "Unsupported type "~typeof(a).stringof);
    }

    return new Btn(params, r.id, r.enabled, r.events);
  }


The long chain of is's are required to be able to show the error message at the end when an unhandled parameter type is found.

I will have more of these and want to reuse these ifs in other functions as well, so I decided to take out the first 2 if's and put it into a template function:

  static bool processId(bool captureIntId, alias r, alias a)(){
    mixin("alias ta = typeof("~a.stringof~");");
    pragma(msg, "ta "~ta.stringof);
         static if(same!(ta, id)) { r = a.val; return true; }
else static if(captureIntId && (same!(ta, int) || same!(ta, uint))) { r = a; return true; }
    else return false;
  }

later I call it with:

  static if(processId!(true, r.id, a)){}
  else static if(...

'a' is the variadic foreach variable (_param_1 and so on),
'r.id' is the result field from an Arg structure.
Both 'a' and 'r.id' are existing and compiling, also the pragma messages are good, I see it can find the right types, but I have the following error for every variadic parameter:

Error: template instance processId!(true, id, _param_1) processId!(true, id, _param_1) is nested in both Args and btn

id is a struct. And also a field in the Args struct. I changed it to id1 in the Args struct ant the error remains the same. Everything resides in the scope of a class called ContainerBuilder.

Is there a way to do this elegantly?
Maybe if I put everything in a very large chain of if's and enable the required parameters with a set of flags, but that's not structured well, and also needs the biggest possible set of runtime parameter storage to store the processed parametest.

Here's an example using the above function:
btn(`Yes flex=1`, id(54231), enabled(true), { lastClickedBtn = "Yes"; hehe = true; })
checkbox("Checkbox_1", 12345432, (bool b){ hehe = b; })

I will have a lot of controls and a lot of parameter types. I wanna do something like in the old VisualBasic, where you can skip a lot of default parameters, and also access the only few you need by name. Something like this: btn("caption", hint:"blabla", icon:"icon.ico"), but as I currently know this is not implemented in D.

Thank You in advance!


Reply via email to