Registrar.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarXCore
19 * @author Raphael Grimm ( raphael dot grimm at kit dot edu)
20 * @date 2016
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#pragma once
25
26#include <mutex>
27#include <stdexcept>
28#include <unordered_map>
29#include <vector>
30
31namespace armarx
32{
33 /**
34 * @brief Stores key object pairs.
35 * The third template parameter offers the option to tag this registrar with a class.
36 *
37 * If polymorphic objects are required use a base class and unique pointers.
38 * E.g.:
39 * \code{.cpp}
40 * class Base{};
41 * class DerivedA{};
42 * class DerivedB{};
43 * Registrar<std::unique_ptr<Base>>::registerElement("A", DerivedA{});
44 * Registrar<std::unique_ptr<Base>>::registerElement("B", DerivedB{});
45 * \endcode
46 *
47 * If functions are stored use std::function (or function pointers).
48 *
49 * To register elements on file inclusion use this code in the header (note the missing static).
50 * \code{.cpp}
51 * Registrar<Type>::RegisterElement register("A", object);
52 * \endcode
53 * Example for strings
54 * \code{.cpp}
55 * Registrar<std::string>::RegisterElement register1("key 1", "value 1");
56 * Registrar<std::string>::RegisterElement register2("key 2", "value 2");
57 * \endcode
58 *
59 * \ingroup core-utility
60 */
61 template <class RegisteredType, class KeyType = std::string, class = void>
63 {
64 public:
65 using ContainerType = std::unordered_map<KeyType, RegisteredType>;
66
67 /**
68 * @brief Registers the object passed to the constructor.
69 * This can be used in combination with global variables to register types when a header is included.
70 */
72 {
73 RegisterElement(const KeyType& key, RegisteredType element)
74 {
75 registerElement(key, std::move(element));
76 }
77 };
78
79 /**
80 * @brief Returns the registered object for the given key.
81 * @param key The object's key.
82 * @return The registered object for the given key.
83 */
84 static const RegisteredType&
85 get(const KeyType& key)
86 {
87 std::lock_guard<std::recursive_mutex> guard{registeredElementsMutex()};
88 if (!has(key))
89 {
90 throw std::invalid_argument{"No factory for this key! "};
91 }
92 return registeredElements().at(key);
93 }
94
95 static bool
96 has(const KeyType& key)
97 {
98 std::lock_guard<std::recursive_mutex> guard{registeredElementsMutex()};
99 return registeredElements().end() != registeredElements().find(key);
100 }
101
102 /**
103 * @brief Registers an element.
104 * @param key The element's key.
105 * @param element The element.
106 */
107 static void
108 registerElement(const KeyType& key, RegisteredType element)
109 {
110 std::lock_guard<std::recursive_mutex> guard{registeredElementsMutex()};
111 registeredElements()[key] = std::move(element);
112 }
113
114 /**
115 * @brief Retrieves the list of all registered elements.
116 * @return The list of all registered elements.
117 */
118 static std::vector<KeyType>
120 {
121 std::lock_guard<std::recursive_mutex> guard{registeredElementsMutex()};
122 std::vector<KeyType> result;
123 result.reserve(registeredElements().size());
124 for (const auto& elem : registeredElements())
125 {
126 result.emplace_back(elem.first);
127 }
128 return result;
129 }
130
131 private:
132 /**
133 * @brief Holds the map of registered elements.
134 * @return The map of registered elements.
135 */
136 static ContainerType&
137 registeredElements()
138 {
139 static ContainerType elementContainer;
140 return elementContainer;
141 }
142
143 static std::recursive_mutex&
144 registeredElementsMutex()
145 {
146 static std::recursive_mutex elementContainerMutex;
147 return elementContainerMutex;
148 }
149 };
150} // namespace armarx
Stores key object pairs.
Definition Registrar.h:63
static bool has(const KeyType &key)
Definition Registrar.h:96
static const RegisteredType & get(const KeyType &key)
Returns the registered object for the given key.
Definition Registrar.h:85
static std::vector< KeyType > getKeys()
Retrieves the list of all registered elements.
Definition Registrar.h:119
std::unordered_map< std::string, ComponentCreatorObject > ContainerType
Definition Registrar.h:65
static void registerElement(const KeyType &key, RegisteredType element)
Registers an element.
Definition Registrar.h:108
This file offers overloads of toIce() and fromIce() functions for STL container types.
RegisterElement(const KeyType &key, RegisteredType element)
Definition Registrar.h:73