// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma // de Barcelona (UAB). // // This work is licensed under the terms of the MIT license. // For a copy, see . #pragma once #include "carla/Exception.h" #include "carla/MsgPack.h" #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4583) #pragma warning(disable:4582) #include #pragma warning(pop) #else #include #endif #include namespace clmdep_msgpack { MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) { namespace adaptor { // =========================================================================== // -- Adaptors for boost::optional ------------------------------------------- // =========================================================================== template struct convert> { const clmdep_msgpack::object &operator()( const clmdep_msgpack::object &o, boost::optional &v) const { if (o.type != clmdep_msgpack::type::ARRAY) { ::carla::throw_exception(clmdep_msgpack::type_error()); } if (o.via.array.size == 1) { v.reset(); } else if (o.via.array.size == 2) { v.reset(o.via.array.ptr[1].as()); } else { ::carla::throw_exception(clmdep_msgpack::type_error()); } return o; } }; template struct pack> { template packer &operator()( clmdep_msgpack::packer &o, const boost::optional &v) const { if (v.has_value()) { o.pack_array(2); o.pack(true); o.pack(*v); } else { o.pack_array(1); o.pack(false); } return o; } }; template struct object_with_zone> { void operator()( clmdep_msgpack::object::with_zone &o, const boost::optional &v) const { o.type = type::ARRAY; if (v.has_value()) { o.via.array.size = 2; o.via.array.ptr = static_cast(o.zone.allocate_align( sizeof(clmdep_msgpack::object) * o.via.array.size, MSGPACK_ZONE_ALIGNOF(clmdep_msgpack::object))); o.via.array.ptr[0] = clmdep_msgpack::object(true, o.zone); o.via.array.ptr[1] = clmdep_msgpack::object(*v, o.zone); } else { o.via.array.size = 1; o.via.array.ptr = static_cast(o.zone.allocate_align( sizeof(clmdep_msgpack::object) * o.via.array.size, MSGPACK_ZONE_ALIGNOF(clmdep_msgpack::object))); o.via.array.ptr[0] = clmdep_msgpack::object(false, o.zone); } } }; // =========================================================================== // -- Adaptors for boost::variant2::variant ---------------------------------- // =========================================================================== template struct convert> { const clmdep_msgpack::object &operator()( const clmdep_msgpack::object &o, boost::variant2::variant &v) const { if (o.type != clmdep_msgpack::type::ARRAY) { ::carla::throw_exception(clmdep_msgpack::type_error()); } if (o.via.array.size != 2) { ::carla::throw_exception(clmdep_msgpack::type_error()); } const auto index = o.via.array.ptr[0].as(); copy_to_variant(index, o, v, std::make_index_sequence()); return o; } private: template static void copy_to_variant_impl( const clmdep_msgpack::object &o, boost::variant2::variant &v) { /// @todo Workaround for finding the type. auto dummy = std::get(std::tuple{}); using T = decltype(dummy); v = o.via.array.ptr[1].as(); } template static void copy_to_variant( const uint64_t index, const clmdep_msgpack::object &o, boost::variant2::variant &v, std::index_sequence) { std::initializer_list ({ (index == Is ? copy_to_variant_impl(o, v), 0 : 0)... }); } }; template struct pack> { template packer &operator()( clmdep_msgpack::packer &o, const boost::variant2::variant &v) const { o.pack_array(2); o.pack(static_cast(v.index())); boost::variant2::visit([&](const auto &value) { o.pack(value); }, v); return o; } }; template struct object_with_zone> { void operator()( clmdep_msgpack::object::with_zone &o, const boost::variant2::variant &v) const { o.type = type::ARRAY; o.via.array.size = 2; o.via.array.ptr = static_cast(o.zone.allocate_align( sizeof(clmdep_msgpack::object) * o.via.array.size, MSGPACK_ZONE_ALIGNOF(clmdep_msgpack::object))); o.via.array.ptr[0] = clmdep_msgpack::object(static_cast(v.index()), o.zone); boost::variant2::visit([&](const auto &value) { o.via.array.ptr[1] = clmdep_msgpack::object(value, o.zone); }, v); } }; } // namespace adaptor } // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) } // namespace msgpack