Project
Loading...
Searching...
No Matches
Variant.cxx
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#include "Framework/Variant.h"
14#include <cstdlib>
15#include <cstring>
16#include <iostream>
17#include <memory>
18#include <sstream>
19
20namespace o2::framework
21{
22std::ostream& operator<<(std::ostream& oss, Variant const& val)
23{
24 switch (val.type()) {
26 oss << val.get<int>();
27 break;
29 oss << (int)val.get<int8_t>();
30 break;
32 oss << (int)val.get<int16_t>();
33 break;
35 oss << (int)val.get<uint8_t>();
36 break;
38 oss << (int)val.get<uint16_t>();
39 break;
41 oss << val.get<uint32_t>();
42 break;
44 oss << val.get<uint64_t>();
45 break;
47 oss << val.get<int64_t>();
48 break;
50 oss << val.get<float>();
51 break;
53 oss << val.get<double>();
54 break;
56 oss << val.get<const char*>();
57 break;
59 oss << val.get<bool>();
60 break;
74 break;
76 break;
78 oss << "{}";
79 break;
80 default:
81 oss << "undefined";
82 break;
83 };
84 return oss;
85}
86
87std::string Variant::asString() const
88{
89 std::stringstream ss;
90 ss << *this;
91 return ss.str();
92}
93
94namespace
95{
97template <typename F>
98bool visitStoredObject(VariantType type, F&& f)
99{
100 switch (type) {
102 f.template operator()<std::vector<std::string>>();
103 return true;
105 f.template operator()<Array2D<int>>();
106 return true;
108 f.template operator()<Array2D<float>>();
109 return true;
111 f.template operator()<Array2D<double>>();
112 return true;
114 f.template operator()<LabeledArray<int>>();
115 return true;
117 f.template operator()<LabeledArray<float>>();
118 return true;
120 f.template operator()<LabeledArray<double>>();
121 return true;
123 f.template operator()<LabeledArray<std::string>>();
124 return true;
125 default:
126 return false;
127 }
128}
129
131bool holdsMallocedPointer(VariantType type)
132{
133 switch (type) {
139 return true;
140 default:
141 return false;
142 }
143}
144
145template <typename T>
146T* copyBuffer(T const* values, size_t size)
147{
148 if (values == nullptr) {
149 return nullptr;
150 }
151 return reinterpret_cast<T*>(std::memcpy(std::malloc(size * sizeof(T)), values, size * sizeof(T)));
152}
153} // namespace
154
156{
157 // Make sure that destroying a Variant created without a value is always safe
158 // by creating a default stored object upfront
159 if (!visitStoredObject(mType, [this]<typename T>() { new (&mStore) T{}; })) {
160 std::memset(&mStore, 0, sizeof(mStore));
161 switch (type) {
167 mSize = 0; // empty plain array has size 0
168 break;
169 default:
170 break;
171 }
172 }
173}
174
175void Variant::copyStore(Variant const& other)
176{
177 // Proper objects are simply copied
178 if (visitStoredObject(mType, [this, &other]<typename T>() { new (&mStore) T(*reinterpret_cast<T const*>(&other.mStore)); })) {
179 return;
180 }
181 // Manually allocated buffers have to be managed
182 switch (mType) {
183 case VariantType::String: {
184 auto const* value = *reinterpret_cast<char const* const*>(&other.mStore);
185 *reinterpret_cast<char**>(&mStore) = value != nullptr ? strdup(value) : nullptr;
186 return;
187 }
189 *reinterpret_cast<int**>(&mStore) = copyBuffer(*reinterpret_cast<int* const*>(&other.mStore), mSize);
190 return;
192 *reinterpret_cast<float**>(&mStore) = copyBuffer(*reinterpret_cast<float* const*>(&other.mStore), mSize);
193 return;
195 *reinterpret_cast<double**>(&mStore) = copyBuffer(*reinterpret_cast<double* const*>(&other.mStore), mSize);
196 return;
198 *reinterpret_cast<bool**>(&mStore) = copyBuffer(*reinterpret_cast<bool* const*>(&other.mStore), mSize);
199 return;
200 default:
201 // Trivially copyable content
202 mStore = other.mStore;
203 }
204}
205
206void Variant::moveStore(Variant& other) noexcept
207{
208 // Correct move for objects, leaving proper "moved from" state
209 if (visitStoredObject(mType, [this, &other]<typename T>() { new (&mStore) T(std::move(*reinterpret_cast<T*>(&other.mStore))); })) {
210 return;
211 }
212 mStore = other.mStore;
213 // Buffers have to change their owner
214 if (holdsMallocedPointer(mType)) {
215 *reinterpret_cast<void**>(&other.mStore) = nullptr;
216 }
217}
218
219void Variant::destroyStore() noexcept
220{
221 // destroy objects
222 if (visitStoredObject(mType, [this]<typename T>() { std::destroy_at(reinterpret_cast<T*>(&mStore)); })) {
223 return;
224 }
225 // deallocate buffers
226 if (holdsMallocedPointer(mType)) {
227 free(*reinterpret_cast<void**>(&mStore));
228 }
229}
230
231Variant::Variant(const Variant& other) : mType(other.mType), mSize(other.mSize)
232{
233 copyStore(other);
234}
235
236Variant::Variant(Variant&& other) noexcept : mType(other.mType), mSize(other.mSize)
237{
238 moveStore(other);
239}
240
242{
243 destroyStore();
244}
245
247{
248 if (this != &other) {
249 // Copy first, so that a throwing copy leaves this Variant untouched
250 Variant copy(other);
251 *this = std::move(copy);
252 }
253 return *this;
254}
255
257{
258 if (this != &other) {
259 destroyStore();
260 mType = other.mType;
261 mSize = other.mSize;
262 moveStore(other);
263 }
264 return *this;
265}
266
267std::pair<std::vector<std::string>, std::vector<std::string>> extractLabels(boost::property_tree::ptree const& tree)
268{
269 std::vector<std::string> labels_rows;
270 std::vector<std::string> labels_cols;
271 auto lrc = tree.get_child_optional(labels_rows_str);
272 if (lrc) {
273 labels_rows = basicVectorFromBranch<std::string>(lrc.value());
274 }
275 auto lcc = tree.get_child_optional(labels_cols_str);
276 if (lcc) {
277 labels_cols = basicVectorFromBranch<std::string>(lcc.value());
278 }
279 return std::make_pair(labels_rows, labels_cols);
280}
281
282} // namespace o2::framework
unsigned short int uint16_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
std::vector< std::string > labels_rows
std::vector< std::string > labels_cols
Variant for configuration parameter storage. Owns stored data.
Definition Variant.h:319
std::string asString() const
Definition Variant.cxx:87
Variant & operator=(const Variant &other)
Definition Variant.cxx:246
Variant(VariantType type=VariantType::Unknown)
Definition Variant.cxx:155
GLsizeiptr size
Definition glcorearb.h:659
GLdouble f
Definition glcorearb.h:310
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 ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::ostream & operator<<(std::ostream &s, ChannelType const &type)
Stream operators so that we can use ChannelType with Boost.Test.
std::pair< std::vector< std::string >, std::vector< std::string > > extractLabels(boost::property_tree::ptree const &tree)
Definition Variant.cxx:267
size_t copyBuffer(const std::vector< uint64_t > &b64, std::vector< std::byte > &b8, uint64_t prefix=0)
Definition MoveBuffer.h:24
static void write(std::ostream &o, Variant const &v)
VectorOfTObjectPtrs other
void free(void *p)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))