D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 2984 - Failure to find front/back/popBack/popFront/etc should fall back to opApply
Summary: Failure to find front/back/popBack/popFront/etc should fall back to opApply
Status: RESOLVED DUPLICATE of issue 3514
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Windows
: P2 major
Assignee: No Owner
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2009-05-15 15:04 UTC by Koroskin Denis
Modified: 2015-06-09 01:26 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Koroskin Denis 2009-05-15 15:04:23 UTC
I have a Vector class which is modeled after std::vector. As such, it has front, back, popBack but no popFront method. DMD2.029 fails to compile foreach over the vector because it lacks popFront even though there are opApply overloads for it. Marking it as a regression since it used to compile with DMD2.028 although it used other primitive names. Here is a cut-down code to reproduce the problem:

module Vector;

public struct Vector(Type)
{
    private uint    _size = 0;
    private Type[]  _elements = null;

    uint length()
    {
        return _size;
    }

    bool empty()
    {
        return _size == 0;
    }

    void popBack()
    in
    {
        assert(_size >= 1);
    }
    body
    {
        --_size;
    }

    Type back()
    in
    {
        assert(!empty());
    }
    body
    {
        return _elements[_size-1];
    }

    Type front()
    in
    {
        assert(!empty());
    }
    body
    {
        return _elements[0];
    }

    int opApply(int delegate(ref Type value) dg)
    {
        for(uint i=0; i<_size; ++i)
        {
            int result = dg(_elements[i]);
            if( result != 0 ) {
                return result;
            }
        }

        return 0;
    }

    int opApply(int delegate(ref uint index, ref Type value) dg)
    {
        for(uint i=0; i<_size; ++i)
        {
            int result = dg(i, _elements[i]);
            if( result != 0 ) {
                return result;
            }
        }

        return 0;
    }
}

void main()
{
    Vector!(int) v;
    foreach (int i; v) {
        // do nothing
    }
}
Comment 1 Koroskin Denis 2009-05-15 16:21:50 UTC
Error message issued:
Vector.d(83): Error: no property 'popFront' for type 'Vector!(int)'
Comment 2 Koroskin Denis 2009-05-15 16:22:13 UTC
Note that adding

Type[] opSlice()
{
    return _elements[0.._size];
}

to the Vector struct will result int the following error message instead:

Error: undefined identifier module Vector.empty
Error: function expected before (), not module Vector.empty of type void
Error: undefined identifier module Vector.popFront
Error: function expected before (), not module Vector.popFront of type void
Error: undefined identifier module Vector.front
Error: function expected before (), not module Vector.front of type void
Comment 3 Don 2009-11-16 07:34:06 UTC
This isn't a regression -- the language changed. Bug 3514 expresses this better.
Comment 4 Koroskin Denis 2009-11-16 07:47:14 UTC
Well, yes. It is a regression in a sense that the code used to compile but it doesn't anymore. It sees a front(), back() and empty() methods in my Vector struct (which is designed after std::vector and thus has similar members) and mistakenly assumes it is a range (and it's not).

The language change shouldn't have caused this compilation error, be it implemented more correct, that's why I marked it as a regression :)
Comment 5 Leandro Lucarella 2009-11-16 12:44:28 UTC
*** Issue 3514 has been marked as a duplicate of this issue. ***
Comment 6 Steven Schveighoffer 2009-11-16 14:04:03 UTC
Although bug 3514 came later, it captures more information, and following the fix prescribed in 3514 would make this bug sort of moot.  There is no reason to have a special case of partially implemented range functions vs. opApply -- opApply should be the default choice even with valid range functions.

*** This issue has been marked as a duplicate of issue 3514 ***