|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 // 00003 // rcast.h: Rcpp R/C++ interface class library -- cast from one SEXP type to another 00004 // 00005 // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 00006 // 00007 // This file is part of Rcpp. 00008 // 00009 // Rcpp is free software: you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation, either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // Rcpp is distributed in the hope that it will be useful, but 00015 // WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 00021 00022 #include <RcppCommon.h> 00023 #include <Rcpp/RObject.h> 00024 00025 namespace Rcpp{ 00026 namespace internal{ 00027 00028 template<> SEXP r_true_cast<INTSXP>(SEXP x) { 00029 switch( TYPEOF(x) ){ 00030 case REALSXP: 00031 case RAWSXP: 00032 case LGLSXP: 00033 case CPLXSXP: 00034 return Rf_coerceVector( x, INTSXP) ; 00035 default: 00036 throw ::Rcpp::not_compatible( "not compatible with INTSXP" ) ; 00037 } 00038 return R_NilValue ; /* -Wall */ 00039 } 00040 00041 template<> SEXP r_true_cast<REALSXP>( SEXP x) { 00042 switch( TYPEOF( x ) ){ 00043 case INTSXP: 00044 case LGLSXP: 00045 case CPLXSXP: 00046 case RAWSXP: 00047 return Rf_coerceVector( x, REALSXP ); 00048 default: 00049 throw ::Rcpp::not_compatible( "not compatible with REALSXP" ) ; 00050 } 00051 return R_NilValue ; /* -Wall */ 00052 } 00053 00054 template<> SEXP r_true_cast<LGLSXP>( SEXP x) { 00055 switch( TYPEOF( x ) ){ 00056 case REALSXP: 00057 case INTSXP: 00058 case CPLXSXP: 00059 case RAWSXP: 00060 return Rf_coerceVector( x, LGLSXP ); 00061 default: 00062 throw ::Rcpp::not_compatible( "not compatible with LGLSXP" ) ; 00063 } 00064 return R_NilValue ; /* -Wall */ 00065 } 00066 00067 template<> SEXP r_true_cast<RAWSXP>( SEXP x) { 00068 switch( TYPEOF( x ) ){ 00069 case LGLSXP: 00070 case REALSXP: 00071 case INTSXP: 00072 case CPLXSXP: 00073 return Rf_coerceVector( x, RAWSXP ); 00074 default: 00075 throw ::Rcpp::not_compatible( "not compatible with RAWSXP" ) ; 00076 } 00077 return R_NilValue ; /* -Wall */ 00078 } 00079 00080 00081 template<> SEXP r_true_cast<CPLXSXP>( SEXP x) { 00082 switch( TYPEOF( x ) ){ 00083 case RAWSXP: 00084 case LGLSXP: 00085 case REALSXP: 00086 case INTSXP: 00087 return Rf_coerceVector( x, CPLXSXP ); 00088 default: 00089 throw ::Rcpp::not_compatible( "not compatible with CPLXSXP" ) ; 00090 } 00091 return R_NilValue ; /* -Wall */ 00092 } 00093 00094 template<> SEXP r_true_cast<STRSXP>( SEXP x) { 00095 switch( TYPEOF( x ) ){ 00096 case CPLXSXP: 00097 case RAWSXP: 00098 case LGLSXP: 00099 case REALSXP: 00100 case INTSXP: 00101 { 00102 // return Rf_coerceVector( x, STRSXP ); 00103 // coerceVector does not work for some reason 00104 SEXP call = PROTECT( Rf_lang2( Rf_install( "as.character" ), x ) ) ; 00105 SEXP res = PROTECT( Rf_eval( call, R_GlobalEnv ) ) ; 00106 UNPROTECT(2); 00107 return res ; 00108 } 00109 case CHARSXP: 00110 return Rf_ScalarString( x ) ; 00111 case SYMSXP: 00112 return Rf_ScalarString( PRINTNAME( x ) ) ; 00113 default: 00114 throw ::Rcpp::not_compatible( "not compatible with STRSXP" ) ; 00115 } 00116 return R_NilValue ; /* -Wall */ 00117 } 00118 00119 template<> SEXP r_true_cast<VECSXP>(SEXP x) { 00120 return convert_using_rfunction(x, "as.list" ) ; 00121 } 00122 00123 template<> SEXP r_true_cast<EXPRSXP>(SEXP x) { 00124 return convert_using_rfunction(x, "as.expression" ) ; 00125 } 00126 00127 template<> SEXP r_true_cast<LISTSXP>(SEXP x) { 00128 switch( TYPEOF(x) ){ 00129 case LANGSXP: 00130 { 00131 SEXP y = R_NilValue ; 00132 PROTECT(y = Rf_duplicate( x )); 00133 SET_TYPEOF(y,LISTSXP) ; 00134 UNPROTECT(1); 00135 return y ; 00136 } 00137 default: 00138 return convert_using_rfunction(x, "as.pairlist" ) ; 00139 } 00140 00141 } 00142 00143 template<> SEXP r_true_cast<LANGSXP>(SEXP x) { 00144 return convert_using_rfunction(x, "as.call" ) ; 00145 } 00146 00147 // this was in Language.cpp before it became generated by DottedPair template class 00148 // 00149 // int n = Rf_length(lang) ; 00150 // if( n == 0 ) throw not_compatible("cannot convert to call (LANGSXP)") ; 00151 // SEXP names = RCPP_GET_NAMES(lang) ; 00152 // SEXP res, ap; 00153 // PROTECT( ap = res = Rf_allocList( n ) ) ; 00154 // for( int i=0; i<n; i++){ 00155 // SETCAR(ap, VECTOR_ELT(lang, i)); 00156 // if (names != R_NilValue && !Rf_StringBlank(STRING_ELT(names, i))){ 00157 // SET_TAG(ap, Rf_install(Rf_translateChar(STRING_ELT(names, i)))); 00158 // } 00159 // ap = CDR( ap) ; 00160 // } 00161 // UNPROTECT(1) ; 00162 // setSEXP(res) ; 00163 00164 } // namespace internal 00165 } // namespace Rcpp 00166