From f2209e019d094fe2bae71562d42a018bd0669b20 Mon Sep 17 00:00:00 2001 From: CismonX Date: Sun, 22 Apr 2018 22:47:30 +0800 Subject: [PATCH] Add `flatten()`. Remove `lastIndexOf()`. --- src/collections_me.c | 1 - src/collections_methods.c | 42 ++++++++++++++++++++++++++------------- src/php_collections_me.h | 1 - stubs/Collection.php | 12 ++--------- tests/022-flatten.php | 10 ++++++++++ 5 files changed, 40 insertions(+), 26 deletions(-) create mode 100644 tests/022-flatten.php diff --git a/src/collections_me.c b/src/collections_me.c index 5aec610..fcd8d68 100644 --- a/src/collections_me.c +++ b/src/collections_me.c @@ -166,7 +166,6 @@ const zend_function_entry collection_methods[] = { PHP_ME(Collection, isNotEmpty, NULL, ZEND_ACC_PUBLIC) PHP_ME(Collection, keys, NULL, ZEND_ACC_PUBLIC) PHP_ME(Collection, last, predicate_arginfo, ZEND_ACC_PUBLIC) - PHP_ME(Collection, lastIndexOf, element_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, map, transform_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, mapKeys, transform_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, mapKeysTo, destination_transform_arginfo, ZEND_ACC_PUBLIC) diff --git a/src/collections_methods.c b/src/collections_methods.c index 5705750..80c73b7 100644 --- a/src/collections_methods.c +++ b/src/collections_methods.c @@ -74,16 +74,17 @@ #define ERR_BAD_SIZE() PHP_COLLECTIONS_ERROR(E_WARNING, "Size must be non-negative") #define ERR_BAD_INDEX() PHP_COLLECTIONS_ERROR(E_WARNING, "Index must be non-negative") #define ERR_NOT_ARITHMETIC() PHP_COLLECTIONS_ERROR(E_WARNING, "Elements should be int or double") +#define ERR_SILENCED() -#define ELEMENTS_VALIDATE(elements) \ +#define ELEMENTS_VALIDATE(elements, err, err_then) \ zend_array* elements##_arr; \ if (IS_COLLECTION_P(elements)) \ (elements##_arr) = COLLECTION_FETCH(elements); \ else if (UNEXPECTED(Z_TYPE_P(elements) == IS_ARRAY))\ (elements##_arr) = Z_ARRVAL_P(elements); \ else { \ - ERR_BAD_ARGUMENT_TYPE(); \ - return; \ + err(); \ + err_then; \ } #define ARRAY_NEW(name, size) \ @@ -173,7 +174,7 @@ PHP_METHOD(Collection, addAll) ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_ZVAL(elements) ZEND_PARSE_PARAMETERS_END(); - ELEMENTS_VALIDATE(elements); + ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return); zend_array* current = COLLECTION_FETCH_EX(); SEPARATE_COLLECTION_EX(current); ZEND_HASH_FILL_PACKED(current) @@ -350,7 +351,7 @@ PHP_METHOD(Collection, containsAll) ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_ZVAL(elements) ZEND_PARSE_PARAMETERS_END(); - ELEMENTS_VALIDATE(elements); + ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return); zend_array* current = COLLECTION_FETCH_EX(); ZEND_HASH_FOREACH_VAL(elements_arr, zval* element) INIT_EQUAL_CHECK_FUNC(element); @@ -719,7 +720,7 @@ PHP_METHOD(Collection, flatMap) ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket) CALLBACK_KEYVAL_INVOKE(params, bucket); zval* retval_p = &retval; - ELEMENTS_VALIDATE(retval_p); + ELEMENTS_VALIDATE(retval_p, ERR_BAD_CALLBACK_RETVAL, continue); ZEND_HASH_FOREACH_BUCKET(retval_p_arr, Bucket* bucket) if (Z_REFCOUNTED(bucket->val)) GC_ADDREF(Z_COUNTED(bucket->val)); @@ -749,7 +750,7 @@ PHP_METHOD(Collection, flatMapTo) ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket) CALLBACK_KEYVAL_INVOKE(params, bucket); zval* retval_p = &retval; - ELEMENTS_VALIDATE(retval_p); + ELEMENTS_VALIDATE(retval_p, ERR_BAD_CALLBACK_RETVAL, continue); ZEND_HASH_FOREACH_BUCKET(retval_p_arr, Bucket* bucket) if (Z_REFCOUNTED(bucket->val)) GC_ADDREF(Z_COUNTED(bucket->val)); @@ -765,7 +766,25 @@ PHP_METHOD(Collection, flatMapTo) PHP_METHOD(Collection, flatten) { - + zend_array* current = COLLECTION_FETCH_EX(); + ARRAY_NEW_EX(new_collection, current); + ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket) + zval* val = &bucket->val; + ELEMENTS_VALIDATE(val, ERR_SILENCED, { + if (bucket->key) + zend_hash_add(new_collection, bucket->key, &bucket->val); + else + zend_hash_next_index_insert(new_collection, &bucket->val); + continue; + }); + ZEND_HASH_FOREACH_BUCKET(val_arr, Bucket* bucket) + if (bucket->key) + zend_hash_add(new_collection, bucket->key, &bucket->val); + else + zend_hash_next_index_insert(new_collection, &bucket->val); + ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_END(); + RETVAL_NEW_COLLECTION(new_collection); } PHP_METHOD(Collection, fold) @@ -821,7 +840,7 @@ PHP_METHOD(Collection, init) Z_PARAM_ZVAL(elements) ZEND_PARSE_PARAMETERS_END(); if (elements) { - ELEMENTS_VALIDATE(elements); + ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return); RETURN_NEW_COLLECTION(elements_arr); } ARRAY_NEW(collection, 0); @@ -874,11 +893,6 @@ PHP_METHOD(Collection, last) RETVAL_NULL(); } -PHP_METHOD(Collection, lastIndexOf) -{ - -} - PHP_METHOD(Collection, map) { diff --git a/src/php_collections_me.h b/src/php_collections_me.h index 78f22a3..9426bfc 100644 --- a/src/php_collections_me.h +++ b/src/php_collections_me.h @@ -52,7 +52,6 @@ PHP_METHOD(Collection, isEmpty); PHP_METHOD(Collection, isNotEmpty); PHP_METHOD(Collection, keys); PHP_METHOD(Collection, last); -PHP_METHOD(Collection, lastIndexOf); PHP_METHOD(Collection, map); PHP_METHOD(Collection, mapKeys); PHP_METHOD(Collection, mapKeysTo); diff --git a/stubs/Collection.php b/stubs/Collection.php index 5570b29..e893bbb 100644 --- a/stubs/Collection.php +++ b/stubs/Collection.php @@ -331,7 +331,7 @@ class Collection implements ArrayAccess, Countable * Returns key of the first element matching the given predicate, or null if the collection * does not contain such element. * - * @param callable $predicate ($value) -> bool + * @param callable $predicate[optional] ($value) -> bool * @return int|string|null */ function indexOfFirst($predicate) {} @@ -340,7 +340,7 @@ class Collection implements ArrayAccess, Countable * Returns key of the last element matching the given predicate, or null if the collection * does not contain such element. * - * @param callable $predicate ($value) -> bool + * @param callable $predicate[optional] ($value) -> bool * @return int|string|null */ function indexOfLast($predicate) {} @@ -389,14 +389,6 @@ class Collection implements ArrayAccess, Countable */ function last($predicate) {} - /** - * Returns last key of element, or null if the collection does not contain element. - * - * @param mixed $element - * @return int|string|null - */ - function lastIndexOf($element) {} - /** * Returns a collection containing the results of applying the given transform function * to each element in the original collection. diff --git a/tests/022-flatten.php b/tests/022-flatten.php new file mode 100644 index 0000000..0e2f835 --- /dev/null +++ b/tests/022-flatten.php @@ -0,0 +1,10 @@ +--TEST-- +Test Collection::flatten(). +--FILE-- + 'b'], ['c', 'd', ['e']], 'bar' => 'f']; +$collection = Collection::init($array)->flatten(); +if ($collection->toArray() != ['a', 'foo' => 'b', 'c', 'd', ['e'], 'bar' => 'f']) + echo 'Collection::flatten() failed.', PHP_EOL; +?> +--EXPECT--