Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
25 / 25 |
CRAP | |
100.00% |
105 / 105 |
DynamicArray | |
100.00% |
1 / 1 |
|
100.00% |
25 / 25 |
46 | |
100.00% |
105 / 105 |
__construct($size = 0) // [\SplFixedArray] | |
100.00% |
1 / 1 |
3 | |
100.00% |
5 / 5 |
|||
__clone() | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
count() // -> int [\Countable] | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
current() // -> mixed [\Iterator] | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
fromArray($array, $save_indexes = true) // -> DynamicArray [\SplFixedArray] | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getAllocatedSize() // -> int | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getSize() // -> int [\SplFixedArray] | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
isEmpty() // -> bool | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
key() // -> int [\Iterator] | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
next() // [\Iterator] | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
offsetExists($index) // -> bool [\ArrayAccess] | |
100.00% |
1 / 1 |
2 | |
100.00% |
1 / 1 |
|||
offsetGet($index) // -> mixed [\ArrayAccess] | |
100.00% |
1 / 1 |
2 | |
100.00% |
7 / 7 |
|||
offsetSet($index, $newval) // [\ArrayAccess] | |
100.00% |
1 / 1 |
3 | |
100.00% |
10 / 10 |
|||
offsetUnset($index) // [\ArrayAccess] | |
100.00% |
1 / 1 |
2 | |
100.00% |
6 / 6 |
|||
pop() // -> mixed | |
100.00% |
1 / 1 |
2 | |
100.00% |
10 / 10 |
|||
push($value) | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
rewind() // [\Iterator] | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
setSize($size) // -> int [\SplFixedArray] | |
100.00% |
1 / 1 |
6 | |
100.00% |
19 / 19 |
|||
toArray() // -> array [\SplFixedArray] | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
valid() // -> bool [\Iterator] | |
100.00% |
1 / 1 |
2 | |
100.00% |
2 / 2 |
|||
__wakeup() // [\SplFixedArray] | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
grow() | |
100.00% |
1 / 1 |
3 | |
100.00% |
8 / 8 |
|||
offsetValid($index) // -> bool | |
100.00% |
1 / 1 |
2 | |
100.00% |
1 / 1 |
|||
resize($size, $count = null) | |
100.00% |
1 / 1 |
3 | |
100.00% |
8 / 8 |
|||
shrink() | |
100.00% |
1 / 1 |
2 | |
100.00% |
6 / 6 |
<?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\CantPopFromEmptyException; | |
use \SEIDS\Arrays\InvalidArgumentException; | |
use \SEIDS\Arrays\InvalidIndexException; | |
class DynamicArray implements \ArrayAccess, \Countable, \Iterator | |
{ | |
//////////////////////////////////////////////////////////////////////////// | |
// Members | |
//////////////////////////////////////////////////////////////////////////// | |
protected $data = null; // &\SplFixedArray | |
protected $count = 0; // int | |
//////////////////////////////////////////////////////////////////////////// | |
// Public methods | |
//////////////////////////////////////////////////////////////////////////// | |
public function __construct($size = 0) // [\SplFixedArray] | |
{ | |
$this->data = ($size instanceof \SplFixedArray) ? $size | |
: new \SplFixedArray($size); | |
$this->count = ($size instanceof \SplFixedArray) ? $this->data->getSize() | |
: $size; | |
} | |
public function __clone() | |
{ | |
$this->data = clone $this->data; | |
} | |
public function count() // -> int [\Countable] | |
{ | |
return $this->count; | |
} | |
public function current() // -> mixed [\Iterator] | |
{ | |
return $this->data->current(); | |
} | |
public static function fromArray($array, $save_indexes = true) // -> DynamicArray [\SplFixedArray] | |
{ | |
return new DynamicArray(\SplFixedArray::fromArray($array, $save_indexes)); | |
} | |
public function getAllocatedSize() // -> int | |
{ | |
return $this->data->getSize(); | |
} | |
public function getSize() // -> int [\SplFixedArray] | |
{ | |
return $this->count(); | |
} | |
public function isEmpty() // -> bool | |
{ | |
return 0 === $this->count; | |
} | |
public function key() // -> int [\Iterator] | |
{ | |
return $this->data->key(); | |
} | |
public function next() // [\Iterator] | |
{ | |
if($this->valid()) | |
{ | |
$this->data->next(); | |
} | |
} | |
public function offsetExists($index) // -> bool [\ArrayAccess] | |
{ | |
return (!$this->offsetValid($index)) ? false : $this->data->offsetExists($index); | |
} | |
public function offsetGet($index) // -> mixed [\ArrayAccess] | |
{ | |
$r = null; | |
if($this->offsetValid($index)) | |
{ | |
$r = $this->data->offsetGet($index); | |
} | |
else | |
{ | |
throw new InvalidIndexException('Index invalid or out of range'); | |
} | |
return $r; | |
} | |
public function offsetSet($index, $newval) // [\ArrayAccess] | |
{ | |
if(null === $index) | |
{ | |
$this->push($newval); | |
} | |
else if($this->offsetValid($index)) | |
{ | |
$this->data->offsetSet($index, $newval); | |
} | |
else | |
{ | |
throw new InvalidIndexException('Index invalid or out of range'); | |
} | |
} | |
public function offsetUnset($index) // [\ArrayAccess] | |
{ | |
if($this->offsetValid($index)) | |
{ | |
$this->data->offsetUnset($index); | |
} | |
else | |
{ | |
throw new InvalidIndexException('Index invalid or out of range'); | |
} | |
} | |
public function pop() // -> mixed | |
{ | |
$r = null; | |
if($this->isEmpty()) | |
{ | |
throw new CantPopFromEmptyException('Can\'t pop from an empty datastructure'); | |
} | |
else | |
{ | |
$n = $this->count - 1; | |
$r = $this->offsetGet($n); | |
$this->offsetUnset($n); | |
--$this->count; | |
$this->shrink(); | |
} | |
return $r; | |
} | |
public function push($value) | |
{ | |
$this->grow(); | |
$this->offsetSet($this->count++, $value); | |
} | |
public function rewind() // [\Iterator] | |
{ | |
$this->data->rewind(); | |
} | |
public function setSize($size) // -> int [\SplFixedArray] | |
{ | |
if(true === $size) | |
{ | |
$size = 1; | |
} | |
else if(false === $size) | |
{ | |
$size = 0; | |
} | |
else if(null === $size) | |
{ | |
$size = 0; | |
} | |
if(!is_numeric($size)) | |
trigger_error('SplFixedArray::setSize() expects parameter 1 to be long, ' . gettype($size) . ' given', E_USER_WARNING); // No braces to workaround code coverage bug. | |
else if($size < 0) | |
{ | |
throw new InvalidArgumentException('array size cannot be less than zero'); | |
} | |
else | |
{ | |
$this->resize($size, $size); | |
} | |
return 1; | |
} | |
public function toArray() // -> array [\SplFixedArray] | |
{ | |
return array_slice($this->data->toArray(), 0, $this->count); | |
} | |
public function valid() // -> bool [\Iterator] | |
{ | |
return ($this->data->key() < $this->count) ? $this->data->valid() | |
: false; | |
} | |
public function __wakeup() // [\SplFixedArray] | |
{ | |
$this->data->__wakeup(); | |
} | |
//////////////////////////////////////////////////////////////////////////// | |
// Protected methods | |
//////////////////////////////////////////////////////////////////////////// | |
protected function grow() | |
{ | |
$size = $this->data->getSize(); | |
if($size === $this->count) | |
{ | |
$size = (0 < $size) ? 2 * $size | |
: 1; | |
$this->resize($size); | |
} | |
} | |
protected function offsetValid($index) // -> bool | |
{ | |
return (0 <= $index) && ($index < $this->count); | |
} | |
protected function resize($size, $count = null) | |
{ | |
$count = (null === $count) ? $this->count : $count; | |
$this->data->SetSize($size); | |
$n = $count; | |
while($n < $size) | |
{ | |
$this->data->offsetUnset($n++); | |
} | |
$this->count = $count; | |
} | |
protected function shrink() | |
{ | |
$new_size = $this->data->getSize() / 2; | |
if($this->count < ($new_size / 2) ) | |
{ | |
$this->resize($new_size); | |
} | |
} | |
} | |