Rcpp Version 1.1.2
Loading...
Searching...
No Matches
Environment.h
Go to the documentation of this file.
1
2// Environment.h: Rcpp R/C++ interface class library -- access R environments
3//
4// Copyright (C) 2009-2013 Dirk Eddelbuettel and Romain François
5// Copyright (C) 2014-2025 Dirk Eddelbuettel, Romain François and Kevin Ushey
6// Copyright (C) 2026 Dirk Eddelbuettel, Romain François, Kevin Ushey and Iñaki Ucar
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 {
36 Shield<SEXP> call(Rf_lang2(asEnvironmentSym, x));
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].";
41 throw not_compatible(fmt, Rf_type2char(TYPEOF(x)));
42 }
43 }
44
45 public:
47
49 Storage::set__(R_GlobalEnv) ;
50 } ;
51
58 Shield<SEXP> env(as_environment(x));
59 Storage::set__(env) ;
60 }
61
67 Environment_Impl( const std::string& name ) ;
68
75 Environment_Impl( int pos ) ;
76
85 SEXP ls(bool all) const {
86 SEXP env = Storage::get__() ;
87 return R_lsInternal3(env, all ? TRUE : FALSE, TRUE);
88 return R_NilValue ;
89 }
90
98 SEXP get(const std::string& name) const {
99 Symbol nameSym = Rf_install(name.c_str());
100 return get(nameSym);
101 }
102
110 SEXP get(Symbol name) const {
111 SEXP env = Storage::get__() ;
112#if R_VERSION < R_Version(4,5,0)
113 SEXP res = Rf_findVarInFrame( env, name ) ;
114 if (res == R_UnboundValue) return R_NilValue;
115 if (TYPEOF(res) == PROMSXP)
116 res = internal::Rcpp_eval_impl(res, env);
117#else
118 SEXP res = R_getVarEx(name, env, FALSE, R_NilValue);
119#endif
120 return res ;
121 }
122
123
131 SEXP find( const std::string& name) const{
132 Symbol nameSym = Rf_install(name.c_str());
133 return find(nameSym);
134 }
135
142 SEXP find(Symbol name) const{
143 SEXP env = Storage::get__() ;
144#if R_VERSION < R_Version(4,5,0)
145 SEXP res = Rf_findVar( name, env ) ;
146 if (res == R_UnboundValue) throw binding_not_found(name.c_str());
147 if (TYPEOF(res) == PROMSXP)
148 res = internal::Rcpp_eval_impl(res, env);
149#else
150 SEXP res = R_getVarEx(name, env, TRUE, NULL);
151 if (res == NULL) throw binding_not_found(name.c_str());
152#endif
153 return res ;
154 }
155
164 bool exists( const std::string& name ) const {
165 SEXP nameSym = Rf_install(name.c_str());
166#if R_VERSION < R_Version(4,5,0)
167 SEXP res = Rf_findVarInFrame( Storage::get__() , nameSym ) ;
168 return res != R_UnboundValue;
169#else
170 SEXP res = R_getVarEx(nameSym, Storage::get__(), FALSE, NULL);
171 return res != NULL;
172#endif
173 }
174
186 bool assign( const std::string& name, SEXP x ) const{
187 if( exists( name) && bindingIsLocked(name) ) throw binding_is_locked(name) ;
188 SEXP nameSym = Rf_install(name.c_str());
189 Rf_defineVar( nameSym, x, Storage::get__() );
190 return true ;
191 }
192
193 bool assign(const std::string& name, const Shield<SEXP>& x) const {
194 return assign(name, (SEXP) x);
195 }
196
205 template <typename WRAPPABLE>
206 bool assign( const std::string& name, const WRAPPABLE& x) const ;
207
212 bool isLocked() const {
213 return R_EnvironmentIsLocked(Storage::get__());
214 }
215
219 bool remove( const std::string& name ){
220 if( exists(name) ){
221 if( bindingIsLocked(name) ){
222 throw binding_is_locked(name) ;
223 } else{
224 /* unless we want to copy all of do_remove,
225 we have to go back to R to do this operation */
226 SEXP internalSym = Rf_install( ".Internal" );
227 SEXP removeSym = Rf_install( "remove" );
228 Shield<SEXP> str(Rf_mkString(name.c_str()));
229 Shield<SEXP> call(Rf_lang2(internalSym, Rf_lang4(removeSym, str, Storage::get__(), Rf_ScalarLogical(FALSE))));
230 Rcpp_fast_eval( call, R_GlobalEnv ) ;
231 }
232 } else{
233 throw no_such_binding(name) ;
234 }
235 return true;
236 }
237
243 void lock(bool bindings = false) {
244 R_LockEnvironment( Storage::get__(), bindings ? TRUE: FALSE ) ;
245 }
246
253 void lockBinding(const std::string& name){
254 if( !exists( name) ) throw no_such_binding(name) ;
255 SEXP nameSym = Rf_install(name.c_str());
256 R_LockBinding( nameSym, Storage::get__() );
257 }
258
265 void unlockBinding(const std::string& name){
266 if( !exists( name) ) throw no_such_binding(name) ;
267 SEXP nameSym = Rf_install(name.c_str());
268 R_unLockBinding( nameSym, Storage::get__() );
269 }
270
279 bool bindingIsLocked(const std::string& name) const{
280 if( !exists( name) ) throw no_such_binding(name) ;
281 SEXP nameSym = Rf_install(name.c_str());
282 return R_BindingIsLocked(nameSym, Storage::get__() ) ;
283 }
284
294 bool bindingIsActive(const std::string& name) const {
295 if( !exists( name) ) throw no_such_binding(name) ;
296 SEXP nameSym = Rf_install(name.c_str());
297 return R_BindingIsActive(nameSym, Storage::get__()) ;
298 }
299
304 return R_GlobalEnv ;
305 }
306
311 return R_EmptyEnv ;
312 }
313
318 return R_BaseEnv ;
319 }
320
325 return R_BaseNamespace ;
326 }
327
334
342 static Environment_Impl namespace_env(const std::string& package){
343 Armor<SEXP> env ;
344 try{
345 SEXP getNamespaceSym = Rf_install("getNamespace");
346 Shield<SEXP> package_str( Rf_mkString(package.c_str()) );
347 Shield<SEXP> call( Rf_lang2(getNamespaceSym, package_str) );
348 env = Rcpp_fast_eval(call, R_GlobalEnv);
349 } catch( ... ){
350 throw no_such_namespace( package ) ;
351 }
352 return Environment_Impl( env ) ;
353 }
354
359#if R_VERSION < R_Version(4,5,0)
360 return Environment_Impl( ENCLOS(Storage::get__()) ) ;
361#else
362 return Environment_Impl(R_ParentEnv(Storage::get__()));
363#endif
364 }
365
369 Environment_Impl new_child(bool hashed) const {
370 SEXP newEnvSym = Rf_install("new.env");
371 Shield<SEXP> call(Rf_lang3(newEnvSym, Rf_ScalarLogical(hashed), Storage::get__()));
372 return Environment_Impl(Rcpp_fast_eval(call, R_GlobalEnv));
373 }
374
375 void update(SEXP){}
376 };
377
379
380} // namespace Rcpp
381
382#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:40
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:49
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
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:76
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