helly Thu May 25 17:44:59 2006 UTC Added files: /php-src/ext/spl/examples dualiterator.inc recursivedualiterator.inc /php-src/ext/spl/examples/tests dualiterator_001.phpt Log: - Add DualIterator and RecursiveDualIterator to examples including a test
http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/examples/dualiterator.inc?view=markup&rev=1.1 Index: php-src/ext/spl/examples/dualiterator.inc +++ php-src/ext/spl/examples/dualiterator.inc <?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(); } } ?> http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/examples/recursivedualiterator.inc?view=markup&rev=1.1 Index: php-src/ext/spl/examples/recursivedualiterator.inc +++ php-src/ext/spl/examples/recursivedualiterator.inc <?php /** @file recursivedualiterator.inc * @ingroup Examples * @brief class RecursiveDualIterator * @author Marcus Boerger * @date 2003 - 2006 * * SPL - Standard PHP Library */ /** @ingroup Examples * @brief Synchronous iteration over two recursive iterators * @author Marcus Boerger * @version 1.0 */ class RecursiveDualIterator extends DualIterator implements RecursiveIterator { private $ref; /** construct iterator from two iterators * * @param lhs Left Hand Side Iterator * @param rhs Right Hand Side Iterator * @param flags iteration flags */ function __construct(RecursiveIterator $lhs, RecursiveIterator $rhs, $flags = 0x33 /*DualIterator::DEFAULT_FLAGS*/) { parent::__construct($lhs, $rhs, $flags); } /** @return whether both LHS and RHS have children */ function hasChildren() { return $this->getLHS()->hasChildren() && $this->getRHS()->hasChildren(); } /** @return new RecursiveDualIterator (late binding) for the two inner * iterators current children. */ function getChildren() { if (empty($this->ref)) { $this->ref = new ReflectionClass($this); } return $this->ref->newInstance( $this->getLHS()->current(), $this->getRHS()->current(), $this->flags); } /** @return whether both inner iterators are valid, have same hasChildren() * state and identical current and key values or both are non valid. */ function areIdentical() { return $this->getLHS()->hasChildren() === $this->getRHS()->hasChildren() && parent::areIdentical(); } /** @return whether both inner iterators are valid, have same hasChildren() * state and equal current and key values or both are invalid. */ function areEqual() { return $this->getLHS()->hasChildren() === $this->getRHS()->hasChildren() && parent::areEqual(); } } ?> http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/examples/tests/dualiterator_001.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/examples/tests/dualiterator_001.phpt +++ php-src/ext/spl/examples/tests/dualiterator_001.phpt --TEST-- SPL: DualIterator --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php function spl_examples_autoload($classname) { include(dirname(__FILE__) . '/../' . strtolower($classname) . '.inc'); } spl_autoload_register('spl_examples_autoload'); function test($a, $b, $identical = false) { var_dump(DualIterator::compareIterators( new RecursiveArrayIterator($a), new RecursiveArrayIterator($b), $identical)); } test(array(1,2,3), array(1,2,3)); test(array(1,2,3), array(1,2)); test(array(1,array(21,22),3), array(1,array(21,22),3)); test(array(1,array(21,22),3), array(1,array(21,22,23),3)); test(array(1,array(21,22),3), array(1,array(21,22,3))); test(array(1,array(21,22),3), array(1,array(21),array(22),3)); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(true) bool(false) bool(false) bool(false) ===DONE=== -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php