1 /*=============================================================================
2 Copyright (c) 2001-2010 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 "../measure.hpp"
8 #include <string>
9 #include <vector>
10 #include <cstdlib>
11 #include <boost/spirit/include/qi.hpp>
12
13 namespace
14 {
15 int const ndigits = 9;
16 std::string numbers[ndigits] =
17 {
18 "1234",
19 "-1.2e3",
20 "0.1",
21 "-1.2e-3",
22 "-.2e3",
23 "-2e6",
24 "1.2345e5",
25 "-5.7222349715140557e+307",
26 "2.0332938517515416e-308"
27 };
28
29 char const* first[ndigits];
30 char const* last[ndigits];
31
32 ///////////////////////////////////////////////////////////////////////////
33 struct atof_test : test::base
34 {
benchmark__anone9910d970111::atof_test35 void benchmark()
36 {
37 for (int i = 0; i < ndigits; ++i)
38 {
39 double d = atof(first[i]);
40 this->val += *reinterpret_cast<int*>(&d);
41 }
42 }
43 };
44
45 ///////////////////////////////////////////////////////////////////////////
46 struct strtod_test : test::base
47 {
benchmark__anone9910d970111::strtod_test48 void benchmark()
49 {
50 for (int i = 0; i < ndigits; ++i)
51 {
52 double d = strtod(first[i], const_cast<char**>(&last[i]));
53 this->val += *reinterpret_cast<int*>(&d);
54 }
55 }
56 };
57
58 ///////////////////////////////////////////////////////////////////////////
59 struct spirit_double_test : test::base
60 {
parse__anone9910d970111::spirit_double_test61 static double parse(char const* first, char const* last)
62 {
63 double n;
64 namespace qi = boost::spirit::qi;
65 using qi::double_;
66 qi::parse(first, last, double_, n);
67 return n;
68 }
69
benchmark__anone9910d970111::spirit_double_test70 void benchmark()
71 {
72 for (int i = 0; i < ndigits; ++i)
73 {
74 double d = parse(first[i], last[i]);
75 this->val += *reinterpret_cast<int*>(&d);
76 }
77 }
78 };
79 }
80
main()81 int main()
82 {
83 std::cout << "///////////////////////////////////////////////////////////////////////////" << std::endl;
84 std::cout << "Numbers to test:" << std::endl;
85 for (int i = 0; i < ndigits; ++i)
86 {
87 first[i] = numbers[i].c_str();
88 last[i] = first[i];
89 while (*last[i])
90 last[i]++;
91 std::cout << numbers[i] << std::endl;
92 }
93 std::cout.precision(17);
94 std::cout << "///////////////////////////////////////////////////////////////////////////" << std::endl;
95 std::cout << "atof/strtod/qi.double results:" << std::endl;
96 for (int i = 0; i < ndigits; ++i)
97 {
98 std::cout
99 << atof(first[i]) << ','
100 << strtod(first[i], const_cast<char**>(&last[i])) << ','
101 << spirit_double_test::parse(first[i], last[i]) << ','
102 << std::endl;
103 }
104 std::cout << "///////////////////////////////////////////////////////////////////////////" << std::endl;
105
106 BOOST_SPIRIT_TEST_BENCHMARK(
107 10000000, // This is the maximum repetitions to execute
108 (atof_test)
109 (strtod_test)
110 (spirit_double_test)
111 )
112
113 // This is ultimately responsible for preventing all the test code
114 // from being optimized away. Change this to return 0 and you
115 // unplug the whole test's life support system.
116 return test::live_code != 0;
117 }
118
119