writing iterators without code duplication. inout?

pompei2 pompei2 at gmail.com
Wed Dec 21 07:54:06 PST 2011


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;
    }



More information about the Digitalmars-d-learn mailing list