OrderedHashMapIterator.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Form\Util;
  11. /**
  12. * Iterator for {@link OrderedHashMap} objects.
  13. *
  14. * @author Bernhard Schussek <bschussek@gmail.com>
  15. *
  16. * @internal
  17. */
  18. class OrderedHashMapIterator implements \Iterator
  19. {
  20. /**
  21. * @var array
  22. */
  23. private $elements;
  24. /**
  25. * @var array
  26. */
  27. private $orderedKeys;
  28. /**
  29. * @var int
  30. */
  31. private $cursor;
  32. /**
  33. * @var int
  34. */
  35. private $cursorId;
  36. /**
  37. * @var array
  38. */
  39. private $managedCursors;
  40. /**
  41. * @var string|int|null
  42. */
  43. private $key;
  44. /**
  45. * @var mixed
  46. */
  47. private $current;
  48. /**
  49. * @param array $elements The elements of the map, indexed by their
  50. * keys
  51. * @param array $orderedKeys The keys of the map in the order in which
  52. * they should be iterated
  53. * @param array $managedCursors An array from which to reference the
  54. * iterator's cursor as long as it is alive.
  55. * This array is managed by the corresponding
  56. * {@link OrderedHashMap} instance to support
  57. * recognizing the deletion of elements.
  58. */
  59. public function __construct(array &$elements, array &$orderedKeys, array &$managedCursors)
  60. {
  61. $this->elements = &$elements;
  62. $this->orderedKeys = &$orderedKeys;
  63. $this->managedCursors = &$managedCursors;
  64. $this->cursorId = \count($managedCursors);
  65. $this->managedCursors[$this->cursorId] = &$this->cursor;
  66. }
  67. public function __sleep()
  68. {
  69. throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
  70. }
  71. public function __wakeup()
  72. {
  73. throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
  74. }
  75. /**
  76. * Removes the iterator's cursors from the managed cursors of the
  77. * corresponding {@link OrderedHashMap} instance.
  78. */
  79. public function __destruct()
  80. {
  81. // Use array_splice() instead of unset() to prevent holes in the
  82. // array indices, which would break the initialization of $cursorId
  83. array_splice($this->managedCursors, $this->cursorId, 1);
  84. }
  85. /**
  86. * {@inheritdoc}
  87. */
  88. public function current()
  89. {
  90. return $this->current;
  91. }
  92. /**
  93. * {@inheritdoc}
  94. */
  95. public function next()
  96. {
  97. ++$this->cursor;
  98. if (isset($this->orderedKeys[$this->cursor])) {
  99. $this->key = $this->orderedKeys[$this->cursor];
  100. $this->current = $this->elements[$this->key];
  101. } else {
  102. $this->key = null;
  103. $this->current = null;
  104. }
  105. }
  106. /**
  107. * {@inheritdoc}
  108. */
  109. public function key()
  110. {
  111. if (null === $this->key) {
  112. return null;
  113. }
  114. $array = [$this->key => null];
  115. return key($array);
  116. }
  117. /**
  118. * {@inheritdoc}
  119. */
  120. public function valid(): bool
  121. {
  122. return null !== $this->key;
  123. }
  124. /**
  125. * {@inheritdoc}
  126. */
  127. public function rewind()
  128. {
  129. $this->cursor = 0;
  130. if (isset($this->orderedKeys[0])) {
  131. $this->key = $this->orderedKeys[0];
  132. $this->current = $this->elements[$this->key];
  133. } else {
  134. $this->key = null;
  135. $this->current = null;
  136. }
  137. }
  138. }