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