cvs: php-src /ext/spl spl_dllist.c /ext/spl/tests dllist_007.phpt

From: Date: Sat, 26 Jan 2008 18:06:51 +0000
Subject: cvs: php-src /ext/spl spl_dllist.c /ext/spl/tests dllist_007.phpt
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-48008@lists.php.net to get a copy of this message
colder Sat Jan 26 18:06:51 2008 UTC Added files: /php-src/ext/spl/tests dllist_007.phpt Modified files: /php-src/ext/spl spl_dllist.c Log: Iterator implementation for SplDoublyLinkedList, SplStack, SplQueue http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_dllist.c?r1=1.5&r2=1.6&diff_format=u Index: php-src/ext/spl/spl_dllist.c diff -u php-src/ext/spl/spl_dllist.c:1.5 php-src/ext/spl/spl_dllist.c:1.6 --- php-src/ext/spl/spl_dllist.c:1.5 Tue Jan 22 19:51:11 2008 +++ php-src/ext/spl/spl_dllist.c Sat Jan 26 18:06:51 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_dllist.c,v 1.5 2008/01/22 19:51:11 colder Exp $ */ +/* $Id: spl_dllist.c,v 1.6 2008/01/26 18:06:51 colder Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -877,6 +877,67 @@ } /* }}} */ +static void spl_dllist_it_helper_rewind(spl_ptr_llist_element **traverse_pointer_ptr, int *traverse_position_ptr, spl_ptr_llist *llist, int flags TSRMLS_DC) /* {{{ */ +{ + SPL_LLIST_CHECK_DELREF(*traverse_pointer_ptr); + + if (flags & SPL_DLLIST_IT_LIFO) { + *traverse_position_ptr = llist->count-1; + *traverse_pointer_ptr = llist->tail; + } else { + *traverse_position_ptr = 0; + *traverse_pointer_ptr = llist->head; + } + + SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr); +} +/* }}} */ + +static void spl_dllist_it_helper_move_forward(spl_ptr_llist_element **traverse_pointer_ptr, int *traverse_position_ptr, spl_ptr_llist *llist, int flags TSRMLS_DC) /* {{{ */ +{ + if (*traverse_pointer_ptr) { + spl_ptr_llist_element *old = *traverse_pointer_ptr; + + if (flags & SPL_DLLIST_IT_LIFO) { + *traverse_pointer_ptr = old->prev; + (*traverse_position_ptr)--; + + if (flags & SPL_DLLIST_IT_DELETE) { + zval *prev = (zval *)spl_ptr_llist_pop(llist); + + if (prev) { + zval_ptr_dtor((zval **)&prev); + } + } + } else { + *traverse_pointer_ptr = old->next; + (*traverse_position_ptr)++; + + if (flags & SPL_DLLIST_IT_DELETE) { + zval *prev = (zval *)spl_ptr_llist_shift(llist); + + if (prev) { + zval_ptr_dtor((zval **)&prev); + } + } + } + + SPL_LLIST_DELREF(old); + SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr); + } +} +/* }}} */ + +static void spl_dllist_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ +{ + spl_dllist_it *iterator = (spl_dllist_it *)iter; + spl_dllist_object *object = iterator->object; + spl_ptr_llist *llist = object->llist; + + spl_dllist_it_helper_rewind(&iterator->traverse_pointer, &iterator->traverse_position, llist, object->flags TSRMLS_CC); +} +/* }}} */ + static int spl_dllist_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ { spl_dllist_it *iterator = (spl_dllist_it *)iter; @@ -915,56 +976,63 @@ zend_user_it_invalidate_current(iter TSRMLS_CC); - if (iterator->traverse_pointer) { - spl_ptr_llist_element *old = iterator->traverse_pointer; + spl_dllist_it_helper_move_forward(&iterator->traverse_pointer, &iterator->traverse_position, object->llist, object->flags TSRMLS_CC); +} +/* }}} */ - if (iterator->flags & SPL_DLLIST_IT_LIFO) { - iterator->traverse_pointer = old->prev; - iterator->traverse_position--; +/* {{{ proto int SplDoublyLinkedList::key() U + Return current array key */ +SPL_METHOD(SplDoublyLinkedList, key) +{ + spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (iterator->flags & SPL_DLLIST_IT_DELETE) { - zval *prev = (zval *)spl_ptr_llist_pop(object->llist); + RETURN_LONG(intern->traverse_position); +} +/* }}} */ - if (prev) { - zval_ptr_dtor((zval **)&prev); - } - } - } else { - iterator->traverse_pointer = old->next; - iterator->traverse_position++; +/* {{{ proto void SplDoublyLinkedList::next() U + Move to next entry */ +SPL_METHOD(SplDoublyLinkedList, next) +{ + spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (iterator->flags & SPL_DLLIST_IT_DELETE) { - zval *prev = (zval *)spl_ptr_llist_shift(object->llist); + spl_dllist_it_helper_move_forward(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags TSRMLS_CC); +} +/* }}} */ - if (prev) { - zval_ptr_dtor((zval **)&prev); - } - } - } +/* {{{ proto bool SplDoublyLinkedList::valid() U + Check whether the datastructure contains more entries */ +SPL_METHOD(SplDoublyLinkedList, valid) +{ + spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - SPL_LLIST_DELREF(old); - SPL_LLIST_CHECK_ADDREF(iterator->traverse_pointer); - } + RETURN_BOOL(intern->traverse_pointer != NULL); } /* }}} */ -static void spl_dllist_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ +/* {{{ proto void SplDoublyLinkedList::rewind() U + Rewind the datastructure back to the start */ +SPL_METHOD(SplDoublyLinkedList, rewind) { - spl_dllist_it *iterator = (spl_dllist_it *)iter; - spl_dllist_object *object = iterator->object; - spl_ptr_llist *llist = object->llist; + spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer); + spl_dllist_it_helper_rewind(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags TSRMLS_CC); +} +/* }}} */ - if (iterator->flags & SPL_DLLIST_IT_LIFO) { - iterator->traverse_position = llist->count-1; - iterator->traverse_pointer = llist->tail; +/* {{{ proto mixed|NULL SplDoublyLinkedList::current() U + Return current datastructure entry */ +SPL_METHOD(SplDoublyLinkedList, current) +{ + spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_ptr_llist_element *element = intern->traverse_pointer; + + if (element == NULL || element->data == NULL) { + RETURN_NULL(); } else { - iterator->traverse_position = 0; - iterator->traverse_pointer = llist->head; + zval *data = (zval *)element->data; + RETURN_ZVAL(data, 1, 0); } - - SPL_LLIST_CHECK_ADDREF(iterator->traverse_pointer); } /* }}} */ @@ -1050,6 +1118,11 @@ SPL_ME(SplDoublyLinkedList, offsetGet, arginfo_dllist_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, offsetSet, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, offsetUnset, arginfo_dllist_offsetGet, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, rewind, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, current, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, key, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, next, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, valid, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; /* }}} */ @@ -1067,6 +1140,7 @@ REGISTER_SPL_CLASS_CONST_LONG(SplDoublyLinkedList, "IT_MODE_DELETE",SPL_DLLIST_IT_DELETE); REGISTER_SPL_CLASS_CONST_LONG(SplDoublyLinkedList, "IT_MODE_KEEP", 0); + REGISTER_SPL_IMPLEMENTS(SplDoublyLinkedList, Iterator); REGISTER_SPL_IMPLEMENTS(SplDoublyLinkedList, Countable); REGISTER_SPL_IMPLEMENTS(SplDoublyLinkedList, ArrayAccess); http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/dllist_007.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/dllist_007.phpt +++ php-src/ext/spl/tests/dllist_007.phpt --TEST-- SPL: DoublyLinkedList: Iterator --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php $a = new SplDoublyLinkedList(); $a->push(1); $a->push(2); $a->push(3); $a->rewind(); while ($a->valid()) { var_dump($a->current(), $a->next()); } ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- int(1) NULL int(2) NULL int(3) NULL ===DONE===

« previous php.cvs (#48008) next »