Actually I can improve syntax a bit as follows:
Just figured out we can do this. Could this be added to phobos?----//in std.compiler (or std.traits?)template Version(alias V){mixin(`version(`~V~`){enum Version=true;}elseenum Version=false;`);}----usage:----import std.compiler;void main(){static if(!Version!"assert")writeln("not assert");static if(Version!"OSX" && !Version!"D_NoBoundsChecks" || !Version!"assert"){writeln("special code");}}----without this, we have to resort to something ugly, not dry, error prone:----//pollutes namespace, as we can't define version=temp inside a functionversion(OSX){version(D_NoBoundsChecks){}else{version=temp;//need to make sure temp doesn't clash with other version identifiers / symbols}}else{version(assert){}else{version=temp;//NOT DRY: repeats temp}}void main(){version(assert){}else{writeln("not assert");}version(temp) // here we use it{writeln("special code");}}----Likewise, with debug:----template Debug(alias V){import std.traits:isIntegral;static if(!isIntegral!(typeof(V))){mixin(`debug(`~V~`){enum Debug=true;}elseenum Debug=false;`);}else{import std.conv:to;mixin(`debug(`~V.to!string~`){enum Debug=true;}elseenum Debug=false;`);/+//NOTE:maybe a dmd bug but this didn't workdebug(V)enum Debug=true;elseenum Debug=false;+/}}----usage:----void main(){import std.compiler;static if(Debug!2){writeln("debug>=2");}static if(Debug!"foo"){writeln("debug=foo");}}----