Rcpp Version 0.9.10
XPtr.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines