1 #ifndef SOURCETOOLS_R_R_CALL_RECURSER_H 2 #define SOURCETOOLS_R_R_CALL_RECURSER_H 3 4 #include <vector> 5 6 #include <sourcetools/core/core.h> 7 8 #include <sourcetools/r/RHeaders.h> 9 #include <sourcetools/r/RFunctions.h> 10 11 12 namespace sourcetools { 13 namespace r { 14 15 class CallRecurser : noncopyable 16 { 17 public: 18 19 class Operation 20 { 21 public: 22 virtual void apply(SEXP dataSEXP) = 0; ~Operation()23 virtual ~Operation() {} 24 }; 25 CallRecurser(SEXP dataSEXP)26 explicit CallRecurser(SEXP dataSEXP) 27 { 28 if (Rf_isPrimitive(dataSEXP)) 29 dataSEXP_ = R_NilValue; 30 else if (Rf_isFunction(dataSEXP)) 31 dataSEXP_ = r::util::functionBody(dataSEXP); 32 else if (TYPEOF(dataSEXP) == LANGSXP) 33 dataSEXP_ = dataSEXP; 34 else 35 dataSEXP_ = R_NilValue; 36 } 37 add(Operation * pOperation)38 void add(Operation* pOperation) 39 { 40 operations_.push_back(pOperation); 41 } 42 run()43 void run() 44 { 45 runImpl(dataSEXP_); 46 } 47 runImpl(SEXP dataSEXP)48 void runImpl(SEXP dataSEXP) 49 { 50 for (std::vector<Operation*>::iterator it = operations_.begin(); 51 it != operations_.end(); 52 ++it) 53 { 54 (*it)->apply(dataSEXP); 55 } 56 57 if (TYPEOF(dataSEXP) == LANGSXP) 58 { 59 while (dataSEXP != R_NilValue) 60 { 61 runImpl(CAR(dataSEXP)); 62 dataSEXP = CDR(dataSEXP); 63 } 64 } 65 } 66 67 private: 68 SEXP dataSEXP_; 69 std::vector<Operation*> operations_; 70 }; 71 72 } // namespace r 73 } // namespace sourcetools 74 75 #endif /* SOURCETOOLS_R_R_CALL_RECURSER_H */ 76