1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // test_typeof2.cpp |
3 | // |
4 | // Copyright 2008 David Jenkins. Distributed under the Boost |
5 | // Software License, Version 1.0. (See accompanying file |
6 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7 | |
8 | #define BOOST_TYPEOF_LIMIT_SIZE 200 |
9 | #define BOOST_TYPEOF_EMULATION 1 |
10 | |
11 | #include <string> |
12 | #include <map> |
13 | #include <list> |
14 | #include <stack> |
15 | #include <boost/version.hpp> |
16 | #include <boost/xpressive/xpressive_static.hpp> |
17 | #include <boost/xpressive/regex_actions.hpp> |
18 | #include <boost/xpressive/xpressive_typeof.hpp> |
19 | #include <boost/typeof/std/stack.hpp> |
20 | #include <boost/typeof/std/list.hpp> |
21 | #include <boost/test/unit_test.hpp> |
22 | |
23 | |
24 | // I couldn't find these registrations anywhere else, so I put them here |
25 | // They are necessary for this program to compile |
26 | #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() |
27 | BOOST_TYPEOF_REGISTER_TEMPLATE(boost::mpl::int_, (int)) |
28 | BOOST_TYPEOF_REGISTER_TEMPLATE(boost::reference_wrapper, (typename)) |
29 | |
30 | // Here's the test for typeof registration, to be used on static regular expressions |
31 | #define TYPEOF_TEST(Expr) { BOOST_PROTO_AUTO(Dummy, Expr); } |
32 | |
33 | namespace xp = boost::xpressive; |
34 | |
35 | /////////////////////////////////////////////////////////////////////////////// |
36 | // test_actions |
37 | // regular expressions from test_actions.cpp |
38 | void test_actions() |
39 | { |
40 | using namespace boost::xpressive; |
41 | // regexes from test_actions.cpp |
42 | std::string result; |
43 | TYPEOF_TEST((+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ])); |
44 | TYPEOF_TEST((+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ]) >> repeat<4>(_)); |
45 | std::list<int> result2; |
46 | TYPEOF_TEST((+_d)[ xp::ref(result2)->*push_back( as<int>(_) ) ] |
47 | >> *(' ' >> (+_d)[ xp::ref(result2)->*push_back( as<int>(_) ) ])); |
48 | std::map<std::string, int> result3; |
49 | TYPEOF_TEST(( (s1= +_w) >> "=>" >> (s2= +_d) )[ xp::ref(result3)[s1] = as<int>(s2) ]); |
50 | placeholder< std::map<std::string, int> > const _map5 = {.proto_expr_: {}}; |
51 | TYPEOF_TEST(( (s1= +_w) >> "=>" >> (s2= +_d) )[ _map5[s1] = as<int>(s2) ]); |
52 | |
53 | smatch what; |
54 | placeholder< std::map<std::string, int> > const _map6 = {.proto_expr_: {}}; |
55 | std::map<std::string, int> result6; |
56 | what.let(arg: _map6 = result6); // bind the argument! |
57 | |
58 | local<int> left, right; |
59 | std::stack<int> stack_; |
60 | reference<std::stack<int> > stack(stack_); |
61 | cregex expression2, factor2, term2, group2; |
62 | TYPEOF_TEST( '(' >> by_ref(expression2) >> ')'); |
63 | TYPEOF_TEST( (+_d)[ push(stack, as<int>(_)) ] | group2); |
64 | TYPEOF_TEST(factor2 >> *( |
65 | ('*' >> factor2) |
66 | [ right = top(stack) |
67 | , pop(stack) |
68 | , left = top(stack) |
69 | , pop(stack) |
70 | , push(stack, left * right) |
71 | ] |
72 | )); |
73 | TYPEOF_TEST(term2 >> *( |
74 | ('+' >> term2) |
75 | [ right = top(stack) |
76 | , pop(stack) |
77 | , left = top(stack) |
78 | , pop(stack) |
79 | , push(stack, left + right) |
80 | ] |
81 | )); |
82 | } |
83 | |
84 | |
85 | #ifndef BOOST_XPRESSIVE_NO_WREGEX |
86 | struct City |
87 | { |
88 | std::wstring name; |
89 | char const* nickname; |
90 | int population; |
91 | }; |
92 | BOOST_TYPEOF_REGISTER_TYPE(City) |
93 | #endif |
94 | |
95 | /////////////////////////////////////////////////////////////////////////////// |
96 | // test_symbols |
97 | // regular expressions from test_symbols.cpp |
98 | void test_symbols() |
99 | { |
100 | using namespace boost::xpressive; |
101 | std::string result; |
102 | std::map<std::string,std::string> map10; |
103 | TYPEOF_TEST((a1=map10)[ xp::ref(result) = a1 ] >> *(' ' >> (a1=map10)[ xp::ref(result) += ',' + a1 ])); |
104 | TYPEOF_TEST((a1=map10)[ xp::ref(result) = a1 ] |
105 | >> *((a1=map10)[ xp::ref(result) += ',', xp::ref(result) += a1 ])); |
106 | std::list<int> result12; |
107 | std::map<std::string,int> map12; |
108 | TYPEOF_TEST((a1=map12)[ xp::ref(result12)->*push_back( a1 ) ] |
109 | >> *(' ' >> (a1=map12)[ xp::ref(result12)->*push_back( a1 ) ])); |
110 | |
111 | placeholder< std::map<std::string, int> > const _map13 = {}; |
112 | BOOST_PROTO_AUTO(pair13, ( (a1=map10) >> "=>" >> (a2= map12) )[ _map13[a1] = a2 ]); |
113 | smatch what; |
114 | std::map<std::string, int> result13; |
115 | what.let(arg: _map13 = result13); |
116 | TYPEOF_TEST(pair13 >> *(+_s >> pair13)); |
117 | |
118 | int result14 = 0; |
119 | std::map<std::string,int> map1a; |
120 | std::map<std::string,int> map2a; |
121 | std::map<std::string,int> map3a; |
122 | TYPEOF_TEST((a1=map1a)[ xp::ref(result14) += a1 ] |
123 | >> (a2=map2a)[ xp::ref(result) += a2 ] |
124 | >> (a3=map3a)[ xp::ref(result) += a3 ] |
125 | ); |
126 | { |
127 | TYPEOF_TEST(icase(a1= map10) [ xp::ref(result) = a1 ] |
128 | >> repeat<3>( (' ' >> icase(a1= map10) [ xp::ref(result) += ',', xp::ref(result) += a1 ]) ) |
129 | ); |
130 | TYPEOF_TEST(*((a1= map1a) | (a1= map2a) | 'e') [ xp::ref(result) += (a1 | "9" ) ]); |
131 | } |
132 | #ifndef BOOST_XPRESSIVE_NO_WREGEX |
133 | City result17a, result17b; |
134 | std::map<std::wstring, City> map17; |
135 | TYPEOF_TEST((a1= map17)[ xp::ref(result17a) = a1 ] >> +_s |
136 | >> (a1= map17)[ xp::ref(result17b) = a1 ]); |
137 | #else |
138 | // This test is empty |
139 | #endif |
140 | |
141 | } |
142 | |
143 | bool three_or_six(xp::csub_match const &sub) |
144 | { |
145 | return sub.length() == 3 || sub.length() == 6; |
146 | } |
147 | |
148 | /////////////////////////////////////////////////////////////////////////////// |
149 | // test_assert |
150 | // regular expressions from test_assert.cpp |
151 | void test_assert() |
152 | { |
153 | using namespace boost::xpressive; |
154 | std::string result; |
155 | TYPEOF_TEST((bow >> +_w >> eow)[ check(&three_or_six) ]); |
156 | TYPEOF_TEST((bow >> +_w >> eow)[ check(length(_)==3 || length(_)==6) ]); |
157 | int const days_per_month[] = |
158 | {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 31, 31}; |
159 | mark_tag month(1), day(2); |
160 | // Note: if you uncomment the lines below, |
161 | // the BOOST_TYPEOF_LIMIT_SIZE is exceeded |
162 | TYPEOF_TEST(( |
163 | // Month must be between 1 and 12 inclusive |
164 | (month= _d >> !_d) [ check(as<int>(_) >= 1 |
165 | && as<int>(_) <= 12) ] |
166 | //>> '/' |
167 | // // Day must be between 1 and 31 inclusive |
168 | //>> (day= _d >> !_d) [ check(as<int>(_) >= 1 |
169 | // && as<int>(_) <= 31) ] |
170 | //>> '/' |
171 | // // Only consider years between 1970 and 2038 |
172 | //>> (_d >> _d >> _d >> _d) [ check(as<int>(_) >= 1970 |
173 | // && as<int>(_) <= 2038) ] |
174 | ) |
175 | // Ensure the month actually has that many days. |
176 | [ check( ref(days_per_month)[as<int>(month)-1] >= as<int>(day) ) ]); |
177 | } |
178 | |
179 | |