MessagePack for C++
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 
19 #include "msgpack/versioning.hpp"
20 
21 #if __GNUC__ >= 4
22 #pragma GCC diagnostic push
23 #pragma GCC diagnostic ignored "-Wunused-parameter"
24 #endif // __GNUC__ >= 4
25 
26 #include <boost/config/warning_disable.hpp>
27 #include <boost/spirit/home/x3.hpp>
28 #include <boost/spirit/home/x3/binary.hpp>
29 
30 namespace msgpack {
31 
35 
36 namespace detail {
37 
38 namespace x3 = boost::spirit::x3;
39 
40 using x3::byte_;
41 
42 // byte range utility
43 const auto byte_range = [](const std::uint8_t from, const std::uint8_t to) {
44  const auto check = [from, to](auto& ctx)
45  {
46  const std::uint8_t value = x3::_attr(ctx);
47  x3::_val(ctx) = value;
48  x3::_pass(ctx) = from <= value && value <= to;
49  };
50  return x3::byte_ [check];
51 };
52 
53 // MessagePack rule
54 const auto mp_positive_fixint = byte_range(0x00, 0x7f);
55 const auto mp_fixmap = byte_range(0x80, 0x8f);
56 const auto mp_fixarray = byte_range(0x90, 0x9f);
57 const auto mp_fixstr = byte_range(0xa0, 0xbf);
58 const auto mp_nil = x3::byte_(0xc0);
59 const auto mp_false = x3::byte_(0xc2);
60 const auto mp_true = x3::byte_(0xc3);
61 const auto mp_bin8 = x3::byte_(0xc4);
62 const auto mp_bin16 = x3::byte_(0xc5);
63 const auto mp_bin32 = x3::byte_(0xc6);
64 const auto mp_ext8 = x3::byte_(0xc7);
65 const auto mp_ext16 = x3::byte_(0xc8);
66 const auto mp_ext32 = x3::byte_(0xc9);
67 const auto mp_float32 = x3::byte_(0xca);
68 const auto mp_float64 = x3::byte_(0xcb);
69 const auto mp_uint8 = x3::byte_(0xcc);
70 const auto mp_uint16 = x3::byte_(0xcd);
71 const auto mp_uint32 = x3::byte_(0xce);
72 const auto mp_uint64 = x3::byte_(0xcf);
73 const auto mp_int8 = x3::byte_(0xd0);
74 const auto mp_int16 = x3::byte_(0xd1);
75 const auto mp_int32 = x3::byte_(0xd2);
76 const auto mp_int64 = x3::byte_(0xd3);
77 const auto mp_fixext1 = x3::byte_(0xd4);
78 const auto mp_fixext2 = x3::byte_(0xd5);
79 const auto mp_fixext4 = x3::byte_(0xd6);
80 const auto mp_fixext8 = x3::byte_(0xd7);
81 const auto mp_fixext16 = x3::byte_(0xd8);
82 const auto mp_str8 = x3::byte_(0xd9);
83 const auto mp_str16 = x3::byte_(0xda);
84 const auto mp_str32 = x3::byte_(0xdb);
85 const auto mp_array16 = x3::byte_(0xdc);
86 const auto mp_array32 = x3::byte_(0xdd);
87 const auto mp_map16 = x3::byte_(0xde);
88 const auto mp_map32 = x3::byte_(0xdf);
89 const auto mp_negative_fixint = byte_range(0xe0, 0xff);
90 
91 const auto mp_d_uint8 = x3::byte_;
92 const auto mp_d_uint16 = x3::big_word;
93 const auto mp_d_uint32 = x3::big_dword;
94 const auto mp_d_uint64 = x3::big_qword;
95 
96 const auto mp_d_int8 = x3::byte_;
97 const auto mp_d_int16 = x3::big_word;
98 const auto mp_d_int32 = x3::big_dword;
99 const auto mp_d_int64 = x3::big_qword;
100 
101 x3::rule<class mp_object> const mp_object("mp_object");
102 x3::rule<class array_items> const array_item("array_item");
103 x3::rule<class map_items> const map_item("map_item");
104 x3::rule<class kv> const kv("kv");
105 
106 struct tag_app_specific {};
107 struct index_size {
108  enum struct type_t {
109  array,
110  map,
111  other
112  };
113  index_size(std::size_t size, type_t type = type_t::other):size(size), type(type) {}
114  std::size_t index = 0;
115  std::size_t size;
116  type_t type;
117 };
118 
119 template <typename Visitor>
120 struct app_specific {
121  template <typename Vis>
122  app_specific(Vis&& vis):vis(vis) {}
123  std::vector<index_size> index_sizes;
124  Visitor vis;
125 };
126 
127 template <typename Visitor>
128 app_specific<Visitor> make_app_specific(Visitor&& vis) {
129  return app_specific<Visitor>(std::forward<Visitor>(vis));
130 }
131 
132 const auto more = [](auto &ctx) {
133  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
134  _pass(ctx) = app_specific.index_sizes.back().index++ < app_specific.index_sizes.back().size;
135 };
136 
137 const auto done = [](auto &ctx) {
138  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
139  if (app_specific.index_sizes.back().index == app_specific.index_sizes.back().size + 1) {
140  _pass(ctx) = true;
141  switch (app_specific.index_sizes.back().type) {
142  case index_size::type_t::array:
143  app_specific.vis.end_array();
144  break;
145  case index_size::type_t::map:
146  app_specific.vis.end_map();
147  break;
148  case index_size::type_t::other:
149  break;
150  }
151  app_specific.index_sizes.pop_back();
152  }
153  else {
154  _pass(ctx) = false;
155  }
156 };
157 
158 const auto mp_object_def =
159  // -----------------------------------------------
160  mp_nil [
161  (
162  [](auto& ctx){
163  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
164  app_specific.vis.visit_nil();
165  }
166  )
167  ]
168  |
169  // -----------------------------------------------
170  mp_true [
171  (
172  [](auto& ctx){
173  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
174  app_specific.vis.visit_boolean(true);
175  }
176  )
177  ]
178  |
179  // -----------------------------------------------
180  mp_false [
181  (
182  [](auto& ctx){
183  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
184  app_specific.vis.visit_boolean(false);
185  }
186  )
187  ]
188  |
189  // -----------------------------------------------
190  mp_positive_fixint [
191  (
192  [](auto& ctx){
193  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
194  app_specific.vis.visit_positive_integer(_attr(ctx));
195  }
196  )
197  ]
198  |
199  // -----------------------------------------------
200  mp_negative_fixint [
201  (
202  [](auto& ctx){
203  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
204  std::int8_t val = _attr(ctx);
205  app_specific.vis.visit_negative_integer(val);
206  }
207  )
208  ]
209  |
210  // -----------------------------------------------
211  mp_uint8 >> mp_d_uint8 [
212  (
213  [](auto& ctx){
214  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
215  app_specific.vis.visit_negative_integer(_attr(ctx));
216  }
217  )
218  ]
219  |
220  // -----------------------------------------------
221  mp_uint16 >> mp_d_uint16 [
222  (
223  [](auto& ctx){
224  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
225  app_specific.vis.visit_positive_integer(_attr(ctx));
226  }
227  )
228  ]
229  |
230  // -----------------------------------------------
231  mp_uint32 >> mp_d_uint32 [
232  (
233  [](auto& ctx){
234  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
235  app_specific.vis.visit_positive_integer(_attr(ctx));
236  }
237  )
238  ]
239  |
240  // -----------------------------------------------
241  mp_uint64 >> mp_d_uint64 [
242  (
243  [](auto& ctx){
244  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
245  app_specific.vis.visit_positive_integer(_attr(ctx));
246  }
247  )
248  ]
249  |
250  // -----------------------------------------------
251  mp_int8 >> mp_d_int8 [
252  (
253  [](auto& ctx){
254  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
255  std::int8_t val = _attr(ctx);
256  app_specific.vis.visit_negative_integer(val);
257  }
258  )
259  ]
260  |
261  // -----------------------------------------------
262  mp_int16 >> mp_d_int16 [
263  (
264  [](auto& ctx){
265  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
266  std::int16_t val = _attr(ctx);
267  app_specific.vis.visit_negative_integer(val);
268  }
269  )
270  ]
271  |
272  // -----------------------------------------------
273  mp_int32 >> mp_d_int32 [
274  (
275  [](auto& ctx){
276  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
277  std::int32_t val = _attr(ctx);
278  app_specific.vis.visit_negative_integer(val);
279  }
280  )
281  ]
282  |
283  // -----------------------------------------------
284  mp_int64 >> mp_d_int64 [
285  (
286  [](auto& ctx){
287  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
288  std::int64_t val = _attr(ctx);
289  app_specific.vis.visit_negative_integer(val);
290  }
291  )
292  ]
293  |
294  // -----------------------------------------------
295  mp_float32 >> mp_d_uint32 [
296  (
297  [](auto& ctx){
298  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
299  union { uint32_t i; float f; } mem;
300  mem.i = _attr(ctx);
301  app_specific.vis.visit_float(mem.f);
302  }
303  )
304  ]
305  |
306  // -----------------------------------------------
307  mp_float64 >> mp_d_uint64 [
308  (
309  [](auto& ctx){
310  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
311  union { uint64_t i; double f; } mem;
312  mem.i = _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_float(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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_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  std::size_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  std::size_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  std::size_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  std::size_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  std::size_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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_t size = 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  std::size_t size = std::distance(ext.begin(), ext.end());
764  app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
765  }
766  )
767  ];
768 
769 const 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  _pass(ctx) = true;
776  }
777  )
778  ]
779  >>
780  mp_object
781  >>
782  x3::eps[
783  (
784  [](auto& ctx){
785  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
786  app_specific.vis.end_array_item();
787  _pass(ctx) = true;
788  }
789  )
790  ];
791 
792 const auto map_item_def = kv;
793 const auto kv_def =
794  x3::eps[
795  (
796  [](auto& ctx){
797  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
798  app_specific.vis.start_map_key();
799  _pass(ctx) = true;
800  }
801  )
802  ]
803  >>
804  mp_object
805  >>
806  x3::eps[
807  (
808  [](auto& ctx){
809  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
810  app_specific.vis.end_map_key();
811  _pass(ctx) = true;
812  }
813  )
814  ]
815  >>
816  x3::eps[
817  (
818  [](auto& ctx){
819  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
820  app_specific.vis.start_map_value();
821  _pass(ctx) = true;
822  }
823  )
824  ]
825  >>
826  mp_object
827  >>
828  x3::eps[
829  (
830  [](auto& ctx){
831  auto& app_specific = x3::get<tag_app_specific>(ctx).get();
832  app_specific.vis.end_map_value();
833  _pass(ctx) = true;
834  }
835  )
836  ];
837 
838 BOOST_SPIRIT_DEFINE(
839  mp_object, array_item, map_item, kv
840 );
841 
842 const auto rule = mp_object;
843 
844 } // namespace detail
845 
846 template <typename Iterator, typename Visitor>
847 inline bool parse(Iterator&& begin, Iterator&& end, Visitor&& vis) {
848  auto data = detail::make_app_specific(std::forward<Visitor>(vis));
849  return detail::x3::parse(
850  std::forward<Iterator>(begin),
851  std::forward<Iterator>(end),
852  detail::x3::with<detail::tag_app_specific>(std::ref(data))[detail::rule]
853  );
854 }
855 
857 } // MSGPACK_API_VERSION_NAMESPACE(v2)
859 
860 } // namespace msgpack
861 
862 #if __GNUC__ >= 4
863 #pragma GCC diagnostic pop
864 #endif // __GNUC__ >= 4
865 
866 #else // BOOST_VERSION >= 106100
867 
868 #error Boost 1.61.0 or later is required to use x3 parse
869 
870 #endif // BOOST_VERSION >= 106100
871 
872 #endif // defined(MSGPACK_USE_X3_PARSE)
873 
874 #endif // MSGPACK_V2_X3_PARSE_HPP
msgpack::object_kv * begin(msgpack::object_map &map)
Definition: iterator.hpp:23
Definition: adaptor_base.hpp:15
msgpack::object_kv * end(msgpack::object_map &map)
Definition: iterator.hpp:25
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
bool parse(const char *data, size_t len, size_t &off, Visitor &v)
Unpack msgpack formatted data via a visitor.
Definition: parse.hpp:1000
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58