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 auto ptr = reinterpret_cast<std::vector<std::string>*>(store);
278 new (ptr) std::vector<std::string>{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 <>
286 static void set(void* store, std::string* values, size_t size)
287 {
288 auto ptr = reinterpret_cast<std::vector<std::string>*>(store);
289 new (ptr) std::vector<std::string>{values, values + size};
290 }
291
292 static std::string const* get(const void* store) { return (*(reinterpret_cast<std::vector<std::string> const*>(store))).data(); }
293};
294
295template <>
296struct variant_helper<const char*> {
297 static const char* get(const void* store) { return *reinterpret_cast<const char* const*>(store); }
298
299 static void set(void* store, const char* value) { *reinterpret_cast<char**>(store) = strdup(value); }
300};
301
302template <>
303struct variant_helper<std::string_view> {
304 static std::string_view get(const void* store) { return std::string_view(*reinterpret_cast<const char* const*>(store)); }
305
306 static void set(void* store, std::string_view value) { *reinterpret_cast<char**>(store) = strdup(value.data()); }
307};
308
309template <>
311 static std::string get(const void* store) { return std::string(*reinterpret_cast<const char* const*>(store)); }
312
313 static void set(void* store, std::string value) { *reinterpret_cast<char**>(store) = strdup(value.data()); }
314};
315
318{
319 public:
321
322 template <typename T>
324 {
325 variant_helper<decltype(value)>::set(&mStore, value);
326 }
327
328 template <typename T>
329 Variant(T values, size_t size) : mType{variant_trait_v<T>}, mSize{size}
330 {
331 variant_helper<T>::set(&mStore, values, mSize);
332 }
333
334 template <typename T>
335 Variant(std::vector<T>& values) : mType{variant_trait_v<T*>}, mSize{values.size()}
336 {
337 variant_helper<T*>::set(&mStore, values.data(), mSize);
338 }
339
340 Variant(std::vector<std::string>& values) : mType{VariantType::ArrayString}, mSize{values.size()}
341 {
343 }
344
345 template <typename T>
346 Variant(std::initializer_list<T>)
347 {
348 static_assert(sizeof(T) == 0,
349 "brace-enclosed initializer list forbidden for Variant"
350 "\n did you accidentally put braces around the default value?");
351 }
352
353 Variant(const Variant& other);
354 Variant(Variant&& other) noexcept;
355 ~Variant();
357 Variant& operator=(Variant&& other) noexcept;
358 template <typename T>
359 Variant& operator=(std::vector<T>&& other) noexcept
360 {
361 *this = Variant(other);
362 return *this;
363 }
364
365 template <typename T>
366 T get() const
367 {
368 if (mType != variant_trait_v<T>) {
369 throw runtime_error_f("Variant::get: Mismatch between types %d %d.", mType, variant_trait_v<T>);
370 }
371 return variant_helper<T>::get(&mStore);
372 }
373
374 template <typename T>
375 [[nodiscard]] std::string const* get() const
376 requires(std::same_as<std::string*, T>)
377 {
378 if (mType != VariantType::ArrayString) {
379 throw runtime_error_f("Variant::get: Mismatch between types %d %d.", mType, VariantType::ArrayString);
380 }
381 return variant_helper<T>::get(&mStore);
382 }
383
384 template <typename T>
385 void set(T value)
386 {
387 return variant_helper<T>::set(&mStore, value);
388 }
389
390 template <typename T>
391 void set(T value, size_t size)
392 {
393 mSize = size;
394 return variant_helper<T>::set(&mStore, value, mSize);
395 }
396
397 template <typename T>
398 void set(std::vector<T>& values)
399 requires(std::is_pod_v<T>)
400 {
401 return variant_helper<T*>::set(&mStore, values.data(), values.size());
402 }
403
404 template <typename T>
405 void set(std::vector<T>& values)
406 requires(std::is_same_v<T, std::string>)
407 {
408 return variant_helper<T*>::set(&mStore, values);
409 }
410
411 [[nodiscard]] VariantType type() const { return mType; }
412 [[nodiscard]] size_t size() const { return mSize; }
413 [[nodiscard]] std::string asString() const;
414
415 private:
416 friend std::ostream& operator<<(std::ostream& oss, Variant const& val);
417 using storage_t = std::aligned_union<8, int, int8_t, int16_t, int64_t,
418 uint8_t, uint16_t, uint32_t, uint64_t,
419 const char*, float, double, bool,
420 int*, float*, double*, bool*, std::string*,
423 storage_t mStore;
425 size_t mSize = 1;
426};
427
429
430} // namespace o2::framework
431
432#endif
TBranch * ptr
#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:318
Variant(std::vector< std::string > &values)
Definition Variant.h:340
Variant(std::vector< T > &values)
Definition Variant.h:335
Variant(T values, size_t size)
Definition Variant.h:329
std::string asString() const
Definition Variant.cxx:80
Variant & operator=(std::vector< T > &&other) noexcept
Definition Variant.h:359
void set(T value)
Definition Variant.h:385
Variant & operator=(const Variant &other)
Definition Variant.cxx:164
friend std::ostream & operator<<(std::ostream &oss, Variant const &val)
Definition Variant.cxx:19
void set(std::vector< T > &values)
Definition Variant.h:405
void set(T value, size_t size)
Definition Variant.h:391
Variant(std::initializer_list< T >)
Definition Variant.h:346
size_t size() const
Definition Variant.h:412
void set(std::vector< T > &values)
Definition Variant.h:398
Variant(VariantType type=VariantType::Unknown)
Definition Variant.h:320
VariantType type() const
Definition Variant.h:411
std::string const * get() const
Definition Variant.h:375
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.
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:428
Defining DataPointCompositeObject explicitly as copiable.
static constexpr char symbol
Definition Variant.h:161
static const char * get(const void *store)
Definition Variant.h:297
static void set(void *store, const char *value)
Definition Variant.h:299
static void set(void *store, std::string value)
Definition Variant.h:313
static std::string get(const void *store)
Definition Variant.h:311
static std::string const * get(const void *store)
Definition Variant.h:292
static void set(void *store, std::string *values, size_t size)
Definition Variant.h:286
static void set(void *store, std::string_view value)
Definition Variant.h:306
static std::string_view get(const void *store)
Definition Variant.h:304
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