Rcpp Version 0.9.10
ifelse.h
Go to the documentation of this file.
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
00002 //
00003 // ifelse.h: Rcpp R/C++ interface class library -- ifelse
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 #ifndef Rcpp__sugar__ifelse_h
00023 #define Rcpp__sugar__ifelse_h
00024 
00025 namespace Rcpp{
00026 namespace sugar{
00027 
00028 template <
00029         int RTYPE, 
00030         bool COND_NA, typename COND_T, 
00031         bool LHS_NA , typename LHS_T, 
00032         bool RHS_NA , typename RHS_T
00033         >
00034 class IfElse : public VectorBase< 
00035         RTYPE, 
00036         ( COND_NA || LHS_NA || RHS_NA ) ,
00037         IfElse<RTYPE,COND_NA,COND_T,LHS_NA,LHS_T,RHS_NA,RHS_T>
00038 > {
00039 public:         
00040         typedef Rcpp::VectorBase<LGLSXP,COND_NA,COND_T> COND_TYPE ;
00041         typedef Rcpp::VectorBase<RTYPE ,LHS_NA ,LHS_T>  LHS_TYPE ;
00042         typedef Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T>  RHS_TYPE ;
00043         typedef typename traits::storage_type<RTYPE>::type STORAGE ;
00044         
00045         // typedef typename Rcpp::traits::Extractor<RTYPE ,LHS_NA ,LHS_T>::type  LHS_EXT ;
00046         // typedef typename Rcpp::traits::Extractor<RTYPE ,RHS_NA ,RHS_T>::type  RHS_EXT ;
00047         
00048         IfElse( const COND_TYPE& cond_, const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 
00049                 cond(cond_), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {
00050                         /* FIXME : cond, lhs and rhs must all have the same size */
00051                         
00052                 RCPP_DEBUG( DEMANGLE(IfElse) ) ;        
00053         }
00054         
00055         inline STORAGE operator[]( int i ) const {
00056                 int x = cond[i] ;
00057                 if( Rcpp::traits::is_na<LGLSXP>(x) ) return x ;
00058                 if( x ) return lhs[i] ;
00059                 return rhs[i] ;
00060         }
00061         
00062         inline int size() const { return cond.size() ; }
00063                  
00064 private:
00065         const COND_TYPE& cond ;
00066         const LHS_T& lhs ;
00067         const RHS_T& rhs ;
00068         
00069 } ;
00070   
00071 template <
00072         int RTYPE, 
00073         typename COND_T, 
00074         bool LHS_NA , typename LHS_T, 
00075         bool RHS_NA , typename RHS_T
00076         >
00077 class IfElse<RTYPE,false,COND_T,LHS_NA,LHS_T,RHS_NA,RHS_T> : public VectorBase< 
00078         RTYPE, 
00079         ( LHS_NA || RHS_NA ) ,
00080         IfElse<RTYPE,false,COND_T,LHS_NA,LHS_T,RHS_NA,RHS_T>
00081 > {
00082 public:         
00083         typedef Rcpp::VectorBase<LGLSXP,false,COND_T> COND_TYPE ;
00084         typedef Rcpp::VectorBase<RTYPE ,LHS_NA ,LHS_T>  LHS_TYPE ;
00085         typedef Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T>  RHS_TYPE ;
00086         typedef typename traits::storage_type<RTYPE>::type STORAGE ;
00087         
00088         typedef typename Rcpp::traits::Extractor<RTYPE ,LHS_NA ,LHS_T>::type  LHS_EXT ;
00089         typedef typename Rcpp::traits::Extractor<RTYPE ,RHS_NA ,RHS_T>::type  RHS_EXT ;
00090         
00091         IfElse( const COND_TYPE& cond_, const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 
00092                 cond(cond_), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {
00093                         /* FIXME : cond, lhs and rhs must all have the same size */     
00094         }
00095         
00096         inline STORAGE operator[]( int i ) const {
00097                 if( cond[i] ) return lhs[i] ;
00098                 return rhs[i] ;
00099         }
00100         
00101         inline int size() const { return cond.size() ; }
00102                  
00103 private:
00104         
00105         const COND_TYPE& cond ;
00106         const LHS_EXT& lhs ;
00107         const RHS_EXT& rhs ;
00108         
00109 } ;
00110 
00111 
00112 /* ifelse( cond, primitive, Vector ) */
00113 
00114 template <
00115         int RTYPE, 
00116         bool COND_NA, typename COND_T, 
00117         bool RHS_NA , typename RHS_T
00118         >
00119 class IfElse_Primitive_Vector : public VectorBase< 
00120         RTYPE, 
00121         true ,
00122         IfElse_Primitive_Vector<RTYPE,COND_NA,COND_T,RHS_NA,RHS_T>
00123 > {
00124 public:         
00125         typedef Rcpp::VectorBase<LGLSXP,COND_NA,COND_T> COND_TYPE ;
00126         typedef Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T>  RHS_TYPE ;
00127         typedef typename traits::storage_type<RTYPE>::type STORAGE ;
00128         
00129         typedef typename Rcpp::traits::Extractor<RTYPE ,RHS_NA ,RHS_T>::type  RHS_EXT ;
00130         
00131         IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : 
00132                 cond(cond_), lhs(lhs_), rhs(rhs_.get_ref()) {
00133                         /* FIXME : cond, lhs and rhs must all have the sale size */     
00134         }
00135         
00136         inline STORAGE operator[]( int i ) const {
00137                 int x = cond[i] ;
00138                 if( Rcpp::traits::is_na<LGLSXP>(x) ) return x ;
00139                 if( x ) return lhs ;
00140                 return rhs[i] ;
00141         }
00142         
00143         inline int size() const { return cond.size() ; }
00144                  
00145 private:
00146         const COND_TYPE& cond ;
00147         STORAGE lhs ;
00148         const RHS_EXT& rhs ;
00149         
00150 } ;
00151 
00152 template <
00153         int RTYPE, 
00154         typename COND_T, 
00155         bool RHS_NA , typename RHS_T
00156         >
00157 class IfElse_Primitive_Vector<RTYPE,false,COND_T,RHS_NA,RHS_T> : public VectorBase< 
00158         RTYPE, 
00159         true,
00160         IfElse_Primitive_Vector<RTYPE,false,COND_T,RHS_NA,RHS_T>
00161 > {
00162 public:         
00163         typedef Rcpp::VectorBase<LGLSXP,false,COND_T> COND_TYPE ;
00164         typedef Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T>  RHS_TYPE ;
00165         typedef typename traits::storage_type<RTYPE>::type STORAGE ;
00166         typedef typename Rcpp::traits::Extractor<RTYPE ,RHS_NA ,RHS_T>::type  RHS_EXT ;
00167         
00168         IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : 
00169                 cond(cond_), lhs(lhs_), rhs(rhs_.get_ref()) {
00170                         /* FIXME : cond, lhs and rhs must all have the same size */     
00171         }
00172         
00173         inline STORAGE operator[]( int i ) const {
00174                 if( cond[i] ) return lhs ;
00175                 return rhs[i] ;
00176         }
00177         
00178         inline int size() const { return cond.size() ; }
00179                  
00180 private:
00181         const COND_TYPE& cond ;
00182         STORAGE lhs ;
00183         const RHS_EXT& rhs ;
00184         
00185 } ;
00186 
00187 
00188 
00189 /* ifelse( cond, Vector, primitive ) */
00190 
00191 template <
00192         int RTYPE, 
00193         bool COND_NA, typename COND_T, 
00194         bool LHS_NA , typename LHS_T
00195         >
00196 class IfElse_Vector_Primitive : public VectorBase< 
00197         RTYPE, 
00198         true ,
00199         IfElse_Vector_Primitive<RTYPE,COND_NA,COND_T,LHS_NA,LHS_T>
00200 > {
00201 public:         
00202         typedef Rcpp::VectorBase<LGLSXP,COND_NA,COND_T> COND_TYPE ;
00203         typedef Rcpp::VectorBase<RTYPE ,LHS_NA ,LHS_T>  LHS_TYPE ;
00204         typedef typename traits::storage_type<RTYPE>::type STORAGE ;
00205         typedef typename Rcpp::traits::Extractor<RTYPE ,LHS_NA ,LHS_T>::type  LHS_EXT ;
00206         
00207         IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : 
00208                 cond(cond_), lhs(lhs_.get_ref()), rhs(rhs_) {
00209                         /* FIXME : cond, lhs and rhs must all have the same size */     
00210         }
00211         
00212         inline STORAGE operator[]( int i ) const {
00213                 int x = cond[i] ;
00214                 if( Rcpp::traits::is_na<LGLSXP>(x) ) return Rcpp::traits::get_na<RTYPE>() ;
00215                 if( x ) return lhs[i] ;
00216                 return rhs ;
00217         }
00218         
00219         inline int size() const { return cond.size() ; }
00220                  
00221 private:
00222         const COND_TYPE& cond ;
00223         const LHS_EXT& lhs ;
00224         const STORAGE rhs ;
00225         
00226 } ;
00227 
00228 template <
00229         int RTYPE, 
00230         typename COND_T, 
00231         bool LHS_NA , typename LHS_T
00232         >
00233 class IfElse_Vector_Primitive<RTYPE,false,COND_T,LHS_NA,LHS_T> : public VectorBase< 
00234         RTYPE, 
00235         true ,
00236         IfElse_Vector_Primitive<RTYPE,false,COND_T,LHS_NA,LHS_T>
00237 > {
00238 public:         
00239         typedef Rcpp::VectorBase<LGLSXP,false,COND_T> COND_TYPE ;
00240         typedef Rcpp::VectorBase<RTYPE ,LHS_NA ,LHS_T>  LHS_TYPE ;
00241         typedef typename traits::storage_type<RTYPE>::type STORAGE ;
00242         typedef typename Rcpp::traits::Extractor<RTYPE ,LHS_NA ,LHS_T>::type  LHS_EXT ;
00243         
00244         IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : 
00245                 cond(cond_), lhs(lhs_.get_ref()), rhs(rhs_) {
00246                         /* FIXME : cond, lhs and rhs must all have the sale size */     
00247         }
00248         
00249         inline STORAGE operator[]( int i ) const {
00250                 if( cond[i] ) return lhs[i] ;
00251                 return rhs ;
00252         }
00253         
00254         inline int size() const { return cond.size() ; }
00255                  
00256 private:
00257         const COND_TYPE& cond ;
00258         const LHS_EXT& lhs ;
00259         const STORAGE rhs ;
00260         
00261 } ;
00262 
00263 
00264 
00265 
00266 
00267 /* ifelse( cond, primitive, primitive ) */
00268 
00269 template <
00270         int RTYPE, 
00271         bool COND_NA, typename COND_T
00272         >
00273 class IfElse_Primitive_Primitive : public VectorBase< 
00274         RTYPE, 
00275         true ,
00276         IfElse_Primitive_Primitive<RTYPE,COND_NA,COND_T>
00277 > {
00278 public:         
00279         typedef Rcpp::VectorBase<LGLSXP,COND_NA,COND_T> COND_TYPE ;
00280         typedef typename traits::storage_type<RTYPE>::type STORAGE ;
00281         
00282         IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : 
00283                 cond(cond_), lhs(lhs_), rhs(rhs_)  {
00284                         /* FIXME : cond, lhs and rhs must all have the same size */     
00285         }
00286         
00287         inline STORAGE operator[]( int i ) const {
00288                 int x = cond[i] ;
00289                 if( Rcpp::traits::is_na<LGLSXP>(x) ) return Rcpp::traits::get_na<RTYPE>() ;
00290                 return x ? lhs : rhs ;
00291         }
00292         
00293         inline int size() const { return cond.size() ; }
00294                  
00295 private:
00296         const COND_TYPE& cond ;
00297         STORAGE lhs ;
00298         STORAGE rhs ;
00299         STORAGE na ;
00300         
00301 } ;
00302 
00303 template <
00304         int RTYPE, typename COND_T
00305         >
00306 class IfElse_Primitive_Primitive<RTYPE,false,COND_T> : public VectorBase< 
00307         RTYPE, 
00308         true ,
00309         IfElse_Primitive_Primitive<RTYPE,false,COND_T>
00310 > {
00311 public:         
00312         typedef Rcpp::VectorBase<LGLSXP,false,COND_T> COND_TYPE ;
00313         typedef typename traits::storage_type<RTYPE>::type STORAGE ;
00314         
00315         IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : 
00316                 cond(cond_), lhs(lhs_), rhs(rhs_) {
00317                         /* FIXME : cond, lhs and rhs must all have the same size */     
00318         }
00319         
00320         inline STORAGE operator[]( int i ) const {
00321                 return cond[i] ? lhs : rhs ;
00322         }
00323         
00324         inline int size() const { return cond.size() ; }
00325                  
00326 private:
00327         const COND_TYPE& cond ;
00328         STORAGE lhs ;
00329         STORAGE rhs ;
00330         
00331 } ;
00332 
00333 } // sugar
00334 
00335 template <
00336         int RTYPE, 
00337         bool COND_NA, typename COND_T, 
00338         bool LHS_NA , typename LHS_T, 
00339         bool RHS_NA , typename RHS_T
00340         >
00341 inline sugar::IfElse< RTYPE,COND_NA,COND_T,LHS_NA,LHS_T,RHS_NA,RHS_T > 
00342 ifelse( 
00343         const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
00344         const Rcpp::VectorBase<RTYPE ,LHS_NA ,LHS_T>& lhs,
00345         const Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T>& rhs
00346         ){
00347         return sugar::IfElse<RTYPE,COND_NA,COND_T,LHS_NA,LHS_T,RHS_NA,RHS_T>( cond, lhs, rhs ) ;
00348 }
00349 
00350 
00351 template <
00352         int RTYPE, 
00353         bool COND_NA, typename COND_T, 
00354         bool RHS_NA , typename RHS_T
00355         >
00356 inline sugar::IfElse_Primitive_Vector< RTYPE,COND_NA,COND_T,RHS_NA,RHS_T > 
00357 ifelse( 
00358         const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
00359         typename traits::storage_type<RTYPE>::type lhs,
00360         const Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T>& rhs
00361         ){
00362         return sugar::IfElse_Primitive_Vector<RTYPE,COND_NA,COND_T,RHS_NA,RHS_T>( cond, lhs, rhs ) ;
00363 }
00364 
00365 template <
00366         int RTYPE, 
00367         bool COND_NA, typename COND_T, 
00368         bool RHS_NA , typename RHS_T
00369         >
00370 inline sugar::IfElse_Vector_Primitive< RTYPE,COND_NA,COND_T,RHS_NA,RHS_T > 
00371 ifelse( 
00372         const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
00373         const Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T>& lhs,
00374         typename traits::storage_type<RTYPE>::type rhs
00375         ){
00376         return sugar::IfElse_Vector_Primitive<RTYPE,COND_NA,COND_T,RHS_NA,RHS_T>( cond, lhs, rhs ) ;
00377 }
00378 
00379 template< 
00380         bool COND_NA, typename COND_T
00381 >
00382 inline sugar::IfElse_Primitive_Primitive< REALSXP,COND_NA,COND_T > 
00383 ifelse( 
00384         const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
00385         double lhs,
00386         double rhs
00387         ){
00388         return sugar::IfElse_Primitive_Primitive<REALSXP,COND_NA,COND_T>( cond, lhs, rhs ) ;
00389 }
00390 
00391 template< 
00392         bool COND_NA, typename COND_T
00393 >
00394 inline sugar::IfElse_Primitive_Primitive< INTSXP,COND_NA,COND_T > 
00395 ifelse( 
00396         const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
00397         int lhs,
00398         int rhs
00399         ){
00400         return sugar::IfElse_Primitive_Primitive<INTSXP,COND_NA,COND_T>( cond, lhs, rhs ) ;
00401 }
00402 
00403 template< 
00404         bool COND_NA, typename COND_T
00405 >
00406 inline sugar::IfElse_Primitive_Primitive< CPLXSXP,COND_NA,COND_T > 
00407 ifelse( 
00408         const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
00409         Rcomplex lhs,
00410         Rcomplex rhs
00411         ){
00412         return sugar::IfElse_Primitive_Primitive<CPLXSXP,COND_NA,COND_T>( cond, lhs, rhs ) ;
00413 }
00414 
00415 template< 
00416         bool COND_NA, typename COND_T
00417 >
00418 inline sugar::IfElse_Primitive_Primitive< LGLSXP,COND_NA,COND_T > 
00419 ifelse( 
00420         const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
00421         bool lhs,
00422         bool rhs
00423         ){
00424         return sugar::IfElse_Primitive_Primitive<LGLSXP,COND_NA,COND_T>( cond, lhs, rhs ) ;
00425 }
00426 
00427 
00428 } // Rcpp
00429 
00430 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines