www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19644] New: std.range.takeOne opSlice asserts incorrectly

https://issues.dlang.org/show_bug.cgi?id=19644

          Issue ID: 19644
           Summary: std.range.takeOne opSlice asserts incorrectly when
                    operating on non-forward input range
           Product: D
           Version: D2
          Hardware: x86
                OS: Mac OS X
            Status: NEW
          Severity: normal
          Priority: P1
         Component: phobos
          Assignee: nobody puremagic.com
          Reporter: jrdemail2000-dlang yahoo.com

std.range.takeOne supports slicing. The valid slice is [0..1]. However, the
implementation for non-forward input ranges incorrectly asserts on this call.
This is due incorrectly checking for the second argument being less-than
length. The test should be less-than-equal.

A PR is in progress.

--- Test program (test.d) ---

import std.range;
import std.stdio;

struct ValInputRange(R)
{
    R data;
    this(R _data) pure  safe nothrow { data = _data; }
     property bool empty() pure  safe nothrow { return data.empty; }
     property auto front() pure  safe nothrow { assert(!empty); return
data.front; }
    void popFront() pure  safe nothrow { assert(!empty); data.popFront(); }
}

auto valInputRange(R)(R range) { return ValInputRange!R(range); }

void main(string[] args)
{
    auto a = [1, 2, 3, 4, 5];
    auto r1 = a.takeOne;

    auto q1 = r1[0..1];   // Works fine.
    writeln(q1);

    auto r2 = a.valInputRange.takeOne;
    auto q2 = r2[0..1];   // Asserts here.
    writeln(q2);
}
----------------------------

Run:

$ dmd --version
DMD64 D Compiler v2.084.0

$ dmd test.d

$ ./test
[1]
core.exception.AssertError /INSTALLDIR/osx/bin/../../src/phobos/std/range/package.d(2658):
Attempting to index a takeOne out of bounds
----------------
??:? _d_assert_msg [0x2db17d8]
??:? pure nothrow  nogc  safe
std.range.takeOne!(test.ValInputRange!(int[]).ValInputRange).takeOne(test.ValInputRange!(int[]).ValInputRange).Result
std.range.takeOne!(test.ValInputRange!(int[]).ValInputRange).takeOne(test.ValInputRange!(int[]).ValInputRange).Result.opSlice(ulong,
ulong) [0x2da45f8]
??:? _Dmain [0x2d9867b]

--
Feb 03