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 _LIBCPP_TEMPLATE_VIS time_point {
35 static_assert(__is_duration<_Duration>::value,
36 "Second template parameter of time_point must be a std::chrono::duration");
37
38public:
39 typedef _Clock clock;
40 typedef _Duration duration;
41 typedef typename duration::rep rep;
42 typedef typename duration::period period;
43
44private:
45 duration __d_;
46
47public:
48 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point() : __d_(duration::zero()) {}
49 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit time_point(const duration& __d) : __d_(__d) {}
50
51 // conversions
52 template <class _Duration2, __enable_if_t<is_convertible<_Duration2, duration>::value, int> = 0>
53 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point(const time_point<clock, _Duration2>& __t)
54 : __d_(__t.time_since_epoch()) {}
55
56 // observer
57
58 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const { return __d_; }
59
60 // arithmetic
61
62 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator+=(const duration& __d) {
63 __d_ += __d;
64 return *this;
65 }
66 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator-=(const duration& __d) {
67 __d_ -= __d;
68 return *this;
69 }
70
71 // special values
72
73 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT { return time_point(duration::min()); }
74 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT { return time_point(duration::max()); }
75};
76
77} // namespace chrono
78
79template <class _Clock, class _Duration1, class _Duration2>
80struct _LIBCPP_TEMPLATE_VIS
81common_type<chrono::time_point<_Clock, _Duration1>, chrono::time_point<_Clock, _Duration2> > {
82 typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type;
83};
84
85namespace chrono {
86
87template <class _ToDuration, class _Clock, class _Duration>
88inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration>
89time_point_cast(const time_point<_Clock, _Duration>& __t) {
90 return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
91}
92
93#if _LIBCPP_STD_VER >= 17
94template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration<_ToDuration>::value, int> = 0>
95inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> floor(const time_point<_Clock, _Duration>& __t) {
96 return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())};
97}
98
99template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration<_ToDuration>::value, int> = 0>
100inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> ceil(const time_point<_Clock, _Duration>& __t) {
101 return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())};
102}
103
104template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration<_ToDuration>::value, int> = 0>
105inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> round(const time_point<_Clock, _Duration>& __t) {
106 return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())};
107}
108
109template <class _Rep, class _Period, enable_if_t<numeric_limits<_Rep>::is_signed, int> = 0>
110inline _LIBCPP_HIDE_FROM_ABI constexpr duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) {
111 return __d >= __d.zero() ? +__d : -__d;
112}
113#endif // _LIBCPP_STD_VER >= 17
114
115// time_point ==
116
117template <class _Clock, class _Duration1, class _Duration2>
118inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
119operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
120 return __lhs.time_since_epoch() == __rhs.time_since_epoch();
121}
122
123#if _LIBCPP_STD_VER <= 17
124
125// time_point !=
126
127template <class _Clock, class _Duration1, class _Duration2>
128inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
129operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
130 return !(__lhs == __rhs);
131}
132
133#endif // _LIBCPP_STD_VER <= 17
134
135// time_point <
136
137template <class _Clock, class _Duration1, class _Duration2>
138inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
139operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
140 return __lhs.time_since_epoch() < __rhs.time_since_epoch();
141}
142
143// time_point >
144
145template <class _Clock, class _Duration1, class _Duration2>
146inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
147operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
148 return __rhs < __lhs;
149}
150
151// time_point <=
152
153template <class _Clock, class _Duration1, class _Duration2>
154inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
155operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
156 return !(__rhs < __lhs);
157}
158
159// time_point >=
160
161template <class _Clock, class _Duration1, class _Duration2>
162inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
163operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
164 return !(__lhs < __rhs);
165}
166
167#if _LIBCPP_STD_VER >= 20
168
169template <class _Clock, class _Duration1, three_way_comparable_with<_Duration1> _Duration2>
170_LIBCPP_HIDE_FROM_ABI constexpr auto
171operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
172 return __lhs.time_since_epoch() <=> __rhs.time_since_epoch();
173}
174
175#endif // _LIBCPP_STD_VER >= 20
176
177// time_point operator+(time_point x, duration y);
178
179template <class _Clock, class _Duration1, class _Rep2, class _Period2>
180inline _LIBCPP_HIDE_FROM_ABI
181_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
182operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
183 typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
184 return _Tr(__lhs.time_since_epoch() + __rhs);
185}
186
187// time_point operator+(duration x, time_point y);
188
189template <class _Rep1, class _Period1, class _Clock, class _Duration2>
190inline _LIBCPP_HIDE_FROM_ABI
191_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
192operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
193 return __rhs + __lhs;
194}
195
196// time_point operator-(time_point x, duration y);
197
198template <class _Clock, class _Duration1, class _Rep2, class _Period2>
199inline _LIBCPP_HIDE_FROM_ABI
200_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
201operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
202 typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret;
203 return _Ret(__lhs.time_since_epoch() - __rhs);
204}
205
206// duration operator-(time_point x, time_point y);
207
208template <class _Clock, class _Duration1, class _Duration2>
209inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename common_type<_Duration1, _Duration2>::type
210operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
211 return __lhs.time_since_epoch() - __rhs.time_since_epoch();
212}
213
214} // namespace chrono
215
216_LIBCPP_END_NAMESPACE_STD
217
218_LIBCPP_POP_MACROS
219
220#endif // _LIBCPP___CHRONO_TIME_POINT_H
221