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