// // 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 , func) \ PHP_ARMA_OPERATOR_EX(mapval_spmat , func) \ PHP_ARMA_OPERATOR_EX(mapval_sp_subview, 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 struct mapval { using sp_mapval_t = std::conditional_t, arma::SpMat_MapMat_val>; using native_t = std::conditional_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(ce, [&init_val](auto obj) { memcpy(obj, &init_val, sizeof(native_t)); return &handlers; }); } else { zobj = object_create(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 using mapval_dense = mapval; template using mapval_spmat = mapval; template using mapval_sp_subview = mapval; 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 struct mapval::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