[Challenge] implementing the ambiguous operator in D

Philippe Sigaud philippe.sigaud at gmail.com
Fri Sep 3 23:58:18 PDT 2010


On Sat, Sep 4, 2010 at 01:40, Simen kjaeraas <simen.kjaras at gmail.com> wrote:

> Simen kjaeraas <simen.kjaras at gmail.com> wrote:
>
>  I believe this will only work with arrays as input. Either that, or I need
>> a way to make this work:
>>
>> struct Foo( R ) if ( isForwardRange!R ) {
>>     bool delegate( ElementType!R ) bar;
>>     Filter!( bar, R ) range;
>> }
>>
>> Or, well, something like it. I need a static type for a Filter that
>> delegates to a struct member, in this case bar.
>>
>
Maybe with a dynamic filter?

struct DynamicFilter(R) if (isInputRange!R)
{
    R range;
    bool delegate(ElementType!R) predicate;
    bool set;
    this(R _range) { range = _range; }
    this(R _range, bool delegate(ElementType!R) _predicate) { range =
_range; predicate = _predicate; set = true; popFront(); }
    void setPredicate(bool delegate(ElementType!R) _predicate) { predicate =
_predicate; set = true; popFront();}

    ElementType!R front() { if (set) { return range.front();} else { throw
new Exception("Calling DynamicFilter with an unset predicate.");};}
    bool empty() { if (set) {return range.empty;} else { throw new
Exception("Calling DynamicFilter with an unset predicate.");};}
    void popFront()
    {
        if (set)
        {
            while( !range.empty && !predicate(range.front))
            {
                range.popFront();
            }
        }
        else
        {
            throw new Exception("Calling DynamicFilter with an unset
predicate.");
        }
    }
}

//DynamicFilter!(R) dynamicFilter(R)(R range)
//{
//    return DynamicFilter!R(range);
//}

DynamicFilter!(R) dynamicFilter(R,E)(R range, bool delegate(E) pred = null)
if ((isInputRange!R) && is(ElementType!R == E))
{
    if (pred is null)
        return DynamicFilter!(R)(range);
    else
        return DynamicFilter!R(range, pred);
}

void main()
{
    auto f = dynamicFilter([0,1,2,3], (int i) { return i%2 == 0;});
    writeln(f.front); // 0
    f.setPredicate((int i) { return i%2 == 1;});
    writeln(f.front); // 1
}


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.


Philippe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20100904/c789161d/attachment.html>


More information about the Digitalmars-d mailing list