DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
serialization
include
serialization
serialize_variant.hpp
Go to the documentation of this file.
1
13
14
#ifndef SERIALIZATION_INCLUDE_SERIALIZATION_SERIALIZE_VARIANT_HPP_
15
#define SERIALIZATION_INCLUDE_SERIALIZATION_SERIALIZE_VARIANT_HPP_
16
17
#include "msgpack.hpp"
18
19
#include <iostream>
20
#include <utility>
21
#include <variant>
22
23
// NOLINTNEXTLINE
24
namespace
msgpack
{
25
MSGPACK_API_VERSION_NAMESPACE
(MSGPACK_DEFAULT_API_NS)
26
{
27
namespace
adaptor {
28
29
template
<
typename
... Args>
30
struct
pack<
std
::variant<Args...>>
31
{
32
template
<
typename
Stream>
33
packer<Stream>& operator()(msgpack::packer<Stream>& o, std::variant<Args...>
const
& v)
const
34
{
35
// There are always exactly 2 items in the msgpack array: the
36
// index indicating which type the variant is holding, and the
37
// instance of the type itself (it *doesn't* depend sizeof...(Args))
38
o.pack_array(2);
39
o.pack(v.index());
40
std::visit([&o](
auto
&& arg) { o.pack(arg); }, v);
41
return
o;
42
}
43
};
44
45
template
<
typename
... Args>
46
struct
convert<
std
::variant<Args...>>
47
{
48
49
// Base case for the variadic template function below. Should never be
50
// called, but the compiler needs to see it
51
template
<
typename
VariantType>
52
void
set_variant_helper(std::size_t, msgpack::object
const
&, VariantType&&)
const
53
{
54
}
55
56
// Deserializing std::variant is tricky, because we only know the
57
// index of the type that's held at runtime. We want something that is effectively:
58
//
59
// std::variant<T0, T1, T2, ...> v;
60
// size_t index = deserialize index...;
61
// switch(index){
62
// case 0:
63
// v = o.via.array.ptr.as<T0>(); break
64
// case 1:
65
// v = o.via.array.ptr.as<T1>(); break
66
// ...etc...
67
//
68
// This recursive variadic template function achieves that, using
69
// the index as a regular function parameter (not a template
70
// parameter, since it's only known at runtime). We peel off the
71
// variant types one at a time, decreasing the index each time. When
72
// the index reaches zero, we've peeled off enough types to get the
73
// one we want, so we can set the std::variant
74
template
<
typename
VariantType,
typename
T,
typename
... Types>
75
void
set_variant_helper(std::size_t i, msgpack::object
const
& o, VariantType&& v)
const
76
{
77
if
(i == 0)
78
v = o.via.array.ptr[1].as<T>();
// NOLINT
79
else
80
set_variant_helper<VariantType, Types...>(i - 1, o, v);
81
}
82
83
msgpack::object
const
& operator()(msgpack::object
const
& o, std::variant<Args...>& v)
const
84
{
85
if
(o.type != msgpack::type::ARRAY)
86
throw
msgpack::type_error();
87
// There are always exactly 2 items in the msgpack array: the
88
// index indicating which type the variant is holding, and the
89
// instance of the type itself (it *doesn't* depend sizeof...(Args))
90
if
(o.via.array.size != 2)
91
throw
msgpack::type_error();
92
std::size_t index = o.via.array.ptr[0].as<std::size_t>();
// NOLINT
93
if
(index >=
sizeof
...(Args)) {
94
throw
msgpack::type_error();
95
}
96
set_variant_helper<std::variant<Args...>&, Args...>(index, o, v);
97
return
o;
98
}
99
};
100
101
}
// namespace adaptor
102
}
// MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
103
}
// namespace msgpack
104
105
#endif
// SERIALIZATION_INCLUDE_SERIALIZATION_SERIALIZE_VARIANT_HPP_
msgpack
Definition
serialize_variant.hpp:24
msgpack::MSGPACK_API_VERSION_NAMESPACE
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
Definition
serialize_variant.hpp:25
std
Definition
SchemaUtils.hpp:118
Generated on
for DUNE-DAQ by
1.17.0