]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/classic/test/numerics_tests.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / spirit / classic / test / numerics_tests.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2003 Joel de Guzman
3 Copyright (c) 2001-2003 Hartmut Kaiser
4 http://spirit.sourceforge.net/
5
6 Use, modification and distribution is subject to the Boost Software
7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #include <boost/spirit/include/classic_core.hpp>
11 #include <boost/spirit/include/classic_assign_actor.hpp>
12
13 #include <boost/core/lightweight_test.hpp>
14 #include <iostream>
15 #include <climits>
16
17 using namespace std;
18 using namespace BOOST_SPIRIT_CLASSIC_NS;
19
20 template <typename T>
21 struct ts_real_parser_policies : public ureal_parser_policies<T>
22 {
23 // These policies can be used to parse thousand separated
24 // numbers with at most 2 decimal digits after the decimal
25 // point. e.g. 123,456,789.01
26
27 typedef uint_parser<int, 10, 1, 2> uint2_t;
28 typedef uint_parser<T, 10, 1, -1> uint_parser_t;
29 typedef int_parser<int, 10, 1, -1> int_parser_t;
30
31 ////////////////////////////////// 2 decimal places Max
32 template <typename ScannerT>
33 static typename parser_result<uint2_t, ScannerT>::type
34 parse_frac_n(ScannerT& scan)
35 { return uint2_t().parse(scan); }
36
37 ////////////////////////////////// No exponent
38 template <typename ScannerT>
39 static typename parser_result<chlit<>, ScannerT>::type
40 parse_exp(ScannerT& scan)
41 { return scan.no_match(); }
42
43 ////////////////////////////////// No exponent
44 template <typename ScannerT>
45 static typename parser_result<int_parser_t, ScannerT>::type
46 parse_exp_n(ScannerT& scan)
47 { return scan.no_match(); }
48
49 ////////////////////////////////// Thousands separated numbers
50 template <typename ScannerT>
51 static typename parser_result<uint_parser_t, ScannerT>::type
52 parse_n(ScannerT& scan)
53 {
54 typedef typename parser_result<uint_parser_t, ScannerT>::type RT;
55 static uint_parser<unsigned, 10, 1, 3> uint3_p;
56 static uint_parser<unsigned, 10, 3, 3> uint3_3_p;
57
58 if (RT hit = uint3_p.parse(scan))
59 {
60 T n;
61 typedef typename ScannerT::iterator_t iterator_t;
62 iterator_t save = scan.first;
63 while (match<> next = (',' >> uint3_3_p[assign_a(n)]).parse(scan))
64 {
65 hit.value((hit.value() * 1000) + n);
66 scan.concat_match(hit, next);
67 save = scan.first;
68 }
69 scan.first = save;
70 return hit;
71 }
72 return scan.no_match();
73 }
74 };
75
76 real_parser<double, ts_real_parser_policies<double> > const
77 ts_real_p = real_parser<double, ts_real_parser_policies<double> >();
78
79 template <typename T>
80 struct no_trailing_dot : public real_parser_policies<T>
81 {
82 static const bool allow_trailing_dot = false;
83 };
84
85 real_parser<double, no_trailing_dot<double> > const
86 notrdot_real_p = real_parser<double, no_trailing_dot<double> >();
87
88 template <typename T>
89 struct no_leading_dot : public real_parser_policies<T>
90 {
91 static const bool allow_leading_dot = false;
92 };
93
94 real_parser<double, no_leading_dot<double> > const
95 nolddot_real_p = real_parser<double, no_leading_dot<double> >();
96
97 ///////////////////////////////////////////////////////////////////////////////
98 int
99 main()
100 {
101 cout << "/////////////////////////////////////////////////////////\n\n";
102 cout << "\t\tNumeric tests...\n\n";
103 cout << "/////////////////////////////////////////////////////////\n\n";
104
105 // *** The following assumes 32 bit integers. Modify these constant
106 // *** strings when appropriate. BEWARE PLATFORM DEPENDENT!
107
108 char const* max_unsigned = "4294967295";
109 char const* unsigned_overflow = "4294967296";
110 char const* max_int = "2147483647";
111 char const* int_overflow = "2147483648";
112 char const* min_int = "-2147483648";
113 char const* int_underflow = "-2147483649";
114 char const* max_binary = "11111111111111111111111111111111";
115 char const* binary_overflow = "100000000000000000000000000000000";
116 char const* max_octal = "37777777777";
117 char const* octal_overflow = "100000000000";
118 char const* max_hex = "FFFFFFFF";
119 char const* hex_overflow = "100000000";
120
121 #ifdef BOOST_HAS_LONG_LONG
122
123 char const* max_long_long = "9223372036854775807";
124 char const* long_long_overflow = "9223372036854775808";
125 char const* min_long_long = "-9223372036854775808";
126 char const* long_long_underflow = "-9223372036854775809";
127
128 #endif
129
130 // BEGIN TESTS...
131
132 unsigned u;
133
134 // unsigned integer
135
136 parse("123456", uint_p[assign_a(u)]);
137 BOOST_TEST(u == 123456);
138
139 parse(max_unsigned, uint_p[assign_a(u)]);
140 BOOST_TEST(u == UINT_MAX);
141
142 BOOST_TEST(!parse(unsigned_overflow, uint_p).full);
143
144 // signed integer
145
146 int i;
147
148 parse("123456", int_p[assign_a(i)]);
149 BOOST_TEST(i == 123456);
150
151 parse("-123456", int_p[assign_a(i)]);
152 BOOST_TEST(i == -123456);
153
154 parse(max_int, int_p[assign_a(i)]);
155 BOOST_TEST(i == INT_MAX);
156
157 parse(min_int, int_p[assign_a(i)]);
158 BOOST_TEST(i == INT_MIN);
159
160 BOOST_TEST(!parse(int_overflow, int_p).full);
161 BOOST_TEST(!parse(int_underflow, int_p).full);
162
163 BOOST_TEST(!parse("-", int_p).hit);
164
165 // binary
166
167 parse("11111110", bin_p[assign_a(u)]);
168 BOOST_TEST(u == 0xFE);
169
170 parse(max_binary, bin_p[assign_a(u)]);
171 BOOST_TEST(u == UINT_MAX);
172
173 BOOST_TEST(!parse(binary_overflow, bin_p).full);
174
175 // octal
176
177 parse("12545674515", oct_p[assign_a(u)]);
178 BOOST_TEST(u == 012545674515);
179
180 parse(max_octal, oct_p[assign_a(u)]);
181 BOOST_TEST(u == UINT_MAX);
182
183 BOOST_TEST(!parse(octal_overflow, oct_p).full);
184
185 // hex
186
187 parse("95BC8DF", hex_p[assign_a(u)]);
188 BOOST_TEST(u == 0x95BC8DF);
189
190 parse("abcdef12", hex_p[assign_a(u)]);
191 BOOST_TEST(u == 0xabcdef12);
192
193 parse(max_hex, hex_p[assign_a(u)]);
194 BOOST_TEST(u == UINT_MAX);
195
196 BOOST_TEST(!parse(hex_overflow, hex_p).full);
197
198 // limited fieldwidth
199
200 uint_parser<unsigned, 10, 1, 3> uint3_p;
201 parse("123456", uint3_p[assign_a(u)]);
202 BOOST_TEST(u == 123);
203
204 uint_parser<unsigned, 10, 1, 4> uint4_p;
205 parse("123456", uint4_p[assign_a(u)]);
206 BOOST_TEST(u == 1234);
207
208 uint_parser<unsigned, 10, 3, 3> uint3_3_p;
209
210 // thousand separated numbers
211
212 #define r (uint3_p >> *(',' >> uint3_3_p))
213
214 BOOST_TEST(parse("1,234,567,890", r).full); // OK
215 BOOST_TEST(parse("12,345,678,900", r).full); // OK
216 BOOST_TEST(parse("123,456,789,000", r).full); // OK
217 BOOST_TEST(!parse("1000,234,567,890", r).full); // Bad
218 BOOST_TEST(!parse("1,234,56,890", r).full); // Bad
219 BOOST_TEST(!parse("1,66", r).full); // Bad
220
221 // long long
222
223 #ifdef BOOST_HAS_LONG_LONG
224
225 // Some compilers have long long, but don't define the
226 // LONG_LONG_MIN and LONG_LONG_MAX macros in limits.h. This
227 // assumes that long long is 64 bits.
228 #if !defined(LONG_LONG_MIN) && !defined(LONG_LONG_MAX) \
229 && !defined(ULONG_LONG_MAX)
230 #define ULONG_LONG_MAX 0xffffffffffffffffLLU
231 #define LONG_LONG_MAX 0x7fffffffffffffffLL
232 #define LONG_LONG_MIN (-LONG_LONG_MAX - 1)
233 #endif
234
235 ::boost::long_long_type ll;
236 int_parser< ::boost::long_long_type> long_long_p;
237
238 parse("1234567890123456789", long_long_p[assign_a(ll)]);
239 BOOST_TEST(ll == 1234567890123456789LL);
240
241 parse("-1234567890123456789", long_long_p[assign_a(ll)]);
242 BOOST_TEST(ll == -1234567890123456789LL);
243
244 parse(max_long_long, long_long_p[assign_a(ll)]);
245 BOOST_TEST(ll == LONG_LONG_MAX);
246
247 parse(min_long_long, long_long_p[assign_a(ll)]);
248 BOOST_TEST(ll == LONG_LONG_MIN);
249
250 #if defined(__GNUG__) && (__GNUG__ == 3) && (__GNUC_MINOR__ < 3) \
251 && !defined(__EDG__)
252 // gcc 3.2.3 crashes on parse(long_long_overflow, long_long_p)
253 // wrapping long_long_p into a rule avoids the crash
254 rule<> gcc_3_2_3_long_long_r = long_long_p;
255 BOOST_TEST(!parse(long_long_overflow, gcc_3_2_3_long_long_r).full);
256 BOOST_TEST(!parse(long_long_underflow, gcc_3_2_3_long_long_r).full);
257 #else
258 BOOST_TEST(!parse(long_long_overflow, long_long_p).full);
259 BOOST_TEST(!parse(long_long_underflow, long_long_p).full);
260 #endif
261
262 #endif
263
264 // real numbers
265
266 double d;
267
268 BOOST_TEST(parse("1234", ureal_p[assign_a(d)]).full && d == 1234); // Good.
269 BOOST_TEST(parse("1.2e3", ureal_p[assign_a(d)]).full && d == 1.2e3); // Good.
270 BOOST_TEST(parse("1.2e-3", ureal_p[assign_a(d)]).full && d == 1.2e-3); // Good.
271 BOOST_TEST(parse("1.e2", ureal_p[assign_a(d)]).full && d == 1.e2); // Good.
272 BOOST_TEST(parse(".2e3", ureal_p[assign_a(d)]).full && d == .2e3); // Good.
273 BOOST_TEST(parse("2e3", ureal_p[assign_a(d)]).full && d == 2e3); // Good. No fraction
274 BOOST_TEST(!parse("e3", ureal_p).full); // Bad! No number
275 BOOST_TEST(!parse("-1.2e3", ureal_p).full); // Bad! Negative number
276 BOOST_TEST(!parse("+1.2e3", ureal_p).full); // Bad! Positive sign
277 BOOST_TEST(!parse("1.2e", ureal_p).full); // Bad! No exponent
278 BOOST_TEST(!parse("-.3", ureal_p).full); // Bad! Negative
279
280 BOOST_TEST(parse("-1234", real_p[assign_a(d)]).full && d == -1234); // Good.
281 BOOST_TEST(parse("-1.2e3", real_p[assign_a(d)]).full && d == -1.2e3); // Good.
282 BOOST_TEST(parse("+1.2e3", real_p[assign_a(d)]).full && d == 1.2e3); // Good.
283 BOOST_TEST(parse("-0.1", real_p[assign_a(d)]).full && d == -0.1); // Good.
284 BOOST_TEST(parse("-1.2e-3", real_p[assign_a(d)]).full && d == -1.2e-3); // Good.
285 BOOST_TEST(parse("-1.e2", real_p[assign_a(d)]).full && d == -1.e2); // Good.
286 BOOST_TEST(parse("-.2e3", real_p[assign_a(d)]).full && d == -.2e3); // Good.
287 BOOST_TEST(parse("-2e3", real_p[assign_a(d)]).full && d == -2e3); // Good. No fraction
288 BOOST_TEST(!parse("-e3", real_p).full); // Bad! No number
289 BOOST_TEST(!parse("-1.2e", real_p).full); // Bad! No exponent
290
291 BOOST_TEST(!parse("1234", strict_ureal_p[assign_a(d)]).full); // Bad. Strict real
292 BOOST_TEST(parse("1.2", strict_ureal_p[assign_a(d)]).full && d == 1.2); // Good.
293 BOOST_TEST(!parse("-1234", strict_real_p[assign_a(d)]).full); // Bad. Strict real
294 BOOST_TEST(parse("123.", strict_real_p[assign_a(d)]).full && d == 123); // Good.
295 BOOST_TEST(parse("3.E6", strict_real_p[assign_a(d)]).full && d == 3e6); // Good.
296
297 BOOST_TEST(!parse("1234.", notrdot_real_p[assign_a(d)]).full); // Bad trailing dot
298 BOOST_TEST(!parse(".1234", nolddot_real_p[assign_a(d)]).full); // Bad leading dot
299
300 // Special thousands separated numbers
301
302 BOOST_TEST(parse("123,456,789.01", ts_real_p[assign_a(d)]).full && d == 123456789.01); // Good.
303 BOOST_TEST(parse("12,345,678.90", ts_real_p[assign_a(d)]).full && d == 12345678.90); // Good.
304 BOOST_TEST(parse("1,234,567.89", ts_real_p[assign_a(d)]).full && d == 1234567.89); // Good.
305 BOOST_TEST(!parse("1234,567,890", ts_real_p).full); // Bad.
306 BOOST_TEST(!parse("1,234,5678,9", ts_real_p).full); // Bad.
307 BOOST_TEST(!parse("1,234,567.89e6", ts_real_p).full); // Bad.
308 BOOST_TEST(!parse("1,66", ts_real_p).full); // Bad.
309
310 // END TESTS.
311
312 /////////////////////////////////////////////////////////////////
313 return boost::report_errors();
314 }