r - Access "natural coercion" logic from C/C++ code -
when calling unlist
or c
, type promoted smallest type capable of representing everything:
> c(as.integer(1), 2.3, '3') [1] "1" "2.3" "3" > c(true, 5) [1] 1 5 > unlist(list(as.integer(1:5), as.complex(2:4))) [1] 1+0i 2+0i 3+0i 4+0i 5+0i 2+0i 3+0i 4+0i
how can access logic c/c++ code?
i have looked c sources of c
, unlist
, found following code in both do_c_dflt
, do_unlist
(main/bind.c
):
if (data.ans_flags & 512) mode = exprsxp; else if (data.ans_flags & 256) mode = vecsxp; else if (data.ans_flags & 128) mode = strsxp; else if (data.ans_flags & 64) mode = cplxsxp; else if (data.ans_flags & 32) mode = realsxp; else if (data.ans_flags & 16) mode = intsxp; else if (data.ans_flags & 2) mode = lglsxp; else if (data.ans_flags & 1) mode = rawsxp;
the variable data
, of type binddata
, computed routine answertype
seems define coercion logic. however, type binddata
declared in bind.c
only.
so: r's general coercion logic exported anywhere, or bound copy-paste code bind.c
? (sorry pun...)
kevin posted an article on rcpp gallery pretty close in spirit, tests explicitly using macros r's api:
#include <rcpp.h> using namespace rcpp; // [[rcpp::export]] list do_stuff( list x_ ) { list x = clone(x_); for( list::iterator = x.begin(); != x.end(); ++it ) { switch( typeof(*it) ) { case realsxp: { numericvector tmp = as<numericvector>(*it); tmp = tmp * 2; break; } case intsxp: { if( rf_isfactor(*it) ) break; // factors have type intsxp integervector tmp = as<integervector>(*it); tmp = tmp + 1; break; } default: { stop("incompatible sexp encountered;"); } } } return x; }
Comments
Post a Comment