Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
registry.hh
Go to the documentation of this file.
1 #ifndef LIB_VCSN_ALGOS_REGISTRY_HH
2 # define LIB_VCSN_ALGOS_REGISTRY_HH
3 
4 # include <iostream>
5 # include <map>
6 # include <stdexcept>
7 
8 # include <vcsn/dyn/translate.hh> // compile
9 # include <vcsn/misc/name.hh>
10 # include <vcsn/misc/signature.hh>
11 # include <vcsn/misc/raise.hh>
12 
13 namespace vcsn
14 {
15  namespace dyn
16  {
17  namespace detail
18  {
19  template <typename Fun>
20  class Registry
21  {
22  public:
25  Registry(const std::string& name)
26  : name_(name)
27  {}
28 
29  Registry() = delete;
30 
32  bool debug = getenv("VCSN_DYN");
33 
35  bool set(const signature& sig, Fun fn)
36  {
37  if (debug)
38  std::cerr << "Register(" << name_ << ").set(" << sig << ")\n";
39  map_[sig] = fn;
40  return true;
41  }
42 
44  const Fun* get0(const signature& sig)
45  {
46  if (debug)
47  std::cerr << "Register(" << name_ << ").get(" << sig << ")\n";
48  auto i = map_.find(sig);
49  if (i == map_.end())
50  return nullptr;
51  else
52  return i->second;
53  }
54 
56  std::string signatures(const signature& sig) const
57  {
58  std::string res;
59  res += " failed signature:\n";
60  res += " " + sig.to_string() + "\n";
61  res += " available versions:\n";
62  for (auto p: map_)
63  res += " " + p.first.to_string() + "\n";
64  return res;
65  }
66 
68  const Fun& get(const signature& sig)
69  {
70  // Maybe already loaded.
71  if (auto fun = get0(sig))
72  return *fun;
73  else
74  {
75  // No, try to compile it.
76  try
77  {
79  auto fun = get0(sig);
80  require(fun,
81  name_,
82  ": compilation succeeded, but function is unavailable\n",
83  signatures(sig));
84  return *fun;
85  }
86  catch (const jit_error& e)
87  {
88  raise(e.assertions.empty()
89  ? name_ + ": no such implementation\n"
90  : e.assertions,
91  signatures(sig),
92  e.what());
93  }
94  }
95  }
96 
98  template <typename... Args>
99  auto
100  call(const signature& sig, Args&&... args)
101  -> decltype(std::declval<Fun>()(args...))
102  {
103  return (get(sig))(std::forward<Args>(args)...);
104  }
105 
106  template <typename... Args>
107  auto
108  call(Args&&... args)
109  -> decltype(std::declval<Fun>()(args...))
110  {
111  return call(vsignature(std::forward<Args>(args)...),
112  std::forward<Args>(args)...);
113  }
114 
115  template <typename T>
116  auto
117  call_variadic(const std::vector<T>& ts)
118  -> decltype(std::declval<Fun>()(ts))
119  {
120  signature sig;
121  for (const auto& t: ts)
122  sig.sig.emplace_back(vname(t));
123  return (get(sig))(ts);
124  }
125 
126  private:
128  std::string name_;
130  using map_t = std::map<signature, Fun*>;
132  };
133  }
134  }
135 }
136 
138 # define REGISTER_DEFINE(Name) \
139  namespace detail \
140  { \
141  static \
142  Registry<Name ## _t>& \
143  Name ## _registry() \
144  { \
145  static Registry<Name ## _t> instance{#Name}; \
146  return instance; \
147  } \
148  \
149  bool \
150  Name ## _register(const signature& sig, Name ## _t fn) \
151  { \
152  return Name ## _registry().set(sig, fn); \
153  } \
154  }
155 
156 #endif // !LIB_VCSN_ALGOS_REGISTRY_HH
An exception suited for our compilation errors.
Definition: translate.hh:14
bool debug
Whether log messages should be issued.
Definition: registry.hh:32
void compile(const std::string &ctx)
Compile, and load, a DSO with instantiations for ctx.
Definition: translate.cc:337
std::string name_
Function name (e.g., "determinize").
Definition: registry.hh:128
auto call(const signature &sig, Args &&...args) -> decltype(std::declval< Fun >()(args...))
Call function for signature sig.
Definition: registry.hh:100
signature vsignature(Args &&...args)
The signature of (Args...).
Definition: name.hh:178
std::string signatures(const signature &sig) const
A message about a failed signature compilation.
Definition: registry.hh:56
std::map< signature, Fun * > map_t
Context name -> pointer to implementation.
Definition: registry.hh:130
Signature of a function call.
Definition: signature.hh:14
std::string vname(T &t)
Definition: name.hh:65
bool set(const signature &sig, Fun fn)
Register function fn for signature sig.
Definition: registry.hh:35
auto call(Args &&...args) -> decltype(std::declval< Fun >()(args...))
Definition: registry.hh:108
const Fun * get0(const signature &sig)
Get function for signature sig.
Definition: registry.hh:44
std::string assertions
If defined, static assertions that failed (ends with a eol).
Definition: translate.hh:18
Registry(const std::string &name)
Create a register for an algorithm.
Definition: registry.hh:25
auto call_variadic(const std::vector< T > &ts) -> decltype(std::declval< Fun >()(ts))
Definition: registry.hh:117
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:39
std::string to_string() const
Definition: signature.cc:9