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___CXX03___CHRONO_DURATION_H 11 #define _LIBCPP___CXX03___CHRONO_DURATION_H 12 13 #include <__cxx03/__config> 14 #include <__cxx03/__type_traits/common_type.h> 15 #include <__cxx03/__type_traits/enable_if.h> 16 #include <__cxx03/__type_traits/is_convertible.h> 17 #include <__cxx03/__type_traits/is_floating_point.h> 18 #include <__cxx03/limits> 19 #include <__cxx03/ratio> 20 21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22 # pragma GCC system_header 23 #endif 24 25 _LIBCPP_PUSH_MACROS 26 #include <__cxx03/__undef_macros> 27 28 _LIBCPP_BEGIN_NAMESPACE_STD 29 30 namespace chrono { 31 32 template <class _Rep, class _Period = ratio<1> > 33 class _LIBCPP_TEMPLATE_VIS duration; 34 35 template <class _Tp> 36 struct __is_duration : false_type {}; 37 38 template <class _Rep, class _Period> 39 struct __is_duration<duration<_Rep, _Period> > : true_type {}; 40 41 template <class _Rep, class _Period> 42 struct __is_duration<const duration<_Rep, _Period> > : true_type {}; 43 44 template <class _Rep, class _Period> 45 struct __is_duration<volatile duration<_Rep, _Period> > : true_type {}; 46 47 template <class _Rep, class _Period> 48 struct __is_duration<const volatile duration<_Rep, _Period> > : true_type {}; 49 50 } // namespace chrono 51 52 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 53 struct _LIBCPP_TEMPLATE_VIS common_type<chrono::duration<_Rep1, _Period1>, chrono::duration<_Rep2, _Period2> > { 54 typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type, typename __ratio_gcd<_Period1, _Period2>::type> 55 type; 56 }; 57 58 namespace chrono { 59 60 // duration_cast 61 62 template <class _FromDuration, 63 class _ToDuration, 64 class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type, 65 bool = _Period::num == 1, 66 bool = _Period::den == 1> 67 struct __duration_cast; 68 69 template <class _FromDuration, class _ToDuration, class _Period> 70 struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> { 71 _LIBCPP_HIDE_FROM_ABI _ToDuration operator()(const _FromDuration& __fd) const { 72 return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count())); 73 } 74 }; 75 76 template <class _FromDuration, class _ToDuration, class _Period> 77 struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> { 78 _LIBCPP_HIDE_FROM_ABI _ToDuration operator()(const _FromDuration& __fd) const { 79 typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; 80 return _ToDuration( 81 static_cast<typename _ToDuration::rep>(static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); 82 } 83 }; 84 85 template <class _FromDuration, class _ToDuration, class _Period> 86 struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> { 87 _LIBCPP_HIDE_FROM_ABI _ToDuration operator()(const _FromDuration& __fd) const { 88 typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; 89 return _ToDuration( 90 static_cast<typename _ToDuration::rep>(static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); 91 } 92 }; 93 94 template <class _FromDuration, class _ToDuration, class _Period> 95 struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> { 96 _LIBCPP_HIDE_FROM_ABI _ToDuration operator()(const _FromDuration& __fd) const { 97 typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct; 98 return _ToDuration(static_cast<typename _ToDuration::rep>( 99 static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) / static_cast<_Ct>(_Period::den))); 100 } 101 }; 102 103 template <class _ToDuration, class _Rep, class _Period, __enable_if_t<__is_duration<_ToDuration>::value, int> = 0> 104 inline _LIBCPP_HIDE_FROM_ABI _ToDuration duration_cast(const duration<_Rep, _Period>& __fd) { 105 return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd); 106 } 107 108 template <class _Rep> 109 struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {}; 110 111 // clang-format off 112 template <class _Rep> 113 struct _LIBCPP_TEMPLATE_VIS duration_values { 114 public: 115 _LIBCPP_HIDE_FROM_ABI static _Rep zero() _NOEXCEPT { return _Rep(0); } 116 _LIBCPP_HIDE_FROM_ABI static _Rep max() _NOEXCEPT { return numeric_limits<_Rep>::max(); } 117 _LIBCPP_HIDE_FROM_ABI static _Rep min() _NOEXCEPT { return numeric_limits<_Rep>::lowest(); } 118 }; 119 // clang-format on 120 121 // duration 122 123 template <class _Rep, class _Period> 124 class _LIBCPP_TEMPLATE_VIS duration { 125 static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); 126 static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); 127 static_assert(_Period::num > 0, "duration period must be positive"); 128 129 template <class _R1, class _R2> 130 struct __no_overflow { 131 private: 132 static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; 133 static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; 134 static const intmax_t __n1 = _R1::num / __gcd_n1_n2; 135 static const intmax_t __d1 = _R1::den / __gcd_d1_d2; 136 static const intmax_t __n2 = _R2::num / __gcd_n1_n2; 137 static const intmax_t __d2 = _R2::den / __gcd_d1_d2; 138 static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); 139 140 template <intmax_t _Xp, intmax_t _Yp, bool __overflow> 141 struct __mul // __overflow == false 142 { 143 static const intmax_t value = _Xp * _Yp; 144 }; 145 146 template <intmax_t _Xp, intmax_t _Yp> 147 struct __mul<_Xp, _Yp, true> { 148 static const intmax_t value = 1; 149 }; 150 151 public: 152 static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); 153 typedef ratio<__mul<__n1, __d2, !value>::value, __mul<__n2, __d1, !value>::value> type; 154 }; 155 156 public: 157 typedef _Rep rep; 158 typedef typename _Period::type period; 159 160 private: 161 rep __rep_; 162 163 public: 164 _LIBCPP_HIDE_FROM_ABI duration() {} 165 166 template <class _Rep2, 167 __enable_if_t<is_convertible<const _Rep2&, rep>::value && 168 (treat_as_floating_point<rep>::value || !treat_as_floating_point<_Rep2>::value), 169 int> = 0> 170 _LIBCPP_HIDE_FROM_ABI explicit duration(const _Rep2& __r) : __rep_(__r) {} 171 172 // conversions 173 template <class _Rep2, 174 class _Period2, 175 __enable_if_t<__no_overflow<_Period2, period>::value && (treat_as_floating_point<rep>::value || 176 (__no_overflow<_Period2, period>::type::den == 1 && 177 !treat_as_floating_point<_Rep2>::value)), 178 int> = 0> 179 _LIBCPP_HIDE_FROM_ABI duration(const duration<_Rep2, _Period2>& __d) 180 : __rep_(chrono::duration_cast<duration>(__d).count()) {} 181 182 // observer 183 184 _LIBCPP_HIDE_FROM_ABI rep count() const { return __rep_; } 185 186 // arithmetic 187 188 _LIBCPP_HIDE_FROM_ABI typename common_type<duration>::type operator+() const { 189 return typename common_type<duration>::type(*this); 190 } 191 _LIBCPP_HIDE_FROM_ABI typename common_type<duration>::type operator-() const { 192 return typename common_type<duration>::type(-__rep_); 193 } 194 _LIBCPP_HIDE_FROM_ABI duration& operator++() { 195 ++__rep_; 196 return *this; 197 } 198 _LIBCPP_HIDE_FROM_ABI duration operator++(int) { return duration(__rep_++); } 199 _LIBCPP_HIDE_FROM_ABI duration& operator--() { 200 --__rep_; 201 return *this; 202 } 203 _LIBCPP_HIDE_FROM_ABI duration operator--(int) { return duration(__rep_--); } 204 205 _LIBCPP_HIDE_FROM_ABI duration& operator+=(const duration& __d) { 206 __rep_ += __d.count(); 207 return *this; 208 } 209 _LIBCPP_HIDE_FROM_ABI duration& operator-=(const duration& __d) { 210 __rep_ -= __d.count(); 211 return *this; 212 } 213 214 _LIBCPP_HIDE_FROM_ABI duration& operator*=(const rep& __rhs) { 215 __rep_ *= __rhs; 216 return *this; 217 } 218 _LIBCPP_HIDE_FROM_ABI duration& operator/=(const rep& __rhs) { 219 __rep_ /= __rhs; 220 return *this; 221 } 222 _LIBCPP_HIDE_FROM_ABI duration& operator%=(const rep& __rhs) { 223 __rep_ %= __rhs; 224 return *this; 225 } 226 _LIBCPP_HIDE_FROM_ABI duration& operator%=(const duration& __rhs) { 227 __rep_ %= __rhs.count(); 228 return *this; 229 } 230 231 // special values 232 233 _LIBCPP_HIDE_FROM_ABI static duration zero() _NOEXCEPT { return duration(duration_values<rep>::zero()); } 234 _LIBCPP_HIDE_FROM_ABI static duration min() _NOEXCEPT { return duration(duration_values<rep>::min()); } 235 _LIBCPP_HIDE_FROM_ABI static duration max() _NOEXCEPT { return duration(duration_values<rep>::max()); } 236 }; 237 238 typedef duration<long long, nano> nanoseconds; 239 typedef duration<long long, micro> microseconds; 240 typedef duration<long long, milli> milliseconds; 241 typedef duration<long long > seconds; 242 typedef duration< long, ratio< 60> > minutes; 243 typedef duration< long, ratio<3600> > hours; 244 245 // Duration == 246 247 template <class _LhsDuration, class _RhsDuration> 248 struct __duration_eq { 249 _LIBCPP_HIDE_FROM_ABI bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const { 250 typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; 251 return _Ct(__lhs).count() == _Ct(__rhs).count(); 252 } 253 }; 254 255 template <class _LhsDuration> 256 struct __duration_eq<_LhsDuration, _LhsDuration> { 257 _LIBCPP_HIDE_FROM_ABI bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const { 258 return __lhs.count() == __rhs.count(); 259 } 260 }; 261 262 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 263 inline _LIBCPP_HIDE_FROM_ABI bool 264 operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 265 return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); 266 } 267 268 // Duration != 269 270 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 271 inline _LIBCPP_HIDE_FROM_ABI bool 272 operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 273 return !(__lhs == __rhs); 274 } 275 276 // Duration < 277 278 template <class _LhsDuration, class _RhsDuration> 279 struct __duration_lt { 280 _LIBCPP_HIDE_FROM_ABI bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const { 281 typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; 282 return _Ct(__lhs).count() < _Ct(__rhs).count(); 283 } 284 }; 285 286 template <class _LhsDuration> 287 struct __duration_lt<_LhsDuration, _LhsDuration> { 288 _LIBCPP_HIDE_FROM_ABI bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const { 289 return __lhs.count() < __rhs.count(); 290 } 291 }; 292 293 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 294 inline _LIBCPP_HIDE_FROM_ABI bool 295 operator<(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 296 return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); 297 } 298 299 // Duration > 300 301 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 302 inline _LIBCPP_HIDE_FROM_ABI bool 303 operator>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 304 return __rhs < __lhs; 305 } 306 307 // Duration <= 308 309 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 310 inline _LIBCPP_HIDE_FROM_ABI bool 311 operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 312 return !(__rhs < __lhs); 313 } 314 315 // Duration >= 316 317 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 318 inline _LIBCPP_HIDE_FROM_ABI bool 319 operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 320 return !(__lhs < __rhs); 321 } 322 323 // Duration + 324 325 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 326 inline _LIBCPP_HIDE_FROM_ABI typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type 327 operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 328 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; 329 return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); 330 } 331 332 // Duration - 333 334 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 335 inline _LIBCPP_HIDE_FROM_ABI typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type 336 operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 337 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; 338 return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); 339 } 340 341 // Duration * 342 343 template <class _Rep1, 344 class _Period, 345 class _Rep2, 346 __enable_if_t<is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0> 347 inline _LIBCPP_HIDE_FROM_ABI duration<typename common_type<_Rep1, _Rep2>::type, _Period> 348 operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { 349 typedef typename common_type<_Rep1, _Rep2>::type _Cr; 350 typedef duration<_Cr, _Period> _Cd; 351 return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); 352 } 353 354 template <class _Rep1, 355 class _Period, 356 class _Rep2, 357 __enable_if_t<is_convertible<const _Rep1&, typename common_type<_Rep1, _Rep2>::type>::value, int> = 0> 358 inline _LIBCPP_HIDE_FROM_ABI duration<typename common_type<_Rep1, _Rep2>::type, _Period> 359 operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) { 360 return __d * __s; 361 } 362 363 // Duration / 364 365 template <class _Rep1, 366 class _Period, 367 class _Rep2, 368 __enable_if_t<!__is_duration<_Rep2>::value && 369 is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value, 370 int> = 0> 371 inline _LIBCPP_HIDE_FROM_ABI duration<typename common_type<_Rep1, _Rep2>::type, _Period> 372 operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { 373 typedef typename common_type<_Rep1, _Rep2>::type _Cr; 374 typedef duration<_Cr, _Period> _Cd; 375 return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); 376 } 377 378 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 379 inline _LIBCPP_HIDE_FROM_ABI typename common_type<_Rep1, _Rep2>::type 380 operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 381 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct; 382 return _Ct(__lhs).count() / _Ct(__rhs).count(); 383 } 384 385 // Duration % 386 387 template <class _Rep1, 388 class _Period, 389 class _Rep2, 390 __enable_if_t<!__is_duration<_Rep2>::value && 391 is_convertible<const _Rep2&, typename common_type<_Rep1, _Rep2>::type>::value, 392 int> = 0> 393 inline _LIBCPP_HIDE_FROM_ABI duration<typename common_type<_Rep1, _Rep2>::type, _Period> 394 operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { 395 typedef typename common_type<_Rep1, _Rep2>::type _Cr; 396 typedef duration<_Cr, _Period> _Cd; 397 return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); 398 } 399 400 template <class _Rep1, class _Period1, class _Rep2, class _Period2> 401 inline _LIBCPP_HIDE_FROM_ABI typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type 402 operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { 403 typedef typename common_type<_Rep1, _Rep2>::type _Cr; 404 typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd; 405 return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); 406 } 407 408 } // namespace chrono 409 410 _LIBCPP_END_NAMESPACE_STD 411 412 _LIBCPP_POP_MACROS 413 414 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) 415 # include <__cxx03/type_traits> 416 #endif 417 418 #endif // _LIBCPP___CXX03___CHRONO_DURATION_H 419