www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3874] New: std.range.stride assumes a bidirectional input range

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

           Summary: std.range.stride assumes a bidirectional input range
           Product: D
           Version: 2.040
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: minor
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: philippe.sigaud gmail.com



15:03:36 CET ---
std.range.Stride assumes a bidirectional input range: it defines back/popBack
without checking.

Here is the minor moodification necessary to correct this:

Also, maybe the global constraint should be isForwardRange!R and not
isInputRange!R, as the input is copied inside the struct.


**
std.range.Stride assumes a bidirectional range. This slight modification
just add the necessary 'isBidirectionalRange!R' throughout the code.
*/
struct Stride(R) if (isInputRange!(R)) // isForwardRange!R ?
{
private:
    R _input;
    size_t _n;

public:
    this(R input, size_t n)
    {
        _input = input;
        _n = n;
        static if (hasLength!(R))
        {
            auto slack = _input.length % _n;
            if (slack) slack--;
            if (!slack) return;
            static if (isRandomAccessRange!(R) && hasSlicing!(R))
            {
                _input = _input[0 .. _input.length - slack];
            }
            else
            {
                foreach (i; 0 .. slack)
                {
                    if (_input.empty) break;
                    _input.popBack;
                }
            }
        }
    }

    Stride opSlice()
    {
        return this;
    }

    bool empty()
    {
        return _input.empty;
    }

    void popFront()
    {
        static if (isRandomAccessRange!(R) && hasLength!(R) && hasSlicing!(R))
        {
            _input = _input[
                _n < _input.length ? _n : _input.length
                .. _input.length];
        }
        else
            foreach (i; 0 .. _n)
            {
                _input.popFront;
                if (_input.empty) break;
            }
    }

    static if (hasLength!(R) && isBidirectionalRange!R)
        void popBack()
        {
            enforce(_input.length >= _n);
            static if (isRandomAccessRange!(R) && hasSlicing!(R))
            {
                _input = _input[0 .. _input.length - _n];
            }
            else
            {
                foreach (i; 0 .. _n)
                {
                    if (_input.empty) break;
                    _input.popBack;
                }
            }
        }

    ref ElementType!(R) front()
    {
        return _input.front;
    }

    static if (isBidirectionalRange!R) {
        ref ElementType!(R) back()
        {
            return _input.back;
        }
    }

    static if (isRandomAccessRange!(R) && hasLength!(R))
        ref ElementType!(R) opIndex(uint n)
        {
            return _input[_n * n];
        }

    static if (hasLength!(R))
        size_t length()
        {
            return (_input.length + _n - 1) / _n;
        }
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 04 2010
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3874


David Simcha <dsimcha yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |dsimcha yahoo.com
         Resolution|                            |FIXED



Fixed in SVN.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 24 2010