Add `retainWhile()`. Refactor code.

This commit is contained in:
CismonX 2018-09-07 16:00:08 +08:00
parent 1b1595a801
commit 34354803c7
7 changed files with 54 additions and 17 deletions

View File

@ -8,12 +8,11 @@
#include "config.h" #include "config.h"
#endif #endif
#include <php.h> #include "php_collections.h"
#include <zend_interfaces.h> #include <zend_interfaces.h>
#include <ext/standard/info.h> #include <ext/standard/info.h>
#include "php_collections.h"
zend_object_handlers collection_handlers; zend_object_handlers collection_handlers;
zend_class_entry* collections_collection_ce; zend_class_entry* collections_collection_ce;

View File

@ -4,8 +4,6 @@
// @Author CismonX // @Author CismonX
// //
#include <php.h>
#include "php_collections_me.h" #include "php_collections_me.h"
ZEND_BEGIN_ARG_INFO(action_arginfo, 0) 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, removeAll, other_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, removeWhile, predicate_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, 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, reverse, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Collection, reversed, NULL, ZEND_ACC_PUBLIC) PHP_ME(Collection, reversed, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Collection, shuffle, NULL, ZEND_ACC_PUBLIC) PHP_ME(Collection, shuffle, NULL, ZEND_ACC_PUBLIC)

View File

@ -4,13 +4,12 @@
// @Author CismonX // @Author CismonX
// //
#include <php.h>
#include <ext/standard/php_string.h>
#include <ext/standard/php_mt_rand.h>
#include "php_collections.h" #include "php_collections.h"
#include "php_collections_me.h" #include "php_collections_me.h"
#include <ext/standard/php_string.h>
#include <ext/standard/php_mt_rand.h>
#if PHP_VERSION_ID < 70300 #if PHP_VERSION_ID < 70300
#define GC_ADDREF(p) ++GC_REFCOUNT(p) #define GC_ADDREF(p) ++GC_REFCOUNT(p)
#define GC_DELREF(p) --GC_REFCOUNT(p) #define GC_DELREF(p) --GC_REFCOUNT(p)
@ -742,7 +741,7 @@ PHP_METHOD(Collection, average)
sum += Z_DVAL_P(val); sum += Z_DVAL_P(val);
} else { } else {
ERR_NOT_NUMERIC(); ERR_NOT_NUMERIC();
RETURN_FALSE; RETURN_NULL();
} }
ZEND_HASH_FOREACH_END(); ZEND_HASH_FOREACH_END();
RETVAL_DOUBLE(sum / zend_hash_num_elements(current)); 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) PHP_METHOD(Collection, reverse)
{ {
zend_array* current = COLLECTION_FETCH_CURRENT(); zend_array* current = COLLECTION_FETCH_CURRENT();
@ -2726,7 +2745,7 @@ PHP_METHOD(Collection, sum)
ZVAL_DOUBLE(&sum, 0.0); ZVAL_DOUBLE(&sum, 0.0);
} else { } else {
ERR_NOT_NUMERIC(); ERR_NOT_NUMERIC();
RETURN_FALSE; RETURN_NULL();
} }
} }
if (Z_TYPE_P(val) == IS_LONG) { if (Z_TYPE_P(val) == IS_LONG) {
@ -2735,7 +2754,7 @@ PHP_METHOD(Collection, sum)
Z_DVAL(sum) += Z_DVAL_P(val); Z_DVAL(sum) += Z_DVAL_P(val);
} else { } else {
ERR_NOT_NUMERIC(); ERR_NOT_NUMERIC();
RETURN_FALSE; RETURN_NULL();
} }
ZEND_HASH_FOREACH_END(); ZEND_HASH_FOREACH_END();
RETVAL_ZVAL(&sum, 0, 0); RETVAL_ZVAL(&sum, 0, 0);
@ -2762,7 +2781,7 @@ PHP_METHOD(Collection, sumBy)
} else { } else {
ERR_NOT_NUMERIC(); ERR_NOT_NUMERIC();
zval_ptr_dtor(&retval); zval_ptr_dtor(&retval);
RETURN_FALSE; RETURN_NULL();
} }
} }
if (Z_TYPE(retval) == IS_LONG) { if (Z_TYPE(retval) == IS_LONG) {
@ -2772,7 +2791,7 @@ PHP_METHOD(Collection, sumBy)
} else { } else {
ERR_NOT_NUMERIC(); ERR_NOT_NUMERIC();
zval_ptr_dtor(&retval); zval_ptr_dtor(&retval);
RETURN_FALSE; RETURN_NULL();
} }
ZEND_HASH_FOREACH_END(); ZEND_HASH_FOREACH_END();
RETVAL_ZVAL(&sum, 0, 0); RETVAL_ZVAL(&sum, 0, 0);

