1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___CHRONO_TIME_POINT_H
11#define _LIBCPP___CHRONO_TIME_POINT_H
12
13#include <__chrono/duration.h>
14#include <__compare/ordering.h>
15#include <__compare/three_way_comparable.h>
16#include <__config>
17#include <__type_traits/common_type.h>
18#include <__type_traits/enable_if.h>
19#include <__type_traits/is_convertible.h>
20#include <limits>
21
22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23# pragma GCC system_header
24#endif
25
26_LIBCPP_PUSH_MACROS
27#include <__undef_macros>
28
29_LIBCPP_BEGIN_NAMESPACE_STD
30
31namespace chrono {
32
33template <class _Clock, class _Duration = typename _Clock::duration>
34class time_point {
35 static_assert(__is_duration_v<_Duration>, "Second template parameter of time_point must be a std::chrono::duration");
36
37public:
38 typedef _Clock clock;
39 typedef _Duration duration;
40 typedef typename duration::rep rep;
41 typedef typename duration::period period;
42
43private:
44 duration __d_;
45
46public:
47 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point() : __d_(duration::zero()) {}
48 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit time_point(const duration& __d) : __d_(__d) {}
49
50 // conversions
51 template <class _Duration2, __enable_if_t<is_convertible<_Duration2, duration>::value, int> = 0>
52 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point(const time_point<clock, _Duration2>& __t)
53 : __d_(__t.time_since_epoch()) {}
54
55 // observer
56
57 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const { return __d_; }
58
59 // arithmetic
60
61#if _LIBCPP_STD_VER >= 20
62 _LIBCPP_HIDE_FROM_ABI constexpr time_point& operator++() {
63 ++__d_;
64 return *this;
65 }
66 _LIBCPP_HIDE_FROM_ABI constexpr time_point operator++(int) { return time_point{__d_++}; }
67 _LIBCPP_HIDE_FROM_ABI constexpr time_point& operator--() {
68 --__d_;
69 return *this;
70 }
71 _LIBCPP_HIDE_FROM_ABI constexpr time_point operator--(int) { return time_point{__d_--}; }
72#endif // _LIBCPP_STD_VER >= 20
73
74 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator+=(const duration& __d) {
75 __d_ += __d;
76 return *this;
77 }
78 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator-=(const duration& __d) {
79 __d_ -= __d;
80 return *this;
81 }
82
83 // special values
84
85 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT { return time_point(duration::min()); }
86 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT { return time_point(duration::max()); }
87};
88
89} // namespace chrono
90
91template <class _Clock, class _Duration1, class _Duration2>
92struct common_type<chrono::time_point<_Clock, _Duration1>, chrono::time_point<_Clock, _Duration2> > {
93 typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type;
94};
95
96namespace chrono {
97
98template <class _ToDuration, class _Clock, class _Duration>
99inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration>
100time_point_cast(const time_point<_Clock, _Duration>& __t) {
101 return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
102}
103
104#if _LIBCPP_STD_VER >= 17
105template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
106inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> floor(const time_point<_Clock, _Duration>& __t) {
107 return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())};
108}
109
110template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
111inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> ceil(const time_point<_Clock, _Duration>& __t) {
112 return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())};
113}
114
115template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
116inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> round(const time_point<_Clock, _Duration>& __t) {
117 return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())};
118}
119
120template <class _Rep, class _Period, enable_if_t<numeric_limits<_Rep>::is_signed, int> = 0>
121inline _LIBCPP_HIDE_FROM_ABI constexpr duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) {
122 return __d >= __d.zero() ? +__d : -__d;
123}
124#endif // _LIBCPP_STD_VER >= 17
125
126// time_point ==
127
128template <class _Clock, class _Duration1, class _Duration2>
129inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
130operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
131 return __lhs.time_since_epoch() == __rhs.time_since_epoch();
132}
133
134#if _LIBCPP_STD_VER <= 17
135
136// time_point !=
137
138template <class _Clock, class _Duration1, class _Duration2>
139inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
140operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
141 return !(__lhs == __rhs);
142}
143
144#endif // _LIBCPP_STD_VER <= 17
145
146// time_point <
147
148template <class _Clock, class _Duration1, class _Duration2>
149inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
150operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
151 return __lhs.time_since_epoch() < __rhs.time_since_epoch();
152}
153
154// time_point >
155
156template <class _Clock, class _Duration1, class _Duration2>
157inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
158operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
159 return __rhs < __lhs;
160}
161
162// time_point <=
163
164template <class _Clock, class _Duration1, class _Duration2>
165inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
166operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
167 return !(__rhs < __lhs);
168}
169
170// time_point >=
171
172template <class _Clock, class _Duration1, class _Duration2>
173inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
174operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
175 return !(__lhs < __rhs);
176}
177
178#if _LIBCPP_STD_VER >= 20
179
180template <class _Clock, class _Duration1, three_way_comparable_with<_Duration1> _Duration2>
181_LIBCPP_HIDE_FROM_ABI constexpr auto
182operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
183 return __lhs.time_since_epoch() <=> __rhs.time_since_epoch();
184}
185
186#endif // _LIBCPP_STD_VER >= 20
187
188// time_point operator+(time_point x, duration y);
189
190template <class _Clock, class _Duration1, class _Rep2, class _Period2>
191inline _LIBCPP_HIDE_FROM_ABI
192_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
193operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
194 typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
195 return _Tr(__lhs.time_since_epoch() + __rhs);
196}
197
198// time_point operator+(duration x, time_point y);
199
200template <class _Rep1, class _Period1, class _Clock, class _Duration2>
201inline _LIBCPP_HIDE_FROM_ABI
202_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
203operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
204 return __rhs + __lhs;
205}
206
207// time_point operator-(time_point x, duration y);
208
209template <class _Clock, class _Duration1, class _Rep2, class _Period2>
210inline _LIBCPP_HIDE_FROM_ABI
211_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
212operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
213 typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret;
214 return _Ret(__lhs.time_since_epoch() - __rhs);
215}
216
217// duration operator-(time_point x, time_point y);
218
219template <class _Clock, class _Duration1, class _Duration2>
220inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename common_type<_Duration1, _Duration2>::type
221operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
222 return __lhs.time_since_epoch() - __rhs.time_since_epoch();
223}
224
225} // namespace chrono
226
227_LIBCPP_END_NAMESPACE_STD
228
229_LIBCPP_POP_MACROS
230
231#endif // _LIBCPP___CHRONO_TIME_POINT_H
232