Le 19/02/13 18:19, Hadley Wickham a écrit :
Unfortunately, at the moment modules and attributes don't play together. The
attributes feature used to be built on top of modules, but this caused
issues on windows.
One thing we could perhaps negociate with JJ is recognition of the export
attribute on module. Something like :
// [[Rcpp::export]]
RCPP_MODULE(SimpleModule) {
class_<Simple>( "Simple")
.constructor<double>()
.const_method("times", &Simple::times)
;
}
or perhaps even just recognizing the RCPP_MODULE declaration.
That'd be cool!
Once we have that, you won't need the SEXP constructor or the SEXP
conversion operator, and you would only need that before your class
declaration:
RCPP_EXPOSED_CLASS(Simple)
So that as and wrap are taken care of.
Until that happens, is it possible to write my own as and wrap methods?
Hadley
Sure.
For as, You can get a Simple* using this:
Simple* obj = as_module_object<Simple>(x) ;
For the details, see as.h, this will call this:
template <typename T> object<T> as_module_object(SEXP x){
return (T*) as_module_object_internal(x) ;
}
and then this:
namespace internal{
void* as_module_object_internal(SEXP obj){
Environment env(obj) ;
SEXP xp = env.get(".pointer") ;
return R_ExternalPtrAddr(xp );
}
}
which uses the way we structured the c++ class around the reference class.
but writing RCPP_EXPOSED_AS(Simple) is enough I think so that you get
"as<Simple>" directly.
For wrap, using RCPP_EXPOSED_WRAP(Simple) will just define a class trait
that the dispatch maze uses:
#define RCPP_EXPOSED_WRAP(CLASS) namespace Rcpp{ namespace traits{
template<> struct wrap_type_traits< CLASS >{typedef
wrap_type_module_object_tag wrap_category ; } ; }}
So that wrap<Simple>( const Simple& ) dispatches to:
template <typename T>
inline SEXP wrap_dispatch( const T& object,
::Rcpp::traits::wrap_type_module_object_tag ){
return Rcpp::internal::make_new_object<T>( new T(object) ) ;
}
so you could call make_new_object directly I guess.
make_new_object is the function that actually uses the way we structured
the c++ class representation around the ref class:
namespace internal {
template <typename Class>
SEXP make_new_object( Class* ptr ){
Rcpp::XPtr<Class> xp( ptr, true ) ;
Function maker = Environment::Rcpp_namespace()[
"cpp_object_maker"] ;
return maker( typeid(Class).name() , xp ) ;
}
}
This essentially calls the R function Rcpp:::cpp_object_maker
cpp_object_maker <- function(typeid, pointer){
Class <- Rcpp:::.classes_map[[ typeid ]]
new( Class, .object_pointer = pointer )
}
Romain
--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
R Graph Gallery: http://gallery.r-enthusiasts.com
blog: http://romainfrancois.blog.free.fr
|- http://bit.ly/14LJhmm : bibtex 0.3-5
`- http://bit.ly/RE6sYH : OOP with Rcpp modules
_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel