diff options
author | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 19:39:21 -0400 |
---|---|---|
committer | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 19:39:21 -0400 |
commit | 6821b67124604da690c5e9276d5370d679c63ac8 (patch) | |
tree | befb4ca2520eb577950cef6cb76d10b914cbf67a /ext/spl/internal | |
parent | cd0b49c72aee33b3e44a9c589fcd93b9e1c7a64f (diff) | |
download | php-6821b67124604da690c5e9276d5370d679c63ac8.tar.gz |
Imported Upstream version 5.3.0RC1upstream/5.3.0_RC1upstream/5.3.0RC1
Diffstat (limited to 'ext/spl/internal')
-rwxr-xr-x | ext/spl/internal/multipleiterator.inc | 223 | ||||
-rwxr-xr-x | ext/spl/internal/recursivetreeiterator.inc | 132 | ||||
-rw-r--r-- | ext/spl/internal/spldoublylinkedlist.inc | 277 | ||||
-rwxr-xr-x | ext/spl/internal/splobjectstorage.inc | 96 | ||||
-rw-r--r-- | ext/spl/internal/splqueue.inc | 71 | ||||
-rw-r--r-- | ext/spl/internal/splstack.inc | 48 |
6 files changed, 834 insertions, 13 deletions
diff --git a/ext/spl/internal/multipleiterator.inc b/ext/spl/internal/multipleiterator.inc new file mode 100755 index 000000000..e977ca369 --- /dev/null +++ b/ext/spl/internal/multipleiterator.inc @@ -0,0 +1,223 @@ +<?php +/** @file multipleiterator.inc + * @ingroup SPL + * @brief class MultipleIterator + * @author Johannes Schlueter + * @author Marcus Boerger + * @date 2008 + * + * SPL - Standard PHP Library + */ + +/** @ingroup SPL + * @brief Iterator that iterates over several iterators one after the other + * @author Johannes Schlueter + * @author Marcus Boerger + * @version 1.0 + * @since PHP 5.3 + */ +class MultipleIterator implements Iterator +{ + /** Inner Iterators */ + private $iterators; + + /** Flags: const MIT_* */ + private $flags; + + /** do not require all sub iterators to be valid in iteration */ + const MIT_NEED_ANY = 0; + + /** require all sub iterators to be valid in iteration */ + const MIT_NEED_ALL = 1; + + /** keys are created from sub iterators position */ + const MIT_KEYS_NUMERIC = 0; + + /** keys are created from sub iterators associated infromation */ + const MIT_KEYS_ASSOC = 2; + + /** Construct a new empty MultipleIterator + * @param flags MIT_* flags + */ + public function __construct($flags = self::MIT_NEED_ALL|self::MIT_KEYS_NUMERIC) + { + $this->iterators = new SplObjectStorage(); + $this->flags = $flags; + } + + /** @return current flags MIT_* */ + public function getFlags() + { + return $this->flags; + } + + /** @param $flags new flags. */ + public function setFlags($flags) + { + $this->flags = $flags; + } + + /** @param $iter new Iterator to attach. + * @param $inf associative info forIteraotr, must be NULL, integer or string + * + * @throws IllegalValueException if a inf is none of NULL, integer or string + * @throws IllegalValueException if a inf is already an associated info + */ + public function attachIterator(Iterator $iter, $inf = NULL) + { + + if (!is_null($inf)) + { + if (!is_int($inf) && !is_string($inf)) + { + throw new IllegalValueException('Inf must be NULL, integer or string'); + } + foreach($this->iterators as $iter) + { + if ($inf == $this->iterators->getInfo()) + { + throw new IllegalValueException('Key duplication error'); + } + } + } + $this->iterators->attach($iter, $inf); + } + + /** @param $iter attached Iterator that should be detached. */ + public function detachIterator(Iterator $iter) + { + $this->iterators->detach($iter); + } + + /** @param $iter Iterator to check + * @return whether $iter is attached or not + */ + public function containsIterator(Iterator $iter) + { + return $this->iterator->contains($iter); + } + + /** @return number of attached Iterator instances. */ + public function countIterators() + { + return $this->iterators->count(); + } + + /** Rewind all attached Iterator instances. */ + public function rewind() + { + foreach($this->iterators as $iter) + { + $iter->rewind(); + } + } + + /** + * @return whether all or one sub iterator is valid depending on flags. + * In mode MIT_NEED_ALL we expect all sub iterators to be valid and + * return flase on the first non valid one. If that flag is not set we + * return true on the first valid sub iterator found. If no Iterator + * is attached, we always return false. + */ + public function valid() + { + if (!sizeof($this->iterators)) { + return false; + } + // The following code is an optimized version that executes as few + // valid() calls as necessary and that only checks the flags once. + $expect = $this->flags & self::MIT_NEED_ALL ? true : false; + foreach($this->iterators as $iter) + { + if ($expect != $iter->valid()) + { + return !$expect; + } + } + return $expect; + } + + /** Move all attached Iterator instances forward. That is invoke + * their next() method regardless of their state. + */ + public function next() + { + foreach($this->iterators as $iter) + { + $iter->next(); + } + } + + /** @return false if no sub Iterator is attached and an array of + * all registered Iterator instances current() result. + * @throws RuntimeException if mode MIT_NEED_ALL is set and at least one + * attached Iterator is not valid(). + * @throws IllegalValueException if a key is NULL and MIT_KEYS_ASSOC is set. + */ + public function current() + { + if (!sizeof($this->iterators)) + { + return false; + } + $retval = array(); + foreach($this->iterators as $iter) + { + if ($it->valid()) + { + if ($this->flags & self::MIT_KEYS_ASSOC) + { + $key = $this->iterators->getInfo(); + if (is_null($key)) + { + throw new IllegalValueException('Sub-Iterator is associated with NULL'); + } + $retval[$key] = $iter->current(); + } + else + { + $retval[] = $iter->current(); + } + } + else if ($this->flags & self::MIT_NEED_ALL) + { + throw new RuntimeException('Called current() with non valid sub iterator'); + } + else + { + $retval[] = NULL; + } + } + return $retval; + } + + /** @return false if no sub Iterator is attached and an array of + * all registered Iterator instances key() result. + * @throws LogicException if mode MIT_NEED_ALL is set and at least one + * attached Iterator is not valid(). + */ + public function key() + { + if (!sizeof($this->iterators)) + { + return false; + } + $retval = array(); + foreach($this->iterators as $iter) + { + if ($it->valid()) + { + $retval[] = $iter->key(); + } + else if ($this->flags & self::MIT_NEED_ALL) + { + throw new LogicException('Called key() with non valid sub iterator'); + } + else + { + $retval[] = NULL; + } + } + return $retval; + } +} diff --git a/ext/spl/internal/recursivetreeiterator.inc b/ext/spl/internal/recursivetreeiterator.inc new file mode 100755 index 000000000..b35718ee8 --- /dev/null +++ b/ext/spl/internal/recursivetreeiterator.inc @@ -0,0 +1,132 @@ +<?php + +/** @file recursivetreeiterator.inc + * @ingroup SPL + * @brief class RecursiveTreeIterator + * @author Marcus Boerger, Johannes Schlueter + * @date 2005 + * + * SPL - Standard PHP Library + */ + + +/** @ingroup SPL + * @brief RecursiveIteratorIterator to generate ASCII graphic trees for the + * entries in a RecursiveIterator + * @author Marcus Boerger, Johannes Schlueter + * @version 1.1 + * @since PHP 5.3 + */ +class RecursiveTreeIterator extends RecursiveIteratorIterator +{ + const BYPASS_CURRENT = 0x00000004; + const BYPASS_KEY = 0x00000008; + + private $rit_flags; + + /** + * @param it iterator to use as inner iterator + * @param rit_flags flags passed to RecursiveIteratoIterator (parent) + * @param cit_flags flags passed to RecursiveCachingIterator (for hasNext) + * @param mode mode passed to RecursiveIteratoIterator (parent) + */ + function __construct(RecursiveIterator $it, $rit_flags = self::BYPASS_KEY, $cit_flags = CachingIterator::CATCH_GET_CHILD, $mode = self::SELF_FIRST) + { + parent::__construct(new RecursiveCachingIterator($it, $cit_flags), $mode, $rit_flags); + $this->rit_flags = $rit_flags; + } + + private $prefix = array(0=>'', 1=>'| ', 2=>' ', 3=>'|-', 4=>'\-', 5=>''); + + /** Prefix used to start elements. */ + const PREFIX_LEFT = 0; + /** Prefix used if $level < depth and hasNext($level) == true. */ + const PREFIX_MID_HAS_NEXT = 1; + /** Prefix used if $level < depth and hasNext($level) == false. */ + const PREFIX_MID_LAST = 2; + /** Prefix used if $level == depth and hasNext($level) == true. */ + const PREFIX_END_HAS_NEXT = 3; + /** Prefix used if $level == depth and hasNext($level) == false. */ + const PREFIX_END_LAST = 4; + /** Prefix used right in front of the current element. */ + const PREFIX_RIGHT = 5; + + /** + * Set prefix part as used in getPrefix() and stored in $prefix. + * @param $part any PREFIX_* const. + * @param $value new prefix string for specified part. + * @throws OutOfRangeException if 0 > $part or $part > 5. + */ + function setPrefixPart($part, $value) + { + if (0 > $part || $part > 5) { + throw new OutOfRangeException(); + } + $this->prefix[$part] = (string)$value; + } + + /** @return string to place in front of current element + */ + function getPrefix() + { + $tree = ''; + for ($level = 0; $level < $this->getDepth(); $level++) + { + $tree .= $this->getSubIterator($level)->hasNext() ? $this->prefix[1] : $this->prefix[2]; + } + $tree .= $this->getSubIterator($level)->hasNext() ? $this->prefix[3] : $this->prefix[4]; + + return $this->prefix[0] . $tree . $this->prefix[5]; + } + + /** @return string presentation build for current element + */ + function getEntry() + { + return @(string)parent::current(); + } + + /** @return string to place after the current element + */ + function getPostfix() + { + return ''; + } + + /** @return the current element prefixed and postfixed + */ + function current() + { + if ($this->rit_flags & self::BYPASS_CURRENT) + { + return parent::current(); + } + else + { + return $this->getPrefix() . $this->getEntry() . $this->getPostfix(); + } + } + + /** @return the current key prefixed and postfixed + */ + function key() + { + if ($this->rit_flags & self::BYPASS_KEY) + { + return parent::key(); + } + else + { + return $this->getPrefix() . parent::key() . $this->getPostfix(); + } + } + + /** Aggregates the inner iterator + */ + function __call($func, $params) + { + return call_user_func_array(array($this->getSubIterator(), $func), $params); + } +} + +?>
\ No newline at end of file diff --git a/ext/spl/internal/spldoublylinkedlist.inc b/ext/spl/internal/spldoublylinkedlist.inc new file mode 100644 index 000000000..ba6443edc --- /dev/null +++ b/ext/spl/internal/spldoublylinkedlist.inc @@ -0,0 +1,277 @@ +<?php +/** @file spldoublylinkedlist.inc + * @ingroup SPL + * @brief class SplDoublyLinkedList + * @author Etienne Kneuss + * @date 2008 + * + * SPL - Standard PHP Library + */ + +/** @ingroup SPL + * @brief Doubly Linked List + * @since PHP 5.3 + * + * The SplDoublyLinkedList class provides the main functionalities of a + * doubly linked list (DLL). + * @note The following userland implementation of Iterator is a bit different + * from the internal one. Internally, iterators generated by nested + * foreachs are independent, while they share the same traverse pointer + * in userland. + */ +class SplDoublyLinkedList implements Iterator, ArrayAccess, Countable +{ + protected $_llist = array(); + protected $_it_mode = 0; + protected $_it_pos = 0; + + /** Iterator mode + * @see setIteratorMode + */ + const IT_MODE_LIFO = 0x00000002; + + /** Iterator mode + * @see setIteratorMode + */ + const IT_MODE_FIFO = 0x00000000; + + /** Iterator mode + * @see setIteratorMode + */ + const IT_MODE_KEEP = 0x00000000; + + /** Iterator mode + * @see setIteratorMode + */ + const IT_MODE_DELETE = 0x00000001; + + /** @return the element popped from the end of the DLL. + * @throw RuntimeException If the datastructure is empty. + */ + public function pop() + { + if (count($this->_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); + } + } +} + +?> diff --git a/ext/spl/internal/splobjectstorage.inc b/ext/spl/internal/splobjectstorage.inc index a6adafb67..9d06a05a6 100755 --- a/ext/spl/internal/splobjectstorage.inc +++ b/ext/spl/internal/splobjectstorage.inc @@ -4,7 +4,7 @@ * @ingroup SPL * @brief class SplObjectStorage * @author Marcus Boerger - * @date 2003 - 2005 + * @date 2003 - 2008 * * SPL - Standard PHP Library */ @@ -12,7 +12,7 @@ /**
* @brief Object storage
* @author Marcus Boerger
- * @version 1.0
+ * @version 1.1
* @since PHP 5.1.2
*
* This container allows to store objects uniquly without the need to compare
@@ -20,7 +20,7 @@ * here therefore has a complexity of O(n) while the actual implementation has
* complexity O(1).
*/
-class SplObjectStorage implements Iterator, Countable
+class SplObjectStorage implements Iterator, Countable, ArrayAccess
{
private $storage = array();
private $index = 0;
@@ -50,7 +50,27 @@ class SplObjectStorage implements Iterator, Countable */
function current()
{
- return current($this->storage);
+ $element = current($this->storage);
+ return $element ? $element[0] : NULL
+ }
+
+ /** @return get current object's associated information
+ * @since 5.3.0
+ */
+ function getInfo()
+ {
+ $element = current($this->storage);
+ return $element ? $element[1] : NULL
+ }
+
+ /** @return set current object's associated information
+ * @since 5.3.0
+ */
+ function setInfo($inf = NULL)
+ {
+ if ($this->valid()) {
+ $this->storage[$this->index][1] = $inf;
+ }
}
/** Forward to next element
@@ -68,16 +88,16 @@ class SplObjectStorage implements Iterator, Countable return count($this->storage);
}
- /** @param obj object to look for
+ /** @param $obj object to look for
* @return whether $obj is contained in storage
- */
+ */
function contains($obj)
{
if (is_object($obj))
{
- foreach($this->storage as $object)
+ foreach($this->storage as $element)
{
- if ($object === $obj)
+ if ($object === $element[0])
{
return true;
}
@@ -86,13 +106,15 @@ class SplObjectStorage implements Iterator, Countable return false;
}
- /** @param $obj new object to attach to storage if not yet contained
+ /** @param $obj new object to attach to storage or object whose
+ * associative information is to be replaced
+ * @param $inf associative information stored along the object
*/
- function attach($obj)
+ function attach($obj, $inf = NULL)
{
if (is_object($obj) && !$this->contains($obj))
{
- $this->storage[] = $obj;
+ $this->storage[] = array($obj, $inf);
}
}
@@ -102,9 +124,9 @@ class SplObjectStorage implements Iterator, Countable {
if (is_object($obj))
{
- foreach($this->storage as $idx => $object)
+ foreach($this->storage as $idx => $element)
{
- if ($object === $obj)
+ if ($object === $element[0])
{
unset($this->storage[$idx]);
$this->rewind();
@@ -113,6 +135,54 @@ class SplObjectStorage implements Iterator, Countable }
}
}
+
+ /** @param $obj new object to attach to storage or object whose
+ * associative information is to be replaced
+ * @param $inf associative information stored along the object
+ * @since 5.3.0
+ */
+ function offsetSet($obj, $inf)
+ {
+ $this->attach($obj, $inf);
+ }
+
+ /** @param $obj Exising object to look for
+ * @return associative information stored with object
+ * @throw UnexpectedValueException if Object $obj is not contained in
+ * storage
+ * @since 5.3.0
+ */
+ function offsetGet($obj)
+ {
+ if (is_object($obj))
+ {
+ foreach($this->storage as $idx => $element)
+ {
+ if ($object === $element[0])
+ {
+ return $element[1];
+ }
+ }
+ }
+ throw new UnexpectedValueException('Object not found');
+ }
+
+ /** @param $obj Exising object to look for
+ * @return associative information stored with object
+ * @since 5.3.0
+ */
+ function offsetUnset($obj)
+ {
+ $this->detach($obj);
+ }
+
+ /** @param $obj object to look for
+ * @return whether $obj is contained in storage
+ */
+ function offsetEsists($obj)
+ {
+ return $this->contains($obj);
+ }
}
?> diff --git a/ext/spl/internal/splqueue.inc b/ext/spl/internal/splqueue.inc new file mode 100644 index 000000000..f795eabbc --- /dev/null +++ b/ext/spl/internal/splqueue.inc @@ -0,0 +1,71 @@ +<?php + +/** @file splqueue.inc + * @ingroup SPL + * @brief class SplQueue + * @author Etienne Kneuss + * @date 2008 + * + * SPL - Standard PHP Library + */ + +/** @ingroup SPL + * @brief Implementation of a Queue through a DoublyLinkedList. As SplQueue + * extends SplDoublyLinkedList, unshift() and pop() are still available + * even though they don't make much sense for a queue. For convenience, + * two aliases are available: + * - enqueue() is an alias of push() + * - dequeue() is an alias of shift() + * + * @since PHP 5.3 + * + * The SplQueue class provides the main functionalities of a + * queue implemented using a doubly linked list (DLL). + */ +class SplQueue extends SplDoublyLinkedList +{ + protected $_it_mode = parent::IT_MODE_FIFO; + + /** Changes the iteration mode. There are two orthogonal sets of modes that + * can be set: + * + * - 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_LIFO | SplDoublyLnkedList::IT_MODE_KEEP + * + * @note The iteration's direction is not modifiable for queue instances + * @param $mode New mode of iteration + * @throw RuntimeException If the new mode affects the iteration's direction. + */ + public function setIteratorMode($mode) + { + if ($mode & parent::IT_MODE_LIFO === parent::IT_MODE_LIFO) { + throw new RuntimeException("Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen"); + } + + $this->_it_mode = $mode; + } + + /** @return the first element of the queue. + * @note dequeue is an alias of push() + * @see splDoublyLinkedList::push() + */ + public function dequeue() + { + return parent::shift(); + } + + /** Pushes an element at the end of the queue. + * @param $data variable to add to the queue. + * @note enqueue is an alias of shift() + * @see splDoublyLinkedList::shift() + */ + public function enqueue($data) + { + return parent::push($data); + } +} + +?> diff --git a/ext/spl/internal/splstack.inc b/ext/spl/internal/splstack.inc new file mode 100644 index 000000000..4d3c62bab --- /dev/null +++ b/ext/spl/internal/splstack.inc @@ -0,0 +1,48 @@ +<?php + +/** @file splstack.inc + * @ingroup SPL + * @brief class SplStack + * @author Etienne Kneuss + * @date 2008 + * + * SPL - Standard PHP Library + */ + +/** @ingroup SPL + * @brief Implementation of a stack through a DoublyLinkedList. As SplStack + * extends SplDoublyLinkedList, shift() and unshift() are still available even + * though they don't make much sense for a stack. + * @since PHP 5.3 + * + * The SplStack class provides the main functionalities of a + * stack implemented using a doubly linked list (DLL). + */ +class SplStack extends SplDoublyLinkedList +{ + protected $_it_mode = parent::IT_MODE_LIFO; + + /** Changes the iteration mode. There are two orthogonal sets of modes that + * can be set: + * + * - 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_LIFO | SplDoublyLnkedList::IT_MODE_KEEP + * + * @note The iteration's direction is not modifiable for stack instances + * @param $mode New mode of iteration + * @throw RuntimeException If the new mode affects the iteration's direction. + */ + public function setIteratorMode($mode) + { + if ($mode & parent::IT_MODE_LIFO !== parent::IT_MODE_LIFO) { + throw new RuntimeException("Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen"); + } + + $this->_it_mode = $mode; + } +} + +?> |