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

141 lines
4.0 KiB
C++

//
// php-armadillo/mapval.hh
//
// @Author CismonX
//
#ifndef PHP_ARMA_MAPVAL_HH
#define PHP_ARMA_MAPVAL_HH
#include "php_arma.hh"
#ifdef PHP_ARMA_OPERATORS
#define PHP_ARMA_MAPVAL_OPERATOR_EX(type, func) \
PHP_ARMA_OPERATOR_EX(mapval_dense <type>, func) \
PHP_ARMA_OPERATOR_EX(mapval_spmat <type>, func) \
PHP_ARMA_OPERATOR_EX(mapval_sp_subview<type>, func)
#define PHP_ARMA_MAPVAL_OPERATOR(func) \
PHP_ARMA_OPERATOR_BEGIN(scalar_ce) \
PHP_ARMA_MAPVAL_OPERATOR_EX(double, func) \
PHP_ARMA_MAPVAL_OPERATOR_EX(zend_long, func) \
PHP_ARMA_MAPVAL_OPERATOR_EX(cx_double, func) \
PHP_ARMA_OPERATOR_END()
#endif // PHP_ARMA_OPERATORS
namespace php_arma
{
template <typename T, bool IsSparse, bool IsSubview>
struct mapval
{
using sp_mapval_t = std::conditional_t<IsSubview,
arma::SpSubview_MapMat_val<T>, arma::SpMat_MapMat_val<T>>;
using native_t = std::conditional_t<IsSparse, sp_mapval_t, T*>;
struct operators;
friend void mapval_init();
zend_always_inline
static void set_val(zend_object *zobj, T val)
{
if constexpr (IsSparse) {
*ZOBJ_NATIVE(zobj) = val;
} else {
**ZOBJ_NATIVE(zobj) = val;
}
}
zend_always_inline
static T get_val(zend_object *zobj)
{
if constexpr (IsSparse) {
return *ZOBJ_NATIVE(zobj);
} else {
return **ZOBJ_NATIVE(zobj);
}
}
zend_always_inline
static zend_object *create(zval *parent, native_t init_val)
{
zend_object *zobj;
if constexpr (IsSparse) {
zobj = object_create<native_t>(ce, [&init_val](auto obj) {
memcpy(obj, &init_val, sizeof(native_t));
return &handlers;
});
} else {
zobj = object_create<native_t>(ce, [init_val](auto obj) {
*obj = init_val;
return &handlers;
});
}
object_set_property(zobj, 0, parent);
return zobj;
}
PHP_ARMA_CE_HANDLRES_DECLARE();
private:
PHP_ARMA_COMMON_DECLARE();
static PHP_FUNCTION(val);
static PHP_FUNCTION(setTo);
static void ce_init(zend_class_entry*);
};
template <typename T>
using mapval_dense = mapval<T, false, false>;
template <typename T>
using mapval_spmat = mapval<T, true, false>;
template <typename T>
using mapval_sp_subview = mapval<T, true, true>;
void mapval_init();
constexpr const char scalar_php_name[] = "Scalar";
constexpr const char mapval_php_name[] = "MapVal";
constexpr const char sp_mapval_php_name[] = "SpMapVal";
constexpr const char spsv_mapval_php_name[] = "SpSvMapVal";
inline zend_class_entry *scalar_ce;
inline zend_class_entry *mapval_ce;
inline zend_class_entry *sp_mapval_ce;
inline zend_class_entry *spsv_mapval_ce;
template <typename T, bool IsSparse, bool IsSubview>
struct mapval<T, IsSparse, IsSubview>::operators
{
zend_always_inline
static bool mul(
#if PHP_VERSION_ID < 70300
zval *zv1, zval *zv2,
#else
zval *zv2, zval *zv1,
#endif
zval *retval)
{
if (EXPECTED(Z_TYPE_P(zv1) == IS_LONG)) {
if (Z_LVAL_P(zv1) == 1) {
zval_set_scalar(retval, get_val(Z_OBJ_P(zv2)));
} else if (Z_LVAL_P(zv1) == -1) {
zval_set_scalar(retval, -get_val(Z_OBJ_P(zv2)));
} else {
return false;
}
return true;
}
return false;
}
};
}
#endif // !PHP_ARMA_MAPVAL_HH