Add `fill()`. Now `init()` performs a hard copy on source array.

This commit is contained in:
CismonX 2018-04-12 15:24:53 +08:00
parent 55e1bbda22
commit 3d996ade8b
4 changed files with 47 additions and 13 deletions

View File

@ -97,7 +97,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(fill_arginfo, 0)
ZEND_ARG_INFO(0, element)
ZEND_ARG_TYPE_INFO(0, from_index, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, to_index, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, num_elements, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(get_arginfo, 0)

View File

@ -470,12 +470,11 @@ PHP_METHOD(Collection, copyOfRange)
ARRAY_NEW(new_collection, num_elements);
Bucket* bucket = Z_ARRVAL_P(current)->arData;
Bucket* end = bucket + Z_ARRVAL_P(current)->nNumUsed;
for (bucket += from_idx; num_elements > 0 && bucket < end; ++bucket, --num_elements) {
for (bucket += from_idx; num_elements > 0 && bucket < end; ++bucket, --num_elements)
if (bucket->key)
zend_hash_add(new_collection, bucket->key, &bucket->val);
else
zend_hash_next_index_insert(new_collection, &bucket->val);
}
RETVAL_NEW_COLLECTION(new_collection);
}
@ -512,8 +511,8 @@ PHP_METHOD(Collection, drop)
Bucket* bucket = new_collection->arData;
Bucket* end = bucket + new_collection->nNumUsed;
for (; n > 0 && bucket < end; ++bucket, --n) {
if (Z_REFCOUNTED_P(&bucket->val))
GC_ADDREF(Z_COUNTED_P(&bucket->val));
if (Z_REFCOUNTED(bucket->val))
GC_ADDREF(Z_COUNTED(bucket->val));
zend_hash_del_bucket(new_collection, bucket);
}
RETVAL_NEW_COLLECTION(new_collection);
@ -535,8 +534,8 @@ PHP_METHOD(Collection, dropLast)
unsigned idx = new_collection->nNumUsed;
for (; n > 0 && idx > 0; --idx, --n) {
Bucket* bucket = new_collection->arData + idx - 1;
if (Z_REFCOUNTED_P(&bucket->val))
GC_ADDREF(Z_COUNTED_P(&bucket->val));
if (Z_REFCOUNTED(bucket->val))
GC_ADDREF(Z_COUNTED(bucket->val));
zend_hash_del_bucket(new_collection, bucket);
}
RETVAL_NEW_COLLECTION(new_collection);
@ -590,7 +589,27 @@ PHP_METHOD(Collection, dropWhile)
PHP_METHOD(Collection, fill)
{
zval* element;
zend_long from_idx = 0;
zval rv;
zval* current = COLLECTION_FETCH_EX();
zend_long num_elements = zend_hash_num_elements(Z_ARRVAL_P(current) - from_idx);
ZEND_PARSE_PARAMETERS_START(1, 3)
Z_PARAM_ZVAL(element)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(from_idx)
Z_PARAM_LONG(num_elements)
ZEND_PARSE_PARAMETERS_END();
Bucket* bucket = Z_ARRVAL_P(current)->arData;
Bucket* end = bucket + Z_ARRVAL_P(current)->nNumUsed;
for (bucket += from_idx; num_elements > 0 && bucket < end; ++bucket, --num_elements) {
if (Z_REFCOUNTED(bucket->val))
GC_ADDREF(Z_COUNTED(bucket->val));
if (bucket->key)
zend_hash_update(Z_ARRVAL_P(current), bucket->key, element);
else
zend_hash_index_update(Z_ARRVAL_P(current), bucket->h, element);
}
}
PHP_METHOD(Collection, filter)
@ -697,8 +716,8 @@ PHP_METHOD(Collection, init)
ZEND_PARSE_PARAMETERS_END();
if (elements) {
ELEMENTS_VALIDATE(elements);
GC_ADDREF(Z_ARR_P(elements));
RETURN_NEW_COLLECTION(Z_ARRVAL_P(elements));
ARRAY_CLONE(new_collection, elements);
RETURN_NEW_COLLECTION(new_collection);
}
ARRAY_NEW(collection, 0);
RETVAL_NEW_COLLECTION(collection);

View File

@ -184,10 +184,10 @@ class Collection implements ArrayAccess, Countable
*
* @param mixed $element
* @param int $from_index[optional]
* @param int $to_index[optional]
* @return Collection
* @param int $num_elements[optional]
* @return void
*/
function fill($element, $from_index, $to_index) {}
function fill($element, $from_index, $num_elements) {}
/**
* Returns a collection containing only elements matching the given predicate.

15
tests/016-fill.phpt Normal file
View File

@ -0,0 +1,15 @@
--TEST--
Test Collection::fill().
--FILE--
<?php
$array = ['foo', 'bar' => 'baz', 1, 2, 3];
$collection = Collection::init($array);
$collection->fill('t', 1, 3);
$array1 = ['foo', 'bar' => 't', 't', 't', 3];
$collection1 = Collection::init($array);
$collection1->fill(0);
$array2 = [0, 'bar' => 0, 0, 0, 0];
if ($collection->toArray() != $array1 || $collection1->toArray() != $array2)
echo 'Collection::fill() failed.', PHP_EOL;
?>
--EXPECT--