check in R-swig changes that implement vector conversions to and
from std::vector git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12961 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
7d6da8d319
commit
800e00c9be
4 changed files with 297 additions and 5 deletions
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
|
||||
|
||||
%fragment("RSequence_Base","header",fragment="<stddef.h>")
|
||||
%fragment("StdSequenceTraits","header",fragment="<stddef.h>")
|
||||
{
|
||||
%#include <functional>
|
||||
namespace swig {
|
||||
|
|
@ -133,7 +133,7 @@ namespace swig {
|
|||
// %swig_sequence_iterator(%arg(Sequence))
|
||||
%swig_container_methods(%arg(Sequence))
|
||||
|
||||
%fragment("RSequence_Base");
|
||||
%fragment("StdSequenceTraits");
|
||||
|
||||
%extend {
|
||||
value_type pop() throw (std::out_of_range) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,35 @@
|
|||
%include <rstdcommon.swg>
|
||||
%include <std/std_common.i>
|
||||
|
||||
%define %traits_enum(Type...)
|
||||
%define %traits_ptypen(Type...)
|
||||
%fragment(SWIG_Traits_frag(Type),"header",
|
||||
fragment=SWIG_AsVal_frag(Type),
|
||||
fragment=SWIG_From_frag(Type),
|
||||
fragment="StdTraits") {
|
||||
namespace swig {
|
||||
template <> struct traits<Type > {
|
||||
typedef value_category category;
|
||||
static const char* type_name() { return #Type; }
|
||||
};
|
||||
template <> struct traits_asval<Type > {
|
||||
typedef Type value_type;
|
||||
static int asval(SEXP obj, value_type *val) {
|
||||
return SWIG_AsVal(Type)(obj, val);
|
||||
}
|
||||
};
|
||||
template <> struct traits_from<Type > {
|
||||
typedef Type value_type;
|
||||
static SEXP from(const value_type& val) {
|
||||
return SWIG_From(Type)(val);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
%enddef
|
||||
|
||||
//
|
||||
// Generates the traits for all the known primitive
|
||||
// C++ types (int, double, ...)
|
||||
//
|
||||
%apply_cpptypes(%traits_ptypen);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,269 @@
|
|||
%fragment("StdVectorTraits","header")
|
||||
// R specific swig components
|
||||
/*
|
||||
Vectors
|
||||
Thanks to Richard Beare - richard.beare@ieee.org for StdVectorTraits
|
||||
*/
|
||||
|
||||
%fragment("StdVectorTraits","header",fragment="StdSequenceTraits")
|
||||
%{
|
||||
namespace swig {
|
||||
// vectors of doubles
|
||||
template <>
|
||||
struct traits_from_ptr<std::vector<double> > {
|
||||
static SEXP from (std::vector<double > *val, int owner = 0) {
|
||||
SEXP result;
|
||||
PROTECT(result = Rf_allocVector(REALSXP, val->size()));
|
||||
for (unsigned pos = 0; pos < val->size(); pos++)
|
||||
{
|
||||
NUMERIC_POINTER(result)[pos] = ((*val)[pos]);
|
||||
}
|
||||
UNPROTECT(1);
|
||||
return(result);
|
||||
}
|
||||
};
|
||||
// vectors of floats
|
||||
template <>
|
||||
struct traits_from_ptr<std::vector<float> > {
|
||||
static SEXP from (std::vector<float > *val, int owner = 0) {
|
||||
SEXP result;
|
||||
PROTECT(result = Rf_allocVector(REALSXP, val->size()));
|
||||
for (unsigned pos = 0; pos < val->size(); pos++)
|
||||
{
|
||||
NUMERIC_POINTER(result)[pos] = ((*val)[pos]);
|
||||
}
|
||||
UNPROTECT(1);
|
||||
return(result);
|
||||
}
|
||||
};
|
||||
// vectors of unsigned int
|
||||
template <>
|
||||
struct traits_from_ptr<std::vector<unsigned int> > {
|
||||
static SEXP from (std::vector<unsigned int > *val, int owner = 0) {
|
||||
SEXP result;
|
||||
PROTECT(result = Rf_allocVector(INTSXP, val->size()));
|
||||
for (unsigned pos = 0; pos < val->size(); pos++)
|
||||
{
|
||||
INTEGER_POINTER(result)[pos] = ((*val)[pos]);
|
||||
}
|
||||
UNPROTECT(1);
|
||||
return(result);
|
||||
}
|
||||
};
|
||||
// vectors of int
|
||||
template <>
|
||||
struct traits_from_ptr<std::vector<int> > {
|
||||
static SEXP from (std::vector<int > *val, int owner = 0) {
|
||||
SEXP result;
|
||||
PROTECT(result = Rf_allocVector(INTSXP, val->size()));
|
||||
for (unsigned pos = 0; pos < val->size(); pos++)
|
||||
{
|
||||
INTEGER_POINTER(result)[pos] = ((*val)[pos]);
|
||||
}
|
||||
UNPROTECT(1);
|
||||
return(result);
|
||||
}
|
||||
};
|
||||
// vectors of bool
|
||||
template <>
|
||||
struct traits_from_ptr<std::vector<bool> > {
|
||||
static SEXP from (std::vector<bool> *val, int owner = 0) {
|
||||
SEXP result;
|
||||
PROTECT(result = Rf_allocVector(LGLSXP, val->size()));
|
||||
for (unsigned pos = 0; pos < val->size(); pos++)
|
||||
{
|
||||
LOGICAL_POINTER(result)[pos] = ((*val)[pos]);
|
||||
}
|
||||
UNPROTECT(1);
|
||||
return(result);
|
||||
//return SWIG_R_NewPointerObj(val, type_info< std::vector<T > >(), owner);
|
||||
}
|
||||
};
|
||||
// vectors of strings
|
||||
template <>
|
||||
struct traits_from_ptr<std::vector<std::basic_string<char> > > {
|
||||
static SEXP from (std::vector<std::basic_string<char> > *val, int owner = 0) {
|
||||
SEXP result;
|
||||
PROTECT(result = Rf_allocVector(STRSXP, val->size()));
|
||||
for (unsigned pos = 0; pos < val->size(); pos++)
|
||||
{
|
||||
CHARACTER_POINTER(result)[pos] = Rf_mkChar(((*val)[pos]).c_str());
|
||||
}
|
||||
UNPROTECT(1);
|
||||
return(result);
|
||||
//return SWIG_R_NewPointerObj(val, type_info< std::vector<T > >(), owner);
|
||||
}
|
||||
};
|
||||
|
||||
// catch all that does everything with vectors
|
||||
template <typename T>
|
||||
struct traits_from_ptr< std::vector< T > > {
|
||||
static SEXP from (std::vector< T > *val, int owner = 0) {
|
||||
return SWIG_R_NewPointerObj(val, type_info< std::vector< T > >(), owner);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traits_asptr < std::vector<double> > {
|
||||
static int asptr(SEXP obj, std::vector<double> **val) {
|
||||
std::vector<double> *p;
|
||||
// not sure how to check the size of the SEXP obj is correct
|
||||
unsigned int sexpsz = Rf_length(obj);
|
||||
p = new std::vector<double>(sexpsz);
|
||||
double *S = NUMERIC_POINTER(obj);
|
||||
for (unsigned pos = 0; pos < p->size(); pos++)
|
||||
{
|
||||
(*p)[pos] = static_cast<double>(S[pos]);
|
||||
}
|
||||
int res = SWIG_OK;
|
||||
if (SWIG_IsOK(res)) {
|
||||
if (val) *val = p;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traits_asptr < std::vector<float> > {
|
||||
static int asptr(SEXP obj, std::vector<float> **val) {
|
||||
std::vector<float> *p;
|
||||
// not sure how to check the size of the SEXP obj is correct
|
||||
unsigned int sexpsz = Rf_length(obj);
|
||||
p = new std::vector<float>(sexpsz);
|
||||
double *S = NUMERIC_POINTER(obj);
|
||||
for (unsigned pos = 0; pos < p->size(); pos++)
|
||||
{
|
||||
(*p)[pos] = static_cast<double>(S[pos]);
|
||||
}
|
||||
int res = SWIG_OK;
|
||||
if (SWIG_IsOK(res)) {
|
||||
if (val) *val = p;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traits_asptr < std::vector<unsigned int> > {
|
||||
static int asptr(SEXP obj, std::vector<unsigned int> **val) {
|
||||
std::vector<unsigned int> *p;
|
||||
unsigned int sexpsz = Rf_length(obj);
|
||||
p = new std::vector<unsigned int>(sexpsz);
|
||||
SEXP coerced;
|
||||
PROTECT(coerced = Rf_coerceVector(obj, INTSXP));
|
||||
int *S = INTEGER_POINTER(coerced);
|
||||
for (unsigned pos = 0; pos < p->size(); pos++)
|
||||
{
|
||||
(*p)[pos] = static_cast<unsigned int>(S[pos]);
|
||||
}
|
||||
int res = SWIG_OK;
|
||||
if (SWIG_IsOK(res)) {
|
||||
if (val) *val = p;
|
||||
}
|
||||
UNPROTECT(1);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traits_asptr < std::vector<int> > {
|
||||
static int asptr(SEXP obj, std::vector<int> **val) {
|
||||
std::vector<int> *p;
|
||||
// not sure how to check the size of the SEXP obj is correct
|
||||
int sexpsz = Rf_length(obj);
|
||||
p = new std::vector<int>(sexpsz);
|
||||
SEXP coerced;
|
||||
PROTECT(coerced = Rf_coerceVector(obj, INTSXP));
|
||||
int *S = INTEGER_POINTER(coerced);
|
||||
for (unsigned pos = 0; pos < p->size(); pos++)
|
||||
{
|
||||
(*p)[pos] = static_cast<int>(S[pos]);
|
||||
}
|
||||
int res = SWIG_OK;
|
||||
if (SWIG_IsOK(res)) {
|
||||
if (val) *val = p;
|
||||
}
|
||||
UNPROTECT(1);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
// catchall for R to vector conversion
|
||||
template <typename T>
|
||||
struct traits_asptr < std::vector<T> > {
|
||||
static int asptr(SEXP obj, std::vector<T> **val) {
|
||||
std::vector<T> *p;
|
||||
Rprintf("my asptr\n");
|
||||
int res = SWIG_R_ConvertPtr(obj, (void**)&p, type_info< std::vector<T> >(), 0);
|
||||
if (SWIG_IsOK(res)) {
|
||||
if (val) *val = p;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
%}
|
||||
|
||||
#define %swig_vector_methods(Type...) %swig_sequence_methods(Type)
|
||||
#define %swig_vector_methods_val(Type...) %swig_sequence_methods_val(Type);
|
||||
|
||||
%define %traits_type_name(Type...)
|
||||
%fragment(SWIG_Traits_frag(Type), "header",
|
||||
fragment="StdTraits",fragment="StdVectorTraits") {
|
||||
namespace swig {
|
||||
template <> struct traits< Type > {
|
||||
typedef pointer_category category;
|
||||
static const char* type_name() {
|
||||
return #Type;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
%enddef
|
||||
|
||||
%include <std/std_vector.i>
|
||||
|
||||
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<double>)
|
||||
%traits_type_name(std::vector<double>)
|
||||
%typemap("rtypecheck") std::vector<double> %{ is.numeric($arg) %}
|
||||
%typemap("rtype") std::vector<double> "numeric"
|
||||
|
||||
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<float>)
|
||||
%traits_type_name(std::vector<float>)
|
||||
%typemap("rtypecheck") std::vector<float> %{ is.numeric($arg) %}
|
||||
%typemap("rtype") std::vector<float> "numeric"
|
||||
|
||||
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<bool>);
|
||||
%traits_type_name(std::vector<bool>);
|
||||
%typemap("rtypecheck") std::vector<bool> %{ is.logical($arg) %}
|
||||
%typemap("rtype") std::vector<bool> "logical"
|
||||
|
||||
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<int>);
|
||||
%traits_type_name(std::vector<int>);
|
||||
%typemap("rtypecheck") std::vector<int>
|
||||
%{ is.integer($arg) || is.numeric($arg) %}
|
||||
%typemap("rtype") std::vector<int> "integer"
|
||||
%typemap("scoercein") std::vector<int> "$input = as.integer($input);";
|
||||
|
||||
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<unsigned int>);
|
||||
%traits_type_name(std::vector<unsigned int>);
|
||||
%typemap("rtypecheck") std::vector<unsigned int>
|
||||
%{ is.integer($arg) || is.numeric($arg) %}
|
||||
%typemap("rtype") std::vector<unsigned int> "integer"
|
||||
%typemap("scoercein") std::vector<unsigned int> "$input = as.integer($input);";
|
||||
|
||||
// we don't want these to be given R classes as they
|
||||
// have already been turned into R vectors.
|
||||
%typemap(scoerceout) std::vector<double>,
|
||||
std::vector<double> *,
|
||||
std::vector<double> &,
|
||||
std::vector<bool>,
|
||||
std::vector<bool> *,
|
||||
std::vector<bool> &,
|
||||
std::vector<unsigned int>,
|
||||
std::vector<unsigned int> *,
|
||||
std::vector<unsigned int> &
|
||||
%{ %}
|
||||
|
||||
|
||||
%include <std/std_vector.i>
|
||||
Loading…
Add table
Add a link
Reference in a new issue