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