Build all combinations of strings

"Nordlöw" via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jan 11 12:33:02 PST 2015


On Sunday, 11 January 2015 at 18:01:09 UTC, bearophile wrote:
> 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

Nice! PR anyone?


More information about the Digitalmars-d-learn mailing list