DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
msgpack Namespace Reference

Functions

 MSGPACK_API_VERSION_NAMESPACE (MSGPACK_DEFAULT_API_NS)
 

Function Documentation

◆ MSGPACK_API_VERSION_NAMESPACE()

msgpack::MSGPACK_API_VERSION_NAMESPACE ( MSGPACK_DEFAULT_API_NS )

Definition at line 25 of file serialize_variant.hpp.

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)
default char v[0]