Support for more numeric types in std::vector for R.

This change allows R to automatically convert std::vectors of
signed and unsigned 8, 16, 32 and 64 bit integer types.

rtype, rtypecheck, scoercein and scoerceout typemaps are copied
across integer types.
This commit is contained in:
Richard Beare 2016-03-15 11:32:51 +11:00
commit 0821ec0b45

View file

@ -34,10 +34,10 @@
return(result);
}
};
// vectors of unsigned int
// vectors of unsigned 8bit int
template <>
struct traits_from_ptr<std::vector<unsigned int> > {
static SEXP from (std::vector<unsigned int > *val, int owner = 0) {
struct traits_from_ptr<std::vector<unsigned char> > {
static SEXP from (std::vector<unsigned char > *val, int owner = 0) {
SEXP result;
PROTECT(result = Rf_allocVector(INTSXP, val->size()));
for (unsigned pos = 0; pos < val->size(); pos++)
@ -48,7 +48,66 @@
return(result);
}
};
// vectors of int
// vectors of 8bit int
template <>
struct traits_from_ptr<std::vector<signed char> > {
static SEXP from (std::vector<signed char > *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 unsigned 16bit int
template <>
struct traits_from_ptr<std::vector<unsigned short int> > {
static SEXP from (std::vector<unsigned short 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 16bit int
template <>
struct traits_from_ptr<std::vector<short int> > {
static SEXP from (std::vector<short 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 32 bit 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 32bit int
template <>
struct traits_from_ptr<std::vector<int> > {
static SEXP from (std::vector<int > *val, int owner = 0) {
@ -63,6 +122,64 @@
}
};
// vectors of 64 bit unsigned int
#if defined(SWIGWORDSIZE64)
template <>
struct traits_from_ptr<std::vector<unsigned long int> > {
static SEXP from (std::vector<unsigned long 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 64 bit int
template <>
struct traits_from_ptr<std::vector<long int> > {
static SEXP from (std::vector<long 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);
}
};
#else
template <>
struct traits_from_ptr<std::vector<unsigned long long int> > {
static SEXP from (std::vector<unsigned long long 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 64 bit int
template <>
struct traits_from_ptr<std::vector<long long int> > {
static SEXP from (std::vector<long long 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);
}
};
#endif
// vectors of bool
template <>
struct traits_from_ptr<std::vector<bool> > {
@ -78,6 +195,7 @@
//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> > > {
@ -101,7 +219,7 @@
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) {
@ -142,6 +260,98 @@
}
};
// 8 bit integer types
template <>
struct traits_asptr < std::vector<unsigned char> > {
static int asptr(SEXP obj, std::vector<unsigned char> **val) {
std::vector<unsigned char> *p;
unsigned int sexpsz = Rf_length(obj);
p = new std::vector<unsigned char>(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 char>(S[pos]);
}
int res = SWIG_OK;
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
UNPROTECT(1);
return res;
}
};
template <>
struct traits_asptr < std::vector<signed char> > {
static int asptr(SEXP obj, std::vector<signed char> **val) {
std::vector<signed char> *p;
// not sure how to check the size of the SEXP obj is correct
int sexpsz = Rf_length(obj);
p = new std::vector<signed char>(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<signed char>(S[pos]);
}
int res = SWIG_OK;
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
UNPROTECT(1);
return res;
}
};
// 16 bit integer types
template <>
struct traits_asptr < std::vector<unsigned short int> > {
static int asptr(SEXP obj, std::vector<unsigned short int> **val) {
std::vector<unsigned short int> *p;
unsigned int sexpsz = Rf_length(obj);
p = new std::vector<unsigned short 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 short 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<short int> > {
static int asptr(SEXP obj, std::vector<short int> **val) {
std::vector<short int> *p;
// not sure how to check the size of the SEXP obj is correct
int sexpsz = Rf_length(obj);
p = new std::vector<short 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<short int>(S[pos]);
}
int res = SWIG_OK;
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
UNPROTECT(1);
return res;
}
};
// 32 bit integer types
template <>
struct traits_asptr < std::vector<unsigned int> > {
static int asptr(SEXP obj, std::vector<unsigned int> **val) {
@ -187,6 +397,102 @@
}
};
#if defined(SWIGWORDSIZE64)
// 64 bit integer types
template <>
struct traits_asptr < std::vector<unsigned long int> > {
static int asptr(SEXP obj, std::vector<unsigned long int> **val) {
std::vector<unsigned long int> *p;
unsigned int sexpsz = Rf_length(obj);
p = new std::vector<unsigned long 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 long 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<long int> > {
static int asptr(SEXP obj, std::vector<long int> **val) {
std::vector<long int> *p;
// not sure how to check the size of the SEXP obj is correct
int sexpsz = Rf_length(obj);
p = new std::vector<long 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<long int>(S[pos]);
}
int res = SWIG_OK;
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
UNPROTECT(1);
return res;
}
};
#else
// 64 bit integer types
template <>
struct traits_asptr < std::vector<unsigned long long int> > {
static int asptr(SEXP obj, std::vector<unsigned long long int> **val) {
std::vector<unsigned long long int> *p;
unsigned int sexpsz = Rf_length(obj);
p = new std::vector<unsigned long long 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 long long 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<long long int> > {
static int asptr(SEXP obj, std::vector<long long int> **val) {
std::vector<long long int> *p;
// not sure how to check the size of the SEXP obj is correct
int sexpsz = Rf_length(obj);
p = new std::vector<long long 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<long long int>(S[pos]);
}
int res = SWIG_OK;
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
UNPROTECT(1);
return res;
}
};
#endif
template <>
struct traits_asptr < std::vector<bool> > {
static int asptr(SEXP obj, std::vector<bool> **val) {
@ -228,7 +534,7 @@
// catch all that does everything with vectors
template <>
struct traits_from_ptr<std::vector<std::vector<unsigned int> > > {
static SEXP from (std::vector< std::vector<unsigned int > > *val, int owner = 0) {
static SEXP from (std::vector< std::vector<unsigned int> > *val, int owner = 0) {
SEXP result;
// allocate the R list
PROTECT(result = Rf_allocVector(VECSXP, val->size()));
@ -247,6 +553,7 @@
}
};
template <>
struct traits_from_ptr<std::vector<std::vector<int> > > {
static SEXP from (std::vector< std::vector<int > > *val, int owner = 0) {
@ -338,6 +645,8 @@
}
};
/////////////////////////////////////////////////////////////////
// R side
template <>
struct traits_asptr < std::vector< std::vector<unsigned int> > > {
@ -514,10 +823,12 @@
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<float>)
%traits_type_name(std::vector<float>)
%typemap("rtypecheck") std::vector<float>, std::vector<float> const, std::vector<float> const&
%{ is.numeric($arg) %}
%typemap("rtype") std::vector<float> "numeric"
%typemap("scoercein") std::vector<double>, std::vector<float> const, std::vector<float> const& "";
// reuse these for float
%typemap("rtype") std::vector<float> = std::vector<double>;
%typemap("rtypecheck") std::vector<float> = std::vector<double>;
%typemap("scoercein") std::vector<float> = std::vector<double>;
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<bool>);
%traits_type_name(std::vector<bool>);
@ -526,26 +837,94 @@
%typemap("rtype") std::vector<bool> "logical"
%typemap("scoercein") std::vector<bool> , std::vector<bool> const, std::vector<bool> const& "$input = as.logical($input);";
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<int>);
%traits_type_name(std::vector<int>);
%typemap("rtypecheck") std::vector<int> , std::vector<int> const, std::vector<int> const&
%typemap("rtypecheck") std::vector<int>, std::vector<int> const, std::vector<int> const &
%{ is.integer($arg) || is.numeric($arg) %}
%typemap("rtype") std::vector<int> "integer"
%typemap("scoercein") std::vector<int> , std::vector<int> const, std::vector<int> const& "$input = as.integer($input);";
// all the related integer vectors
// signed
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<signed char>);
%traits_type_name(std::vector<signed char>);
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<signed short>);
%traits_type_name(std::vector<signed short>);
#if defined(SWIGWORDSIZE64)
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<long int>);
%traits_type_name(std::vector<long int>);
#else
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<long long int>);
%traits_type_name(std::vector<long long int>);
#endif
// unsigned
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<unsigned char>);
%traits_type_name(std::vector<unsigned char>);
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<unsigned short>);
%traits_type_name(std::vector<unsigned short>);
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<unsigned int>);
%traits_type_name(std::vector<unsigned int>);
%typemap("rtypecheck") std::vector<unsigned int>, std::vector<unsigned int> const, std::vector<unsigned int> const&
%{ is.integer($arg) || is.numeric($arg) %}
%typemap("rtype") std::vector<unsigned int> "integer"
%typemap("scoercein") std::vector<unsigned int>, std::vector<unsigned int> const, std::vector<unsigned int> const& "$input = as.integer($input);";
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<std::vector<unsigned int> >);
%traits_type_name(std::vector< std::vector<unsigned int> >);
%typemap("rtypecheck") std::vector<std::vector<unsigned int> >, std::vector<std::vector<unsigned int> > const, std::vector<std::vector<unsigned int> >const&
%{ is.list($arg) && all(sapply($arg , is.integer) || sapply($arg, is.numeric)) %}
%typemap("rtype") std::vector<std::vector<unsigned int> > "list"
%typemap("scoercein") std::vector< std::vector<unsigned int> >, std::vector<std::vector<unsigned int> > const, std::vector<std::vector<unsigned int> >const& "$input = lapply($input, as.integer);";
#if defined(SWIGWORDSIZE64)
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<unsigned long int>);
%traits_type_name(std::vector<unsigned long int>);
#else
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<unsigned long long int>);
%traits_type_name(std::vector<unsigned long long int>);
#endif
// These R side typemaps are common for integer types
// but we can't use %apply as it will copy the C side ones too
// Also note that we don't seem to be able to use types like
// int_least8_t here.
%typemap("rtype") std::vector<signed char> = std::vector<int>;
%typemap("rtype") std::vector<signed short> = std::vector<int>;
%typemap("rtype") std::vector<unsigned char> = std::vector<int>;
%typemap("rtype") std::vector<unsigned int> = std::vector<int>;
#if defined(SWIGWORDSIZE64)
%typemap("rtype") std::vector<long int> = std::vector<int>;
%typemap("rtype") std::vector<unsigned long int> = std::vector<int>;
#else
%typemap("rtype") std::vector<long long int> = std::vector<int>;
%typemap("rtype") std::vector<unsigned long long int> = std::vector<int>;
#endif
%typemap("scoercein") std::vector<signed char> = std::vector<int>;
%typemap("scoercein") std::vector<signed short> = std::vector<int>;
%typemap("scoercein") std::vector<unsigned char> = std::vector<int>;
%typemap("scoercein") std::vector<unsigned int> = std::vector<int>;
#if defined(SWIGWORDSIZE64)
%typemap("scoercein") std::vector<long int> = std::vector<int>;
%typemap("scoercein") std::vector<unsigned long int> = std::vector<int>;
#else
%typemap("scoercein") std::vector<long long int> = std::vector<int>;
%typemap("scoercein") std::vector<unsigned long long int> = std::vector<int>;
#endif
%typemap("rtypecheck") std::vector<signed char> = std::vector<int>;
%typemap("rtypecheck") std::vector<signed short> = std::vector<int>;
%typemap("rtypecheck") std::vector<unsigned char> = std::vector<int>;
%typemap("rtypecheck") std::vector<unsigned int> = std::vector<int>;
#if defined(SWIGWORDSIZE64)
%typemap("rtypecheck") std::vector<long int> = std::vector<int>;
%typemap("rtypecheck") std::vector<unsigned long int> = std::vector<int>;
#else
%typemap("rtypecheck") std::vector<long long int> = std::vector<int>;
%typemap("rtypecheck") std::vector<unsigned long long int> = std::vector<int>;
#endif
///////////////////////////////////////////////////////////////
%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<std::vector<int> >);
%traits_type_name(std::vector< std::vector<int> >);
@ -579,14 +958,32 @@
// 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<double>*,
std::vector<double>&,
std::vector<float> ,
std::vector<float>*,
std::vector<float> ,
std::vector<signed char>,
std::vector<signed char>*,
std::vector<signed char>&,
std::vector<signed short>,
std::vector<signed short>*,
std::vector<signed short>&,
std::vector<int>,
std::vector<int>*,
std::vector<int>&,
std::vector<unsigned char>,
std::vector<unsigned char>*,
std::vector<unsigned char>&,
std::vector<unsigned short>,
std::vector<unsigned short>*,
std::vector<unsigned short>&,
std::vector<unsigned int>,
std::vector<unsigned int> *,
std::vector<unsigned int> &,
std::vector<unsigned int>*,
std::vector<unsigned int>&,
std::vector<bool>,
std::vector<bool>*,
std::vector<bool>&,
// vectors of vectors
std::vector< std::vector<unsigned int> >,
std::vector< std::vector<unsigned int> >*,
@ -603,6 +1000,24 @@
std::vector< std::vector<bool> >,
std::vector< std::vector<bool> >*,
std::vector< std::vector<bool> >&
%{ %}
#if defined(SWIGWORDSIZE64)
%typemap(scoerceout) std::vector<long int>,
std::vector<long int>*,
std::vector<long int>&,
std::vector<unsigned long int>,
std::vector<unsigned long int>*,
std::vector<unsigned long int>&
%{ %}
#else
%typemap(scoerceout) std::vector<long long int>,
std::vector<long long int>*,
std::vector<long long int>&,
std::vector<unsigned long long int>,
std::vector<unsigned long long int>*,
std::vector<unsigned long long int>&
%{ %}
#endif