|
SPL-StandardPHPLibrary
|
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 ?>
1.7.5.1