diff --git a/src/collections.c b/src/collections.c index 75e613b..5d64896 100644 --- a/src/collections.c +++ b/src/collections.c @@ -8,12 +8,11 @@ #include "config.h" #endif -#include +#include "php_collections.h" + #include #include -#include "php_collections.h" - zend_object_handlers collection_handlers; zend_class_entry* collections_collection_ce; diff --git a/src/collections_me.c b/src/collections_me.c index dedd281..f7f5233 100644 --- a/src/collections_me.c +++ b/src/collections_me.c @@ -4,8 +4,6 @@ // @Author CismonX // -#include - #include "php_collections_me.h" ZEND_BEGIN_ARG_INFO(action_arginfo, 0) @@ -189,6 +187,7 @@ const zend_function_entry collection_methods[] = { PHP_ME(Collection, removeAll, other_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, removeWhile, predicate_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, retainAll, other_arginfo, ZEND_ACC_PUBLIC) + PHP_ME(Collection, retainWhile, predicate_arginfo, ZEND_ACC_PUBLIC) PHP_ME(Collection, reverse, NULL, ZEND_ACC_PUBLIC) PHP_ME(Collection, reversed, NULL, ZEND_ACC_PUBLIC) PHP_ME(Collection, shuffle, NULL, ZEND_ACC_PUBLIC) diff --git a/src/collections_methods.c b/src/collections_methods.c index 6c2bc94..de74290 100644 --- a/src/collections_methods.c +++ b/src/collections_methods.c @@ -4,13 +4,12 @@ // @Author CismonX // -#include -#include -#include - #include "php_collections.h" #include "php_collections_me.h" +#include +#include + #if PHP_VERSION_ID < 70300 #define GC_ADDREF(p) ++GC_REFCOUNT(p) #define GC_DELREF(p) --GC_REFCOUNT(p) @@ -742,7 +741,7 @@ PHP_METHOD(Collection, average) sum += Z_DVAL_P(val); } else { ERR_NOT_NUMERIC(); - RETURN_FALSE; + RETURN_NULL(); } ZEND_HASH_FOREACH_END(); RETVAL_DOUBLE(sum / zend_hash_num_elements(current)); @@ -2273,6 +2272,26 @@ PHP_METHOD(Collection, retainAll) } +PHP_METHOD(Collection, retainWhile) +{ + zend_fcall_info fci; + zend_fcall_info_cache fcc; + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_FUNC(fci, fcc) + ZEND_PARSE_PARAMETERS_END(); + zend_array* current = COLLECTION_FETCH_CURRENT(); + SEPARATE_CURRENT_COLLECTION(current); + INIT_FCI(&fci, 2); + ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket) + CALLBACK_KEYVAL_INVOKE(params, bucket); + if (!zend_is_true(&retval)) { + zend_hash_del_bucket(current, bucket); + } + zval_ptr_dtor(&retval); + ZEND_HASH_FOREACH_END(); +} + PHP_METHOD(Collection, reverse) { zend_array* current = COLLECTION_FETCH_CURRENT(); @@ -2726,7 +2745,7 @@ PHP_METHOD(Collection, sum) ZVAL_DOUBLE(&sum, 0.0); } else { ERR_NOT_NUMERIC(); - RETURN_FALSE; + RETURN_NULL(); } } if (Z_TYPE_P(val) == IS_LONG) { @@ -2735,7 +2754,7 @@ PHP_METHOD(Collection, sum) Z_DVAL(sum) += Z_DVAL_P(val); } else { ERR_NOT_NUMERIC(); - RETURN_FALSE; + RETURN_NULL(); } ZEND_HASH_FOREACH_END(); RETVAL_ZVAL(&sum, 0, 0); @@ -2762,7 +2781,7 @@ PHP_METHOD(Collection, sumBy) } else { ERR_NOT_NUMERIC(); zval_ptr_dtor(&retval); - RETURN_FALSE; + RETURN_NULL(); } } if (Z_TYPE(retval) == IS_LONG) { @@ -2772,7 +2791,7 @@ PHP_METHOD(Collection, sumBy) } else { ERR_NOT_NUMERIC(); zval_ptr_dtor(&retval); - RETURN_FALSE; + RETURN_NULL(); } ZEND_HASH_FOREACH_END(); RETVAL_ZVAL(&sum, 0, 0); diff --git a/src/php_collections.h b/src/php_collections.h index 34ee85a..78ab8a6 100644 --- a/src/php_collections.h +++ b/src/php_collections.h @@ -7,6 +7,8 @@ #ifndef PHP_COLLECTIONS_H #define PHP_COLLECTIONS_H +#include + extern zend_module_entry collections_module_entry; #define phpext_collections_ptr &collections_module_entry diff --git a/src/php_collections_me.h b/src/php_collections_me.h index f5bab68..1399c9a 100644 --- a/src/php_collections_me.h +++ b/src/php_collections_me.h @@ -7,6 +7,8 @@ #ifndef PHP_COLLECTIONS_ME_H #define PHP_COLLECTIONS_ME_H +#include + PHP_METHOD(Collection, __construct); PHP_METHOD(Collection, addAll); PHP_METHOD(Collection, all); @@ -77,6 +79,7 @@ PHP_METHOD(Collection, remove); PHP_METHOD(Collection, removeAll); PHP_METHOD(Collection, removeWhile); PHP_METHOD(Collection, retainAll); +PHP_METHOD(Collection, retainWhile); PHP_METHOD(Collection, reverse); PHP_METHOD(Collection, reversed); PHP_METHOD(Collection, shuffle); diff --git a/stubs/Collection.php b/stubs/Collection.php index 0b33e21..895486c 100644 --- a/stubs/Collection.php +++ b/stubs/Collection.php @@ -88,7 +88,7 @@ class Collection implements ArrayAccess, Countable /** * Returns an average value of elements in the collection. * - * @return double|false + * @return double|null */ function average() {} @@ -664,6 +664,14 @@ class Collection implements ArrayAccess, Countable */ function retainAll($elements) {} + /** + * Retains all elements from this collection that match the given predicate. + * + * @param callable $predicate ($value, $key) -> bool + * @return void + */ + function retainWhile($predicate) {} + /** * Reverses elements in the collection in-place. * @@ -812,7 +820,7 @@ class Collection implements ArrayAccess, Countable * * All elements should be of the same type, int or double. Otherwise result is undefined. * - * @return int|double|false + * @return int|double|null */ function sum() {} @@ -824,7 +832,7 @@ class Collection implements ArrayAccess, Countable * Otherwise result is undefined. * * @param callable $selector ($value, $key) -> int|double - * @return int|double|false + * @return int|double|null */ function sumBy($selector) {} diff --git a/tests/029-remove-while.phpt b/tests/029-remove-retain-while.phpt similarity index 67% rename from tests/029-remove-while.phpt rename to tests/029-remove-retain-while.phpt index 5593776..733e81c 100644 --- a/tests/029-remove-while.phpt +++ b/tests/029-remove-retain-while.phpt @@ -6,10 +6,17 @@ $array = ['a' => 4, 'b' => 1, 'c' => 9, 'd' => -2, 'e' => 0]; $pred_is_odd = function ($value) { return $value % 2; }; + $collection = Collection::init($array); $collection->removeWhile($pred_is_odd); if ($collection->toArray() != ['a' => 4, 'd' => -2, 'e' => 0]) { echo 'Collection::removeWhile() failed.', PHP_EOL; } + +$collection = Collection::init($array); +$collection->retainWhile($pred_is_odd); +if ($collection->toArray() != ['b' => 1, 'c' => 9]) { + echo 'Collection::retainWhile() failed.', PHP_EOL; +} ?> --EXPECT--