Project
Loading...
Searching...
No Matches
Variant.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef FRAMEWORK_VARIANT_H
12#define FRAMEWORK_VARIANT_H
13
15#include "Framework/Array2D.h"
16#include <type_traits>
17#include <cstring>
18#include <cstdint>
19#include <cstdlib>
20#include <iosfwd>
21#include <initializer_list>
22#include <string_view>
23#include <vector>
24#include <string>
25
26namespace o2::framework
27{
28
29// Do NOT insert entries in this enum, only append at the end (before "Empty"). Hyperloop depends on the order.
30enum class VariantType : int { Int = 0,
31 Int64,
32 Float,
33 Double,
34 String,
35 Bool,
44 LabeledArrayInt, // 2D array
45 LabeledArrayFloat, // 2D array
46 LabeledArrayDouble, // 2D array
47 UInt8,
48 UInt16,
49 UInt32,
50 UInt64,
51 Int8,
52 Int16,
53 LabeledArrayString, // 2D array
54 Empty,
55 Dict,
56 Unknown };
57
58template <VariantType V>
59constexpr auto isArray()
60{
61 return (V == VariantType::ArrayBool ||
66}
67
68template <VariantType V>
69constexpr auto isArray2D()
70{
71 return (V == VariantType::Array2DInt ||
74}
75
76template <VariantType V>
77constexpr auto isLabeledArrayString()
78{
80}
81
82template <VariantType V>
90
91template <VariantType V>
92constexpr auto isSimpleVariant()
93{
94 return (V == VariantType::Int) ||
95 (V == VariantType::Int8) ||
96 (V == VariantType::Int16) ||
97 (V == VariantType::Int64) ||
98 (V == VariantType::UInt8) ||
99 (V == VariantType::UInt16) ||
100 (V == VariantType::UInt32) ||
101 (V == VariantType::UInt64) ||
102 (V == VariantType::Float) ||
103 (V == VariantType::Double) ||
104 (V == VariantType::Bool);
105}
106
107template <typename T>
108struct variant_trait : std::integral_constant<VariantType, VariantType::Unknown> {
109};
110
111#define DECLARE_VARIANT_TRAIT(_Type1_, _Type2_) \
112 template <> \
113 struct variant_trait<_Type1_> : std::integral_constant<VariantType, VariantType::_Type2_> { \
114 };
115
124DECLARE_VARIANT_TRAIT(unsigned long int, UInt64);
125DECLARE_VARIANT_TRAIT(unsigned long long int, UInt64);
126
130
133DECLARE_VARIANT_TRAIT(char* const, String);
134DECLARE_VARIANT_TRAIT(const char* const, String);
135DECLARE_VARIANT_TRAIT(std::string_view, String);
137
143
146DECLARE_VARIANT_TRAIT(std::vector<double>, ArrayDouble);
148DECLARE_VARIANT_TRAIT(std::vector<std::string>, ArrayString);
149
153
158
159template <typename T>
161 constexpr static char symbol = 'u';
162};
163
164template <>
166 constexpr static char symbol = 'i';
167};
168
169template <>
170struct variant_array_symbol<float> {
171 constexpr static char symbol = 'f';
172};
173
174template <>
175struct variant_array_symbol<double> {
176 constexpr static char symbol = 'd';
177};
178
179template <>
181 constexpr static char symbol = 'b';
182};
183
184template <>
186 constexpr static char symbol = 's';
187};
188
189template <typename T>
191
192template <VariantType type>
194};
195
196#define DECLARE_VARIANT_TYPE(_Type1_, _Type2_) \
197 template <> \
198 struct variant_type<VariantType::_Type2_> { \
199 using type = _Type1_; \
200 };
201
214
220
224
229
230template <VariantType type>
233
234#define DECLARE_VARIANT_ARRAY_ELEMENT_TYPE(_Type1_, _Type2_) \
235 template <> \
236 struct variant_array_element_type<VariantType::_Type2_> { \
237 using type = _Type1_; \
238 };
239
248
253
254template <VariantType V>
256
257template <typename T>
259 static void set(void* store, T value)
260 {
261 new (reinterpret_cast<T*>(store)) T{};
262 *(reinterpret_cast<T*>(store)) = value;
263 }
264 static void set(void* store, T values, size_t size)
265 {
266 *reinterpret_cast<T*>(store) = reinterpret_cast<T>(std::memcpy(std::malloc(size * sizeof(std::remove_pointer_t<T>)), reinterpret_cast<void*>(values), size * sizeof(std::remove_pointer_t<T>)));
267 }
268
269 static T get(const void* store) { return *(reinterpret_cast<const T*>(store)); }
270};
271
272template <>
273struct variant_helper<std::vector<std::string>> {
274 // Allocates a new store and copies into it.
275 static void set(void* store, std::vector<std::string> value)
276 {
277 new (reinterpret_cast<std::vector<std::string>*>(store)) std::vector<std::string>{};
278 *(reinterpret_cast<std::vector<std::string>*>(store)) = value;
279 }
280
281 static std::vector<std::string> const& get(const void* store) { return *(reinterpret_cast<std::vector<std::string> const*>(store)); }
282};
283
284template <>
285struct variant_helper<const char*> {
286 static const char* get(const void* store) { return *reinterpret_cast<const char* const*>(store); }
287
288 static void set(void* store, const char* value) { *reinterpret_cast<char**>(store) = strdup(value); }
289};
290
291template <>
292struct variant_helper<std::string_view> {
293 static std::string_view get(const void* store) { return std::string_view(*reinterpret_cast<const char* const*>(store)); }
294
295 static void set(void* store, std::string_view value) { *reinterpret_cast<char**>(store) = strdup(value.data()); }
296};
297
298template <>
300 static std::string get(const void* store) { return std::string(*reinterpret_cast<const char* const*>(store)); }
301
302 static void set(void* store, std::string value) { *reinterpret_cast<char**>(store) = strdup(value.data()); }
303};
304
307{
308 public:
310
311 template <typename T>
313 {
314 variant_helper<decltype(value)>::set(&mStore, value);
315 }
316
317 template <typename T>
318 Variant(T values, size_t size) : mType{variant_trait_v<T>}, mSize{size}
319 {
320 variant_helper<T>::set(&mStore, values, mSize);
321 }
322
323 template <typename T>
324 Variant(std::vector<T>& values) : mType{variant_trait_v<T*>}, mSize{values.size()}
325 {
326 variant_helper<T*>::set(&mStore, values.data(), mSize);
327 }
328
329 Variant(std::vector<std::string>& values) : mType{VariantType::ArrayString}, mSize{values.size()}
330 {
332 }
333
334 template <typename T>
335 Variant(std::initializer_list<T>)
336 {
337 static_assert(sizeof(T) == 0,
338 "brace-enclosed initializer list forbidden for Variant"
339 "\n did you accidentally put braces around the default value?");
340 }
341
342 Variant(const Variant& other);
343 Variant(Variant&& other) noexcept;
344 ~Variant();
346 Variant& operator=(Variant&& other) noexcept;
347 template <typename T>
348 Variant& operator=(std::vector<T>&& other) noexcept
349 {
350 *this = Variant(other);
351 return *this;
352 }
353
354 template <typename T>
355 T get() const
356 {
357 if (mType != variant_trait_v<T>) {
358 throw runtime_error_f("Variant::get: Mismatch between types %d %d.", mType, variant_trait_v<T>);
359 }
360 return variant_helper<T>::get(&mStore);
361 }
362
363 template <typename T>
364 void set(T value)
365 {
366 return variant_helper<T>::set(&mStore, value);
367 }
368
369 template <typename T>
370 void set(T value, size_t size)
371 {
372 mSize = size;
373 return variant_helper<T>::set(&mStore, value, mSize);
374 }
375
376 template <typename T>
377 void set(std::vector<T>& values)
378 requires(std::is_pod_v<T>)
379 {
380 return variant_helper<T*>::set(&mStore, values.data(), values.size());
381 }
382
383 template <typename T>
384 void set(std::vector<T>& values)
385 requires(std::is_same_v<T, std::string>)
386 {
387 return variant_helper<T*>::set(&mStore, values);
388 }
389
390 [[nodiscard]] VariantType type() const { return mType; }
391 [[nodiscard]] size_t size() const { return mSize; }
392 [[nodiscard]] std::string asString() const;
393
394 private:
395 friend std::ostream& operator<<(std::ostream& oss, Variant const& val);
396 using storage_t = std::aligned_union<8, int, int8_t, int16_t, int64_t,
397 uint8_t, uint16_t, uint32_t, uint64_t,
398 const char*, float, double, bool,
399 int*, float*, double*, bool*, std::string*,
402 storage_t mStore;
404 size_t mSize = 1;
405};
406
408
409} // namespace o2::framework
410
411#endif
#define DECLARE_VARIANT_TYPE(_Type1_, _Type2_)
Definition Variant.h:196
#define DECLARE_VARIANT_TRAIT(_Type1_, _Type2_)
Definition Variant.h:111
#define DECLARE_VARIANT_ARRAY_ELEMENT_TYPE(_Type1_, _Type2_)
Definition Variant.h:234
Variant for configuration parameter storage. Owns stored data.
Definition Variant.h:307
Variant(std::vector< std::string > &values)
Definition Variant.h:329
Variant(std::vector< T > &values)
Definition Variant.h:324
Variant(T values, size_t size)
Definition Variant.h:318
std::string asString() const
Definition Variant.cxx:80
Variant & operator=(std::vector< T > &&other) noexcept
Definition Variant.h:348
void set(T value)
Definition Variant.h:364
Variant & operator=(const Variant &other)
Definition Variant.cxx:169
friend std::ostream & operator<<(std::ostream &oss, Variant const &val)
Definition Variant.cxx:19
void set(std::vector< T > &values)
Definition Variant.h:384
void set(T value, size_t size)
Definition Variant.h:370
Variant(std::initializer_list< T >)
Definition Variant.h:335
size_t size() const
Definition Variant.h:391
void set(std::vector< T > &values)
Definition Variant.h:377
Variant(VariantType type=VariantType::Unknown)
Definition Variant.h:309
VariantType type() const
Definition Variant.h:390
GLsizei const GLchar *const * string
Definition glcorearb.h:809
GLsizeiptr size
Definition glcorearb.h:659
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLenum GLsizei GLsizei GLint * values
Definition glcorearb.h:1576
GLuint GLfloat * val
Definition glcorearb.h:1582
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
constexpr auto isArray()
Definition Variant.h:59
constexpr auto isSimpleVariant()
Definition Variant.h:92
constexpr auto isLabeledArrayString()
Definition Variant.h:77
constexpr auto isLabeledArray()
Definition Variant.h:83
constexpr auto isArray2D()
Definition Variant.h:69
typename variant_array_element_type< V >::type variant_array_element_type_t
Definition Variant.h:255
constexpr VariantType variant_trait_v
Definition Variant.h:190
RuntimeErrorRef runtime_error_f(const char *,...)
Variant emptyDict()
Definition Variant.h:407
Defining DataPointCompositeObject explicitly as copiable.
static constexpr char symbol
Definition Variant.h:161
static const char * get(const void *store)
Definition Variant.h:286
static void set(void *store, const char *value)
Definition Variant.h:288
static void set(void *store, std::string value)
Definition Variant.h:302
static std::string get(const void *store)
Definition Variant.h:300
static void set(void *store, std::string_view value)
Definition Variant.h:295
static std::string_view get(const void *store)
Definition Variant.h:293
static std::vector< std::string > const & get(const void *store)
Definition Variant.h:281
static void set(void *store, std::vector< std::string > value)
Definition Variant.h:275
static T get(const void *store)
Definition Variant.h:269
static void set(void *store, T values, size_t size)
Definition Variant.h:264
static void set(void *store, T value)
Definition Variant.h:259
VectorOfTObjectPtrs other