writing iterators without code duplication. inout?

Timon Gehr timon.gehr at gmx.ch
Wed Dec 21 08:07:54 PST 2011


On 12/21/2011 04:54 PM, pompei2 wrote:
> Hello.
>
> I want to add the option to iterate objects of my class using foreach. I
> need them to be iterable as view-only const and as mutable too. I would
> prefer to iterate using the "return a delegate" but if that's not
> possible, ranges are fine too. Also, I'd prefer a template-less solution
> over a templated one.
>
>
> This is what I have, which works but has severe code duplication. I
> hoped inout would help me here, but I just can't figure it out. I also
> gave a try to ranges, but same thing again: I can only get it to work if
> I define my things twice.
>
> (syntax highlight for the coming month: http://pastebin.com/TNmWWgsj)
>
>
> import std.conv, std.stdio;
>
> class Container
> {
> this(int from, int to)
> {
> while(from <= to) {
> _arr ~= from;
> from++;
> }
> }
>
> // FIXME: severe code duplication for const/nonconst/ref
> // and I'm not even trying immutable yet
> int delegate(int delegate(ref int)) doIter()
> {
> writeln("calling non-const");
>
> int doTheIter(int delegate(ref int) dg)
> {
> int result = 0;
> foreach(ref i ; this._arr) {
> result = dg(i);
> if(result)
> break;
> }
> return result;
> }
>
> return &doTheIter;
> }
>
> int delegate(int delegate(ref int)) doIter() const
> {
> writeln("calling const");
>
> int doTheIter(int delegate(ref int) dg)
> {
> int result = 0;
> foreach(i ; this._arr) {
> result = dg(i);
> if(result)
> break;
> }
> return result;
> }
>
> return &doTheIter;
> }
>
> int[] _arr;
> }
>
> int main(string[] args)
> {
> Container c = new Container(1, 9);
> const Container cc = c;
>
> foreach(ref e ; c.doIter()) {
> writeln(e);
> e++;
> }
>
> foreach(e ; cc.doIter()) {
> writeln(e);
> }
>
> return 0;
> }
>

Just remove the non-const overload. const member functions work with 
mutable, immutable and const receivers.


More information about the Digitalmars-d-learn mailing list