Awali
Another Weighted Automata library
handler.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2022 Sylvain Lombardy, Victor Marsault, Jacques Sakarovitch
3 //
4 // Awali is a free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef AWALI_DYN_LOADING_HANDLER_HH
18 #define AWALI_DYN_LOADING_HANDLER_HH
19 #include <dlfcn.h>
20 #include <iostream>
22 #include <unordered_map>
23 #include <map>
26 
27 namespace awali {
28  namespace dyn {
29  namespace loading {
30 
31  /* This function returns a pointer on the function 'name' of the library
32  corresponding to the 'context'.
33  If the library does not exist or does contain this function,
34  make_library is called.
35  */
36 
37 
38  void* get_handler(const std::string& name, const std::string& group,
39  const std::string& static_context);
40 
41  void* get_handler(const std::string& name, const std::string& group,
42  const std::string& static_context1,
43  const std::string& static_context2);
44 
45  void* get_handler(const std::string& name, const std::string& static_context);
46 
47 // template<typename TYPERET, TYPERET (*FCT)(automaton_t)>
48 // TYPERET call(std::string name, std::string group, automaton_t aut) {
49 // std::string stat_ctx = aut->get_context()->sname();
50 // typedef TYPERET (*bridge_t)(automaton_t);
51 // auto bridge = (bridge_t) get_handler(name, group, aut->get_context()->sname());
52 // return bridge(aut);
53 // }
54 //
55 
56  template<typename RET_T, typename... ARGS_T>
57  RET_T
58  call0(std::string const& name, std::string const& group, std::string const& stat_ctx,
59  ARGS_T... args)
60  {
61  typedef RET_T (*bridge_t)(ARGS_T...);
62  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
63  return bridge(args...);
64  }
65 
66 
67  template<typename RET_T, typename ARG1_T, typename... ARGS_T>
68  RET_T
69  call1(std::string const& name, std::string const& group,
70  ARG1_T arg1, ARGS_T... args)
71  {
72  std::string stat_ctx = arg1->get_context()->sname();
73  typedef RET_T (*bridge_t)(ARG1_T, ARGS_T...);
74  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
75  return bridge(arg1, args...);
76  }
77 
78 
79  template<typename RET_T, typename ARG2_T, typename ARG1_T,
80  typename... ARGS_T>
81  RET_T
82  call2(std::string const& name, std::string const& group,
83  ARG1_T arg1, ARG2_T arg2, ARGS_T... args)
84  {
85  std::string stat_ctx1 = arg1->get_context()->sname();
86  std::string stat_ctx2 = arg2->get_context()->sname();
87  typedef RET_T (*bridge_t)(ARG1_T, ARG2_T, ARGS_T...);
88  bridge_t bridge
89  = (bridge_t) get_handler(name, group, stat_ctx1, stat_ctx2);
90  return bridge(arg1, arg2, args...);
91  }
92 
93 
94  //In name call_X_Y :
95  // - first X arguments are part of sttc context
96  // - following Y arguments are not
97  // The last argument (named `fct`) is only used for helping template substution. When it does not work, templates parameters should be put by hand and this argument may be omitted.
98 
99 
100  /* In the special case where X=0, the static context is explicitely given as argument 3 */
101  template<typename RET_T, typename ARG1_T>
102  RET_T
103  call_0_1(std::string const& name, std::string const& group, std::string const& stat_ctx,
104  ARG1_T other1,
105  RET_T(*fct)(ARG1_T) = nullptr)
106  {
107  typedef RET_T (*bridge_t)(ARG1_T);
108  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
109  return bridge(other1);
110  }
111 
112  template<typename RET_T, typename ARG1_T, typename ARG2_T>
113  RET_T
114  call_0_2(std::string const& name, std::string const& group, std::string const& stat_ctx,
115  ARG1_T other1, ARG2_T other2,
116  RET_T(*fct)(ARG1_T, ARG2_T) = nullptr)
117  {
118  typedef RET_T (*bridge_t)(ARG1_T, ARG2_T);
119  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
120  return bridge(other1, other2);
121  }
122 
123  template<typename RET_T, typename ARG1_T, typename ARG2_T, typename
124  ARG3_T>
125  RET_T
126  call_0_3(std::string const& name, std::string const& group, std::string const& stat_ctx,
127  ARG1_T other1, ARG2_T other2, ARG3_T other3,
128  RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T) = nullptr)
129  {
130  typedef RET_T (*bridge_t)(ARG1_T, ARG2_T, ARG3_T);
131  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
132  return bridge(other1, other2, other3);
133  }
134 
135  template<typename RET_T, typename ARG1_T>
136  RET_T
137  call_1_0(std::string const& name, std::string const& group, ARG1_T aut,
138  RET_T(*fct)(ARG1_T) = nullptr)
139  {
140  std::string stat_ctx = aut->get_context()->sname();
141  typedef RET_T (*bridge_t)(ARG1_T);
142  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
143  return bridge(aut);
144  }
145 
146 
147  template<typename RET_T, typename ARG1_T, typename ARG2_T>
148  RET_T
149  call_1_1(std::string const& name, std::string const& group, ARG1_T aut1,
150  ARG2_T other1, RET_T(*fct)(ARG1_T, ARG2_T) = nullptr)
151  {
152  std::string const& stat_ctx = aut1->get_context()->sname();
153  typedef RET_T (*bridge_t)(ARG1_T,ARG2_T);
154  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
155  return bridge(aut1, other1);
156  }
157 
158  template<typename RET_T, typename ARG1_T, typename ARG2_T,
159  typename ARG3_T>
160  RET_T
161  call_1_2(std::string const& name, std::string const& group, ARG1_T aut1,
162  ARG2_T other1, ARG3_T other2, RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T) = nullptr)
163  {
164  std::string stat_ctx = aut1->get_context()->sname();
165  typedef RET_T (*bridge_t)(ARG1_T,ARG2_T,ARG3_T);
166  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
167  return bridge(aut1, other1, other2);
168  }
169 
170  template<typename RET_T, typename ARG1_T, typename ARG2_T,
171  typename ARG3_T, typename ARG4_T>
172  RET_T
173  call_1_3(std::string const& name, std::string const& group, ARG1_T aut1,
174  ARG2_T other1, ARG3_T other2, ARG4_T other3,
175  RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T, ARG4_T) = nullptr)
176  {
177  std::string stat_ctx = aut1->get_context()->sname();
178  typedef RET_T (*bridge_t)(ARG1_T,ARG2_T,ARG3_T,ARG4_T);
179  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
180  return bridge(aut1, other1, other2, other3);
181  }
182 
183  template<typename RET_T, typename ARG1_T, typename ARG2_T,
184  typename ARG3_T, typename ARG4_T, typename ARG5_T>
185  RET_T
186  call_1_4(std::string const& name, std::string const& group, ARG1_T aut1,
187  ARG2_T other1, ARG3_T other2, ARG4_T other3, ARG5_T other4,
188  RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T, ARG4_T, ARG5_T) = nullptr)
189  {
190  std::string stat_ctx = aut1->get_context()->sname();
191  typedef RET_T (*bridge_t)(ARG1_T,ARG2_T,ARG3_T,ARG4_T, ARG5_T);
192  bridge_t bridge = (bridge_t) get_handler(name, group, stat_ctx);
193  return bridge(aut1, other1, other2, other3, other4);
194  }
195 
196  template<typename RET_T, typename ARG1_T, typename ARG2_T>
197  RET_T
198  call_2_0(std::string const& name, std::string const& group, ARG1_T aut1,
199  ARG2_T aut2, RET_T(*fct)(ARG1_T, ARG2_T) = nullptr)
200  {
201  std::string stat_ctx1 = aut1->get_context()->sname();
202  std::string stat_ctx2 = aut2->get_context()->sname();
203  typedef RET_T (*bridge_t)(ARG1_T, ARG2_T);
204  bridge_t bridge
205  = (bridge_t) get_handler(name, group, stat_ctx1, stat_ctx2);
206  return bridge(aut1, aut2);
207  }
208 
209  template<typename RET_T, typename ARG1_T, typename ARG2_T,
210  typename ARG3_T>
211  RET_T
212  call_2_1(std::string const& name, std::string const& group, ARG1_T aut1,
213  ARG2_T aut2, ARG3_T other1, RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T) = nullptr)
214  {
215  std::string stat_ctx1 = aut1->get_context()->sname();
216  std::string stat_ctx2 = aut2->get_context()->sname();
217  typedef RET_T (*bridge_t)(ARG1_T, ARG2_T, ARG3_T);
218  bridge_t bridge
219  = (bridge_t) get_handler(name, group, stat_ctx1, stat_ctx2);
220  return bridge(aut1, aut2, other1);
221  }
222 
223  template<typename TYPERET, typename ARG1, typename ARG2,
224  TYPERET(*FCT)(ARG1,ARG2)>
225  TYPERET call_tdc2(std::string const& name, std::string const& group, ARG1 aut1, ARG2 aut2)
226  {
227  std::string stat_ctx1 = aut1->get_context()->sname();
228  std::string stat_ctx2 = aut2->get_context()->sname();
229  std::string stat_ctx = stat_ctx1+"_"+stat_ctx2;
230  typedef TYPERET (*bridge_t)(ARG1, ARG2);
231  static std::unordered_map<std::string, void*> bridges;
232  auto it = bridges.find(stat_ctx);
233  if(it == bridges.end()) {
234  auto bridge = (bridge_t) get_handler(name, group, stat_ctx1, stat_ctx2);
235  bridges.emplace(stat_ctx, (void*) bridge);
236  return bridge(aut1, aut2);
237  }
238  else {
239  return ((bridge_t)it->second)(aut1, aut2);
240  }
241  }
242 
243 
244 // template<typename TYPERET, typename T2, TYPERET (*FCT)(automaton_t,T2)>
245 // TYPERET call2(std::string name, std::string group, automaton_t aut, T2 arg) {
246 // std::string stat_ctx = aut->get_context()->sname();
247 // typedef TYPERET (*bridge_t)(automaton_t,T2);
248 // static std::unordered_map<std::string, void*> bridges;
249 // auto it = bridges.find(stat_ctx);
250 // if(it == bridges.end()) {
251 // auto bridge = (bridge_t) get_handler(name, group, aut->get_context()->sname());
252 // bridges.emplace(stat_ctx, (void*) bridge);
253 // return bridge(aut, arg);
254 // }
255 // else {
256 // return ((bridge_t)it->second)(aut, arg);
257 // }
258 // }
259 //
260 // template<typename TYPERET, typename T2, typename T3, TYPERET (*FCT)(automaton_t,T2,T3)>
261 // TYPERET call3(std::string name, std::string group, automaton_t aut, T2 arg2, T3 arg3) {
262 // std::string stat_ctx = aut->get_context()->sname();
263 // typedef TYPERET (*bridge_t)(automaton_t,T2,T3);
264 // static std::unordered_map<std::string, void*> bridges;
265 // auto it = bridges.find(stat_ctx);
266 // if(it == bridges.end()) {
267 // auto bridge = (bridge_t) get_handler(name, group, aut->get_context()->sname());
268 // bridges.emplace(stat_ctx, (void*) bridge);
269 // return bridge(aut, arg2, arg3);
270 // }
271 // else {
272 // return ((bridge_t)it->second)(aut, arg2, arg3);
273 // }
274 // }
275 //
276 // template<typename TYPERET, typename T2, typename T3, typename T4, TYPERET (*FCT)(automaton_t,T2,T3,T4)>
277 // TYPERET call4(std::string name, std::string group, automaton_t aut, T2 arg2, T3 arg3, T4 arg4) {
278 // std::string stat_ctx = aut->get_context()->sname();
279 // typedef TYPERET (*bridge_t)(automaton_t,T2,T3,T4);
280 // static std::unordered_map<std::string, void*> bridges;
281 // auto it = bridges.find(stat_ctx);
282 // if(it == bridges.end()) {
283 // auto bridge = (bridge_t) get_handler(name, group, aut->get_context()->sname());
284 // bridges.emplace(stat_ctx, (void*) bridge);
285 // return bridge(aut, arg2, arg3, arg4);
286 // }
287 // else {
288 // return ((bridge_t)it->second)(aut, arg2, arg3, arg4);
289 // }
290 // }
291 //
292 // template<typename T, T (*FCT)(automaton_t,automaton_t)>
293 // T call_mixte(std::string name, std::string group, automaton_t aut1,
294 // automaton_t aut2)
295 // {
296 // std::string stat_ctx1 = aut1->get_context()->sname();
297 // std::string stat_ctx2 = aut2->get_context()->sname();
298 // std::string stat_ctx = stat_ctx1+"_"+stat_ctx2;
299 // typedef T (*bridge_t)(automaton_t, automaton_t);
300 // static std::unordered_map<std::string, void*> bridges;
301 // auto it = bridges.find(stat_ctx);
302 // if(it == bridges.end()) {
303 // auto bridge = (bridge_t) get_handler(name, group, stat_ctx1, stat_ctx2);
304 // bridges.emplace(stat_ctx, (void*) bridge);
305 // return bridge(aut1, aut2);
306 // }
307 // else {
308 // return ((bridge_t)it->second)(aut1, aut2);
309 // }
310 // }
311 //
312 // template<typename T, typename T2, T (*FCT)(automaton_t,automaton_t,T2)>
313 // T call_mixte2(std::string name, std::string group, automaton_t aut1, automaton_t aut2, T2 arg2) {
314 // std::string stat_ctx1 = aut1->get_context()->sname();
315 // std::string stat_ctx2 = aut2->get_context()->sname();
316 // std::string stat_ctx = stat_ctx1+"_"+stat_ctx2;
317 // typedef T (*bridge_t)(automaton_t, automaton_t, T2);
318 // static std::unordered_map<std::string, void*> bridges;
319 // auto it = bridges.find(stat_ctx);
320 // if(it == bridges.end()) {
321 // auto bridge = (bridge_t) get_handler(name, group, stat_ctx1, stat_ctx2);
322 // bridges.emplace(stat_ctx, (void*) bridge);
323 // return bridge(aut1, aut2, arg2);
324 // }
325 // else {
326 // return ((bridge_t) it->second)(aut1, aut2, arg2);
327 // }
328 // }
329  }
330  }
331 }//end of ns awali::dyn
332 
333 #define HANDLER_EXTERN extern
335 #undef HANDLER_EXTERN
336 
337 #endif
RET_T call_1_4(std::string const &name, std::string const &group, ARG1_T aut1, ARG2_T other1, ARG3_T other2, ARG4_T other3, ARG5_T other4, RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T, ARG4_T, ARG5_T)=nullptr)
Definition: handler.hh:186
RET_T call0(std::string const &name, std::string const &group, std::string const &stat_ctx, ARGS_T... args)
Definition: handler.hh:58
RET_T call_1_2(std::string const &name, std::string const &group, ARG1_T aut1, ARG2_T other1, ARG3_T other2, RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T)=nullptr)
Definition: handler.hh:161
RET_T call_2_0(std::string const &name, std::string const &group, ARG1_T aut1, ARG2_T aut2, RET_T(*fct)(ARG1_T, ARG2_T)=nullptr)
Definition: handler.hh:198
RET_T call_1_1(std::string const &name, std::string const &group, ARG1_T aut1, ARG2_T other1, RET_T(*fct)(ARG1_T, ARG2_T)=nullptr)
Definition: handler.hh:149
RET_T call2(std::string const &name, std::string const &group, ARG1_T arg1, ARG2_T arg2, ARGS_T... args)
Definition: handler.hh:82
RET_T call_1_3(std::string const &name, std::string const &group, ARG1_T aut1, ARG2_T other1, ARG3_T other2, ARG4_T other3, RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T, ARG4_T)=nullptr)
Definition: handler.hh:173
RET_T call_1_0(std::string const &name, std::string const &group, ARG1_T aut, RET_T(*fct)(ARG1_T)=nullptr)
Definition: handler.hh:137
TYPERET call_tdc2(std::string const &name, std::string const &group, ARG1 aut1, ARG2 aut2)
Definition: handler.hh:225
RET_T call1(std::string const &name, std::string const &group, ARG1_T arg1, ARGS_T... args)
Definition: handler.hh:69
RET_T call_2_1(std::string const &name, std::string const &group, ARG1_T aut1, ARG2_T aut2, ARG3_T other1, RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T)=nullptr)
Definition: handler.hh:212
void * get_handler(const std::string &name, const std::string &group, const std::string &static_context)
RET_T call_0_2(std::string const &name, std::string const &group, std::string const &stat_ctx, ARG1_T other1, ARG2_T other2, RET_T(*fct)(ARG1_T, ARG2_T)=nullptr)
Definition: handler.hh:114
RET_T call_0_3(std::string const &name, std::string const &group, std::string const &stat_ctx, ARG1_T other1, ARG2_T other2, ARG3_T other3, RET_T(*fct)(ARG1_T, ARG2_T, ARG3_T)=nullptr)
Definition: handler.hh:126
RET_T call_0_1(std::string const &name, std::string const &group, std::string const &stat_ctx, ARG1_T other1, RET_T(*fct)(ARG1_T)=nullptr)
Definition: handler.hh:103
Main namespace of Awali.
Definition: ato.hh:22