Le 22/11/12 13:42, JJ Allaire a écrit :
Would something like this work? (Romain you probably know best whether
this will actually work out over a large range of scenarios as well as
if the std::string specialization would work)


#include <Rcpp.h>
using namespace Rcpp;

template<int RTYPE>
RObject unique_generic(RObject x) {
     Vector<RTYPE> vector = as<Vector<RTYPE> >(x);
     std::tr1::unordered_set<typename Vector<RTYPE>::stored_type >
                                         set(vector.begin(), vector.end());
     return wrap(set);
}

template<> RObject unique_generic<CHARSXP>(RObject x) {
   // TODO: appropriate specialization for CHARSXP (std::string)
   return x;
}

#define DISPATCH_METHOD(method, x) \
    switch(x.sexp_type()) { \
     case REALSXP: \
       return method<REALSXP>(x); \
     case INTSXP: \
       return method<INTSXP>(x); \
     case CHARSXP: \
       return method<CHARSXP>(x); \
     case LGLSXP: \
       return method<LGLSXP>(x); \
     default: \
       Rf_error("Unsupported type"); \
       return x; \
   }


// [[Rcpp::export]]
RObject unique2(RObject x) {
   DISPATCH_METHOD(unique_generic, x)
}

/*** R

unique2(c(1.0,2.4,3.3,3.3,3.3,3.3,2,2,6))

unique2(c(1,5,5,6,7))

*/

the case CHARSXP is not going to be useful. You need to handle the STRSXP case.

I've been looking at related things this morning. Right now, I can propose this:

#include <Rcpp.h>
using namespace Rcpp;

template<int RTYPE>
SEXP unique_generic( const Vector<RTYPE> vector ) {
typedef RCPP_UNORDERED_SET< typename Vector<RTYPE>::stored_type > SET ;
    SET set(vector.begin(), vector.end());
    Vector<RTYPE> out( set.size() ) ;
    std::copy( set.begin(), set.end(), out.begin() ) ;
    return out ;
}

#define DISPATCH_METHOD(method, x)  \
  switch( TYPEOF(x) ){          \
    case REALSXP:                   \
      return method<REALSXP>(x);    \
    case INTSXP:                    \
      return method<INTSXP>(x);     \
    case STRSXP:                    \
      return method<STRSXP>(x);     \
    case LGLSXP:                    \
      return method<LGLSXP>(x);     \
    default:                        \
      Rf_error("Unsupported type"); \
      return x;                     \
  }


// [[Rcpp::export]]
SEXP unique2(SEXP x) {
  DISPATCH_METHOD(unique_generic, x)
}


I'm not fully satisfied with this, and I'd like to have this instead:

template<int RTYPE>
SEXP unique_generic( const Vector<RTYPE> vector ) {
typedef RCPP_UNORDERED_SET< typename Vector<RTYPE>::stored_type > SET ;
    SET set(vector.begin(), vector.end());
    return Vector<RTYPE> out( set.begin(), set.end() ) ;
}

But the range constructor for Vector does not do what I want. I'm looking into it.

Romain

--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30

R Graph Gallery: http://gallery.r-enthusiasts.com
`- http://bit.ly/SweN1Z : SuperStorm Sandy

blog:            http://romainfrancois.blog.free.fr
|- http://bit.ly/RE6sYH : OOP with Rcpp modules
`- http://bit.ly/Thw7IK : Rcpp modules more flexible

_______________________________________________
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

Reply via email to