11
11
#ifndef MSGPACK_V1_TYPE_VARIANT_HPP
12
12
#define MSGPACK_V1_TYPE_VARIANT_HPP
13
13
14
- #define MSGPACK_USE_STD_VARIANT_ADAPTOR
15
-
16
14
#if defined(MSGPACK_USE_STD_VARIANT_ADAPTOR)
17
15
18
16
#include " msgpack/cpp_version.hpp"
@@ -43,20 +41,31 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
43
41
}
44
42
}
45
43
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
+ };
46
57
} // namespace detail
47
58
48
59
template <typename ... Ts>
49
60
struct as <std::variant<Ts...>, typename std::enable_if<(msgpack::has_as<Ts>::value && ...)>::type> {
50
61
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)) {
58
66
throw msgpack::type_error{};
59
67
}
68
+
60
69
return detail::construct_variant<std::variant<Ts...>, Ts...>(
61
70
o.via .array .ptr [0 ].as <std::size_t >(),
62
71
o.via .array .ptr [1 ],
@@ -68,15 +77,13 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
68
77
template <typename ... Ts>
69
78
struct convert <std::variant<Ts...>> {
70
79
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)) {
78
84
throw msgpack::type_error{};
79
85
}
86
+
80
87
v = detail::construct_variant<std::variant<Ts...>, Ts...>(
81
88
o.via .array .ptr [0 ].as <std::size_t >(),
82
89
o.via .array .ptr [1 ],
@@ -92,38 +99,24 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
92
99
msgpack::packer<Stream>& operator ()(msgpack::packer<Stream> &o, std::variant<Ts...> const &v) const {
93
100
o.pack_array (2 );
94
101
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);
96
103
return o;
97
104
}
98
105
};
99
106
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
+ };
127
120
} // namespace adaptor
128
121
}
129
122
} // namespace msgpack
0 commit comments