1 //  duration.hpp  --------------------------------------------------------------//
2 
3 //  Copyright 2008 Howard Hinnant
4 //  Copyright 2008 Beman Dawes
5 //  Copyright 2009-2012 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 
12 This code 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 
30 #ifndef BOOST_CHRONO_TIME_POINT_HPP
31 #define BOOST_CHRONO_TIME_POINT_HPP
32 
33 #include <boost/chrono/duration.hpp>
34 
35 #ifndef BOOST_CHRONO_HEADER_ONLY
36 // this must occur after all of the includes and before any code appears:
37 #include <boost/config/abi_prefix.hpp> // must be the last #include
38 #endif
39 
40 //----------------------------------------------------------------------------//
41 //                                                                            //
42 //                        20.9 Time utilities [time]                          //
43 //                                 synopsis                                   //
44 //                                                                            //
45 //----------------------------------------------------------------------------//
46 
47 namespace boost {
48 namespace chrono {
49 
50   template <class Clock, class Duration = typename Clock::duration>
51     class time_point;
52 
53 
54 } // namespace chrono
55 
56 
57 // common_type trait specializations
58 
59 template <class Clock, class Duration1, class Duration2>
60   struct common_type<chrono::time_point<Clock, Duration1>,
61                      chrono::time_point<Clock, Duration2> >;
62 
63 
64 //----------------------------------------------------------------------------//
65 //      20.9.2.3 Specializations of common_type [time.traits.specializations] //
66 //----------------------------------------------------------------------------//
67 
68 
69 template <class Clock, class Duration1, class Duration2>
70 struct common_type<chrono::time_point<Clock, Duration1>,
71                    chrono::time_point<Clock, Duration2> >
72 {
73   typedef chrono::time_point<Clock,
74     typename common_type<Duration1, Duration2>::type> type;
75 };
76 
77 
78 
79 namespace chrono {
80 
81     // time_point arithmetic
82     template <class Clock, class Duration1, class Rep2, class Period2>
83     inline BOOST_CONSTEXPR
84     time_point<Clock,
85         typename common_type<Duration1, duration<Rep2, Period2> >::type>
86     operator+(
87             const time_point<Clock, Duration1>& lhs,
88             const duration<Rep2, Period2>& rhs);
89     template <class Rep1, class Period1, class Clock, class Duration2>
90     inline BOOST_CONSTEXPR
91     time_point<Clock,
92         typename common_type<duration<Rep1, Period1>, Duration2>::type>
93     operator+(
94             const duration<Rep1, Period1>& lhs,
95             const time_point<Clock, Duration2>& rhs);
96     template <class Clock, class Duration1, class Rep2, class Period2>
97     inline BOOST_CONSTEXPR
98     time_point<Clock,
99         typename common_type<Duration1, duration<Rep2, Period2> >::type>
100     operator-(
101             const time_point<Clock, Duration1>& lhs,
102             const duration<Rep2, Period2>& rhs);
103     template <class Clock, class Duration1, class Duration2>
104     inline BOOST_CONSTEXPR
105     typename common_type<Duration1, Duration2>::type
106     operator-(
107             const time_point<Clock, Duration1>& lhs,
108             const time_point<Clock,
109             Duration2>& rhs);
110 
111     // time_point comparisons
112     template <class Clock, class Duration1, class Duration2>
113     inline BOOST_CONSTEXPR
114     bool operator==(
115           const time_point<Clock, Duration1>& lhs,
116           const time_point<Clock, Duration2>& rhs);
117     template <class Clock, class Duration1, class Duration2>
118     inline BOOST_CONSTEXPR
119     bool operator!=(
120           const time_point<Clock, Duration1>& lhs,
121           const time_point<Clock, Duration2>& rhs);
122     template <class Clock, class Duration1, class Duration2>
123     inline BOOST_CONSTEXPR
124     bool operator< (
125           const time_point<Clock, Duration1>& lhs,
126           const time_point<Clock, Duration2>& rhs);
127     template <class Clock, class Duration1, class Duration2>
128     inline BOOST_CONSTEXPR
129     bool operator<=(
130           const time_point<Clock, Duration1>& lhs,
131           const time_point<Clock, Duration2>& rhs);
132     template <class Clock, class Duration1, class Duration2>
133     inline BOOST_CONSTEXPR
134     bool operator> (
135           const time_point<Clock, Duration1>& lhs,
136           const time_point<Clock, Duration2>& rhs);
137     template <class Clock, class Duration1, class Duration2>
138     inline BOOST_CONSTEXPR
139     bool operator>=(
140           const time_point<Clock, Duration1>& lhs,
141           const time_point<Clock, Duration2>& rhs);
142 
143     // time_point_cast
144     template <class ToDuration, class Clock, class Duration>
145     inline BOOST_CONSTEXPR
146     time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
147 
148 //----------------------------------------------------------------------------//
149 //                                                                            //
150 //      20.9.4 Class template time_point [time.point]                         //
151 //                                                                            //
152 //----------------------------------------------------------------------------//
153 
154     template <class Clock, class Duration>
155     class time_point
156     {
157         BOOST_CHRONO_STATIC_ASSERT(boost::chrono::detail::is_duration<Duration>::value,
158                 BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION, (Duration));
159     public:
160         typedef Clock                     clock;
161         typedef Duration                  duration;
162         typedef typename duration::rep    rep;
163         typedef typename duration::period period;
164         typedef Duration                  difference_type;
165 
166     private:
167         duration d_;
168 
169     public:
170         BOOST_FORCEINLINE BOOST_CONSTEXPR
time_point()171         time_point() : d_(duration::zero())
172         {}
173         BOOST_FORCEINLINE BOOST_CONSTEXPR
time_point(const duration & d)174         explicit time_point(const duration& d)
175             : d_(d)
176         {}
177 
178         // conversions
179         template <class Duration2>
180         BOOST_FORCEINLINE BOOST_CONSTEXPR
time_point(const time_point<clock,Duration2> & t,typename boost::enable_if<boost::is_convertible<Duration2,duration>>::type * =0)181         time_point(const time_point<clock, Duration2>& t
182                 , typename boost::enable_if
183                 <
184                     boost::is_convertible<Duration2, duration>
185                 >::type* = 0
186         )
187             : d_(t.time_since_epoch())
188         {
189         }
190         // observer
191 
192         BOOST_CONSTEXPR
time_since_epoch() const193         duration time_since_epoch() const
194         {
195             return d_;
196         }
197 
198         // arithmetic
199 
200 #ifdef BOOST_CHRONO_EXTENSIONS
201         BOOST_CONSTEXPR
operator +() const202         time_point  operator+() const {return *this;}
203         BOOST_CONSTEXPR
operator -() const204         time_point  operator-() const {return time_point(-d_);}
operator ++()205         time_point& operator++()      {++d_; return *this;}
operator ++(int)206         time_point  operator++(int)   {return time_point(d_++);}
operator --()207         time_point& operator--()      {--d_; return *this;}
operator --(int)208         time_point  operator--(int)   {return time_point(d_--);}
209 
operator +=(const rep & r)210         time_point& operator+=(const rep& r) {d_ += duration(r); return *this;}
operator -=(const rep & r)211         time_point& operator-=(const rep& r) {d_ -= duration(r); return *this;}
212 
213 #endif
214 
operator +=(const duration & d)215         time_point& operator+=(const duration& d) {d_ += d; return *this;}
operator -=(const duration & d)216         time_point& operator-=(const duration& d) {d_ -= d; return *this;}
217 
218         // special values
219 
220         static BOOST_CHRONO_LIB_CONSTEXPR time_point
BOOST_PREVENT_MACRO_SUBSTITUTION()221         min BOOST_PREVENT_MACRO_SUBSTITUTION ()
222         {
223             return time_point((duration::min)());
224         }
225         static BOOST_CHRONO_LIB_CONSTEXPR time_point
BOOST_PREVENT_MACRO_SUBSTITUTION()226         max BOOST_PREVENT_MACRO_SUBSTITUTION ()
227         {
228             return time_point((duration::max)());
229         }
230     };
231 
232 //----------------------------------------------------------------------------//
233 //      20.9.4.5 time_point non-member arithmetic [time.point.nonmember]      //
234 //----------------------------------------------------------------------------//
235 
236     // time_point operator+(time_point x, duration y);
237 
238     template <class Clock, class Duration1, class Rep2, class Period2>
239     inline BOOST_CONSTEXPR
240     time_point<Clock,
241         typename common_type<Duration1, duration<Rep2, Period2> >::type>
operator +(const time_point<Clock,Duration1> & lhs,const duration<Rep2,Period2> & rhs)242     operator+(const time_point<Clock, Duration1>& lhs,
243             const duration<Rep2, Period2>& rhs)
244     {
245       typedef typename common_type<Duration1, duration<Rep2, Period2> >::type CDuration;
246       typedef time_point<
247           Clock,
248           CDuration
249       > TimeResult;
250         return TimeResult(lhs.time_since_epoch() + CDuration(rhs));
251     }
252 
253     // time_point operator+(duration x, time_point y);
254 
255     template <class Rep1, class Period1, class Clock, class Duration2>
256     inline BOOST_CONSTEXPR
257     time_point<Clock,
258         typename common_type<duration<Rep1, Period1>, Duration2>::type>
operator +(const duration<Rep1,Period1> & lhs,const time_point<Clock,Duration2> & rhs)259     operator+(const duration<Rep1, Period1>& lhs,
260             const time_point<Clock, Duration2>& rhs)
261     {
262         return rhs + lhs;
263     }
264 
265     // time_point operator-(time_point x, duration y);
266 
267     template <class Clock, class Duration1, class Rep2, class Period2>
268     inline BOOST_CONSTEXPR
269     time_point<Clock,
270         typename common_type<Duration1, duration<Rep2, Period2> >::type>
operator -(const time_point<Clock,Duration1> & lhs,const duration<Rep2,Period2> & rhs)271     operator-(const time_point<Clock, Duration1>& lhs,
272             const duration<Rep2, Period2>& rhs)
273     {
274         return lhs + (-rhs);
275     }
276 
277     // duration operator-(time_point x, time_point y);
278 
279     template <class Clock, class Duration1, class Duration2>
280     inline BOOST_CONSTEXPR
281     typename common_type<Duration1, Duration2>::type
operator -(const time_point<Clock,Duration1> & lhs,const time_point<Clock,Duration2> & rhs)282     operator-(const time_point<Clock, Duration1>& lhs,
283             const time_point<Clock, Duration2>& rhs)
284     {
285         return lhs.time_since_epoch() - rhs.time_since_epoch();
286     }
287 
288 //----------------------------------------------------------------------------//
289 //      20.9.4.6 time_point comparisons [time.point.comparisons]              //
290 //----------------------------------------------------------------------------//
291 
292     // time_point ==
293 
294     template <class Clock, class Duration1, class Duration2>
295     inline BOOST_CONSTEXPR
296     bool
operator ==(const time_point<Clock,Duration1> & lhs,const time_point<Clock,Duration2> & rhs)297     operator==(const time_point<Clock, Duration1>& lhs,
298              const time_point<Clock, Duration2>& rhs)
299     {
300         return lhs.time_since_epoch() == rhs.time_since_epoch();
301     }
302 
303     // time_point !=
304 
305     template <class Clock, class Duration1, class Duration2>
306     inline BOOST_CONSTEXPR
307     bool
operator !=(const time_point<Clock,Duration1> & lhs,const time_point<Clock,Duration2> & rhs)308     operator!=(const time_point<Clock, Duration1>& lhs,
309              const time_point<Clock, Duration2>& rhs)
310     {
311         return !(lhs == rhs);
312     }
313 
314     // time_point <
315 
316     template <class Clock, class Duration1, class Duration2>
317     inline BOOST_CONSTEXPR
318     bool
operator <(const time_point<Clock,Duration1> & lhs,const time_point<Clock,Duration2> & rhs)319     operator<(const time_point<Clock, Duration1>& lhs,
320             const time_point<Clock, Duration2>& rhs)
321     {
322         return lhs.time_since_epoch() < rhs.time_since_epoch();
323     }
324 
325     // time_point >
326 
327     template <class Clock, class Duration1, class Duration2>
328     inline BOOST_CONSTEXPR
329     bool
operator >(const time_point<Clock,Duration1> & lhs,const time_point<Clock,Duration2> & rhs)330     operator>(const time_point<Clock, Duration1>& lhs,
331             const time_point<Clock, Duration2>& rhs)
332     {
333         return rhs < lhs;
334     }
335 
336     // time_point <=
337 
338     template <class Clock, class Duration1, class Duration2>
339     inline BOOST_CONSTEXPR
340     bool
operator <=(const time_point<Clock,Duration1> & lhs,const time_point<Clock,Duration2> & rhs)341     operator<=(const time_point<Clock, Duration1>& lhs,
342              const time_point<Clock, Duration2>& rhs)
343     {
344         return !(rhs < lhs);
345     }
346 
347     // time_point >=
348 
349     template <class Clock, class Duration1, class Duration2>
350     inline BOOST_CONSTEXPR
351     bool
operator >=(const time_point<Clock,Duration1> & lhs,const time_point<Clock,Duration2> & rhs)352     operator>=(const time_point<Clock, Duration1>& lhs,
353              const time_point<Clock, Duration2>& rhs)
354     {
355         return !(lhs < rhs);
356     }
357 
358 //----------------------------------------------------------------------------//
359 //      20.9.4.7 time_point_cast [time.point.cast]                            //
360 //----------------------------------------------------------------------------//
361 
362     template <class ToDuration, class Clock, class Duration>
363     inline BOOST_CONSTEXPR
364     time_point<Clock, ToDuration>
time_point_cast(const time_point<Clock,Duration> & t)365     time_point_cast(const time_point<Clock, Duration>& t)
366     {
367         return time_point<Clock, ToDuration>(
368                 duration_cast<ToDuration>(t.time_since_epoch()));
369     }
370 
371 } // namespace chrono
372 } // namespace boost
373 
374 #ifndef BOOST_CHRONO_HEADER_ONLY
375 // the suffix header occurs after all of our code:
376 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
377 #endif
378 
379 #endif // BOOST_CHRONO_TIME_POINT_HPP
380