• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2001-2011 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #include <boost/config/warning_disable.hpp>
7 #include <boost/detail/lightweight_test.hpp>
8 
9 #include <boost/assign/std/vector.hpp>
10 
11 #include <boost/spirit/include/karma_operator.hpp>
12 #include <boost/spirit/include/karma_char.hpp>
13 #include <boost/spirit/include/karma_string.hpp>
14 #include <boost/spirit/include/karma_numeric.hpp>
15 #include <boost/spirit/include/karma_directive.hpp>
16 #include <boost/spirit/include/karma_operator.hpp>
17 #include <boost/spirit/include/karma_action.hpp>
18 #include <boost/spirit/include/karma_nonterminal.hpp>
19 #include <boost/spirit/include/karma_auxiliary.hpp>
20 #include <boost/spirit/include/karma_directive.hpp>
21 #include <boost/spirit/include/karma_phoenix_attributes.hpp>
22 #include <boost/spirit/include/support_argument.hpp>
23 #include <boost/spirit/include/phoenix_core.hpp>
24 #include <boost/spirit/include/phoenix_operator.hpp>
25 #include <boost/fusion/include/std_pair.hpp>
26 
27 #include <string>
28 #include <iostream>
29 #include <vector>
30 
31 #include "test.hpp"
32 
33 using namespace spirit_test;
34 
35 ///////////////////////////////////////////////////////////////////////////////
36 struct action
37 {
actionaction38     action (std::vector<char>& vec)
39       : vec(vec), it(vec.begin())
40     {}
41 
operator ()action42     void operator()(unsigned& value, boost::spirit::unused_type, bool& pass) const
43     {
44        pass = (it != vec.end());
45        if (pass)
46            value = *it++;
47     }
48 
49     std::vector<char>& vec;
50     mutable std::vector<char>::iterator it;
51 };
52 
53 ///////////////////////////////////////////////////////////////////////////////
main()54 int main()
55 {
56     using namespace boost::spirit::ascii;
57     using boost::spirit::karma::repeat;
58     using boost::spirit::karma::inf;
59     using boost::spirit::karma::int_;
60     using boost::spirit::karma::hex;
61     using boost::spirit::karma::_1;
62 
63     { // lazy repeats
64         using boost::phoenix::val;
65 
66         std::string str8("aaaaaaaa");
67         BOOST_TEST(test("aaaaaaaa", repeat[char_], str8));   // kleene synonym
68         BOOST_TEST(test("aaaaaaaa", repeat(val(8))[char_], str8));
69         BOOST_TEST(test("aaa", repeat(val(3))[char_], str8));
70         BOOST_TEST(!test("aaaaaaaa", repeat(val(9))[char_], str8));
71 
72         std::string str3("aaa");
73         BOOST_TEST(test("aaaaa", repeat(val(3), val(5))[char_], str8));
74         BOOST_TEST(test("aaa", repeat(val(3), val(5))[char_], str3));
75         BOOST_TEST(!test("aaa", repeat(val(4), val(5))[char_], str3));
76 
77         BOOST_TEST(test("aaa", repeat(val(3), val(inf))[char_], str3));
78         BOOST_TEST(test("aaaaaaaa", repeat(val(3), val(inf))[char_], str8));
79         BOOST_TEST(!test("aaa", repeat(val(4), val(inf))[char_], str3));
80     }
81 
82 
83     {
84         std::string str8("aaaaaaaa");
85         BOOST_TEST(test("aaaaaaaa", repeat[char_], str8));   // kleene synonym
86         BOOST_TEST(test("aaaaaaaa", repeat(8)[char_], str8));
87         BOOST_TEST(test("aaa", repeat(3)[char_], str8));
88         BOOST_TEST(!test("aaaaaaaa", repeat(9)[char_], str8));
89 
90         std::string str3("aaa");
91         BOOST_TEST(test("aaaaa", repeat(3, 5)[char_], str8));
92         BOOST_TEST(test("aaa", repeat(3, 5)[char_], str3));
93         BOOST_TEST(!test("aaa", repeat(4, 5)[char_], str3));
94 
95         BOOST_TEST(test("aaa", repeat(3, inf)[char_], str3));
96         BOOST_TEST(test("aaaaaaaa", repeat(3, inf)[char_], str8));
97         BOOST_TEST(!test("aaa", repeat(4, inf)[char_], str3));
98     }
99 
100     {
101         std::string str8("aaaaaaaa");
102         BOOST_TEST(test_delimited("a a a a a a a a ", repeat[char_], str8, space));
103         BOOST_TEST(test_delimited("a a a a a a a a ", repeat(8)[char_], str8, space));
104         BOOST_TEST(test_delimited("a a a ", repeat(3)[char_], str8, space));
105         BOOST_TEST(!test_delimited("a a a a a a a a ", repeat(9)[char_], str8, space));
106 
107         std::string str3("aaa");
108         BOOST_TEST(test_delimited("a a a a a ", repeat(3, 5)[char_], str8, space));
109         BOOST_TEST(test_delimited("a a a ", repeat(3, 5)[char_], str3, space));
110         BOOST_TEST(!test_delimited("a a a ", repeat(4, 5)[char_], str3, space));
111 
112         BOOST_TEST(test_delimited("a a a ", repeat(3, inf)[char_], str3, space));
113         BOOST_TEST(test_delimited("a a a a a a a a ", repeat(3, inf)[char_], str8, space));
114         BOOST_TEST(!test_delimited("a a a ", repeat(4, inf)[char_], str3, space));
115     }
116 
117     {
118         // make sure user defined end condition is applied if no attribute
119         // is passed in
120         using namespace boost::assign;
121 
122         std::vector<char> v;
123         v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h';
124         BOOST_TEST(test("[6162636465666768]",
125             '[' << repeat[hex[action(v)]] << ']'));
126     }
127 
128 // we support Phoenix attributes only starting with V2.2
129 #if SPIRIT_VERSION >= 0x2020
130     {
131         namespace ascii = boost::spirit::ascii;
132         namespace phoenix = boost::phoenix;
133 
134         char c = 'a';
135         BOOST_TEST(test("bcd", repeat(3)[ascii::char_[_1 = ++phoenix::ref(c)]]));
136 
137         c = 'a';
138         BOOST_TEST(test("bcd", repeat(3)[ascii::char_], ++phoenix::ref(c)));
139     }
140 #endif
141 
142     return boost::report_errors();
143 }
144 
145