File: RCallRecurser.h

package info (click to toggle)
r-cran-sourcetools 0.1.7-1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 308 kB
  • sloc: cpp: 1,985; ansic: 505; sh: 10; makefile: 2
file content (75 lines) | stat: -rw-r--r-- 1,370 bytes parent folder | download | duplicates (5)
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 */