<?php
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_0 = 0x00;
const DEFAULT_FLAGS = 0x13;
private $lhs;
private $rhs;
private $flags;
function __construct(Iterator $lhs, Iterator $rhs,
$flags = 0x13 )
{
$this->lhs = $lhs;
$this->rhs = $rhs;
$this->flags = $flags;
}
function getLHS()
{
return $this->lhs;
}
function getRHS()
{
return $this->rhs;
}
function setFlags($flags)
{
$this->flags = $flags;
}
function getFlags()
{
return $this->flags;
}
function rewind()
{
$this->lhs->rewind();
$this->rhs->rewind();
}
function valid()
{
return $this->lhs->valid() && $this->rhs->valid();
}
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;
}
}
function key()
{
switch($this->flags & 0xF0)
{
default:
case self::KEY_LHS:
return $this->lhs->key();
case self::KEY_RHS:
return $this->rhs->key();
case self::KEY_0:
return NULL;
}
}
function next()
{
$this->lhs->next();
$this->rhs->next();
}
function areIdentical()
{
return $this->valid()
? $this->lhs->current() === $this->rhs->current()
&& $this->lhs->key() === $this->rhs->key()
: $this->lhs->valid() == $this->rhs->valid();
}
function areEqual()
{
return $this->valid()
? $this->lhs->current() == $this->rhs->current()
&& $this->lhs->key() == $this->rhs->key()
: $this->lhs->valid() == $this->rhs->valid();
}
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);
$it = new RecursiveCompareDualIterator($it);
}
else
{
return false;
}
}
else
{
$it = new DualIterator($lhs, $rhs, self::CURRENT_0 | self::KEY_0);
}
if ($identical)
{
foreach($it as $n)
{
if (!$it->areIdentical())
{
return false;
}
}
}
else
{
foreach($it as $n)
{
if (!$it->areEqual())
{
return false;
}
}
}
return $identical ? $it->areIdentical() : $it->areEqual();
}
}
?>