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/dense.hh

139 lines
4.2 KiB
C++
Raw Normal View History

2019-05-25 18:21:48 +00:00
//
// php-armadillo/dense.hh
//
// @Author CismonX
//
#ifndef PHP_ARMA_DENSE_HH
#define PHP_ARMA_DENSE_HH
#include "php_arma.hh"
2019-05-30 06:01:40 +00:00
#include "complex.hh"
#include <armadillo>
2019-05-25 18:21:48 +00:00
#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()
2019-05-25 18:21:48 +00:00
namespace php_arma
{
template <typename T, typename ChildT>
struct dense
{
using native_t = typename ChildT::native_t;
struct operators;
2019-06-06 15:56:10 +00:00
template <bool IsEq, typename F>
zend_always_inline
static bool 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 false;
}
if constexpr (!IsEq && std::is_same_v<T, cx_double>) {
2019-06-11 10:18:40 +00:00
throw_error("no such comparation for complex elements");
2019-06-07 20:15:41 +00:00
return false;
2019-06-06 15:56:10 +00:00
} else {
2019-07-07 16:57:25 +00:00
using dest_t = typename ChildT::with_int_elem_t::orig_t;
2019-06-06 15:56:10 +00:00
using dest_native_t = typename dest_t::native_t;
2019-06-07 18:59:11 +00:00
try {
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))));
2019-06-08 10:10:20 +00:00
return true;
2019-06-07 18:59:11 +00:00
} catch (const std::logic_error& err) {
2019-06-11 10:18:40 +00:00
throw_error(err.what());
2019-06-07 20:15:41 +00:00
return false;
2019-06-07 18:59:11 +00:00
}
2019-06-06 15:56:10 +00:00
}
}
2019-05-25 18:21:48 +00:00
PHP_ARMA_COMMON_DECLARE();
private:
static PHP_FUNCTION(equals);
static PHP_FUNCTION(notEquals);
static PHP_FUNCTION(greaterThan);
static PHP_FUNCTION(smallerThan);
static PHP_FUNCTION(notGreaterThan);
static PHP_FUNCTION(notSmallerThan);
static PHP_FUNCTION(fill);
static PHP_FUNCTION(imbue);
2019-05-30 06:01:40 +00:00
template <bool, typename F>
static void compare(INTERNAL_FUNCTION_PARAMETERS, F&&);
2019-05-25 18:21:48 +00:00
};
void dense_init();
constexpr const char dense_php_name[] = "Dense";
inline zend_class_entry *dense_ce;
template <typename T, typename ChildT>
struct dense<T, ChildT>::operators
{
2019-06-06 15:56:10 +00:00
zend_always_inline
static bool equals(zval *zv1, zval *zv2, zval *retval)
{
return compare_op<true>(zv1, zv2, retval, [] (auto v1, auto v2) {
return *v1 == *v2;
});
}
zend_always_inline
static bool not_equals(zval *zv1, zval *zv2, zval *retval)
{
return compare_op<true>(zv1, zv2, retval, [] (auto v1, auto v2) {
return *v1 != *v2;
});
}
zend_always_inline
static bool greater_than(zval *zv1, zval *zv2, zval *retval)
{
return compare_op<false>(zv1, zv2, retval, [] (auto v1, auto v2) {
return *v1 > *v2;
});
}
zend_always_inline
static bool smaller_than(zval *zv1, zval *zv2, zval *retval)
{
return compare_op<false>(zv1, zv2, retval, [] (auto v1, auto v2) {
return *v1 < *v2;
});
}
zend_always_inline
static bool not_greater_than(zval *zv1, zval *zv2, zval *retval)
{
return compare_op<false>(zv1, zv2, retval, [] (auto v1, auto v2) {
return *v1 <= *v2;
});
}
zend_always_inline
static bool not_smaller_than(zval *zv1, zval *zv2, zval *retval)
{
return compare_op<false>(zv1, zv2, retval, [] (auto v1, auto v2) {
return *v1 >= *v2;
});
}
2019-05-25 18:21:48 +00:00
};
}
#endif // !PHP_ARMA_DENSE_HH