/hphp/system/php/spl/datastructures/SplDoublyLinkedList.php

https://gitlab.com/iranjith4/hhvm · PHP · 522 lines · 267 code · 40 blank · 215 comment · 52 complexity · e1b170a064707bb673a033a5ca879740 MD5 · raw file

  1. <?php
  2. class _SplDoublyLinkedListNode {
  3. public $data = null;
  4. public $next = null;
  5. public $prev = null;
  6. public function getNext($fifo = true) {
  7. return $fifo ? $this->next : $this->prev;
  8. }
  9. public function getPrev($fifo = true) {
  10. return $fifo ? $this->prev : $this->next;
  11. }
  12. }
  13. // This doc comment block generated by idl/sysdoc.php
  14. /**
  15. * ( excerpt from http://php.net/manual/en/class.spldoublylinkedlist.php )
  16. *
  17. * The SplDoublyLinkedList class provides the main functionalities of a
  18. * doubly linked list.
  19. *
  20. */
  21. class SplDoublyLinkedList
  22. implements \HH\Iterator, ArrayAccess, Countable, Serializable {
  23. const IT_MODE_LIFO = 2;
  24. const IT_MODE_FIFO = 0;
  25. const IT_MODE_DELETE = 1;
  26. const IT_MODE_KEEP = 0;
  27. protected $head = null;
  28. protected $tail = null;
  29. protected $key = 0;
  30. protected $current = null;
  31. protected $count = 0;
  32. protected $mode = 0;
  33. public function add($index, $value) {
  34. if ((!is_int($index) && !is_numeric($index)) ||
  35. $index < 0 || $index > $this->count()) {
  36. throw new OutOfRangeException(
  37. "Offset invalid or out of range"
  38. );
  39. }
  40. if ($index == $this->count()) {
  41. // End of list, simply push it
  42. $this->push($value);
  43. } else {
  44. $pos = $this->head;
  45. for ($i = 0; $i < $index; ++$i) {
  46. // Fetch element to insert before
  47. $pos = $pos->next;
  48. }
  49. $node = new _SplDoublyLinkedListNode;
  50. $node->data = $value;
  51. $node->prev = $pos->prev;
  52. $node->next = $pos;
  53. if ($node->prev === null) {
  54. $this->head = $node;
  55. } else {
  56. $pos->prev->next = $node;
  57. }
  58. $pos->prev = $node;
  59. ++$this->count;
  60. }
  61. }
  62. // This doc comment block generated by idl/sysdoc.php
  63. /**
  64. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.bottom.php )
  65. *
  66. *
  67. * @return mixed The value of the first node.
  68. */
  69. public function bottom() {
  70. if ($this->head === null) {
  71. throw new RuntimeException("Can't shift from an empty datastructure");
  72. }
  73. return $this->head->data;
  74. }
  75. // This doc comment block generated by idl/sysdoc.php
  76. /**
  77. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.top.php )
  78. *
  79. *
  80. * @return mixed The value of the last node.
  81. */
  82. public function top() {
  83. if ($this->tail === null) {
  84. throw new RuntimeException("Can't pop from an empty datastructure");
  85. }
  86. return $this->tail->data;
  87. }
  88. // This doc comment block generated by idl/sysdoc.php
  89. /**
  90. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.isempty.php
  91. * )
  92. *
  93. *
  94. * @return mixed Returns whether the doubly linked list is empty.
  95. */
  96. public function isEmpty() {
  97. return !$this->count;
  98. }
  99. // This doc comment block generated by idl/sysdoc.php
  100. /**
  101. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.push.php )
  102. *
  103. * Pushes value at the end of the doubly linked list.
  104. *
  105. * @value mixed The value to push.
  106. *
  107. * @return mixed No value is returned.
  108. */
  109. public function push($value) {
  110. $node = new _SplDoublyLinkedListNode;
  111. $node->data = $value;
  112. if ($this->isEmpty()) {
  113. $this->head = $node;
  114. } else {
  115. $node->prev = $this->tail;
  116. $this->tail->next = $node;
  117. }
  118. $this->tail = $node;
  119. ++$this->count;
  120. return;
  121. }
  122. // This doc comment block generated by idl/sysdoc.php
  123. /**
  124. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.pop.php )
  125. *
  126. *
  127. * @return mixed The value of the popped node.
  128. */
  129. public function pop() {
  130. $retval = $this->top();
  131. $this->tail = $this->tail->prev;
  132. if ($this->tail !== null) {
  133. $this->tail->next = null;
  134. }
  135. --$this->count;
  136. return $retval;
  137. }
  138. // This doc comment block generated by idl/sysdoc.php
  139. /**
  140. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.unshift.php
  141. * )
  142. *
  143. * Prepends value at the beginning of the doubly linked list.
  144. *
  145. * @value mixed The value to unshift.
  146. *
  147. * @return mixed No value is returned.
  148. */
  149. public function unshift($value) {
  150. $node = new _SplDoublyLinkedListNode;
  151. $node->data = $value;
  152. if ($this->isEmpty()) {
  153. $this->head = $this->tail = $node;
  154. } else {
  155. $node->next = $this->head;
  156. $this->head->prev = $node;
  157. $this->head = $node;
  158. }
  159. ++$this->count;
  160. return;
  161. }
  162. // This doc comment block generated by idl/sysdoc.php
  163. /**
  164. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.shift.php )
  165. *
  166. *
  167. * @return mixed The value of the shifted node.
  168. */
  169. public function shift() {
  170. $retval = $this->bottom();
  171. $this->head = $this->head->next;
  172. if ($this->head !== null) {
  173. $this->head->prev = null;
  174. }
  175. --$this->count;
  176. return $retval;
  177. }
  178. // This doc comment block generated by idl/sysdoc.php
  179. /**
  180. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.current.php
  181. * )
  182. *
  183. * Get the current doubly linked list node.
  184. *
  185. * @return mixed The current node value.
  186. */
  187. public function current() {
  188. if (!$this->valid()) {
  189. return null;
  190. }
  191. return $this->current->data;
  192. }
  193. // This doc comment block generated by idl/sysdoc.php
  194. /**
  195. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.key.php )
  196. *
  197. * This function returns the current node index
  198. *
  199. * @return mixed The current node index.
  200. */
  201. public function key() {
  202. return $this->key;
  203. }
  204. // This doc comment block generated by idl/sysdoc.php
  205. /**
  206. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.next.php )
  207. *
  208. * Move the iterator to the next node.
  209. *
  210. * @return mixed No value is returned.
  211. */
  212. public function next() {
  213. if ($this->mode & self::IT_MODE_DELETE) {
  214. --$this->count;
  215. if ($this->current->prev !== null) {
  216. $this->current->prev->next = $this->current->next;
  217. }
  218. if ($this->current->next !== null) {
  219. $this->current->next->prev = $this->current->prev;
  220. }
  221. if ($this->current === $this->tail) {
  222. $this->tail = $this->current->prev;
  223. }
  224. if ($this->current === $this->head) {
  225. $this->head = $this->current->next;
  226. }
  227. }
  228. if ($this->mode & self::IT_MODE_LIFO) {
  229. --$this->key;
  230. $this->current = $this->current ? $this->current->prev : null;
  231. } else {
  232. if (!($this->mode & self::IT_MODE_DELETE)) {
  233. ++$this->key;
  234. }
  235. $this->current = $this->current ? $this->current->next : null;
  236. }
  237. }
  238. // This doc comment block generated by idl/sysdoc.php
  239. /**
  240. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.prev.php )
  241. *
  242. * Move the iterator to the previous node.
  243. *
  244. * @return mixed No value is returned.
  245. */
  246. public function prev() {
  247. if ($this->mode & self::IT_MODE_DELETE) {
  248. --$this->count;
  249. if ($this->current->prev !== null) {
  250. $this->current->prev->next = $this->current->next;
  251. }
  252. if ($this->current->next !== null) {
  253. $this->current->next->prev = $this->current->prev;
  254. }
  255. }
  256. if ($this->mode & self::IT_MODE_LIFO) {
  257. if (!($this->mode & self::IT_MODE_DELETE)) {
  258. ++$this->key;
  259. }
  260. $this->current = $this->current ? $this->current->next : null;
  261. } else {
  262. --$this->key;
  263. $this->current = $this->current ? $this->current->prev : null;
  264. }
  265. }
  266. // This doc comment block generated by idl/sysdoc.php
  267. /**
  268. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.rewind.php )
  269. *
  270. * This rewinds the iterator to the beginning.
  271. *
  272. * @return mixed No value is returned.
  273. */
  274. public function rewind() {
  275. if ($this->mode & self::IT_MODE_LIFO) {
  276. $this->key = $this->count - 1;
  277. $this->current = $this->tail;
  278. } else {
  279. $this->key = 0;
  280. $this->current = $this->head;
  281. }
  282. }
  283. // This doc comment block generated by idl/sysdoc.php
  284. /**
  285. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.valid.php )
  286. *
  287. * Checks if the doubly linked list contains any more nodes.
  288. *
  289. * @return mixed Returns TRUE if the doubly linked list contains any
  290. * more nodes, FALSE otherwise.
  291. */
  292. public function valid() {
  293. return $this->current !== null;
  294. }
  295. // This doc comment block generated by idl/sysdoc.php
  296. /**
  297. * ( excerpt from
  298. * http://php.net/manual/en/spldoublylinkedlist.getiteratormode.php )
  299. *
  300. *
  301. * @return mixed Returns the different modes and flags that affect
  302. * the iteration.
  303. */
  304. public function getIteratorMode() {
  305. return $this->mode;
  306. }
  307. // This doc comment block generated by idl/sysdoc.php
  308. /**
  309. * ( excerpt from
  310. * http://php.net/manual/en/spldoublylinkedlist.setiteratormode.php )
  311. *
  312. *
  313. * @mode mixed There are two orthogonal sets of modes that can be
  314. * set: The direction of the iteration (either one or
  315. * the other): SplDoublyLinkedList::IT_MODE_LIFO (Stack
  316. * style) SplDoublyLinkedList::IT_MODE_FIFO (Queue
  317. * style) The behavior of the iterator (either one or
  318. * the other): SplDoublyLinkedList::IT_MODE_DELETE
  319. * (Elements are deleted by the iterator)
  320. * SplDoublyLinkedList::IT_MODE_KEEP (Elements are
  321. * traversed by the iterator)
  322. *
  323. * The default mode is:
  324. * SplDoublyLinkedList::IT_MODE_FIFO |
  325. * SplDoublyLinkedList::IT_MODE_KEEP
  326. *
  327. * @return mixed No value is returned.
  328. */
  329. public function setIteratorMode($mode) {
  330. $this->mode = $mode;
  331. }
  332. // This doc comment block generated by idl/sysdoc.php
  333. /**
  334. * ( excerpt from
  335. * http://php.net/manual/en/spldoublylinkedlist.offsetexists.php )
  336. *
  337. *
  338. * @index mixed The index being checked.
  339. *
  340. * @return mixed TRUE if the requested index exists, otherwise FALSE
  341. */
  342. public function offsetExists($index) {
  343. return $index < $this->count;
  344. }
  345. // This doc comment block generated by idl/sysdoc.php
  346. /**
  347. * ( excerpt from
  348. * http://php.net/manual/en/spldoublylinkedlist.offsetget.php )
  349. *
  350. *
  351. * @index mixed The index with the value.
  352. *
  353. * @return mixed The value at the specified index.
  354. */
  355. public function offsetGet($index) {
  356. if (!is_int($index) && !is_numeric($index)) {
  357. throw new OutOfRangeException("Offset invalid or out of range");
  358. }
  359. $node = ($this->mode & self::IT_MODE_LIFO) ? $this->tail : $this->head;
  360. for ($i = 0; $i < $index && $node !== null; ++$i) {
  361. $node = $node->getNext(!($this->mode & self::IT_MODE_LIFO));
  362. }
  363. if (!$node) {
  364. throw new OutOfRangeException("Offset invalid or out of range");
  365. }
  366. return $node->data;
  367. }
  368. // This doc comment block generated by idl/sysdoc.php
  369. /**
  370. * ( excerpt from
  371. * http://php.net/manual/en/spldoublylinkedlist.offsetset.php )
  372. *
  373. * Sets the value at the specified index to newval.
  374. *
  375. * @index mixed The index being set.
  376. * @newval mixed The new value for the index.
  377. *
  378. * @return mixed No value is returned.
  379. */
  380. public function offsetSet($index, $newval) {
  381. if ($index === null) {
  382. $this->push($newval);
  383. return;
  384. }
  385. if ($index < 0 || $index >= $this->count) {
  386. throw new OutOfRangeException("Offset invalid or out of range");
  387. }
  388. if ($this->isEmpty()) {
  389. $node = new _SplDoublyLinkedListNode;
  390. $this->head = $node;
  391. $this->tail = $node;
  392. ++$this->count;
  393. }
  394. $node = ($this->mode & self::IT_MODE_LIFO) ? $this->tail : $this->head;
  395. for ($i = 0; $i < $index; ++$i) {
  396. $node = $node->getNext(!($this->mode & self::IT_MODE_LIFO));
  397. }
  398. $node->data = $newval;
  399. }
  400. // This doc comment block generated by idl/sysdoc.php
  401. /**
  402. * ( excerpt from
  403. * http://php.net/manual/en/spldoublylinkedlist.offsetunset.php )
  404. *
  405. * Unsets the value at the specified index.
  406. *
  407. * @index mixed The index being unset.
  408. *
  409. * @return mixed No value is returned.
  410. */
  411. public function offsetUnset($index) {
  412. if (!is_int($index) && !is_numeric($index)) {
  413. throw new OutOfRangeException("Offset invalid or out of range");
  414. }
  415. if ($index < 0 || $index >= $this->count()) {
  416. throw new OutOfRangeException("Offset out of range");
  417. }
  418. $node = ($this->mode & self::IT_MODE_LIFO) ? $this->tail : $this->head;
  419. for ($i = 0; $i < $index; ++$i) {
  420. $node = $node->getNext(!($this->mode & self::IT_MODE_LIFO));
  421. }
  422. --$this->count;
  423. if ($node->prev) {
  424. $node->prev->next = $node->next;
  425. } else {
  426. $this->head = $node->next;
  427. }
  428. if ($node->next) {
  429. $node->next->prev = $node->prev;
  430. } else {
  431. $this->tail = $node->prev;
  432. }
  433. }
  434. // This doc comment block generated by idl/sysdoc.php
  435. /**
  436. * ( excerpt from http://php.net/manual/en/spldoublylinkedlist.count.php )
  437. *
  438. *
  439. * @return mixed Returns the number of elements in the doubly linked
  440. * list.
  441. */
  442. public function count() {
  443. return $this->count;
  444. }
  445. // This doc comment block generated by idl/sysdoc.php
  446. /**
  447. * ( excerpt from
  448. * http://php.net/manual/en/spldoublylinkedlist.serialize.php )
  449. *
  450. * Serializes the storage. WarningThis function is currently not
  451. * documented; only its argument list is available.
  452. *
  453. * @return mixed The serialized string.
  454. */
  455. public function serialize() {
  456. $data = array();
  457. foreach ($this as $val) {
  458. $data[] = $val;
  459. }
  460. return serialize(array($data, $this->mode));
  461. }
  462. // This doc comment block generated by idl/sysdoc.php
  463. /**
  464. * ( excerpt from
  465. * http://php.net/manual/en/spldoublylinkedlist.unserialize.php )
  466. *
  467. * Unserializes the storage, from SplDoublyLinkedList::serialize().
  468. * WarningThis function is currently not documented; only its argument list
  469. * is available.
  470. *
  471. * @serialized mixed The serialized string.
  472. *
  473. * @return mixed No value is returned.
  474. */
  475. public function unserialize($serialized) {
  476. list($data, $this->mode) = unserialize($serialized);
  477. foreach ($data as $elem) {
  478. $this->push($elem);
  479. }
  480. }
  481. }