diff options
| author | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:36:21 -0400 |
|---|---|---|
| committer | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:36:21 -0400 |
| commit | d29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (patch) | |
| tree | b38e2e5c6974b9a15f103e5cf884cba9fff90ef4 /ext/spl/examples/dualiterator.inc | |
| parent | a88a88d0986a4a32288c102cdbfebd78d7e91d99 (diff) | |
| download | php-upstream/5.2.0.tar.gz | |
Imported Upstream version 5.2.0upstream/5.2.0
Diffstat (limited to 'ext/spl/examples/dualiterator.inc')
| -rwxr-xr-x | ext/spl/examples/dualiterator.inc | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/ext/spl/examples/dualiterator.inc b/ext/spl/examples/dualiterator.inc new file mode 100755 index 000000000..544034856 --- /dev/null +++ b/ext/spl/examples/dualiterator.inc @@ -0,0 +1,212 @@ +<?php + +/** @file dualiterator.inc + * @ingroup Examples + * @brief class DualIterator + * @author Marcus Boerger + * @date 2003 - 2006 + * + * SPL - Standard PHP Library + */ + +/** @ingroup Examples + * @brief Synchronous iteration over two iterators + * @author Marcus Boerger + * @version 1.1 + */ +class DualIterator implements Iterator +{ + const CURRENT_LHS = 0x01; + const CURRENT_RHS = 0x02; + const CURRENT_ARRAY = 0x03; + const CURRENT_0 = 0x00; + + const KEY_LHS = 0x10; + const KEY_RHS = 0x20; + const KEY_ARRAY = 0x30; + const KEY_0 = 0x00; + + const DEFAULT_FLAGS = 0x33; + + private $lhs; + private $rhs; + private $flags; + + /** construct iterator from two iterators + * + * @param lhs Left Hand Side Iterator + * @param rhs Right Hand Side Iterator + * @param flags iteration flags + */ + function __construct(Iterator $lhs, Iterator $rhs, + $flags = 0x33 /*DualIterator::DEFAULT_FLAGS*/) + { + $this->lhs = $lhs; + $this->rhs = $rhs; + $this->flags = $flags; + } + + /** @return Left Hand Side Iterator + */ + function getLHS() + { + return $this->lhs; + } + + /** @return Right Hand Side Iterator + */ + function getRHS() + { + return $this->rhs; + } + + /** @param flags new flags + */ + function setFlags($flags) + { + $this->flags = $flags; + } + + /** @return current flags + */ + function getFlags() + { + return $this->flags; + } + + /** rewind both inner iterators + */ + function rewind() + { + $this->lhs->rewind(); + $this->rhs->rewind(); + } + + /** @return whether both inner iterators are valid + */ + function valid() + { + return $this->lhs->valid() && $this->rhs->valid(); + } + + /** @return current value depending on CURRENT_* flags + */ + function current() + { + switch($this->flags & 0x0F) + { + default: + case self::CURRENT_ARRAY: + return array($this->lhs->current(), $this->rhs->current()); + case self::CURRENT_LHS: + return $this->lhs->current(); + case self::CURRENT_RHS: + return $this->rhs->current(); + case self::CURRENT_0: + return NULL; + } + } + + /** @return current value depending on KEY_* flags + */ + function key() + { + switch($this->flags & 0xF0) + { + default: + case self::CURRENT_ARRAY: + return array($this->lhs->key(), $this->rhs->key()); + case self::CURRENT_LHS: + return $this->lhs->key(); + case self::CURRENT_RHS: + return $this->rhs->key(); + case self::CURRENT_0: + return NULL; + } + } + + /** move both inner iterators forward + */ + function next() + { + $this->lhs->next(); + $this->rhs->next(); + } + + /** @return whether both inner iterators are valid and have identical + * current and key values or both are non valid. + */ + function areIdentical() + { + return $this->valid() + ? $this->lhs->current() === $this->rhs->current() + && $this->lhs->key() === $this->rhs->key() + : $this->lhs->valid() == $this->rhs->valid(); + } + + /** @return whether both inner iterators are valid and have equal current + * and key values or both are non valid. + */ + function areEqual() + { + return $this->valid() + ? $this->lhs->current() == $this->rhs->current() + && $this->lhs->key() == $this->rhs->key() + : $this->lhs->valid() == $this->rhs->valid(); + } + + /** Compare two iterators + * + * @param lhs Left Hand Side Iterator + * @param rhs Right Hand Side Iterator + * @param identical whether to use areEqual() or areIdentical() + * @return whether both iterators are equal/identical + * + * @note If one implements RecursiveIterator the other must do as well. + * And if both do then a recursive comparison is being used. + */ + static function compareIterators(Iterator $lhs, Iterator $rhs, + $identical = false) + { + if ($lhs instanceof RecursiveIterator) + { + if ($rhs instanceof RecursiveIterator) + { + $it = new RecursiveDualIterator($lhs, $rhs, + self::CURRENT_0 | self::KEY_0); + } + else + { + return false; + } + } + else + { + $it = new DualIterator($lhs, $rhs, self::CURRENT_0 | self::KEY_0); + } + + if ($identical) + { + foreach(new RecursiveIteratorIterator($it) as $n) + { + if (!$it->areIdentical()) + { + return false; + } + } + } + else + { + foreach($it as $n) + { + if (!$it->areEqual()) + { + return false; + } + } + } + return $identical ? $it->areIdentical() : $it->areEqual(); + } +} + +?> |
