Vcsn  2.8
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 <lib/vcsn/dyn/translate.hh> // compile
9 #include <vcsn/dyn/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  Registry(const Registry&) = delete;
32  Registry(Registry&&) = delete;
33 
35  bool debug = getenv("VCSN_DYN");
36 
38  bool set(const signature& sig, Fun* fn)
39  {
40  assert(fn);
41  if (debug)
42  std::cerr << "Register(" << name_ << ").set(" << sig << ")\n";
43  map_[sig] = fn;
44  return true;
45  }
46 
48  const Fun* get0(const signature& sig)
49  {
50  if (debug)
51  std::cerr << "Register(" << name_ << ").get(" << sig << ")\n";
52  auto i = map_.find(sig);
53  if (i == map_.end())
54  return nullptr;
55  else
56  return i->second;
57  }
58 
60  std::string signatures(const signature& sig) const
61  {
62  auto sigs = std::vector<std::string>();
63  sigs.reserve(map_.size());
64  for (auto p: map_)
65  sigs.emplace_back(p.first.to_string());
66  boost::sort(sigs);
67 
68  auto res = std::string{};
69  res += " failed signature:\n";
70  res += " " + sig.to_string() + "\n";
71  res += " available versions:\n";
72  for (auto s: sigs)
73  res += " " + s + "\n";
74  return res;
75  }
76 
78  const Fun* get(const signature& sig)
79  {
80  // Maybe already loaded.
81  if (auto res = get0(sig))
82  return res;
83  else
84  // No, try to compile it.
85  {
86  try
87  {
89  }
90  catch (const jit_error& e)
91  {
92  raise(e.assertions.empty()
93  ? name_ + ": no such implementation\n"
94  : e.assertions,
95  signatures(sig),
96  e.what());
97  }
98  res = get0(sig);
100  name_,
101  ": compilation succeeded, "
102  "but function is unavailable\n",
103  signatures(sig));
104  return res;
105  }
106  }
107 
111  template <typename... Args>
112  auto
113  call(const signature& sig, Args&&... args)
114  -> decltype(std::declval<Fun>()(args...))
115  {
116  return (get(sig))(std::forward<Args>(args)...);
117  }
118 
119  template <typename... Args>
120  auto
121  call(Args&&... args)
122  -> decltype(std::declval<Fun>()(args...))
123  {
124  return call(vsignature(std::forward<Args>(args)...),
125  std::forward<Args>(args)...);
126  }
127 
128  private:
130  std::string name_;
132  using map_t = std::unordered_map<signature, Fun*>;
134  };
135  }
136  }
137 }
138 
140 #define REGISTRY_DEFINE(Name) \
141  namespace detail \
142  { \
143  static \
144  Registry<Name ## _t>& \
145  Name ## _registry() \
146  { \
147  static Registry<Name ## _t> instance{#Name}; \
148  return instance; \
149  } \
150  \
151  bool \
152  Name ## _register(const signature& sig, Name ## _t fn) \
153  { \
154  return Name ## _registry().set(sig, fn); \
155  } \
156  }
std::unordered_map< signature, Fun * > map_t
Signature -> pointer to implementation.
Definition: registry.hh:132
const Fun * get0(const signature &sig)
Get function for signature sig.
Definition: registry.hh:48
auto sort(const Aut &a) -> permutation_automaton< Aut >
Definition: sort.hh:161
std::string to_string() const
Definition: signature.cc:9
void compile(const std::string &ctx)
Compile, and load, a DSO with instantiations for ctx.
Definition: translate.cc:409
Registry(const std::string &name)
Create a register for an algorithm.
Definition: registry.hh:26
std::string signatures(const signature &sig) const
A message about a failed signature compilation.
Definition: registry.hh:60
std::string name_
Function name (e.g., "determinize").
Definition: registry.hh:130
auto call(Args &&... args) -> decltype(std::declval< Fun >()(args...))
Definition: registry.hh:121
An exception suited for our compilation errors.
Definition: translate.hh:13
Definition: a-star.hh:8
Signature of a function call.
Definition: signature.hh:15
signature vsignature(Args &&... args)
The signature of (Args...).
Definition: name.hh:310
bool debug
Whether log messages should be issued.
Definition: registry.hh:35
std::string assertions
If defined, static assertions that failed (ends with a eol).
Definition: translate.hh:17
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
Definition: raise.hh:98
return res
Definition: multiply.hh:399
auto call(const signature &sig, Args &&... args) -> decltype(std::declval< Fun >()(args...))
Call function for signature sig.
Definition: registry.hh:113