numerics_tests.cpp 11 KB

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