xref: /llvm-project/libcxx/include/__chrono/hh_mm_ss.h (revision f69585235ec85d54e0f3fc41b2d5700430907f99)
1d7862497SMark de Wever // -*- C++ -*-
2d7862497SMark de Wever //===----------------------------------------------------------------------===//
3d7862497SMark de Wever //
4d7862497SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5d7862497SMark de Wever // See https://llvm.org/LICENSE.txt for license information.
6d7862497SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7d7862497SMark de Wever //
8d7862497SMark de Wever //===----------------------------------------------------------------------===//
9d7862497SMark de Wever 
10d7862497SMark de Wever #ifndef _LIBCPP___CHRONO_HH_MM_SS_H
11d7862497SMark de Wever #define _LIBCPP___CHRONO_HH_MM_SS_H
12d7862497SMark de Wever 
13d7862497SMark de Wever #include <__chrono/duration.h>
14d7862497SMark de Wever #include <__chrono/time_point.h>
15d7862497SMark de Wever #include <__config>
160a4aa8a1SNikolas Klauser #include <__type_traits/common_type.h>
17d7862497SMark de Wever #include <ratio>
18d7862497SMark de Wever 
19d7862497SMark de Wever #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20d7862497SMark de Wever #  pragma GCC system_header
21d7862497SMark de Wever #endif
22d7862497SMark de Wever 
234f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
24d7862497SMark de Wever 
25d7862497SMark de Wever _LIBCPP_BEGIN_NAMESPACE_STD
26d7862497SMark de Wever 
279783f28cSLouis Dionne namespace chrono {
28d7862497SMark de Wever 
29d7862497SMark de Wever template <class _Duration>
309783f28cSLouis Dionne class hh_mm_ss {
31d7862497SMark de Wever private:
327c010bfdSNikolas Klauser   static_assert(__is_duration_v<_Duration>, "template parameter of hh_mm_ss must be a std::chrono::duration");
33*f6958523SNikolas Klauser   using __CommonType _LIBCPP_NODEBUG = common_type_t<_Duration, chrono::seconds>;
34d7862497SMark de Wever 
359783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI static constexpr uint64_t __pow10(unsigned __exp) {
36d7862497SMark de Wever     uint64_t __ret = 1;
37d7862497SMark de Wever     for (unsigned __i = 0; __i < __exp; ++__i)
38d7862497SMark de Wever       __ret *= 10U;
39d7862497SMark de Wever     return __ret;
40d7862497SMark de Wever   }
41d7862497SMark de Wever 
429783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) {
43d7862497SMark de Wever     if (__n >= 2 && __d != 0 && __w < 19)
44d7862497SMark de Wever       return 1 + __width(__n, __d % __n * 10, __w + 1);
45d7862497SMark de Wever     return 0;
46d7862497SMark de Wever   }
47d7862497SMark de Wever 
48d7862497SMark de Wever public:
499783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI static unsigned constexpr fractional_width =
509783f28cSLouis Dionne       __width(__CommonType::period::den) < 19 ? __width(__CommonType::period::den) : 6u;
51d7862497SMark de Wever   using precision = duration<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>;
52d7862497SMark de Wever 
53d7862497SMark de Wever   _LIBCPP_HIDE_FROM_ABI constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {}
54d7862497SMark de Wever 
559783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr explicit hh_mm_ss(_Duration __d) noexcept
569783f28cSLouis Dionne       : __is_neg_(__d < _Duration(0)),
57841399a2SNikolas Klauser         __h_(chrono::duration_cast<chrono::hours>(chrono::abs(__d))),
58841399a2SNikolas Klauser         __m_(chrono::duration_cast<chrono::minutes>(chrono::abs(__d) - hours())),
59841399a2SNikolas Klauser         __s_(chrono::duration_cast<chrono::seconds>(chrono::abs(__d) - hours() - minutes())),
609783f28cSLouis Dionne         __f_(chrono::duration_cast<precision>(chrono::abs(__d) - hours() - minutes() - seconds())) {}
61d7862497SMark de Wever 
6284fc2c3cSNikolas Klauser   _LIBCPP_HIDE_FROM_ABI constexpr bool is_negative() const noexcept { return __is_neg_; }
6384fc2c3cSNikolas Klauser   _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours hours() const noexcept { return __h_; }
6484fc2c3cSNikolas Klauser   _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes minutes() const noexcept { return __m_; }
6584fc2c3cSNikolas Klauser   _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds seconds() const noexcept { return __s_; }
6684fc2c3cSNikolas Klauser   _LIBCPP_HIDE_FROM_ABI constexpr precision subseconds() const noexcept { return __f_; }
67d7862497SMark de Wever 
689783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr precision to_duration() const noexcept {
6984fc2c3cSNikolas Klauser     auto __dur = __h_ + __m_ + __s_ + __f_;
7084fc2c3cSNikolas Klauser     return __is_neg_ ? -__dur : __dur;
71d7862497SMark de Wever   }
72d7862497SMark de Wever 
73d7862497SMark de Wever   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator precision() const noexcept { return to_duration(); }
74d7862497SMark de Wever 
75d7862497SMark de Wever private:
7684fc2c3cSNikolas Klauser   bool __is_neg_;
7784fc2c3cSNikolas Klauser   chrono::hours __h_;
7884fc2c3cSNikolas Klauser   chrono::minutes __m_;
7984fc2c3cSNikolas Klauser   chrono::seconds __s_;
8084fc2c3cSNikolas Klauser   precision __f_;
81d7862497SMark de Wever };
827f5d130aSMark de Wever _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(hh_mm_ss);
83d7862497SMark de Wever 
849783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_am(const hours& __h) noexcept {
859783f28cSLouis Dionne   return __h >= hours(0) && __h < hours(12);
869783f28cSLouis Dionne }
879783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_pm(const hours& __h) noexcept {
889783f28cSLouis Dionne   return __h >= hours(12) && __h < hours(24);
89d7862497SMark de Wever }
90d7862497SMark de Wever 
919783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI inline constexpr hours make12(const hours& __h) noexcept {
929783f28cSLouis Dionne   if (__h == hours(0))
939783f28cSLouis Dionne     return hours(12);
949783f28cSLouis Dionne   else if (__h <= hours(12))
959783f28cSLouis Dionne     return __h;
969783f28cSLouis Dionne   else
979783f28cSLouis Dionne     return __h - hours(12);
989783f28cSLouis Dionne }
999783f28cSLouis Dionne 
1009783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI inline constexpr hours make24(const hours& __h, bool __is_pm) noexcept {
101d7862497SMark de Wever   if (__is_pm)
102d7862497SMark de Wever     return __h == hours(12) ? __h : __h + hours(12);
103d7862497SMark de Wever   else
104d7862497SMark de Wever     return __h == hours(12) ? hours(0) : __h;
105d7862497SMark de Wever }
106d7862497SMark de Wever } // namespace chrono
107d7862497SMark de Wever 
108d7862497SMark de Wever _LIBCPP_END_NAMESPACE_STD
109d7862497SMark de Wever 
1104f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
111d7862497SMark de Wever 
112d7862497SMark de Wever #endif // _LIBCPP___CHRONO_HH_MM_SS_H
113