<br><br><div class="gmail_quote">On Sat, Sep 4, 2010 at 01:40, Simen kjaeraas <span dir="ltr">&lt;<a href="mailto:simen.kjaras@gmail.com">simen.kjaras@gmail.com</a>&gt;</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 &lt;<a href="mailto:simen.kjaras@gmail.com" target="_blank">simen.kjaras@gmail.com</a>&gt; 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(&quot;Calling DynamicFilter with an unset predicate.&quot;);};}<br>    bool empty() { if (set) {return range.empty;} else { throw new Exception(&quot;Calling DynamicFilter with an unset predicate.&quot;);};}<br>
    void popFront()<br>    {<br>        if (set)<br>        {<br>            while( !range.empty &amp;&amp; !predicate(range.front))<br>            {<br>                range.popFront();<br>            }<br>        }<br>        else<br>
        {<br>            throw new Exception(&quot;Calling DynamicFilter with an unset predicate.&quot;);<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) &amp;&amp; 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>