[Rcpp-devel] Defining wrap methods for C++ classes that have data members of Rcpp types

Romain Francois romain at r-enthusiasts.com
Tue Dec 7 18:24:36 CET 2010


Le 07/12/10 18:09, Douglas Bates a écrit :
> I have created a small package available as
> http://www.stat.wisc.edu/~bates/wrap_1..0.tar.gz that uses the
> "non-intrusive" approach.
>
> Attempts to compile produce
> dtrMatrix.h:17: error: field ‘d_dat’ has incomplete type
> dtrMatrix.h:18: error: field ‘d_dimnames’ has incomplete type
> dtrMatrix.h: In member function ‘const Rcpp::NumericVector&
> dtrMatrix::dat() const’:
> dtrMatrix.h:24: error: ‘d_dat’ was not declared in this scope
> dtrMatrix.h: In member function ‘const Rcpp::List&  dtrMatrix::dimnames() const’:
> ...
>
> Apparently the forward declaration of the templated Vector class and
> the typedef are unsuccessful.
>
> I think we have been here before but did not resolve the issue.

Apparently we need to review the documentation.

The problem you have here is that you use the classes before they are 
defined (dtrMatrix has fields of type List, etc ...). It seems forward 
declaration does not give enough to the compiler.

Here is an approach. The main trick is to use the 
Rcppp::traits::is_convertible traits to ensure that conversion from 
dtrMatrix to SEXP si possible. This is used as part of the traits 
journey of wrap.


I also had to write this in two lines:

S4 s(x_) ;
dtrMatrix x(s) ;

Otherwise with your version:

dtrMatrix x( S4(x_) ) ;

The compiler believes that x is a function that takes an S4 and returns 
a dtrMatrix. If you have a copy of "Effective STL", this is explained in 
item 6 : "Be alert of C++ Most vexing parse".


As a sidenote, I don't have much experience with Matrix (the package, I 
have a bit of experience with the movie), but I understand that this 
means that Matrix objects are S4 objects. Any interest in moving them to 
C++ modules, so that the logic could be kept internal,etc ... Maybe for 
MatrixReloaded. One of the issues I would imagine is that Matrix is 
recommended so it cannot depend on Rcpp.

Romain


> On Tue, Dec 7, 2010 at 10:35 AM, Romain Francois
> <romain at r-enthusiasts.com>  wrote:
>> Yes. One cheap way to deal with this is:
>>
>> settings<- getPlugin( "Rcpp" )
>> settings$includes<- ..
>> cxxfunction( .., settings = settings )
>>
>> I'm looking at the rest of the first email now.
>>
>> Romain
>>
>> Le 07/12/10 17:32, Douglas Bates a écrit :
>>>
>>> On looking more closely I can't use cxxfunction with plugin="Rcpp" to
>>> test this because the plugin inserts
>>>
>>> #include<Rcpp.h>
>>>
>>> before the user includes and some parts in the user includes need to
>>> be declared before Rcpp.h is included.  I'll create a small package.
>>>
>>> On Tue, Dec 7, 2010 at 10:06 AM, Douglas Bates<bates at stat.wisc.edu>
>>>   wrote:
>>>>
>>>> I'm again trying to define instances of the wrap template for C++
>>>> classes that have data members defined in Rcpp.h
>>>>
>>>> A stand-alone example, which is rather lengthy, is enclosed.  In this
>>>> example I am unsuccessful in using the "intrusive" formulation
>>>> described in the "Extending Rcpp" vignette.  I will try again with the
>>>> "non-intrusive" formulation.  Other suggestions are welcome.
>>>>
>>>> library(Matrix)
>>>> library(inline)
>>>> library(Rcpp)
>>>>
>>>> incl<- '
>>>> #include<RcppCommon.h>
>>>>
>>>> namespace Rcpp {
>>>>      template<int RTYPE>    class Vector;
>>>>      template<int RTYPE>    class Matrix;
>>>>      class S4;
>>>>      typedef Vector<REALSXP>    NumericVector;
>>>>      typedef Vector<INTSXP>      IntegerVector;
>>>>      typedef Vector<VECSXP>      List;
>>>>      typedef Matrix<REALSXP>    NumericMatrix;
>>>> }
>>>>
>>>> class dtrMatrix {
>>>> protected:
>>>>     Rcpp::NumericVector d_dat;
>>>>     Rcpp::List d_dimnames;
>>>>     int d_size;                 // must be square
>>>>     bool d_upper;               // true if upper triangular
>>>>     bool d_unit;                // true if unit diagonal
>>>> public:
>>>>     dtrMatrix(Rcpp::S4&) throw (std::runtime_error);
>>>>     operator SEXP();
>>>> };
>>>>
>>>> #include<Rcpp.h>
>>>>
>>>> dtrMatrix::dtrMatrix(Rcpp::S4&    xp) throw (std::runtime_error)
>>>>     : d_dat(xp.slot("x")), d_dimnames(xp.slot("Dimnames")) {
>>>>     if (!xp.inherits("dtrMatrix"))
>>>>         throw std::runtime_error("constructor needs S4 class dtrMatrix");
>>>>     IntegerVector dd = xp.slot("Dim");
>>>>     if (dd.size() != 2 || dd[0] != dd[1])
>>>>         throw std::runtime_error("Matrix must be square");
>>>>     d_size = dd[0];
>>>>     std::string uplo = as<std::string>(xp.slot("uplo"));
>>>>     d_upper = (uplo == "U") || (uplo == "u");
>>>>     std::string diag = as<std::string>(xp.slot("diag"));
>>>>     d_unit = (diag == "U") || (diag == "u");
>>>> }
>>>>
>>>> dtrMatrix::operator SEXP() {
>>>>     Rcpp::S4 ans("dtrMatrix");
>>>>     ans.slot("x") = clone(d_dat);
>>>>     ans.slot("Dimnames") = clone(d_dimnames);
>>>>     IntegerVector dd(2);
>>>>     dd[0] = dd[1] = d_size;
>>>>     ans.slot("Dim") = dd;
>>>>     ans.slot("uplo") = d_upper ? "U" : "L";
>>>>     ans.slot("diag") = d_unit ? "U" : "N";
>>>>     return ans;
>>>> }
>>>> '
>>>>
>>>> code<- '
>>>> dtrMatrix x(S4(x_));
>>>> return wrap(x);
>>>> '
>>>> ff<- cxxfunction(signature(x_ = "ANY"), code, incl, plugin="Rcpp")
>>>>
>>>> example("dtrMatrix-class")
>>>> ff(T)
>>>>
>>> _______________________________________________
>>> Rcpp-devel mailing list
>>> Rcpp-devel at lists.r-forge.r-project.org
>>> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>>>
>>
>>
>> --
>> Romain Francois
>> Professional R Enthusiast
>> +33(0) 6 28 91 30 30
>> http://romainfrancois.blog.free.fr
>> |- http://bit.ly/fT2rZM : highlight 0.2-5
>> |- http://bit.ly/gpCSpH : Evolution of Rcpp code size
>> `- http://bit.ly/hovakS : RcppGSL initial release
>>
>>
>> _______________________________________________
>> Rcpp-devel mailing list
>> Rcpp-devel at lists.r-forge.r-project.org
>> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>>
>


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/fT2rZM : highlight 0.2-5
|- http://bit.ly/gpCSpH : Evolution of Rcpp code size
`- http://bit.ly/hovakS : RcppGSL initial release

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: doug.cpp
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20101207/041413ac/attachment.txt>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: doug.R
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20101207/041413ac/attachment.asc>


More information about the Rcpp-devel mailing list