MessagePack for C++
Loading...
Searching...
No Matches
x3_parse.hpp
Go to the documentation of this file.
1//
2// MessagePack for C++ deserializing routine
3//
4// Copyright (C) 2017 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_V2_X3_PARSE_HPP
11#define MSGPACK_V2_X3_PARSE_HPP
12
13#if defined(MSGPACK_USE_X3_PARSE)
14
15#include <boost/version.hpp>
16
17#if BOOST_VERSION >= 106100
18
21
22#if __GNUC__ >= 4
23#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-Wunused-parameter"
25#pragma GCC diagnostic ignored "-Wconversion"
26#endif // __GNUC__ >= 4
27
28#include <boost/config/warning_disable.hpp>
29#include <boost/spirit/home/x3.hpp>
30#include <boost/spirit/home/x3/binary.hpp>
31
32namespace msgpack {
33
37
38namespace detail {
39
40namespace x3 = boost::spirit::x3;
41
42using x3::byte_;
43
44// byte range utility
45const auto byte_range = [](const std::uint8_t from, const std::uint8_t to) {
46 const auto check = [from, to](auto& ctx)
47 {
48 const std::uint8_t value = x3::_attr(ctx);
49 x3::_val(ctx) = value;
50 x3::_pass(ctx) = from <= value && value <= to;
51 };
52 return x3::byte_ [check];
53};
54
55// MessagePack rule
56const auto mp_positive_fixint = byte_range(0x00, 0x7f);
57const auto mp_fixmap = byte_range(0x80, 0x8f);
58const auto mp_fixarray = byte_range(0x90, 0x9f);
59const auto mp_fixstr = byte_range(0xa0, 0xbf);
60const auto mp_nil = x3::byte_(0xc0);
61const auto mp_false = x3::byte_(0xc2);
62const auto mp_true = x3::byte_(0xc3);
63const auto mp_bin8 = x3::byte_(0xc4);
64const auto mp_bin16 = x3::byte_(0xc5);
65const auto mp_bin32 = x3::byte_(0xc6);
66const auto mp_ext8 = x3::byte_(0xc7);
67const auto mp_ext16 = x3::byte_(0xc8);
68const auto mp_ext32 = x3::byte_(0xc9);
69const auto mp_float32 = x3::byte_(0xca);
70const auto mp_float64 = x3::byte_(0xcb);
71const auto mp_uint8 = x3::byte_(0xcc);
72const auto mp_uint16 = x3::byte_(0xcd);
73const auto mp_uint32 = x3::byte_(0xce);
74const auto mp_uint64 = x3::byte_(0xcf);
75const auto mp_int8 = x3::byte_(0xd0);
76const auto mp_int16 = x3::byte_(0xd1);
77const auto mp_int32 = x3::byte_(0xd2);
78const auto mp_int64 = x3::byte_(0xd3);
79const auto mp_fixext1 = x3::byte_(0xd4);
80const auto mp_fixext2 = x3::byte_(0xd5);
81const auto mp_fixext4 = x3::byte_(0xd6);
82const auto mp_fixext8 = x3::byte_(0xd7);
83const auto mp_fixext16 = x3::byte_(0xd8);
84const auto mp_str8 = x3::byte_(0xd9);
85const auto mp_str16 = x3::byte_(0xda);
86const auto mp_str32 = x3::byte_(0xdb);
87const auto mp_array16 = x3::byte_(0xdc);
88const auto mp_array32 = x3::byte_(0xdd);
89const auto mp_map16 = x3::byte_(0xde);
90const auto mp_map32 = x3::byte_(0xdf);
91const auto mp_negative_fixint = byte_range(0xe0, 0xff);
92
93const auto mp_d_uint8 = x3::byte_;
94const auto mp_d_uint16 = x3::big_word;
95const auto mp_d_uint32 = x3::big_dword;
96const auto mp_d_uint64 = x3::big_qword;
97
98const auto mp_d_int8 = x3::byte_;
99const auto mp_d_int16 = x3::big_word;
100const auto mp_d_int32 = x3::big_dword;
101const auto mp_d_int64 = x3::big_qword;
102
103x3::rule<class mp_object> const mp_object("mp_object");
104x3::rule<class array_items> const array_item("array_item");
105x3::rule<class map_items> const map_item("map_item");
106x3::rule<class kv> const kv("kv");
107
108struct tag_app_specific {};
109struct index_size {
110 enum struct type_t {
111 array,
112 map,
113 other
114 };
115 index_size(std::size_t size, type_t type = type_t::other):size(size), type(type) {}
116 std::size_t index = 0;
117 std::size_t size;
118 type_t type;
119};
120
121template <typename Visitor>
122struct app_specific {
123 template <typename Vis>
124 app_specific(Vis&& vis):vis(vis) {}
125 std::vector<index_size> index_sizes;
126 Visitor vis;
127};
128
129template <typename Visitor>
130app_specific<Visitor> make_app_specific(Visitor&& vis) {
131 return app_specific<Visitor>(std::forward<Visitor>(vis));
132}
133
134const auto more = [](auto &ctx) {
135 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
136 _pass(ctx) = app_specific.index_sizes.back().index++ < app_specific.index_sizes.back().size;
137};
138
139const auto done = [](auto &ctx) {
140 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
141 if (app_specific.index_sizes.back().index == app_specific.index_sizes.back().size + 1) {
142 _pass(ctx) = true;
143 switch (app_specific.index_sizes.back().type) {
144 case index_size::type_t::array:
145 app_specific.vis.end_array();
146 break;
147 case index_size::type_t::map:
148 app_specific.vis.end_map();
149 break;
150 case index_size::type_t::other:
151 break;
152 }
153 app_specific.index_sizes.pop_back();
154 }
155 else {
156 _pass(ctx) = false;
157 }
158};
159
160const auto mp_object_def =
161 // -----------------------------------------------
162 mp_nil [
163 (
164 [](auto& ctx){
165 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
166 app_specific.vis.visit_nil();
167 }
168 )
169 ]
170 |
171 // -----------------------------------------------
172 mp_true [
173 (
174 [](auto& ctx){
175 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
176 app_specific.vis.visit_boolean(true);
177 }
178 )
179 ]
180 |
181 // -----------------------------------------------
182 mp_false [
183 (
184 [](auto& ctx){
185 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
186 app_specific.vis.visit_boolean(false);
187 }
188 )
189 ]
190 |
191 // -----------------------------------------------
192 mp_positive_fixint [
193 (
194 [](auto& ctx){
195 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
196 app_specific.vis.visit_positive_integer(_attr(ctx));
197 }
198 )
199 ]
200 |
201 // -----------------------------------------------
202 mp_negative_fixint [
203 (
204 [](auto& ctx){
205 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
206 std::int8_t val = static_cast<std::int8_t>(_attr(ctx));
207 app_specific.vis.visit_negative_integer(val);
208 }
209 )
210 ]
211 |
212 // -----------------------------------------------
213 mp_uint8 >> mp_d_uint8 [
214 (
215 [](auto& ctx){
216 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
217 app_specific.vis.visit_negative_integer(_attr(ctx));
218 }
219 )
220 ]
221 |
222 // -----------------------------------------------
223 mp_uint16 >> mp_d_uint16 [
224 (
225 [](auto& ctx){
226 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
227 app_specific.vis.visit_positive_integer(_attr(ctx));
228 }
229 )
230 ]
231 |
232 // -----------------------------------------------
233 mp_uint32 >> mp_d_uint32 [
234 (
235 [](auto& ctx){
236 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
237 app_specific.vis.visit_positive_integer(_attr(ctx));
238 }
239 )
240 ]
241 |
242 // -----------------------------------------------
243 mp_uint64 >> mp_d_uint64 [
244 (
245 [](auto& ctx){
246 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
247 app_specific.vis.visit_positive_integer(_attr(ctx));
248 }
249 )
250 ]
251 |
252 // -----------------------------------------------
253 mp_int8 >> mp_d_int8 [
254 (
255 [](auto& ctx){
256 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
257 std::int8_t val = static_cast<std::int8_t>(_attr(ctx));
258 app_specific.vis.visit_negative_integer(val);
259 }
260 )
261 ]
262 |
263 // -----------------------------------------------
264 mp_int16 >> mp_d_int16 [
265 (
266 [](auto& ctx){
267 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
268 std::int16_t val = static_cast<std::int16_t>(_attr(ctx));
269 app_specific.vis.visit_negative_integer(val);
270 }
271 )
272 ]
273 |
274 // -----------------------------------------------
275 mp_int32 >> mp_d_int32 [
276 (
277 [](auto& ctx){
278 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
279 std::int32_t val = static_cast<std::int32_t>(_attr(ctx));
280 app_specific.vis.visit_negative_integer(val);
281 }
282 )
283 ]
284 |
285 // -----------------------------------------------
286 mp_int64 >> mp_d_int64 [
287 (
288 [](auto& ctx){
289 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
290 std::int64_t val = static_cast<std::int64_t>(_attr(ctx));
291 app_specific.vis.visit_negative_integer(val);
292 }
293 )
294 ]
295 |
296 // -----------------------------------------------
297 mp_float32 >> mp_d_uint32 [
298 (
299 [](auto& ctx){
300 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
301 union { uint32_t i; float f; } mem = { _attr(ctx) };
302 app_specific.vis.visit_float32(mem.f);
303 }
304 )
305 ]
306 |
307 // -----------------------------------------------
308 mp_float64 >> mp_d_uint64 [
309 (
310 [](auto& ctx){
311 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
312 union { uint64_t i; double f; } mem = { _attr(ctx) };
313#if defined(TARGET_OS_IPHONE)
314 // ok
315#elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
316 // https://github.com/msgpack/msgpack-perl/pull/1
317 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
318#endif
319 app_specific.vis.visit_float64(mem.f);
320 }
321 )
322 ]
323 |
324 // -----------------------------------------------
325 mp_fixstr [
326 (
327 [](auto& ctx){
328 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
329 std::size_t size = _attr(ctx) & 0b00011111;
330 app_specific.index_sizes.emplace_back(size);
331 }
332 )
333 ]
334 >>
335 x3::raw [
336 *(x3::eps [more] >> x3::char_)
337 >> x3::eps [done]
338 ][
339 (
340 [](auto& ctx){
341 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
342 auto const& str = _attr(ctx);
343 auto size = static_cast<uint32_t>(std::distance(str.begin(), str.end()));
344 app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
345 }
346 )
347 ]
348 |
349 // -----------------------------------------------
350 mp_str8 >> mp_d_uint8 [
351 (
352 [](auto& ctx){
353 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
354 app_specific.index_sizes.emplace_back(_attr(ctx));
355 }
356 )
357 ]
358 >>
359 x3::raw [
360 *(x3::eps [more] >> x3::char_)
361 >> x3::eps [done]
362 ][
363 (
364 [](auto& ctx){
365 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
366 auto const& str = _attr(ctx);
367 auto size = static_cast<uint32_t>(std::distance(str.begin(), str.end()));
368 app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
369 }
370 )
371 ]
372 |
373 // -----------------------------------------------
374 mp_str16 >> mp_d_uint16 [
375 (
376 [](auto& ctx){
377 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
378 app_specific.index_sizes.emplace_back(_attr(ctx));
379 }
380 )
381 ]
382 >>
383 x3::raw [
384 *(x3::eps [more] >> x3::char_)
385 >> x3::eps [done]
386 ][
387 (
388 [](auto& ctx){
389 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
390 auto const& str = _attr(ctx);
391 auto size = static_cast<uint32_t>(std::distance(str.begin(), str.end()));
392 app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
393 }
394 )
395 ]
396 |
397 // -----------------------------------------------
398 mp_str32 >> mp_d_uint32 [
399 (
400 [](auto& ctx){
401 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
402 app_specific.index_sizes.emplace_back(_attr(ctx));
403 }
404 )
405 ]
406 >>
407 x3::raw [
408 *(x3::eps [more] >> x3::char_)
409 >> x3::eps [done]
410 ][
411 (
412 [](auto& ctx){
413 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
414 auto const& str = _attr(ctx);
415 auto size = static_cast<uint32_t>(std::distance(str.begin(), str.end()));
416 app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
417 }
418 )
419 ]
420 |
421 // -----------------------------------------------
422 mp_bin8 >> mp_d_uint8 [
423 (
424 [](auto& ctx){
425 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
426 app_specific.index_sizes.emplace_back(_attr(ctx));
427 }
428 )
429 ]
430 >>
431 x3::raw [
432 *(x3::eps [more] >> x3::char_)
433 >> x3::eps [done]
434 ][
435 (
436 [](auto& ctx){
437 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
438 auto const& bin = _attr(ctx);
439 auto size = static_cast<uint32_t>(std::distance(bin.begin(), bin.end()));
440 app_specific.vis.visit_bin(size ? &bin.front() : nullptr, size);
441 }
442 )
443 ]
444 |
445 // -----------------------------------------------
446 mp_bin16 >> mp_d_uint16 [
447 (
448 [](auto& ctx){
449 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
450 app_specific.index_sizes.emplace_back(_attr(ctx));
451 }
452 )
453 ]
454 >>
455 x3::raw [
456 *(x3::eps [more] >> x3::char_)
457 >> x3::eps [done]
458 ][
459 (
460 [](auto& ctx){
461 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
462 auto const& bin = _attr(ctx);
463 auto size = static_cast<uint32_t>(std::distance(bin.begin(), bin.end()));
464 app_specific.vis.visit_bin(size ? &bin.front() : nullptr, size);
465 }
466 )
467 ]
468 |
469 // -----------------------------------------------
470 mp_bin32 >> mp_d_uint32 [
471 (
472 [](auto& ctx){
473 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
474 app_specific.index_sizes.emplace_back(_attr(ctx));
475 }
476 )
477 ]
478 >>
479 x3::raw [
480 *(x3::eps [more] >> x3::char_)
481 >> x3::eps [done]
482 ][
483 (
484 [](auto& ctx){
485 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
486 auto const& bin = _attr(ctx);
487 auto size = static_cast<uint32_t>(std::distance(bin.begin(), bin.end()));
488 app_specific.vis.visit_bin(size ? &bin.front() : nullptr, size);
489 }
490 )
491 ]
492 |
493 // -----------------------------------------------
494 mp_fixarray [
495 (
496 [](auto& ctx){
497 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
498 uint32_t size = _attr(ctx) & 0b00001111;
499 app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
500 app_specific.vis.start_array(size);
501 }
502 )
503 ]
504 >> *(x3::eps [more] >> array_item)
505 >> x3::eps [done]
506 |
507 // -----------------------------------------------
508 mp_array16 >> mp_d_uint16 [
509 (
510 [](auto& ctx){
511 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
512 uint32_t size = _attr(ctx);
513 app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
514 app_specific.vis.start_array(size);
515 }
516 )
517 ]
518 >> *(x3::eps [more] >> array_item)
519 >> x3::eps [done]
520 |
521 // -----------------------------------------------
522 mp_array32 >> mp_d_uint32 [
523 (
524 [](auto& ctx){
525 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
526 uint32_t size = _attr(ctx);
527 app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
528 app_specific.vis.start_array(size);
529 }
530 )
531 ]
532 >> *(x3::eps [more] >> array_item)
533 >> x3::eps [done]
534 |
535 // -----------------------------------------------
536 mp_fixmap [
537 (
538 [](auto& ctx){
539 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
540 uint32_t size = _attr(ctx) & 0b00001111;
541 app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
542 app_specific.vis.start_map(size);
543 }
544 )
545 ]
546 >> *(x3::eps [more] >> map_item)
547 >> x3::eps [done]
548 |
549 // -----------------------------------------------
550 mp_map16 >> mp_d_uint16 [
551 (
552 [](auto& ctx){
553 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
554 uint32_t size = _attr(ctx);
555 app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
556 app_specific.vis.start_map(size);
557 }
558 )
559 ]
560 >> *(x3::eps [more] >> map_item)
561 >> x3::eps [done]
562 |
563 // -----------------------------------------------
564 mp_map32 >> mp_d_uint32 [
565 (
566 [](auto& ctx){
567 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
568 uint32_t size = _attr(ctx);
569 app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
570 app_specific.vis.start_map(size);
571 }
572 )
573 ]
574 >> *(x3::eps [more] >> map_item)
575 >> x3::eps [done]
576 |
577 // -----------------------------------------------
578 mp_fixext1 [
579 (
580 [](auto& ctx){
581 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
582 app_specific.index_sizes.emplace_back(1+1);
583 }
584 )
585 ]
586 >>
587 x3::raw [
588 *(x3::eps [more] >> x3::char_)
589 >> x3::eps [done]
590 ][
591 (
592 [](auto& ctx){
593 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
594 auto const& ext = _attr(ctx);
595 auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
596 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
597 }
598 )
599 ]
600 |
601 // -----------------------------------------------
602 mp_fixext2 [
603 (
604 [](auto& ctx){
605 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
606 app_specific.index_sizes.emplace_back(2+1);
607 }
608 )
609 ]
610 >>
611 x3::raw [
612 *(x3::eps [more] >> x3::char_)
613 >> x3::eps [done]
614 ][
615 (
616 [](auto& ctx){
617 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
618 auto const& ext = _attr(ctx);
619 auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
620 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
621 }
622 )
623 ]
624 |
625 // -----------------------------------------------
626 mp_fixext4 [
627 (
628 [](auto& ctx){
629 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
630 app_specific.index_sizes.emplace_back(4+1);
631 }
632 )
633 ]
634 >>
635 x3::raw [
636 *(x3::eps [more] >> x3::char_)
637 >> x3::eps [done]
638 ][
639 (
640 [](auto& ctx){
641 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
642 auto const& ext = _attr(ctx);
643 auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
644 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
645 }
646 )
647 ]
648 |
649 // -----------------------------------------------
650 mp_fixext8 [
651 (
652 [](auto& ctx){
653 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
654 app_specific.index_sizes.emplace_back(8+1);
655 }
656 )
657 ]
658 >>
659 x3::raw [
660 *(x3::eps [more] >> x3::char_)
661 >> x3::eps [done]
662 ][
663 (
664 [](auto& ctx){
665 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
666 auto const& ext = _attr(ctx);
667 auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
668 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
669 }
670 )
671 ]
672 |
673 // -----------------------------------------------
674 mp_fixext16 [
675 (
676 [](auto& ctx){
677 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
678 app_specific.index_sizes.emplace_back(16+1);
679 }
680 )
681 ]
682 >>
683 x3::raw [
684 *(x3::eps [more] >> x3::char_)
685 >> x3::eps [done]
686 ][
687 (
688 [](auto& ctx){
689 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
690 auto const& ext = _attr(ctx);
691 auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
692 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
693 }
694 )
695 ]
696 |
697 // -----------------------------------------------
698 mp_ext8 >> mp_d_uint8 [
699 (
700 [](auto& ctx){
701 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
702 app_specific.index_sizes.emplace_back(_attr(ctx)+1);
703 }
704 )
705 ]
706 >>
707 x3::raw [
708 *(x3::eps [more] >> x3::char_)
709 >> x3::eps [done]
710 ][
711 (
712 [](auto& ctx){
713 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
714 auto const& ext = _attr(ctx);
715 auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
716 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
717 }
718 )
719 ]
720 |
721 // -----------------------------------------------
722 mp_ext16 >> mp_d_uint16 [
723 (
724 [](auto& ctx){
725 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
726 app_specific.index_sizes.emplace_back(_attr(ctx)+1);
727 }
728 )
729 ]
730 >>
731 x3::raw [
732 *(x3::eps [more] >> x3::char_)
733 >> x3::eps [done]
734 ][
735 (
736 [](auto& ctx){
737 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
738 auto const& ext = _attr(ctx);
739 auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
740 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
741 }
742 )
743 ]
744 |
745 // -----------------------------------------------
746 mp_ext32 >> mp_d_uint32 [
747 (
748 [](auto& ctx){
749 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
750 app_specific.index_sizes.emplace_back(_attr(ctx)+1);
751 }
752 )
753 ]
754 >>
755 x3::raw [
756 *(x3::eps [more] >> x3::char_)
757 >> x3::eps [done]
758 ][
759 (
760 [](auto& ctx){
761 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
762 auto const& ext = _attr(ctx);
763 auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
764 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
765 }
766 )
767 ];
768
769const auto array_item_def =
770 x3::eps[
771 (
772 [](auto& ctx){
773 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
774 app_specific.vis.start_array_item();
775
776 _pass(ctx) = true;
777 }
778 )
779 ]
780 >>
781 mp_object
782 >>
783 x3::eps[
784 (
785 [](auto& ctx){
786 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
787 app_specific.vis.end_array_item();
788 _pass(ctx) = true;
789 }
790 )
791 ];
792
793const auto map_item_def = kv;
794const auto kv_def =
795 x3::eps[
796 (
797 [](auto& ctx){
798 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
799 app_specific.vis.start_map_key();
800 _pass(ctx) = true;
801 }
802 )
803 ]
804 >>
805 mp_object
806 >>
807 x3::eps[
808 (
809 [](auto& ctx){
810 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
811 app_specific.vis.end_map_key();
812 _pass(ctx) = true;
813 }
814 )
815 ]
816 >>
817 x3::eps[
818 (
819 [](auto& ctx){
820 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
821 app_specific.vis.start_map_value();
822 _pass(ctx) = true;
823 }
824 )
825 ]
826 >>
827 mp_object
828 >>
829 x3::eps[
830 (
831 [](auto& ctx){
832 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
833 app_specific.vis.end_map_value();
834 _pass(ctx) = true;
835 }
836 )
837 ];
838
839BOOST_SPIRIT_DEFINE(
840 mp_object, array_item, map_item, kv
841);
842
843const auto rule = mp_object;
844
845} // namespace detail
846
847template <typename Iterator, typename Visitor>
848inline bool parse(Iterator&& begin, Iterator&& end, Visitor&& vis) {
849 auto data = detail::make_app_specific(std::forward<Visitor>(vis));
850 return detail::x3::parse(
851 std::forward<Iterator>(begin),
852 std::forward<Iterator>(end),
853 detail::x3::with<detail::tag_app_specific>(std::ref(data))[detail::rule]
854 );
855}
856
858} // MSGPACK_API_VERSION_NAMESPACE(v2)
860
861} // namespace msgpack
862
863#if __GNUC__ >= 4
864#pragma GCC diagnostic pop
865#endif // __GNUC__ >= 4
866
867#else // BOOST_VERSION >= 106100
868
869#error Boost 1.61.0 or later is required to use x3 parse
870
871#endif // BOOST_VERSION >= 106100
872
873#endif // defined(MSGPACK_USE_X3_PARSE)
874
875#endif // MSGPACK_V2_X3_PARSE_HPP
std::size_t size(T const &t)
Definition size_equal_only.hpp:24
Definition adaptor_base.hpp:15
bool parse(const char *data, size_t len, size_t &off, Visitor &v)
Unpack msgpack formatted data via a visitor.
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition versioning.hpp:66