|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 00002 // 00003 // pmax.h: Rcpp R/C++ interface class library -- pmax 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__pmax_h 00023 #define Rcpp__sugar__pmax_h 00024 00025 namespace Rcpp{ 00026 namespace sugar{ 00027 00028 template <int RTYPE, bool LHS_NA, bool RHS_NA> class pmax_op { 00029 public: 00030 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00031 00032 inline STORAGE operator()( STORAGE left, STORAGE right ) const { 00033 if( Rcpp::traits::is_na<RTYPE>(left) ) return left ; 00034 if( Rcpp::traits::is_na<RTYPE>(right) ) return right ; 00035 return left > right ? left : right ; 00036 } 00037 00038 } ; 00039 template <int RTYPE, bool LHS_NA> class pmax_op<RTYPE,LHS_NA,false> { 00040 public: 00041 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00042 00043 inline STORAGE operator()( STORAGE left, STORAGE right ) const { 00044 if( Rcpp::traits::is_na<RTYPE>(left) ) return left ; 00045 return left > right ? left : right ; 00046 } 00047 } ; 00048 template <int RTYPE, bool RHS_NA> class pmax_op<RTYPE,false,RHS_NA> { 00049 public: 00050 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00051 00052 inline STORAGE operator()( STORAGE left, STORAGE right ) const { 00053 if( Rcpp::traits::is_na<RTYPE>(right) ) return right ; 00054 return left > right ? left : right ; 00055 } 00056 } ; 00057 template <int RTYPE> class pmax_op<RTYPE,false,false> { 00058 public: 00059 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00060 00061 inline STORAGE operator()( STORAGE left, STORAGE right ) const { 00062 return left > right ? left : right ; 00063 } 00064 } ; 00065 00066 template <int RTYPE,bool NA> class pmax_op_Vector_Primitive { 00067 public: 00068 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00069 00070 pmax_op_Vector_Primitive( STORAGE right_ ) : 00071 right(right_) {} 00072 00073 inline STORAGE operator()( STORAGE left ) const { 00074 if( Rcpp::traits::is_na<RTYPE>(left) ) return left ; 00075 return left > right ? left : right ; 00076 } 00077 00078 private: 00079 STORAGE right ; 00080 } ; 00081 00082 template <int RTYPE> class pmax_op_Vector_Primitive<RTYPE,false> { 00083 public: 00084 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00085 00086 pmax_op_Vector_Primitive( STORAGE right_ ) : 00087 right(right_){} 00088 00089 inline STORAGE operator()( STORAGE left ) const { 00090 return left > right ? left : right ; 00091 } 00092 00093 private: 00094 STORAGE right ; 00095 } ; 00096 00097 00098 00099 template < 00100 int RTYPE, 00101 bool LHS_NA, typename LHS_T, 00102 bool RHS_NA, typename RHS_T 00103 > 00104 class Pmax_Vector_Vector : public VectorBase< 00105 RTYPE , 00106 ( LHS_NA || RHS_NA ) , 00107 Pmax_Vector_Vector<RTYPE,LHS_NA,LHS_T,RHS_NA,RHS_T> 00108 > { 00109 public: 00110 typedef typename Rcpp::VectorBase<RTYPE,LHS_NA,LHS_T> LHS_TYPE ; 00111 typedef typename Rcpp::VectorBase<RTYPE,RHS_NA,RHS_T> RHS_TYPE ; 00112 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00113 typedef pmax_op<RTYPE,LHS_NA,RHS_NA> OPERATOR ; 00114 00115 Pmax_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 00116 lhs(lhs_), rhs(rhs_), op() {} 00117 00118 inline STORAGE operator[]( int i ) const { 00119 return op( lhs[i], rhs[i] ) ; 00120 } 00121 inline int size() const { return lhs.size() ; } 00122 00123 private: 00124 const LHS_TYPE& lhs ; 00125 const RHS_TYPE& rhs ; 00126 OPERATOR op ; 00127 } ; 00128 00129 00130 00131 template < 00132 int RTYPE, 00133 bool LHS_NA, typename LHS_T 00134 > 00135 class Pmax_Vector_Primitive : public VectorBase< 00136 RTYPE , 00137 true , 00138 Pmax_Vector_Primitive<RTYPE,LHS_NA,LHS_T> 00139 > { 00140 public: 00141 typedef typename Rcpp::VectorBase<RTYPE,LHS_NA,LHS_T> LHS_TYPE ; 00142 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 00143 typedef pmax_op_Vector_Primitive<RTYPE,LHS_NA> OPERATOR ; 00144 00145 Pmax_Vector_Primitive( const LHS_TYPE& lhs_, STORAGE rhs_ ) : 00146 lhs(lhs_), op(rhs_), rhs(rhs_), isna( Rcpp::traits::is_na<RTYPE>(rhs_) ) {} 00147 00148 inline STORAGE operator[]( int i ) const { 00149 return isna ? rhs : op( lhs[i] ) ; 00150 } 00151 inline int size() const { return lhs.size() ; } 00152 00153 private: 00154 const LHS_TYPE& lhs ; 00155 OPERATOR op ; 00156 STORAGE rhs ; 00157 bool isna ; 00158 } ; 00159 00160 00161 00162 } // sugar 00163 00164 template < 00165 int RTYPE, 00166 bool LHS_NA, typename LHS_T, 00167 bool RHS_NA, typename RHS_T 00168 > 00169 inline sugar::Pmax_Vector_Vector<RTYPE,LHS_NA,LHS_T,RHS_NA,RHS_T> 00170 pmax( 00171 const Rcpp::VectorBase<RTYPE,LHS_NA,LHS_T>& lhs, 00172 const Rcpp::VectorBase<RTYPE,RHS_NA,RHS_T>& rhs 00173 ){ 00174 return sugar::Pmax_Vector_Vector<RTYPE,LHS_NA,LHS_T,RHS_NA,RHS_T>( lhs, rhs ) ; 00175 } 00176 00177 template < 00178 int RTYPE, 00179 bool LHS_NA, typename LHS_T 00180 > 00181 inline sugar::Pmax_Vector_Primitive<RTYPE,LHS_NA,LHS_T> 00182 pmax( 00183 const Rcpp::VectorBase<RTYPE,LHS_NA,LHS_T>& lhs, 00184 typename Rcpp::traits::storage_type<RTYPE>::type rhs 00185 ){ 00186 return sugar::Pmax_Vector_Primitive<RTYPE,LHS_NA,LHS_T>( lhs, rhs ) ; 00187 } 00188 00189 00190 template < 00191 int RTYPE, 00192 bool RHS_NA, typename RHS_T 00193 > 00194 inline sugar::Pmax_Vector_Primitive<RTYPE,RHS_NA,RHS_T> 00195 pmax( 00196 typename Rcpp::traits::storage_type<RTYPE>::type lhs, 00197 const Rcpp::VectorBase<RTYPE,RHS_NA,RHS_T>& rhs 00198 ){ 00199 return sugar::Pmax_Vector_Primitive<RTYPE,RHS_NA,RHS_T>( rhs, lhs ) ; 00200 } 00201 00202 00203 } // Rcpp 00204 00205 #endif