I understand that you've suggested a different approach. But you can already implement some kind of custom iterations. Just create a function that returns this.

class CustomDataClass
{
      public typeof(this) filter(Color col)
      {
             // ...
             return this;
      }

      void opApply(....) ...
}


auto datas = CustomDataClass();
foreach(u, i; datas.filter(Color.Red))
{
     // ...
}


----------------

Am 12.10.2011 09:55, schrieb Gor Gyolchanyan:
The foreach loop is truly a marvelous tool, which allows one to
implement custom iterations, which look and feel just like all other
kinds of iterations.
The only philosophical problem with it is, that it thinks that only
classes and structs can be looped over in a custom way and that they
can have only one way to be iterated over.
It would be great to be able to implement iterative algorithms for
arbitrary types (templated iterations), like strided iteration to
extract the red part of an image.
It would also be great to be able to have more, then one kind of
iteration for every type of iterable.
Here's the list of what I mean by that:
1. Allow passing parameters to iterables in foreach:
     foreach(c, i; MyType(), 3) { }
     the `3` would be passed to MyType's opApply right after the
delegate (of such an overload of opApply is available, of course).
2. Allow named foreach loops:
     foreach strided(c, i, MyType, 3) { }
     the `strided` is passed as a template parameter to the opApplly,
which (depending on what overloads of opApply are available) may be
optional.
3. Allow free-function opApply, which could be templated to work with
any kind of iterable in a specific way:
     int opApply(string name : "strided", Iterable)(Iterable iterable,
int delegate(ForeachParamsTuple!Iterable) dg, size_t stride) { /* ...
*/ }
     this function would allow you to add stride to any iterable. the
`ForeachParamsTuple` will return the tuple of parameters of the given
iterable type.
4. Allow foreach loops with a single iterator to be specified without
a body, in which case it would return an input range (or some other
type of range), lazily evaluating and returning the iterator.
     void printRange(Range)(Range range) { foreach(r, range) {  writeln(r); } };
     unittest { printRange(foreach(i; 0..100)); }
     This would vastly improve the usability and performance of
iterable types and ranges, since you no longer need to cache and copy
around the data and you don't need to wrap it around delegating
structs or classes either.
     The overloaded opApplies could be allowed to construct and return
those ranges themselves.
Yes, i know, you might have some questions like "but<this>  wouldn't
work with<that>." I thought it out pretty carefully and the details
are numerous, so I'd rather just answer those questions as they occur,
instead of listing them all here.

Given these four improvements iterations would become very easy and powerful.
The iterations would become very flexible and easily used with
range-based algorithms.

Reply via email to