diff --git a/src/collections_me.c b/src/collections_me.c index 571eff4..e7f3ed0 100644 --- a/src/collections_me.c +++ b/src/collections_me.c @@ -183,6 +183,7 @@ const zend_function_entry collection_methods[] = { PHP_ME(Collection, minusValuesAssign, elements_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, none, predicate_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, onEach, action_arginfo, ZEND_ACC_PUBLIC) + PHP_ME(Collection, packed, NULL, ZEND_ACC_PUBLIC) PHP_ME(Collection, partition, predicate_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, plus, elements_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, plusAssign, elements_arginfo, ZEND_ACC_PUBLIC) diff --git a/src/collections_methods.c b/src/collections_methods.c index 332a200..d69d23a 100644 --- a/src/collections_methods.c +++ b/src/collections_methods.c @@ -1217,6 +1217,12 @@ PHP_METHOD(Collection, onEach) RETVAL_ZVAL(getThis(), 1, 0); } +PHP_METHOD(Collection, packed) +{ + zend_array* current = COLLECTION_FETCH_CURRENT(); + RETVAL_BOOL(HT_IS_PACKED(current)); +} + PHP_METHOD(Collection, partition) { zend_fcall_info fci; @@ -1301,27 +1307,25 @@ PHP_METHOD(Collection, reduce) RETURN_NULL(); } INIT_FCI(3); - zval acc; Bucket* bucket = current->arData; Bucket* end = bucket + current->nNumUsed; for (; bucket < end; ++bucket) { if (Z_ISUNDEF(bucket->val)) continue; - ZVAL_COPY_VALUE(&acc, &(bucket++)->val); + ZVAL_COPY(&retval, &(bucket++)->val); break; } for (; bucket < end; ++bucket) { if (Z_ISUNDEF(bucket->val)) continue; - ZVAL_COPY_VALUE(¶ms[0], &acc); + ZVAL_COPY_VALUE(¶ms[0], &retval); ZVAL_COPY_VALUE(¶ms[1], &bucket->val); if (bucket->key) ZVAL_STR(¶ms[2], bucket->key); else ZVAL_LONG(¶ms[2], bucket->h); zend_call_function(&fci, &fcc); - zval_ptr_dtor(&acc); - ZVAL_COPY_VALUE(&acc, &retval); + zval_ptr_dtor(¶ms[0]); } RETVAL_ZVAL(&retval, 0, 0); } @@ -1339,27 +1343,25 @@ PHP_METHOD(Collection, reduceRight) RETURN_NULL(); } INIT_FCI(3); - zval acc; Bucket* start = current->arData; Bucket* bucket = start + current->nNumUsed - 1; for (; bucket >= start; --bucket) { if (Z_ISUNDEF(bucket->val)) continue; - ZVAL_COPY_VALUE(&acc, &(bucket--)->val); + ZVAL_COPY(&retval, &(bucket--)->val); break; } for (; bucket >= start; --bucket) { if (Z_ISUNDEF(bucket->val)) continue; - ZVAL_COPY_VALUE(¶ms[0], &acc); + ZVAL_COPY_VALUE(¶ms[0], &retval); ZVAL_COPY_VALUE(¶ms[1], &bucket->val); if (bucket->key) ZVAL_STR(¶ms[2], bucket->key); else ZVAL_LONG(¶ms[2], bucket->h); zend_call_function(&fci, &fcc); - zval_ptr_dtor(&acc); - ZVAL_COPY_VALUE(&acc, &retval); + zval_ptr_dtor(¶ms[0]); } RETVAL_ZVAL(&retval, 0, 0); } diff --git a/src/php_collections_me.h b/src/php_collections_me.h index 90e1f39..287d915 100644 --- a/src/php_collections_me.h +++ b/src/php_collections_me.h @@ -69,6 +69,7 @@ PHP_METHOD(Collection, minusValues); PHP_METHOD(Collection, minusValuesAssign); PHP_METHOD(Collection, none); PHP_METHOD(Collection, onEach); +PHP_METHOD(Collection, packed); PHP_METHOD(Collection, partition); PHP_METHOD(Collection, plus); PHP_METHOD(Collection, plusAssign); diff --git a/stubs/Collection.php b/stubs/Collection.php index baa96a2..7ccd75f 100644 --- a/stubs/Collection.php +++ b/stubs/Collection.php @@ -568,6 +568,13 @@ class Collection implements ArrayAccess, Countable */ function onEach($action) {} + /** + * Check whether the collection wraps a packed hashtable (regular array). + * + * @return bool + */ + function packed() {} + /** * Splits the original collection into pair of collections, where first collection contains * elements for which predicate yielded true, while second collection contains elements for diff --git a/tests/040-packed.phpt b/tests/040-packed.phpt new file mode 100644 index 0000000..7f47f05 --- /dev/null +++ b/tests/040-packed.phpt @@ -0,0 +1,11 @@ +--TEST-- +Test Collection::packed(). +--FILE-- +packed(); +$case1 = Collection::init(['foo' => 'bar', 'baz'])->packed(); +$case2 = Collection::init()->packed(); +if (!$case || $case1 || $case2) + echo 'Collection::packed() failed.', PHP_EOL; +?> +--EXPECT--