www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Array reduction

I have the following code, in which I would like to try and 
simplify tUnrollArgs which I find to be a mess because of all the 
redundant code in it(having a static ternary if would definitely 
simplify things. (the tIf would help if I could "box" the args in 
an array easily so I could allow for a false statement too).

In any case, I am trying to get the tUnrollArgs2 working using 
the tForEach. This can simplify it a great deal. The problem is 
that the lambda expression must change for each argument passed 
to be able to handle arrays.

That is, I need to be able to call tForEach like

tForEach!((isAny!(args) x) { ... }, args);

where isAny is sort of a compound type of all the types used in 
args.

That is, so I can handle T and T[]. (right now I'm just using the 
type of the first argument, which is not always correct)

Any ideas how I can solve this problem?





module main;

import std.stdio, std.traits;

template tuple(args...) { alias tuple = args; }

template tIf(alias cond) { alias tIf = tuple!(); }
template tIf(alias cond, T...)
{
	static if (T.length == 0) alias tIf = tuple!();
	static if (cond) alias tIf = T;
	else
		alias tIf = tuple!();
}

template tForEach(alias func, args...)
{
	static if (args.length == 0)
		alias tForEach = tuple!();
	else
	{
		static assert(is(typeof(func(args[0]))), "tForEach: function 
not valid for argument : "~typeof(args[0]).stringof);
		alias tForEach = tuple!(func(args[0]), tIf!(args.length > 1, 
tForEach!(func, args[1..$]))); 	
	}
}

template tUnrollArgs(args...)
{
	static if (args.length > 0)
		pragma(msg, ">"~args.stringof~" : "~typeof(args[0]).stringof~" 
- "~Unqual!(typeof(args[0])).stringof);
	static if (args.length == 0)
	{
		alias tUnrollArgs = tuple!();
	}
	else static if (is(typeof(args[0]) == string) || 
is(Unqual!(typeof(args[0])) == string))
	{
		pragma(msg, "1: is string");
		static if (args.length == 1) alias tUnrollArgs =  
tuple!(args[0]); else alias tUnrollArgs = tuple!(args[0], 
tUnrollArgs!(args[1..$]));
	}
	else static if (isArray!(typeof(args[0])))
	{
		pragma(msg, "2: is array");
		static if (__traits(compiles, { enum x = args[0]; }))
		{
			static if (args[0].length == 0)
			{
				pragma(msg, "2: is empty");
				alias tUnrollArgs = tuple!(tUnrollArgs!(args[1..$]));
			}
			else
			static if (is(Unqual!(typeof(args[0])) == string))
			{
				pragma(msg, "4: is string");
				alias tUnrollArgs = tuple!(tUnrollArgs!(args[0]), 
tIf!(args.length > 1, tUnrollArgs!(args[1..$])));
			} else
			{
				pragma(msg, "5: unrolling array");
				alias tUnrollArgs = tuple!(tUnrollArgs!(args[0][0]), 
tIf!(args.length > 1, tUnrollArgs!(args[0][1..$], args[1..$])));
			}
		}
		else
		{
			static if(args.length > 1)
				alias tUnrollArgs = tuple!(args[0], tUnrollArgs!(args[1..$]));
			else
				alias tUnrollArgs = args[0];

		}
	}
	else
		alias tUnrollArgs = args;
}

template tUnrollArgs2(args...)
{
	alias tUnrollArgs2 = tForEach!((Unqual!(typeof(args[0])) x)
	{
		if (is(Unqual!(typeof(x)) == string))
		{
			return x~"<s>";
		} else
		if (isArray!(Unqual!(typeof(x))))
		{
			return x~"<a>";
		}
	}, args);

}
void main(string[] argv)
{
	immutable string[] z = ["111", "222"];
	auto x = ["3", "4"];
     //writeln(tUnrollArgs!("qXX", ["a", "bYY"], z, x,"cTT"));
	//writeln(
		//tForEach!((string x) => x ~ "#", tUnrollArgs2!("qXX", z, "a"))
		//);
		writeln(tUnrollArgs2!("a", z, "b"));
	readln();
}
Jul 27 2013