• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
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 <string>
8 #include <vector>
9 
10 #include <boost/detail/lightweight_test.hpp>
11 #include <boost/utility/enable_if.hpp>
12 
13 #if defined(__GNUC__) && (__GNUC__ >= 8)
14 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92539
15 # pragma GCC diagnostic ignored "-Warray-bounds"
16 #endif
17 #include <boost/spirit/home/x3.hpp>
18 #include <string>
19 #include <iostream>
20 #include "test.hpp"
21 #include "utils.hpp"
22 
23 int
main()24 main()
25 {
26     using spirit_test::test_attr;
27     using spirit_test::test;
28 
29     using namespace boost::spirit::x3::ascii;
30     using boost::spirit::x3::repeat;
31     using boost::spirit::x3::inf;
32     using boost::spirit::x3::omit;
33     using boost::spirit::x3::int_;
34     using boost::spirit::x3::lexeme;
35     using boost::spirit::x3::char_;
36 
37     BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(repeat['x']);
38     BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(repeat(3)['x']);
39     BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(repeat(3, 5)['x']);
40     BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(repeat(3, inf)['x']);
41 
42     {
43         BOOST_TEST(test("aaaaaaaa", repeat[char_])); // kleene synonym
44         BOOST_TEST(test("aaaaaaaa", repeat(8)[char_]));
45         BOOST_TEST(!test("aa", repeat(3)[char_]));
46         BOOST_TEST(test("aaa", repeat(3, 5)[char_]));
47         BOOST_TEST(test("aaaaa", repeat(3, 5)[char_]));
48         BOOST_TEST(!test("aaaaaa", repeat(3, 5)[char_]));
49         BOOST_TEST(!test("aa", repeat(3, 5)[char_]));
50 
51         BOOST_TEST(test("aaa", repeat(3, inf)[char_]));
52         BOOST_TEST(test("aaaaa", repeat(3, inf)[char_]));
53         BOOST_TEST(test("aaaaaa", repeat(3, inf)[char_]));
54         BOOST_TEST(!test("aa", repeat(3, inf)[char_]));
55     }
56     {
57         std::string s;
58         BOOST_TEST(test_attr("aaaaaaaa", repeat[char_ >> char_], s)); // kleene synonym
59         BOOST_TEST(s == "aaaaaaaa");
60 
61         s.clear();
62         BOOST_TEST(test_attr("aaaaaaaa", repeat(4)[char_ >> char_], s));
63         BOOST_TEST(s == "aaaaaaaa");
64 
65         BOOST_TEST(!test("aa", repeat(3)[char_ >> char_]));
66         BOOST_TEST(!test("a", repeat(1)[char_ >> char_]));
67 
68         s.clear();
69         BOOST_TEST(test_attr("aa", repeat(1, 3)[char_ >> char_], s));
70         BOOST_TEST(s == "aa");
71 
72         s.clear();
73         BOOST_TEST(test_attr("aaaaaa", repeat(1, 3)[char_ >> char_], s));
74         BOOST_TEST(s == "aaaaaa");
75 
76         BOOST_TEST(!test("aaaaaaa", repeat(1, 3)[char_ >> char_]));
77         BOOST_TEST(!test("a", repeat(1, 3)[char_ >> char_]));
78 
79         s.clear();
80         BOOST_TEST(test_attr("aaaa", repeat(2, inf)[char_ >> char_], s));
81         BOOST_TEST(s == "aaaa");
82 
83         s.clear();
84         BOOST_TEST(test_attr("aaaaaa", repeat(2, inf)[char_ >> char_], s));
85         BOOST_TEST(s == "aaaaaa");
86 
87         BOOST_TEST(!test("aa", repeat(2, inf)[char_ >> char_]));
88     }
89 
90     { // from classic spirit tests
91         BOOST_TEST(test("", repeat(0, inf)['x']));
92 
93         //  repeat exact 8
94         #define rep8 repeat(8)[alpha] >> 'X'
95         BOOST_TEST(!test("abcdefgX", rep8, false));
96         BOOST_TEST(test("abcdefghX", rep8));
97         BOOST_TEST(!test("abcdefghiX", rep8, false));
98         BOOST_TEST(!test("abcdefgX", rep8, false));
99         BOOST_TEST(!test("aX", rep8, false));
100 
101         //  repeat 2 to 8
102         #define rep28 repeat(2, 8)[alpha] >> '*'
103         BOOST_TEST(test("abcdefg*", rep28));
104         BOOST_TEST(test("abcdefgh*", rep28));
105         BOOST_TEST(!test("abcdefghi*", rep28, false));
106         BOOST_TEST(!test("a*", rep28, false));
107 
108         //  repeat 2 or more
109         #define rep2_ repeat(2, inf)[alpha] >> '+'
110         BOOST_TEST(test("abcdefg+", rep2_));
111         BOOST_TEST(test("abcdefgh+", rep2_));
112         BOOST_TEST(test("abcdefghi+", rep2_));
113         BOOST_TEST(test("abcdefg+", rep2_));
114         BOOST_TEST(!test("a+", rep2_, false));
115 
116         //  repeat 0
117         #define rep0 repeat(0)[alpha] >> '/'
118         BOOST_TEST(test("/", rep0));
119         BOOST_TEST(!test("a/", rep0, false));
120 
121         //  repeat 0 or 1
122         #define rep01 repeat(0, 1)[alpha >> digit] >> '?'
123         BOOST_TEST(!test("abcdefg?", rep01, false));
124         BOOST_TEST(!test("a?", rep01, false));
125         BOOST_TEST(!test("1?", rep01, false));
126         BOOST_TEST(!test("11?", rep01, false));
127         BOOST_TEST(!test("aa?", rep01, false));
128         BOOST_TEST(test("?", rep01));
129         BOOST_TEST(test("a1?", rep01));
130     }
131 
132     {
133         BOOST_TEST(test(" a a aaa aa", repeat(7)[char_], space));
134         BOOST_TEST(test("12345 678 9", repeat(9)[digit], space));
135     }
136 
137     {
138         std::vector<std::string> v;
139         BOOST_TEST(test_attr("a b c d", repeat(4)[lexeme[+alpha]], v, space) && 4 == v.size() &&
140             v[0] == "a" && v[1] == "b" && v[2] == "c" &&  v[3] == "d");
141     }
142     {
143         BOOST_TEST(test("1 2 3", int_ >> repeat(2)[int_], space));
144         BOOST_TEST(!test("1 2", int_ >> repeat(2)[int_], space));
145     }
146 
147     {
148         std::vector<char> v;
149         BOOST_TEST(test_attr("1 2 3", int_ >> repeat(2)[int_], v, space));
150         BOOST_TEST(v.size() == 3 && v[0] == 1 && v[1] == 2 && v[2] == 3);
151 
152         BOOST_TEST(!test("1 2", int_ >> repeat(2)[int_], space));
153     }
154 
155     { // test move only types
156         std::vector<move_only> v;
157         BOOST_TEST(test_attr("sss", repeat(3)[synth_move_only], v));
158         BOOST_TEST_EQ(v.size(), 3);
159     }
160 
161     return boost::report_errors();
162 }
163