diff options
author | Marcus Boerger <helly@php.net> | 2006-07-09 10:24:32 +0000 |
---|---|---|
committer | Marcus Boerger <helly@php.net> | 2006-07-09 10:24:32 +0000 |
commit | d26b539c61a727a8aebac93ced7fac6b09b3a447 (patch) | |
tree | 0b4f8ba4153a650195ef26ec98df6d71648caaa0 | |
parent | 5fee10735fa87f66089effcab60ecf18d2aae283 (diff) | |
download | php-git-d26b539c61a727a8aebac93ced7fac6b09b3a447.tar.gz |
- MFH DualIterator
-rwxr-xr-x | ext/spl/examples/dualiterator.inc | 212 | ||||
-rwxr-xr-x | ext/spl/examples/recursivedualiterator.inc | 72 | ||||
-rwxr-xr-x | ext/spl/examples/tests/dualiterator_001.phpt | 47 |
3 files changed, 331 insertions, 0 deletions
diff --git a/ext/spl/examples/dualiterator.inc b/ext/spl/examples/dualiterator.inc new file mode 100755 index 0000000000..dae381f9c0 --- /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(); + } +} + +?> diff --git a/ext/spl/examples/recursivedualiterator.inc b/ext/spl/examples/recursivedualiterator.inc new file mode 100755 index 0000000000..702e0cd745 --- /dev/null +++ b/ext/spl/examples/recursivedualiterator.inc @@ -0,0 +1,72 @@ +<?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()->getChildren(), $this->getRHS()->getChildren(), $this->getFlags()); + } + + /** @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(); + } +} + +?> diff --git a/ext/spl/examples/tests/dualiterator_001.phpt b/ext/spl/examples/tests/dualiterator_001.phpt new file mode 100755 index 0000000000..5577c4dc18 --- /dev/null +++ b/ext/spl/examples/tests/dualiterator_001.phpt @@ -0,0 +1,47 @@ +--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)); +test(array(1,2,3), array(1,"2",3), false); +test(array(1,2,3), array(1,"2",3), true); +test(array(1,array(21,22),3), array(1,array(21,"22"),3), false); +test(array(1,array(21,22),3), array(1,array(21,"22"),3), true); + +?> +===DONE=== +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +===DONE=== |