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>
inspect_duration(boost::chrono::duration<Rep,Period> d,const std::string & name)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 
inspect_all()71 void inspect_all()
72 {
73     using namespace boost::chrono;
74     std::cout.precision(6);
75     inspect_duration(nanoseconds(), "nanoseconds");
76     inspect_duration(microseconds(), "microseconds");
77     inspect_duration(milliseconds(), "milliseconds");
78     inspect_duration(seconds(), "seconds");
79     inspect_duration(minutes(), "minutes");
80     inspect_duration(hours(), "hours");
81     inspect_duration(duration<double>(), "duration<double>");
82 }
83 
84 
85 
86 using namespace boost::chrono;
test_duration_division()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 
test_duration_multiply()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 
f(duration<double> d,double res)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 
g(nanoseconds d,boost::intmax_t res)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>
tmpl(duration<Rep,Period> d,boost::intmax_t res)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>
tmpl2(duration<long long,Period> d,boost::intmax_t res)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 
main()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>(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(microseconds(3), 0.000003);
170     g(microseconds(3), 3000);
171     duration<double> s(1./3);  // 1/3 of a second
172     g(duration_cast<nanoseconds>(s), 333333333);  // round towards zero in conversion to nanoseconds
173     //f(s);  // does not compile
174     tmpl(duration<double>(1./3), 333333334);
175     tmpl2(duration<long long, boost::pico>(333333333333LL), 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(milliseconds(3) * 2.5, "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