mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-06-12 17:05:04 +02:00
enhance error handling, implement object_with_zone, and add more tests
This commit is contained in:
parent
8bd1b7877c
commit
211c50c755
@ -11,8 +11,6 @@
|
|||||||
#ifndef MSGPACK_V1_TYPE_VARIANT_HPP
|
#ifndef MSGPACK_V1_TYPE_VARIANT_HPP
|
||||||
#define MSGPACK_V1_TYPE_VARIANT_HPP
|
#define MSGPACK_V1_TYPE_VARIANT_HPP
|
||||||
|
|
||||||
#define MSGPACK_USE_STD_VARIANT_ADAPTOR
|
|
||||||
|
|
||||||
#if defined(MSGPACK_USE_STD_VARIANT_ADAPTOR)
|
#if defined(MSGPACK_USE_STD_VARIANT_ADAPTOR)
|
||||||
|
|
||||||
#include "msgpack/cpp_version.hpp"
|
#include "msgpack/cpp_version.hpp"
|
||||||
@ -43,20 +41,31 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct object_variant_overload {
|
||||||
|
object_variant_overload(msgpack::object &obj, msgpack::zone &zone)
|
||||||
|
: obj{obj}
|
||||||
|
, zone{zone} {}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void operator()(T const &value) {
|
||||||
|
obj = msgpack::object(value, zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
msgpack::object &obj;
|
||||||
|
msgpack::zone &zone;
|
||||||
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
struct as<std::variant<Ts...>, typename std::enable_if<(msgpack::has_as<Ts>::value && ...)>::type> {
|
struct as<std::variant<Ts...>, typename std::enable_if<(msgpack::has_as<Ts>::value && ...)>::type> {
|
||||||
std::variant<Ts...> operator()(msgpack::object const &o) const {
|
std::variant<Ts...> operator()(msgpack::object const &o) const {
|
||||||
if (o.type != msgpack::type::ARRAY) {
|
if ( o.type != msgpack::type::ARRAY
|
||||||
throw msgpack::type_error{};
|
|| o.via.array.size != 2
|
||||||
}
|
|| o.via.array.ptr[0].type != msgpack::type::POSITIVE_INTEGER
|
||||||
if (o.via.array.size != 2) {
|
|| o.via.array.ptr[0].via.u64 >= sizeof...(Ts)) {
|
||||||
throw msgpack::type_error{};
|
|
||||||
}
|
|
||||||
if (o.via.array.ptr[0].type != msgpack::type::POSITIVE_INTEGER) {
|
|
||||||
throw msgpack::type_error{};
|
throw msgpack::type_error{};
|
||||||
}
|
}
|
||||||
|
|
||||||
return detail::construct_variant<std::variant<Ts...>, Ts...>(
|
return detail::construct_variant<std::variant<Ts...>, Ts...>(
|
||||||
o.via.array.ptr[0].as<std::size_t>(),
|
o.via.array.ptr[0].as<std::size_t>(),
|
||||||
o.via.array.ptr[1],
|
o.via.array.ptr[1],
|
||||||
@ -68,15 +77,13 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
struct convert<std::variant<Ts...>> {
|
struct convert<std::variant<Ts...>> {
|
||||||
msgpack::object const &operator()(msgpack::object const &o, std::variant<Ts...> &v) const {
|
msgpack::object const &operator()(msgpack::object const &o, std::variant<Ts...> &v) const {
|
||||||
if (o.type != msgpack::type::ARRAY) {
|
if ( o.type != msgpack::type::ARRAY
|
||||||
throw msgpack::type_error{};
|
|| o.via.array.size != 2
|
||||||
}
|
|| o.via.array.ptr[0].type != msgpack::type::POSITIVE_INTEGER
|
||||||
if (o.via.array.size != 2) {
|
|| o.via.array.ptr[0].via.u64 >= sizeof...(Ts)) {
|
||||||
throw msgpack::type_error{};
|
|
||||||
}
|
|
||||||
if (o.via.array.ptr[0].type != msgpack::type::POSITIVE_INTEGER) {
|
|
||||||
throw msgpack::type_error{};
|
throw msgpack::type_error{};
|
||||||
}
|
}
|
||||||
|
|
||||||
v = detail::construct_variant<std::variant<Ts...>, Ts...>(
|
v = detail::construct_variant<std::variant<Ts...>, Ts...>(
|
||||||
o.via.array.ptr[0].as<std::size_t>(),
|
o.via.array.ptr[0].as<std::size_t>(),
|
||||||
o.via.array.ptr[1],
|
o.via.array.ptr[1],
|
||||||
@ -92,38 +99,24 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream> &o, std::variant<Ts...> const &v) const {
|
msgpack::packer<Stream>& operator()(msgpack::packer<Stream> &o, std::variant<Ts...> const &v) const {
|
||||||
o.pack_array(2);
|
o.pack_array(2);
|
||||||
o.pack_uint64(v.index());
|
o.pack_uint64(v.index());
|
||||||
std::visit([&o](auto const &real_value){o.pack(real_value);}, v);
|
std::visit([&o](auto const &value){o.pack(value);}, v);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// template <typename... Ts>
|
|
||||||
// struct object<std::variant<Ts...>> {
|
template<typename... Ts>
|
||||||
// void operator()(msgpack::object &o, std::variant<Ts...> const &v) const {
|
struct object_with_zone<std::variant<Ts...>> {
|
||||||
// o.type = msgpack::type::ARRAY;
|
void operator()(msgpack::object::with_zone &o, std::variant<Ts...> const &v) const {
|
||||||
// o.via.array.size = 2;
|
msgpack::object *p = static_cast<msgpack::object *>(o.zone.allocate_align(sizeof(msgpack::object) * 2, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
|
||||||
// msgpack::adaptor::object<std::size_t>(o.via.array.ptr[0], v.index());
|
|
||||||
// std::visit([&o](auto const &value) {
|
o.type = msgpack::type::ARRAY;
|
||||||
// msgpack::adaptor::object(o.via.array.ptr[1], value);
|
o.via.array.size = 2;
|
||||||
// }, v);
|
o.via.array.ptr = p;
|
||||||
// }
|
o.via.array.ptr[0]= msgpack::object(v.index(), o.zone);
|
||||||
// };
|
std::visit(detail::object_variant_overload(o.via.array.ptr[1], o.zone), v);
|
||||||
//
|
}
|
||||||
// template<typename... Ts>
|
};
|
||||||
// struct object_with_zone<std::variant<Ts...>> {
|
|
||||||
// void operator()(msgpack::object::with_zone &o, std::variant<Ts...> const &v) const {
|
|
||||||
// o.type = msgpack::type::ARRAY;
|
|
||||||
//
|
|
||||||
// msgpack::object *p = static_cast<msgpack::object *>(o.zone.allocate_align(sizeof(msgpack::object) * 2, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
|
|
||||||
//
|
|
||||||
// o.via.array.size = 2;
|
|
||||||
// o.via.array.ptr = p;
|
|
||||||
// msgpack::adaptor::object_with_zone<std::size_t>()(o.via.array.ptr[0], v.index(), o.zone);
|
|
||||||
// std::visit([&o](auto const &real_value){
|
|
||||||
// o.via.array.ptr[1] = msgpack::adaptor::object()(real_value, o.zone);
|
|
||||||
// }, v);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
} // namespace adaptor
|
} // namespace adaptor
|
||||||
}
|
}
|
||||||
} // namespace msgpack
|
} // namespace msgpack
|
||||||
|
@ -461,7 +461,9 @@ BOOST_AUTO_TEST_CASE(carray_byte_object_with_zone)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(variant_as) {
|
#if defined(MSGPACK_USE_STD_VARIANT_ADAPTOR)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(variant_pack_unpack_as) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
std::variant<bool, int, float, double> val1{1.0};
|
std::variant<bool, int, float, double> val1{1.0};
|
||||||
msgpack::pack(ss, val1);
|
msgpack::pack(ss, val1);
|
||||||
@ -470,6 +472,18 @@ BOOST_AUTO_TEST_CASE(variant_as) {
|
|||||||
msgpack::unpack(str.data(), str.size());
|
msgpack::unpack(str.data(), str.size());
|
||||||
std::variant<bool, int, float, double> val2 = oh.get().as<std::variant<bool, int, float, double> >();
|
std::variant<bool, int, float, double> val2 = oh.get().as<std::variant<bool, int, float, double> >();
|
||||||
BOOST_CHECK(val1 == val2);
|
BOOST_CHECK(val1 == val2);
|
||||||
|
BOOST_CHECK_THROW((oh.get().as<std::variant<bool>>()), msgpack::type_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(variant_with_zone) {
|
||||||
|
msgpack::zone z;
|
||||||
|
std::variant<bool, int, float, double> val1{1.0};
|
||||||
|
msgpack::object obj(val1, z);
|
||||||
|
std::variant<bool, int, float, double> val2 = obj.as<std::variant<bool, int, float, double>>();
|
||||||
|
BOOST_CHECK(val1 == val2);
|
||||||
|
BOOST_CHECK_THROW((obj.as<std::variant<bool>>()), msgpack::type_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // defined(MSGPACK_USE_STD_VARIANT_ADAPTOR)
|
||||||
|
|
||||||
#endif // MSGPACK_CPP_VERSION >= 201703
|
#endif // MSGPACK_CPP_VERSION >= 201703
|
||||||
|
Loading…
x
Reference in New Issue
Block a user