]>
git.proxmox.com Git - ceph.git/blob - 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/
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>
13 #include <boost/core/lightweight_test.hpp>
18 using namespace BOOST_SPIRIT_CLASSIC_NS
;
21 struct ts_real_parser_policies
: public ureal_parser_policies
<T
>
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
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
;
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
); }
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(); }
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(); }
49 ////////////////////////////////// Thousands separated numbers
50 template <typename ScannerT
>
51 static typename parser_result
<uint_parser_t
, ScannerT
>::type
52 parse_n(ScannerT
& scan
)
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
;
58 if (RT hit
= uint3_p
.parse(scan
))
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
))
65 hit
.value((hit
.value() * 1000) + n
);
66 scan
.concat_match(hit
, next
);
72 return scan
.no_match();
76 real_parser
<double, ts_real_parser_policies
<double> > const
77 ts_real_p
= real_parser
<double, ts_real_parser_policies
<double> >();
80 struct no_trailing_dot
: public real_parser_policies
<T
>
82 static const bool allow_trailing_dot
= false;
85 real_parser
<double, no_trailing_dot
<double> > const
86 notrdot_real_p
= real_parser
<double, no_trailing_dot
<double> >();
89 struct no_leading_dot
: public real_parser_policies
<T
>
91 static const bool allow_leading_dot
= false;
94 real_parser
<double, no_leading_dot
<double> > const
95 nolddot_real_p
= real_parser
<double, no_leading_dot
<double> >();
97 ///////////////////////////////////////////////////////////////////////////////
101 cout
<< "/////////////////////////////////////////////////////////\n\n";
102 cout
<< "\t\tNumeric tests...\n\n";
103 cout
<< "/////////////////////////////////////////////////////////\n\n";
105 // *** The following assumes 32 bit integers. Modify these constant
106 // *** strings when appropriate. BEWARE PLATFORM DEPENDENT!
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";
121 #ifdef BOOST_HAS_LONG_LONG
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";
136 parse("123456", uint_p
[assign_a(u
)]);
137 BOOST_TEST(u
== 123456);
139 parse(max_unsigned
, uint_p
[assign_a(u
)]);
140 BOOST_TEST(u
== UINT_MAX
);
142 BOOST_TEST(!parse(unsigned_overflow
, uint_p
).full
);
148 parse("123456", int_p
[assign_a(i
)]);
149 BOOST_TEST(i
== 123456);
151 parse("-123456", int_p
[assign_a(i
)]);
152 BOOST_TEST(i
== -123456);
154 parse(max_int
, int_p
[assign_a(i
)]);
155 BOOST_TEST(i
== INT_MAX
);
157 parse(min_int
, int_p
[assign_a(i
)]);
158 BOOST_TEST(i
== INT_MIN
);
160 BOOST_TEST(!parse(int_overflow
, int_p
).full
);
161 BOOST_TEST(!parse(int_underflow
, int_p
).full
);
163 BOOST_TEST(!parse("-", int_p
).hit
);
167 parse("11111110", bin_p
[assign_a(u
)]);
168 BOOST_TEST(u
== 0xFE);
170 parse(max_binary
, bin_p
[assign_a(u
)]);
171 BOOST_TEST(u
== UINT_MAX
);
173 BOOST_TEST(!parse(binary_overflow
, bin_p
).full
);
177 parse("12545674515", oct_p
[assign_a(u
)]);
178 BOOST_TEST(u
== 012545674515);
180 parse(max_octal
, oct_p
[assign_a(u
)]);
181 BOOST_TEST(u
== UINT_MAX
);
183 BOOST_TEST(!parse(octal_overflow
, oct_p
).full
);
187 parse("95BC8DF", hex_p
[assign_a(u
)]);
188 BOOST_TEST(u
== 0x95BC8DF);
190 parse("abcdef12", hex_p
[assign_a(u
)]);
191 BOOST_TEST(u
== 0xabcdef12);
193 parse(max_hex
, hex_p
[assign_a(u
)]);
194 BOOST_TEST(u
== UINT_MAX
);
196 BOOST_TEST(!parse(hex_overflow
, hex_p
).full
);
198 // limited fieldwidth
200 uint_parser
<unsigned, 10, 1, 3> uint3_p
;
201 parse("123456", uint3_p
[assign_a(u
)]);
202 BOOST_TEST(u
== 123);
204 uint_parser
<unsigned, 10, 1, 4> uint4_p
;
205 parse("123456", uint4_p
[assign_a(u
)]);
206 BOOST_TEST(u
== 1234);
208 uint_parser
<unsigned, 10, 3, 3> uint3_3_p
;
210 // thousand separated numbers
212 #define r (uint3_p >> *(',' >> uint3_3_p))
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
223 #ifdef BOOST_HAS_LONG_LONG
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)
235 ::boost::long_long_type ll
;
236 int_parser
< ::boost::long_long_type
> long_long_p
;
238 parse("1234567890123456789", long_long_p
[assign_a(ll
)]);
239 BOOST_TEST(ll
== 1234567890123456789LL);
241 parse("-1234567890123456789", long_long_p
[assign_a(ll
)]);
242 BOOST_TEST(ll
== -1234567890123456789LL);
244 parse(max_long_long
, long_long_p
[assign_a(ll
)]);
245 BOOST_TEST(ll
== LONG_LONG_MAX
);
247 parse(min_long_long
, long_long_p
[assign_a(ll
)]);
248 BOOST_TEST(ll
== LONG_LONG_MIN
);
250 #if defined(__GNUG__) && (__GNUG__ == 3) && (__GNUC_MINOR__ < 3) \
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
);
258 BOOST_TEST(!parse(long_long_overflow
, long_long_p
).full
);
259 BOOST_TEST(!parse(long_long_underflow
, long_long_p
).full
);
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
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
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.
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
300 // Special thousands separated numbers
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.
312 /////////////////////////////////////////////////////////////////
313 return boost::report_errors();