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