Skip to content

Commit 211c50c

Browse files
committed
enhance error handling, implement object_with_zone, and add more tests
1 parent 8bd1b78 commit 211c50c

File tree

2 files changed

+52
-45
lines changed

2 files changed

+52
-45
lines changed

include/msgpack/v1/adaptor/cpp17/variant.hpp

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
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

test/msgpack_cpp17.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,9 @@ BOOST_AUTO_TEST_CASE(carray_byte_object_with_zone)
461461
}
462462
}
463463

464-
BOOST_AUTO_TEST_CASE(variant_as) {
464+
#if defined(MSGPACK_USE_STD_VARIANT_ADAPTOR)
465+
466+
BOOST_AUTO_TEST_CASE(variant_pack_unpack_as) {
465467
std::stringstream ss;
466468
std::variant<bool, int, float, double> val1{1.0};
467469
msgpack::pack(ss, val1);
@@ -470,6 +472,18 @@ BOOST_AUTO_TEST_CASE(variant_as) {
470472
msgpack::unpack(str.data(), str.size());
471473
std::variant<bool, int, float, double> val2 = oh.get().as<std::variant<bool, int, float, double> >();
472474
BOOST_CHECK(val1 == val2);
475+
BOOST_CHECK_THROW((oh.get().as<std::variant<bool>>()), msgpack::type_error);
476+
}
477+
478+
BOOST_AUTO_TEST_CASE(variant_with_zone) {
479+
msgpack::zone z;
480+
std::variant<bool, int, float, double> val1{1.0};
481+
msgpack::object obj(val1, z);
482+
std::variant<bool, int, float, double> val2 = obj.as<std::variant<bool, int, float, double>>();
483+
BOOST_CHECK(val1 == val2);
484+
BOOST_CHECK_THROW((obj.as<std::variant<bool>>()), msgpack::type_error);
473485
}
474486

487+
#endif // defined(MSGPACK_USE_STD_VARIANT_ADAPTOR)
488+
475489
#endif // MSGPACK_CPP_VERSION >= 201703

0 commit comments

Comments
 (0)