1 /*=============================================================================
2 Copyright (c) 2001-2011 Hartmut Kaiser
3 http://spirit.sourceforge.net/
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #include <boost/config/warning_disable.hpp>
9
10 //[reference_karma_includes
11 #include <boost/spirit/include/karma.hpp>
12 #include <boost/spirit/include/support_utree.hpp>
13 #include <boost/spirit/include/phoenix_core.hpp>
14 #include <boost/spirit/include/phoenix_operator.hpp>
15 #include <boost/fusion/include/std_pair.hpp>
16 #include <iostream>
17 #include <string>
18 //]
19
20 //[reference_karma_includes_simple
21 #include <boost/spirit/include/karma.hpp>
22 #include <iostream>
23 #include <string>
24 //]
25
26 //[reference_karma_output_iterator
27 typedef std::back_insert_iterator<std::string> output_iterator_type;
28 //]
29
30 //[reference_karma_test
31 template <typename G>
test_generator(char const * expected,G const & g)32 void test_generator(char const* expected, G const& g)
33 {
34 std::string s;
35 std::back_insert_iterator<std::string> out(s);
36 if (boost::spirit::karma::generate(out, g) && s == expected)
37 std::cout << "ok" << std::endl;
38 else
39 std::cout << "fail" << std::endl;
40 }
41 //]
42
43 //[reference_karma_test_attr
44 template <typename G, typename T>
test_generator_attr(char const * expected,G const & g,T const & attr)45 void test_generator_attr(char const* expected, G const& g, T const& attr)
46 {
47 std::string s;
48 std::back_insert_iterator<std::string> out(s);
49 if (boost::spirit::karma::generate(out, g, attr) && s == expected)
50 std::cout << "ok" << std::endl;
51 else
52 std::cout << "fail" << std::endl;
53 }
54 //]
55
56 //[reference_karma_test_attr2
57 template <typename G, typename T1, typename T2>
test_generator_attr(char const * expected,G const & g,T1 const & attr1,T2 const & attr2)58 void test_generator_attr(char const* expected, G const& g, T1 const& attr1,
59 T2 const& attr2)
60 {
61 std::string s;
62 std::back_insert_iterator<std::string> out(s);
63 if (boost::spirit::karma::generate(out, g, attr1, attr2) && s == expected)
64 std::cout << "ok" << std::endl;
65 else
66 std::cout << "fail" << std::endl;
67 }
68 //]
69
70 //[reference_karma_test_attr_delim
71 template <typename G, typename Delimiter, typename T>
test_generator_attr_delim(char const * expected,G const & g,Delimiter const & d,T const & attr)72 void test_generator_attr_delim(char const* expected, G const& g, Delimiter const& d, T const& attr)
73 {
74 std::string s;
75 std::back_insert_iterator<std::string> out(s);
76 if (boost::spirit::karma::generate_delimited(out, g, d, attr) && s == expected)
77 std::cout << "ok" << std::endl;
78 else
79 std::cout << "fail" << std::endl;
80 }
81 //]
82
83 //[reference_karma_binary_test
84 template <typename G>
test_binary_generator(char const * expected,std::size_t size,G const & g)85 void test_binary_generator(char const* expected, std::size_t size, G const& g)
86 {
87 std::string s;
88 std::back_insert_iterator<std::string> out(s);
89 if (boost::spirit::karma::generate(out, g) && !std::memcmp(s.c_str(), expected, size))
90 std::cout << "ok" << std::endl;
91 else
92 std::cout << "fail" << std::endl;
93 }
94 //]
95
96 //[reference_karma_binary_test_attr
97 template <typename G, typename T>
test_binary_generator_attr(char const * expected,std::size_t size,G const & g,T const & attr)98 void test_binary_generator_attr(char const* expected, std::size_t size, G const& g, T const& attr)
99 {
100 std::string s;
101 std::back_insert_iterator<std::string> out(s);
102 if (boost::spirit::karma::generate(out, g, attr) && !std::memcmp(s.c_str(), expected, size))
103 std::cout << "ok" << std::endl;
104 else
105 std::cout << "fail" << std::endl;
106 }
107 //]
108
109 //[reference_karma_complex
110 // a simple complex number representation z = a + bi
111 struct complex
112 {
complexcomplex113 complex (double a, double b)
114 : a(a), b(b)
115 {}
116
117 double a;
118 double b;
119 };
120 //]
121
122 //[reference_karma_stream_complex
123 // define streaming operator for the type complex
124 std::ostream&
operator <<(std::ostream & os,complex const & z)125 operator<< (std::ostream& os, complex const& z)
126 {
127 os << "{" << z.a << "," << z.b << "}";
128 return os;
129 }
130 //]
131
132 //[reference_karma_auto_complex
133 /*`The following construct is required to allow the `complex` data structure
134 to be utilized as a __fusion__ sequence. This is required as we will
135 emit output for this data structure with a __karma__ sequence:
136 `'{' << karma::double_ << ',' << karma::double_ << '}'`.
137 */
138 BOOST_FUSION_ADAPT_STRUCT(
139 complex,
140 (double, a)
141 (double, b)
142 )
143
144 /*`We add a specialization for the create_generator customization point
145 defining a custom output format for the complex type. Generally, any
146 specialization for create_generator is expected to return the proto
147 expression to be used to generate output for the type the customization
148 point has been specialized for.
149 */
150 /*`We need to utilize `proto::deep_copy` as the expression contains literals
151 (the `'{'`, `','`, and `'}'`) which normally get embedded in the proto
152 expression by reference only. The deep copy converts the proto tree to
153 hold this by value. The deep copy operation can be left out for simpler
154 proto expressions (not containing references to temporaries). Alternatively
155 you could use the `proto::make_expr` facility to build the required
156 proto expression.
157 */
158 namespace boost { namespace spirit { namespace traits
159 {
160 template <>
161 struct create_generator<complex>
162 {
163 typedef proto::result_of::deep_copy<
164 BOOST_TYPEOF('{' << karma::double_ << ',' << karma::double_ << '}')
165 >::type type;
166
callboost::spirit::traits::create_generator167 static type call()
168 {
169 return proto::deep_copy(
170 '{' << karma::double_ << ',' << karma::double_ << '}');
171 }
172 };
173 }}}
174 //]
175
176 //[reference_karma_auxiliary_attr_cast_data1
177 // this is just a test structure we want to use in place of an int
178 struct int_data
179 {
180 int i;
181 };
182
183 // we provide a custom attribute transformation to allow its use as an int
184 namespace boost { namespace spirit { namespace traits
185 {
186 template <>
187 struct transform_attribute<int_data const, int, karma::domain>
188 {
189 typedef int type;
preboost::spirit::traits::transform_attribute190 static int pre(int_data const& d) { return d.i; }
191 };
192 }}}
193 //]
194
195 namespace client
196 {
197 using boost::spirit::karma::grammar;
198 using boost::spirit::karma::rule;
199 using boost::spirit::ascii::space_type;
200
201 //[karma_reference_grammar_definition
202 /*`Basic grammar usage:
203 */
204 struct num_list : grammar<output_iterator_type, space_type, std::vector<int>()>
205 {
num_listclient::num_list206 num_list() : base_type(start)
207 {
208 using boost::spirit::int_;
209 num = int_;
210 start = num << *(',' << num);
211 }
212
213 rule<output_iterator_type, space_type, std::vector<int>()> start;
214 rule<output_iterator_type, space_type, int()> num;
215 };
216 //]
217 }
218
main()219 int main()
220 {
221 ///////////////////////////////////////////////////////////////////////////
222 // Operators
223 ///////////////////////////////////////////////////////////////////////////
224 {
225 //[reference_karma_using_declarations_sequence
226 using boost::spirit::karma::double_;
227 //]
228
229 //[reference_karma_sequence
230 test_generator_attr("1.0,2.0", double_ << ',' << double_, std::make_pair(1.0, 2.0));
231 //]
232 }
233
234 {
235 //[reference_karma_using_declarations_alternative
236 using boost::spirit::karma::double_;
237 using boost::spirit::karma::ascii::string;
238 //]
239
240 //[reference_karma_alternative1
241 boost::variant<std::string, double> v1(1.0);
242 test_generator_attr("1.0", string | double_, v1);
243 test_generator_attr("2.0", string | double_, 2.0);
244 //]
245
246 //[reference_karma_alternative2
247 boost::variant<std::string, double> v2("example");
248 test_generator_attr("example", string | double_, v2);
249 test_generator_attr("example", string | double_, "example");
250 //]
251 }
252
253 {
254 //[reference_karma_using_declarations_kleene
255 using boost::spirit::karma::double_;
256 using boost::spirit::karma::space;
257 //]
258
259 //[reference_karma_kleene
260 std::vector<double> v;
261 v.push_back(1.0);
262 v.push_back(2.0);
263 v.push_back(3.0);
264 test_generator_attr_delim("1.0 2.0 3.0 ", *double_, space, v);
265 //]
266 }
267
268 {
269 //[reference_karma_using_declarations_plus
270 using boost::spirit::karma::double_;
271 using boost::spirit::karma::space;
272 //]
273
274 //[reference_karma_plus1
275 std::vector<double> v1;
276 v1.push_back(1.0);
277 v1.push_back(2.0);
278 v1.push_back(3.0);
279 test_generator_attr_delim("1.0 2.0 3.0 ", +double_, space, v1);
280 //]
281
282 //[reference_karma_plus2
283 std::vector<double> v2; // empty container
284 test_generator_attr("empty", +double_ | "empty", v2);
285 //]
286 }
287
288 {
289 //[reference_karma_using_declarations_list
290 using boost::spirit::karma::double_;
291 //]
292
293 //[reference_karma_list
294 std::vector<double> v1;
295 v1.push_back(1.0);
296 test_generator_attr("1.0", double_ % ',', v1);
297
298 v1.push_back(2.0);
299 test_generator_attr("1.0,2.0", double_ % ',', v1);
300 //]
301 }
302
303 {
304 //[reference_karma_using_declarations_optional
305 using boost::spirit::karma::double_;
306 //]
307
308 //[reference_karma_optional1
309 boost::optional<double> val(1.0);
310 test_generator_attr("1.0", -double_, val);
311 test_generator_attr("2.0", -double_, 2.0);
312 //]
313 }
314 {
315 using boost::spirit::karma::double_;
316
317 //[reference_karma_optional2
318 boost::optional<double> val; // empty optional
319 test_generator_attr("", -double_, val);
320 //]
321 }
322
323 {
324 //[reference_karma_using_declarations_and_predicate
325 using boost::spirit::karma::double_;
326 using boost::spirit::karma::ascii::char_;
327 using boost::spirit::karma::ascii::string;
328 using boost::phoenix::ref;
329 //]
330
331 //[reference_karma_and_predicate
332 test_generator_attr("b", &char_('a') << 'b' | 'c', 'a');
333 test_generator_attr("c", &char_('a') << 'b' | 'c', 'x');
334
335 test_generator_attr("abc", &string("123") << "abc" | "def", "123");
336 test_generator_attr("def", &string("123") << "abc" | "def", "456");
337 //]
338 }
339
340 {
341 //[reference_karma_using_declarations_not_predicate
342 using boost::spirit::karma::double_;
343 using boost::spirit::karma::ascii::char_;
344 using boost::spirit::karma::ascii::string;
345 using boost::phoenix::ref;
346 //]
347
348 //[reference_karma_not_predicate
349 test_generator_attr("c", !char_('a') << 'b' | 'c', 'a');
350 test_generator_attr("b", !char_('a') << 'b' | 'c', 'x');
351
352 test_generator_attr("def", !string("123") << "abc" | "def", "123");
353 test_generator_attr("abc", !string("123") << "abc" | "def", "456");
354 //]
355 }
356
357 ///////////////////////////////////////////////////////////////////////////
358 // Directives
359 ///////////////////////////////////////////////////////////////////////////
360 {
361 //[reference_karma_using_declarations_alignment
362 using boost::spirit::karma::double_;
363 using boost::spirit::karma::left_align;
364 using boost::spirit::karma::center;
365 using boost::spirit::karma::right_align;
366 //]
367
368 //[reference_karma_alignment
369 std::pair<double, double> p (1.0, 2.0);
370 test_generator_attr("1.0 |2.0", left_align(8)[double_] << '|' << double_, p);
371 test_generator_attr(" 1.0 |2.0", center(8)[double_] << '|' << double_, p);
372 test_generator_attr(" 1.0|2.0", right_align(8)[double_] << '|' << double_, p);
373 //]
374 }
375
376 {
377 //[reference_karma_using_declarations_repeat
378 using boost::spirit::karma::double_;
379 using boost::spirit::karma::repeat;
380 //]
381
382 //[reference_karma_repeat
383 std::vector<double> v;
384 v.push_back(1.0);
385 v.push_back(2.0);
386 v.push_back(3.0);
387
388 test_generator_attr("[1.0][2.0][3.0]", repeat['[' << double_ << ']'], v);
389 test_generator_attr("[1.0][2.0]", repeat(2)['[' << double_ << ']'], v);
390
391 // fails because of insufficient number of items
392 test_generator_attr("", repeat(4)['[' << double_ << ']'], v);
393 //]
394 }
395
396 {
397 //[reference_karma_using_declarations_delimit
398 using boost::spirit::karma::double_;
399 using boost::spirit::karma::delimit;
400 using boost::spirit::karma::verbatim;
401 //]
402
403 //[reference_karma_delimit
404 test_generator_attr("[ 2.0 , 4.3 ] ",
405 delimit['[' << double_ << ',' << double_ << ']'], 2.0, 4.3);
406 test_generator_attr("[*2.0*,*4.3*]*",
407 delimit('*')['[' << double_ << ',' << double_ << ']'], 2.0, 4.3);
408 test_generator_attr("[2.0, 4.3 ] ",
409 delimit[verbatim['[' << double_ << ','] << double_ << ']'], 2.0, 4.3);
410 //]
411 }
412
413 {
414 //[reference_karma_using_declarations_upperlower
415 using boost::spirit::karma::double_;
416 using boost::spirit::ascii::upper;
417 using boost::spirit::ascii::lower;
418 //]
419
420 //[reference_karma_upperlower
421 test_generator_attr("abc:2.0e-06", lower["ABC:" << double_], 2e-6);
422 test_generator_attr("ABC:2.0E-06", upper["abc:" << double_], 2e-6);
423 //]
424 }
425
426 {
427 //[reference_karma_using_declarations_maxwidth
428 using boost::spirit::karma::double_;
429 using boost::spirit::karma::maxwidth;
430 using boost::spirit::karma::left_align;
431 using boost::spirit::karma::right_align;
432 //]
433
434 //[reference_karma_maxwidth
435 test_generator("01234", maxwidth(5)["0123456789"]);
436 test_generator(" 012", maxwidth(5)[right_align(12)["0123456789"]]);
437 test_generator("0123 ", maxwidth(8)[left_align(8)["0123"]]);
438 //]
439 }
440
441 {
442 //[reference_karma_using_declarations_buffer
443 using boost::spirit::karma::double_;
444 using boost::spirit::karma::buffer;
445 //]
446
447 //[reference_karma_buffer
448 std::vector<double> v; // empty container
449 test_generator_attr("", -buffer['[' << +double_ << ']'], v);
450
451 v.push_back(1.0); // now, fill the container
452 v.push_back(2.0);
453 test_generator_attr("[1.02.0]", buffer['[' << +double_ << ']'], v);
454 //]
455 }
456
457 {
458 //[reference_karma_using_declarations_omit
459 using boost::spirit::karma::double_;
460 using boost::spirit::karma::omit;
461 //]
462
463 //[reference_karma_omit
464 std::pair<double, double> p (1.0, 2.0);
465 test_generator_attr("2.0", omit[double_] << double_, p);
466 //]
467 }
468
469 {
470 //[reference_karma_using_declarations_duplicate
471 using boost::spirit::karma::double_;
472 using boost::spirit::karma::duplicate;
473 using boost::spirit::karma::space;
474 //]
475
476 //[reference_karma_duplicate
477 test_generator_attr("2.02.0", duplicate[double_ << double_], 2.0);
478 test_generator_attr_delim("2.0 2.0 ", duplicate[double_ << double_], space, 2.0);
479 //]
480 }
481
482 {
483 //[reference_karma_using_declarations_columns
484 using boost::spirit::karma::double_;
485 using boost::spirit::karma::columns;
486 using boost::spirit::karma::space;
487 //]
488
489 //[reference_karma_columns
490 std::vector<double> v;
491 v.push_back(1.0);
492 v.push_back(2.0);
493 v.push_back(3.0);
494 test_generator_attr("1.0\n2.0\n3.0\n", columns(1)[*double_], v);
495 test_generator_attr_delim("1.0 2.0 \n3.0 \n", columns(2)[*double_], space, v);
496 //]
497 }
498
499 {
500 //[reference_karma_using_declarations_bool
501 using boost::spirit::karma::bool_;
502 using boost::spirit::karma::lit;
503 //]
504
505 //[reference_karma_bool
506 test_generator("true", lit(true));
507 test_generator("false", bool_(false));
508 test_generator_attr("true", bool_(true), true);
509 test_generator_attr("", bool_(true), false); // fails (as true != false)!
510 test_generator_attr("false", bool_, false);
511 //]
512 }
513
514 {
515 //[reference_karma_using_declarations_int
516 using boost::spirit::karma::int_;
517 using boost::spirit::karma::lit;
518 //]
519
520 //[reference_karma_int
521 test_generator("-2", lit(-2));
522 test_generator("-2", int_(-2));
523 test_generator_attr("-2", int_(-2), -2);
524 test_generator_attr("", int_(-2), 3); // fails (as -2 != 3)!
525 test_generator_attr("-2", int_, -2);
526 //]
527 }
528
529 {
530 //[reference_karma_using_declarations_uint
531 using boost::spirit::karma::uint_;
532 using boost::spirit::karma::lit;
533 //]
534
535 //[reference_karma_uint
536 test_generator("2", lit(2U));
537 test_generator("2", uint_(2));
538 test_generator_attr("2", uint_(2), 2);
539 test_generator_attr("", uint_(2), 3); // fails (as 2 != 3)!
540 test_generator_attr("2", uint_, 2);
541 //]
542 }
543
544 {
545 //[reference_karma_using_declarations_real
546 using boost::spirit::karma::double_;
547 using boost::spirit::karma::lit;
548 //]
549
550 //[reference_karma_real
551 test_generator("2.0", lit(2.0));
552 test_generator("2.0", double_(2));
553 test_generator_attr("2.0", double_(2.0), 2.0);
554 test_generator_attr("", double_(2.0), 3.0); // fails (as 2.0 != 3.0)!
555 test_generator_attr("-2.0", double_, -2.0);
556
557 test_generator_attr("1.234e05", double_, 1234.0e2);
558 test_generator_attr("1.234e-06", double_, 0.000001234);
559 //]
560 }
561
562 {
563 //[reference_karma_using_declarations_char
564 using boost::spirit::karma::lit;
565 using boost::spirit::ascii::char_;
566 //]
567
568 //[reference_karma_char
569 test_generator("A", 'A');
570 test_generator("A", lit('A'));
571
572 test_generator_attr("a", char_, 'a');
573 test_generator("A", char_('A'));
574 test_generator_attr("A", char_('A'), 'A');
575 test_generator_attr("", char_('A'), 'B'); // fails (as 'A' != 'B')
576
577 test_generator_attr("A", char_('A', 'Z'), 'A');
578 test_generator_attr("", char_('A', 'Z'), 'a'); // fails (as 'a' does not belong to 'A'...'Z')
579
580 test_generator_attr("k", char_("a-z0-9"), 'k');
581 test_generator_attr("", char_("a-z0-9"), 'A'); // fails (as 'A' does not belong to "a-z0-9")
582 //]
583 }
584
585 {
586 //[reference_karma_using_declarations_char_class
587 using boost::spirit::karma::alpha;
588 using boost::spirit::karma::upper;
589 //]
590
591 //[reference_karma_char_class
592 test_generator_attr("a", alpha, 'a');
593 test_generator_attr("A", alpha, 'A');
594 test_generator_attr("", alpha, '1'); // fails (as isalpha('1') is false)
595 test_generator_attr("A", upper[alpha], 'A');
596 test_generator_attr("", upper[alpha], 'a'); // fails (as isupper('a') is false)
597 //]
598 }
599
600 ///////////////////////////////////////////////////////////////////////////
601 // string
602 {
603 //[reference_karma_using_declarations_string
604 using boost::spirit::karma::lit;
605 using boost::spirit::ascii::string;
606 //]
607
608 //[reference_karma_string
609 test_generator("abc", "abc");
610 test_generator("abc", lit("abc"));
611 test_generator("abc", lit(std::string("abc")));
612
613 test_generator_attr("abc", string, "abc");
614 test_generator("abc", string("abc"));
615 test_generator("abc", string(std::string("abc")));
616
617 test_generator_attr("abc", string("abc"), "abc");
618 test_generator_attr("", string("abc"), "cba"); // fails (as "abc" != "cba")
619 //]
620 }
621
622 ///////////////////////////////////////////////////////////////////////////
623 // auxiliary
624 {
625 //[reference_karma_using_declarations_eol
626 using boost::spirit::karma::eol;
627 //]
628
629 //[reference_karma_eol
630 test_generator("\n", eol);
631 test_generator("abc\n", "abc" << eol);
632 //]
633 }
634
635 {
636 //[reference_karma_using_declarations_attr_cast
637 using boost::spirit::karma::int_;
638 //]
639
640 //[reference_karma_attr_cast1
641 int_data d = { 1 };
642 test_generator_attr("1", boost::spirit::karma::attr_cast(int_), d);
643 //]
644 }
645
646 {
647 //[reference_karma_using_declarations_eps
648 using boost::spirit::karma::eps;
649 using boost::phoenix::val;
650 //]
651
652 //[reference_karma_eps
653 test_generator("abc", eps[std::cout << val("starting eps example")] << "abc");
654 test_generator("abc", eps(true) << "abc");
655 test_generator("", eps(false) << "abc"); // fails as eps expression is 'false'
656 //]
657 }
658
659 {
660 //[reference_karma_using_declarations_lazy
661 namespace karma = boost::spirit::karma;
662 using boost::spirit::karma::_1;
663 using boost::spirit::ascii::string;
664 using boost::phoenix::val;
665 //]
666
667 //[reference_karma_lazy
668 test_generator_attr("abc", karma::lazy(val(string)), "abc");
669 test_generator("abc", karma::lazy(val(string))[_1 = "abc"]);
670 //]
671 }
672
673 ///////////////////////////////////////////////////////////////////////////
674 // stream module
675 {
676 //[reference_karma_using_declarations_stream
677 using boost::spirit::karma::stream;
678 //]
679
680 //[reference_karma_stream
681 test_generator_attr("abc", stream, "abc");
682 test_generator("abc", stream("abc"));
683 test_generator_attr("{1.2,2.4}", stream, complex(1.2, 2.4));
684 test_generator("{1.2,2.4}", stream(complex(1.2, 2.4)));
685 //]
686 }
687
688 ///////////////////////////////////////////////////////////////////////////
689 // auto module
690 {
691 //[reference_karma_using_declarations_auto
692 using boost::spirit::karma::auto_;
693 //]
694
695 //[reference_karma_auto
696 /*`Emit a simple string using the `karma::string` generator:
697 */
698 test_generator_attr("abc", auto_, "abc");
699 test_generator("abc", auto_("abc"));
700
701 /*`Emit instances of the `complex` data type as defined above using the
702 generator defined by the customization point for `complex`:
703 */
704 test_generator_attr("{1.2,2.4}", auto_, complex(1.2, 2.4));
705 test_generator("{1.2,2.4}", auto_(complex(1.2, 2.4)));
706 //]
707 }
708
709 ///////////////////////////////////////////////////////////////////////////
710 // binary module
711 {
712 //[reference_karma_using_declarations_native_binary
713 using boost::spirit::karma::byte_;
714 using boost::spirit::karma::word;
715 using boost::spirit::karma::dword;
716 using boost::spirit::karma::qword;
717 //]
718
719 //[reference_karma_native_binary_little
720 test_binary_generator("\x01", 1, byte_(0x01));
721 test_binary_generator("\x01\x02", 2, word(0x0201));
722 test_binary_generator("\x01\x02\x03\x04", 4, dword(0x04030201));
723 test_binary_generator("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword(0x0807060504030201LL));
724
725 test_binary_generator_attr("\x01", 1, byte_, 0x01);
726 test_binary_generator_attr("\x01\x02", 2, word, 0x0201);
727 test_binary_generator_attr("\x01\x02\x03\x04", 4, dword, 0x04030201);
728 test_binary_generator_attr("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword, 0x0807060504030201LL);
729 //]
730
731 //[reference_karma_native_binary_big
732 test_binary_generator("\x01", 1, byte_(0x01));
733 test_binary_generator("\x02\x01", 2, word(0x0201));
734 test_binary_generator("\x04\x03\x02\x01", 4, dword(0x04030201));
735 test_binary_generator("\x08\x07\x06\x05\x04\x03\x02\x01", 8, qword(0x0807060504030201LL));
736
737 test_binary_generator_attr("\x01", 1, byte_, 0x01);
738 test_binary_generator_attr("\x02\x01", 2, word, 0x0201);
739 test_binary_generator_attr("\x04\x03\x02\x01", 4, dword, 0x04030201);
740 test_binary_generator_attr("\x08\x07\x06\x05\x04\x03\x02\x01", 8, qword, 0x0807060504030201LL);
741 //]
742 }
743
744 {
745 //[reference_karma_using_declarations_little_binary
746 using boost::spirit::karma::little_word;
747 using boost::spirit::karma::little_dword;
748 using boost::spirit::karma::little_qword;
749 //]
750
751 //[reference_karma_little_binary
752 test_binary_generator("\x01\x02", 2, little_word(0x0201));
753 test_binary_generator("\x01\x02\x03\x04", 4, little_dword(0x04030201));
754 test_binary_generator("\x01\x02\x03\x04\x05\x06\x07\x08", 8, little_qword(0x0807060504030201LL));
755
756 test_binary_generator_attr("\x01\x02", 2, little_word, 0x0201);
757 test_binary_generator_attr("\x01\x02\x03\x04", 4, little_dword, 0x04030201);
758 test_binary_generator_attr("\x01\x02\x03\x04\x05\x06\x07\x08", 8, little_qword, 0x0807060504030201LL);
759 //]
760 }
761
762 {
763 //[reference_karma_using_declarations_big_binary
764 using boost::spirit::karma::big_word;
765 using boost::spirit::karma::big_dword;
766 using boost::spirit::karma::big_qword;
767 //]
768
769 //[reference_karma_big_binary
770 test_binary_generator("\x02\x01", 2, big_word(0x0201));
771 test_binary_generator("\x04\x03\x02\x01", 4, big_dword(0x04030201));
772 test_binary_generator("\x08\x07\x06\x05\x04\x03\x02\x01", 8, big_qword(0x0807060504030201LL));
773
774 test_binary_generator_attr("\x02\x01", 2, big_word, 0x0201);
775 test_binary_generator_attr("\x04\x03\x02\x01", 4, big_dword, 0x04030201);
776 test_binary_generator_attr("\x08\x07\x06\x05\x04\x03\x02\x01", 8, big_qword, 0x0807060504030201LL);
777 //]
778 }
779
780 // action
781 {
782 //[reference_karma_using_declarations_action
783 using boost::spirit::karma::int_;
784 using boost::spirit::karma::string;
785 using boost::spirit::karma::_1;
786 using boost::phoenix::ref;
787 using boost::phoenix::val;
788 //]
789
790 //[reference_karma_action
791 int i = 42;
792 test_generator("42", int_[_1 = ref(i)]);
793 test_generator("abc", string[_1 = val("abc")]);
794 //]
795 }
796
797 // rule
798 {
799 //[karma_reference_rule
800 //`Some using declarations:
801 using boost::spirit::karma::rule;
802 using boost::spirit::karma::int_;
803 using boost::spirit::ascii::space;
804 using boost::spirit::ascii::space_type;
805
806 /*`Basic rule:
807 */
808 rule<output_iterator_type> r;
809 r = int_(123);
810 test_generator("123", r);
811
812 /*`Rule with consumed attribute:
813 */
814 rule<output_iterator_type, int()> ra;
815 ra = int_;
816 test_generator_attr("123", ra, 123);
817
818 /*`Rule with delimiter and consumed attribute:
819 */
820 rule<output_iterator_type, std::vector<int>(), space_type> rs;
821 rs = *int_;
822 std::vector<int> v;
823 v.push_back(123);
824 v.push_back(456);
825 v.push_back(789);
826 test_generator_attr_delim("123 456 789", rs, space, v);
827 //]
828 }
829
830 // grammar
831 {
832 using client::num_list;
833
834 //[karma_reference_grammar_using
835 //`Some using declarations:
836 using boost::spirit::ascii::space_type;
837 using boost::spirit::ascii::space;
838 using boost::spirit::int_;
839 using boost::spirit::karma::grammar;
840 using boost::spirit::karma::rule;
841 //]
842
843 //[karma_reference_grammar
844 //`How to use the example grammar:
845 num_list nlist;
846 std::vector<int> v;
847 v.push_back(123);
848 v.push_back(456);
849 v.push_back(789);
850 test_generator_attr_delim("123 , 456 , 789", nlist, space, v);
851 //]
852 }
853
854 // symbols
855 {
856 //[reference_karma_using_declarations_symbols
857 using boost::spirit::karma::symbols;
858 //]
859
860 //[reference_karma_symbols
861 symbols<char, char const*> sym;
862
863 sym.add
864 ('a', "Apple")
865 ('b', "Banana")
866 ('o', "Orange")
867 ;
868
869 test_generator_attr("Banana", sym, 'b');
870 //]
871 }
872
873 // as
874 {
875 //[reference_karma_using_declarations_as
876 using boost::spirit::utree;
877 using boost::spirit::utree_type;
878 using boost::spirit::utf8_symbol_type;
879 using boost::spirit::karma::as;
880 using boost::spirit::karma::as_string;
881 using boost::spirit::karma::char_;
882 using boost::spirit::karma::double_;
883 //]
884
885 //[reference_karma_as
886 /*`To properly handle string concatenation with __utree__, we
887 make use of `as_string[]`. We also use `as<T>` to explicitly extract
888 a __utree__ symbol node.*/
889
890 typedef as<utf8_symbol_type> as_symbol_type;
891 as_symbol_type const as_symbol = as_symbol_type();
892
893 utree ut;
894 ut.push_back("xyz");
895 ut.push_back(1.23);
896
897 test_generator_attr("xyz1.23", as_string[*char_] << double_, ut);
898 test_generator_attr("xyz1.23", as<std::string>()[*char_] << double_, ut);
899
900 ut.clear();
901
902 ut.push_back(utf8_symbol_type("xyz"));
903 ut.push_back(1.23);
904
905 test_generator_attr("xyz1.23", as_symbol[*char_] << double_, ut);
906 test_generator_attr("xyz1.23", as<utf8_symbol_type>()[*char_] << double_, ut);
907 //]
908 }
909
910 return 0;
911 }
912