From: <dr...@us...> - 2012-03-29 16:33:01
|
Revision: 12961 http://swig.svn.sourceforge.net/swig/?rev=12961&view=rev Author: drjoe Date: 2012-03-29 16:32:51 +0000 (Thu, 29 Mar 2012) Log Message: ----------- check in R-swig changes that implement vector conversions to and from std::vector Modified Paths: -------------- trunk/Examples/test-suite/r_overload_array.i trunk/Lib/r/rcontainer.swg trunk/Lib/r/std_common.i trunk/Lib/r/std_vector.i Modified: trunk/Examples/test-suite/r_overload_array.i =================================================================== --- trunk/Examples/test-suite/r_overload_array.i 2012-03-27 15:26:53 UTC (rev 12960) +++ trunk/Examples/test-suite/r_overload_array.i 2012-03-29 16:32:51 UTC (rev 12961) @@ -9,6 +9,10 @@ double bar(double w) {return w;}; double bar(double *w) {return w[0];} double bar(std::vector<double> w) {return w[0];} + + int bar_int(int w) {return w;} + int bar_int(int *w) {return w[0];} + int bar_int(std::vector<int> w) {return w[0];} }; %} Modified: trunk/Lib/r/rcontainer.swg =================================================================== --- trunk/Lib/r/rcontainer.swg 2012-03-27 15:26:53 UTC (rev 12960) +++ trunk/Lib/r/rcontainer.swg 2012-03-29 16:32:51 UTC (rev 12961) @@ -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 @@ // %swig_sequence_iterator(%arg(Sequence)) %swig_container_methods(%arg(Sequence)) - %fragment("RSequence_Base"); + %fragment("StdSequenceTraits"); %extend { value_type pop() throw (std::out_of_range) { Modified: trunk/Lib/r/std_common.i =================================================================== --- trunk/Lib/r/std_common.i 2012-03-27 15:26:53 UTC (rev 12960) +++ trunk/Lib/r/std_common.i 2012-03-29 16:32:51 UTC (rev 12961) @@ -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); + Modified: trunk/Lib/r/std_vector.i =================================================================== --- trunk/Lib/r/std_vector.i 2012-03-27 15:26:53 UTC (rev 12960) +++ trunk/Lib/r/std_vector.i 2012-03-29 16:32:51 UTC (rev 12961) @@ -1,10 +1,269 @@ -%fragment("StdVectorTraits","header") +// R specific swig components +/* + Vectors + Thanks to Richard Beare - ric...@ie... 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> -%include <std/std_vector.i> \ No newline at end of file +%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> & + %{ %} + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |