Rcpp Version 0.9.10
r_cast.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines