Vcsn  2.2a
Be Rational
registry.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <iostream>
5 
6 #include <boost/range/algorithm/sort.hpp>
7 
8 #include <vcsn/dyn/translate.hh> // compile
9 #include <vcsn/misc/name.hh>
10 #include <vcsn/misc/raise.hh>
11 #include <vcsn/misc/signature.hh>
13 
14 namespace vcsn
15 {
16  namespace dyn
17  {
18  namespace detail
19  {
20  template <typename Fun>
21  class Registry
22  {
23  public:
26  Registry(const std::string& name)
27  : name_(name)
28  {}
29 
30  Registry() = delete;
31 
33  bool debug = getenv("VCSN_DYN");
34 
36  bool set(const signature& sig, Fun* fn)
37  {
38  if (debug)
39  std::cerr << "Register(" << name_ << ").set(" << sig << ")\n";
40  map_[sig] = fn;
41  return true;
42  }
43 
45  const Fun* get0(const signature& sig)
46  {
47  if (debug)
48  std::cerr << "Register(" << name_ << ").get(" << sig << ")\n";
49  auto i = map_.find(sig);
50  if (i == map_.end())
51  return nullptr;
52  else
53  return i->second;
54  }
55 
57  std::string signatures(const signature& sig) const
58  {
59  auto sigs = std::vector<std::string>();
60  sigs.reserve(map_.size());
61  for (auto p: map_)
62  sigs.emplace_back(p.first.to_string());
63  boost::sort(sigs);
64 
65  std::string res;
66  res += " failed signature:\n";
67  res += " " + sig.to_string() + "\n";
68  res += " available versions:\n";
69  for (auto s: sigs)
70  res += " " + s + "\n";
71  return res;
72  }
73 
75  const Fun* get(const signature& sig)
76  {
77  // Maybe already loaded.
78  if (auto fun = get0(sig))
79  return fun;
80  else
81  // No, try to compile it.
82  try
83  {
85  auto fun = get0(sig);
86  VCSN_REQUIRE(fun,
87  name_,
88  ": compilation succeeded, "
89  "but function is unavailable\n",
90  signatures(sig));
91  return fun;
92  }
93  catch (const jit_error& e)
94  {
95  raise(e.assertions.empty()
96  ? name_ + ": no such implementation\n"
97  : e.assertions,
98  signatures(sig),
99  e.what());
100  }
101  }
102 
106  template <typename... Args>
107  auto
108  call(const signature& sig, Args&&... args)
109  -> decltype(std::declval<Fun>()(args...))
110  {
111  return (get(sig))(std::forward<Args>(args)...);
112  }
113 
114  template <typename... Args>
115  auto
116  call(Args&&... args)
117  -> decltype(std::declval<Fun>()(args...))
118  {
119  return call(vsignature(std::forward<Args>(args)...),
120  std::forward<Args>(args)...);
121  }
122 
123  private:
125  std::string name_;
127  using map_t = std::unordered_map<signature, Fun*>;
129  };
130  }
131  }
132 }
133 
135 #define REGISTRY_DEFINE(Name) \
136  namespace detail \
137  { \
138  static \
139  Registry<Name ## _t>& \
140  Name ## _registry() \
141  { \
142  static Registry<Name ## _t> instance{#Name}; \
143  return instance; \
144  } \
145  \
146  bool \
147  Name ## _register(const signature& sig, Name ## _t fn) \
148  { \
149  return Name ## _registry().set(sig, fn); \
150  } \
151  }
std::unordered_map< signature, Fun * > map_t
Signature -> pointer to implementation.
Definition: registry.hh:127
auto sort(const Aut &a) -> permutation_automaton< Aut >
Definition: sort.hh:163
Registry(const std::string &name)
Create a register for an algorithm.
Definition: registry.hh:26
std::string assertions
If defined, static assertions that failed (ends with a eol).
Definition: translate.hh:17
std::string name_
Function name (e.g., "determinize").
Definition: registry.hh:125
An exception suited for our compilation errors.
Definition: translate.hh:13
void compile(const std::string &ctx)
Compile, and load, a DSO with instantiations for ctx.
Definition: translate.cc:388
bool debug
Whether log messages should be issued.
Definition: registry.hh:33
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
Definition: raise.hh:89
bool set(const signature &sig, Fun *fn)
Register function fn for signature sig.
Definition: registry.hh:36
std::string signatures(const signature &sig) const
A message about a failed signature compilation.
Definition: registry.hh:57
std::string to_string() const
Definition: signature.cc:9
const Fun * get0(const signature &sig)
Get function for signature sig.
Definition: registry.hh:45
auto call(const signature &sig, Args &&...args) -> decltype(std::declval< Fun >()(args...))
Call function for signature sig.
Definition: registry.hh:108
auto call(Args &&...args) -> decltype(std::declval< Fun >()(args...))
Definition: registry.hh:116
Signature of a function call.
Definition: signature.hh:15
signature vsignature(Args &&...args)
The signature of (Args...).
Definition: name.hh:288
Definition: a-star.hh:8