cpp-mate  0.7
Helpful library for C++.
Forge.hpp
1 /*
2  * Copyright (C) 2020 Alexander Kornilov (akornilov.82@gmail.com)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CPP_MATE_FORGE_HPP
18 #define CPP_MATE_FORGE_HPP
19 
20 #include <CppMate/Checkers.hpp>
21 
22 #include <string>
23 #include <utility>
24 #include <memory>
25 #include <vector>
26 #include <map>
27 #include <stdexcept>
28 
29 namespace CppMate {
30 namespace Forge {
31 
35 template<typename T, typename I, typename P>
36 class Factory
37 {
38 public:
39 
44  Factory(const Factory& other) = delete;
45 
50  Factory(Factory&& other) = default;
51 
57  Factory& operator=(const Factory& other) = delete;
58 
64  Factory& operator=(Factory&& other) = default;
65 
73  template<typename... A>
74  std::unique_ptr<T> createInstance(const std::string& name, A&&... args) const {
75  return getProvider(name).getInstance(std::forward<A>(args)...);
76  }
77 
84  template<typename... A>
85  std::unique_ptr<T> requestInstance(A&&... args) const {
86  for (const auto& pair: _providers) {
87  try {
88  return pair.second->getInstance(std::forward<A>(args)...);
89  } catch(const std::invalid_argument&) {
90  // Ignore, try next provider
91  }
92  }
93  throw std::invalid_argument("Appropriate provider not found");
94  }
95 
100  std::vector<std::string> getProviders() const {
101  std::vector<std::string> names;
102  for (const auto& pair: _providers) {
103  names.push_back(pair.first);
104  }
105  return names;
106  }
107 
114  I getInfo(const std::string& name) const {
115  return getProvider(name).getInfo();
116  }
117 
124  void registerProvider(std::unique_ptr<P> provider, bool override = false) {
125  checkArg(provider.get());
126  const auto& name = provider->getInfo().getName();
127  if (!override) {
128  checkArg(_providers.find(name) == std::end(_providers));
129  }
130  _providers[name] = std::move(provider);
131  }
132 
138  bool deregisterProvider(const std::string& name) {
139  return _providers.erase(name) > 0;
140  }
141 
142 protected:
143 
147  Factory() = default;
148 
152  virtual ~Factory() = default;
153 
159  P& getProvider(const std::string& name) const {
160  auto it = _providers.find(name);
161  checkArg(it != std::end(_providers));
162  return *it->second;
163  }
164 
168  std::map<std::string, std::unique_ptr<P> > _providers;
169 };
170 
174 class Info
175 {
176 public:
177 
182  explicit Info(const std::string& name): _name(name) {}
183 
187  virtual ~Info() = default;
188 
193  virtual std::string getName() const {
194  return _name;
195  }
196 
197 protected:
198 
202  std::string _name;
203 };
204 
208 template <typename T>
209 class Provider
210 {
211 public:
212 
217  explicit Provider(const T& info): _info(info) {}
218 
222  virtual ~Provider() = default;
223 
228  virtual T getInfo() const {
229  return _info;
230  }
231 
232 protected:
233 
237  T _info;
238 };
239 
240 } // namespace Forge
241 } // namespace CppMate
242 
243 #endif // CPP_MATE_FORGE_HPP
Represents abstract factory.
Definition: Forge.hpp:37
void registerProvider(std::unique_ptr< P > provider, bool override=false)
Registers new provider.
Definition: Forge.hpp:124
Factory(const Factory &other)=delete
Disabled copy constructor.
P & getProvider(const std::string &name) const
Returns provider by name.
Definition: Forge.hpp:159
bool deregisterProvider(const std::string &name)
Deregisters provider by name.
Definition: Forge.hpp:138
virtual ~Factory()=default
I getInfo(const std::string &name) const
Returns information about provider by name.
Definition: Forge.hpp:114
Factory & operator=(const Factory &other)=delete
Disabled assign operator.
Factory(Factory &&other)=default
Default move constructor.
Factory & operator=(Factory &&other)=default
Default move operator.
std::unique_ptr< T > requestInstance(A &&... args) const
Tries to create a new instance by provided arguments.
Definition: Forge.hpp:85
std::map< std::string, std::unique_ptr< P > > _providers
Map of providers.
Definition: Forge.hpp:168
std::vector< std::string > getProviders() const
Returns list of provider names.
Definition: Forge.hpp:100
std::unique_ptr< T > createInstance(const std::string &name, A &&... args) const
Creates a new instance by name.
Definition: Forge.hpp:74
Represents information about provider.
Definition: Forge.hpp:175
virtual std::string getName() const
Returns name of provider.
Definition: Forge.hpp:193
std::string _name
Name field.
Definition: Forge.hpp:202
virtual ~Info()=default
Info(const std::string &name)
Constructor.
Definition: Forge.hpp:182
Represents provider.
Definition: Forge.hpp:210
Provider(const T &info)
Constructor.
Definition: Forge.hpp:217
virtual ~Provider()=default
T _info
Information field.
Definition: Forge.hpp:237
virtual T getInfo() const
Returns information about provider.
Definition: Forge.hpp:228
Definition: BinaryData.hpp:28