|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 00002 // 00003 // or.h: Rcpp R/C++ interface class library -- 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__logical_or_h 00023 #define Rcpp__sugar__logical_or_h 00024 00025 namespace Rcpp{ 00026 namespace sugar{ 00027 00028 template <bool LHS_NA, typename LHS_T, bool RHS_NA, typename RHS_T> 00029 class Or_SingleLogicalResult_SingleLogicalResult : 00030 public SingleLogicalResult< 00031 (LHS_NA || RHS_NA) , 00032 Or_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,RHS_NA,RHS_T> 00033 > 00034 { 00035 public: 00036 typedef SingleLogicalResult<LHS_NA,LHS_T> LHS_TYPE ; 00037 typedef SingleLogicalResult<RHS_NA,RHS_T> RHS_TYPE ; 00038 typedef SingleLogicalResult< 00039 (LHS_NA || RHS_NA) , 00040 Or_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,RHS_NA,RHS_T> 00041 > BASE ; 00042 00043 Or_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : 00044 lhs(lhs_), rhs(rhs_){} ; 00045 00046 inline void apply(){ 00047 int left = lhs.get() ; 00048 if( Rcpp::traits::is_na<LGLSXP>( left ) ){ 00049 BASE::set( left ) ; 00050 } else if( left == TRUE ){ 00051 BASE::set( TRUE ) ; 00052 } else { 00053 BASE::set( rhs.get() ) ; 00054 } 00055 } 00056 00057 private: 00058 const LHS_TYPE& lhs ; 00059 const RHS_TYPE& rhs ; 00060 00061 } ; 00062 00063 // special version when we know the rhs is not NA 00064 template <bool LHS_NA, typename LHS_T, typename RHS_T> 00065 class Or_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,false,RHS_T> : 00066 public SingleLogicalResult< 00067 LHS_NA , 00068 Or_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,false,RHS_T> 00069 > 00070 { 00071 public: 00072 typedef SingleLogicalResult<LHS_NA,LHS_T> LHS_TYPE ; 00073 typedef SingleLogicalResult<false,RHS_T> RHS_TYPE ; 00074 typedef SingleLogicalResult< 00075 LHS_NA, 00076 Or_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,false,RHS_T> 00077 > BASE ; 00078 00079 Or_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : 00080 lhs(lhs_), rhs(rhs_){} ; 00081 00082 inline void apply(){ 00083 // here we know rhs does not have NA, so we start with the rhs 00084 int right = rhs.get() ; 00085 if( right == TRUE ){ 00086 BASE::set( TRUE ) ; 00087 } else { 00088 BASE::set( lhs.get() ) ; 00089 } 00090 } 00091 00092 private: 00093 const LHS_TYPE& lhs ; 00094 const RHS_TYPE& rhs ; 00095 00096 } ; 00097 00098 00099 // special version when we know the lhs is not NA 00100 template <typename LHS_T, bool RHS_NA, typename RHS_T> 00101 class Or_SingleLogicalResult_SingleLogicalResult<false,LHS_T,RHS_NA,RHS_T> : 00102 public SingleLogicalResult< 00103 RHS_NA , 00104 Or_SingleLogicalResult_SingleLogicalResult<false,LHS_T,RHS_NA,RHS_T> 00105 > 00106 { 00107 public: 00108 typedef SingleLogicalResult<false,LHS_T> LHS_TYPE ; 00109 typedef SingleLogicalResult<RHS_NA,RHS_T> RHS_TYPE ; 00110 typedef SingleLogicalResult< 00111 RHS_NA, 00112 Or_SingleLogicalResult_SingleLogicalResult<false,LHS_T,RHS_NA,RHS_T> 00113 > BASE ; 00114 00115 Or_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : 00116 lhs(lhs_), rhs(rhs_){} ; 00117 00118 inline void apply(){ 00119 // here we know lhs does not have NA, so we start with the rhs 00120 int left = lhs.get() ; 00121 if( left == TRUE ){ 00122 BASE::set( TRUE ) ; 00123 } else { 00124 BASE::set( rhs.get() ) ; 00125 } 00126 } 00127 00128 private: 00129 const LHS_TYPE& lhs ; 00130 const RHS_TYPE& rhs ; 00131 00132 } ; 00133 00134 // special version when we know both the lhs and the rhs are not NA 00135 template <typename LHS_T, typename RHS_T> 00136 class Or_SingleLogicalResult_SingleLogicalResult<false,LHS_T,false,RHS_T> : 00137 public SingleLogicalResult< 00138 false , 00139 Or_SingleLogicalResult_SingleLogicalResult<false,LHS_T,false,RHS_T> 00140 > 00141 { 00142 public: 00143 typedef SingleLogicalResult<false,LHS_T> LHS_TYPE ; 00144 typedef SingleLogicalResult<false,RHS_T> RHS_TYPE ; 00145 typedef SingleLogicalResult< 00146 false, 00147 Or_SingleLogicalResult_SingleLogicalResult<false,LHS_T,false,RHS_T> 00148 > BASE ; 00149 00150 Or_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : 00151 lhs(lhs_), rhs(rhs_){} ; 00152 00153 inline void apply(){ 00154 int left = lhs.get() ; 00155 if( left == TRUE ){ 00156 BASE::set( TRUE ) ; 00157 } else { 00158 BASE::set( rhs.get() ) ; 00159 } 00160 } 00161 00162 private: 00163 const LHS_TYPE& lhs ; 00164 const RHS_TYPE& rhs ; 00165 00166 } ; 00167 00168 00169 template <bool LHS_NA, typename LHS_T> 00170 class Or_SingleLogicalResult_bool : 00171 public SingleLogicalResult< 00172 LHS_NA , 00173 And_SingleLogicalResult_bool<LHS_NA,LHS_T> 00174 > 00175 { 00176 public: 00177 typedef SingleLogicalResult<LHS_NA,LHS_T> LHS_TYPE ; 00178 typedef SingleLogicalResult< 00179 LHS_NA , 00180 Or_SingleLogicalResult_bool<LHS_NA,LHS_T> 00181 > BASE ; 00182 00183 Or_SingleLogicalResult_bool( const LHS_TYPE& lhs_, bool rhs_) : 00184 lhs(lhs_), rhs(rhs_){} ; 00185 00186 inline void apply(){ 00187 if( rhs ){ 00188 BASE::set( TRUE ) ; 00189 } else{ 00190 BASE::set( lhs.get() ) ; 00191 } 00192 } 00193 00194 private: 00195 const LHS_TYPE& lhs ; 00196 bool rhs ; 00197 00198 } ; 00199 00200 } 00201 } 00202 00203 template <bool LHS_NA, typename LHS_T, bool RHS_NA, typename RHS_T> 00204 inline Rcpp::sugar::Or_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,RHS_NA,RHS_T> 00205 operator||( 00206 const Rcpp::sugar::SingleLogicalResult<LHS_NA,LHS_T>& lhs, 00207 const Rcpp::sugar::SingleLogicalResult<LHS_NA,LHS_T>& rhs 00208 ){ 00209 return Rcpp::sugar::Or_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,RHS_NA,RHS_T>( lhs, rhs ) ; 00210 } 00211 00212 template <bool LHS_NA, typename LHS_T> 00213 inline Rcpp::sugar::Or_SingleLogicalResult_bool<LHS_NA,LHS_T> 00214 operator||( 00215 const Rcpp::sugar::SingleLogicalResult<LHS_NA,LHS_T>& lhs, 00216 bool rhs 00217 ){ 00218 return Rcpp::sugar::Or_SingleLogicalResult_bool<LHS_NA,LHS_T>( lhs, rhs ) ; 00219 } 00220 00221 template <bool LHS_NA, typename LHS_T> 00222 inline Rcpp::sugar::Or_SingleLogicalResult_bool<LHS_NA,LHS_T> 00223 operator||( 00224 bool rhs, 00225 const Rcpp::sugar::SingleLogicalResult<LHS_NA,LHS_T>& lhs 00226 ){ 00227 return Rcpp::sugar::Or_SingleLogicalResult_bool<LHS_NA,LHS_T>( lhs, rhs ) ; 00228 } 00229 00230 #endif