25{
26 namespace adaptor {
27
28 template<typename... Args>
29 struct pack<
std::variant<Args...>>
30 {
31 template<typename Stream>
32 packer<Stream>& operator()(msgpack::packer<Stream>& o, std::variant<Args...> const& v) const
33 {
34
35
36
37 o.pack_array(2);
38 o.pack(v.index());
39 std::visit([&o](auto&& arg) { o.pack(arg); }, v);
40 return o;
41 }
42 };
43
44 template<typename... Args>
45 struct convert<
std::variant<Args...>>
46 {
47
48
49
50 template<typename VariantType>
51 void set_variant_helper(std::size_t, msgpack::object const&, VariantType&&) const
52 {}
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 template<typename VariantType, typename T, typename... Types>
73 void set_variant_helper(std::size_t i, msgpack::object const& o, VariantType&& v) const
74 {
75 if (i == 0)
76 v = o.via.array.ptr[1].as<T>();
77 else
78 set_variant_helper<VariantType, Types...>(i - 1, o, v);
79 }
80
81 msgpack::object const& operator()(msgpack::object const& o, std::variant<Args...>& v) const
82 {
83 if (o.type != msgpack::type::ARRAY)
84 throw msgpack::type_error();
85
86
87
88 if (o.via.array.size != 2)
89 throw msgpack::type_error();
90 std::size_t
index = o.via.array.ptr[0].as<std::size_t>();
91 if (index >= sizeof...(Args)) {
92 throw msgpack::type_error();
93 }
94 set_variant_helper<std::variant<Args...>&, Args...>(
index, o, v);
95 return o;
96 }
97 };
98
99 }
100}