1111#ifndef MSGPACK_V1_TYPE_VARIANT_HPP
1212#define MSGPACK_V1_TYPE_VARIANT_HPP
1313
14- #define MSGPACK_USE_STD_VARIANT_ADAPTOR
15-
1614#if defined(MSGPACK_USE_STD_VARIANT_ADAPTOR)
1715
1816#include " msgpack/cpp_version.hpp"
@@ -43,20 +41,31 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
4341 }
4442 }
4543
44+ struct object_variant_overload {
45+ object_variant_overload (msgpack::object &obj, msgpack::zone &zone)
46+ : obj{obj}
47+ , zone{zone} {}
48+
49+ template <typename T>
50+ void operator ()(T const &value) {
51+ obj = msgpack::object (value, zone);
52+ }
53+
54+ msgpack::object &obj;
55+ msgpack::zone &zone;
56+ };
4657 } // namespace detail
4758
4859 template <typename ... Ts>
4960 struct as <std::variant<Ts...>, typename std::enable_if<(msgpack::has_as<Ts>::value && ...)>::type> {
5061 std::variant<Ts...> operator ()(msgpack::object const &o) const {
51- if (o.type != msgpack::type::ARRAY) {
52- throw msgpack::type_error{};
53- }
54- if (o.via .array .size != 2 ) {
55- throw msgpack::type_error{};
56- }
57- if (o.via .array .ptr [0 ].type != msgpack::type::POSITIVE_INTEGER) {
62+ if ( o.type != msgpack::type::ARRAY
63+ || o.via .array .size != 2
64+ || o.via .array .ptr [0 ].type != msgpack::type::POSITIVE_INTEGER
65+ || o.via .array .ptr [0 ].via .u64 >= sizeof ...(Ts)) {
5866 throw msgpack::type_error{};
5967 }
68+
6069 return detail::construct_variant<std::variant<Ts...>, Ts...>(
6170 o.via .array .ptr [0 ].as <std::size_t >(),
6271 o.via .array .ptr [1 ],
@@ -68,15 +77,13 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
6877 template <typename ... Ts>
6978 struct convert <std::variant<Ts...>> {
7079 msgpack::object const &operator ()(msgpack::object const &o, std::variant<Ts...> &v) const {
71- if (o.type != msgpack::type::ARRAY) {
72- throw msgpack::type_error{};
73- }
74- if (o.via .array .size != 2 ) {
75- throw msgpack::type_error{};
76- }
77- if (o.via .array .ptr [0 ].type != msgpack::type::POSITIVE_INTEGER) {
80+ if ( o.type != msgpack::type::ARRAY
81+ || o.via .array .size != 2
82+ || o.via .array .ptr [0 ].type != msgpack::type::POSITIVE_INTEGER
83+ || o.via .array .ptr [0 ].via .u64 >= sizeof ...(Ts)) {
7884 throw msgpack::type_error{};
7985 }
86+
8087 v = detail::construct_variant<std::variant<Ts...>, Ts...>(
8188 o.via .array .ptr [0 ].as <std::size_t >(),
8289 o.via .array .ptr [1 ],
@@ -92,38 +99,24 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
9299 msgpack::packer<Stream>& operator ()(msgpack::packer<Stream> &o, std::variant<Ts...> const &v) const {
93100 o.pack_array (2 );
94101 o.pack_uint64 (v.index ());
95- std::visit ([&o](auto const &real_value ){o.pack (real_value );}, v);
102+ std::visit ([&o](auto const &value ){o.pack (value );}, v);
96103 return o;
97104 }
98105 };
99106
100- // template <typename... Ts>
101- // struct object<std::variant<Ts...>> {
102- // void operator()(msgpack::object &o, std::variant<Ts...> const &v) const {
103- // o.type = msgpack::type::ARRAY;
104- // o.via.array.size = 2;
105- // msgpack::adaptor::object<std::size_t>(o.via.array.ptr[0], v.index());
106- // std::visit([&o](auto const &value) {
107- // msgpack::adaptor::object(o.via.array.ptr[1], value);
108- // }, v);
109- // }
110- // };
111- //
112- // template<typename... Ts>
113- // struct object_with_zone<std::variant<Ts...>> {
114- // void operator()(msgpack::object::with_zone &o, std::variant<Ts...> const &v) const {
115- // o.type = msgpack::type::ARRAY;
116- //
117- // msgpack::object *p = static_cast<msgpack::object *>(o.zone.allocate_align(sizeof(msgpack::object) * 2, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
118- //
119- // o.via.array.size = 2;
120- // o.via.array.ptr = p;
121- // msgpack::adaptor::object_with_zone<std::size_t>()(o.via.array.ptr[0], v.index(), o.zone);
122- // std::visit([&o](auto const &real_value){
123- // o.via.array.ptr[1] = msgpack::adaptor::object()(real_value, o.zone);
124- // }, v);
125- // }
126- // };
107+
108+ template <typename ... Ts>
109+ struct object_with_zone <std::variant<Ts...>> {
110+ void operator ()(msgpack::object::with_zone &o, std::variant<Ts...> const &v) const {
111+ msgpack::object *p = static_cast <msgpack::object *>(o.zone .allocate_align (sizeof (msgpack::object) * 2 , MSGPACK_ZONE_ALIGNOF (msgpack::object)));
112+
113+ o.type = msgpack::type::ARRAY;
114+ o.via .array .size = 2 ;
115+ o.via .array .ptr = p;
116+ o.via .array .ptr [0 ]= msgpack::object (v.index (), o.zone );
117+ std::visit (detail::object_variant_overload (o.via .array .ptr [1 ], o.zone ), v);
118+ }
119+ };
127120 } // namespace adaptor
128121}
129122} // namespace msgpack
0 commit comments