You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 line
3.0 KiB

  1. #pragma once
  2. #include <chrono>
  3. #include <utility>
  4. namespace utl
  5. {
  6. namespace __impl
  7. {
  8. template<class From, class To>
  9. struct op_convert_time;
  10. template<typename Rep, typename Period>
  11. struct op_convert_time<std::chrono::duration<Rep, Period>, ::timeval>
  12. {
  13. static ::timeval cast(const std::chrono::duration<Rep, Period>& d)
  14. {
  15. ::timeval tv;
  16. const std::chrono::seconds sec = std::chrono::duration_cast<std::chrono::seconds>(d);
  17. tv.tv_sec = sec.count();
  18. tv.tv_usec = std::chrono::duration_cast<std::chrono::microseconds>(d - sec).count();
  19. return tv;
  20. }
  21. };
  22. template<typename Rep, typename Period>
  23. struct op_convert_time<::timeval, std::chrono::duration<Rep, Period>>
  24. {
  25. static std::chrono::duration<Rep, Period> cast(const ::timeval& tv)
  26. {
  27. return std::chrono::duration_cast<std::chrono::duration<Rep, Period>>(
  28. std::chrono::seconds(tv.tv_sec) + std::chrono::microseconds(tv.tv_usec));
  29. }
  30. };
  31. template<typename Rep, typename Period>
  32. struct op_convert_time<std::chrono::duration<Rep, Period>, ::timespec>
  33. {
  34. static ::timespec cast(const std::chrono::duration<Rep, Period>& d)
  35. {
  36. ::timespec ts;
  37. const std::chrono::seconds sec = std::chrono::duration_cast<std::chrono::seconds>(d);
  38. ts.tv_sec = sec.count();
  39. ts.tv_nsec = std::chrono::duration_cast<std::chrono::nanoseconds>(d - sec).count();
  40. return ts;
  41. }
  42. };
  43. template<typename Rep, typename Period>
  44. struct op_convert_time<::timespec, std::chrono::duration<Rep, Period>>
  45. {
  46. static std::chrono::duration<Rep, Period> cast(const ::timespec& ts)
  47. {
  48. return std::chrono::duration_cast<std::chrono::duration<Rep, Period>>(
  49. std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec));
  50. }
  51. };
  52. }
  53. template<typename T, typename Rep, typename Period>
  54. inline auto duration_cast(const std::chrono::duration<Rep, Period>& d)
  55. -> std::enable_if_t< std::is_same<T, ::timeval>::value, ::timeval>
  56. { return __impl::op_convert_time<std::chrono::duration<Rep, Period>, ::timeval>::cast(d); }
  57. template<typename T, typename Rep, typename Period>
  58. inline auto duration_cast(const std::chrono::duration<Rep, Period>& d)
  59. -> std::enable_if_t< std::is_same<T, ::timespec>::value, ::timespec>
  60. { return __impl::op_convert_time<std::chrono::duration<Rep, Period>, ::timespec>::cast(d); }
  61. template<typename Duration>
  62. Duration duration_cast(const ::timeval& tv)
  63. { return __impl::op_convert_time<::timeval, Duration>::cast(tv); }
  64. template<typename Duration>
  65. Duration duration_cast(const ::timespec& ts)
  66. { return __impl::op_convert_time<::timespec, Duration>::cast(ts); }
  67. }