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__anonbbf578680111::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__anonbbf578680111::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__anonbbf578680111::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__anonbbf578680111::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