#include <RcppEigen.h>
//[[Rcpp::depends(RcppEigen)]]

using namespace Rcpp;

typedef Eigen::Map<Eigen::MatrixXd> MapMatd;
typedef Eigen::Map<Eigen::MatrixXi> MapMati;
typedef Eigen::MappedSparseMatrix<double> MSpMat;

// [[Rcpp::export]]
SEXP getType ( SEXP XX_ ){
  int type = TYPEOF(XX_) ;
  return wrap(type);
}

template <typename TT>
SEXP do_compute( SEXP XX_ ){
  const TT X(as<TT>(XX_));
  return wrap(X.sum()); // some computation on X...
};

// [[Rcpp::export]]
SEXP compute ( SEXP XX_ ){
  int type = TYPEOF(XX_) ;
  Rf_PrintValue(wrap(type));
  switch( type ){
  case 13 : return do_compute<MapMati>(XX_); // matrix - integer 
  case 14 : return do_compute<MapMatd>(XX_); // matrix - double
  case 25 : return do_compute<MSpMat>(XX_); // dgCMatrix
  }
  return R_NilValue ;
}

// [[Rcpp::export]]
SEXP compute2 ( SEXP XX_ ){
  int type = TYPEOF(XX_) ;
  Rf_PrintValue(wrap(type));
  switch( type ){
  case INTSXP : return do_compute<MapMati>(XX_); // matrix - integer 
  case REALSXP : return do_compute<MapMatd>(XX_); // matrix - double
  case 25 : return do_compute<MSpMat>(XX_); // dgCMatrix
  }
  return R_NilValue ;
}

/*** R

library(Matrix)
m <- matrix(1:9, nrow=3)
M <- as(m, "dgCMatrix")

getType( m ); getType( M ); getType( 1 ); getType( 1L )

compute( m )   # integer
compute( 1*m ) # double
compute( M )   # sparse dgCMatrix
*/


