icedb  version 0.5.1
Snow particle scattering database API
unitsPlugins.cpp
Go to the documentation of this file.
1 #include <string>
2 #include <map>
3 #include <mutex>
4 #include <vector>
5 #include "../icedb/units/units.hpp"
6 #include "../icedb/units/unitsPlugins.hpp"
7 #include "../private/unitsBackend.hpp"
8 #include "../icedb/logging.hpp"
9 #include "../icedb/error.hpp"
10 #include "../private/options.hpp"
11 
12 namespace icedb {
13  namespace units {
14 
15  namespace implementations {
16  implementations::Unithandler::Unithandler(const char* id) : id(id) {}
19 
20  std::mutex m_backends;
21  std::map<std::string, converter_p> _backends;
22  std::shared_ptr<std::vector<conv_prov_cp > > _providers;
23 
24  inline std::string _mangle_string(const std::string &inUnits, const std::string &outUnits,
25  const std::string &family) {
26  std::string res(family);
27  res.append("___");
28  res.append(inUnits);
29  res.append("___");
30  res.append(outUnits);
31  return res;
32  }
33 
34  void _registerBackend(const std::string &inUnits, const std::string &outUnits,
35  const std::string &family, converter_p p) {
36  std::lock_guard<std::mutex> mlock(m_backends);
37  std::string h = _mangle_string(inUnits, outUnits, family);
38  _backends.emplace(std::pair<std::string, converter_p>(h, p));
39  }
40  converter_p _queryBackend(const std::string &inUnits, const std::string &outUnits,
41  const std::string &family) {
42  std::string h = _mangle_string(inUnits, outUnits, family);
43  std::lock_guard<std::mutex> mlock(m_backends);
44  converter_p res;
45  if (_backends.count(h)) res = _backends.at(h);
46  return res;
47  }
48 
49  void _init() {
50  static bool inited = false;
51  if (inited) return;
52  inited = true;
53  //template <class base, class reg, class obj>
54  // void doRegisterHook(const obj& res)
55  std::shared_ptr<implementations::Converter_registry_provider> res(
57  res->canConvert = simpleUnits::canConvert;
58  res->constructConverter = simpleUnits::constructConverter;
59  static const char* name = "1simple";
60  res->name = name;
61  _providers = std::shared_ptr<std::vector<conv_prov_cp > >(new std::vector<conv_prov_cp >);
62  _providers->push_back(res);
63  }
65  return _providers;
66  }
67  }
68 
69  std::shared_ptr<const implementations::Unithandler> converter::getConverter(
70  const std::string &inUnits, const std::string &outUnits) {
71  implementations::_init(); // Static function that registers the builtin unit converters.
72 
73  const auto &hooks = implementations::getHooks();
74  // hull_provider_registry, hull_provider<convexHull> >::getHooks();
75  //std::cerr << hooks->size() << std::endl;
76  auto opts = registry::options::generate();
77  opts->setVal<std::string>("inUnits", inUnits);
78  opts->setVal<std::string>("outUnits", outUnits);
79  for (const auto &i : *(hooks.get()))
80  {
81  if (!i->canConvert) continue;
82  if (!i->constructConverter) continue;
83  if (!i->canConvert(opts)) continue;
84  return i->constructConverter(opts);
85  }
86  // Only return nullptr if unable to find a usable hook.
87  ICEDB_log("units", icedb::logging::ICEDB_LOG_DEBUG_1, "No handler for unit conversion found for "
88  "conversions between " << inUnits << " and " << outUnits << ".");
89  // We don;t want to throw an error here. Only throw if a conversion is actually attempted.
90  // Otherwise, we quash the purpose of isValid().
91  //ICEDB_throw(icedb::error::error_types::xBadInput)
92  // .add<std::string>("Reason", "There is no code which can handle this unit conversion.")
93  // .add<std::string>("inUnits", inUnits)
94  // .add<std::string>("outUnits", outUnits)
95  // ;
96  return nullptr;
97  }
98 
99 
100  }
101 }
102 
static bool canConvert(Converter_registry_provider::optsType opts)
Definition: unitsSimple.cpp:10
std::shared_ptr< const std::vector< conv_prov_cp > > conv_hooks_t
static Unithandler_p getConverter(const std::string &inUnits, const std::string &outUnits)
std::map< std::string, converter_p > _backends
static std::shared_ptr< options > generate()
Definition: options.cpp:18
std::shared_ptr< std::vector< conv_prov_cp > > _providers
std::string _mangle_string(const std::string &inUnits, const std::string &outUnits, const std::string &family)
void _registerBackend(const std::string &inUnits, const std::string &outUnits, const std::string &family, converter_p p)
converter_p _queryBackend(const std::string &inUnits, const std::string &outUnits, const std::string &family)
#define ICEDB_log(c, p, x)
Definition: logging.hpp:45
static std::shared_ptr< const Unithandler > constructConverter(Converter_registry_provider::optsType opts)
Definition: unitsSimple.cpp:17
std::shared_ptr< const converter > converter_p
Definition: units.hpp:16