How to implement a range?

Jack jckj33 at gmail.com
Fri Apr 16 06:21:35 UTC 2021


In order to my array class work with filter, I went to implement 
an ``InputRange``. But I don't quite get how do that and didn't 
find much help on the docs. From below code, is ``moveFront()`` 
implemented correctly? I'm using a simple int i as index of 
current item and in popFront() just increment it. I must reset 
the i value once the loop is done, right? where am I supposed to 
do that? opApply()? not properly reseting it result in obvious 
bugs like subsequent calls doesn't work because the index is in 
the end of the array:

```d
auto arr = new MyArray!int;
arr.Add(1);
arr.Add(2);
arr.Add(3);
arr.Add(4);
auto r = arr.filter!(n => (n % 2) == 0);
auto r2 = arr.filter!(n => n >= 2);
writeln(r); // ok
writeln(r2); // empty
```

yeah, i'm a bit confused... here's the code:

```d
class MyArray(T) : InputRange!T
{
     private T[] arr;
     private int i = 0;

     void Add(T item)
     {
         arr ~= item;
     }

     void Add(T[] items)
     {
         foreach(item; items)
         {
             Add(item);
         }
     }

     size_t length() nothrow
     {
         return arr.length;
     }

     bool empty()
     {
     	return i == length;
     }

     T front()
     {
     	return arr[i];
     }

     void popFront()
     {
     	i++;
     }

     T moveFront()
     {
     	auto r = front;
     	popFront();
     	return r;
     }

     int opApply(scope int delegate(ref T) dg)
     {
         int result = 0;

         foreach (item; arr)
         {
             result = dg(item);
             if (result) {
                 break;
             }
         }

         return result;
     }

     int opApply(scope int delegate(T) dg)
     {
         int result = 0;

         foreach (item; arr)
         {
             result = dg(item);
             if (result) {
                 break;
             }
         }

         return result;
     }

     int opApply(scope int delegate(uint, T) dg)
     {
         int result = 0;
     	
         foreach (j, item; arr)
         {
             result = dg(j, item);
             if (result) {
                 break;
             }
         }

         return result;
     }
}
```


More information about the Digitalmars-d-learn mailing list