View File

@ -7,6 +7,8 @@
#ifndef PHP_COLLECTIONS_H #ifndef PHP_COLLECTIONS_H
#define PHP_COLLECTIONS_H #define PHP_COLLECTIONS_H
#include <php.h>
extern zend_module_entry collections_module_entry; extern zend_module_entry collections_module_entry;
#define phpext_collections_ptr &collections_module_entry #define phpext_collections_ptr &collections_module_entry

View File

@ -7,6 +7,8 @@
#ifndef PHP_COLLECTIONS_ME_H #ifndef PHP_COLLECTIONS_ME_H
#define PHP_COLLECTIONS_ME_H #define PHP_COLLECTIONS_ME_H
#include <php.h>
PHP_METHOD(Collection, __construct); PHP_METHOD(Collection, __construct);
PHP_METHOD(Collection, addAll); PHP_METHOD(Collection, addAll);
PHP_METHOD(Collection, all); PHP_METHOD(Collection, all);
@ -77,6 +79,7 @@ PHP_METHOD(Collection, remove);
PHP_METHOD(Collection, removeAll); PHP_METHOD(Collection, removeAll);
PHP_METHOD(Collection, removeWhile); PHP_METHOD(Collection, removeWhile);
PHP_METHOD(Collection, retainAll); PHP_METHOD(Collection, retainAll);
PHP_METHOD(Collection, retainWhile);
PHP_METHOD(Collection, reverse); PHP_METHOD(Collection, reverse);
PHP_METHOD(Collection, reversed); PHP_METHOD(Collection, reversed);
PHP_METHOD(Collection, shuffle); PHP_METHOD(Collection, shuffle);

View File

@ -88,7 +88,7 @@ class Collection implements ArrayAccess, Countable
/** /**
* Returns an average value of elements in the collection. * Returns an average value of elements in the collection.
* *
* @return double|false * @return double|null
*/ */
function average() {} function average() {}
@ -664,6 +664,14 @@ class Collection implements ArrayAccess, Countable
*/ */
function retainAll($elements) {} 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. * 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. * 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() {} function sum() {}
@ -824,7 +832,7 @@ class Collection implements ArrayAccess, Countable
* Otherwise result is undefined. * Otherwise result is undefined.
* *
* @param callable $selector ($value, $key) -> int|double * @param callable $selector ($value, $key) -> int|double
* @return int|double|false * @return int|double|null
*/ */
function sumBy($selector) {} function sumBy($selector) {}

View File

@ -6,10 +6,17 @@ $array = ['a' => 4, 'b' => 1, 'c' => 9, 'd' => -2, 'e' => 0];
$pred_is_odd = function ($value) { $pred_is_odd = function ($value) {
return $value % 2; return $value % 2;
}; };
$collection = Collection::init($array); $collection = Collection::init($array);
$collection->removeWhile($pred_is_odd); $collection->removeWhile($pred_is_odd);
if ($collection->toArray() != ['a' => 4, 'd' => -2, 'e' => 0]) { if ($collection->toArray() != ['a' => 4, 'd' => -2, 'e' => 0]) {
echo 'Collection::removeWhile() failed.', PHP_EOL; 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-- --EXPECT--