Stochastic Loading Module
factory.h
1 /* THIS LICENSE ONLY APPLIES TO THIS FILE, FACTORY.H. THE REMAINDER OF THE FILES */
2 /* IN THIS PROJECT ARE RELEASED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 */
3 
4 /* # MIT License */
5 
6 /* Copyright (c) 2018 NHERI SimCenter */
7 /* Copyright (c) 2017 CB-Geo MPM */
8 
9 /* Permission is hereby granted, free of charge, to any person obtaining a copy */
10 /* of this software and associated documentation files (the "Software"), to deal */
11 /* in the Software without restriction, including without limitation the rights */
12 /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
13 /* copies of the Software, and to permit persons to whom the Software is */
14 /* furnished to do so, subject to the following conditions: */
15 
16 /* The above copyright notice and this permission notice shall be included in all */
17 /* copies or substantial portions of the Software. */
18 
19 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
20 /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
21 /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
22 /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
23 /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
24 /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
25 /* SOFTWARE. */
26 
27 
28 #ifndef _FACTORY_H_
29 #define _FACTORY_H_
30 
31 #include <functional>
32 #include <map>
33 #include <memory>
34 #include <string>
35 #include <utility>
36 #include <vector>
37 
43 template <typename Tbaseclass, typename... Targs>
44 class Factory {
45  public:
49  static Factory* instance() {
50  static Factory factory;
51  return &factory;
52  }
53 
59  template <typename Tderivedclass>
60  void register_factory(const std::string& key) {
61  registry[key].reset(new Creator<Tderivedclass>);
62  }
63 
70  std::shared_ptr<Tbaseclass> create(const std::string& key, Targs&&... args) {
71  if (!this->check(key))
72  throw std::runtime_error("Invalid key: " + key +
73  ", not found in the factory register!");
74  return registry.at(key)->create(std::forward<Targs>(args)...);
75  }
76 
82  bool check(const std::string& key) const {
83  bool status = false;
84  for (const auto& keyvalue : registry)
85  if (keyvalue.first == key) status = true;
86  return status;
87  }
88 
93  std::vector<std::string> list() const {
94  std::vector<std::string> factory_items;
95  for (const auto& keyvalue : registry)
96  factory_items.push_back(keyvalue.first);
97  return factory_items;
98  }
99 
100  private:
104  Factory() = default;
105 
109  struct CreatorBase {
110  // A virtual create function
111  virtual std::shared_ptr<Tbaseclass> create(Targs&&...) = 0;
112  };
113 
118  template <typename Tderivedclass>
119  struct Creator : public CreatorBase {
123  std::shared_ptr<Tbaseclass> create(Targs&&... args) override {
124  return std::make_shared<Tderivedclass>(std::forward<Targs>(args)...);
125  }
126  };
127 
128  std::map<std::string, std::shared_ptr<CreatorBase>> registry;
131 };
132 
139 template <typename Tbaseclass, typename Tderivedclass, typename... Targs>
140 class Register {
141  public:
146  explicit Register(const std::string& key) {
147  // register the class factory function
149  ->template register_factory<Tderivedclass>(key);
150  }
151 };
152 
153 #endif // _FACTORY_H_
void register_factory(const std::string &key)
Definition: factory.h:60
std::shared_ptr< Tbaseclass > create(const std::string &key, Targs &&...args)
Definition: factory.h:70
Register(const std::string &key)
Definition: factory.h:146
static Factory * instance()
Definition: factory.h:49
std::vector< std::string > list() const
Definition: factory.h:93
bool check(const std::string &key) const
Definition: factory.h:82