reference.cpp 29 KB

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