Variadic template arguments unpacking

Max Strakhov monnoroch at gmail.com
Sat Jul 6 12:39:32 PDT 2013


> foo(getArray(v[0])[], getArray(v[1])[], getArray(v[2])[]);
>
> It's easy to conceptualise and easy to get it right.

I wrote a template, that can do something like that:

template Expand(string code, string Args, string args, Ts...) {
	const hasType = std.string.indexOf(code, "%Arg") != -1;
	const hasVal  = std.string.indexOf(code, "%arg") != -1;

	static if(hasType)
		const code1 = std.array.replace(code, "%Arg", Args ~ "[%d]");
	else
		const code1 = code;

	static if(hasVal)
		const code2 = std.array.replace(code1, "%arg", args ~ "[%d]");
	else
		const code2 = code1;

	template Fun(size_t i, T) {
		static if(!hasType && !hasVal)
			alias Fun = TypeTuple!(code2);
		else static if(hasType && hasVal)
			alias Fun = TypeTuple!(std.string.format(code2, i, i));
		else
			alias Fun = TypeTuple!(std.string.format(code2, i));
	}

	template ConcatArgs() {
		const Val = "";
	}

	template ConcatArgs(T, As...) if(!is(T == string)) {
		static assert(T);
	}

	template ConcatArgs(string s, As...) if(As.length == 0) {
		const Val = s;
	}

	template ConcatArgs(string s, As...) if(As.length != 0) {
		const Val = s ~ ", " ~ ConcatArgs!As.Val;
	}

	const Val = ConcatArgs!(staticIndexedMap!(Fun, Ts)).Val;
}

Usage:

writeln(Expand!("getArray(%arg)[]", "", "v", string, int, 
int).Val); // == getArray(v[0])[], getArray(v[1])[], 
getArray(v[2])[]

If anyine has any ideas how make this implementation simplier, 
bring it on :)


More information about the Digitalmars-d-learn mailing list