Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
16 / 16
CRAP
100.00% covered (success)
100.00%
88 / 88
ArrayDeque
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
16 / 16
33
100.00% covered (success)
100.00%
88 / 88
 __construct($size = 0) // [\SplFixedArray]
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 current() // -> mixed [\Iterator]
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 key() // -> int [\Iterator]
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 next() // [\Iterator]
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 offsetExists($index) // -> bool [\ArrayAccess]
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 offsetGet($index) // -> mixed [\ArrayAccess]
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 offsetSet($index, $newval) // [\ArrayAccess]
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 offsetUnset($index) // [\ArrayAccess]
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 rewind() // [\Iterator]
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 shift() // -> mixed
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
16 / 16
 toArray() // -> array [\SplFixedArray]
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
11 / 11
 unshift($value)
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
9 / 9
 valid() // -> bool [\Iterator]
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 map($index) // -> int
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
11 / 11
 offsetValid($index) // -> bool [DynamicArray]
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
8 / 8
 resize($size, $count = null) // [DynamicArray]
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
13 / 13
<?php namespace SEIDS\Arrays\Dynamic;
//==============================================================================
// PHP SEIDS: Supplementary, Easily Interchangeable Data Structures
// 
// Copyright 2015, Daniel A.C. Martin
// Distributed under the MIT License.
// (See LICENSE file for details.)
//==============================================================================
use \SEIDS\Arrays\CantShiftFromEmptyException;
class ArrayDeque extends DynamicArray
{
    ////////////////////////////////////////////////////////////////////////////
    // Members
    ////////////////////////////////////////////////////////////////////////////
    
    protected $start       = 0; // int
    protected $current_key = 0; // int
    
    ////////////////////////////////////////////////////////////////////////////
    // Public methods - Same interface as DynamicArray but with ability to
    //                  shift and unshift.
    ////////////////////////////////////////////////////////////////////////////
    
    public function __construct($size = 0) // [\SplFixedArray]
    {
        $this->start = ($size instanceof \SplFixedArray) ? 0
                                                         : $size / 2;
        parent::__construct($size);
    }
    
    public function current() // -> mixed [\Iterator]
    {
        return $this->data->offsetGet($this->map($this->current_key));
    }
    
    public function key() // -> int [\Iterator]
    {
        return $this->current_key;
    }
    
    public function next() // [\Iterator]
    {
        if($this->valid())
        {
            ++$this->current_key;
        }
    }
    
    public function offsetExists($index) // -> bool [\ArrayAccess]
    {
        return parent::offsetExists($this->map($index));
    }
    
    public function offsetGet($index) // -> mixed [\ArrayAccess]
    {
        return parent::offsetGet($this->map($index));
    }
    
    public function offsetSet($index, $newval) // [\ArrayAccess]
    {
        parent::offsetSet($this->map($index), $newval);
    }
    
    public function offsetUnset($index) // [\ArrayAccess]
    {
        parent::offsetUnset($this->map($index));
    }
    
    public function rewind() // [\Iterator]
    {
        $this->current_key = 0;
    }
    
    public function shift() // -> mixed
    {
        $r = null;
        
        if($this->isEmpty())
        {
            throw new CantShiftFromEmptyException('Can\'t shift from an empty datastructure');
        }
        else
        {
            $n = 0;
            $r = $this->offsetGet($n);
        
            $this->offsetUnset($n);
            
            --$this->count;
            ++$this->start;
            
            $size = $this->data->getSize();
            
            if($size <= $this->start)
            {
                $this->start -= $size;
            }
            
            $this->shrink();
        }
        
        return $r;
    }
    
    public function toArray() // -> array [\SplFixedArray]
    {
        $r     = null;
        $array = $this->data->toArray();
        
        if($this->map(0) < $this->map($this->count - 1))
        {
            $r = array_slice($array, $this->map(0), $this->count);
        }
        else
        {
            $r = array_merge
            (
                array_slice($array, $this->map(0)),
                array_slice($array, 0, $this->map($this->count))
            );
        }
        
        return $r;
    }
    
    public function unshift($value)
    {
        $this->grow();
        
        ++$this->count;
        --$this->start;
        
        if(0 > $this->start)
        {
            $this->start += $this->data->getSize();
        }
        
        $this->offsetSet(0, $value);
    }
    
    public function valid() // -> bool [\Iterator]
    {
        return (0 <= $this->current_key) && ($this->current_key < ($this->count) );
    }
    
    ////////////////////////////////////////////////////////////////////////////
    // Protected methods
    ////////////////////////////////////////////////////////////////////////////
    
    protected function map($index) // -> int
    {
        $r = $index;
        
        if( (null !== $index) && is_integer($index))
        {
            $r    = $index + $this->start;
            $size = $this->data->getSize();
            
            if($r >= $size)
            {
                $r -= $size;
            }
        }
        
        return $r;
    }
    
    protected function offsetValid($index) // -> bool [DynamicArray]
    {
        $size = $this->data->getSize();
        
        return
        (
               ($this->start <= $index)
            && ($index < ($this->start + $this->count) )
            && ($index < ($size) )
        ) || (
               (0 <= $index)
            && ($index < $this->start + $this->count - $size)
        );
    }
    
    protected function resize($size, $count = null) // [DynamicArray]
    {
        $data  = new \SplFixedArray($size);
        $count = (null === $count) ? $this->count : $count;
        $start = (int)(($size - $count) / 2);
        $n     = 0;
        $N     = ($count < $this->count) ? $count : $this->count;
        
        while($n < $N)
        {
            $data->offsetSet($n + $start, $this->data->offsetGet($this->map($n)));
            ++$n;
        }
        
        $this->data  = $data;
        $this->start = $start;
        $this->count = $count;
    }
}