update
This commit is contained in:
parent
a5b4f5b682
commit
12d04c22db
|
@ -25,7 +25,7 @@
|
|||
#endif
|
||||
|
||||
// For non-assignment operators, first operand can be of type double.
|
||||
#define PHP_ARMA_COMPLEX_OPERATOR(type, func) \
|
||||
#define PHP_ARMA_COMPLEX_OPERATOR_EX(type, func) \
|
||||
if (instanceof_function(ce, complex<type>::ce)) { \
|
||||
zval tmp; \
|
||||
ZVAL_UNDEF(&tmp); \
|
||||
|
@ -45,14 +45,18 @@
|
|||
return v; \
|
||||
}
|
||||
|
||||
#define PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(type, func) \
|
||||
if (instanceof_function(ce, complex<type>::ce)) { \
|
||||
auto v = complex<type>::operators::func(zv1, zv2, zv1); \
|
||||
if (rv) { \
|
||||
ZVAL_COPY(rv, zv1); \
|
||||
} \
|
||||
return v; \
|
||||
}
|
||||
#define PHP_ARMA_COMPLEX_OPERATOR(func) \
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce) \
|
||||
PHP_ARMA_COMPLEX_OPERATOR_EX(double, func) \
|
||||
PHP_ARMA_OPERATOR_END()
|
||||
|
||||
#define PHP_ARMA_COMPLEX_OPERATOR_ASSIGN_EX(type, func) \
|
||||
PHP_ARMA_OPERATOR_ASSIGN_EX(complex<type>, func)
|
||||
|
||||
#define PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(func) \
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce) \
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN_EX(double, func) \
|
||||
PHP_ARMA_OPERATOR_END()
|
||||
|
||||
#endif // PHP_ARMA_OPERATORS
|
||||
|
||||
|
@ -143,7 +147,7 @@ namespace php_arma
|
|||
}
|
||||
|
||||
zend_always_inline
|
||||
void zval_set_scalar(zval *zv, cx_double val)
|
||||
void zval_set_scalar(zval *zv, const cx_double& val)
|
||||
{
|
||||
auto zobj = object_create(PHP_ARMA_CE(complex, double), PHP_ARMA_HANDLERS(complex, double));
|
||||
ZVAL_DOUBLE(OBJ_PROP_NUM(zobj, 0), val.real());
|
||||
|
|
66
src/dense.cc
66
src/dense.cc
|
@ -5,69 +5,75 @@
|
|||
//
|
||||
|
||||
#include "dense.hh"
|
||||
#include "base.hh"
|
||||
#include "mat.hh"
|
||||
|
||||
namespace php_arma
|
||||
{
|
||||
template <typename T, typename ChildT>
|
||||
template <bool IsEq, typename F>
|
||||
zend_always_inline
|
||||
void dense<T, ChildT>::compare(INTERNAL_FUNCTION_PARAMETERS, F&& func)
|
||||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(dense, equals, T, T1)
|
||||
{
|
||||
zval *other;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_OBJECT_DEREF(other)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
compare_op<T, ChildT, IsEq>(getThis(), other, return_value, std::move(func));
|
||||
operators::equals(getThis(), other, return_value);
|
||||
}
|
||||
|
||||
template <typename T, typename ChildT>
|
||||
PHP_ARMA_METHOD(dense, equals, T, ChildT)
|
||||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(dense, notEquals, T, T1)
|
||||
{
|
||||
compare<true>(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) {
|
||||
return *v1 == *v2;
|
||||
});
|
||||
}
|
||||
zval *other;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_OBJECT_DEREF(other)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
template <typename T, typename ChildT>
|
||||
PHP_ARMA_METHOD(dense, notEquals, T, ChildT)
|
||||
{
|
||||
compare<true>(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) {
|
||||
return *v1 != *v2;
|
||||
});
|
||||
operators::not_equals(getThis(), other, return_value);
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(dense, greaterThan, T, T1)
|
||||
{
|
||||
compare<false>(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) {
|
||||
return *v1 > *v2;
|
||||
});
|
||||
zval *other;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_OBJECT_DEREF(other)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
operators::greater_than(getThis(), other, return_value);
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(dense, smallerThan, T, T1)
|
||||
{
|
||||
compare<false>(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) {
|
||||
return *v1 < *v2;
|
||||
});
|
||||
zval *other;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_OBJECT_DEREF(other)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
operators::smaller_than(getThis(), other, return_value);
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(dense, notGreaterThan, T, T1)
|
||||
{
|
||||
compare<false>(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) {
|
||||
return *v1 <= *v2;
|
||||
});
|
||||
zval *other;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_OBJECT_DEREF(other)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
operators::not_greater_than(getThis(), other, return_value);
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
PHP_ARMA_METHOD(dense, notSmallerThan, T, T1)
|
||||
{
|
||||
compare<false>(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) {
|
||||
return *v1 >= *v2;
|
||||
});
|
||||
zval *other;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_OBJECT_DEREF(other)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
operators::not_smaller_than(getThis(), other, return_value);
|
||||
}
|
||||
|
||||
template <typename T, typename T1>
|
||||
|
@ -96,7 +102,7 @@ namespace php_arma
|
|||
|
||||
void dense_init()
|
||||
{
|
||||
dense_ce = interface_register<dense_php_name>();
|
||||
dense_ce = interface_register<dense_php_name>(base_ce);
|
||||
}
|
||||
|
||||
PHP_ARMA_INSTANTIATE(dense, mat);
|
||||
|
|
90
src/dense.hh
90
src/dense.hh
|
@ -14,33 +14,33 @@
|
|||
|
||||
namespace php_arma
|
||||
{
|
||||
template <typename ElemT, typename ContainerT, bool IsEq, typename F>
|
||||
zend_always_inline
|
||||
void compare_op(zval *zv1, zval *zv2, zval *return_value, F&& func)
|
||||
{
|
||||
if (Z_OBJCE_P(zv1) != Z_OBJCE_P(zv2)) {
|
||||
ex_bad_type(zval_get_type_name(zv1), zval_get_type_name(zv2));
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
if constexpr (!IsEq && std::is_same_v<ElemT, cx_double>) {
|
||||
zend_throw_exception(zend_ce_error, "no such comparation for complex elements", 0);
|
||||
RETVAL_NULL();
|
||||
} else {
|
||||
using native_t = typename ContainerT::native_t;
|
||||
using dest_t = typename ContainerT::with_int_elem_t;
|
||||
using dest_native_t = typename dest_t::native_t;
|
||||
auto ret = func(Z_NATIVE_OBJ_P(zv1), Z_NATIVE_OBJ_P(zv2)).eval();
|
||||
RETVAL_OBJ(dest_t::create(std::move(arma::conv_to<dest_native_t>::from(ret))));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename ChildT>
|
||||
struct dense
|
||||
{
|
||||
using native_t = typename ChildT::native_t;
|
||||
|
||||
struct operators;
|
||||
|
||||
template <bool IsEq, typename F>
|
||||
zend_always_inline
|
||||
static bool compare_op(zval *zv1, zval *zv2, zval *return_value, F&& func)
|
||||
{
|
||||
if (Z_OBJCE_P(zv1) != Z_OBJCE_P(zv2)) {
|
||||
ex_bad_type(zval_get_type_name(zv1), zval_get_type_name(zv2));
|
||||
return false;
|
||||
}
|
||||
|
||||
if constexpr (!IsEq && std::is_same_v<T, cx_double>) {
|
||||
zend_throw_exception(zend_ce_error, "no such comparation for complex elements", 0);
|
||||
return false;
|
||||
} else {
|
||||
using dest_t = typename ChildT::with_int_elem_t;
|
||||
using dest_native_t = typename dest_t::native_t;
|
||||
auto ret = func(Z_NATIVE_OBJ_P(zv1), Z_NATIVE_OBJ_P(zv2)).eval();
|
||||
RETVAL_OBJ(dest_t::create(std::move(arma::conv_to<dest_native_t>::from(ret))));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
PHP_ARMA_COMMON_DECLARE();
|
||||
|
||||
|
@ -67,7 +67,53 @@ namespace php_arma
|
|||
template <typename T, typename ChildT>
|
||||
struct dense<T, ChildT>::operators
|
||||
{
|
||||
|
||||
zend_always_inline
|
||||
static bool equals(zval *zv1, zval *zv2, zval *retval)
|
||||
{
|
||||
return compare_op<true>(zv1, zv2, retval, [] (auto v1, auto v2) {
|
||||
return *v1 == *v2;
|
||||
});
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
static bool not_equals(zval *zv1, zval *zv2, zval *retval)
|
||||
{
|
||||
return compare_op<true>(zv1, zv2, retval, [] (auto v1, auto v2) {
|
||||
return *v1 != *v2;
|
||||
});
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
static bool greater_than(zval *zv1, zval *zv2, zval *retval)
|
||||
{
|
||||
return compare_op<false>(zv1, zv2, retval, [] (auto v1, auto v2) {
|
||||
return *v1 > *v2;
|
||||
});
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
static bool smaller_than(zval *zv1, zval *zv2, zval *retval)
|
||||
{
|
||||
return compare_op<false>(zv1, zv2, retval, [] (auto v1, auto v2) {
|
||||
return *v1 < *v2;
|
||||
});
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
static bool not_greater_than(zval *zv1, zval *zv2, zval *retval)
|
||||
{
|
||||
return compare_op<false>(zv1, zv2, retval, [] (auto v1, auto v2) {
|
||||
return *v1 <= *v2;
|
||||
});
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
static bool not_smaller_than(zval *zv1, zval *zv2, zval *retval)
|
||||
{
|
||||
return compare_op<false>(zv1, zv2, retval, [] (auto v1, auto v2) {
|
||||
return *v1 >= *v2;
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
//
|
||||
|
||||
#include "dense_matrix.hh"
|
||||
#include "dense.hh"
|
||||
#include "matrix.hh"
|
||||
#include "mapval.hh"
|
||||
#include "mat.hh"
|
||||
|
||||
|
@ -31,9 +33,9 @@ namespace php_arma
|
|||
} else {
|
||||
zobj = mapval_dense<T>::create(&native->operator()(i, j));
|
||||
}
|
||||
} catch (std::logic_error& err) {
|
||||
} catch (const std::logic_error& err) {
|
||||
zend_throw_exception(zend_ce_exception, "index out of bounds", 0);
|
||||
RETURN_NULL();
|
||||
return;
|
||||
}
|
||||
|
||||
RETVAL_OBJ(zobj);
|
||||
|
@ -159,7 +161,7 @@ namespace php_arma
|
|||
|
||||
void dense_matrix_init()
|
||||
{
|
||||
dense_matrix_ce = interface_register<dense_matrix_php_name>();
|
||||
dense_matrix_ce = interface_register<dense_matrix_php_name>(dense_ce, matrix_ce);
|
||||
}
|
||||
|
||||
PHP_ARMA_INSTANTIATE(dense_matrix, mat);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
//
|
||||
|
||||
#include "dense_resizable_matrix.hh"
|
||||
#include "dense_matrix.hh"
|
||||
#include "resizable_matrix.hh"
|
||||
#include "mat.hh"
|
||||
|
||||
namespace php_arma
|
||||
|
@ -64,7 +66,8 @@ namespace php_arma
|
|||
|
||||
void dense_resizable_matrix_init()
|
||||
{
|
||||
dense_resizable_matrix_ce = interface_register<dense_resizable_matrix_php_name>();
|
||||
dense_resizable_matrix_ce = interface_register<dense_resizable_matrix_php_name>(
|
||||
dense_matrix_ce, resizable_matrix_ce);
|
||||
}
|
||||
|
||||
PHP_ARMA_INSTANTIATE(dense_resizable_matrix, mat);
|
||||
|
|
|
@ -11,17 +11,6 @@
|
|||
|
||||
namespace php_arma
|
||||
{
|
||||
template <typename T, bool IsSparse, bool B>
|
||||
zend_always_inline
|
||||
T mapval<T, IsSparse, B>::get_val(zend_object *zobj)
|
||||
{
|
||||
if constexpr (IsSparse) {
|
||||
return *ZOBJ_NATIVE(zobj);
|
||||
} else {
|
||||
return **ZOBJ_NATIVE(zobj);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, bool B1, bool B2>
|
||||
PHP_ARMA_METHOD(mapval, val, T, B1, B2)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,30 @@
|
|||
|
||||
#include "php_arma.hh"
|
||||
|
||||
#define PHP_ARMA_MAPVAL_OPERATOR_EX(type, func) \
|
||||
PHP_ARMA_OPERATOR_EX(mapval_dense <type>, func) \
|
||||
PHP_ARMA_OPERATOR_EX(mapval_spmat <type>, func) \
|
||||
PHP_ARMA_OPERATOR_EX(mapval_sp_subview<type>, func)
|
||||
|
||||
#define PHP_ARMA_MAPVAL_OPERATOR(func) \
|
||||
PHP_ARMA_OPERATOR_BEGIN(scalar_ce) \
|
||||
PHP_ARMA_MAPVAL_OPERATOR_EX(double, func) \
|
||||
PHP_ARMA_MAPVAL_OPERATOR_EX(zend_long, func) \
|
||||
PHP_ARMA_MAPVAL_OPERATOR_EX(cx_double, func) \
|
||||
PHP_ARMA_OPERATOR_END()
|
||||
|
||||
#define PHP_ARMA_MAPVAL_OPERATOR_ASSIGN_EX(type, func) \
|
||||
PHP_ARMA_OPERATOR_ASSIGN_EX(mapval_dense <type>, func) \
|
||||
PHP_ARMA_OPERATOR_ASSIGN_EX(mapval_spmat <type>, func) \
|
||||
PHP_ARMA_OPERATOR_ASSIGN_EX(mapval_sp_subview<type>, func)
|
||||
|
||||
#define PHP_ARMA_MAPVAL_OPERATOR_ASSIGN(func) \
|
||||
PHP_ARMA_OPERATOR_BEGIN(scalar_ce) \
|
||||
PHP_ARMA_MAPVAL_OPERATOR_ASSIGN_EX(double, func) \
|
||||
PHP_ARMA_MAPVAL_OPERATOR_ASSIGN_EX(zend_long, func) \
|
||||
PHP_ARMA_MAPVAL_OPERATOR_ASSIGN_EX(cx_double, func) \
|
||||
PHP_ARMA_OPERATOR_END()
|
||||
|
||||
// Forward declarations.
|
||||
namespace arma
|
||||
{
|
||||
|
@ -26,6 +50,8 @@ namespace php_arma
|
|||
|
||||
using native_t = std::conditional_t<IsSparse, sp_mapval_t, T*>;
|
||||
|
||||
struct operators;
|
||||
|
||||
friend void mapval_init();
|
||||
|
||||
zend_always_inline
|
||||
|
@ -38,6 +64,16 @@ namespace php_arma
|
|||
}
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
static T get_val(zend_object *zobj)
|
||||
{
|
||||
if constexpr (IsSparse) {
|
||||
return *ZOBJ_NATIVE(zobj);
|
||||
} else {
|
||||
return **ZOBJ_NATIVE(zobj);
|
||||
}
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
static zend_object *create(native_t init_val)
|
||||
{
|
||||
|
@ -62,8 +98,6 @@ namespace php_arma
|
|||
static PHP_FUNCTION(val);
|
||||
static PHP_FUNCTION(setTo);
|
||||
|
||||
static T get_val(zend_object*);
|
||||
|
||||
static void ce_init(zend_class_entry*);
|
||||
};
|
||||
|
||||
|
@ -87,6 +121,37 @@ namespace php_arma
|
|||
inline zend_class_entry *mapval_ce;
|
||||
inline zend_class_entry *sp_mapval_ce;
|
||||
inline zend_class_entry *spsv_mapval_ce;
|
||||
|
||||
template <typename T, bool IsSparse, bool IsSubview>
|
||||
struct mapval<T, IsSparse, IsSubview>::operators
|
||||
{
|
||||
zend_always_inline
|
||||
static bool assign(zval *zv1, zval *zv2, zval *retval)
|
||||
{
|
||||
if (!zval_is_scalar<T>(zv2)) {
|
||||
return false;
|
||||
}
|
||||
set_val(Z_OBJ_P(retval), zval_get_scalar<T>(zv2));
|
||||
return true;
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
static bool mul(zval *zv1, zval *zv2, zval *retval)
|
||||
{
|
||||
#if PHP_VERSION_ID < 70300
|
||||
if (Z_TYPE_P(zv1) == IS_LONG && Z_LVAL_P(zv1) == 1) {
|
||||
zval_set_scalar(retval, get_val(Z_OBJ_P(zv2)));
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if (Z_TYPE_P(zv2) == IS_LONG && Z_LVAL_P(zv2) == 1) {
|
||||
zval_set_scalar(retval, get_val(Z_OBJ_P(zv1)));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !PHP_ARMA_MAPVAL_HH
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace php_arma
|
|||
auto first_row = zend_hash_index_find(Z_ARR_P(arr), 0);
|
||||
if (UNEXPECTED(first_row == nullptr || Z_TYPE_P(first_row) != IS_ARRAY)) {
|
||||
zend_throw_exception(zend_ce_error, "bad input matrix", 0);
|
||||
RETURN_NULL();
|
||||
return;
|
||||
}
|
||||
auto num_cols = zend_hash_num_elements(Z_ARR_P(first_row));
|
||||
if (UNEXPECTED(num_rows == 0)) {
|
||||
|
@ -133,7 +133,7 @@ namespace php_arma
|
|||
|
||||
void mat_init()
|
||||
{
|
||||
mat_ce = interface_register<mat_php_name>();
|
||||
mat_ce = abstract_class_register<mat_php_name>(dense_resizable_matrix_ce);
|
||||
|
||||
mat<double >::ce_init(mat_ce);
|
||||
mat<zend_long>::ce_init(mat_ce);
|
||||
|
|
|
@ -7,12 +7,18 @@
|
|||
#include "php_arma.hh"
|
||||
#include "operators.hh"
|
||||
#include "complex.hh"
|
||||
#include "mapval.hh"
|
||||
|
||||
#include <armadillo>
|
||||
|
||||
#if PHP_VERSION_ID >= 70300
|
||||
// See https://github.com/php/php-src/blob/PHP-7.3/UPGRADING.INTERNALS section 3.1.b.
|
||||
#define EX_CONSTANT(op) RT_CONSTANT(EX(opline), op)
|
||||
#endif
|
||||
|
||||
#define PHP_ARMA_OP_HANDLER_FUNC \
|
||||
[] (auto zv1, auto zv2, auto rv, auto ce)
|
||||
|
||||
namespace php_arma
|
||||
{
|
||||
zend_always_inline
|
||||
|
@ -78,12 +84,19 @@ namespace php_arma
|
|||
return ZEND_USER_OPCODE_CONTINUE;
|
||||
}
|
||||
|
||||
int assign_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_MAPVAL_OPERATOR_ASSIGN(assign);
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
int add_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR(double, add)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR(add);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -91,10 +104,8 @@ namespace php_arma
|
|||
|
||||
int add_assign_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(double, add)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(add);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -102,10 +113,8 @@ namespace php_arma
|
|||
|
||||
int sub_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR(double, sub)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR(sub);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -113,10 +122,8 @@ namespace php_arma
|
|||
|
||||
int sub_assign_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(double, sub)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(sub);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -124,10 +131,9 @@ namespace php_arma
|
|||
|
||||
int mul_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR(double, mul)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR(mul);
|
||||
PHP_ARMA_MAPVAL_OPERATOR(mul);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -135,10 +141,8 @@ namespace php_arma
|
|||
|
||||
int mul_assign_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(double, mul)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(mul);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -146,10 +150,8 @@ namespace php_arma
|
|||
|
||||
int div_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR(double, div)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR(div);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -157,10 +159,8 @@ namespace php_arma
|
|||
|
||||
int div_assign_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(double, div)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(div);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -168,10 +168,8 @@ namespace php_arma
|
|||
|
||||
int pow_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR(double, pow)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR(pow);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -179,10 +177,8 @@ namespace php_arma
|
|||
|
||||
int pow_assign_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(double, pow)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR_ASSIGN(pow);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -190,10 +186,8 @@ namespace php_arma
|
|||
|
||||
int bw_not_handler(zend_execute_data *execute_data)
|
||||
{
|
||||
return op_handler(execute_data, [] (auto zv1, auto zv2, auto rv, auto ce) {
|
||||
PHP_ARMA_OPERATOR_BEGIN(complex_ce)
|
||||
PHP_ARMA_COMPLEX_OPERATOR(double, conj)
|
||||
PHP_ARMA_OPERATOR_END();
|
||||
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
|
||||
PHP_ARMA_COMPLEX_OPERATOR(conj);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
@ -211,6 +205,7 @@ namespace php_arma
|
|||
void operators_init()
|
||||
{
|
||||
set_op_handlers(
|
||||
std::tuple(ZEND_ASSIGN, assign_handler),
|
||||
std::tuple(ZEND_ADD, add_handler),
|
||||
std::tuple(ZEND_ASSIGN_ADD, add_assign_handler),
|
||||
std::tuple(ZEND_SUB, sub_handler),
|
||||
|
|
|
@ -106,6 +106,20 @@
|
|||
} \
|
||||
}
|
||||
|
||||
#define PHP_ARMA_OPERATOR_EX(cls, func) \
|
||||
if (instanceof_function(ce, cls::ce)) { \
|
||||
return cls::operators::func(zv1, zv2, rv); \
|
||||
}
|
||||
|
||||
#define PHP_ARMA_OPERATOR_ASSIGN_EX(cls, func) \
|
||||
if (instanceof_function(ce, cls::ce)) { \
|
||||
auto v = cls::operators::func(zv1, zv2, zv1); \
|
||||
if (rv) { \
|
||||
ZVAL_COPY(rv, zv1); \
|
||||
} \
|
||||
return v; \
|
||||
}
|
||||
|
||||
#endif // PHP_ARMA_OPERATORS
|
||||
|
||||
/// Helper macros for handling native objects.
|
||||
|
@ -198,14 +212,14 @@ namespace php_arma
|
|||
{
|
||||
// Although methods are declared in interfaces as you see in the stubs,
|
||||
// nothing is declared in the internal interface implementation.
|
||||
return ce_init<str::with_internal_prefix<Name>>(nullptr, zend_register_internal_class);
|
||||
return ce_init<str::with_internal_prefix<Name>>(nullptr, zend_register_internal_interface);
|
||||
}
|
||||
|
||||
template <const char *Name, typename... Ts>
|
||||
zend_always_inline
|
||||
zend_class_entry *interface_register(Ts... parents)
|
||||
{
|
||||
return ce_init<str::with_internal_prefix<Name>>(nullptr, zend_register_internal_class, parents...);
|
||||
return ce_init<str::with_internal_prefix<Name>>(nullptr, zend_register_internal_interface, parents...);
|
||||
}
|
||||
|
||||
template <const char *Name>
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
//
|
||||
|
||||
#include "resizable_matrix.hh"
|
||||
#include "resizable.hh"
|
||||
#include "matrix.hh"
|
||||
#include "mat.hh"
|
||||
|
||||
#include <armadillo>
|
||||
|
@ -145,7 +147,7 @@ namespace php_arma
|
|||
|
||||
void resizable_matrix_init()
|
||||
{
|
||||
resizable_matrix_ce = interface_register<resizable_matrix_php_name>();
|
||||
resizable_matrix_ce = interface_register<resizable_matrix_php_name>(resizable_ce, matrix_ce);
|
||||
}
|
||||
|
||||
PHP_ARMA_INSTANTIATE(resizable_matrix, mat);
|
||||
|
|
Reference in New Issue