[Rcpp-devel] Rcpp version of c( )

Romain François romain at r-enthusiasts.com
Wed Jan 22 01:45:45 CET 2014


Le 22 janv. 2014 à 01:10, Kevin Ushey <kevinushey at gmail.com> a écrit :

> Hi Søren,
> 
> I like the idea. Currently there is nothing like that in Rcpp. It
> could be made more flexible if we:
> 
> 1. Accept a generic set of vectors that could be appropriately casted as needed,
> 2. Cast these vectors to the appropriate type if necessary,
> 3. Fill an output vector with the elements of these vectors.
> 
> Of course, we would like to be able to accept primitives as well so
> that e.g. c(x, 1, y) works so something a bit more designed would be
> nice.

there is also the problem of names, e.g. c(x, foo = 1, y). This is a big part of the problem with ::create
As a first approximation, perhaps we could ignore names. 

> There should be a flexible way to implement this using variadic
> templates, so that e.g.
> 
> template <typename T, typename... Args>
> T c( Args... args ) {
>    ...do the concatenation…
> }

I’ll discuss more on the issue you opened or if you create a branch for the feature in Rcpp11. I guess the R type must play a role, so I’d imagine an interface more like this : 

template <int RTYPE, typename... Args>
Vector<RTYPE> c( Args... args ) {
   static_assert( all types in Args are compatible with RTYPE )

   - find the final length
   - allocate a vector of that length
   - recursively iterate through args
}

Once you understand them, variadic templates are quite fun to work with. On a related note, I’ve added a structure function recently to Rcpp11. 

> Of course, this requires C++11 so it might not fit until R 3.1.0 is
> out with its C++11 support, but it could be a natural fit in Rcpp11.
> Adding the generic version in Rcpp would require code bloat
> unfortunately.

This might be fun to produce with C++11, but a massive pain with C++98. 

Romain

> -Kevin
> 
> On Tue, Jan 21, 2014 at 2:02 PM, Søren Højsgaard <sorenh at math.aau.dk> wrote:
>> Dear all,
>> 
>> I have made the following primitive "concatenate" function, because I couldn't find one in Rcpp:
>> 
>> template <const int RTYPE>
>> Vector<RTYPE> do_conc_(Vector<RTYPE> x, Vector<RTYPE> y){
>>  int nx=x.size(), n=x.size()+y.size(),i,j;
>>  Vector<RTYPE> out=no_init(n);
>>  for (i=0; i<nx; ++i){ out[ i ] = x[ i ];}
>>  for (j=i, i=0; j<n; ++j, ++i){ out[ j ] = y[i] ;}
>>  return out;
>> }
>> 
>> // [[Rcpp::export]]
>> SEXP conc( SEXP& XX_, SEXP& YY_){
>>  int type = TYPEOF(XX_) ;
>>  switch( type ){
>>  case INTSXP  : return do_conc_<INTSXP> ( XX_, YY_ ) ;
>>  case REALSXP : return do_conc_<REALSXP>( XX_, YY_ ) ;
>>  case STRSXP  : return do_conc_<STRSXP> ( XX_, YY_ ) ;
>>  case VECSXP  : return do_conc_<VECSXP> ( XX_, YY_ ) ;
>>  }
>>  return R_NilValue ;
>> }
>> 
>> As you can see it assumes that the two inputs XX_ and YY_ are of the same type, and it fails to copy names to the output. If I have missed any such functionality in Rcpp then I would be happy to know...
>> 
>> Cheers
>> Søren
>> 
>> 
>> 
>> _______________________________________________
>> 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
> _______________________________________________
> 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



More information about the Rcpp-devel mailing list