Add `packed()`. Fix bug for `reduce()`.

This commit is contained in:
CismonX 2018-08-08 01:34:09 +08:00
parent 440d3fdb63
commit e0e5cf2425
5 changed files with 32 additions and 10 deletions

View File

@ -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)

View File

@ -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(&params[0], &acc);
ZVAL_COPY_VALUE(&params[0], &retval);
ZVAL_COPY_VALUE(&params[1], &bucket->val);
if (bucket->key)
ZVAL_STR(&params[2], bucket->key);
else
ZVAL_LONG(&params[2], bucket->h);
zend_call_function(&fci, &fcc);
zval_ptr_dtor(&acc);
ZVAL_COPY_VALUE(&acc, &retval);
zval_ptr_dtor(&params[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(&params[0], &acc);
ZVAL_COPY_VALUE(&params[0], &retval);
ZVAL_COPY_VALUE(&params[1], &bucket->val);
if (bucket->key)
ZVAL_STR(&params[2], bucket->key);
else
ZVAL_LONG(&params[2], bucket->h);
zend_call_function(&fci, &fcc);
zval_ptr_dtor(&acc);
ZVAL_COPY_VALUE(&acc, &retval);
zval_ptr_dtor(&params[0]);
}
RETVAL_ZVAL(&retval, 0, 0);
}

View File

@ -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);

View File

@ -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

11
tests/040-packed.phpt Normal file
View File

@ -0,0 +1,11 @@
--TEST--
Test Collection::packed().
--FILE--
<?php
$case = Collection::init(['a', 'b', 'c'])->packed();
$case1 = Collection::init(['foo' => 'bar', 'baz'])->packed();
$case2 = Collection::init()->packed();
if (!$case || $case1 || $case2)
echo 'Collection::packed() failed.', PHP_EOL;
?>
--EXPECT--