Skip to content

Commit

Permalink
Better vector/C++ containers support for Scilab
Browse files Browse the repository at this point in the history
  • Loading branch information
Vincent Couvert committed Aug 24, 2012
1 parent 0d7be20 commit 6138b43
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 71 deletions.
32 changes: 16 additions & 16 deletions Lib/scilab/scicontainer.swg
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
* scicontainer.swg
*
* Scilab cell <-> C++ container wrapper (Basd on Octave version)
* Scilab list <-> C++ container wrapper (Based on Octave wrapper)
*
* This wrapper, and its iterator, allows a general use (and reuse) of
* the mapping between C++ and Scilab, thanks to the C++ templates.
Expand All @@ -24,7 +24,7 @@

%include <sciiterators.swg>

// The Octave C++ Wrap
// The Scilab C++ Wrap

%insert(header) %{
#include <stdexcept>
Expand Down Expand Up @@ -74,8 +74,8 @@ namespace std {
bool
operator()(const SciObject& v, const SciObject& w) const
{
SciObject res = do_binary_op(SciObject::op_le,v,w);
return res.is_true();
//SciObject res = do_binary_op(SciObject::op_le,v,w);
return true;//res.is_true();
}
};
}
Expand Down Expand Up @@ -191,7 +191,7 @@ namespace swig {
namespace swig
{
template <class T>
struct SciSequence_Ref // * octave can't support these, because of how assignment works
struct SciSequence_Ref // * Scilab can't support these, because of how assignment works
{
SciSequence_Ref(const SciObject& seq, int index)
: _seq(seq), _index(index)
Expand Down Expand Up @@ -489,7 +489,7 @@ namespace swig
#endif //SWIG_EXPORT_ITERATOR_METHODS
%enddef

// The octave container methods
// The Scilab container methods

%define %swig_container_methods(Container...)
%enddef
Expand Down Expand Up @@ -543,15 +543,15 @@ namespace swig
namespace swig {
template <class SciSeq, class Seq>
inline void
assign(const SciSeq& octseq, Seq* seq) {
assign(const SciSeq& sciseq, Seq* seq) {
%#ifdef SWIG_STD_NOASSIGN_STL
typedef typename SciSeq::value_type value_type;
typename SciSeq::const_iterator it = octseq.begin();
for (;it != octseq.end(); ++it) {
typename SciSeq::const_iterator it = sciseq.begin();
for (;it != sciseq.end(); ++it) {
seq->insert(seq->end(),(value_type)(*it));
}
%#else
seq->assign(octseq.begin(), octseq.end());
seq->assign(sciseq.begin(), sciseq.end());
%#endif
}

Expand All @@ -570,18 +570,18 @@ namespace swig {
}
} else if (obj.is_cell()) {
try {
SciSequence_Cont<value_type> octseq(obj);
SciSequence_Cont<value_type> sciseq(obj);
if (seq) {
sequence *pseq = new sequence();
assign(octseq, pseq);
assign(sciseq, pseq);
*seq = pseq;
return SWIG_NEWOBJ;
} else {
return octseq.check() ? SWIG_OK : SWIG_ERROR;
return sciseq.check() ? SWIG_OK : SWIG_ERROR;
}
} catch (std::exception& e) {
if (seq&&!error_state)
Scierror(999, "swig type error: %s",e.what());
error("swig type error: %s",e.what());
return SWIG_ERROR;
}
}
Expand All @@ -597,7 +597,7 @@ namespace swig {
typedef typename sequence::const_iterator const_iterator;

static SciObject from(const sequence& seq) {
#ifdef SWIG_OCTAVE_EXTRA_NATIVE_CONTAINERS
#ifdef SWIG_SCILAB_EXTRA_NATIVE_CONTAINERS
swig_type_info *desc = swig::type_info<sequence>();
if (desc && desc->clientdata) {
return SWIG_NewPointerObj(new sequence(seq), desc, SWIG_POINTER_OWN);
Expand All @@ -613,7 +613,7 @@ namespace swig {
}
return c;
} else {
Scierror(999, "swig overflow error: sequence size not valid in Scilab");
error("swig overflow error: sequence size not valid in Scilab");
return SciObject();
}
return SciObject();
Expand Down
2 changes: 1 addition & 1 deletion Lib/scilab/sciiterators.swg
Expand Up @@ -296,7 +296,7 @@ namespace swig
struct stop_iteration {};

%typemap(throws) stop_iteration {
Scierror(999, "stop_iteration exception");
error("stop_iteration exception");
SWIG_fail;
}

Expand Down
7 changes: 7 additions & 0 deletions Lib/scilab/scirun.swg
Expand Up @@ -26,3 +26,10 @@ static void SWIG_Scilab_SetOutputPosition(int _outputPosition) {

#define Scilab_Error_Occurred() 0
#define SWIG_Scilab_AddErrorMsg(msg) {;}

namespace std {
class SciObject {
public:
SciObject();
};
}
77 changes: 36 additions & 41 deletions Lib/scilab/scistdcommon.swg
@@ -1,14 +1,10 @@
// Based on Python implementation

%fragment("StdTraits","header",fragment="StdTraitsCommon")
{
namespace swig {
/*
Traits that provides the from method
*/
// Traits that provides the from method
template <class Type> struct traits_from_ptr {
static SciObject from(Type *val, int owner = 0) {
return SWIG_InternalNewPointerObj(val, type_info<Type>(), owner);
return 0; //SWIG_NewPointerObj(val, type_info<Type>(), owner);
}
};

Expand Down Expand Up @@ -41,29 +37,27 @@ namespace swig {
return traits_from_ptr<Type>::from(val, owner);
}

/*
Traits that provides the asval/as/check method
*/
// Traits that provides the asval/as/check method
template <class Type>
struct traits_asptr {
static int asptr(SciObject obj, Type **val) {
struct traits_asptr {
static int asptr(const SciObject& obj, Type **val) {
Type *p;
int res = SWIG_ConvertPtr(obj, (void**)&p, type_info<Type>(), 0);
if (SWIG_IsOK(res)) {
if (val) *val = p;
if (val) *val = p;
}
return res;
}
};
};

template <class Type>
inline int asptr(SciObject obj, Type **vptr) {
inline int asptr(const SciObject& obj, Type **vptr) {
return traits_asptr<Type>::asptr(obj, vptr);
}

template <class Type>
struct traits_asval {
static int asval(SciObject obj, Type *val) {
static int asval(const SciObject& obj, Type *val) {
if (val) {
Type *p = 0;
int res = traits_asptr<Type>::asptr(obj, &p);
Expand All @@ -86,7 +80,7 @@ namespace swig {
};

template <class Type> struct traits_asval<Type*> {
static int asval(SciObject obj, Type **val) {
static int asval(const SciObject& obj, Type **val) {
if (val) {
typedef typename noconst_traits<Type>::noconst_type noconst_type;
noconst_type *p = 0;
Expand All @@ -102,30 +96,30 @@ namespace swig {
};

template <class Type>
inline int asval(SciObject obj, Type *val) {
inline int asval(const SciObject& obj, Type *val) {
return traits_asval<Type>::asval(obj, val);
}

template <class Type>
struct traits_as<Type, value_category> {
static Type as(SciObject obj, bool throw_error) {
static Type as(const SciObject& obj, bool throw_error) {
Type v;
int res = asval(obj, &v);
if (!obj || !SWIG_IsOK(res)) {
// if (!PyErr_Occurred()) {
// ::%type_error(swig::type_name<Type>());
// }
//if (!obj.is_defined() || !SWIG_IsOK(res)) {
if (!Scilab_Error_Occurred()) {
%type_error(swig::type_name<Type>());
}
if (throw_error) throw std::invalid_argument("bad type");
}
//}
return v;
}
};

template <class Type>
struct traits_as<Type, pointer_category> {
static Type as(SciObject obj, bool throw_error) {
static Type as(const SciObject& obj, bool throw_error) {
Type *v = 0;
int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
int res = traits_asptr<Type>::asptr(obj, &v);
if (SWIG_IsOK(res) && v) {
if (SWIG_IsNewObj(res)) {
Type r(*v);
Expand All @@ -137,9 +131,9 @@ namespace swig {
} else {
// Uninitialized return value, no Type() constructor required.
static Type *v_def = (Type*) malloc(sizeof(Type));
// if (!PyErr_Occurred()) {
// %type_error(swig::type_name<Type>());
// }
if (!Scilab_Error_Occurred()) {
%type_error(swig::type_name<Type>());
}
if (throw_error) throw std::invalid_argument("bad type");
memset(v_def,0,sizeof(Type));
return *v_def;
Expand All @@ -149,44 +143,44 @@ namespace swig {

template <class Type>
struct traits_as<Type*, pointer_category> {
static Type* as(SciObject obj, bool throw_error) {
static Type* as(const SciObject& obj, bool throw_error) {
Type *v = 0;
int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
int res = traits_asptr<Type>::asptr(obj, &v);
if (SWIG_IsOK(res)) {
return v;
} else {
// if (!PyErr_Occurred()) {
// %type_error(swig::type_name<Type>());
// }
if (!Scilab_Error_Occurred()) {
%type_error(swig::type_name<Type>());
}
if (throw_error) throw std::invalid_argument("bad type");
return 0;
}
}
};

template <class Type>
inline Type as(SciObject obj, bool te = false) {
inline Type as(const SciObject& obj, bool te = false) {
return traits_as<Type, typename traits<Type>::category>::as(obj, te);
}

template <class Type>
struct traits_check<Type, value_category> {
static bool check(SciObject obj) {
int res = obj ? asval(obj, (Type *)(0)) : SWIG_ERROR;
static bool check(const SciObject& obj) {
int res = asval(obj, (Type *)(0));
return SWIG_IsOK(res) ? true : false;
}
};

template <class Type>
struct traits_check<Type, pointer_category> {
static bool check(SciObject obj) {
int res = obj ? asptr(obj, (Type **)(0)) : SWIG_ERROR;
static bool check(const SciObject& obj) {
int res = asptr(obj, (Type **)(0));
return SWIG_IsOK(res) ? true : false;
}
};

template <class Type>
inline bool check(SciObject obj) {
inline bool check(const SciObject& obj) {
return traits_check<Type, typename traits<Type>::category>::check(obj);
}
}
Expand All @@ -197,7 +191,7 @@ namespace swig {
namespace swig {
template <> struct traits_asval<Type > {
typedef Type value_type;
static int asval(SciObject obj, value_type *val) {
static int asval(const SciObject& obj, value_type *val) {
if (Check(obj)) {
if (val) *val = As(obj);
return SWIG_OK;
Expand All @@ -214,7 +208,7 @@ namespace swig {

template <>
struct traits_check<Type, value_category> {
static int check(SciObject obj) {
static int check(const SciObject& obj) {
int res = Check(obj);
return obj && res ? res : 0;
}
Expand All @@ -229,3 +223,4 @@ namespace swig {
#define specialize_std_deque(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From)
#define specialize_std_set(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From)
#define specialize_std_multiset(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From)

64 changes: 64 additions & 0 deletions Lib/scilab/scivector.i
@@ -0,0 +1,64 @@
/*
Vectors typemaps
*/

// Typemap for input arguments of type const std::vector<double> &
%typecheck(SWIG_TYPECHECK_POINTER)
const std::vector<double> &
{
// TODO
}
%typemap(in)
const std::vector<double> &
(int is_new_object=0, std::vector<double> arrayv)
{
{
SciErr sciErr;
int iRows = 0;
int iCols = 0;
int *piAddrVar = NULL;
double *pdblTmp = NULL;

/* Scilab value must be a double vector */
sciErr = getVarAddressFromPosition(pvApiCtx, $input, &piAddrVar);
if (sciErr.iErr) {
printError(&sciErr, 0);
return SWIG_ERROR;
}

if (isDoubleType(pvApiCtx, piAddrVar) && !isVarComplex(pvApiCtx, piAddrVar)) {
sciErr = getMatrixOfDouble(pvApiCtx, piAddrVar, &iRows, &iCols, &pdblTmp);
if (sciErr.iErr) {
printError(&sciErr, 0);
return SWIG_ERROR;
}
} else {
Scierror(999, _("%s: Wrong type for input argument #%d: A real vector expected.\n"), fname, $input);
return SWIG_ERROR;
}

if ((iRows!=1) && (iCols!=1)) {
Scierror(999, _("%s: Wrong size for input argument #%d: A real vector expected.\n"), fname, $input);
return SWIG_ERROR;
}
/* Copy vector contents into new allocated std::vector<double> */
arrayv = std::vector<double>(iRows*iCols);
$1 = &arrayv;
{
int arr_i = 0;
for (arr_i = 0; arr_i < iRows*iCols; ++arr_i)
arrayv[arr_i] = pdblTmp[arr_i];
}
}
}
%typemap(freearg)
const std::vector<double> &
{
// TODO
}

// Typemap for return values of type std::vector<double>
%typemap(out) std::vector<double>
{
// TODO
}

0 comments on commit 6138b43

Please sign in to comment.