From 3d996ade8be88cc2ec5ef82b1b54155f7d352092 Mon Sep 17 00:00:00 2001 From: CismonX Date: Thu, 12 Apr 2018 15:24:53 +0800 Subject: [PATCH] Add `fill()`. Now `init()` performs a hard copy on source array. --- src/collections_me.c | 2 +- src/collections_methods.c | 37 ++++++++++++++++++++++++++++--------- stubs/Collection.php | 6 +++--- tests/016-fill.phpt | 15 +++++++++++++++ 4 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 tests/016-fill.phpt diff --git a/src/collections_me.c b/src/collections_me.c index af49843..bbef692 100644 --- a/src/collections_me.c +++ b/src/collections_me.c @@ -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) diff --git a/src/collections_methods.c b/src/collections_methods.c index 49701d4..05745e5 100644 --- a/src/collections_methods.c +++ b/src/collections_methods.c @@ -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); diff --git a/stubs/Collection.php b/stubs/Collection.php index 4888943..00a21a9 100644 --- a/stubs/Collection.php +++ b/stubs/Collection.php @@ -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. diff --git a/tests/016-fill.phpt b/tests/016-fill.phpt new file mode 100644 index 0000000..f386991 --- /dev/null +++ b/tests/016-fill.phpt @@ -0,0 +1,15 @@ +--TEST-- +Test Collection::fill(). +--FILE-- + '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--