implement replace() and transform()

This commit is contained in:
CismonX 2019-08-14 03:32:15 +08:00
parent 9b353bb011
commit 36b4cb977b
3 changed files with 62 additions and 6 deletions

View File

@ -62,13 +62,58 @@ namespace php_arma
template <typename T, typename T1> template <typename T, typename T1>
PHP_ARMA_METHOD(base, replace, T, T1) PHP_ARMA_METHOD(base, replace, T, T1)
{ {
zval *old_value;
zval *new_value;
ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_ZVAL(old_value)
Z_PARAM_ZVAL(new_value)
ZEND_PARSE_PARAMETERS_END();
if (UNEXPECTED(!zval_check_scalar<T>(old_value) || !zval_check_scalar<T>(new_value) )) {
return;
}
auto native = THIS_NATIVE;
native->replace(zval_get_scalar<T>(old_value), zval_get_scalar<T>(new_value));
} }
template <typename T, typename T1> template <typename T, typename T1>
PHP_ARMA_METHOD(base, transform, T, T1) PHP_ARMA_METHOD(base, transform, T, T1)
{ {
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_FUNC(fci, fcc);
ZEND_PARSE_PARAMETERS_END();
zval params[1], retval;
fci.param_count = 1;
fci.params = params;
fci.retval = &retval;
if constexpr (std::is_same_v<T, cx_double>) {
// prevent segfault in `zval_set_scalar()`..
ZVAL_UNDEF(&params[0]);
}
auto native = THIS_NATIVE;
native->transform([&fci, &fcc](auto&& val) {
zval_set_scalar(&fci.params[0], val);
zend_call_function(&fci, &fcc);
if (!zval_check_scalar<T>(fci.retval)) {
zval_ptr_dtor(fci.retval);
return T();
}
T retval = zval_get_scalar<T>(fci.retval);
if constexpr (std::is_same_v<T, cx_double>) {
zval_ptr_dtor(fci.retval);
}
return retval;
});
if constexpr (std::is_same_v<T, cx_double>) {
zval_ptr_dtor(&params[0]);
}
} }
template <typename T, typename T1> template <typename T, typename T1>
@ -86,7 +131,7 @@ namespace php_arma
fci.retval = &retval; fci.retval = &retval;
auto native = THIS_NATIVE; auto native = THIS_NATIVE;
native->for_each([&fci, &fcc](T& val) { native->for_each([&fci, &fcc](auto&& val) {
ZVAL_OBJ(&fci.params[0], mapval_dense<T>::create(&val)); ZVAL_OBJ(&fci.params[0], mapval_dense<T>::create(&val));
zend_call_function(&fci, &fcc); zend_call_function(&fci, &fcc);
zval_ptr_dtor(&fci.params[0]); zval_ptr_dtor(&fci.params[0]);

View File

@ -82,10 +82,10 @@ interface Base extends Countable
* *
* Transformation is done column-by-column, and for SpMat only non-zero elements will be transformed. * Transformation is done column-by-column, and for SpMat only non-zero elements will be transformed.
* *
* @param callable $callback (Scalar) => $new_value * @param callable $transform (number|Complex) => $new_value
* @return void * @return void
*/ */
function transform($callback); function transform($transform);
/** /**
* For each element, pass its reference to a callback function. * For each element, pass its reference to a callback function.

View File

@ -1,5 +1,5 @@
--TEST-- --TEST--
Test for method `forEach()`. Test for methods `forEach()`, `transform()`, `replace()`.
--SKIPIF-- --SKIPIF--
<?php <?php
require_once 'includes/loaded.php'; require_once 'includes/loaded.php';
@ -19,6 +19,13 @@ $mat->forEach(function (Arma\MapVal $elem) {
}); });
echo PHP_EOL; echo PHP_EOL;
$mat->rawPrint(); $mat->rawPrint();
$mat->transform(function (int $elem) {
return $elem + 4;
});
$mat->rawPrint();
$mat->replace(10, -1);
$mat->replace(11, -2);
$mat->rawPrint();
?> ?>
--EXPECT-- --EXPECT--
@ -27,3 +34,7 @@ $mat->rawPrint();
1324 1324
5 6 5 6
7 8 7 8
9 10
11 12
9 -1
-2 12