From 03c78a58507f246d70cae1ce84ff61b3e8f7b1e5 Mon Sep 17 00:00:00 2001 From: CismonX Date: Thu, 30 May 2019 14:01:40 +0800 Subject: [PATCH] Implement compare functions. --- src/dense.cc | 55 +++++++++++++++++++++++++--------------------------- src/dense.hh | 27 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/dense.cc b/src/dense.cc index eb0feed..6fdb31a 100644 --- a/src/dense.cc +++ b/src/dense.cc @@ -7,70 +7,67 @@ #include "dense.hh" #include "mat.hh" -#include - namespace php_arma { template - PHP_ARMA_METHOD(dense, equals, T, ChildT) + template + zend_always_inline + void dense::compare(INTERNAL_FUNCTION_PARAMETERS, F&& func) { zval *other; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_OBJECT_DEREF(other) ZEND_PARSE_PARAMETERS_END(); - if (Z_OBJCE_P(other) != ChildT::ce) { - ex_bad_type(zval_get_type_name(getThis()), zval_get_type_name(other)); - RETURN_NULL(); - } + compare_op(getThis(), other, return_value, std::move(func)); + } - using dest_t = typename ChildT::with_int_elem_t; - using dest_native_t = typename dest_t::native_t; - auto eq = (*Z_NATIVE_OBJ_P(getThis()) == *Z_NATIVE_OBJ_P(other)).eval(); - RETVAL_OBJ(dest_t::create(std::move(arma::conv_to::from(eq)))); + template + PHP_ARMA_METHOD(dense, equals, T, ChildT) + { + compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) { + return *v1 == *v2; + }); } template PHP_ARMA_METHOD(dense, notEquals, T, ChildT) { - zval *other; - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT_DEREF(other) - ZEND_PARSE_PARAMETERS_END(); - - if (Z_OBJCE_P(other) != ChildT::ce) { - ex_bad_type(zval_get_type_name(getThis()), zval_get_type_name(other)); - RETURN_NULL(); - } - - using dest_t = typename ChildT::with_int_elem_t; - using dest_native_t = typename dest_t::native_t; - auto eq = (*Z_NATIVE_OBJ_P(getThis()) != *Z_NATIVE_OBJ_P(other)).eval(); - RETVAL_OBJ(dest_t::create(std::move(arma::conv_to::from(eq)))); + compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) { + return *v1 != *v2; + }); } template PHP_ARMA_METHOD(dense, greaterThan, T, T1) { - + compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) { + return *v1 > *v2; + }); } template PHP_ARMA_METHOD(dense, smallerThan, T, T1) { - + compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) { + return *v1 < *v2; + }); } template PHP_ARMA_METHOD(dense, notGreaterThan, T, T1) { - + compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) { + return *v1 <= *v2; + }); } template PHP_ARMA_METHOD(dense, notSmallerThan, T, T1) { - + compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) { + return *v1 >= *v2; + }); } template diff --git a/src/dense.hh b/src/dense.hh index 358ea3b..8d9bc59 100644 --- a/src/dense.hh +++ b/src/dense.hh @@ -8,9 +8,33 @@ #define PHP_ARMA_DENSE_HH #include "php_arma.hh" +#include "complex.hh" + +#include namespace php_arma { + template + 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) { + 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::from(ret)))); + } + } + template struct dense { @@ -29,6 +53,9 @@ namespace php_arma static PHP_FUNCTION(notSmallerThan); static PHP_FUNCTION(fill); static PHP_FUNCTION(imbue); + + template + static void compare(INTERNAL_FUNCTION_PARAMETERS, F&&); }; void dense_init();