geopm  3.1.1.dev272+gdfb40a8d
GEOPM - Global Extensible Open Power Manager
PluginFactory.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 - 2024 Intel Corporation
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #ifndef PLUGINFACTORY_HPP_INCLUDE
7 #define PLUGINFACTORY_HPP_INCLUDE
8 
9 #include <functional>
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "geopm_public.h"
16 
17 #include "Exception.hpp"
18 
19 namespace geopm
20 {
21  template<class T> class PluginFactory
22  {
23  public:
24  PluginFactory() = default;
25  virtual ~PluginFactory() = default;
26  PluginFactory(const PluginFactory &other) = delete;
27  PluginFactory &operator=(const PluginFactory &other) = delete;
38  void register_plugin(const std::string &plugin_name,
39  std::function<std::unique_ptr<T>()> make_plugin,
40  const std::map<std::string, std::string> &dictionary = m_empty_dictionary)
41  {
42  auto result = m_name_func_map.emplace(plugin_name, make_plugin);
43  if (!result.second) {
44  throw Exception("PluginFactory::register_plugin(): name: \"" +
45  plugin_name + "\" has been previously registered",
46  GEOPM_ERROR_INVALID, __FILE__, __LINE__);
47  }
48  m_dictionary.emplace(plugin_name, dictionary);
49  m_plugin_names.push_back(plugin_name);
50  }
59  std::unique_ptr<T> make_plugin(const std::string &plugin_name) const
60  {
61  auto it = m_name_func_map.find(plugin_name);
62  if (it == m_name_func_map.end()) {
63  throw Exception("PluginFactory::make_plugin(): name: \"" +
64  plugin_name + "\" has not been previously registered",
65  GEOPM_ERROR_INVALID, __FILE__, __LINE__);
66  }
67  return it->second();
68  }
74  std::vector<std::string> plugin_names(void) const
75  {
76  return m_plugin_names;
77  }
85  const std::map<std::string, std::string> &dictionary(const std::string &plugin_name) const
86  {
87  auto it = m_dictionary.find(plugin_name);
88  if (it == m_dictionary.end()) {
89  throw Exception("PluginFactory::dictionary(): Plugin named \"" + plugin_name +
90  "\" has not been registered with the factory.",
91  GEOPM_ERROR_INVALID, __FILE__, __LINE__);
92  }
93  return it->second;
94  }
95  private:
96  std::map<std::string, std::function<std::unique_ptr<T>()> > m_name_func_map;
97  std::vector<std::string> m_plugin_names;
98  std::map<std::string, const std::map<std::string, std::string> > m_dictionary;
99  static const std::map<std::string, std::string> m_empty_dictionary;
100  };
101 
102  template <class Type>
103  const std::map<std::string, std::string> PluginFactory<Type>::m_empty_dictionary = {};
104 
105 }
106 #endif
Class for all GEOPM-specific exceptions.
Definition: Exception.hpp:48
Definition: PluginFactory.hpp:22
virtual ~PluginFactory()=default
PluginFactory(const PluginFactory &other)=delete
std::vector< std::string > plugin_names(void) const
Returns a list of all valid plugin names registered with the factory in the order they were registere...
Definition: PluginFactory.hpp:74
const std::map< std::string, std::string > & dictionary(const std::string &plugin_name) const
Returns the dictionary of static metadata about a registered type. If the type was not registered,...
Definition: PluginFactory.hpp:85
PluginFactory & operator=(const PluginFactory &other)=delete
std::unique_ptr< T > make_plugin(const std::string &plugin_name) const
Create an object of the requested type. If the type was not registered, throws an exception.
Definition: PluginFactory.hpp:59
void register_plugin(const std::string &plugin_name, std::function< std::unique_ptr< T >()> make_plugin, const std::map< std::string, std::string > &dictionary=m_empty_dictionary)
Add a plugin to the factory.
Definition: PluginFactory.hpp:38
@ GEOPM_ERROR_INVALID
Definition: geopm_error.h:20
Definition: Agg.cpp:20