|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 00002 // 00003 // and.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_and_h 00023 #define Rcpp__sugar__logical_and_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 And_SingleLogicalResult_SingleLogicalResult : 00030 public SingleLogicalResult< 00031 (LHS_NA || RHS_NA) , 00032 And_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 And_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,RHS_NA,RHS_T> 00041 > BASE ; 00042 00043 And_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 == FALSE ){ 00051 BASE::set( FALSE ) ; 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 And_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,false,RHS_T> : 00066 public SingleLogicalResult< 00067 LHS_NA , 00068 And_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 And_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,false,RHS_T> 00077 > BASE ; 00078 00079 And_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 == FALSE ){ 00086 BASE::set( FALSE ) ; 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 And_SingleLogicalResult_SingleLogicalResult<false,LHS_T,RHS_NA,RHS_T> : 00102 public SingleLogicalResult< 00103 RHS_NA , 00104 And_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 And_SingleLogicalResult_SingleLogicalResult<false,LHS_T,RHS_NA,RHS_T> 00113 > BASE ; 00114 00115 And_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 == FALSE ){ 00122 BASE::set( FALSE ) ; 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 And_SingleLogicalResult_SingleLogicalResult<false,LHS_T,false,RHS_T> : 00137 public SingleLogicalResult< 00138 false , 00139 And_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 And_SingleLogicalResult_SingleLogicalResult<false,LHS_T,false,RHS_T> 00148 > BASE ; 00149 00150 And_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 == FALSE ){ 00156 BASE::set( FALSE ) ; 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 00170 template <bool LHS_NA, typename LHS_T> 00171 class And_SingleLogicalResult_bool : 00172 public SingleLogicalResult< 00173 LHS_NA , 00174 And_SingleLogicalResult_bool<LHS_NA,LHS_T> 00175 > 00176 { 00177 public: 00178 typedef SingleLogicalResult<LHS_NA,LHS_T> LHS_TYPE ; 00179 typedef SingleLogicalResult< 00180 LHS_NA , 00181 And_SingleLogicalResult_bool<LHS_NA,LHS_T> 00182 > BASE ; 00183 00184 And_SingleLogicalResult_bool( const LHS_TYPE& lhs_, bool rhs_) : 00185 lhs(lhs_), rhs(rhs_){} ; 00186 00187 inline void apply(){ 00188 if( !rhs ){ 00189 BASE::set( FALSE ) ; 00190 } else{ 00191 BASE::set( lhs.get() ) ; 00192 } 00193 } 00194 00195 private: 00196 const LHS_TYPE& lhs ; 00197 bool rhs ; 00198 00199 } ; 00200 00201 00202 } 00203 } 00204 00205 template <bool LHS_NA, typename LHS_T, bool RHS_NA, typename RHS_T> 00206 inline Rcpp::sugar::And_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,RHS_NA,RHS_T> 00207 operator&&( 00208 const Rcpp::sugar::SingleLogicalResult<LHS_NA,LHS_T>& lhs, 00209 const Rcpp::sugar::SingleLogicalResult<LHS_NA,LHS_T>& rhs 00210 ){ 00211 return Rcpp::sugar::And_SingleLogicalResult_SingleLogicalResult<LHS_NA,LHS_T,RHS_NA,RHS_T>( lhs, rhs ) ; 00212 } 00213 00214 template <bool LHS_NA, typename LHS_T> 00215 inline Rcpp::sugar::And_SingleLogicalResult_bool<LHS_NA,LHS_T> 00216 operator&&( 00217 const Rcpp::sugar::SingleLogicalResult<LHS_NA,LHS_T>& lhs, 00218 bool rhs 00219 ){ 00220 return Rcpp::sugar::And_SingleLogicalResult_bool<LHS_NA,LHS_T>( lhs, rhs ) ; 00221 } 00222 00223 template <bool LHS_NA, typename LHS_T> 00224 inline Rcpp::sugar::And_SingleLogicalResult_bool<LHS_NA,LHS_T> 00225 operator&&( 00226 bool rhs, 00227 const Rcpp::sugar::SingleLogicalResult<LHS_NA,LHS_T>& lhs 00228 ){ 00229 return Rcpp::sugar::And_SingleLogicalResult_bool<LHS_NA,LHS_T>( lhs, rhs ) ; 00230 } 00231 00232 00233 00234 #endif