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