On 01/15/2013 12:53 PM, FG wrote:
On 2013-01-15 06:51, Andrei Alexandrescu wrote:
If r is a forward range but not better, this is rather simple:

R rfind(R, E)(R range, E element)
{
     for (;;)
     {
         auto ahead = range.save.find(element);
         if (ahead.empty) return range;
         range = ahead;
     }
}

That example creates an infinite loop. Needs a popFront:

     R rfind(R, E)(R range, E element)
     {
         if (range.empty) return range;
         for (;;)
         {
             auto ahead = range.save;
             ahead.popFront();
             ahead = ahead.find(element);
             if (ahead.empty) return range;
             range = ahead;
         }
     }


That is buggy too.

Another thing: if the element is not found, I think an empty range
should be returned and not the whole range.

Yup.

R rfind(R, E)(R range,E element){
    auto r=range.find(element);
    if(r.empty) return r;
    for(;;){
        auto ahead=r.save;
        ahead.popFront();
        ahead=ahead.find(element);
        if(ahead.empty) return r;
        r=ahead;
    }
}


Full proof (assuming purity of the range primitives):

/+pure+/ R tail(R)(R r)out(result){
    assert(result=={
        auto a=r;
        a.popFront();
        return a;
    }());
}body{
    auto a=r;
    a.popFront();
    return a;
}

/+pure+/ R rfind(R, E)(R range,E element)out(result){
        
assert(range.find(element).empty&&result.empty||!range.find(element).empty&&!result.empty&&result.front==element&&result.tail.find(element).empty);
}body{
    auto r=range.find(element);
    assert(r==range.find(element)&&(r.empty||r.front==element));
    if(r.empty){
        assert(r==range.find(element)&&r.empty);
        return r;
        /+assert(result==range.find(element)&&result.empty);
        assert(range.find(element).empty&&result.empty);+/
    }
    assert(r==range.find(element)&&!r.empty&&r.front==element);
    assert(!range.find(element).empty&&!r.empty&&r.front==element);
    for(;;){

assert(true&&!range.find(element).empty&&!r.empty&&r.front==element);

assert(!range.find(element).empty&&!r.empty&&r.front==element&&!r.empty);
        auto ahead=r.save;

assert(!range.find(element).empty&&!r.empty&&r.front==element&&!ahead.empty&&ahead==r.save);
        ahead.popFront();

assert(!range.find(element).empty&&!r.empty&&r.front==element&&ahead=={
            auto ahead=r.save;
            ahead.popFront();
            return ahead;
        }());

assert(!range.find(element).empty&&!r.empty&&r.front==element&&ahead==r.tail);
        ahead=ahead.find(element);

assert(!range.find(element).empty&&!r.empty&&r.front==element&&(ahead.empty||ahead.front==element)&&ahead==r.tail.find(element));
        if(ahead.empty){

assert(!range.find(element).empty&&ahead.empty&&!r.empty&&r.front==element&&ahead==r.tail.find(element));
            return r;

/+assert(!range.find(element).empty&&ahead.empty&&!result.empty&&result.front==element&&ahead==result.tail.find(element));

assert(!range.find(element).empty&&!result.empty&&result.front==element&&result.tail.find(element).empty);+/
        }

assert(!range.find(element).empty&&!ahead.empty&&ahead.front==element);
        r=ahead;
        assert(!range.find(element).empty&&!r.empty&&r.front==element);
    }
    assert(false);
}



Reply via email to