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