The rfind challenge

Phil Lavoie maidenphil at hotmail.com
Tue Jan 15 09:24:41 PST 2013


On Tuesday, 15 January 2013 at 17:14:32 UTC, Andrei Alexandrescu 
wrote:
> On 1/15/13 12:03 PM, Phil Lavoie wrote:
>> Pseudo:
>> original = range.save
>> resPos = range.retro.find
>> return Range.merge( resPos, original ) //DOES NOT WORK
>>
>> The problem with this solution is that:
>> Retro returns a different range type and it would be more 
>> complicated to
>> have the merge function work with this type.
>
> This would be difficult to implement safely, which is an 
> important disadvantage.
>
>> An addition to this solution could be another new primitive: 
>> reverse:
>>
>> Pseudo:
>> original = range.save
>> reversed = range.reverse //Permanently invert start an end. I 
>> think this
>> is feasible for all bidirectional ranges. Still a 
>> bidirectional range.
>> reversed.find( needle ) //In haystack :)
>> return Range.merge( reversed, original ) //Ok, start of 
>> reversed is on
>> needle and end of original hasn't moved. The order of the 
>> range returned
>> is the same as the one received.
>>
>> This is just a suggestion and any primitive could be renamed. 
>> However, I
>> think reverse is a good place to start.
>
> Reverse is really cool and immediate to implement safely for a 
> lot of ranges I can think of. How would you define rfind 
> assuming reverse?
>
>
> Andrei

Ok then, imagine we use @reverse, @reversed and @merge primitives:

auto rfind( Range, E )( Range r , E e ) if( blablabla... ) {
   auto original = r.save;
   auto reversed = r.reverse;
   auto found = find( reversed, e );
   auto res = Range.merge( found, original );
   return original.reversed ? res : res.reverse;
}

And correcting what I said previously:

void reverse() {
  _reversed = !reversed;
}


More information about the Digitalmars-d mailing list