<br><br><div class="gmail_quote">On Sat, Sep 4, 2010 at 01:40, Simen kjaeraas <span dir="ltr"><<a href="mailto:simen.kjaras@gmail.com">simen.kjaras@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div>Simen kjaeraas <<a href="mailto:simen.kjaras@gmail.com" target="_blank">simen.kjaras@gmail.com</a>> wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
I believe this will only work with arrays as input. Either that, or I need<br>
a way to make this work:<br>
<br>
struct Foo( R ) if ( isForwardRange!R ) {<br>
bool delegate( ElementType!R ) bar;<br>
Filter!( bar, R ) range;<br>
}<br>
<br>
Or, well, something like it. I need a static type for a Filter that<br>
delegates to a struct member, in this case bar.<br>
</blockquote>
</div></blockquote><div><br>Maybe with a dynamic filter?<br><br>struct DynamicFilter(R) if (isInputRange!R)<br>{<br> R range;<br> bool delegate(ElementType!R) predicate;<br> bool set;<br> this(R _range) { range = _range; }<br>
this(R _range, bool delegate(ElementType!R) _predicate) { range = _range; predicate = _predicate; set = true; popFront(); }<br> void setPredicate(bool delegate(ElementType!R) _predicate) { predicate = _predicate; set = true; popFront();}<br>
<br> ElementType!R front() { if (set) { return range.front();} else { throw new Exception("Calling DynamicFilter with an unset predicate.");};}<br> bool empty() { if (set) {return range.empty;} else { throw new Exception("Calling DynamicFilter with an unset predicate.");};}<br>
void popFront()<br> {<br> if (set)<br> {<br> while( !range.empty && !predicate(range.front))<br> {<br> range.popFront();<br> }<br> }<br> else<br>
{<br> throw new Exception("Calling DynamicFilter with an unset predicate.");<br> }<br> }<br>}<br><br>//DynamicFilter!(R) dynamicFilter(R)(R range)<br>//{<br>// return DynamicFilter!R(range);<br>
//}<br><br>DynamicFilter!(R) dynamicFilter(R,E)(R range, bool delegate(E) pred = null) if ((isInputRange!R) && is(ElementType!R == E))<br>{<br> if (pred is null)<br> return DynamicFilter!(R)(range);<br> else<br>
return DynamicFilter!R(range, pred);<br>}<br><br>void main()<br>{<br> auto f = dynamicFilter([0,1,2,3], (int i) { return i%2 == 0;});<br> writeln(f.front); // 0<br> f.setPredicate((int i) { return i%2 == 1;});<br>
writeln(f.front); // 1<br>}<br><br><br>Note that in this version, the filtered range always advances. When you change filter, it continues to consume elements from the current point. For backtracking, maybe you need a forward range input, a saved version of this input, and have setPredicate rewind the inner range to the saved version.<br>
<br><br>Philippe<br></div></div>