+++ /dev/null
-<?php
-
-/** @file infiniteiterator.inc
- * @ingroup Examples
- * @brief class InfiniteIterator
- * @author Marcus Boerger
- * @date 2003 - 2004
- *
- * SPL - Standard PHP Library
- */
-
-/** @ingroup Examples
- * @brief An infinite Iterator
- * @author Marcus Boerger
- * @version 1.0
- *
- * This Iterator takes another Iterator and infinitvely iterates it by
- * rewinding it when its end is reached.
- *
- * \note Even an InfiniteIterator stops if its inner Iterator is empty.
- *
- \verbatim
- $it = new ArrayIterator(array(1,2,3));
- $infinite = new InfiniteIterator($it);
- $limit = new LimitIterator($infinite, 0, 5);
- foreach($limit as $val=>$key)
- {
- echo "$val=>$key\n";
- }
- \endverbatim
- */
-class InfiniteIterator implements OuterIterator
-{
- /** @internal
- * The inner Iterator. */
- private $it;
-
- /** Construct from another Iterator.
- * @param $it the inner Iterator.
- */
- function __construct(Iterator $it)
- {
- $this->it = $it;
- }
-
- /** @return the inner iterator
- */
- function getInnerIterator()
- {
- return $this->it;
- }
-
- /** Rewind the inner iterator.
- * @return void
- */
- function rewind()
- {
- $this->getInnerIterator()->rewind();
- }
-
- /** @return whether the current element is valid
- */
- function valid()
- {
- return $this->getInnerIterator()->valid();
- }
-
- /** @return the current value
- */
- function current()
- {
- return $this->getInnerIterator()->current();
- }
-
- /** @return the current key
- */
- function key()
- {
- return $this->getInnerIterator()->key();
- }
-
- /** Move the inner Iterator forward to its next element or rewind it.
- * @return void
- */
- function next()
- {
- $this->getInnerIterator()->next();
- if (!$this->getInnerIterator()->valid())
- {
- $this->getInnerIterator()->rewind();
- }
- }
-
- /** Aggregates the inner iterator
- */
- function __call($func, $params)
- {
- return call_user_func_array(array($this->getInnerIterator(), $func), $params);
- }
-}
-
-?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/** @file infiniteiterator.inc
+ * @ingroup SPL
+ * @brief class InfiniteIterator
+ * @author Marcus Boerger
+ * @date 2003 - 2004
+ *
+ * SPL - Standard PHP Library
+ */
+
+/** @ingroup Examples
+ * @brief An infinite Iterator
+ * @author Marcus Boerger
+ * @version 1.1
+ *
+ * This Iterator takes another Iterator and infinitvely iterates it by
+ * rewinding it when its end is reached.
+ *
+ * \note Even an InfiniteIterator stops if its inner Iterator is empty.
+ *
+ \verbatim
+ $it = new ArrayIterator(array(1,2,3));
+ $infinite = new InfiniteIterator($it);
+ $limit = new LimitIterator($infinite, 0, 5);
+ foreach($limit as $val=>$key)
+ {
+ echo "$val=>$key\n";
+ }
+ \endverbatim
+ */
+class InfiniteIterator extends IteratorIterator
+{
+ /** Move the inner Iterator forward to its next element or rewind it.
+ * @return void
+ */
+ function next()
+ {
+ $this->getInnerIterator()->next();
+ if (!$this->getInnerIterator()->valid())
+ {
+ $this->getInnerIterator()->rewind();
+ }
+ }
+}
+
+?>
\ No newline at end of file
SPL_ADD_CLASS(CachingRecursiveIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(FilterIterator, z_list, sub, allow, ce_flags); \
+ SPL_ADD_CLASS(InfiniteIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(IteratorIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(LimitIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(NoRewindIterator, z_list, sub, allow, ce_flags); \
zend_class_entry *spl_ce_OuterIterator;
zend_class_entry *spl_ce_IteratorIterator;
zend_class_entry *spl_ce_NoRewindIterator;
+zend_class_entry *spl_ce_InfiniteIterator;
function_entry spl_funcs_RecursiveIterator[] = {
SPL_ABSTRACT_ME(RecursiveIterator, hasChildren, NULL)
{NULL, NULL, NULL}
};
-zend_object_iterator_funcs spl_norewind_it_iterator_funcs;
+/* {{{ proto InfiniteIterator::__construct(Iterator it)
+ Create an iterator from another iterator */
+SPL_METHOD(InfiniteIterator, __construct)
+{
+ spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_iterator, DIT_InfiniteIterator);
+} /* }}} */
+
+/* {{{ proto InfiniteIterator::next()
+ Prevent a call to inner iterators rewind() (internally the current data will be fetched if valid()) */
+SPL_METHOD(InfiniteIterator, next)
+{
+ spl_dual_it_object *intern;
+
+ intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ spl_dual_it_next(intern, 1 TSRMLS_CC);
+ if (spl_dual_it_valid(intern TSRMLS_CC) == SUCCESS) {
+ spl_dual_it_fetch(intern, 0 TSRMLS_CC);
+ } else {
+ spl_dual_it_rewind(intern TSRMLS_CC);
+ if (spl_dual_it_valid(intern TSRMLS_CC) == SUCCESS) {
+ spl_dual_it_fetch(intern, 0 TSRMLS_CC);
+ }
+ }
+
+} /* }}} */
+
+static zend_function_entry spl_funcs_InfiniteIterator[] = {
+ SPL_ME(InfiniteIterator, __construct, arginfo_norewind_it___construct, ZEND_ACC_PUBLIC)
+ SPL_ME(InfiniteIterator, next, NULL, ZEND_ACC_PUBLIC)
+};
/* {{{ array iterator_to_array(IteratorAggregate it)
Copy the iterator into an array */
REGISTER_SPL_IMPLEMENTS(IteratorIterator, OuterIterator);
REGISTER_SPL_IMPLEMENTS(NoRewindIterator, OuterIterator);
+ REGISTER_SPL_SUB_CLASS_EX(InfiniteIterator, IteratorIterator, spl_dual_it_new, spl_funcs_InfiniteIterator);
+
return SUCCESS;
}
/* }}} */
extern zend_class_entry *spl_ce_OuterIterator;
extern zend_class_entry *spl_ce_IteratorIterator;
extern zend_class_entry *spl_ce_NoRewindIterator;
+extern zend_class_entry *spl_ce_InfiniteIterator;
PHP_MINIT_FUNCTION(spl_iterators);
DIT_CachingRecursiveIterator,
DIT_IteratorIterator,
DIT_NoRewindIterator,
+ DIT_InfiniteIterator,
} dual_it_type;
enum {
--- /dev/null
+--TEST--
+SPL: InfiniteIterator
+--SKIPIF--
+<?php if (!extension_loaded("spl")) print "skip"; ?>
+--FILE--
+<?php
+
+class ArrayIteratorEx extends ArrayIterator
+{
+ function rewind()
+ {
+ echo __METHOD__ . "\n";
+ parent::rewind();
+ }
+ function valid()
+ {
+ echo __METHOD__ . "\n";
+ return parent::valid();
+ }
+ function current()
+ {
+ echo __METHOD__ . "\n";
+ return parent::current();
+ }
+ function key()
+ {
+ echo __METHOD__ . "\n";
+ return parent::key();
+ }
+ function next()
+ {
+ echo __METHOD__ . "\n";
+ parent::next();
+ }
+}
+
+$it = new InfiniteIterator(new ArrayIteratorEx(range(0,2)));
+
+$pos =0;
+
+foreach ($it as $v) {
+ var_dump($v);
+ if ($pos++ > 5) {
+ break;
+ }
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+ArrayIteratorEx::rewind
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+int(0)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+int(1)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+int(2)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::rewind
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+int(0)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+int(1)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+int(2)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::rewind
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+int(0)
+===DONE===