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)())
21  { InstanceWrapper wrapper(this); fn(); }
22  template<typename T> T call(T(&fn)())
23  { InstanceWrapper wrapper(this); return fn(); }
24  template<typename A> void call(void(&fn)(A), A a)
25  { InstanceWrapper wrapper(this); fn(a); }
26  template<typename T, typename A> T call(T(&fn)(A), A a)
27  { InstanceWrapper wrapper(this); return fn(a); }
28  template<typename A1, typename A2> void call(void(&fn)(A1, A2), A1 a1, A2 a2)
29  { InstanceWrapper wrapper(this); fn(a1, a2); }
30  template<typename T, typename A1, typename A2> T call(T(&fn)(A1, A2), A1 a1, A2 a2)
31  { InstanceWrapper wrapper(this); return fn(a1, a2); }
32 
33  // if a member is instantiated at the beginning of a method,
34  // it makes sure this FortranInstance instance is kept as
35  // current instance during the execution of the method
36  // This wrapper makes the enter()..leave() cycle exception-safe
37  struct InstanceWrapper {
39  { this->instance = instance; instance->enter(); }
40 
42  { instance->leave(); }
43 
45  };
46 
47  // set this instance to be the current one
48  // will throw exception when trying to reenter Herwig twice
49  virtual void enter();
50 
51  // leave instance
52  // will throw if the currently running instance does not match
53  virtual void leave();
54 
55  // get the currently running instance (from enterInstance)
56  // intended for callbacks from Fortran
57  template<typename T>
58  static T *getInstance()
59  {
60  T *instance = dynamic_cast<T*>(currentInstance);
61  if (!instance)
63  return instance;
64  }
65 
66  // Fortran callbacks
67  virtual void upInit();
68  virtual void upEvnt();
69  virtual bool upVeto();
70 
72 
73  private:
74  // list all the Fortran callbacks here
75  friend void gen::upinit_();
76  friend void gen::upevnt_();
77  friend void gen::upveto_(int*);
78 
79  // internal methods
80  static void throwMissingInstance();
81 
82  // how many times enter() was called
83  // this is to make sure leave() will release the instance
84  // after the same number of calls
85  // nesting can in theory occur if the Fortran callback calls
86  // into Herwig again
88 
89  // this points to the Herwig instance that is currently being executed
91 };
92 
93 } // namespace gen
94 
95 #endif // gen_FortranInstance_h
void call(void(&fn)())
#define noexcept
static void throwMissingInstance()
void upinit_()
void upevnt_()
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
void upveto_(int *)
long double T
virtual ~FortranInstance() noexcept(false)
static HepMC::HEPEVT_Wrapper wrapper