March 26, 2016
On Friday, 25 March 2016 at 08:01:04 UTC, cym13 wrote:
>         // This consume
>         auto buffer3 = range.take(4).array;
>         assert(buffer3 == [0, 5, 10, 15]);
>     }

Thanks for your help. However the last statement is incorrect. I am in fact looking for a version of 'take' that consumes the InputRange.

You can see it by doing a second take afterwards.

    auto buffer3 = range.take(4).array;
    assert(buffer3 == [0, 5, 10, 15]);
    auto buffer4 = range.take(4).array;
    assert(buffer4 == [0, 5, 10, 15]);

I haven't clearly explained my main goal. I have a large binary file that I need to deserialize. It's not my file and it's in a custom but simple format, so I would prefer not to depend on a third party serializer library but I will look into that.

I was thinking around the lines of:
1. Open file
2. Map a byChunk.joiner to read by chunks and present an iterator interface
3. Read data with std.bitmanip/read functions

Step 3. works fine as long as items are single scalar values. bitmanip doesn't have array readers. Obviously, I could loop but then I thought that for the case of a ubyte[], there would be a shortcut that I don't know about.

Thanks,
--h

March 26, 2016
On Saturday, 26 March 2016 at 02:28:53 UTC, Hanh wrote:
> On Friday, 25 March 2016 at 08:01:04 UTC, cym13 wrote:
>>         // This consume
>>         auto buffer3 = range.take(4).array;
>>         assert(buffer3 == [0, 5, 10, 15]);
>>     }
>
> Thanks for your help. However the last statement is incorrect. I am in fact looking for a version of 'take' that consumes the InputRange.
>
> You can see it by doing a second take afterwards.
>
>     auto buffer3 = range.take(4).array;
>     assert(buffer3 == [0, 5, 10, 15]);
>     auto buffer4 = range.take(4).array;
>     assert(buffer4 == [0, 5, 10, 15]);
>
> I haven't clearly explained my main goal. I have a large binary file that I need to deserialize. It's not my file and it's in a custom but simple format, so I would prefer not to depend on a third party serializer library but I will look into that.
>
> I was thinking around the lines of:
> 1. Open file
> 2. Map a byChunk.joiner to read by chunks and present an iterator interface
> 3. Read data with std.bitmanip/read functions
>
> Step 3. works fine as long as items are single scalar values. bitmanip doesn't have array readers. Obviously, I could loop but then I thought that for the case of a ubyte[], there would be a shortcut that I don't know about.
>
> Thanks,
> --h

Sorry, it seems I completely misunderstood you goal. I thought that take() consumed its input (which mostly only shows that I really am careful about not reusing ranges). Writting a take that consume shouldn't be difficult though:

    import std.range, std.traits;
    Take!R takeConsume(R)(auto ref R input, size_t n)
        if (isInputRange!(Unqual!R)
        && !isInfinite!(Unqual!R)
    {
        auto buffer = input.take(n);
        input = input.drop(buffer.walkLength);
        return buffer;
    }

but I think going with std.bitmanip/read may be the easiest in the end.

March 26, 2016
On Saturday, 26 March 2016 at 08:34:04 UTC, cym13 wrote:

> Sorry, it seems I completely misunderstood you goal. I thought that take() consumed its input (which mostly only shows that I really am careful about not reusing ranges). Writting a take that consume shouldn't be difficult though:
>
>     import std.range, std.traits;
>     Take!R takeConsume(R)(auto ref R input, size_t n)
>         if (isInputRange!(Unqual!R)
>         && !isInfinite!(Unqual!R)
>     {
>         auto buffer = input.take(n);
>         input = input.drop(buffer.walkLength);
>         return buffer;
>     }
>
> but I think going with std.bitmanip/read may be the easiest in the end.

Turns out bitmanip is actually using a loop.

foreach(ref e; bytes)
{
  e = range.front;
  range.popFront();
}

By the way, in your code above you are actually reusing the range: take is followed by drop and it won't work on an input range like 'byChunk'. That's the problem I ran into (see first post).

1 2
Next ›   Last »