CMS 3D CMS Logo

FortranInstance.h
Go to the documentation of this file.
1 #ifndef gen_FortranInstance_h
2 #define gen_FortranInstance_h
3 
4 #include <string>
5 
6 namespace gen {
7 
8  // the callbacks from Pythia6/Herwig6 which are passed to the FortranInstance
9  extern "C" {
10  void upinit_();
11  void upevnt_();
12  void upveto_(int *);
13  }
14 
16  public:
18  virtual ~FortranInstance() noexcept(false);
19 
20  void call(void (&fn)()) {
22  fn();
23  }
24  template <typename T>
25  T call(T (&fn)()) {
27  return fn();
28  }
29  template <typename A>
30  void call(void (&fn)(A), A a) {
32  fn(a);
33  }
34  template <typename T, typename A>
35  T call(T (&fn)(A), A a) {
37  return fn(a);
38  }
39  template <typename A1, typename A2>
40  void call(void (&fn)(A1, A2), A1 a1, A2 a2) {
42  fn(a1, a2);
43  }
44  template <typename T, typename A1, typename A2>
45  T call(T (&fn)(A1, A2), A1 a1, A2 a2) {
47  return fn(a1, a2);
48  }
49 
50  // if a member is instantiated at the beginning of a method,
51  // it makes sure this FortranInstance instance is kept as
52  // current instance during the execution of the method
53  // This wrapper makes the enter()..leave() cycle exception-safe
54  struct InstanceWrapper {
56  this->instance = instance;
57  instance->enter();
58  }
59 
61 
63  };
64 
65  // set this instance to be the current one
66  // will throw exception when trying to reenter Herwig twice
67  virtual void enter();
68 
69  // leave instance
70  // will throw if the currently running instance does not match
71  virtual void leave();
72 
73  // get the currently running instance (from enterInstance)
74  // intended for callbacks from Fortran
75  template <typename T>
76  static T *getInstance() {
77  T *instance = dynamic_cast<T *>(currentInstance);
78  if (!instance)
80  return instance;
81  }
82 
83  // Fortran callbacks
84  virtual void upInit();
85  virtual void upEvnt();
86  virtual bool upVeto();
87 
89 
90  private:
91  // list all the Fortran callbacks here
92  friend void gen::upinit_();
93  friend void gen::upevnt_();
94  friend void gen::upveto_(int *);
95 
96  // internal methods
97  static void throwMissingInstance();
98 
99  // how many times enter() was called
100  // this is to make sure leave() will release the instance
101  // after the same number of calls
102  // nesting can in theory occur if the Fortran callback calls
103  // into Herwig again
105 
106  // this points to the Herwig instance that is currently being executed
108  };
109 
110 } // namespace gen
111 
112 #endif // gen_FortranInstance_h
void call(void(&fn)())
static PFTauRenderPlugin instance
static void throwMissingInstance()
void upinit_()
void upevnt_()
virtual void upInit()
InstanceWrapper(FortranInstance *instance)
T call(T(&fn)(A1, A2), A1 a1, A2 a2)
virtual void enter()
static T * getInstance()
T call(T(&fn)(A), A a)
static FortranInstance * currentInstance
static const std::string kFortranInstance
void call(void(&fn)(A), A a)
virtual void leave()
void call(void(&fn)(A1, A2), A1 a1, A2 a2)
double a
Definition: hdecay.h:121
Definition: APVGainStruct.h:7
void upveto_(int *)
long double T
virtual ~FortranInstance() noexcept(false)
static HepMC::HEPEVT_Wrapper wrapper