Proposal: takeFront and takeBack

monarch_dodra monarch_dodra at gmail.com
Thu Jul 5 02:57:54 PDT 2012


On Wednesday, 4 July 2012 at 22:08:18 UTC, Jonathan M Davis wrote:
> C++'s iterators definitely do _not_ return an element when you 
> increment them.
>
> - Jonathan M Davis

Just a thought, but C++'s input iterator very often do increment 
when being _dereferenced_, and then they make the _increment_ 
operator a no-op.

So technically, while they do not return a value when you  
increment/popFront(), they do exactly the contrary: they 
increment/popFront() when you dereference/front()

----
Maybe instead of trying to write a "consumeFront" function, it 
would be easier/more manageable to enforce this semantic on input 
ranges?

for example:
----
import std.utf;
import std.range;
import std.stdio;
import std.algorithm;

struct stringAsInputRange
{
   dchar front()
   {
     size_t index = 0;
     dchar c = decode(m_data, index);
     m_data = m_data[index .. $];
     return c;
   }
   void popFront() {}
   typeof(this) Save(){return this;}
   bool empty() {return m_data.empty;}

private: string m_data;
}

void main()
{
   string s = "héllö";
   stringAsInputRange sir = stringAsInputRange(s);
   foreach(c; sir)
     writeln(c);
   writeln(std.algorithm.count(sir, 'l'));
}
----
Voilà! As you can see, I just exploited efficient traversal of a 
utf8 string, both with foreach and an algorithm, without them 
being none the wiser ;)

The "sweet" part is that in theory, this can work with any 
algorithm that is compatible with input ranges, and does not 
mutate their data: The bulk of the algorithms that could use 
consumeFront anyways...

Such algorithms that operate on input ranges *should* never call 
front more than once per loop anyways.

----
For those few algorithms that work on bidirRange, we'd need a 
garantee that they don't ever front/back the same item twice. We 
*could* achieve this by defining a bidirectionalInputRange class 
of range.

inputRange    ->  *bidirectionalInputRange*
     |                      |
     v                      v
ForwardRange  ->  bidirectionalRange

But this would be more work, just to get those last few cases... 
And I'm not sure this "diamond" classification isn't dangerous 
somehow...



More information about the Digitalmars-d mailing list