This repository has been archived on 2020-06-07. You can view files and clone it, but cannot push or open issues or pull requests.
php-armadillo/src/base.cc

299 lines
8.0 KiB
C++

//
// php-armadillo/base.cc
//
// @Author CismonX
//
#include "base.hh"
#include "mat.hh"
#include "subview_mat.hh"
#include "mapval.hh"
#include "stream_utils.hh"
#include <armadillo>
#include <zend_interfaces.h>
namespace php_arma
{
template <typename T, typename T1>
PHP_ARMA_METHOD(base, nElem, T, T1)
{
zend_long count;
count_elements(&EX(This), &count);
RETVAL_LONG(count);
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, add, T, T1)
{
zval *other;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(other)
ZEND_PARSE_PARAMETERS_END();
operators::add(&EX(This), other, return_value);
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, sub, T, T1)
{
zval *other;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(other)
ZEND_PARSE_PARAMETERS_END();
operators::sub(&EX(This), other, return_value);
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, neg, T, T1)
{
operators::neg(&EX(This), return_value);
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, mul, T, T1)
{
zval *other;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(other)
ZEND_PARSE_PARAMETERS_END();
operators::mul(&EX(This), other, return_value);
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, dotMul, T, T1)
{
zval *other;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(other)
ZEND_PARSE_PARAMETERS_END();
operators::dotMul(&EX(This), other, return_value);
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, div, T, T1)
{
zval *other;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(other)
ZEND_PARSE_PARAMETERS_END();
operators::div(&EX(This), other, return_value);
}
template <typename T, typename 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>
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>
PHP_ARMA_METHOD(base, forEach, 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;
auto native = THIS_NATIVE;
native->for_each([&fci, &fcc](auto&& val) {
ZVAL_OBJ(&fci.params[0], mapval_dense<T>::create(&val));
zend_call_function(&fci, &fcc);
zval_ptr_dtor(&fci.params[0]);
zval_ptr_dtor(fci.retval);
});
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, min, T, T1)
{
auto native = THIS_NATIVE;
zval_set_scalar(return_value, native->min());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, max, T, T1)
{
auto native = THIS_NATIVE;
zval_set_scalar(return_value, native->max());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, indexMin, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_LONG(native->index_min());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, indexMax, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_LONG(native->index_max());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, isEmpty, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_BOOL(native->is_empty());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, isFinite, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_BOOL(native->is_finite());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, hasInf, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_BOOL(native->has_inf());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, hasNan, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_BOOL(native->has_nan());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, print, T, T1)
{
zval *stream = nullptr;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_ZVAL(stream)
ZEND_PARSE_PARAMETERS_END();
auto native = THIS_NATIVE;
if (stream == nullptr) {
native->print();
} else {
Z_OSTREAM_P(stream, os);
if constexpr (zval_to_iostream_supported) {
native->print(os);
}
}
}
template <typename T, typename T1>
PHP_ARMA_METHOD(base, rawPrint, T, T1)
{
zval *stream = nullptr;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_ZVAL(stream)
ZEND_PARSE_PARAMETERS_END();
auto native = THIS_NATIVE;
if (stream == nullptr) {
native->raw_print();
} else {
Z_OSTREAM_P(stream, os);
if constexpr (zval_to_iostream_supported) {
native->raw_print(os);
}
}
}
template <typename T, typename T1>
PHP_ARMA_START_ME(base, T, T1)
PHP_ARMA_ME(nElem, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(add, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(sub, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(neg, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(mul, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(dotMul, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(div, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(replace, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(transform, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(forEach, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(min, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(max, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(indexMin, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(indexMax, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(isEmpty, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(isFinite, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(hasInf, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(hasNan, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(print, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(rawPrint, ZEND_ACC_PUBLIC)
PHP_ARMA_END_ME();
void base_init()
{
base_ce = interface_register<base_php_name>(
#if PHP_VERSION_ID >= 70200
zend_ce_countable
#endif
);
}
PHP_ARMA_INSTANTIATE(base, mat);
PHP_ARMA_INSTANTIATE(base, subview_mat);
}