www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 8330] New: std.algorithm.find doesn't handle reference type ranges correctly

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8330

           Summary: std.algorithm.find doesn't handle reference type
                    ranges correctly
           Product: D
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: jmdavisProg gmx.com



PDT ---
This code

import std.algorithm;
import std.range;

void main()
{
    auto arr = [1, 2, 3, 4, 1, 9, 12, 42];
    assert(find(arr, [9, 12, 42]) == [9, 12, 42]);

    auto range = refRange(&arr);
    assert(equal(*find(range, [9, 12, 42]).ptr, [9, 12, 42]));
}

fails, giving

core.exception.AssertError q(10): Assertion failure
----------------
./q(_d_assertm+0x26) [0x43aa4e]
./q() [0x438826]
./q(_Dmain+0x1f8) [0x4312d8]
./q(extern (C) int rt.dmain2.main(int, char**).void runMain()+0x1c) [0x43b2e4]
./q(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void
delegate())+0x2a) [0x43ac5e]
./q(extern (C) int rt.dmain2.main(int, char**).void runAll()+0x3b) [0x43b32b]
./q(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void
delegate())+0x2a) [0x43ac5e]
./q(main+0xd1) [0x43abe9]
/lib/libc.so.6(__libc_start_main+0xf5) [0x7fd9af788455]
----------------

If you print out the result of the find that fails, you get [12, 49]. I believe
that the problem is with this particular overload of find:

R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if (isRandomAccessRange!R1 && hasLength!R1 && isBidirectionalRange!R2
        && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))

It appears that whenever you use a reference type haystack, and your needle has
a length greater than 2, the result is missing one element on its front. It
works with needles of lengthe 2 or less, and it works fine with value type
ranges just fine but not reference types. And it also fails with

import std.algorithm;
import std.range;
import std.stdio;

class C
{
    this(int[] arr)
    {
        _arr = arr;
    }

    bool empty() {return _arr.empty;}
     property auto save() {return new C(_arr);}
     property int front() {return _arr.front;}
    void popFront() {_arr.popFront();}
     property int back() {return _arr.back;}
    void popBack() {_arr.popBack();}
     property size_t length() {return _arr.length;}
    auto opIndex(size_t i) { return _arr[i]; }
    auto opSlice(size_t i, size_t j) { return new C(_arr[i .. j]); }
    auto opSlice() { return save; }

    int[] _arr;
}
    static assert(isRandomAccessRange!C);

void main()
{
    auto arr = [1, 2, 3, 4, 1, 9, 12, 42];
    auto c = new C(arr);

    auto range = refRange(&arr);
    assert(equal(find(c, [9, 12, 42]), [9, 12, 42]));
}

so it's not a bug in RefRange.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 01 2012
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8330


John Colvin <john.loughran.colvin gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |john.loughran.colvin gmail.
                   |                            |com
         Resolution|                            |FIXED



23:52:54 BST ---
No longer occurs. Both examples run fine on git master, although this could
well have been fixed ages ago.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 11 2013