1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 2 // 3 // not.h: Rcpp R/C++ interface class library -- unary operator! 4 // 5 // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 6 // 7 // This file is part of Rcpp. 8 // 9 // Rcpp is free software: you can redistribute it and/or modify it 10 // under the terms of the GNU General Public License as published by 11 // the Free Software Foundation, either version 2 of the License, or 12 // (at your option) any later version. 13 // 14 // Rcpp is distributed in the hope that it will be useful, but 15 // WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 21 22 #ifndef Rcpp__sugar__not_h 23 #define Rcpp__sugar__not_h 24 25 namespace Rcpp{ 26 namespace sugar{ 27 28 template <int RTYPE,bool NA> 29 class not_ { 30 public: 31 typedef typename traits::storage_type<RTYPE>::type STORAGE ; apply(STORAGE x)32 inline int apply( STORAGE x ) const { 33 return Rcpp::traits::is_na<RTYPE>(x) ? NA_LOGICAL : (x ? FALSE : TRUE) ; 34 } 35 } ; 36 template <int RTYPE> 37 class not_<RTYPE,false> { 38 public: 39 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; apply(STORAGE x)40 inline int apply( STORAGE x ) const { 41 return x ? FALSE : TRUE ; 42 } 43 } ; 44 template <bool NA> 45 class not_<REALSXP,NA>{ 46 public: apply(double x)47 inline int apply( double x ) const { 48 return Rcpp::traits::is_na<REALSXP>( x ) ? NA_LOGICAL : ( (x == 0) ? FALSE : TRUE ) ; 49 } 50 } ; 51 template <> 52 class not_<REALSXP,false>{ 53 public: apply(double x)54 inline int apply( double x ) const { 55 return ( x == 0.0 ? FALSE : TRUE ) ; 56 } 57 } ; 58 template <bool NA> 59 class not_<CPLXSXP,NA>{ 60 public: apply(Rcomplex x)61 inline int apply( Rcomplex x ) const { 62 return Rcpp::traits::is_na<CPLXSXP>( x ) ? NA_LOGICAL : ( (x.r == 0.0 & x.i == 0.0 ) ? FALSE : TRUE ) ; 63 } 64 } ; 65 template <> 66 class not_<CPLXSXP,false>{ 67 public: apply(Rcomplex x)68 inline int apply( Rcomplex x ) const { 69 return ((x.r == 0.0) & (x.i == 0.0) ) ? FALSE : TRUE ; 70 } 71 } ; 72 73 74 75 template <int RTYPE, bool NA, typename T> 76 class Not_Vector : public Rcpp::VectorBase<LGLSXP,NA, Not_Vector<RTYPE,NA,T> > { 77 public: 78 typedef typename Rcpp::VectorBase<RTYPE,NA,T> VEC_TYPE ; 79 typedef typename traits::storage_type<RTYPE>::type STORAGE ; 80 typedef not_<RTYPE,NA> OPERATOR ; 81 Not_Vector(const VEC_TYPE & lhs_)82 Not_Vector( const VEC_TYPE& lhs_ ) : 83 lhs(lhs_), op() {} 84 85 inline STORAGE operator[]( R_xlen_t i ) const { 86 return op.apply( lhs[i] ) ; 87 } 88 size()89 inline R_xlen_t size() const { return lhs.size() ; } 90 91 private: 92 const VEC_TYPE& lhs ; 93 OPERATOR op ; 94 } ; 95 96 } 97 } 98 99 template <int RTYPE,bool NA, typename T> 100 inline Rcpp::sugar::Not_Vector< RTYPE , NA , T > 101 operator!( 102 const Rcpp::VectorBase<RTYPE,NA,T>& x 103 ) { 104 return Rcpp::sugar::Not_Vector<RTYPE,NA, T >( x ) ; 105 } 106 107 108 #endif 109