2019-03-14 15:04:34 +00:00
|
|
|
//
|
|
|
|
// php-armadillo/complex.cc
|
|
|
|
//
|
|
|
|
// @Author CismonX
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "complex.hh"
|
|
|
|
|
|
|
|
namespace php_arma
|
|
|
|
{
|
2019-03-28 04:27:29 +00:00
|
|
|
template <typename T>
|
|
|
|
zend_always_inline
|
|
|
|
void property_declare(zend_class_entry *ce, const char *name)
|
|
|
|
{
|
|
|
|
zval property;
|
|
|
|
zval_set_scalar(&property, static_cast<T>(0));
|
|
|
|
zend_declare_property(ce, name, strlen(name), &property, ZEND_ACC_PUBLIC);
|
|
|
|
}
|
|
|
|
|
2019-03-14 15:04:34 +00:00
|
|
|
template <typename T>
|
2019-03-31 03:19:04 +00:00
|
|
|
PHP_ARMA_METHOD(complex, __construct, T)
|
2019-03-14 15:04:34 +00:00
|
|
|
{
|
|
|
|
zval *real, *imag;
|
|
|
|
ZEND_PARSE_PARAMETERS_START(0, 2)
|
|
|
|
Z_PARAM_OPTIONAL
|
|
|
|
Z_PARAM_ZVAL(real)
|
|
|
|
Z_PARAM_ZVAL(imag)
|
|
|
|
ZEND_PARSE_PARAMETERS_END();
|
|
|
|
|
|
|
|
auto num_args = EX_NUM_ARGS();
|
2019-03-15 15:25:24 +00:00
|
|
|
auto has_imag = num_args == 2;
|
2019-03-14 15:04:34 +00:00
|
|
|
auto has_real = num_args > 0;
|
|
|
|
|
2019-03-28 04:27:29 +00:00
|
|
|
auto current = Z_OBJ_P(getThis());
|
2019-03-14 15:04:34 +00:00
|
|
|
|
|
|
|
if (EXPECTED(has_real)) {
|
2019-03-26 11:54:58 +00:00
|
|
|
if (!zval_check_scalar<T>(real)) {
|
2019-03-15 15:25:24 +00:00
|
|
|
return;
|
2019-03-16 11:49:50 +00:00
|
|
|
}
|
2019-03-24 08:59:29 +00:00
|
|
|
object_set_property(current, 0, real);
|
2019-03-14 15:04:34 +00:00
|
|
|
if (EXPECTED(has_imag)) {
|
2019-03-26 11:54:58 +00:00
|
|
|
if (!zval_check_scalar<T>(imag)) {
|
2019-03-15 15:25:24 +00:00
|
|
|
return;
|
2019-03-16 11:49:50 +00:00
|
|
|
}
|
2019-03-24 08:59:29 +00:00
|
|
|
object_set_property(current, 1, imag);
|
2019-03-14 15:04:34 +00:00
|
|
|
}
|
|
|
|
}
|
2019-03-15 15:25:24 +00:00
|
|
|
|
2019-03-24 08:59:29 +00:00
|
|
|
current->handlers = &handlers;
|
2019-03-15 15:25:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2019-03-20 14:55:19 +00:00
|
|
|
void complex<T>::write_property(zval *obj, zval *member, zval *value, void **unused)
|
2019-03-15 15:25:24 +00:00
|
|
|
{
|
|
|
|
// Theoretically we won't get non-string values here, add type check just in case.
|
|
|
|
if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) {
|
|
|
|
zend_throw_exception(zend_ce_error, "Unexpected error. Please contact developer.", -2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (UNEXPECTED(!zval_check_scalar<T>(value))) {
|
|
|
|
return;
|
2019-03-16 11:49:50 +00:00
|
|
|
}
|
2019-03-15 15:25:24 +00:00
|
|
|
if (strcmp(Z_STRVAL_P(member), "real") == 0) {
|
|
|
|
object_set_property(Z_OBJ_P(obj), 0, value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (strcmp(Z_STRVAL_P(member), "imag") == 0) {
|
|
|
|
object_set_property(Z_OBJ_P(obj), 1, value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
zend_throw_exception_ex(zend_ce_exception, -2,
|
|
|
|
"Bad property name for %s, expected 'real' or 'imag', '%s' given.", Z_OBJNAME_P(obj), Z_STRVAL_P(member));
|
2019-03-14 15:04:34 +00:00
|
|
|
}
|
|
|
|
|
2019-03-16 11:49:50 +00:00
|
|
|
template <typename T>
|
2019-03-23 16:24:34 +00:00
|
|
|
zend_always_inline
|
2019-04-01 06:04:46 +00:00
|
|
|
void complex<T>::ce_init(zend_class_entry *parent_ce)
|
2019-03-16 11:49:50 +00:00
|
|
|
{
|
2019-04-01 06:04:46 +00:00
|
|
|
ce = class_register<php_name::val>(parent_ce, me);
|
2019-03-28 04:27:29 +00:00
|
|
|
property_declare<T>(ce, "real");
|
|
|
|
property_declare<T>(ce, "imag");
|
2019-03-20 14:55:19 +00:00
|
|
|
object_handlers_init(&handlers);
|
|
|
|
handlers.write_property = write_property;
|
2019-03-16 11:49:50 +00:00
|
|
|
}
|
|
|
|
|
2019-04-01 06:21:38 +00:00
|
|
|
PHP_ARMA_NAME_DECLARE(complex, "CxDouble", double);
|
|
|
|
|
2019-03-14 15:04:34 +00:00
|
|
|
void complex_init()
|
|
|
|
{
|
2019-04-01 06:04:46 +00:00
|
|
|
complex_ce = abstract_class_register<complex_php_name>();
|
2019-03-14 15:04:34 +00:00
|
|
|
|
2019-04-01 06:04:46 +00:00
|
|
|
complex<double>::ce_init(complex_ce);
|
2019-03-14 15:04:34 +00:00
|
|
|
}
|
|
|
|
}
|