1 // Copyright (C) 2013 Romain Francois 2 // 3 // This file is part of Rcpp. 4 // 5 // Rcpp is free software: you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 2 of the License, or 8 // (at your option) any later version. 9 // 10 // Rcpp is distributed in the hope that it will be useful, but 11 // WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 17 18 #ifndef Rcpp_proxy_AttributeProxy_h 19 #define Rcpp_proxy_AttributeProxy_h 20 21 namespace Rcpp{ 22 23 template <typename CLASS> 24 class AttributeProxyPolicy { 25 public: 26 27 class AttributeProxy : public GenericProxy<AttributeProxy> { 28 public: AttributeProxy(CLASS & v,const std::string & name)29 AttributeProxy( CLASS& v, const std::string& name) 30 : parent(v), attr_name(Rf_install(name.c_str())) 31 {} 32 33 AttributeProxy& operator=(const AttributeProxy& rhs){ 34 if( this != &rhs ) set( rhs.get() ) ; 35 return *this ; 36 } 37 38 template <typename T> AttributeProxy& operator=(const T& rhs); 39 40 template <typename T> operator T() const; 41 42 inline operator SEXP() const; 43 44 private: 45 CLASS& parent; 46 SEXP attr_name ; 47 get()48 SEXP get() const { 49 return Rf_getAttrib( parent, attr_name ) ; 50 } set(SEXP x)51 void set(SEXP x ){ 52 Rf_setAttrib( parent, attr_name, Shield<SEXP>(x) ) ; 53 } 54 } ; 55 56 class const_AttributeProxy : public GenericProxy<const_AttributeProxy> { 57 public: const_AttributeProxy(const CLASS & v,const std::string & name)58 const_AttributeProxy( const CLASS& v, const std::string& name) 59 : parent(v), attr_name(Rf_install(name.c_str())){} 60 61 template <typename T> operator T() const; 62 inline operator SEXP() const; 63 64 private: 65 const CLASS& parent; 66 SEXP attr_name ; 67 get()68 SEXP get() const { 69 return Rf_getAttrib( parent, attr_name ) ; 70 } 71 } ; 72 attr(const std::string & name)73 AttributeProxy attr( const std::string& name){ 74 return AttributeProxy( static_cast<CLASS&>( *this ), name ) ; 75 } attr(const std::string & name)76 const_AttributeProxy attr( const std::string& name) const { 77 return const_AttributeProxy( static_cast<const CLASS&>( *this ), name ) ; 78 } 79 attributeNames()80 std::vector<std::string> attributeNames() const { 81 std::vector<std::string> v ; 82 SEXP attrs = ATTRIB( static_cast<const CLASS&>(*this).get__()); 83 while( attrs != R_NilValue ){ 84 v.push_back( std::string(CHAR(PRINTNAME(TAG(attrs)))) ) ; 85 attrs = CDR( attrs ) ; 86 } 87 return v ; 88 } 89 hasAttribute(const std::string & attr)90 bool hasAttribute( const std::string& attr) const { 91 SEXP attrs = ATTRIB(static_cast<const CLASS&>(*this).get__()); 92 while( attrs != R_NilValue ){ 93 if( attr == CHAR(PRINTNAME(TAG(attrs))) ){ 94 return true ; 95 } 96 attrs = CDR( attrs ) ; 97 } 98 return false; /* give up */ 99 } 100 101 102 } ; 103 104 } 105 #endif 106