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
36
37
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
50
51 template<typename VariantType>
52 void set_variant_helper(std::size_t, msgpack::object const&, VariantType&&) const
53 {
54 }
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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>();
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
88
89
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>();
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 }
102}