This commit is contained in:
CismonX 2019-06-06 23:56:10 +08:00
parent a5b4f5b682
commit 12d04c22db
11 changed files with 254 additions and 128 deletions

View File

@ -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());

View File

@ -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);

View File

@ -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;
});
}
};
}

View File

@ -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);

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -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);

View File

@ -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),

View File

@ -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>

View File

@ -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);