_llist) == 0) { throw new RuntimeException("Can't pop from an empty datastructure"); } return array_pop($this->_llist); } /** @return the element shifted from the beginning of the DLL. * @throw RuntimeException If the datastructure is empty. */ public function shift() { if (count($this->_llist) == 0) { throw new RuntimeException("Can't shift from an empty datastructure"); } return array_shift($this->_llist); } /** Pushes an element to the end of the DLL. * @param $data variable to add to the DLL. */ public function push($data) { array_push($this->_llist, $data); return true; } /** Adds an element to the beginning of the DLL. * @param $data variable to add to the DLL. */ public function unshift($data) { array_unshift($this->_llist, $data); return true; } /** @return the element at the beginning of the DLL. */ public function top() { return end($this->_llist); } /** @return the element at the end of the DLL. */ public function bottom() { return reset($this->_llist); } /** @return number elements in the DLL. */ public function count() { return count($this->_llist); } /** @return whether the DLL is empty. */ public function isEmpty() { return ($this->count() == 0); } /** Changes the iteration mode. There are two orthogonal sets of modes that * can be set: * - The direction of the iteration (either one or the other) * - SplDoublyLnkedList::IT_MODE_LIFO (Stack style) * - SplDoublyLnkedList::IT_MODE_FIFO (Queue style) * * - The behavior of the iterator (either one or the other) * - SplDoublyLnkedList::IT_MODE_DELETE (Elements are deleted by the iterator) * - SplDoublyLnkedList::IT_MODE_KEEP (Elements are traversed by the iterator) * * The default mode is 0 : SplDoublyLnkedList::IT_MODE_FIFO | SplDoublyLnkedList::IT_MODE_KEEP * * @param $mode new mode of iteration */ public function setIteratorMode($mode) { $this->_it_mode = $mode; } /** @return the current iteration mode * @see setIteratorMode */ public function getIteratorMode() { return $this->_it_mode; } /** Rewind to top iterator as set in constructor */ public function rewind() { if ($this->_it_mode & self::IT_MODE_LIFO) { $this->_it_pos = count($this->_llist)-1; } else { $this->_it_pos = 0; } } /** @return whether iterator is valid */ public function valid() { return array_key_exists($this->_it_pos, $this->_llist); } /** @return current key */ public function key() { return $this->_it_pos; } /** @return current object */ public function current() { return $this->_llist[$this->_it_pos]; } /** Forward to next element */ public function next() { if ($this->_it_mode & self::IT_MODE_LIFO) { if ($this->_it_mode & self::IT_MODE_DELETE) { $this->pop(); } $this->_it_pos--; } else { if ($this->_it_mode & self::IT_MODE_DELETE) { $this->shift(); } else { $this->_it_pos++; } } } /** @return whether a certain offset exists in the DLL * * @param $offset The offset * @throw OutOfRangeException If the offset is either invalid or out of * range. */ public function offsetExists($offset) { if (!is_numeric($offset)) { throw new OutOfRangeException("Offset invalid or out of range"); } else { return array_key_exists($offset, $this->_llist); } } /** @return the data at a certain offset in the DLL * * @param $offset The offset * @throw OutOfRangeException If the offset is either invalid or out of * range. */ public function offsetGet($offset) { if ($this->_it_mode & self::IT_MODE_LIFO) { $realOffset = count($this->_llist)-$offset; } else { $realOffset = $offset; } if (!is_numeric($offset) || !array_key_exists($realOffset, $this->_llist)) { throw new OutOfRangeException("Offset invalid or out of range"); } else { return $this->_llist[$realOffset]; } } /** Defines the data at a certain offset in the DLL * * @param $offset The offset * @param $value New value * @throw OutOfRangeException If the offset is either invalid or out of * range. */ public function offsetSet($offset, $value) { if ($offset === null) { return $this->push($value); } if ($this->_it_mode & self::IT_MODE_LIFO) { $realOffset = count($this->_llist)-$offset; } else { $realOffset = $offset; } if (!is_numeric($offset) || !array_key_exists($realOffset, $this->_llist)) { throw new OutOfRangeException("Offset invalid or out of range"); } else { $this->_llist[$realOffset] = $value; } } /** Unsets the element at a certain offset in the DLL * * @param $offset The offset * @throw OutOfRangeException If the offset is either invalid or out of * range. */ public function offsetUnset($offset) { if ($this->_it_mode & self::IT_MODE_LIFO) { $realOffset = count($this->_llist)-$offset; } else { $realOffset = $offset; } if (!is_numeric($offset) || !array_key_exists($realOffset, $this->_llist)) { throw new OutOfRangeException("Offset invalid or out of range"); } else { array_splice($this->_llist, $realOffset, 1); } } } ?>