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

Reply via email to