This commit is contained in:
CismonX 2019-03-24 16:59:29 +08:00
parent b15a04b95c
commit 965736b28f
11 changed files with 182 additions and 100 deletions

View File

@ -8,13 +8,21 @@ php:
- 7.2
- 7.3
env:
- ARMA_VERSION="9.300.2"
- ARMA_SRC="http://sourceforge.net/projects/arma/files/armadillo-${ARMA_VERSION}.tar.xz"
before_install:
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo apt-get update -qq
- wget $ARMA_SRC -O arma_src.tar.xz
- tar -Jxvf arma_src.tar.xz
install:
- sudo apt-get install -qq g++-7
- sudo apt-get install -qq g++-7 cmake
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 90
- sudo apt-get install -qq libopenblas-dev liblapack-dev libarpack2-dev libsuperlu-dev
- pushd armadillo-${ARMA_VERSION} && cmake . && make && sudo make install && popd
script:
- phpize

View File

@ -9,7 +9,7 @@ if test "$PHP_ARMA" != "no"; then
src/interfaces.cc \
src/constants.cc \
src/complex.cc \
src/subview_val.cc"
src/mapval.cc"
PHP_NEW_EXTENSION(arma, $ARMA_SRC, $ext_shared, , -std=c++17)
PHP_ADD_LIBRARY(armadillo, 1, ARMA_SHARED_LIBADD)

View File

@ -25,27 +25,27 @@ namespace php_arma
zval zero_val;
zval_set_scalar(&zero_val, static_cast<T>(0));
zval *current = getThis();
zend_object *current = Z_OBJ_P(getThis());
if (EXPECTED(has_real)) {
if (UNEXPECTED(!zval_check_scalar<T>(real))) {
return;
}
object_set_property(Z_OBJ_P(current), 0, real);
object_set_property(current, 0, real);
if (EXPECTED(has_imag)) {
if (UNEXPECTED(!zval_check_scalar<T>(imag))) {
return;
}
object_set_property(Z_OBJ_P(current), 1, imag);
object_set_property(current, 1, imag);
} else {
object_set_property(Z_OBJ_P(current), 1, &zero_val);
object_set_property(current, 1, &zero_val);
}
} else {
object_set_property(Z_OBJ_P(current), 0, &zero_val);
object_set_property(Z_OBJ_P(current), 1, &zero_val);
object_set_property(current, 0, &zero_val);
object_set_property(current, 1, &zero_val);
}
Z_OBJ_HT_P(current) = &handlers;
current->handlers = &handlers;
}
template <typename T>

View File

@ -76,7 +76,6 @@ namespace php_arma
subview_ce = interface_register(N_INT "Subview");
diagonal_ce = interface_register(N_INT "Diagonal",
base_ce, non_resizable_ce, subview_ce);
scalar_ce = interface_register(N_INT "Scalar",
subview_ce);
scalar_ce = interface_register(N_INT "Scalar");
}
}

77
src/mapval.cc Normal file
View File

@ -0,0 +1,77 @@
//
// php-armadillo/mapval.cc
//
// @Author CismonX
//
#include "mapval.hh"
#include "interfaces.hh"
#include "complex.hh"
#include <armadillo>
namespace php_arma
{
template <typename T, bool IsSparse, bool B>
zend_always_inline
T mapval<T, IsSparse, B>::get_val(zend_object *zobj)
{
if constexpr(IsSparse) {
return *to_native_object<native_t>(zobj);
} else {
return **to_native_object<native_t>(zobj);
}
}
template <typename T, bool B1, bool B2>
PHP_ARMA_FUNCTION(mapval, val, T, B1, B2)
{
zend_object *current = Z_OBJ_P(getThis());
zval_set_scalar(return_value, get_val(current));
}
template <typename T, bool B1, bool B2>
PHP_ARMA_FUNCTION(mapval, setTo, T, B1, B2)
{
zval *val;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(val)
ZEND_PARSE_PARAMETERS_END();
if (!zval_check_scalar<T>(val)) {
return;
}
zend_object *current = Z_OBJ_P(getThis());
set_val(current, zval_get_scalar<T>(val));
}
template <typename T, bool B1, bool B2>
zend_always_inline
void mapval<T, B1, B2>::ce_init(const char *name, zend_class_entry *parent_ce)
{
ce = class_register(name, parent_ce, me);
ce->create_object = object_non_constructible;
object_handlers_init(&handlers);
handlers.offset = sizeof(native_t);
handlers.clone_obj = nullptr;
}
void mapval_init()
{
mapval_ce = abstract_class_register("MapVal", scalar_ce);
mapval_dense<double >::ce_init("DMapVal", mapval_ce);
mapval_dense<zend_long>::ce_init("IMapVal", mapval_ce);
mapval_dense<cx_double>::ce_init("CxDMapVal", mapval_ce);
sp_mapval_ce = abstract_class_register("SpMapVal", scalar_ce);
mapval_spmat<double >::ce_init("SpDMapVal", sp_mapval_ce);
mapval_spmat<zend_long>::ce_init("SpIMapVal", sp_mapval_ce);
mapval_spmat<cx_double>::ce_init("SpCxDMapVal", sp_mapval_ce);
spsv_mapval_ce = abstract_class_register("SpSvMapVal", scalar_ce);
mapval_sp_subview<double >::ce_init("SpSvDMapVal", spsv_mapval_ce);
mapval_sp_subview<zend_long>::ce_init("SpSvIMapVal", spsv_mapval_ce);
mapval_sp_subview<cx_double>::ce_init("SpSvCxDMapVal", spsv_mapval_ce);
}
}

