www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static foreach and inline if

reply "JS" <js.mdnq gmail.com> writes:
I'd like to have foreach and inline if in templates:


The tIf doesn't work properly but I'm not sure why


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

template tIf(bool cond) { alias tIf = tuple!(); }
template tIf(bool cond, alias T)
{
	static if (cond) alias tIF = T; else alias tIF = tuple!();
}

template tForEach(alias func, args...)
{
	pragma(msg, 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);
		pragma(msg, "1"~typeof(args[0]).stringof);
		alias tForEach = tuple!(func(args[0]), tIf!(args.length > 1, 
tForEach!(func, args[1..$])));
	}
}


e.g.,

writeln(tForEach((string x) => x ~ ";", "a", "b"));

should print a;b;
Jul 27 2013
next sibling parent reply "JS" <js.mdnq gmail.com> writes:
BTW, it works with static if's, I'm trying to use an inline if to 
reduce redundant code.... since there is no static ?:.
Jul 27 2013
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Saturday, 27 July 2013 at 17:15:54 UTC, JS wrote:
 BTW, it works with static if's, I'm trying to use an inline if 
 to reduce redundant code.... since there is no static ?:.
I don't really understand, since you didn't really explain *what* you were trying to do before pasting that code, but for what it's worth, there *is* static foreach is supported in D, via typetuples. Once you are inside a static you can evaluate the arg statically. import std.typetuple, std.stdio; void main() { foreach(I; TypeTuple!(0, 1, 2)) { static if (I == 1) writeln(I); } } As you can see, this compiles, meaning the if is evaluated at compile time. Does this help you? I'm currently working on a static Iota. Details here: http://d.puremagic.com/issues/show_bug.cgi?id=4085
Jul 27 2013
prev sibling next sibling parent reply "anonymous" <anonymous example.com> writes:
On Saturday, 27 July 2013 at 17:14:35 UTC, JS wrote:
 The tIf doesn't work properly but I'm not sure why
[...]
 template tIf(bool cond, alias T)
