SPL-StandardPHPLibrary
spldoublylinkedlist.inc
Go to the documentation of this file.
00001 <?php
00022 class SplDoublyLinkedList implements Iterator, ArrayAccess, Countable
00023 {
00024     protected $_llist   = array();
00025     protected $_it_mode = 0;
00026     protected $_it_pos  = 0;
00027 
00031     const IT_MODE_LIFO     = 0x00000002;
00032 
00036     const IT_MODE_FIFO     = 0x00000000;
00037 
00041     const IT_MODE_KEEP     = 0x00000000;
00042 
00046     const IT_MODE_DELETE   = 0x00000001;
00047 
00051     public function pop()
00052     {
00053         if (count($this->_llist) == 0) {
00054             throw new RuntimeException("Can't pop from an empty datastructure");
00055         }
00056         return array_pop($this->_llist);
00057     }
00058 
00062     public function shift()
00063     {
00064         if (count($this->_llist) == 0) {
00065             throw new RuntimeException("Can't shift from an empty datastructure");
00066         }
00067         return array_shift($this->_llist);
00068     }
00069 
00073     public function push($data)
00074     {
00075         array_push($this->_llist, $data);
00076         return true;
00077     }
00078 
00082     public function unshift($data)
00083     {
00084         array_unshift($this->_llist, $data);
00085         return true;
00086     }
00087 
00090     public function top()
00091     {
00092         return end($this->_llist);
00093     }
00094 
00097     public function bottom()
00098     {
00099         return reset($this->_llist);
00100     }
00101 
00104     public function count()
00105     {
00106         return count($this->_llist);
00107     }
00108 
00111     public function isEmpty()
00112     {
00113         return ($this->count() == 0);
00114     }
00115 
00130     public function setIteratorMode($mode)
00131     {
00132         $this->_it_mode = $mode;
00133     }
00134 
00138     public function getIteratorMode()
00139     {
00140         return $this->_it_mode;
00141     }
00142 
00145     public function rewind()
00146     {
00147         if ($this->_it_mode & self::IT_MODE_LIFO) {
00148             $this->_it_pos = count($this->_llist)-1;
00149         } else {
00150             $this->_it_pos = 0;
00151         }
00152     }
00153 
00156     public function valid()
00157     {
00158         return array_key_exists($this->_it_pos, $this->_llist);
00159     }
00160 
00163     public function key()
00164     {
00165         return $this->_it_pos;
00166     }
00167 
00170     public function current()
00171     {
00172         return $this->_llist[$this->_it_pos];
00173     }
00174 
00177     public function next()
00178     {
00179         if ($this->_it_mode & self::IT_MODE_LIFO) {
00180             if ($this->_it_mode & self::IT_MODE_DELETE) {
00181                 $this->pop();
00182             }
00183             $this->_it_pos--;
00184         } else {
00185             if ($this->_it_mode & self::IT_MODE_DELETE) {
00186                 $this->shift();
00187             } else {
00188                 $this->_it_pos++;
00189             }
00190         }
00191     }
00192 
00199     public function offsetExists($offset)
00200     {
00201         if (!is_numeric($offset)) {
00202             throw new OutOfRangeException("Offset invalid or out of range");
00203         } else {
00204             return array_key_exists($offset, $this->_llist);
00205         }
00206     }
00207 
00214     public function offsetGet($offset)
00215     {
00216         if ($this->_it_mode & self::IT_MODE_LIFO) {
00217             $realOffset = count($this->_llist)-$offset;
00218         } else {
00219             $realOffset = $offset;
00220         }
00221 
00222         if (!is_numeric($offset) || !array_key_exists($realOffset, $this->_llist)) {
00223             throw new OutOfRangeException("Offset invalid or out of range");
00224         } else {
00225             return $this->_llist[$realOffset];
00226         }
00227     }
00228 
00236     public function offsetSet($offset, $value)
00237     {
00238         if ($offset === null) {
00239             return $this->push($value);
00240         }
00241 
00242         if ($this->_it_mode & self::IT_MODE_LIFO) {
00243             $realOffset = count($this->_llist)-$offset;
00244         } else {
00245             $realOffset = $offset;
00246         }
00247 
00248         if (!is_numeric($offset) || !array_key_exists($realOffset, $this->_llist)) {
00249             throw new OutOfRangeException("Offset invalid or out of range");
00250         } else {
00251             $this->_llist[$realOffset] = $value;
00252         }
00253     }
00254 
00261     public function offsetUnset($offset)
00262     {
00263         if ($this->_it_mode & self::IT_MODE_LIFO) {
00264             $realOffset = count($this->_llist)-$offset;
00265         } else {
00266             $realOffset = $offset;
00267         }
00268 
00269         if (!is_numeric($offset) || !array_key_exists($realOffset, $this->_llist)) {
00270             throw new OutOfRangeException("Offset invalid or out of range");
00271         } else {
00272             array_splice($this->_llist, $realOffset, 1);
00273         }
00274     }
00275 }
00276 
00277 ?>