|
Rcpp Version 0.9.10
|
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