MessagePack for C++
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>
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
126 bool is_nil() const {
127 return boost::get<msgpack::type::nil_t>(this) != MSGPACK_NULLPTR;
128 }
129 bool is_bool() const {
130 return boost::get<bool>(this) != MSGPACK_NULLPTR;
131 }
132 bool is_int64_t() const {
133 return boost::get<int64_t>(this) != MSGPACK_NULLPTR;
134 }
135 bool is_uint64_t() const {
136 return boost::get<uint64_t>(this) != MSGPACK_NULLPTR;
137 }
138 bool is_double() const {
139 return boost::get<double>(this) != MSGPACK_NULLPTR;
140 }
141 bool is_string() const {
142 return boost::get<std::string>(this) != MSGPACK_NULLPTR;
143 }
144#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
145 bool is_boost_string_ref() const {
146 return boost::get<boost::string_ref>(this) != MSGPACK_NULLPTR;
147 }
148#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
149 bool is_vector_char() const {
150 return boost::get<std::vector<char> >(this) != MSGPACK_NULLPTR;
151 }
153 return boost::get<std::vector<char> >(this) != MSGPACK_NULLPTR;
154 }
155 bool is_raw_ref() const {
156 return boost::get<raw_ref>(this) != MSGPACK_NULLPTR;
157 }
158 bool is_ext() const {
159 return boost::get<ext>(this) != MSGPACK_NULLPTR;
160 }
161 bool is_ext_ref() const {
162 return boost::get<ext_ref>(this) != MSGPACK_NULLPTR;
163 }
164 bool is_vector() const {
165 return boost::get<std::vector<basic_variant<STR, BIN, EXT> > >(this) != MSGPACK_NULLPTR;
166 }
167 bool is_map() const {
168 return boost::get<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(this) != MSGPACK_NULLPTR;
169 }
170 bool is_multimap() const {
171 return boost::get<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(this) != MSGPACK_NULLPTR;
172 }
173
174 bool as_bool() const {
175 return boost::get<bool>(*this);
176 }
177 int64_t as_int64_t() const {
178 return boost::get<int64_t>(*this);
179 }
180 int64_t& as_int64_t() {
181 return boost::get<int64_t>(*this);
182 }
183 uint64_t as_uint64_t() const {
184 return boost::get<uint64_t>(*this);
185 }
186 uint64_t& as_uint64_t() {
187 return boost::get<uint64_t>(*this);
188 }
189 double as_double() const {
190 return boost::get<double>(*this);
191 }
192 double& as_double() {
193 return boost::get<double>(*this);
194 }
195 std::string const& as_string() const {
196 return boost::get<std::string>(*this);
197 }
198 std::string& as_string() {
199 return boost::get<std::string>(*this);
200 }
201#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
202 boost::string_ref const& as_boost_string_ref() const {
203 return boost::get<boost::string_ref>(*this);
204 }
205 boost::string_ref& as_boost_string_ref() {
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 std::vector<char>& as_vector_char() {
213 return boost::get<std::vector<char> >(*this);
214 }
215 raw_ref const& as_raw_ref() const {
216 return boost::get<raw_ref>(*this);
217 }
218 ext const& as_ext() const {
219 return boost::get<ext>(*this);
220 }
222 return boost::get<ext>(*this);
223 }
224 ext_ref const& as_ext_ref() const {
225 return boost::get<ext_ref>(*this);
226 }
227 std::vector<basic_variant<STR, BIN, EXT> > const& as_vector() const {
228 return boost::get<std::vector<basic_variant<STR, BIN, EXT> > >(*this);
229 }
230 std::vector<basic_variant<STR, BIN, EXT> >& as_vector() {
231 return boost::get<std::vector<basic_variant<STR, BIN, EXT> > >(*this);
232 }
233 std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > const& as_map() const {
234 return boost::get<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
235 }
236 std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> >& as_map() {
237 return boost::get<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
238 }
239 std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > const& as_multimap() const {
240 return boost::get<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
241 }
242 std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> >& as_multimap() {
243 return boost::get<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
244 }
245private:
246 template <typename T>
247 void int_init(T v) {
248 if (v < 0) {
249 static_cast<base&>(*this) = int64_t(v);
250 }
251 else {
252 static_cast<base&>(*this) = uint64_t(v);
253 }
254 }
255};
256
257template <typename STR, typename BIN, typename EXT>
259 return
260 static_cast<typename basic_variant<STR, BIN, EXT>::base const&>(lhs) <
261 static_cast<typename basic_variant<STR, BIN, EXT>::base const&>(rhs);
262}
263
264template <typename STR, typename BIN, typename EXT>
266 return
267 static_cast<typename basic_variant<STR, BIN, EXT>::base const&>(lhs) ==
268 static_cast<typename basic_variant<STR, BIN, EXT>::base const&>(rhs);
269}
270
272typedef basic_variant<
273#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
274 boost::string_ref,
275#else // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
276 std::string,
277#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
279
280} // namespace type
281
282namespace adaptor {
283
284#if !defined (MSGPACK_USE_CPP03)
285
286template <typename STR, typename BIN, typename EXT>
287struct as<type::basic_variant<STR, BIN, EXT> > {
289 switch(o.type) {
290 case type::NIL:
291 return o.as<msgpack::type::nil_t>();
292 case type::BOOLEAN:
293 return o.as<bool>();
295 return o.as<uint64_t>();
297 return o.as<int64_t>();
298 case type::FLOAT32:
299 case type::FLOAT64:
300 return o.as<double>();
301 case type::STR:
302 return o.as<STR>();
303 case type::BIN:
304 return o.as<BIN>();
305 case type::EXT:
306 return o.as<EXT>();
307 case type::ARRAY:
308 return o.as<std::vector<type::basic_variant<STR, BIN, EXT> > >();
309 case type::MAP:
310 return o.as<std::multimap<type::basic_variant<STR, BIN, EXT>, type::basic_variant<STR, BIN, EXT> > >();
311 default:
312 break;
313 }
315 }
316};
317
318#endif // !defined (MSGPACK_USE_CPP03)
319
320
321template <typename STR, typename BIN, typename EXT>
322struct convert<type::basic_variant<STR, BIN, EXT> > {
324 msgpack::object const& o,
326 switch(o.type) {
327 case type::NIL:
328 v = o.as<msgpack::type::nil_t>();
329 break;
330 case type::BOOLEAN:
331 v = o.as<bool>();
332 break;
334 v = o.as<uint64_t>();
335 break;
337 v = o.as<int64_t>();
338 break;
339 case type::FLOAT32:
340 case type::FLOAT64:
341 v = o.as<double>();
342 break;
343 case type::STR:
344 v = o.as<STR>();
345 break;
346 case type::BIN:
347 v = o.as<BIN>();
348 break;
349 case type::EXT:
350 v = o.as<EXT>();
351 break;
352 case type::ARRAY:
353 v = o.as<std::vector<type::basic_variant<STR, BIN, EXT> > >();
354 break;
355 case type::MAP:
356 v = o.as<std::multimap<type::basic_variant<STR, BIN, EXT>, type::basic_variant<STR, BIN, EXT> > >();
357 break;
358 default:
359 break;
360 }
361 return o;
362 }
363};
364
365namespace detail {
366
367template <typename Stream>
368struct pack_imp : boost::static_visitor<void> {
369 template <typename T>
370 void operator()(T const& value) const {
371 pack<T>()(o_, value);
372 }
375};
376
377} // namespace detail
378
379template <typename STR, typename BIN, typename EXT>
380struct pack<type::basic_variant<STR, BIN, EXT> > {
381 template <typename Stream>
383 boost::apply_visitor(detail::pack_imp<Stream>(o), v);
384 return o;
385 }
386};
387
388namespace detail {
389
390struct object_imp : boost::static_visitor<void> {
391 void operator()(msgpack::type::nil_t const& v) const {
393 }
394 void operator()(bool const& v) const {
395 object<bool>()(o_, v);
396 }
397 void operator()(uint64_t const& v) const {
398 object<uint64_t>()(o_, v);
399 }
400 void operator()(int64_t const& v) const {
401 object<int64_t>()(o_, v);
402 }
403 void operator()(double const& v) const {
404 object<double>()(o_, v);
405 }
406 template <typename T>
407 void operator()(T const&) const {
408 throw msgpack::type_error();
409 }
412};
413
414} // namespace detail
415
416template <typename STR, typename BIN, typename EXT>
417struct object<type::basic_variant<STR, BIN, EXT> > {
419 boost::apply_visitor(detail::object_imp(o), v);
420 }
421};
422
423namespace detail {
424
425struct object_with_zone_imp : boost::static_visitor<void> {
426 template <typename T>
427 void operator()(T const& v) const {
429 }
432};
433
434} // namespace detail
435
436template <typename STR, typename BIN, typename EXT>
437struct object_with_zone<type::basic_variant<STR, BIN, EXT> > {
439 boost::apply_visitor(detail::object_with_zone_imp(o), v);
440 }
441};
442
443} // namespace adaptor
444
446} // MSGPACK_API_VERSION_NAMESPACE(v1)
448
449} // namespace msgpack
450
451#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:271
bool operator<(basic_variant< STR, BIN, EXT > const &lhs, basic_variant< STR, BIN, EXT > const &rhs)
Definition: msgpack_variant.hpp:258
basic_variant< std::string, raw_ref, ext_ref > variant_ref
Definition: msgpack_variant.hpp:278
@ EXT
Definition: object_fwd_decl.hpp:42
@ FLOAT64
Definition: object_fwd_decl.hpp:33
@ BOOLEAN
Definition: object_fwd_decl.hpp:29
@ MAP
Definition: object_fwd_decl.hpp:41
@ NIL
Definition: object_fwd_decl.hpp:28
@ STR
Definition: object_fwd_decl.hpp:38
@ ARRAY
Definition: object_fwd_decl.hpp:40
@ BIN
Definition: object_fwd_decl.hpp:39
@ POSITIVE_INTEGER
Definition: object_fwd_decl.hpp:30
@ NEGATIVE_INTEGER
Definition: object_fwd_decl.hpp:31
@ FLOAT32
Definition: object_fwd_decl.hpp:32
bool operator==(basic_variant< STR, BIN, EXT > const &lhs, basic_variant< STR, BIN, EXT > const &rhs)
Definition: msgpack_variant.hpp:265
Definition: adaptor_base.hpp:15
type::basic_variant< STR, BIN, EXT > operator()(msgpack::object const &o) const
Definition: msgpack_variant.hpp:288
Definition: object_fwd_decl.hpp:61
msgpack::object const & operator()(msgpack::object const &o, type::basic_variant< STR, BIN, EXT > &v) const
Definition: msgpack_variant.hpp:323
Definition: adaptor_base.hpp:27
Definition: msgpack_variant.hpp:390
void operator()(uint64_t const &v) const
Definition: msgpack_variant.hpp:397
void operator()(bool const &v) const
Definition: msgpack_variant.hpp:394
object_imp(msgpack::object &o)
Definition: msgpack_variant.hpp:410
void operator()(int64_t const &v) const
Definition: msgpack_variant.hpp:400
msgpack::object & o_
Definition: msgpack_variant.hpp:411
void operator()(T const &) const
Definition: msgpack_variant.hpp:407
void operator()(double const &v) const
Definition: msgpack_variant.hpp:403
void operator()(msgpack::type::nil_t const &v) const
Definition: msgpack_variant.hpp:391
Definition: msgpack_variant.hpp:425
msgpack::object::with_zone & o_
Definition: msgpack_variant.hpp:431
object_with_zone_imp(msgpack::object::with_zone &o)
Definition: msgpack_variant.hpp:430
void operator()(T const &v) const
Definition: msgpack_variant.hpp:427
Definition: msgpack_variant.hpp:368
pack_imp(packer< Stream > &o)
Definition: msgpack_variant.hpp:373
packer< Stream > & o_
Definition: msgpack_variant.hpp:374
void operator()(T const &value) const
Definition: msgpack_variant.hpp:370
Definition: bool.hpp:45
Definition: float.hpp:94
void operator()(msgpack::object &o, const type::basic_variant< STR, BIN, EXT > &v) const
Definition: msgpack_variant.hpp:418
void operator()(msgpack::object::with_zone &o, const type::basic_variant< STR, BIN, EXT > &v) const
Definition: msgpack_variant.hpp:438
Definition: adaptor_base.hpp:43
Definition: adaptor_base.hpp:38
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const type::basic_variant< STR, BIN, EXT > &v) const
Definition: msgpack_variant.hpp:382
Definition: adaptor_base.hpp:32
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:167
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:155
std::vector< basic_variant< STR, BIN, EXT > > & as_vector()
Definition: msgpack_variant.hpp:230
std::multimap< basic_variant< STR, BIN, EXT >, basic_variant< STR, BIN, EXT > > & as_multimap()
Definition: msgpack_variant.hpp:242
double as_double() const
Definition: msgpack_variant.hpp:189
std::map< basic_variant< STR, BIN, EXT >, basic_variant< STR, BIN, EXT > > & as_map()
Definition: msgpack_variant.hpp:236
ext const & as_ext() const
Definition: msgpack_variant.hpp:218
std::string & as_string()
Definition: msgpack_variant.hpp:198
std::vector< basic_variant< STR, BIN, EXT > > const & as_vector() const
Definition: msgpack_variant.hpp:227
bool is_ext_ref() const
Definition: msgpack_variant.hpp:161
bool is_string() const
Definition: msgpack_variant.hpp:141
bool is_int64_t() const
Definition: msgpack_variant.hpp:132
double & as_double()
Definition: msgpack_variant.hpp:192
bool is_vector_char()
Definition: msgpack_variant.hpp:152
bool is_vector() const
Definition: msgpack_variant.hpp:164
bool as_bool() const
Definition: msgpack_variant.hpp:174
std::multimap< basic_variant< STR, BIN, EXT >, basic_variant< STR, BIN, EXT > > const & as_multimap() const
Definition: msgpack_variant.hpp:239
bool is_vector_char() const
Definition: msgpack_variant.hpp:149
basic_variant(unsigned char v)
Definition: msgpack_variant.hpp:112
uint64_t & as_uint64_t()
Definition: msgpack_variant.hpp:186
basic_variant(signed int v)
Definition: msgpack_variant.hpp:113
ext & as_ext()
Definition: msgpack_variant.hpp:221
int64_t as_int64_t() const
Definition: msgpack_variant.hpp:177
basic_variant(unsigned long long v)
Definition: msgpack_variant.hpp:124
ext_ref const & as_ext_ref() const
Definition: msgpack_variant.hpp:224
std::string const & as_string() const
Definition: msgpack_variant.hpp:195
uint64_t as_uint64_t() const
Definition: msgpack_variant.hpp:183
bool is_ext() const
Definition: msgpack_variant.hpp:158
basic_variant(signed long long v)
Definition: msgpack_variant.hpp:121
bool is_uint64_t() const
Definition: msgpack_variant.hpp:135
bool is_nil() const
Definition: msgpack_variant.hpp:126
std::map< basic_variant< STR, BIN, EXT >, basic_variant< STR, BIN, EXT > > const & as_map() const
Definition: msgpack_variant.hpp:233
int64_t & as_int64_t()
Definition: msgpack_variant.hpp:180
basic_variant(unsigned long v)
Definition: msgpack_variant.hpp:120
bool is_double() const
Definition: msgpack_variant.hpp:138
basic_variant(signed long v)
Definition: msgpack_variant.hpp:117
bool is_multimap() const
Definition: msgpack_variant.hpp:170
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:215
basic_variant(unsigned int v)
Definition: msgpack_variant.hpp:116
bool is_bool() const
Definition: msgpack_variant.hpp:129
basic_variant(char v)
Definition: msgpack_variant.hpp:106
basic_variant(signed char v)
Definition: msgpack_variant.hpp:109
basic_variant()
Definition: msgpack_variant.hpp:91
std::vector< char > & as_vector_char()
Definition: msgpack_variant.hpp:212
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