Build all combinations of strings

bearophile via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jan 11 10:01:08 PST 2015


Nordlöw:

> Is doCopy really needed as an argument here?
>
> Couldn't this be inferred from the mutability of T instead?

doCopy is useful, if it's true all the permutation arrays are 
distinct and dup-ped, otherwise they are all different. It's true 
by default, so casual users of that generator will avoid bugs. 
You can set it to false to speed up your code.


Later I have refined the idea, you can see it here, that allows 
true @nogc code when needed:

struct CartesianPower(bool doCopy=true, T) {
     T[] items;
     uint repeat;
     T[] row;
     uint i, maxN;

     this(T[] items_, in uint repeat_, T[] buffer) pure nothrow 
@safe @nogc {
         this.items = items_;
         this.repeat = repeat_;
         row = buffer[0 .. repeat];
         row[] = items[0];
         maxN = items.length ^^ repeat;
     }

     static if (doCopy) {
         @property T[] front() pure nothrow @safe @nogc {
             return row.dup;
         }
     } else {
         @property T[] front() pure nothrow @safe @nogc {
             return row;
         }
     }

     @property bool empty() pure nothrow @safe @nogc {
         return i >= maxN;
     }

     void popFront() pure nothrow @safe @nogc {
         i++;
         if (empty)
             return;
         uint n = i;
         size_t count = repeat - 1;
         while (n) {
             row[count] = items[n % items.length];
             count--;
             n /= items.length;
         }
     }
}

auto cartesianPower(bool doCopy=true, T)(T[] items, in uint 
repeat)
pure nothrow @safe {
     return CartesianPower!(doCopy, T)(items, repeat, new 
T[repeat]);
}

auto cartesianPower(bool doCopy=true, T)(T[] items, in uint 
repeat, T[] buffer)
pure nothrow @safe @nogc {
     if (buffer.length >= repeat) {
         return CartesianPower!(doCopy, T)(items, repeat, buffer);
     } else {
         // Is this correct in presence of chaining?
         static immutable err = new Error("buffer.length < 
repeat");
         throw err;
     }
}

void main() @nogc {
     import core.stdc.stdio;
     int[3] items = [10, 20, 30];
     int[4] buf;
     foreach (p; cartesianPower!false(items, 4, buf))
         printf("(%d, %d, %d, %d)\n", p[0], p[1], p[2], p[3]);
}


Bye,
bearophile


More information about the Digitalmars-d-learn mailing list