Lower case 'f' here, ...
 {
 	static if (cond) alias tIF = T; else alias tIF = tuple!();
... upper case 'F's here.
Jul 27 2013
parent "JS" <js.mdnq gmail.com> writes:
On Saturday, 27 July 2013 at 19:06:48 UTC, anonymous wrote:
 On Saturday, 27 July 2013 at 17:14:35 UTC, JS wrote:
 The tIf doesn't work properly but I'm not sure why
[...]
 template tIf(bool cond, alias T)
Lower case 'f' here, ...
 {
 	static if (cond) alias tIF = T; else alias tIF = tuple!();
... upper case 'F's here.
Thanks... I'm glad someone can see the tree's from the forest. (I originally was going to use all caps but changed it at the last minute.
Jul 27 2013
prev sibling parent reply "QAston" <qaston gmail.com> writes:
On Saturday, 27 July 2013 at 17:14:35 UTC, JS wrote:
 I'd like to have foreach and inline if in templates:
inline if is available as std.traits.Select
Jul 28 2013
parent reply "JS" <js.mdnq gmail.com> writes:
On Sunday, 28 July 2013 at 08:30:17 UTC, QAston wrote:
 On Saturday, 27 July 2013 at 17:14:35 UTC, JS wrote:
 I'd like to have foreach and inline if in templates:
inline if is available as std.traits.Select
This doesn't work for variadic args... Something Split!(Cond, targ..., split, fargs) is what I need... where split somehow signals the split between the two.
Jul 28 2013
parent reply "JS" <js.mdnq gmail.com> writes:
On Sunday, 28 July 2013 at 08:38:01 UTC, JS wrote:
 On Sunday, 28 July 2013 at 08:30:17 UTC, QAston wrote:
 On Saturday, 27 July 2013 at 17:14:35 UTC, JS wrote:
 I'd like to have foreach and inline if in templates:
inline if is available as std.traits.Select
This doesn't work for variadic args... Something Split!(Cond, targ..., split, fargs) is what I need... where split somehow signals the split between the two.
Obviously I mean Select!
Jul 28 2013
next sibling parent "JS" <js.mdnq gmail.com> writes:
The following works but is somewhat of a hack...

module main;

import std.stdio, std.typetuple;

struct tTupleSplit
{

}

template tIndexOf(T, args...)
{
	static if (staticIndexOf!(T, args) < 0) enum tIndexOf = 
args.length;
	else enum tIndexOf = staticIndexOf!(T, args);
}
template tMin(alias a, alias b)
{
	static if (a < b) alias tMin = a; else alias tMin = b;
}
template tIf(alias cond, args...)
{
	enum sp = tIndexOf!(tTupleSplit, args);
     static if (cond)
	    alias tIf = args[0..tMin!($,sp)];
	else
		alias tIf = args[tMin!($,sp+1)..$];
}

int main(string[] argv)
{

	alias x = tIf!(false, "a", tTupleSplit, "b");
    writeln(x);
    readln();
    return 0;
}
Jul 28 2013
prev sibling parent reply "anonymous" <anonymous example.com> writes:
On Sunday, 28 July 2013 at 08:38:40 UTC, JS wrote:
 On Sunday, 28 July 2013 at 08:38:01 UTC, JS wrote:
 On Sunday, 28 July 2013 at 08:30:17 UTC, QAston wrote:
 On Saturday, 27 July 2013 at 17:14:35 UTC, JS wrote:
 I'd like to have foreach and inline if in templates:
inline if is available as std.traits.Select
This doesn't work for variadic args... Something Split!(Cond, targ..., split, fargs) is what I need... where split somehow signals the split between the two.
Obviously I mean Select!
template Wrap(Stuff ...) {alias unwrap = Stuff;} Select!(cond, Wrap!targs, Wrap!fargs).unwrap
Jul 28 2013
parent reply "JS" <js.mdnq gmail.com> writes:
On Sunday, 28 July 2013 at 09:11:55 UTC, anonymous wrote:
 On Sunday, 28 July 2013 at 08:38:40 UTC, JS wrote:
 On Sunday, 28 July 2013 at 08:38:01 UTC, JS wrote:
 On Sunday, 28 July 2013 at 08:30:17 UTC, QAston wrote:
 On Saturday, 27 July 2013 at 17:14:35 UTC, JS wrote:
 I'd like to have foreach and inline if in templates:
inline if is available as std.traits.Select
This doesn't work for variadic args... Something Split!(Cond, targ..., split, fargs) is what I need... where split somehow signals the split between the two.
Obviously I mean Select!
template Wrap(Stuff ...) {alias unwrap = Stuff;} Select!(cond, Wrap!targs, Wrap!fargs).unwrap
I tried to do that with tuple which is identical to your wrap but was not successful... possibly because I did not unwrap it...
Jul 28 2013
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Sunday, 28 July 2013 at 15:33:48 UTC, JS wrote:
 I tried to do that with tuple which is identical to your wrap 
 but was not successful... possibly because I did not unwrap 
 it...
It should work. You can expand the *types* with Types, and the *values* with expand.
Jul 28 2013
prev sibling parent "anonymous" <anonymous example.com> writes:
On Sunday, 28 July 2013 at 15:33:48 UTC, JS wrote:
 On Sunday, 28 July 2013 at 09:11:55 UTC, anonymous wrote:
 On Sunday, 28 July 2013 at 08:38:40 UTC, JS wrote:
[...]
 template Wrap(Stuff ...) {alias unwrap = Stuff;}
 Select!(cond, Wrap!targs, Wrap!fargs).unwrap
I tried to do that with tuple which is identical to your wrap but was not successful... possibly because I did not unwrap it...
If you're refering to that implementation of tuple: On Saturday, 27 July 2013 at 17:14:35 UTC, JS wrote:
 template tuple(args...) { alias tuple = args; }
That's not exactly the same. It really must not be an eponymous template.
Jul 28 2013