|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 00002 // 00003 // XPtr.h: Rcpp R/C++ interface class library -- smart external pointers 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_XPtr_h 00023 #define Rcpp_XPtr_h 00024 00025 #include <RcppCommon.h> 00026 00027 namespace Rcpp{ 00028 00029 template <typename T> 00030 void delete_finalizer(SEXP p){ 00031 if( TYPEOF(p) == EXTPTRSXP ){ 00032 T* ptr = (T*) R_ExternalPtrAddr(p) ; 00033 delete ptr ; 00034 } 00035 } 00036 00037 template <typename T> 00038 void standard_delete_finalizer(T* obj){ 00039 delete obj ; 00040 } 00041 00042 template <typename T, void Finalizer(T*) > 00043 void finalizer_wrapper(SEXP p){ 00044 if( TYPEOF(p) == EXTPTRSXP ){ 00045 T* ptr = (T*) R_ExternalPtrAddr(p) ; 00046 Finalizer(ptr) ; 00047 } 00048 } 00049 00050 template <typename T, void Finalizer(T*) = standard_delete_finalizer<T> > 00051 class XPtr : public RObject { 00052 public: 00053 00059 explicit XPtr(SEXP m_sexp, SEXP tag = R_NilValue, SEXP prot = R_NilValue) : RObject(m_sexp){ 00060 if( TYPEOF(m_sexp) != EXTPTRSXP ) 00061 throw ::Rcpp::not_compatible( "expecting an external pointer" ) ; 00062 R_SetExternalPtrTag( m_sexp, tag ) ; 00063 R_SetExternalPtrProtected( m_sexp, prot ) ; 00064 } ; 00065 00077 explicit XPtr(T* p, bool set_delete_finalizer = true, SEXP tag = R_NilValue, SEXP prot = R_NilValue){ 00078 setSEXP( R_MakeExternalPtr( (void*)p , tag, prot) ) ; 00079 if( set_delete_finalizer ){ 00080 setDeleteFinalizer() ; 00081 } 00082 00083 } 00084 00085 XPtr( const XPtr& other ) : RObject( other.asSexp() ) {} 00086 00087 XPtr& operator=(const XPtr& other){ 00088 setSEXP( other.asSexp() ) ; 00089 return *this ; 00090 } 00091 00096 T& operator*() const { 00097 return *((T*)R_ExternalPtrAddr( m_sexp )) ; 00098 } 00099 00104 T* operator->() const { 00105 return (T*)(R_ExternalPtrAddr(m_sexp)); 00106 } 00107 00108 void setDeleteFinalizer() { 00109 R_RegisterCFinalizerEx( m_sexp, finalizer_wrapper<T,Finalizer> , FALSE) ; 00110 } 00111 00112 inline operator T*(){ return (T*)( R_ExternalPtrAddr(m_sexp)) ; } 00113 00114 class TagProxy{ 00115 public: 00116 TagProxy( XPtr& xp_ ): xp(xp_){} 00117 00118 template <typename U> 00119 TagProxy& operator=( const U& u){ 00120 set( Rcpp::wrap(u) ); 00121 return *this ; 00122 } 00123 00124 template <typename U> 00125 operator U(){ 00126 return Rcpp::as<U>( get() ) ; 00127 } 00128 00129 operator SEXP(){ return get(); } 00130 00131 inline SEXP get(){ 00132 return R_ExternalPtrTag(xp.asSexp()) ; 00133 } 00134 00135 inline void set( SEXP x){ 00136 R_SetExternalPtrTag( xp.asSexp(), x ) ; 00137 } 00138 00139 private: 00140 XPtr& xp ; 00141 } ; 00142 00143 TagProxy tag(){ 00144 return TagProxy( *this ) ; 00145 } 00146 00147 class ProtectedProxy{ 00148 public: 00149 ProtectedProxy( XPtr& xp_ ): xp(xp_){} 00150 00151 template <typename U> 00152 ProtectedProxy& operator=( const U& u){ 00153 set( Rcpp::wrap(u) ); 00154 return *this ; 00155 } 00156 00157 template <typename U> 00158 operator U(){ 00159 return Rcpp::as<U>( get() ) ; 00160 } 00161 00162 operator SEXP(){ return get() ; } 00163 00164 inline SEXP get(){ 00165 return R_ExternalPtrProtected(xp.asSexp()) ; 00166 } 00167 00168 inline void set( SEXP x){ 00169 R_SetExternalPtrProtected( xp.asSexp(), x ) ; 00170 } 00171 00172 private: 00173 XPtr& xp ; 00174 } ; 00175 00176 ProtectedProxy prot(){ 00177 return ProtectedProxy( *this ) ; 00178 } 00179 00180 00181 }; 00182 00183 } // namespace Rcpp 00184 00185 #endif