1 | // test_duration.cpp ----------------------------------------------------------// |
2 | |
3 | // Copyright 2008 Howard Hinnant |
4 | // Copyright 2008 Beman Dawes |
5 | // Copyright 2009 Vicente J. Botet Escriba |
6 | |
7 | // Distributed under the Boost Software License, Version 1.0. |
8 | // See http://www.boost.org/LICENSE_1_0.txt |
9 | |
10 | /* |
11 | This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which |
12 | was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. |
13 | Many thanks to Howard for making his code available under the Boost license. |
14 | The original code was modified to conform to Boost conventions and to section |
15 | 20.9 Time utilities [time] of the C++ committee's working paper N2798. |
16 | See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. |
17 | |
18 | time2_demo contained this comment: |
19 | |
20 | Much thanks to Andrei Alexandrescu, |
21 | Walter Brown, |
22 | Peter Dimov, |
23 | Jeff Garland, |
24 | Terry Golubiewski, |
25 | Daniel Krugler, |
26 | Anthony Williams. |
27 | */ |
28 | |
29 | #include <boost/assert.hpp> |
30 | #include <boost/chrono/chrono.hpp> |
31 | #include <boost/type_traits.hpp> |
32 | |
33 | #include <iostream> |
34 | |
35 | template <class Rep, class Period> |
36 | void inspect_duration(boost::chrono::duration<Rep, Period> d, const std::string& name) |
37 | { |
38 | typedef boost::chrono::duration<Rep, Period> Duration; |
39 | std::cout << "********* " << name << " *********\n" ; |
40 | std::cout << "The period of " << name << " is " << (double)Period::num/Period::den << " seconds.\n" ; |
41 | std::cout << "The frequency of " << name << " is " << (double)Period::den/Period::num << " Hz.\n" ; |
42 | std::cout << "The representation is " ; |
43 | if (boost::is_floating_point<Rep>::value) |
44 | { |
45 | std::cout << "floating point\n" ; |
46 | std::cout << "The precision is the most significant " ; |
47 | std::cout << std::numeric_limits<Rep>::digits10 << " decimal digits.\n" ; |
48 | } |
49 | else if (boost::is_integral<Rep>::value) |
50 | { |
51 | std::cout << "integral\n" ; |
52 | d = Duration(Rep(1)); |
53 | boost::chrono::duration<double> dsec = d; |
54 | std::cout << "The precision is " << dsec.count() << " seconds.\n" ; |
55 | } |
56 | else |
57 | { |
58 | std::cout << "a class type\n" ; |
59 | d = Duration(Rep(1)); |
60 | boost::chrono::duration<double> dsec = d; |
61 | std::cout << "The precision is " << dsec.count() << " seconds.\n" ; |
62 | } |
63 | d = Duration((std::numeric_limits<Rep>::max)()); |
64 | using namespace boost::chrono; |
65 | typedef duration<double, boost::ratio_multiply<boost::ratio<24*3652425,10000>, hours::period>::type> Years; |
66 | Years years = d; |
67 | std::cout << "The range is +/- " << years.count() << " years.\n" ; |
68 | std::cout << "sizeof(" << name << ") = " << sizeof(d) << '\n'; |
69 | } |
70 | |
71 | void inspect_all() |
72 | { |
73 | using namespace boost::chrono; |
74 | std::cout.precision(prec: 6); |
75 | inspect_duration(d: nanoseconds(), name: "nanoseconds" ); |
76 | inspect_duration(d: microseconds(), name: "microseconds" ); |
77 | inspect_duration(d: milliseconds(), name: "milliseconds" ); |
78 | inspect_duration(d: seconds(), name: "seconds" ); |
79 | inspect_duration(d: minutes(), name: "minutes" ); |
80 | inspect_duration(d: hours(), name: "hours" ); |
81 | inspect_duration(d: duration<double>(), name: "duration<double>" ); |
82 | } |
83 | |
84 | |
85 | |
86 | using namespace boost::chrono; |
87 | void test_duration_division() |
88 | { |
89 | typedef boost::common_type<boost::chrono::hours::rep, boost::chrono::minutes::rep>::type h_min_rep; |
90 | h_min_rep r3 = hours(3) / minutes(5); |
91 | std::cout << r3 << '\n'; |
92 | std::cout << hours(3) / minutes(5) << '\n'; |
93 | std::cout << hours(3) / milliseconds(5) << '\n'; |
94 | std::cout << milliseconds(5) / hours(3) << '\n'; |
95 | std::cout << hours(1) / milliseconds(1) << '\n'; |
96 | } |
97 | |
98 | void test_duration_multiply() |
99 | { |
100 | hours h15= 5 * hours(3); |
101 | (void)h15; |
102 | hours h6= hours(3) *2; |
103 | (void)h6; |
104 | } |
105 | |
106 | void f(duration<double> d, double res) // accept floating point seconds |
107 | { |
108 | // d.count() == 3.e-6 when passed microseconds(3) |
109 | BOOST_ASSERT(d.count()==res); |
110 | } |
111 | |
112 | void g(nanoseconds d, boost::intmax_t res) |
113 | { |
114 | // d.count() == 3000 when passed microseconds(3) |
115 | std::cout << d.count() << " " <<res << std::endl; |
116 | BOOST_ASSERT(d.count()==res); |
117 | } |
118 | |
119 | template <class Rep, class Period> |
120 | void tmpl(duration<Rep, Period> d, boost::intmax_t res) |
121 | { |
122 | // convert d to nanoseconds, rounding up if it is not an exact conversion |
123 | nanoseconds ns = duration_cast<nanoseconds>(d); |
124 | if (ns < d) |
125 | ++ns; |
126 | // ns.count() == 333333334 when passed 1/3 of a floating point second |
127 | BOOST_ASSERT(ns.count()==res); |
128 | } |
129 | |
130 | template <class Period> |
131 | void tmpl2(duration<long long, Period> d, boost::intmax_t res) |
132 | { |
133 | // convert d to nanoseconds, rounding up if it is not an exact conversion |
134 | nanoseconds ns = duration_cast<nanoseconds>(d); |
135 | if (ns < d) |
136 | ++ns; |
137 | // ns.count() == 333333334 when passed 333333333333 picoseconds |
138 | BOOST_ASSERT(ns.count()==res); |
139 | } |
140 | |
141 | |
142 | |
143 | int main() |
144 | { |
145 | minutes m1(3); // m1 stores 3 |
146 | minutes m2(2); // m2 stores 2 |
147 | minutes m3 = m1 + m2; // m3 stores 5 |
148 | BOOST_ASSERT(m3.count()==5); |
149 | |
150 | microseconds us1(3); // us1 stores 3 |
151 | microseconds us2(2); // us2 stores 2 |
152 | microseconds us3 = us1 + us2; // us3 stores 5 |
153 | BOOST_ASSERT(us3.count()==5); |
154 | |
155 | microseconds us4 = m3 + us3; // us4 stores 300000005 |
156 | BOOST_ASSERT(us4.count()==300000005); |
157 | microseconds us5 = m3; // us4 stores 300000000 |
158 | BOOST_ASSERT(us5.count()==300000000); |
159 | |
160 | //minutes m4 = m3 + us3; // won't compile |
161 | |
162 | minutes m4 = duration_cast<minutes>(fd: m3 + us3); // m4.count() == 5 |
163 | BOOST_ASSERT(m4.count()==5); |
164 | |
165 | typedef duration<double, boost::ratio<60> > dminutes; |
166 | dminutes dm4 = m3 + us3; // dm4.count() == 5.000000083333333 |
167 | BOOST_ASSERT(dm4.count()==5.000000083333333); |
168 | |
169 | f(d: microseconds(3), res: 0.000003); |
170 | g(d: microseconds(3), res: 3000); |
171 | duration<double> s(1./3); // 1/3 of a second |
172 | g(d: duration_cast<nanoseconds>(fd: s), res: 333333333); // round towards zero in conversion to nanoseconds |
173 | //f(s); // does not compile |
174 | tmpl(d: duration<double>(1./3), res: 333333334); |
175 | tmpl2(d: duration<long long, boost::pico>(333333333333LL), res: 333333334); // About 1/3 of a second worth of picoseconds |
176 | |
177 | //f(3,3); // Will not compile, 3 is not implicitly convertible to any `duration` |
178 | //g(3,3); // Will not compile, 3 is not implicitly convertible to any `duration` |
179 | //tmpl(3,3); // Will not compile, 3 is not implicitly convertible to any `duration` |
180 | //tmpl2(3,3); // Will not compile, 3 is not implicitly convertible to any `duration` |
181 | |
182 | { |
183 | double r = double(milliseconds(3) / milliseconds(3)); |
184 | std::cout << r << '\n'; |
185 | |
186 | duration<double, boost::milli> d = milliseconds(3) * 2.5; |
187 | duration<double, boost::milli> d2 = 2.5 * milliseconds(3) ; |
188 | (void)d2; |
189 | duration<double, boost::milli> d3 = milliseconds(3) / 2.5; |
190 | (void)d3; |
191 | duration<double, boost::milli> d4 = milliseconds(3) + milliseconds(5) ; |
192 | (void)d4; |
193 | inspect_duration(d: milliseconds(3) * 2.5, name: "milliseconds(3) * 2.5" ); |
194 | std::cout << d.count() << '\n'; |
195 | // milliseconds ms(3.5); // doesn't compile |
196 | std::cout << "milliseconds ms(3.5) doesn't compile\n" ; |
197 | } |
198 | |
199 | test_duration_division(); |
200 | test_duration_multiply(); |
201 | return 0; |
202 | } |
203 | |
204 | |