Compile time values & implicit conditional mixin, as an alternative to tertiary operator hell and one-compile-time functions.

Paul Backus snarwin at gmail.com
Sat Jan 16 04:13:12 UTC 2021


On Saturday, 16 January 2021 at 03:36:23 UTC, Paul wrote:
> Consider the following excerpts:
>
>> enum string values= "value.x" ~ (L == 1 ? "" : ",value.y" ~ (L 
>> == 2 ? "" : ",value.z" ~ (L == 3 ? "" : ",value.w")));
>> enum string kind = is(S == uint) ? "ui" :  (is(S == int) ? "i" 
>> :  (is(S == float) ? "f" : (assert(is(S == double)), "d"))); 
>> //(ignore the comma operator for now)
>
>> mixin("glUniform" ~ L.to!string ~ kind ~ "(uniformlocation, " 
>> ~ values ~ ");");
>
> Noticing two things:
> 1. Due to this being at compile time, I'm trying to use enums. 
> Sadly however, due to these being enums I cannot change them 
> after their definition, and am thus forced to use tertiary 
> operators (which feels problematic and very confusing)
> 2. Due to the comma operator being depricated (and not 
> replaced?!) I can no longer "neatly" assert things inside the 
> enum creation, and I see the possibility of needing another 
> other than solely the double type assert, in which case adding 
> an assert on the next line is no longer a valid option, given 
> some 'special' value for the "kind" enum string would no longer 
> be possible.
> [...]
> I realized creating a seperate function to return a string 
> callable inside mixin is an option. However creating a seperate 
> function purely to do compile time string creation seems like a 
> design flaw, which additionally does not prevent its usage at 
> runtime.

You can use immediately-invoked function literals to work around 
all of these issues:

enum string values = () {
     string result = "value.x";
     if (L != 1) { result ~= ",value.y"; }
     if (L != 2) { result ~= ",value.z"; }
     if (L != 3) { result ~= ",value.w"; }
     return result;
}(); // call the function we just defined

enum string kind = () {
     if (is(S == uint)) { return "ui"; }
     else if (is(S == float)) { return "f"; }
     else { assert(is(S == double)); return "d"; }
}();


More information about the Digitalmars-d mailing list