76
src/mapval.hh Normal file
View File

@ -0,0 +1,76 @@
//
// php-armadillo/subview_val.hh
//
// @Author CismonX
//
#ifndef PHP_ARMA_MAPVAL_HH
#define PHP_ARMA_MAPVAL_HH
#include "php_arma.hh"
// Forward declarations.
namespace arma
{
template <typename T>
class SpMat_MapMat_val;
template <typename T>
class SpSubview_MapMat_val;
}
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*>;
friend void mapval_init();
zend_always_inline
static void set_val(zend_object *zobj, T val)
{
if constexpr(IsSparse) {
*to_native_object<native_t>(zobj) = val;
} else {
**to_native_object<native_t>(zobj) = val;
}
}
static T get_val(zend_object*);
PHP_ARMA_CE_HANDLRES_DECLARE();
private:
static ZEND_NAMED_FUNCTION(val);
static ZEND_NAMED_FUNCTION(setTo);
static void ce_init(const char*, zend_class_entry*);
PHP_ARMA_START_ME()
PHP_ARMA_ME(val, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(setTo, ZEND_ACC_PUBLIC)
PHP_ARMA_END_ME();
};
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();
inline zend_class_entry *mapval_ce;
inline zend_class_entry *sp_mapval_ce;
inline zend_class_entry *spsv_mapval_ce;
}
#endif //!PHP_ARMA_MAPVAL_HH

View File

@ -8,7 +8,7 @@
#include "interfaces.hh"
#include "constants.hh"
#include "complex.hh"
#include "subview_val.hh"
#include "mapval.hh"
#include <ext/standard/info.h>
@ -17,6 +17,7 @@ PHP_MINIT_FUNCTION(arma)
php_arma::internal_interfaces_init();
php_arma::constants_init();
php_arma::complex_init();
php_arma::mapval_init();
return SUCCESS;
}

View File

@ -163,6 +163,13 @@ namespace php_arma
ZVAL_COPY(OBJ_PROP_NUM(obj, idx), val);
}
zend_always_inline
zend_object *object_non_constructible(zend_class_entry *ce)
{
zend_throw_exception_ex(zend_ce_error, -3,
"Class %s is not explicitly constructible.", ZSTR_VAL(ce->name));
}
/// Helper functions for handling scalar types.
template <typename>

View File

@ -1,38 +0,0 @@
//
// php-armadillo/subview_val.cc
//
// @Author CismonX
//
#include "subview_val.hh"
namespace php_arma
{
template <typename T, bool B1, bool B2>
zend_always_inline
T subview_val<T, B1, B2>::get_val(zend_object *zobj)
{
return static_cast<T>(*to_native_object<native_t>(zobj));
}
template <typename T, bool B1, bool B2>
PHP_ARMA_FUNCTION(subview_val, val, T, B1, B2)
{
zval *current = getThis();
zval_set_scalar(return_value, get_val(Z_OBJ_P(current)));
}
template <typename T, bool B1, bool B2>
PHP_ARMA_FUNCTION(subview_val, setTo, T, B1, B2)
{
}
template <typename T, bool B1, bool B2>
zend_always_inline
void subview_val<T, B1, B2>::ce_init(const char *name, zend_class_entry *parent_ce)
{
}
}

View File

@ -1,48 +0,0 @@
//
// php-armadillo/subview_val.hh
//
// @Author CismonX
//
#ifndef PHP_ARMA_SVVAL_HH
#define PHP_ARMA_SVVAL_HH
#include "php_arma.hh"
#include <armadillo>
namespace php_arma
{
template <typename T, bool IsSparse, bool IsSubview>
struct subview_val
{
using sp_svval_t = std::conditional_t<IsSubview,
arma::SpSubview_MapMat_val<T>, arma::SpMat_MapMat_val<T>>;
using native_t = std::conditional_t<IsSparse, sp_svval_t, T>;
zend_always_inline
static void set_val(zend_object *zobj, native_t &&val)
{
*to_native_object<native_t>(zobj) = std::move(val);
}
static T get_val(zend_object*);
PHP_ARMA_CE_HANDLRES_DECLARE();
private:
static ZEND_NAMED_FUNCTION(val);
static ZEND_NAMED_FUNCTION(setTo);
static void ce_init(const char*, zend_class_entry*);
PHP_ARMA_START_ME()
PHP_ARMA_ME(val, ZEND_ACC_PUBLIC)
PHP_ARMA_ME(setTo, ZEND_ACC_PUBLIC)
PHP_ARMA_END_ME();
};
}
#endif //!PHP_ARMA_SVVAL_HH

View File

@ -3,11 +3,11 @@
namespace Arma\Internal;
/**
* Interface for subviews which wraps a single scalar value.
* Interface for objects which wraps a single scalar value.
*
* @package Arma\Internal
*/
interface Scalar extends Subview
interface Scalar
{
/**
* Return a copy of the representing scalar value of this object.