|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 // 00003 // RObject.h: Rcpp R/C++ interface class library -- general R object wrapper 00004 // 00005 // Copyright (C) 2009 - 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_RObject_h 00023 #define Rcpp_RObject_h 00024 00025 #include <RcppCommon.h> 00026 00027 namespace Rcpp{ 00028 00029 namespace internal{ 00030 00031 class SEXPstack { 00032 public: 00033 SEXPstack() ; 00034 void preserve( SEXP ) ; 00035 void release( SEXP ) ; 00036 private: 00037 SEXP stack ; 00038 SEXP* data ; 00039 int len, top ; 00040 00041 void grow( ) ; 00042 } ; 00043 00044 } 00045 00046 00047 00048 class RObject { 00049 public: 00050 00054 RObject() : m_sexp(R_NilValue) {} ; 00055 00061 RObject(SEXP x) : m_sexp(R_NilValue) { setSEXP(x) ; }; 00062 00066 RObject( const RObject& other ) ; 00067 00071 RObject& operator=( const RObject& other ) ; 00072 00076 RObject& operator=( SEXP other ) ; 00077 00082 virtual ~RObject() ; 00083 00087 inline operator SEXP() const { return m_sexp ; } 00088 00092 inline bool inherits(const char* clazz) const { return ::Rf_inherits( m_sexp, clazz) ; } 00093 00094 /* attributes */ 00095 00099 std::vector<std::string> attributeNames() const ; 00100 00104 bool hasAttribute( const std::string& attr) const ; 00105 00119 class AttributeProxy { 00120 public: 00121 00126 AttributeProxy( const RObject& v, const std::string& attr_name) ; 00127 00132 AttributeProxy& operator=(const AttributeProxy& rhs) ; 00133 00140 template <typename T> AttributeProxy& operator=(const T& rhs){ 00141 set( wrap(rhs) ) ; 00142 return *this ; 00143 } 00144 00149 template <typename T> operator T() const { 00150 return as<T>(get()) ; 00151 } 00152 00153 private: 00154 const RObject& parent; 00155 std::string attr_name ; 00156 00157 SEXP get() const ; 00158 void set(SEXP x) const ; 00159 } ; 00160 00164 class SlotProxy { 00165 public: 00175 SlotProxy( const RObject& v, const std::string& name) ; 00176 00183 SlotProxy& operator=(const SlotProxy& rhs) ; 00184 00190 template <typename T> SlotProxy& operator=(const T& rhs){ 00191 set( wrap(rhs) ) ; 00192 return *this ; 00193 } 00194 00200 template <typename T> operator T() const { 00201 return as<T>(get()) ; 00202 } 00203 00204 private: 00205 const RObject& parent; 00206 std::string slot_name ; 00207 00208 SEXP get() const ; 00209 void set(SEXP x ) const; 00210 } ; 00211 friend class SlotProxy ; 00212 00229 AttributeProxy attr( const std::string& name) const ; 00230 00234 inline bool isNULL() const{ return Rf_isNull(m_sexp) ; } 00235 00239 inline int sexp_type() const { return TYPEOF(m_sexp) ; } 00240 00244 inline SEXP asSexp() const { return m_sexp ; } 00245 00249 inline bool isObject() const { return ::Rf_isObject(m_sexp) ;} 00250 00254 inline bool isS4() const { return ::Rf_isS4(m_sexp) ; } 00255 00261 bool hasSlot(const std::string& name) const ; 00262 00268 SlotProxy slot(const std::string& name) const ; 00269 00270 protected: 00271 00277 void setSEXP(SEXP x) ; 00278 00283 SEXP m_sexp ; 00284 00285 private: 00286 00287 // static internal::SEXPstack PPstack ; 00288 // void preserve(){ if( m_sexp != R_NilValue ) PPstack.preserve(m_sexp) ; } 00289 // void release() { if( m_sexp != R_NilValue ) PPstack.release(m_sexp) ; } 00290 00291 void preserve(){ if( m_sexp != R_NilValue ) R_PreserveObject(m_sexp) ; } 00292 void release() { if( m_sexp != R_NilValue ) R_ReleaseObject(m_sexp) ; } 00293 00294 virtual void update() { 00295 RCPP_DEBUG_1( "RObject::update(SEXP = <%p> )", m_sexp ) ; 00296 } ; 00297 00298 }; 00299 00300 } // namespace Rcpp 00301 00302 #endif