Can we get rid of opApply?

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Tue Jan 20 06:42:35 PST 2009


Denis Koroskin wrote:
> One nice thing that opApply capable of is it can avoid heap activity by 
> stack-allocating data during iteration.
> 
> For example, given an array of ints, iterate over string representations 
> of them:
> 
> struct IntegersAsString
> {
>    void opAplly(int delegate(string s) dg)
>    {
>        char[16] temp;
> 
>        foreach (i; array) {
>            int len = sprintf(temp, "%d", i);
>            int result = dg(temp[0..len]);
>            if (result != 0) {
>                return result;
>            }
>        }
> 
>        return 0;
>    }
> 
>    private int[] array;
> }
> 
> int array = [1, 1, 2, 3, 5, 8, 13];
> 
> // no heap allocation take place
> foreach (string s; IntegersAsString(array)) {
>    writeln(s);
> }
> 
> How would you do that with ranges?

Note that at some point you need to do a cast somewhere because you 
operate on mutable chars yet the delegate takes a string.

The range solution is very similar and just as simple. The only care 
must be taken to not fill the buffer unnecessarily as head() may be 
accessed a number of times before next().

struct IntegersAsString
{
private:
     size_t i;
     char[16] buffer;
     int[] array;
public:
     void next() { ++i; buffer[0] = 0; }
     bool empty() { return i >= array.length; }
     const(char)[] head()
     {
         if (buffer[0] == 0)
         {
             sprintf(buffer, "%d", array[i]);
         }
         return buffer;
     }
}


Andrei



More information about the Digitalmars-d mailing list