Distinguishing between const and non-const variable in a template?

mario pernici mario.pernici at mi.infn.it
Thu Feb 22 06:01:23 PST 2007


renoX Wrote:

> Hello,
> 
> I'm trying to improve format string by allowing the format
> " ... %{x} ...", my problem is that when I give a non-const char[] 
> parameter in
> mixin(Putf!(foo));
> 
> then the template fail..
> 
> How can I reliably detect in a template if the parameter is a constant 
> or not?
> 
> My goal is:
> if the parameter isn't a const char[]: leave its name unchanged so that 
> it's parsed by the writef at runtime, if it is a const char[]: parse it 
> myself with the new syntax.
> 
> Regards,
> renoX
> 
> template FindChar(char[] A, char B) {
>      static if (A.length == 0) {
>          const int FindChar = -1;
>      } else static if (A[0] == B) {
>          const int FindChar = 0;
>      } else static if (-1 == FindChar!(A[1..$], B)) {
> 		const int FindChar = -1;
> 	} else {
> 		const int FindChar = 1 + FindChar!(A[1..$], B);
> 	}
> }
> 
> template FmtString(char[] F, A...)
> {
> 	static if (F.length == 0)
> 		static if (A.length)
> 			const char[] FmtString = "\"," ~ Fmt!(A);
> 		else
> 			const char[] FmtString = "\"";
> 	else static if (F.length == 1)
> 		static if (A.length)
> 			const char[] FmtString = F[0] ~ "\"," ~ Fmt!(A);
> 		else
> 			const char[] FmtString = F[0] ~ "\"";
> 	else static if (F[0..2] == "%%")
> 		const char[] FmtString = "%%" ~ FmtString!(F[2..$], A);
> 	else static if (F[0..2] == "%{")
> 	{
> 		// get the variable name between %{ and }
> 		static if (FindChar!(F, '}') <= 2)
> 			static assert(0, "format %{} incorrect in '" ~ F ~ "'");
> 		const char[] FmtString = "%s\"," ~ F[2..FindChar!(F,'}')] ~ ",\"" ~
> 			FmtString!(F[1+FindChar!(F,'}')..$], A);
> 	}
> 	else
> 		const char[] FmtString = F[0] ~ FmtString!(F[1..$], A);
> }
> 
> template Fmt(A...)
> {
> 	//static assert(0, cast(char*)A[0]);
> 	static if (A.length == 0)
> 		const char[] Fmt = "";
> 	else static if (is(typeof(A[0]) : char[]))
> 		const char[] Fmt = "\"" ~ FmtString!(A[0], A[1..$]);
> 	else static if (A.length == 1)
> 		const char[] Fmt = A[0].stringof;
> 	else
> 		const char[] Fmt = A[0].stringof ~ "," ~ Fmt!(A[1..$]);	
> }
> 
> template Putf(A...)
> {
> 	const char[] Putf = "writef(" ~ Fmt!(A) ~ ");";
> }

Maybe you can use something like this

  const char[] s = "ab";
  static if(is(typeof(&s))) {
    writefln(s, " not constant");
  }
  else {
    static if(is(typeof(s))) {
      writefln(s, " constant");
    }
  }



More information about the Digitalmars-d-learn mailing list