1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 2 // 3 // clamp.h: Rcpp R/C++ interface class library -- clamp 4 // 5 // Copyright (C) 2012 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__clamp_h 23 #define Rcpp__sugar__clamp_h 24 25 namespace Rcpp{ 26 namespace sugar{ 27 28 template <int RTYPE, bool NA> 29 struct clamp_operator{ 30 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 31 clamp_operatorclamp_operator32 clamp_operator(STORAGE lhs_, STORAGE rhs_ ) : lhs(lhs_), rhs(rhs_){} 33 operatorclamp_operator34 inline STORAGE operator()(STORAGE x) const { 35 return x < lhs ? lhs : (x > rhs ? rhs : x ) ; 36 } 37 STORAGE lhs, rhs ; 38 } ; 39 // need to write this special version 40 template <> 41 struct clamp_operator<REALSXP,true> { 42 clamp_operator(double lhs_, double rhs_ ) : lhs(lhs_), rhs(rhs_){} 43 44 inline double operator()(double x) const { 45 if( Rcpp::traits::is_na<REALSXP>(x) ) return x ; 46 return x < lhs ? lhs : (x > rhs ? rhs : x ) ; 47 } 48 double lhs, rhs ; 49 } ; 50 51 52 53 template < 54 int RTYPE, 55 bool NA, typename T 56 > 57 class Clamp_Primitive_Vector_Primitive : public VectorBase< 58 RTYPE , 59 NA , 60 Clamp_Primitive_Vector_Primitive<RTYPE,NA,T> 61 > { 62 public: 63 typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ; 64 typedef clamp_operator<RTYPE,NA> OPERATOR ; 65 66 Clamp_Primitive_Vector_Primitive( STORAGE lhs_, const T& vec_, STORAGE rhs_) : vec(vec_), op(lhs_,rhs_) {} 67 68 inline STORAGE operator[]( R_xlen_t i ) const { 69 return op( vec[i] ) ; 70 } 71 inline R_xlen_t size() const { return vec.size() ; } 72 73 private: 74 const T& vec ; 75 OPERATOR op ; 76 } ; 77 78 79 80 } // sugar 81 82 template <int RTYPE, bool NA, typename T> 83 inline sugar::Clamp_Primitive_Vector_Primitive<RTYPE,NA,T> 84 clamp( 85 typename Rcpp::traits::storage_type<RTYPE>::type lhs, 86 const Rcpp::VectorBase<RTYPE,NA,T>& vec, 87 typename Rcpp::traits::storage_type<RTYPE>::type rhs 88 ){ 89 return sugar::Clamp_Primitive_Vector_Primitive<RTYPE,NA,T>( lhs, vec.get_ref(), rhs ) ; 90 } 91 92 93 } // Rcpp 94 95 #endif 96