2019-05-25 18:21:48 +00:00
|
|
|
//
|
|
|
|
// php-armadillo/resizable.cc
|
|
|
|
//
|
|
|
|
// @Author CismonX
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "resizable.hh"
|
2019-09-20 23:23:59 +00:00
|
|
|
#include "base.hh"
|
|
|
|
#include "subview.hh"
|
|
|
|
#include "diagonal.hh"
|
2019-05-25 18:21:48 +00:00
|
|
|
#include "mat.hh"
|
2019-05-27 08:51:57 +00:00
|
|
|
#include "constants.hh"
|
2019-11-04 09:42:11 +00:00
|
|
|
#include "common/stream_utils.hh"
|
2019-05-27 08:51:57 +00:00
|
|
|
|
2019-09-20 23:23:59 +00:00
|
|
|
#include <variant>
|
|
|
|
|
2019-05-25 18:21:48 +00:00
|
|
|
namespace php_arma
|
|
|
|
{
|
2019-05-27 08:51:57 +00:00
|
|
|
#ifdef ARMA_USE_HDF5
|
|
|
|
zend_always_inline
|
|
|
|
arma::hdf5_name zend_array_to_hdf5_name(zend_array *ht)
|
|
|
|
{
|
2019-06-07 17:56:22 +00:00
|
|
|
auto fname_z = zend_hash_str_find(ht, "file_name", sizeof("file_name") - 1);
|
2019-05-27 08:51:57 +00:00
|
|
|
std::string fname(fname_z && Z_TYPE_P(fname_z) == IS_STRING ? Z_STRVAL_P(fname_z) : "");
|
|
|
|
|
2019-06-07 17:56:22 +00:00
|
|
|
auto dsname_z = zend_hash_str_find(ht, "dataset_name", sizeof("dataset_name") - 1);
|
2019-05-27 08:51:57 +00:00
|
|
|
std::string dsname(dsname_z && Z_TYPE_P(dsname_z) == IS_STRING ? Z_STRVAL_P(dsname_z) : "");
|
|
|
|
|
2019-06-07 17:56:22 +00:00
|
|
|
auto opts_z = zend_hash_str_find(ht, "options", sizeof("options") - 1);
|
2019-05-27 08:51:57 +00:00
|
|
|
arma::hdf5_opts::opts opts(opts_z && Z_TYPE_P(opts_z) == IS_LONG ? Z_LVAL_P(opts_z) : hdf5_opts::none);
|
|
|
|
|
|
|
|
return { fname, dsname, opts };
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-05-25 18:21:48 +00:00
|
|
|
template <typename T, typename T1>
|
|
|
|
PHP_ARMA_METHOD(resizable, copySize, T, T1)
|
|
|
|
{
|
2019-09-20 23:23:59 +00:00
|
|
|
zval *other;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
|
|
Z_PARAM_ZVAL(other)
|
|
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
|
2019-09-21 11:45:08 +00:00
|
|
|
if (UNEXPECTED(Z_TYPE_P(other) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(other), base_ce))) {
|
2019-09-20 23:23:59 +00:00
|
|
|
ex_bad_type(ZSTR_VAL(base_ce->name), zval_get_type_name(other));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::variant<ds::base*, ds::subview*, ds::diagview*> other_native_v;
|
2019-09-21 11:45:08 +00:00
|
|
|
if (instanceof_function(Z_OBJCE_P(other), subview_ce)) {
|
|
|
|
if (instanceof_function(Z_OBJCE_P(other), diagonal_ce)) {
|
|
|
|
other_native_v = to_native_object<ds::diagview>(Z_OBJ_P(other));
|
|
|
|
} else {
|
|
|
|
other_native_v = to_native_object<ds::subview>(Z_OBJ_P(other));
|
|
|
|
}
|
2019-09-20 23:23:59 +00:00
|
|
|
} else {
|
|
|
|
other_native_v = to_native_object<ds::base>(Z_OBJ_P(other));
|
|
|
|
}
|
2019-09-03 18:41:50 +00:00
|
|
|
|
2019-09-20 23:23:59 +00:00
|
|
|
std::visit([native = THIS_NATIVE, &other_native_v](auto other_native) {
|
|
|
|
if (std::holds_alternative<decltype(other_native)>(other_native_v)) {
|
|
|
|
native->set_size(other_native->n_rows, other_native->n_cols);
|
|
|
|
}
|
|
|
|
}, other_native_v);
|
2019-05-25 18:21:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename T1>
|
|
|
|
PHP_ARMA_METHOD(resizable, reset, T, T1)
|
|
|
|
{
|
2019-05-29 15:45:04 +00:00
|
|
|
auto native = THIS_NATIVE;
|
|
|
|
native->reset();
|
2019-05-25 18:21:48 +00:00
|
|
|
}
|
|
|
|
|
2019-09-03 18:41:50 +00:00
|
|
|
template <typename T, typename ChildT>
|
|
|
|
PHP_ARMA_METHOD(resizable, setReal, T, ChildT)
|
2019-05-25 18:21:48 +00:00
|
|
|
{
|
2019-09-03 18:41:50 +00:00
|
|
|
zval *other;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
|
|
Z_PARAM_OBJECT(other)
|
|
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
|
2019-09-04 06:24:13 +00:00
|
|
|
using pod_t = typename ChildT::with_pod_elem_t;
|
|
|
|
using n_pod_t = typename pod_t::native_t;
|
2019-05-25 18:21:48 +00:00
|
|
|
|
2019-09-04 06:24:13 +00:00
|
|
|
if (UNEXPECTED(pod_t::ce != Z_OBJCE_P(other))) {
|
|
|
|
ex_bad_type(get_type_name<pod_t>(), zval_get_type_name(other));
|
2019-09-03 18:41:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto native = THIS_NATIVE;
|
|
|
|
|
|
|
|
try {
|
2019-09-04 06:24:13 +00:00
|
|
|
native->set_real(*to_native_object<n_pod_t>(Z_OBJ_P(other)));
|
2019-09-03 18:41:50 +00:00
|
|
|
} catch (const std::logic_error& err) {
|
|
|
|
// Incompatible size.
|
|
|
|
throw_error(err.what());
|
|
|
|
}
|
2019-05-25 18:21:48 +00:00
|
|
|
}
|
|
|
|
|
2019-09-03 18:41:50 +00:00
|
|
|
template <typename T, typename ChildT>
|
|
|
|
PHP_ARMA_METHOD(resizable, setImag, T, ChildT)
|
2019-05-25 18:21:48 +00:00
|
|
|
{
|
2019-09-03 18:41:50 +00:00
|
|
|
if constexpr (std::is_same_v<T, cx_double>) {
|
|
|
|
zval *other;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
|
|
|
Z_PARAM_OBJECT(other)
|
|
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
|
2019-09-04 06:24:13 +00:00
|
|
|
using pod_t = typename ChildT::with_pod_elem_t;
|
|
|
|
using n_pod_t = typename pod_t::native_t;
|
2019-05-25 18:21:48 +00:00
|
|
|
|
2019-09-04 06:24:13 +00:00
|
|
|
if (UNEXPECTED(pod_t::ce != Z_OBJCE_P(other))) {
|
|
|
|
ex_bad_type(get_type_name<pod_t>(), zval_get_type_name(other));
|
2019-09-03 18:41:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto native = THIS_NATIVE;
|
|
|
|
|
|
|
|
try {
|
2019-09-04 06:24:13 +00:00
|
|
|
native->set_imag(*to_native_object<n_pod_t>(Z_OBJ_P(other)));
|
2019-09-03 18:41:50 +00:00
|
|
|
} catch (const std::logic_error& err) {
|
|
|
|
// Incompatible size.
|
|
|
|
throw_error(err.what());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw_error("no such operation for objects with non-complex elements");
|
|
|
|
}
|
2019-05-25 18:21:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename T1>
|
|
|
|
PHP_ARMA_METHOD(resizable, save, T, T1)
|
|
|
|
{
|
2019-05-27 08:51:57 +00:00
|
|
|
zval *dest;
|
|
|
|
zend_long file_type = file_type::arma_binary;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 2)
|
2019-06-08 10:10:20 +00:00
|
|
|
Z_PARAM_ZVAL(dest)
|
2019-05-27 08:51:57 +00:00
|
|
|
Z_PARAM_OPTIONAL
|
2019-06-07 16:07:11 +00:00
|
|
|
Z_PARAM_LONG(file_type)
|
2019-05-27 08:51:57 +00:00
|
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
|
|
|
|
auto native = THIS_NATIVE;
|
|
|
|
auto ftype = file_type::native(file_type);
|
|
|
|
|
|
|
|
zend_bool retval;
|
|
|
|
if (Z_TYPE_P(dest) == IS_STRING) {
|
|
|
|
RETURN_BOOL(native->save(Z_STRVAL_P(dest), ftype, false));
|
|
|
|
}
|
|
|
|
if (Z_TYPE_P(dest) == IS_RESOURCE) {
|
2019-06-07 17:56:22 +00:00
|
|
|
Z_OSTREAM_P(dest, os);
|
2019-06-11 10:18:40 +00:00
|
|
|
if constexpr (zval_to_iostream_supported) {
|
2019-06-07 17:56:22 +00:00
|
|
|
RETURN_BOOL(native->save(os, ftype, false));
|
|
|
|
} else {
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
2019-05-27 08:51:57 +00:00
|
|
|
}
|
|
|
|
#ifdef ARMA_USE_HDF5
|
|
|
|
if (Z_TYPE_P(dest) == IS_ARRAY) {
|
|
|
|
if (ftype != arma::file_type::hdf5_binary) {
|
|
|
|
ex_bad_type("string or resource", zval_get_type_name(dest));
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
RETURN_BOOL(native->save(zend_array_to_hdf5_name(Z_ARR_P(dest)), ftype, false));
|
|
|
|
}
|
|
|
|
ex_bad_type("string, resource or array", zval_get_type_name(dest));
|
|
|
|
#else
|
|
|
|
ex_bad_type("string or resource", zval_get_type_name(dest));
|
|
|
|
#endif // ARMA_USE_HDF5
|
|
|
|
RETURN_FALSE;
|
2019-05-25 18:21:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename T1>
|
|
|
|
PHP_ARMA_METHOD(resizable, load, T, T1)
|
|
|
|
{
|
2019-05-27 08:51:57 +00:00
|
|
|
zval *from;
|
|
|
|
zend_long file_type = file_type::auto_detect;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(1, 2)
|
2019-06-08 10:10:20 +00:00
|
|
|
Z_PARAM_ZVAL(from)
|
2019-05-27 08:51:57 +00:00
|
|
|
Z_PARAM_OPTIONAL
|
2019-06-07 16:07:11 +00:00
|
|
|
Z_PARAM_LONG(file_type)
|
2019-05-27 08:51:57 +00:00
|
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
|
|
|
|
auto native = THIS_NATIVE;
|
|
|
|
auto ftype = file_type::native(file_type);
|
|
|
|
|
|
|
|
zend_bool retval;
|
|
|
|
if (Z_TYPE_P(from) == IS_STRING) {
|
|
|
|
RETURN_BOOL(native->load(Z_STRVAL_P(from), ftype, false));
|
|
|
|
}
|
|
|
|
if (Z_TYPE_P(from) == IS_RESOURCE) {
|
2019-06-07 17:56:22 +00:00
|
|
|
Z_ISTREAM_P(from, is);
|
2019-06-11 10:18:40 +00:00
|
|
|
if constexpr (zval_to_iostream_supported) {
|
2019-06-07 17:56:22 +00:00
|
|
|
RETURN_BOOL(native->load(is, ftype, false));
|
|
|
|
} else {
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
2019-05-27 08:51:57 +00:00
|
|
|
}
|
|
|
|
#ifdef ARMA_USE_HDF5
|
|
|
|
if (Z_TYPE_P(from) == IS_ARRAY) {
|
|
|
|
if (ftype != arma::file_type::hdf5_binary) {
|
|
|
|
ex_bad_type("string or resource", zval_get_type_name(from));
|
|
|
|
RETURN_FALSE;
|
|
|
|
}
|
|
|
|
RETURN_BOOL(native->load(zend_array_to_hdf5_name(Z_ARR_P(from)), ftype, false));
|
|
|
|
}
|
|
|
|
ex_bad_type("string, resource or array", zval_get_type_name(from));
|
|
|
|
#else
|
|
|
|
ex_bad_type("string or resource", zval_get_type_name(from));
|
|
|
|
#endif // ARMA_USE_HDF5
|
|
|
|
RETURN_FALSE;
|
2019-05-25 18:21:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename T1>
|
|
|
|
PHP_ARMA_START_ME(resizable, T, T1)
|
|
|
|
PHP_ARMA_ME(copySize, ZEND_ACC_PUBLIC)
|
|
|
|
PHP_ARMA_ME(reset, ZEND_ACC_PUBLIC)
|
|
|
|
PHP_ARMA_ME(setReal, ZEND_ACC_PUBLIC)
|
|
|
|
PHP_ARMA_ME(setImag, ZEND_ACC_PUBLIC)
|
|
|
|
PHP_ARMA_ME(save, ZEND_ACC_PUBLIC)
|
|
|
|
PHP_ARMA_ME(load, ZEND_ACC_PUBLIC)
|
|
|
|
PHP_ARMA_END_ME();
|
|
|
|
|
|
|
|
void resizable_init()
|
|
|
|
{
|
|
|
|
resizable_ce = interface_register<resizable_php_name>();
|
|
|
|
}
|
|
|
|
|
|
|
|
PHP_ARMA_INSTANTIATE(resizable, mat);
|
|
|
|
}
|