Rcpp Version 1.0.9
Function.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 // Function.h: Rcpp R/C++ interface class library -- functions (also primitives and builtins)
4 //
5 // Copyright (C) 2010 - 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_Function_h
23 #define Rcpp_Function_h
24 
25 #include <RcppCommon.h>
26 
27 #include <Rcpp/grow.h>
28 
29 namespace Rcpp{
30 
34  RCPP_API_CLASS(Function_Impl) {
35  public:
36 
37  RCPP_GENERATE_CTOR_ASSIGN(Function_Impl)
38 
39  Function_Impl(SEXP x){
40  switch( TYPEOF(x) ){
41  case CLOSXP:
42  case SPECIALSXP:
43  case BUILTINSXP:
44  Storage::set__(x);
45  break;
46  default:
47  const char* fmt = "Cannot convert object to a function: "
48  "[type=%s; target=CLOSXP, SPECIALSXP, or "
49  "BUILTINSXP].";
50  throw not_compatible(fmt, Rf_type2char(TYPEOF(x)));
51  }
52  }
53 
61  Function_Impl(const std::string& name) {
62  get_function(name, R_GlobalEnv);
63  }
64 
65  Function_Impl(const std::string& name, const SEXP env) {
66  if (!Rf_isEnvironment(env)) {
67  stop("env is not an environment");
68  }
69  get_function(name, env);
70  }
71 
72  Function_Impl(const std::string& name, const std::string& ns) {
73  Shield<SEXP> env(Rf_findVarInFrame(R_NamespaceRegistry, Rf_install(ns.c_str())));
74  if (env == R_UnboundValue) {
75  stop("there is no namespace called \"%s\"", ns);
76  }
77  get_function(name, env);
78  }
79 
80  SEXP operator()() const {
81  Shield<SEXP> call(Rf_lang1(Storage::get__()));
82  return Rcpp_fast_eval(call, R_GlobalEnv);
83  }
84 
85  #include <Rcpp/generated/Function__operator.h>
86 
90  SEXP environment() const {
91  SEXP fun = Storage::get__() ;
92  if( TYPEOF(fun) != CLOSXP ) {
93  throw not_a_closure(Rf_type2char(TYPEOF(fun)));
94  }
95  return CLOENV(fun) ;
96  }
97 
101  SEXP body() const {
102  return BODY( Storage::get__() ) ;
103  }
104 
105  void update(SEXP){}
106 
107 
108  private:
109  void get_function(const std::string& name, const SEXP env) {
110  SEXP nameSym = Rf_install( name.c_str() ); // cannot be gc()'ed once in symbol table
111  Shield<SEXP> x( Rf_findFun( nameSym, env ) ) ;
112  Storage::set__(x) ;
113  }
114 
115  SEXP invoke(SEXP args_, SEXP env) const {
116  Shield<SEXP> args(args_);
117  Shield<SEXP> call(Rcpp_lcons(Storage::get__(), args));
118  SEXP out = Rcpp_fast_eval(call, env);
119  return out;
120  }
121 
122  };
123 
124  typedef Function_Impl<PreserveStorage> Function ;
125 
126 } // namespace Rcpp
127 
128 #endif
#define RCPP_GENERATE_CTOR_ASSIGN(__CLASS__)
Definition: interface.h:21
#define Rcpp_lcons
Definition: lang.h:32
Rcpp API.
Definition: algo.h:28
Function_Impl< PreserveStorage > Function
Definition: Function.h:122
void update(SEXP)
Definition: Environment.h:400
RCPP_API_CLASS(DottedPair_Impl)
SEXP Rcpp_fast_eval(SEXP expr, SEXP env)
Definition: Rcpp_eval.h:68
void NORET stop(const char *fmt, Args &&... args)
Definition: exceptions.h:51