From e042ca2900deb5a7213d8cb0e55948695be63610 Mon Sep 17 00:00:00 2001 From: CismonX Date: Mon, 29 Jul 2019 00:28:46 +0800 Subject: [PATCH] Implement `insertRows()` and `insertCols()` --- src/dense_resizable_matrix.cc | 70 ++++++++++++++++++++++--- stubs/internal/DenseResizableMatrix.php | 12 ++--- tests/009-comparison-operators.phpt | 7 +-- tests/011-fill-imbue.phpt | 6 +-- tests/012-insert-rows-cols.phpt | 36 +++++++++++++ tests/includes/assert.php | 15 ++++++ 6 files changed, 123 insertions(+), 23 deletions(-) create mode 100644 tests/012-insert-rows-cols.phpt diff --git a/src/dense_resizable_matrix.cc b/src/dense_resizable_matrix.cc index 1297324..9ff0862 100644 --- a/src/dense_resizable_matrix.cc +++ b/src/dense_resizable_matrix.cc @@ -63,16 +63,74 @@ namespace php_arma RETVAL_THIS(); } - template - PHP_ARMA_METHOD(dense_resizable_matrix, insertRows, T, T1) + template + PHP_ARMA_METHOD(dense_resizable_matrix, insertRows, T, ChildT) { - + zend_long row_idx; + zval *rows; + zend_bool set_to_zero = true; + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_LONG(row_idx) + Z_PARAM_ZVAL(rows) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(set_to_zero) + ZEND_PARSE_PARAMETERS_END(); + + auto native = THIS_NATIVE; + try { + if (Z_TYPE_P(rows) == IS_LONG) { + native->insert_rows(row_idx, Z_LVAL_P(rows), set_to_zero); + } else if (Z_TYPE_P(rows) == IS_OBJECT) { + if (Z_OBJCE_P(rows) == ChildT::ce) { + auto rows_obj = to_native_object(Z_OBJ_P(rows)); + native->insert_rows(row_idx, *rows_obj); + } else if (Z_OBJCE_P(rows) == ChildT::subview_t::ce) { + auto rows_obj = to_native_object(Z_OBJ_P(rows)); + native->insert_rows(row_idx, *rows_obj); + } else { + ex_bad_type(ZSTR_VAL(dense_matrix_ce->name), zval_get_type_name(rows)); + } + } else { + ex_bad_type("int or object", zval_get_type_name(rows)); + } + } catch (const std::logic_error& err) { + throw_error(err.what()); + } } - template - PHP_ARMA_METHOD(dense_resizable_matrix, insertCols, T, T1) + template + PHP_ARMA_METHOD(dense_resizable_matrix, insertCols, T, ChildT) { - + zend_long col_idx; + zval *cols; + zend_bool set_to_zero = true; + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_LONG(col_idx) + Z_PARAM_ZVAL(cols) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(set_to_zero) + ZEND_PARSE_PARAMETERS_END(); + + auto native = THIS_NATIVE; + try { + if (Z_TYPE_P(cols) == IS_LONG) { + native->insert_cols(col_idx, Z_LVAL_P(cols), set_to_zero); + } else if (Z_TYPE_P(cols) == IS_OBJECT) { + if (Z_OBJCE_P(cols) == ChildT::ce) { + auto cols_obj = to_native_object(Z_OBJ_P(cols)); + native->insert_cols(col_idx, *cols_obj); + } else if (Z_OBJCE_P(cols) == ChildT::subview_t::ce) { + auto cols_obj = to_native_object(Z_OBJ_P(cols)); + native->insert_cols(col_idx, *cols_obj); + } else { + ex_bad_type(ZSTR_VAL(dense_matrix_ce->name), zval_get_type_name(cols)); + } + } else { + ex_bad_type("int or object", zval_get_type_name(cols)); + } + } catch (const std::logic_error& err) { + throw_error(err.what()); + } } template diff --git a/stubs/internal/DenseResizableMatrix.php b/stubs/internal/DenseResizableMatrix.php index 64d750a..aa09352 100644 --- a/stubs/internal/DenseResizableMatrix.php +++ b/stubs/internal/DenseResizableMatrix.php @@ -52,9 +52,9 @@ interface DenseResizableMatrix extends DenseMatrix, ResizableMatrix * whether to initialize new elements to zero, or insert a copy of specified object * (whose column size is the same as the recipient object), * - * @param int $row_idx - * @param Dense|int $rows - * @param bool $set_to_zero[optional] + * @param int $row_idx + * @param DenseMatrix|int $rows + * @param bool $set_to_zero[optional] * @return void */ function insertRows($row_idx, $rows, $set_to_zero = true); @@ -64,9 +64,9 @@ interface DenseResizableMatrix extends DenseMatrix, ResizableMatrix * whether to initialize new elements to zero, or insert a copy of specified object * (whose row size is the same as the recipient object), * - * @param int $col_idx - * @param Dense|int $cols - * @param bool $set_to_zero[optional] + * @param int $col_idx + * @param DenseMatrix|int $cols + * @param bool $set_to_zero[optional] * @return void */ function insertCols($col_idx, $cols, $set_to_zero = true); diff --git a/tests/009-comparison-operators.phpt b/tests/009-comparison-operators.phpt index ed0fa30..dc67770 100644 --- a/tests/009-comparison-operators.phpt +++ b/tests/009-comparison-operators.phpt @@ -16,12 +16,7 @@ require_once 'includes/assert.php'; $mat0 = Arma\DMat::init(3, 3, Arma\Fill::RANDU); $mat1 = Arma\DMat::init(3, 3, Arma\Fill::RANDU); -$comp = function ($expected, $got) { - $compare_result = $expected->equals($got); - return $compare_result->max() == 1 && $compare_result->min() == 1; -}; - -batch_assert_ex('operator overloading for comparisons', $comp, +batch_assert_mat('operator overloading for comparisons', [$mat0->equals($mat1), $mat0 == $mat1], [$mat0->notEquals($mat1), $mat0 != $mat1], [$mat0->smallerThan($mat1), $mat0 < $mat1], diff --git a/tests/011-fill-imbue.phpt b/tests/011-fill-imbue.phpt index 1064a39..19a8950 100644 --- a/tests/011-fill-imbue.phpt +++ b/tests/011-fill-imbue.phpt @@ -26,11 +26,7 @@ $mat1 = Arma\IMat::fromArray([ $mat->imbue(function () use (&$cnt) { return ++$cnt; }); -$comp = function ($expected, $got) { - $compare_result = $expected->equals($got); - return $compare_result->max() == 1 && $compare_result->min() == 1; -}; -batch_assert_ex('method `imbue()`', $comp, +batch_assert_mat('method `imbue()`', [$mat1, $mat] ); diff --git a/tests/012-insert-rows-cols.phpt b/tests/012-insert-rows-cols.phpt new file mode 100644 index 0000000..616117a --- /dev/null +++ b/tests/012-insert-rows-cols.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test for methods `insertRows()` and `insertCols()`. +--SKIPIF-- + +--FILE-- +insertRows(1, $rows); +batch_assert('method `insertRows()`', + [5, $mat->nRows()], + [3, $mat->nCols()] +); +batch_assert_mat('method `insertRows()`', + [$rows->rows(0, 1), $mat->rows(1, 2)] +); + +$mat->insertCols(2, $cols); +batch_assert('method `insertCols()`', + [5, $mat->nRows()], + [5, $mat->nCols()] +); +batch_assert_mat('method `insertCols()`', + [$cols->cols(0, 1), $mat->cols(2, 3)] +); + +?> +--EXPECT-- diff --git a/tests/includes/assert.php b/tests/includes/assert.php index 888892f..31adfbe 100644 --- a/tests/includes/assert.php +++ b/tests/includes/assert.php @@ -38,3 +38,18 @@ function batch_assert($test, ...$cases) { return $expected == $got; }, ...$cases); } + +/** + * Batch assert for matrix equality. + * + * @param $test + * @param array $cases + * @return bool + */ +function batch_assert_mat($test, ...$cases) { + $comp = function ($expected, $got) { + $compare_result = $expected->equals($got); + return $compare_result->max() == 1 && $compare_result->min() == 1; + }; + return batch_assert_ex($test, $comp, ...$cases); +}