The rfind challenge

Phil Lavoie maidenphil at hotmail.com
Tue Jan 15 10:11:50 PST 2013


Ok, so to sum it up:
rfind should return the same type as provided.
Its direction (popFront()) should be the same.

auto rfing( Range, E )( Range r, E e ) if (blablabla) {
   auto original = r.save; //This is to remember the end of the 
orginal range.
   r.reverse; //Reverse it. The range keeps track of its direction.
   auto found = find( r, e ); //Now front() shall give us e, and 
popFront() moves toward original's beginning.
   auto res = Range.merge( found, original ); //Take the start of 
found, which is on e and take the end of original, which has not 
moved.
   //Where does popFront() goes now? Depends: either expect merge 
to decide for us or make sure its just dumb.
   //If it is dumb, then the assumption we make about the 
direction of the returned range is that popFront() goes in the 
not reversed direction (reversed returns false). Therefore, we 
have start on e and end where we want it, we only need to move in 
the proper direction, which is the one of the original.
   if( original.reversed ) { res.reverse; }
   return res;
}

struct DListRange {
   Node * _start;
   Node * _end; //Initialized to the lists'end.
   bool _reversed = false;

   bool empty() { return _start is null || _end is null; } //The 
user has seen it all.

   void popBack() {
     if( _reversed ) {
      _start = _start.next;
     } else {
      _end = _end.previous;
     }
   }

   ...

   @property bool reversed() { return _reversed; }
   void reverse() { _reversed = !_reversed; }

   //Dumb version.
   static typeof( this ) merge( typeof( this ) sr, typeof( this ) 
er ) {
    return typeof( this )( sr._start, er._end );
   }
}


More information about the Digitalmars-d mailing list