On 7 January 2012 at 10:04, Douglas Bates wrote: | 2012/1/7 Romain François <rom...@r-enthusiasts.com>: | > Le 06/01/12 20:46, Douglas Bates a écrit : | > | >> On Fri, Jan 6, 2012 at 1:12 PM, Dirk Eddelbuettel<e...@debian.org> wrote: | >>> | >>> On 6 January 2012 at 12:59, Douglas Bates wrote: | >>> | On Fri, Jan 6, 2012 at 12:39 PM, John Chambers<j...@stat.stanford.edu> | >>> wrote: | >>> |> The "Rf_" part of the API in particular is ugly and somewhat of an | >>> add-on | >>> |> forced in a few examples by the use of some common names in the macro | >>> files. | >>> | | >>> | But, as it stands, that is a requirement when using Rcpp. | >>> | >>> Where? I can think of one propagated use, which is at the bottom of the | >>> try/catch structure where we use ::Rf_error. But the commonly used | >>> macros | >>> hide it, and we could/should obviously wrap this. | >>> | >>> Otherwise, and especially since the 'Rcpp sugar' initiative took off, I | >>> don't | >>> really touch any ::Rf_* myself anymore. Inside the Rcpp code base, sure. | >>> But | >>> not really in user-facing stuff and Rcpp applications. | >> | >> I didn't make myself clear. What I meant was that it is not possible | >> to use asInteger in Rcpp and count on the name being remapped to | >> Rf_asInteger. | >> | >>> | I think of the Rf_ part as more due to the fact that C doesn't have a | >>> | concept of namespaces so anything in the R API is at the top level | >>> | namespace leading to some conflicts. | >>> | >>> Agreed. But speaking stylistically, for the same reason that we prefer | >>> C++ | >>> versions of C header files (eg cstdint over stdint.h, cstdio over | >>> stdio.h, | >>> ...) I am with John on the preference for C++ idioms when given a choice. | >> | >> I suppose I could have just checked whether Rcpp::as<int> calls | >> Rf_asInteger. If so, everything is cool. Unfortunately, I haven't | >> been able to find that specialization. | >> | > as lives in the inst/include/Rcpp/as.h file, and we have to follow template | > wizardry: | > | > it starts from : | > | > template <typename T> T as( SEXP m_sexp) { | > return internal::as<T>( m_sexp, typename | > traits::r_type_traits<T>::r_category() ) ; | > } | > | > with T=int, so we end up calling this one: | > | > template <typename T> T as( SEXP x, ::Rcpp::traits::r_type_primitive_tag ) { | > if( ::Rf_length(x) != 1 ) throw ::Rcpp::not_compatible( | > "expecting a single value" ) ; | > const int RTYPE = ::Rcpp::traits::r_sexptype_traits<T>::rtype ; | > SEXP y = PROTECT( r_cast<RTYPE>(x) ); | > typedef typename ::Rcpp::traits::storage_type<RTYPE>::type | > STORAGE; | > T res = caster<STORAGE,T>( *r_vector_start<RTYPE,STORAGE>( y ) ) | > ; | > UNPROTECT(1) ; | > return res ; | > } | > | > | > which does the magic. There is no calls to asInteger. | | Which, to me, is the disadvantage. The asInteger function is brief, | understandable, flexible and well-tested. This may look transparent | to you but not to many others.
Let me add that it templated and valid for more types than just integer--it covers everything mapped by the r_type_primitive type so that the caster can be invoked on the matching storage type. Dirk -- "Outside of a dog, a book is a man's best friend. Inside of a dog, it is too dark to read." -- Groucho Marx _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel