add operator overloading for comparison

This commit is contained in:
CismonX 2019-06-08 04:03:21 +08:00
parent 05c04b4d1c
commit d8f908f88f
3 changed files with 84 additions and 14 deletions

View File

@ -12,6 +12,19 @@
#include <armadillo>
#define PHP_ARMA_DENSE_OPERATOR_EX2(cls, type, func) \
PHP_ARMA_OPERATOR_EX2((dense<type, cls<type>>), cls<type>, func)
#define PHP_ARMA_DENSE_OPERATOR_EX(cls, func) \
PHP_ARMA_DENSE_OPERATOR_EX2(cls, double, func) \
PHP_ARMA_DENSE_OPERATOR_EX2(cls, zend_long, func) \
PHP_ARMA_DENSE_OPERATOR_EX2(cls, cx_double, func)
#define PHP_ARMA_DENSE_OPERATOR(func) \
PHP_ARMA_OPERATOR_BEGIN(dense_ce) \
PHP_ARMA_DENSE_OPERATOR_EX(mat, func) \
PHP_ARMA_OPERATOR_END()
namespace php_arma
{
template <typename T, typename ChildT>

View File

@ -7,6 +7,8 @@
#include "php_arma.hh"
#include "operators.hh"
#include "complex.hh"
#include "dense.hh"
#include "mat.hh"
#include "mapval.hh"
#include <armadillo>
@ -184,6 +186,42 @@ namespace php_arma
});
}
int is_equal_handler(zend_execute_data *execute_data)
{
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
PHP_ARMA_DENSE_OPERATOR(equals);
return false;
});
}
int is_not_equal_handler(zend_execute_data *execute_data)
{
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
PHP_ARMA_DENSE_OPERATOR(not_equals);
return false;
});
}
int is_smaller_handler(zend_execute_data *execute_data)
{
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
PHP_ARMA_DENSE_OPERATOR(smaller_than);
return false;
});
}
int is_smaller_or_equal_handler(zend_execute_data *execute_data)
{
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
PHP_ARMA_DENSE_OPERATOR(not_greater_than);
return false;
});
}
template <typename... Ts>
zend_always_inline
void set_op_handlers(Ts&&... op_handlers)
@ -196,17 +234,21 @@ namespace php_arma
void operators_init()
{
set_op_handlers(
std::tuple(ZEND_ADD, add_handler),
std::tuple(ZEND_ASSIGN_ADD, add_assign_handler),
std::tuple(ZEND_SUB, sub_handler),
std::tuple(ZEND_ASSIGN_SUB, sub_assign_handler),
std::tuple(ZEND_MUL, mul_handler),
std::tuple(ZEND_ASSIGN_MUL, mul_assign_handler),
std::tuple(ZEND_DIV, div_handler),
std::tuple(ZEND_ASSIGN_DIV, div_assign_handler),
std::tuple(ZEND_POW, pow_handler),
std::tuple(ZEND_ASSIGN_POW, pow_assign_handler),
std::tuple(ZEND_BW_NOT, bw_not_handler)
std::tuple(ZEND_ADD, add_handler),
std::tuple(ZEND_ASSIGN_ADD, add_assign_handler),
std::tuple(ZEND_SUB, sub_handler),
std::tuple(ZEND_ASSIGN_SUB, sub_assign_handler),
std::tuple(ZEND_MUL, mul_handler),
std::tuple(ZEND_ASSIGN_MUL, mul_assign_handler),
std::tuple(ZEND_DIV, div_handler),
std::tuple(ZEND_ASSIGN_DIV, div_assign_handler),
std::tuple(ZEND_POW, pow_handler),
std::tuple(ZEND_ASSIGN_POW, pow_assign_handler),
std::tuple(ZEND_BW_NOT, bw_not_handler),
std::tuple(ZEND_IS_EQUAL, is_equal_handler),
std::tuple(ZEND_IS_NOT_EQUAL, is_not_equal_handler),
std::tuple(ZEND_IS_SMALLER, is_smaller_handler),
std::tuple(ZEND_IS_SMALLER_OR_EQUAL, is_smaller_or_equal_handler)
);
}
}

View File

@ -86,11 +86,15 @@
} \
}
#define PHP_ARMA_OPERATOR_EX(cls, func) \
if (instanceof_function(ce, cls::ce)) { \
return cls::operators::func(zv1, zv2, rv); \
#define PHP_ARMA_OPERATOR_EX2(base, child, func) \
if (instanceof_function(ce, child::ce)) { \
using base_t = arg_type<void(base)>::type; \
return base_t::operators::func(zv1, zv2, rv); \
}
#define PHP_ARMA_OPERATOR_EX(cls, func) \
PHP_ARMA_OPERATOR_EX2(cls, cls, func)
#define PHP_ARMA_OPERATOR_ASSIGN_EX(cls, func) \
if (instanceof_function(ce, cls::ce)) { \
auto v = cls::operators::func(zv1, zv2, zv1); \
@ -163,6 +167,17 @@ namespace php_arma
concat<internal_prefix, Str>
};
}
/// Hack for extracting type from a parentheses-enclosed macro argument.
template <typename T>
struct arg_type;
template <typename T, typename U>
struct arg_type<T(U)>
{
using type = U;
};
/// Helper functions for initializing class entry and object handlers.