gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-252-gf9a3f78
a Global And Modular Bsm Inference Tool
plugin_interface.hpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
10 //
21 
22 #ifndef __PLUGIN_INTERFACE_HPP
23 #define __PLUGIN_INTERFACE_HPP
24 
25 #include <vector>
26 #include <map>
27 #include <sstream>
28 #include <dlfcn.h>
29 #include <typeinfo>
30 
35 
36 namespace Gambit
37 {
38 
39  namespace Scanner
40  {
41 
42  namespace Plugins
43  {
44  using Gambit::type_index;
45 
46  inline const std::map<type_index, void *>& error_map_return()
47  {
48  static const std::map<type_index, void *> temp_map;
49  return temp_map;
50  }
51 
52  /*******************************************************/
53  /************ Plugin Main Interface Base ***************/
54  /*******************************************************/
55 
56  template <typename T>
58 
59  template <typename ret, typename... args>
60  class Plugin_Main_Interface_Base <ret (args...)>
61  {
62  private:
63  typedef ret (*mainFuncType)(args...);
64  mainFuncType main;
65 
66  public:
68 
69  int enterMain(const std::string &name, const std::map<type_index, void *> & index_map)
70  {
71  for (auto it = index_map.begin(), end = index_map.end(); it != end; it++)
72  {
73  if (it->first == typeid(ret (args...)))
74  {
75  main = reinterpret_cast<mainFuncType>(it->second);
76  return 0;
77  }
78  }
79 
80  scan_err << "Plugin interface requires the plugin_main function in plugin \"" << name << "\" to be of the form \""
81  << demangle(typeid(ret).name()) << " (" << stringifyVariadic(demangle(typeid(args).name())...) << ")\"" << scan_end;
82 
83  return 1;
84  }
85 
86  ret operator() (const args&... params)
87  {
88  return main(params...);
89  }
90  };
91 
92  /**************************************************/
93  /************ Plugin Interface Base ***************/
94  /**************************************************/
95 
97  {
98  private:
99  void *plugin;
100  YAML::Node flags;
101  std::vector<void *> input;
102  std::string tag;
103  typedef const std::map<type_index, void *> &(*initFuncType)(const std::string &, const YAML::Node &, const printer_interface &, Priors::BasePrior &, std::vector<void *> &);
104  typedef void * (*getFuncType)(std::string);
105  initFuncType initFunc;
106  getFuncType getFunc;
107 
108  protected:
109  template <typename... plug_args>
110  const std::map<type_index, void *> &initPlugin(const std::string &type, const std::string &name, const plug_args&... inputs)
111  {
112  Plugin_Interface_Details details = plugin_info(type, name);
113  flags = details.flags;
114  plugin = dlopen (details.details.path.c_str(), RTLD_LAZY);
115 
116  if (bool(plugin))
117  {
118  tag = name;
119  input_variadic_vector(input, inputs...);
120  initFunc = (initFuncType)dlsym(plugin, (std::string("__gambit_plugin_pluginInit_") + details.details.full_string + std::string("__")).c_str());
121  getFunc = (getFuncType)dlsym(plugin, (std::string("__gambit_plugin_getMember_") + details.details.full_string + std::string("__")).c_str());
122 
123  char *errmesg = dlerror();
124  if (errmesg != NULL)
125  {
126  scan_err << "error loading plugin " << name << ": " << errmesg << scan_end;
127  return error_map_return();
128  }
129  else
130  {
131  return initFunc(tag, details.node, *details.printer, *details.prior, input);
132  }
133  }
134  else
135  {
136  scan_err << "Cannot load " << details.details.path << ": " << dlerror() << scan_end;
137  plugin = 0;
138  return error_map_return();
139  }
140  }
141 
142  public:
143  Plugin_Interface_Base() : plugin(0), initFunc(0), getFunc(0) {}
144 
145  YAML::Node operator[](const std::string &key){return flags[key];}
146 
148  {
149  if (plugin != 0) dlclose(plugin);
150  }
151  };
152 
153 
154  /*********************************************/
155  /************ Plugin Interface ***************/
156  /*********************************************/
157 
161  template <typename... T>
163  {
164  private:
165  template <typename... T1>
166  void dummy(T1...){}
167  public:
168  template <typename... plug_args>
169  Plugin_Interface(const std::string &type, const std::string &name, const plug_args&... inputs)
170  {
171  auto index_map = initPlugin(type, name, inputs...);
172  dummy(Plugin_Main_Interface_Base<T>::enterMain(name, index_map)...);
173  }
174 
175  template <typename... args>
176  auto operator()(args&... params) -> typename find_variadic_type <void (args...), T...>::ret_type
177  {
178  static_assert(find_variadic_type <void (args...), T...>::value, "\n\033[00;31;1mPlugin Interface: Entered argument types do not match any of the plugin mains' argument types.\033[00m\n");
179  return Plugin_Main_Interface_Base<typename find_variadic_type <void (args...), T...>::func_type>::operator()(params...);
180  }
181  };
182 
183  template <typename ret, typename... args>
184  class Plugin_Interface <ret (args...)> : public Plugin_Interface_Base, public Plugin_Main_Interface_Base<ret (args...)>
185  {
186  private:
187 
188  public:
189  template <typename... plug_args>
190  Plugin_Interface(const std::string &type, const std::string &name, const plug_args&... inputs)
191  {
192  Plugin_Main_Interface_Base<ret (args...)>::enterMain(name, initPlugin(type, name, inputs...));
193  }
194 
195  ret operator() (const args&... params)
196  {
197  return Plugin_Main_Interface_Base<ret (args...)>::operator()(params...);
198  }
199  };
200 
201  }
202 
203  }
204 
205 }
206 
207 #endif
Plugin_Interface(const std::string &type, const std::string &name, const plug_args &... inputs)
Abstract base class for priors.
Definition: base_prior.hpp:40
Variadic utilty functions.
YAML::Node operator[](const std::string &key)
declaration for scanner module
const std::map< type_index, void * > & error_map_return()
Plugin_Interface(const std::string &type, const std::string &name, const plug_args &... inputs)
void input_variadic_vector(std::vector< void *> &)
Inputs a varibadic pack into a vector.
std::string path
full path to library containing plugin
const std::string stringifyVariadic()
Plugin info to be given to the interface class.
#define scan_err
Defined to macros to output errors in the form: scan_err << "error" << scan_end; scan_warn << "warnin...
int enterMain(const std::string &name, const std::map< type_index, void *> &index_map)
Utility Functions for the Gambit Scanner.
Interface for a ScannerBit plugin.
hb_ModelParameters void
const std::map< type_index, void * > & initPlugin(const std::string &type, const std::string &name, const plug_args &... inputs)
auto operator()(args &... params) -> typename find_variadic_type< void(args...), T... >::ret_type
#define scan_end
Manager class for creating printer objects.
Loader singleton class for scanner plugins.
std::string demangle(const std::string &in)
Demangles gnu c++ name.
std::string full_string
full string that ScannerBit sees
EXPORT_SYMBOLS pluginInfo plugin_info
Access Functor for plugin info.
TODO: see if we can use this one:
Definition: Analysis.hpp:33