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/complex.cc

95 lines
2.7 KiB
C++
Raw Normal View History

//
// 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);
}
template <typename T>
2019-03-23 16:24:34 +00:00
PHP_ARMA_FUNCTION(complex, __construct, T)
{
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();
auto has_imag = num_args == 2;
auto has_real = num_args > 0;
2019-03-28 04:27:29 +00:00
auto current = Z_OBJ_P(getThis());
if (EXPECTED(has_real)) {
2019-03-26 11:54:58 +00:00
if (!zval_check_scalar<T>(real)) {
return;
}
2019-03-24 08:59:29 +00:00
object_set_property(current, 0, real);
if (EXPECTED(has_imag)) {
2019-03-26 11:54:58 +00:00
if (!zval_check_scalar<T>(imag)) {
return;
}
2019-03-24 08:59:29 +00:00
object_set_property(current, 1, imag);
}
}
2019-03-24 08:59:29 +00:00
current->handlers = &handlers;
}
template <typename T>
2019-03-20 14:55:19 +00:00
void complex<T>::write_property(zval *obj, zval *member, zval *value, void **unused)
{
// 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;
}
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));
}
template <typename T>
2019-03-23 16:24:34 +00:00
zend_always_inline
void complex<T>::ce_init(const char *name, zend_class_entry *parent_ce)
{
2019-03-23 16:24:34 +00:00
ce = class_register(name, 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;
}
void complex_init()
{
2019-03-19 05:28:45 +00:00
complex_ce = abstract_class_register("Complex");
2019-03-23 16:24:34 +00:00
complex<double>::ce_init("CxDouble", complex_ce);
}
}