Skip to content

std.bitmanip.peek does not work with ranges with slicing #11027

@jmdavis

Description

@jmdavis
void main()
{
    import std.bitmanip;
    import std.range.primitives;

    static struct Range
    {
        @property bool empty() @safe const { return _arr.empty; }
        @property ubyte front() @safe const { return _arr[0]; }
        void popFront() @safe { _arr = _arr[1 .. $]; }
        auto save() @safe { return this; }
        @property size_t length() @safe const { return _arr.length; }
        auto opSlice(size_t i, size_t j) @safe { return Range(_arr[i .. j]); }
        this(ubyte[] arr) @safe { _arr = arr; }
        ubyte[] _arr;
    }
    static assert(isForwardRange!Range);
    static assert(!isRandomAccessRange!Range);
    static assert(hasSlicing!Range);

    auto range = Range([1, 5, 22, 9, 44, 255, 8]);
    assert(range.peek!ushort() == 261);

    size_t index;
    assert(range.peek!ushort(&index) == 261);
    assert(index == 2);
}

fails with

/usr/local/include/dmd/std/bitmanip.d(3378): Error: cannot implicitly convert expression `range.opSlice(0LU, 2LU)` of type `Range` to `const(ubyte)[]`
        const ubyte[T.sizeof] bytes = range[0 .. T.sizeof];
                                           ^
test2.d(22): Error: template instance `std.bitmanip.peek!(ushort, Endian.bigEndian, Range)` error instantiating
    assert(range.peek!ushort() == 261);
                            ^
/usr/local/include/dmd/std/bitmanip.d(3419): Error: cannot implicitly convert expression `range.opSlice(begin, end)` of type `Range` to `const(ubyte)[]`
    const ubyte[T.sizeof] bytes = range[begin .. end];
                                       ^
test2.d(25): Error: template instance `std.bitmanip.peek!(ushort, Endian.bigEndian, Range)` error instantiating
    assert(range.peek!ushort(&index) == 261);

Basically, the two overloads of peek assume that if the range has slicing, a slice of the range can be assigned to a static array of ubyte, which isn't possible. And the tests largely don't actually test the code with ranges, just arrays (my fault, since I wrote them many moons ago). :|

read doesn't have this issue only because it was previously caught and fixed, but the issue with peek was not caught and fixed at the same time: https://issues.dlang.org/show_bug.cgi?id=17247

Metadata

Metadata

Assignees

No one assigned

    Labels

    Phobos 2Issues and PR's specific to Phobos 2.

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions