chunks equivalent with unpacking?

Andrej Mitrovic andrej.mitrovich at gmail.com
Wed Jul 31 12:49:58 PDT 2013


On 7/31/13, Andrej Mitrovic <andrej.mitrovich at gmail.com> wrote:
> On 7/31/13, bearophile <bearophileHUGS at lycos.com> wrote:
>> How nice. Have we just won another bug report?
>
> It's not the only one either, my opApply version works ok alone, but
> when put into another module with package imports it fails to compile,
> which is yet another new regression.. It's frustrating having to hit
> so many regressions lately.

Btw my version with opApply: codepad.org/yojenuZl

Pasted here for convenience:

-----
module test;

import std.array;
import std.range;
import std.stdio;
import std.string;

/** Implements chunks iteration through an input range. */
struct Pack(Range, size_t count)
    if (isInputRange!Range)
{
    this(Range range)
    {
        this.range = range;
    }

    alias Item = ElementType!Range;

    mixin genPackOpApply!count;

private:
    Range range;
}

/**
    Return a struct instance that wraps an
    input range and provides iteration through
    $(D count) chunks at a time.
*/
auto pack(size_t count, Range)(Range range)
    if (isInputRange!Range)
{
    return Pack!(Range, count)(range);
}

///
unittest
{
    int[] arr = [
         0, 1, 2, 3,
         4, 5, 6, 7
    ];

    size_t index;
    foreach (x, y, z, w; arr.pack!4)
    {
        if (index++ == 0)
            assert(x == 0);
        else
            assert(x == 4);
    }

    foreach (idx, x, y, z, w; arr.pack!4)
    {
        if (idx == 0)
            assert(x == 0);
        else
            assert(x == 4);
    }

    foreach (idx, ref x, y, z, w; arr.pack!4)
    {
        if (idx == 0)
            x = 1;
    }

    assert(arr[0] == 1 && arr[4] == 4);
}

private mixin template genPackOpApply(size_t count)
{
    mixin(genPackOpApplyImpl(count));
}

private string genPackOpApplyImpl(size_t count)
{
    string[] items;
    foreach (i; 0 .. count)
        items ~= "items[%s]".format(i);

    string opApply1 = q{
        /// foreach without index
        int opApply(int delegate(%s) dg)
        {
            int result = 0;

            foreach (items; std.range.chunks(range, %s))
            {
                result = dg(%s);
                if (result)
                    break;
            }

            return result;
        }
    }.format(std.array.replicate(["ref Item"], count).join(", "),
count, items.join(", "));

    string opApply2 = q{
        /// foreach with index
        int opApply(int delegate(size_t index, %s) dg)
        {
            int result = 0;

            size_t index;
            foreach (items; std.range.chunks(range, %s))
            {
                result = dg(index++, %s);
                if (result)
                    break;
            }

            return result;
        }
    }.format(std.array.replicate(["ref Item"], count).join(", "),
count, items.join(", "));

    return format("%s\n%s", opApply1, opApply2);
}

void main()
{
}
-----


More information about the Digitalmars-d-learn mailing list