PODIO v00-16-03
An Event-Data-Model Toolkit for High Energy Physics Experiments
Loading...
Searching...
No Matches
GenericParameters.h
Go to the documentation of this file.
1// -*- C++ -*-
2#ifndef PODIO_GENERICPARAMETERS_H
3#define PODIO_GENERICPARAMETERS_H 1
4
6
7#include <algorithm>
8#include <iostream>
9#include <map>
10#include <memory>
11#include <mutex>
12#include <string>
13#include <vector>
14
15#define DEPRECATED_ACCESS [[deprecated("Use templated access functionality")]]
16
17namespace podio {
18
19/// The types which are supported in the GenericParameters
20using SupportedGenericDataTypes = std::tuple<int, float, std::string, double>;
21
22/// Static bool for determining if a type T is a supported GenericParamter type
23template <typename T>
24static constexpr bool isSupportedGenericDataType = detail::isAnyOrVectorOf<T, SupportedGenericDataTypes>;
25
26/// Alias template to be used for enabling / disabling template overloads that
27/// should only be present for actually supported data types
28template <typename T>
29using EnableIfValidGenericDataType = typename std::enable_if_t<isSupportedGenericDataType<T>>;
30
31namespace detail {
32 /// Helper struct to determine how to return different types from the
33 /// GenericParamters to avoid unnecessary copies but also to prohibit carrying
34 /// around const references to ints or floats
35 template <typename T>
37 using type = T;
38 };
39
40 /// Specialization for std::string. Those will always be returned by const ref
41 template <>
42 struct GenericDataReturnTypeHelper<std::string> {
43 using type = const std::string&;
44 };
45
46 /// Specialization for std::vector. Those will always be returned by const ref
47 template <typename T>
48 struct GenericDataReturnTypeHelper<std::vector<T>> {
49 using type = const std::vector<T>&;
50 };
51} // namespace detail
52
53/// Alias template for determining the appropriate return type for the passed in
54/// type
55template <typename T>
57
58// These should be trivial to remove once the deprecated non-templated access
59// functionality is actually removed
60typedef std::vector<int> IntVec;
61typedef std::vector<float> FloatVec;
62typedef std::vector<std::string> StringVec;
63
64/** GenericParameters objects allow to store generic named parameters of type
65 * int, float and string or vectors of these types.
66 * They can be used to store (user) meta data that is
67 * run, event or collection dependent.
68 * (based on lcio::LCParameters)
69 *
70 * @author F. Gaede, DESY
71 * @date Apr 2020
72 */
73
75public:
76 template <typename T>
77 using MapType = std::map<std::string, std::vector<T>>;
78
79private:
80 using IntMap = MapType<int>;
81 using FloatMap = MapType<float>;
82 using DoubleMap = MapType<double>;
83 using StringMap = MapType<std::string>;
84 // need mutex pointers for having the possibility to copy/move GenericParameters
85 using MutexPtr = std::unique_ptr<std::mutex>;
86
87public:
89
90 /// GenericParameters are copyable
91 /// NOTE: This is currently mainly done to keep the ROOT I/O happy, because
92 /// that needs a copy constructor
95
96 /// GenericParameters are default moveable
99
101
102 /// Get the value that is stored under the given key, by const reference or by
103 /// value depending on the desired type
104 template <typename T, typename = EnableIfValidGenericDataType<T>>
105 GenericDataReturnType<T> getValue(const std::string&) const;
106
107 /// Store (a copy of) the passed value under the given key
108 template <typename T, typename = EnableIfValidGenericDataType<T>>
109 void setValue(const std::string& key, T value);
110
111 /// Overload for catching const char* setting for string values
112 void setValue(const std::string& key, std::string value) {
113 setValue<std::string>(key, std::move(value));
114 }
115
116 /// Overlaod for catching initializer list setting of string vector values
117 void setValue(const std::string& key, std::vector<std::string> values) {
118 setValue<std::vector<std::string>>(key, std::move(values));
119 }
120
121 /// Overload for catching initializer list setting for vector values
122 template <typename T, typename = std::enable_if_t<detail::isInTuple<T, SupportedGenericDataTypes>>>
123 void setValue(const std::string& key, std::initializer_list<T>&& values) {
124 setValue<std::vector<T>>(key, std::move(values));
125 }
126
127 /// Get the number of elements stored under the given key for a type
128 template <typename T, typename = EnableIfValidGenericDataType<T>>
129 size_t getN(const std::string& key) const;
130
131 /// Get all available keys for a given type
132 template <typename T, typename = EnableIfValidGenericDataType<T>>
133 std::vector<std::string> getKeys() const;
134
135 /** Returns the first integer value for the given key.
136 */
137 DEPRECATED_ACCESS int getIntVal(const std::string& key) const;
138
139 /** Returns the first float value for the given key.
140 */
141 DEPRECATED_ACCESS float getFloatVal(const std::string& key) const;
142
143 /** Returns the first string value for the given key.
144 */
145 DEPRECATED_ACCESS const std::string& getStringVal(const std::string& key) const;
146
147 /** Adds all integer values for the given key to values.
148 * Returns a reference to values for convenience.
149 */
150 DEPRECATED_ACCESS IntVec& getIntVals(const std::string& key, IntVec& values) const;
151
152 /** Adds all float values for the given key to values.
153 * Returns a reference to values for convenience.
154 */
155 DEPRECATED_ACCESS FloatVec& getFloatVals(const std::string& key, FloatVec& values) const;
156
157 /** Adds all float values for the given key to values.
158 * Returns a reference to values for convenience.
159 */
160 DEPRECATED_ACCESS StringVec& getStringVals(const std::string& key, StringVec& values) const;
161
162 /** Returns a list of all keys of integer parameters.
163 */
165
166 /** Returns a list of all keys of float parameters.
167 */
169
170 /** Returns a list of all keys of string parameters.
171 */
173
174 /** The number of integer values stored for this key.
175 */
176 DEPRECATED_ACCESS int getNInt(const std::string& key) const;
177
178 /** The number of float values stored for this key.
179 */
180 DEPRECATED_ACCESS int getNFloat(const std::string& key) const;
181
182 /** The number of string values stored for this key.
183 */
184 DEPRECATED_ACCESS int getNString(const std::string& key) const;
185
186 /** Set integer values for the given key.
187 */
188 DEPRECATED_ACCESS void setValues(const std::string& key, const IntVec& values);
189
190 /** Set float values for the given key.
191 */
192 DEPRECATED_ACCESS void setValues(const std::string& key, const FloatVec& values);
193
194 /** Set string values for the given key.
195 */
196 DEPRECATED_ACCESS void setValues(const std::string& key, const StringVec& values);
197
198 /// erase all elements
199 void clear() {
200 _intMap.clear();
201 _floatMap.clear();
202 _stringMap.clear();
203 }
204
205 void print(std::ostream& os = std::cout, bool flush = true);
206
207 /// Check if no parameter is stored (i.e. if all internal maps are empty)
208 bool empty() const {
209 return _intMap.empty() && _floatMap.empty() && _stringMap.empty();
210 }
211
212 /**
213 * Get the internal int map (necessary for serialization with SIO)
214 */
215 const IntMap& getIntMap() const {
216 return getMap<int>();
217 }
218 IntMap& getIntMap() {
219 return getMap<int>();
220 }
221
222 /**
223 * Get the internal float map (necessary for serialization with SIO)
224 */
225 const FloatMap& getFloatMap() const {
226 return getMap<float>();
227 }
228 FloatMap& getFloatMap() {
229 return getMap<float>();
230 }
231
232 /**
233 * Get the internal double map (necessary for serialization with SIO)
234 */
235 const DoubleMap& getDoubleMap() const {
236 return getMap<double>();
237 }
238 DoubleMap& getDoubleMap() {
239 return getMap<double>();
240 }
241
242 /**
243 * Get the internal string map (necessary for serialization with SIO)
244 */
245 const StringMap& getStringMap() const {
246 return getMap<std::string>();
247 }
248 StringMap& getStringMap() {
249 return getMap<std::string>();
250 }
251
252private:
253 /// Get a reference to the internal map for a given type (necessary for SIO)
254 template <typename T>
255 const MapType<detail::GetVectorType<T>>& getMap() const {
256 if constexpr (std::is_same_v<detail::GetVectorType<T>, int>) {
257 return _intMap;
258 } else if constexpr (std::is_same_v<detail::GetVectorType<T>, float>) {
259 return _floatMap;
260 } else if constexpr (std::is_same_v<detail::GetVectorType<T>, double>) {
261 return _doubleMap;
262 } else {
263 return _stringMap;
264 }
265 }
266
267 /// Get a reference to the internal map for a given type (necessary for SIO)
268 template <typename T>
269 MapType<detail::GetVectorType<T>>& getMap() {
270 if constexpr (std::is_same_v<detail::GetVectorType<T>, int>) {
271 return _intMap;
272 } else if constexpr (std::is_same_v<detail::GetVectorType<T>, float>) {
273 return _floatMap;
274 } else if constexpr (std::is_same_v<detail::GetVectorType<T>, double>) {
275 return _doubleMap;
276 } else {
277 return _stringMap;
278 }
279 }
280
281 /// Get the mutex that guards the map for the given type
282 template <typename T>
283 std::mutex& getMutex() const {
284 if constexpr (std::is_same_v<detail::GetVectorType<T>, int>) {
285 return *(m_intMtx.get());
286 } else if constexpr (std::is_same_v<detail::GetVectorType<T>, float>) {
287 return *(m_floatMtx.get());
288 } else if constexpr (std::is_same_v<detail::GetVectorType<T>, double>) {
289 return *(m_doubleMtx.get());
290 } else {
291 return *(m_stringMtx.get());
292 }
293 }
294
295private:
296 IntMap _intMap{}; ///< The map storing the integer values
297 mutable MutexPtr m_intMtx{nullptr}; ///< The mutex guarding the integer map
298 FloatMap _floatMap{}; ///< The map storing the float values
299 mutable MutexPtr m_floatMtx{nullptr}; ///< The mutex guarding the float map
300 StringMap _stringMap{}; ///< The map storing the string values
301 mutable MutexPtr m_stringMtx{nullptr}; ///< The mutex guarding the string map
302 DoubleMap _doubleMap{}; ///< The map storing the double values
303 mutable MutexPtr m_doubleMtx{nullptr}; ///< The mutex guarding the double map
304};
305
306template <typename T, typename>
308 const auto& map = getMap<T>();
309 auto& mtx = getMutex<T>();
310 std::lock_guard lock{mtx};
311 const auto it = map.find(key);
312 // If there is no entry to the key, we just return an empty default
313 // TODO: make this case detectable from the outside
314 if (it == map.end()) {
315 static const auto empty = T{};
316 return empty;
317 }
318
319 // We have to check whether the return type is a vector or a single value
320 if constexpr (detail::isVector<T>) {
321 return it->second;
322 } else {
323 const auto& iv = it->second;
324 return iv[0];
325 }
326}
327
328template <typename T, typename>
329void GenericParameters::setValue(const std::string& key, T value) {
330 auto& map = getMap<T>();
331 auto& mtx = getMutex<T>();
332
333 if constexpr (detail::isVector<T>) {
334 std::lock_guard lock{mtx};
335 map.insert_or_assign(key, std::move(value));
336 } else {
337 // Wrap the value into a vector with exactly one entry and store that
338 std::vector<T> v = {value};
339 std::lock_guard lock{mtx};
340 map.insert_or_assign(key, std::move(v));
341 }
342}
343
344template <typename T, typename>
345size_t GenericParameters::getN(const std::string& key) const {
346 const auto& map = getMap<T>();
347 auto& mtx = getMutex<T>();
348 std::lock_guard lock{mtx};
349 if (const auto it = map.find(key); it != map.end()) {
350 return it->second.size();
351 }
352 return 0;
353}
354
355template <typename T, typename>
356std::vector<std::string> GenericParameters::getKeys() const {
357 std::vector<std::string> keys;
358 const auto& map = getMap<T>();
359 keys.reserve(map.size());
360 {
361 auto& mtx = getMutex<T>();
362 std::lock_guard lock{mtx};
363 std::transform(map.begin(), map.end(), std::back_inserter(keys), [](const auto& pair) { return pair.first; });
364 }
365
366 return keys;
367}
368
369} // namespace podio
370#endif
#define DEPRECATED_ACCESS
DEPRECATED_ACCESS int getIntVal(const std::string &key) const
GenericParameters(GenericParameters &&)=default
GenericParameters are default moveable.
DEPRECATED_ACCESS IntVec & getIntVals(const std::string &key, IntVec &values) const
GenericDataReturnType< T > getValue(const std::string &) const
DEPRECATED_ACCESS int getNString(const std::string &key) const
void setValue(const std::string &key, std::initializer_list< T > &&values)
Overload for catching initializer list setting for vector values.
std::vector< std::string > getKeys() const
Get all available keys for a given type.
void setValue(const std::string &key, std::vector< std::string > values)
Overlaod for catching initializer list setting of string vector values.
void setValue(const std::string &key, std::string value)
Overload for catching const char* setting for string values.
bool empty() const
Check if no parameter is stored (i.e. if all internal maps are empty)
void setValue(const std::string &key, T value)
Store (a copy of) the passed value under the given key.
DEPRECATED_ACCESS void setValues(const std::string &key, const IntVec &values)
GenericParameters & operator=(const GenericParameters &)=delete
DEPRECATED_ACCESS FloatVec & getFloatVals(const std::string &key, FloatVec &values) const
DEPRECATED_ACCESS const std::string & getStringVal(const std::string &key) const
const StringMap & getStringMap() const
void clear()
erase all elements
DEPRECATED_ACCESS int getNFloat(const std::string &key) const
DEPRECATED_ACCESS int getNInt(const std::string &key) const
const IntMap & getIntMap() const
std::map< std::string, std::vector< T > > MapType
DEPRECATED_ACCESS StringVec & getStringVals(const std::string &key, StringVec &values) const
const FloatMap & getFloatMap() const
DEPRECATED_ACCESS float getFloatVal(const std::string &key) const
void print(std::ostream &os=std::cout, bool flush=true)
GenericParameters & operator=(GenericParameters &&)=default
size_t getN(const std::string &key) const
Get the number of elements stored under the given key for a type.
const DoubleMap & getDoubleMap() const
DEPRECATED_ACCESS const StringVec & getIntKeys(StringVec &keys) const
DEPRECATED_ACCESS const StringVec & getFloatKeys(StringVec &keys) const
DEPRECATED_ACCESS const StringVec & getStringKeys(StringVec &keys) const
std::vector< float > FloatVec
std::vector< int > IntVec
typename detail::GenericDataReturnTypeHelper< T >::type GenericDataReturnType
std::tuple< int, float, std::string, double > SupportedGenericDataTypes
The types which are supported in the GenericParameters.
std::vector< std::string > StringVec
typename std::enable_if_t< isSupportedGenericDataType< T > > EnableIfValidGenericDataType