Implement compare functions.

This commit is contained in:
CismonX 2019-05-30 14:01:40 +08:00
parent 79fbb7cb21
commit 03c78a5850
2 changed files with 53 additions and 29 deletions

View File

@ -7,70 +7,67 @@
#include "dense.hh"
#include "mat.hh"
#include <armadillo>
namespace php_arma
{
template <typename T, typename ChildT>
PHP_ARMA_METHOD(dense, equals, T, ChildT)
template <bool IsEq, typename F>
zend_always_inline
void dense<T, ChildT>::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<T, ChildT, IsEq>(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<dest_native_t>::from(eq))));
template <typename T, typename ChildT>
PHP_ARMA_METHOD(dense, equals, T, ChildT)
{
compare<true>(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) {
return *v1 == *v2;
});
}
template <typename T, typename ChildT>
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<dest_native_t>::from(eq))));
compare<true>(INTERNAL_FUNCTION_PARAM_PASSTHRU, [](auto v1, auto v2) {
return *v1 != *v2;
});
}
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;
});
}
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;
});
}
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;
});
}
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;
});
}
template <typename T, typename T1>

View File

@ -8,9 +8,33 @@
#define PHP_ARMA_DENSE_HH
#include "php_arma.hh"
#include "complex.hh"
#include <armadillo>
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
{
@ -29,6 +53,9 @@ namespace php_arma
static PHP_FUNCTION(notSmallerThan);
static PHP_FUNCTION(fill);
static PHP_FUNCTION(imbue);
template <bool, typename F>
static void compare(INTERNAL_FUNCTION_PARAMETERS, F&&);
};
void dense_init();