CARLA
 
载入中...
搜索中...
未找到
MsgPackAdaptors.h
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#pragma once
8
9#include "carla/Exception.h"
10#include "carla/MsgPack.h"
11
12#include <boost/optional.hpp>
13
14#ifdef _MSC_VER
15#pragma warning(push)
16#pragma warning(disable:4583)
17#pragma warning(disable:4582)
18#include <boost/variant2/variant.hpp>
19#pragma warning(pop)
20#else
21#include <boost/variant2/variant.hpp>
22#endif
23
24#include <tuple>
25
26namespace clmdep_msgpack {
27MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
28namespace adaptor {
29
30 // ===========================================================================
31 // -- Adaptors for boost::optional -------------------------------------------
32 // ===========================================================================
33
34 template<typename T>
35 struct convert<boost::optional<T>> {
36 const clmdep_msgpack::object &operator()(
37 const clmdep_msgpack::object &o,
38 boost::optional<T> &v) const {
39 if (o.type != clmdep_msgpack::type::ARRAY) {
40 ::carla::throw_exception(clmdep_msgpack::type_error());
41 }
42 if (o.via.array.size == 1) {
43 v.reset();
44 } else if (o.via.array.size == 2) {
45 v.reset(o.via.array.ptr[1].as<T>());
46 } else {
47 ::carla::throw_exception(clmdep_msgpack::type_error());
48 }
49 return o;
50 }
51 };
52
53 template<typename T>
54 struct pack<boost::optional<T>> {
55 template <typename Stream>
56 packer<Stream> &operator()(
57 clmdep_msgpack::packer<Stream> &o,
58 const boost::optional<T> &v) const {
59 if (v.has_value()) {
60 o.pack_array(2);
61 o.pack(true);
62 o.pack(*v);
63 } else {
64 o.pack_array(1);
65 o.pack(false);
66 }
67 return o;
68 }
69 };
70
71 template<typename T>
72 struct object_with_zone<boost::optional<T>> {
73 void operator()(
74 clmdep_msgpack::object::with_zone &o,
75 const boost::optional<T> &v) const {
76 o.type = type::ARRAY;
77 if (v.has_value()) {
78 o.via.array.size = 2;
79 o.via.array.ptr = static_cast<clmdep_msgpack::object*>(o.zone.allocate_align(
80 sizeof(clmdep_msgpack::object) * o.via.array.size,
81 MSGPACK_ZONE_ALIGNOF(clmdep_msgpack::object)));
82 o.via.array.ptr[0] = clmdep_msgpack::object(true, o.zone);
83 o.via.array.ptr[1] = clmdep_msgpack::object(*v, o.zone);
84 } else {
85 o.via.array.size = 1;
86 o.via.array.ptr = static_cast<clmdep_msgpack::object*>(o.zone.allocate_align(
87 sizeof(clmdep_msgpack::object) * o.via.array.size,
88 MSGPACK_ZONE_ALIGNOF(clmdep_msgpack::object)));
89 o.via.array.ptr[0] = clmdep_msgpack::object(false, o.zone);
90 }
91 }
92 };
93
94 // ===========================================================================
95 // -- Adaptors for boost::variant2::variant ----------------------------------
96 // ===========================================================================
97
98 template<typename... Ts>
99 struct convert<boost::variant2::variant<Ts...>> {
100
101 const clmdep_msgpack::object &operator()(
102 const clmdep_msgpack::object &o,
103 boost::variant2::variant<Ts...> &v) const {
104 if (o.type != clmdep_msgpack::type::ARRAY) {
105 ::carla::throw_exception(clmdep_msgpack::type_error());
106 }
107 if (o.via.array.size != 2) {
108 ::carla::throw_exception(clmdep_msgpack::type_error());
109 }
110 const auto index = o.via.array.ptr[0].as<uint64_t>();
111 copy_to_variant(index, o, v, std::make_index_sequence<sizeof...(Ts)>());
112 return o;
113 }
114
115 private:
116
117 template <uint64_t I>
118 static void copy_to_variant_impl(
119 const clmdep_msgpack::object &o,
120 boost::variant2::variant<Ts...> &v) {
121 /// @todo Workaround for finding the type.
122 auto dummy = std::get<I>(std::tuple<Ts...>{});
123 using T = decltype(dummy);
124 v = o.via.array.ptr[1].as<T>();
125 }
126
127 template <uint64_t... Is>
128 static void copy_to_variant(
129 const uint64_t index,
130 const clmdep_msgpack::object &o,
131 boost::variant2::variant<Ts...> &v,
132 std::index_sequence<Is...>) {
133 std::initializer_list<int> ({
134 (index == Is ? copy_to_variant_impl<Is>(o, v), 0 : 0)...
135 });
136 }
137 };
138
139 template<typename... Ts>
140 struct pack<boost::variant2::variant<Ts...>> {
141 template <typename Stream>
142 packer<Stream> &operator()(
143 clmdep_msgpack::packer<Stream> &o,
144 const boost::variant2::variant<Ts...> &v) const {
145 o.pack_array(2);
146 o.pack(static_cast<uint64_t>(v.index()));
147 boost::variant2::visit([&](const auto &value) { o.pack(value); }, v);
148 return o;
149 }
150 };
151
152 template<typename... Ts>
153 struct object_with_zone<boost::variant2::variant<Ts...>> {
154 void operator()(
155 clmdep_msgpack::object::with_zone &o,
156 const boost::variant2::variant<Ts...> &v) const {
157 o.type = type::ARRAY;
158 o.via.array.size = 2;
159 o.via.array.ptr = static_cast<clmdep_msgpack::object*>(o.zone.allocate_align(
160 sizeof(clmdep_msgpack::object) * o.via.array.size,
161 MSGPACK_ZONE_ALIGNOF(clmdep_msgpack::object)));
162 o.via.array.ptr[0] = clmdep_msgpack::object(static_cast<uint64_t>(v.index()), o.zone);
163 boost::variant2::visit([&](const auto &value) {
164 o.via.array.ptr[1] = clmdep_msgpack::object(value, o.zone);
165 }, v);
166 }
167 };
168
169} // namespace adaptor
170} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
171} // namespace msgpack
void throw_exception(const std::exception &e)
Definition Carla.cpp:135
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)