Rcpp Version 1.0.14
Loading...
Searching...
No Matches
Environment.h
Go to the documentation of this file.
1// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2//
3// Environment.h: Rcpp R/C++ interface class library -- access R environments
4//
5// Copyright (C) 2009 - 2013 Dirk Eddelbuettel and Romain Francois
6// Copyright (C) 2014 - 2020 Dirk Eddelbuettel, Romain Francois and Kevin Ushey
7//
8// This file is part of Rcpp.
9//
10// Rcpp is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 2 of the License, or
13// (at your option) any later version.
14//
15// Rcpp is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
22
23#ifndef Rcpp_Environment_h
24#define Rcpp_Environment_h
25
26namespace Rcpp{
27
30 {
31 private:
32 inline SEXP as_environment(SEXP x){
33 if( Rf_isEnvironment(x) ) return x ;
34 SEXP asEnvironmentSym = Rf_install("as.environment");
35 try {
37 return Rcpp_fast_eval(call, R_GlobalEnv);
38 } catch( const eval_error& ex) {
39 const char* fmt = "Cannot convert object to an environment: "
40 "[type=%s; target=ENVSXP].";
42 }
43 }
44
45 public:
47
49 Storage::set__(R_GlobalEnv) ;
50 } ;
51
59 Storage::set__(env) ;
60 }
61
67 Environment_Impl( const std::string& name ) ;
68
76
85 SEXP ls(bool all) const {
86 SEXP env = Storage::get__() ;
87 return R_lsInternal( env, all ? TRUE : FALSE ) ;
88 return R_NilValue ;
89 }
90
98 SEXP get(const std::string& name) const {
99 SEXP env = Storage::get__() ;
100 SEXP nameSym = Rf_install(name.c_str());
101 SEXP res = Rf_findVarInFrame( env, nameSym ) ;
102
103 if( res == R_UnboundValue ) return R_NilValue ;
104
105 /* We need to evaluate if it is a promise */
106 if( TYPEOF(res) == PROMSXP){
107 res = internal::Rcpp_eval_impl( res, env ) ;
108 }
109 return res ;
110 }
111
119 SEXP get(Symbol name) const {
120 SEXP env = Storage::get__() ;
121 SEXP res = Rf_findVarInFrame( env, name ) ;
122
123 if( res == R_UnboundValue ) return R_NilValue ;
124
125 /* We need to evaluate if it is a promise */
126 if( TYPEOF(res) == PROMSXP){
127 res = internal::Rcpp_eval_impl( res, env ) ;
128 }
129 return res ;
130 }
131
132
140 SEXP find( const std::string& name) const{
141 SEXP env = Storage::get__() ;
142 SEXP nameSym = Rf_install(name.c_str());
143 SEXP res = Rf_findVar( nameSym, env ) ;
144
145 if( res == R_UnboundValue ) throw binding_not_found(name) ;
146
147 /* We need to evaluate if it is a promise */
148 if( TYPEOF(res) == PROMSXP){
149 res = internal::Rcpp_eval_impl( res, env ) ;
150 }
151 return res ;
152 }
153
160 SEXP find(Symbol name) const{
161 SEXP env = Storage::get__() ;
162 SEXP res = Rf_findVar( name, env ) ;
163
164 if( res == R_UnboundValue ) {
165 // Pass on the const char* to the RCPP_EXCEPTION_CLASS's
166 // const std::string& requirement
167 throw binding_not_found(name.c_str()) ;
168 }
169
170 /* We need to evaluate if it is a promise */
171 if( TYPEOF(res) == PROMSXP){
172 res = internal::Rcpp_eval_impl( res, env ) ;
173 }
174 return res ;
175 }
176
185 bool exists( const std::string& name ) const {
186 SEXP nameSym = Rf_install(name.c_str());
187 SEXP res = Rf_findVarInFrame( Storage::get__() , nameSym ) ;
188 return res != R_UnboundValue ;
189 }
190
202 bool assign( const std::string& name, SEXP x ) const{
203 if( exists( name) && bindingIsLocked(name) ) throw binding_is_locked(name) ;
204 SEXP nameSym = Rf_install(name.c_str());
205 Rf_defineVar( nameSym, x, Storage::get__() );
206 return true ;
207 }
208
209 bool assign(const std::string& name, const Shield<SEXP>& x) const {
210 return assign(name, (SEXP) x);
211 }
212
221 template <typename WRAPPABLE>
222 bool assign( const std::string& name, const WRAPPABLE& x) const ;
223
228 bool isLocked() const {
229 return R_EnvironmentIsLocked(Storage::get__());
230 }
231
235 bool remove( const std::string& name ){
236 if( exists(name) ){
237 if( bindingIsLocked(name) ){
238 throw binding_is_locked(name) ;
239 } else{
240 /* unless we want to copy all of do_remove,
241 we have to go back to R to do this operation */
242 SEXP internalSym = Rf_install( ".Internal" );
243 SEXP removeSym = Rf_install( "remove" );
244 Shield<SEXP> str(Rf_mkString(name.c_str()));
246 Rcpp_fast_eval( call, R_GlobalEnv ) ;
247 }
248 } else{
249 throw no_such_binding(name) ;
250 }
251 return true;
252 }
253
259 void lock(bool bindings = false) {
260 R_LockEnvironment( Storage::get__(), bindings ? TRUE: FALSE ) ;
261 }
262
269 void lockBinding(const std::string& name){
270 if( !exists( name) ) throw no_such_binding(name) ;
271 SEXP nameSym = Rf_install(name.c_str());
272 R_LockBinding( nameSym, Storage::get__() );
273 }
274
281 void unlockBinding(const std::string& name){
282 if( !exists( name) ) throw no_such_binding(name) ;
283 SEXP nameSym = Rf_install(name.c_str());
284 R_unLockBinding( nameSym, Storage::get__() );
285 }
286
295 bool bindingIsLocked(const std::string& name) const{
296 if( !exists( name) ) throw no_such_binding(name) ;
297 SEXP nameSym = Rf_install(name.c_str());
298 return R_BindingIsLocked(nameSym, Storage::get__() ) ;
299 }
300
310 bool bindingIsActive(const std::string& name) const {
311 if( !exists( name) ) throw no_such_binding(name) ;
312 SEXP nameSym = Rf_install(name.c_str());
313 return R_BindingIsActive(nameSym, Storage::get__()) ;
314 }
315
320 return R_GlobalEnv ;
321 }
322
327 return R_EmptyEnv ;
328 }
329
334 return R_BaseEnv ;
335 }
336
341 return R_BaseNamespace ;
342 }
343
350
358 static Environment_Impl namespace_env(const std::string& package){
359 Armor<SEXP> env ;
360 try{
361 SEXP getNamespaceSym = Rf_install("getNamespace");
362 Shield<SEXP> package_str( Rf_mkString(package.c_str()) );
364 env = Rcpp_fast_eval(call, R_GlobalEnv);
365 } catch( ... ){
366 throw no_such_namespace( package ) ;
367 }
368 return Environment_Impl( env ) ;
369 }
370
375 return Environment_Impl( ENCLOS(Storage::get__()) ) ;
376 }
377
382 SEXP newEnvSym = Rf_install("new.env");
383 Shield<SEXP> call(Rf_lang3(newEnvSym, Rf_ScalarLogical(hashed), Storage::get__()));
385 }
386
387 void update(SEXP){}
388 };
389
391
392} // namespace Rcpp
393
394#endif
#define RCPP_GENERATE_CTOR_ASSIGN(__CLASS__)
Definition interface.h:21
#define RCPP_API_CLASS(__CLASS__)
Definition interface.h:49
attribute_hidden SEXP get_Rcpp_namespace()
Definition routines.h:121
SEXP Rcpp_eval_impl(SEXP expr, SEXP env)
Definition Rcpp_eval.h:48
Rcpp API.
Definition algo.h:28
void lockBinding(const std::string &name)
bool remove(const std::string &name)
static Environment_Impl global_env()
static Environment_Impl Rcpp_namespace()
void lock(bool bindings=false)
void update(SEXP)
bool assign(const std::string &name, SEXP x) const
void unlockBinding(const std::string &name)
SEXP Rcpp_fast_eval(SEXP expr, SEXP env)
Definition Rcpp_eval.h:68
SEXP get(const std::string &name) const
Definition Environment.h:98
SEXP find(const std::string &name) const
static Environment_Impl base_env()
static Environment_Impl namespace_env(const std::string &package)
static Environment_Impl empty_env()
bool bindingIsLocked(const std::string &name) const
Environment_Impl parent() const
Environment_Impl(SEXP x)
Definition Environment.h:57
T as(SEXP x)
Definition as.h:151
static Environment_Impl base_namespace()
sugar::All< NA, T > all(const Rcpp::VectorBase< LGLSXP, NA, T > &t)
Definition all.h:84
Environment_Impl< PreserveStorage > Environment
Environment_Impl new_child(bool hashed) const
Symbol_Impl< NoProtectStorage > Symbol
Definition Symbol.h:84
bool exists(const std::string &name) const
SEXP ls(bool all) const
Definition Environment.h:85
bool isLocked() const
bool bindingIsActive(const std::string &name) const