Rcpp Version 0.12.12
XPtr.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2 //
3 // XPtr.h: Rcpp R/C++ interface class library -- smart external pointers
4 //
5 // Copyright (C) 2009 - 2013 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_XPtr_h
23 #define Rcpp_XPtr_h
24 
25 #include <RcppCommon.h>
26 
27 namespace Rcpp{
28 
29 template <typename T>
31  delete obj ;
32 }
33 
34 template <typename T, void Finalizer(T*) >
35 void finalizer_wrapper(SEXP p){
36  if( TYPEOF(p) == EXTPTRSXP ){
37  T* ptr = (T*) R_ExternalPtrAddr(p) ;
38  RCPP_DEBUG_3( "finalizer_wrapper<%s>(SEXP p = <%p>). ptr = %p", DEMANGLE(T), p, ptr )
39  Finalizer(ptr) ;
40  }
41 }
42 
43 template <
44  typename T,
45  template <class> class StoragePolicy = PreserveStorage,
46  void Finalizer(T*) = standard_delete_finalizer<T>,
47  bool finalizeOnExit = false
48 >
49 class XPtr :
50  public StoragePolicy< XPtr<T,StoragePolicy, Finalizer, finalizeOnExit> >,
51  public SlotProxyPolicy< XPtr<T,StoragePolicy, Finalizer, finalizeOnExit> >,
52  public AttributeProxyPolicy< XPtr<T,StoragePolicy, Finalizer, finalizeOnExit> >,
53  public TagProxyPolicy< XPtr<T,StoragePolicy, Finalizer, finalizeOnExit> >,
54  public ProtectedProxyPolicy< XPtr<T,StoragePolicy, Finalizer, finalizeOnExit> >,
55  public RObjectMethods< XPtr<T,StoragePolicy, Finalizer, finalizeOnExit> >
56 {
57 public:
58 
59  typedef StoragePolicy<XPtr> Storage ;
60 
66  explicit XPtr(SEXP x, SEXP tag = R_NilValue, SEXP prot = R_NilValue) {
67  if( TYPEOF(x) != EXTPTRSXP ) {
68  const char* fmt = "Expecting an external pointer: [type=%s].";
69  throw ::Rcpp::not_compatible(fmt, Rf_type2char(TYPEOF(x)));
70  }
71 
72  Storage::set__(x) ;
73  R_SetExternalPtrTag( x, tag ) ;
74  R_SetExternalPtrProtected( x, prot ) ;
75  } ;
76 
88  explicit XPtr(T* p, bool set_delete_finalizer = true, SEXP tag = R_NilValue, SEXP prot = R_NilValue){
89  RCPP_DEBUG_2( "XPtr(T* p = <%p>, bool set_delete_finalizer = %s, SEXP tag = R_NilValue, SEXP prot = R_NilValue)", p, ( set_delete_finalizer ? "true" : "false" ) )
90  Storage::set__( R_MakeExternalPtr( (void*)p , tag, prot) ) ;
91  if( set_delete_finalizer ){
93  }
94  }
95 
96  XPtr( const XPtr& other ) {
97  Storage::copy__(other) ;
98  }
99 
100  XPtr& operator=(const XPtr& other){
101  Storage::copy__(other) ;
102  return *this ;
103  }
104 
109  inline T* get() const {
110  return (T*)(R_ExternalPtrAddr( Storage::get__() ));
111  }
112 
117  typedef void (*unspecified_bool_type)();
118  static void unspecified_bool_true() {}
119  operator unspecified_bool_type() const
120  {
121  return get() == NULL ? 0 : unspecified_bool_true;
122  }
123  bool operator!() const
124  {
125  return get() == NULL;
126  }
127 
131  inline T* checked_get() const {
132  T* ptr = get();
133  if (ptr == NULL)
134  throw ::Rcpp::exception("external pointer is not valid" ) ;
135  return ptr;
136  }
137 
142  T& operator*() const {
143  return *(checked_get()) ;
144  }
145 
150  T* operator->() const {
151  return checked_get() ;
152  }
153 
155  R_RegisterCFinalizerEx( Storage::get__(), finalizer_wrapper<T,Finalizer> , (Rboolean) finalizeOnExit) ;
156  }
157 
167  void release() {
168 
169  if (get() != NULL)
170  {
171  // Call the finalizer -- note that this implies that finalizers
172  // need to be ready for a NULL external pointer value (our
173  // default C++ finalizer is since delete NULL is a no-op).
174  finalizer_wrapper<T,Finalizer>( Storage::get__() );
175 
176  // Clear the external pointer
177  R_ClearExternalPtr( Storage::get__() );
178  }
179  }
180 
181  inline operator T*(){
182  return checked_get() ;
183  }
184 
185  void update(SEXP){}
186 };
187 
188 } // namespace Rcpp
189 
190 #endif
void(* unspecified_bool_type)()
Definition: XPtr.h:117
void standard_delete_finalizer(T *obj)
Definition: XPtr.h:30
XPtr(SEXP x, SEXP tag=R_NilValue, SEXP prot=R_NilValue)
Definition: XPtr.h:66
#define DEMANGLE(__TYPE__)
Definition: exceptions.h:315
bool operator!() const
Definition: XPtr.h:123
T & operator*() const
Definition: XPtr.h:142
static void unspecified_bool_true()
Definition: XPtr.h:118
void finalizer_wrapper(SEXP p)
Definition: XPtr.h:35
void update(SEXP)
Definition: XPtr.h:185
#define RCPP_DEBUG_3(fmt, M1, M2, M3)
Definition: debug.h:46
StoragePolicy< XPtr > Storage
Definition: XPtr.h:59
void setDeleteFinalizer()
Definition: XPtr.h:154
XPtr(T *p, bool set_delete_finalizer=true, SEXP tag=R_NilValue, SEXP prot=R_NilValue)
Definition: XPtr.h:88
#define RCPP_DEBUG_2(fmt, M1, M2)
Definition: debug.h:45
XPtr & operator=(const XPtr &other)
Definition: XPtr.h:100
Rcpp API.
Definition: algo.h:28
void release()
Definition: XPtr.h:167
T * operator->() const
Definition: XPtr.h:150
XPtr(const XPtr &other)
Definition: XPtr.h:96
T * checked_get() const
Definition: XPtr.h:131