MessagePack for C++
Loading...
Searching...
No Matches
msgpack_variant.hpp
Go to the documentation of this file.
1//
2// MessagePack for C++ static resolution routine
3//
4// Copyright (C) 2015-2016 KONDO Takatoshi
5//
6// Distributed under the Boost Software License, Version 1.0.
7// (See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9//
10#ifndef MSGPACK_V1_TYPE_BOOST_MSGPACK_VARIANT_HPP
11#define MSGPACK_V1_TYPE_BOOST_MSGPACK_VARIANT_HPP
12
14
17
28
29
30#if defined(__GNUC__)
31#pragma GCC diagnostic push
32#pragma GCC diagnostic ignored "-Wconversion"
33#endif // defined(__GNUC__)
34
35#include <boost/variant.hpp>
36
37#if defined(__GNUC__)
38#pragma GCC diagnostic pop
39#endif // defined(__GNUC__)
40
41#include <boost/operators.hpp>
42
43namespace msgpack {
44
48
49namespace type {
50
51
52template <typename STR, typename BIN, typename EXT>
54 boost::variant<
55 nil_t, // NIL
56 bool, // BOOL
57 int64_t, // NEGATIVE_INTEGER
58 uint64_t, // POSITIVE_INTEGER
59 double, // FLOAT32, FLOAT64
60 std::string, // STR
61#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
62 boost::string_ref, // STR
63#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
64 std::vector<char>, // BIN
66 msgpack::type::ext, // EXT
68 boost::recursive_wrapper<std::vector<basic_variant<STR, BIN, EXT> > >, // ARRAY
69 boost::recursive_wrapper<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >, // MAP
70 boost::recursive_wrapper<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >// MAP
71 >,
72 private boost::totally_ordered<basic_variant<STR, BIN, EXT> > {
73 typedef boost::variant<
74 nil_t, // NIL
75 bool, // BOOL
76 int64_t, // NEGATIVE_INTEGER
77 uint64_t, // POSITIVE_INTEGER
78 double, // FLOAT32, FLOAT64
79 std::string, // STR
80#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
81 boost::string_ref, // STR
82#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
83 std::vector<char>, // BIN
85 msgpack::type::ext, // EXT
87 boost::recursive_wrapper<std::vector<basic_variant<STR, BIN, EXT> > >, // ARRAY
88 boost::recursive_wrapper<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >, // MAP
89 boost::recursive_wrapper<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >// MAP
92 template <typename T>
93 basic_variant(T const& t):base(t) {}
94
95#if defined(_MSC_VER) && _MSC_VER < 1700
96 // The following redundant functions are required to avoid MSVC
97 // See https://svn.boost.org/trac/boost/ticket/592
98 basic_variant(basic_variant const& other):base(static_cast<base const&>(other)) {}
99 basic_variant& operator=(basic_variant const& other) {
100 *static_cast<base*>(this) = static_cast<base const&>(other);
101 return *this;
102 }
103#endif // defined(_MSC_VER) && _MSC_VER < 1700
104
105 basic_variant(char const* p):base(std::string(p)) {}
107 int_init(v);
108 }
109 basic_variant(signed char v) {
110 int_init(v);
111 }
112 basic_variant(unsigned char v):base(uint64_t(v)) {}
113 basic_variant(signed int v) {
114 int_init(v);
115 }
116 basic_variant(unsigned int v):base(uint64_t(v)) {}
117 basic_variant(signed long v) {
118 int_init(v);
119 }
120 basic_variant(unsigned long v):base(uint64_t(v)) {}
121 basic_variant(signed long long v) {
122 int_init(v);
123 }
124 basic_variant(unsigned long long v):base(uint64_t(v)) {}
125 basic_variant(float v) {
126 double_init(v);
127 }
128 basic_variant(double v) {
129 double_init(v);
130 }
131
132 bool is_nil() const {
133 return boost::get<msgpack::type::nil_t>(this) != MSGPACK_NULLPTR;
134 }
135 bool is_bool() const {
136 return boost::get<bool>(this) != MSGPACK_NULLPTR;
137 }
138 bool is_int64_t() const {
139 return boost::get<int64_t>(this) != MSGPACK_NULLPTR;
140 }
141 bool is_uint64_t() const {
142 return boost::get<uint64_t>(this) != MSGPACK_NULLPTR;
143 }
144 bool is_double() const {
145 return boost::get<double>(this) != MSGPACK_NULLPTR;
146 }
147 bool is_string() const {
148 return boost::get<std::string>(this) != MSGPACK_NULLPTR;
149 }
150#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
151 bool is_boost_string_ref() const {
152 return boost::get<boost::string_ref>(this) != MSGPACK_NULLPTR;
153 }
154#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
155 bool is_vector_char() const {
156 return boost::get<std::vector<char> >(this) != MSGPACK_NULLPTR;
157 }
159 return boost::get<std::vector<char> >(this) != MSGPACK_NULLPTR;
160 }
161 bool is_raw_ref() const {
162 return boost::get<raw_ref>(this) != MSGPACK_NULLPTR;
163 }
164 bool is_ext() const {
165 return boost::get<ext>(this) != MSGPACK_NULLPTR;
166 }
167 bool is_ext_ref() const {
168 return boost::get<ext_ref>(this) != MSGPACK_NULLPTR;
169 }
170 bool is_vector() const {
171 return boost::get<std::vector<basic_variant<STR, BIN, EXT> > >(this) != MSGPACK_NULLPTR;
172 }
173 bool is_map() const {
174 return boost::get<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(this) != MSGPACK_NULLPTR;
175 }
176 bool is_multimap() const {
177 return boost::get<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(this) != MSGPACK_NULLPTR;
178 }
179
180 bool as_bool() const {
181 return boost::get<bool>(*this);
182 }
183 int64_t as_int64_t() const {
184 return boost::get<int64_t>(*this);
185 }
186 uint64_t as_uint64_t() const {
187 return boost::get<uint64_t>(*this);
188 }
189 double as_double() const {
190 if (is_double()) {
191 return boost::get<double>(*this);
192 }
193 if (is_int64_t()) {
194 return static_cast<double>(boost::get<int64_t>(*this));
195 }
196 if (is_uint64_t()) {
197 return static_cast<double>(boost::get<uint64_t>(*this));
198 }
199 throw msgpack::type_error();
200 }
201 std::string const& as_string() const {
202 return boost::get<std::string>(*this);
203 }
204#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
205 boost::string_ref const& as_boost_string_ref() const {
206 return boost::get<boost::string_ref>(*this);
207 }
208#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
209 std::vector<char> const& as_vector_char() const {
210 return boost::get<std::vector<char> >(*this);
211 }
212 raw_ref const& as_raw_ref() const {
213 return boost::get<raw_ref>(*this);
214 }
215 ext const& as_ext() const {
216 return boost::get<ext>(*this);
217 }
218 ext_ref const& as_ext_ref() const {
219 return boost::get<ext_ref>(*this);
220 }
221 std::vector<basic_variant<STR, BIN, EXT> > const& as_vector() const {
222 return boost::get<std::vector<basic_variant<STR, BIN, EXT> > >(*this);
223 }
224 std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > const& as_map() const {
225 return boost::get<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
226 }
227 std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > const& as_multimap() const {
228 return boost::get<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
229 }
230private:
231 template <typename T>
232 void int_init(T v) {
233 if (v < 0) {
234 static_cast<base&>(*this) = int64_t(v);
235 }
236 else {
237 static_cast<base&>(*this) = uint64_t(v);
238 }
239 }
240 void double_init(double v) {
241 if (v == v) { // check for nan
242 if (v >= 0 && v <= double(std::numeric_limits<uint64_t>::max()) && v == double(uint64_t(v))) {
243 static_cast<base&>(*this) = uint64_t(v);
244 return;
245 }
246 else if (v < 0 && v >= double(std::numeric_limits<int64_t>::min()) && v == double(int64_t(v))) {
247 static_cast<base&>(*this) = int64_t(v);
248 return;
249 }
250 }
251 static_cast<base&>(*this) = v;
252 }
253};
254
255template <typename STR, typename BIN, typename EXT>
257 return
258 static_cast<typename basic_variant<STR, BIN, EXT>::base const&>(lhs) <
259 static_cast<typename basic_variant<STR, BIN, EXT>::base const&>(rhs);
260}
261
262template <typename STR, typename BIN, typename EXT>
264 return
265 static_cast<typename basic_variant<STR, BIN, EXT>::base const&>(lhs) ==
266 static_cast<typename basic_variant<STR, BIN, EXT>::base const&>(rhs);
267}
268
270typedef basic_variant<
271#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
272 boost::string_ref,
273#else // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
274 std::string,
275#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
277
278} // namespace type
279
280namespace adaptor {
281
282#if !defined (MSGPACK_USE_CPP03)
283
284template <typename STR, typename BIN, typename EXT>
285struct as<type::basic_variant<STR, BIN, EXT> > {
286 type::basic_variant<STR, BIN, EXT> operator()(msgpack::object const& o) const {
287 switch(o.type) {
288 case type::NIL:
289 return o.as<msgpack::type::nil_t>();
290 case type::BOOLEAN:
291 return o.as<bool>();
292 case type::POSITIVE_INTEGER:
293 return o.as<uint64_t>();
294 case type::NEGATIVE_INTEGER:
295 return o.as<int64_t>();
296 case type::FLOAT32:
297 case type::FLOAT64:
298 return o.as<double>();
299 case type::STR:
300 return o.as<STR>();
301 case type::BIN:
302 return o.as<BIN>();
303 case type::EXT:
304 return o.as<EXT>();
305 case type::ARRAY:
306 return o.as<std::vector<type::basic_variant<STR, BIN, EXT> > >();
307 case type::MAP:
308 return o.as<std::multimap<type::basic_variant<STR, BIN, EXT>, type::basic_variant<STR, BIN, EXT> > >();
309 default:
310 break;
311 }
313 }
314};
315
316#endif // !defined (MSGPACK_USE_CPP03)
317
318
319template <typename STR, typename BIN, typename EXT>
320struct convert<type::basic_variant<STR, BIN, EXT> > {
322 msgpack::object const& o,
323 type::basic_variant<STR, BIN, EXT>& v) const {
324 switch(o.type) {
325 case type::NIL:
326 v = o.as<msgpack::type::nil_t>();
327 break;
328 case type::BOOLEAN:
329 v = o.as<bool>();
330 break;
331 case type::POSITIVE_INTEGER:
332 v = o.as<uint64_t>();
333 break;
334 case type::NEGATIVE_INTEGER:
335 v = o.as<int64_t>();
336 break;
337 case type::FLOAT32:
338 case type::FLOAT64:
339 v = o.as<double>();
340 break;
341 case type::STR:
342 v = o.as<STR>();
343 break;
344 case type::BIN:
345 v = o.as<BIN>();
346 break;
347 case type::EXT:
348 v = o.as<EXT>();
349 break;
350 case type::ARRAY:
351 v = o.as<std::vector<type::basic_variant<STR, BIN, EXT> > >();
352 break;
353 case type::MAP:
354 v = o.as<std::multimap<type::basic_variant<STR, BIN, EXT>, type::basic_variant<STR, BIN, EXT> > >();
355 break;
356 default:
357 break;
358 }
359 return o;
360 }
361};
362
363namespace detail {
364
365template <typename Stream>
366struct pack_imp : boost::static_visitor<void> {
367 template <typename T>
368 void operator()(T const& value) const {
369 pack<T>()(o_, value);
370 }
373};
374
375} // namespace detail
376
377template <typename STR, typename BIN, typename EXT>
378struct pack<type::basic_variant<STR, BIN, EXT> > {
379 template <typename Stream>
381 boost::apply_visitor(detail::pack_imp<Stream>(o), v);
382 return o;
383 }
384};
385
386namespace detail {
387
388struct object_imp : boost::static_visitor<void> {
389 void operator()(msgpack::type::nil_t const& v) const {
391 }
392 void operator()(bool const& v) const {
393 object<bool>()(o_, v);
394 }
395 void operator()(uint64_t const& v) const {
396 object<uint64_t>()(o_, v);
397 }
398 void operator()(int64_t const& v) const {
399 object<int64_t>()(o_, v);
400 }
401 void operator()(double const& v) const {
402 object<double>()(o_, v);
403 }
404 template <typename T>
405 void operator()(T const&) const {
406 throw msgpack::type_error();
407 }
410};
411
412} // namespace detail
413
414template <typename STR, typename BIN, typename EXT>
415struct object<type::basic_variant<STR, BIN, EXT> > {
417 boost::apply_visitor(detail::object_imp(o), v);
418 }
419};
420
421namespace detail {
422
423struct object_with_zone_imp : boost::static_visitor<void> {
424 template <typename T>
425 void operator()(T const& v) const {
427 }
430};
431
432} // namespace detail
433
434template <typename STR, typename BIN, typename EXT>
435struct object_with_zone<type::basic_variant<STR, BIN, EXT> > {
437 boost::apply_visitor(detail::object_with_zone_imp(o), v);
438 }
439};
440
441} // namespace adaptor
442
444} // MSGPACK_API_VERSION_NAMESPACE(v1)
446
447} // namespace msgpack
448
449#endif // MSGPACK_V1_TYPE_BOOST_MSGPACK_VARIANT_HPP
The class template that supports continuous packing.
Definition pack.hpp:33
Definition ext.hpp:118
Definition ext.hpp:26
Definition object_fwd.hpp:231
basic_variant< std::string, std::vector< char >, ext > variant
Definition msgpack_variant.hpp:269
bool operator<(basic_variant< STR, BIN, EXT > const &lhs, basic_variant< STR, BIN, EXT > const &rhs)
Definition msgpack_variant.hpp:256
basic_variant< std::string, raw_ref, ext_ref > variant_ref
Definition msgpack_variant.hpp:276
bool operator==(basic_variant< STR, BIN, EXT > const &lhs, basic_variant< STR, BIN, EXT > const &rhs)
Definition msgpack_variant.hpp:263
Definition adaptor_base.hpp:15
msgpack::object const & operator()(msgpack::object const &o, T &v) const
Definition object.hpp:646
Definition msgpack_variant.hpp:388
void operator()(uint64_t const &v) const
Definition msgpack_variant.hpp:395
void operator()(bool const &v) const
Definition msgpack_variant.hpp:392
object_imp(msgpack::object &o)
Definition msgpack_variant.hpp:408
void operator()(int64_t const &v) const
Definition msgpack_variant.hpp:398
msgpack::object & o_
Definition msgpack_variant.hpp:409
void operator()(T const &) const
Definition msgpack_variant.hpp:405
void operator()(double const &v) const
Definition msgpack_variant.hpp:401
void operator()(msgpack::type::nil_t const &v) const
Definition msgpack_variant.hpp:389
Definition msgpack_variant.hpp:423
msgpack::object::with_zone & o_
Definition msgpack_variant.hpp:429
object_with_zone_imp(msgpack::object::with_zone &o)
Definition msgpack_variant.hpp:428
void operator()(T const &v) const
Definition msgpack_variant.hpp:425
Definition msgpack_variant.hpp:366
pack_imp(packer< Stream > &o)
Definition msgpack_variant.hpp:371
packer< Stream > & o_
Definition msgpack_variant.hpp:372
void operator()(T const &value) const
Definition msgpack_variant.hpp:368
Definition adaptor_base.hpp:43
void operator()(msgpack::object::with_zone &o, T const &v) const
Definition object.hpp:662
Definition adaptor_base.hpp:38
void operator()(msgpack::object &o, T const &v) const
Definition adaptor_base.hpp:32
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, T const &v) const
Definition object.hpp:655
Definition object.hpp:35
Object class that corresponding to MessagePack format object.
Definition object_fwd.hpp:75
std::enable_if< msgpack::has_as< T >::value, T >::type as() const
Get value as T.
Definition object.hpp:1126
msgpack::type::object_type type
Definition object_fwd.hpp:92
Definition msgpack_variant.hpp:72
bool is_map() const
Definition msgpack_variant.hpp:173
boost::variant< nil_t, bool, int64_t, uint64_t, double, std::string, std::vector< char >, msgpack::type::raw_ref, msgpack::type::ext, msgpack::type::ext_ref, boost::recursive_wrapper< std::vector< basic_variant< STR, BIN, EXT > > >, boost::recursive_wrapper< std::map< basic_variant< STR, BIN, EXT >, basic_variant< STR, BIN, EXT > > >, boost::recursive_wrapper< std::multimap< basic_variant< STR, BIN, EXT >, basic_variant< STR, BIN, EXT > > > > base
Definition msgpack_variant.hpp:90
bool is_raw_ref() const
Definition msgpack_variant.hpp:161
double as_double() const
Definition msgpack_variant.hpp:189
ext const & as_ext() const
Definition msgpack_variant.hpp:215
std::vector< basic_variant< STR, BIN, EXT > > const & as_vector() const
Definition msgpack_variant.hpp:221
bool is_ext_ref() const
Definition msgpack_variant.hpp:167
bool is_string() const
Definition msgpack_variant.hpp:147
bool is_int64_t() const
Definition msgpack_variant.hpp:138
bool is_vector_char()
Definition msgpack_variant.hpp:158
bool is_vector() const
Definition msgpack_variant.hpp:170
bool as_bool() const
Definition msgpack_variant.hpp:180
std::multimap< basic_variant< STR, BIN, EXT >, basic_variant< STR, BIN, EXT > > const & as_multimap() const
Definition msgpack_variant.hpp:227
bool is_vector_char() const
Definition msgpack_variant.hpp:155
basic_variant(unsigned char v)
Definition msgpack_variant.hpp:112
basic_variant(signed int v)
Definition msgpack_variant.hpp:113
int64_t as_int64_t() const
Definition msgpack_variant.hpp:183
basic_variant(unsigned long long v)
Definition msgpack_variant.hpp:124
ext_ref const & as_ext_ref() const
Definition msgpack_variant.hpp:218
std::string const & as_string() const
Definition msgpack_variant.hpp:201
uint64_t as_uint64_t() const
Definition msgpack_variant.hpp:186
bool is_ext() const
Definition msgpack_variant.hpp:164
basic_variant(float v)
Definition msgpack_variant.hpp:125
basic_variant(signed long long v)
Definition msgpack_variant.hpp:121
bool is_uint64_t() const
Definition msgpack_variant.hpp:141
bool is_nil() const
Definition msgpack_variant.hpp:132
std::map< basic_variant< STR, BIN, EXT >, basic_variant< STR, BIN, EXT > > const & as_map() const
Definition msgpack_variant.hpp:224
basic_variant(unsigned long v)
Definition msgpack_variant.hpp:120
bool is_double() const
Definition msgpack_variant.hpp:144
basic_variant(signed long v)
Definition msgpack_variant.hpp:117
bool is_multimap() const
Definition msgpack_variant.hpp:176
basic_variant(T const &t)
Definition msgpack_variant.hpp:93
basic_variant(char const *p)
Definition msgpack_variant.hpp:105
raw_ref const & as_raw_ref() const
Definition msgpack_variant.hpp:212
basic_variant(unsigned int v)
Definition msgpack_variant.hpp:116
bool is_bool() const
Definition msgpack_variant.hpp:135
basic_variant(char v)
Definition msgpack_variant.hpp:106
basic_variant(signed char v)
Definition msgpack_variant.hpp:109
basic_variant(double v)
Definition msgpack_variant.hpp:128
basic_variant()
Definition msgpack_variant.hpp:91
std::vector< char > const & as_vector_char() const
Definition msgpack_variant.hpp:209
Definition nil.hpp:23
Definition raw.hpp:26
#define MSGPACK_NULLPTR
Definition cpp_config_decl.hpp:85
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition versioning.hpp:66