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 | // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html |
11 | |
12 | #ifndef __LIBCPP_SRC_INCLUDE_TZDB_TYPES_PRIVATE_H |
13 | #define __LIBCPP_SRC_INCLUDE_TZDB_TYPES_PRIVATE_H |
14 | |
15 | #include <chrono> |
16 | #include <string> |
17 | #include <utility> |
18 | #include <variant> |
19 | #include <vector> |
20 | |
21 | _LIBCPP_BEGIN_NAMESPACE_STD |
22 | |
23 | // TODO TZDB |
24 | // The helper classes in this header have no constructor but are loaded with |
25 | // dedicated parse functions. In the original design this header was public and |
26 | // the parsing was done in the dylib. In that design having constructors would |
27 | // expand the ABI interface. Since this header is now in the dylib that design |
28 | // should be reconsidered. (For now the design is kept as is, in case this |
29 | // header needs to be public for unforseen reasons.) |
30 | |
31 | namespace chrono::__tz { |
32 | |
33 | // Sun>=8 first Sunday on or after the eighth |
34 | // Sun<=25 last Sunday on or before the 25th |
35 | struct __constrained_weekday { |
36 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI year_month_day operator()(year __year, month __month) const { |
37 | auto __result = static_cast<sys_days>(year_month_day{__year, __month, __day}); |
38 | weekday __wd{static_cast<sys_days>(__result)}; |
39 | |
40 | if (__comparison == __le) |
41 | __result -= __wd - __weekday; |
42 | else |
43 | __result += __weekday - __wd; |
44 | |
45 | return __result; |
46 | } |
47 | |
48 | weekday __weekday; |
49 | enum __comparison_t { __le, __ge } __comparison; |
50 | day __day; |
51 | }; |
52 | |
53 | // The on field has a few alternative presentations |
54 | // 5 the fifth of the month |
55 | // lastSun the last Sunday in the month |
56 | // lastMon the last Monday in the month |
57 | // Sun>=8 first Sunday on or after the eighth |
58 | // Sun<=25 last Sunday on or before the 25th |
59 | using __on = variant<day, weekday_last, __constrained_weekday>; |
60 | |
61 | enum class __clock { __local, __standard, __universal }; |
62 | |
63 | struct __at { |
64 | seconds __time{0}; |
65 | __tz::__clock __clock{__tz::__clock::__local}; |
66 | }; |
67 | |
68 | struct __save { |
69 | seconds __time; |
70 | bool __is_dst; |
71 | }; |
72 | |
73 | // The names of the fields match the fields of a Rule. |
74 | struct __rule { |
75 | year __from; |
76 | year __to; |
77 | month __in; |
78 | __tz::__on __on; |
79 | __tz::__at __at; |
80 | __tz::__save __save; |
81 | string __letters; |
82 | }; |
83 | |
84 | using __rules_storage_type = std::vector<std::pair<string, vector<__tz::__rule>>>; // TODO TZDB use flat_map; |
85 | |
86 | struct __continuation { |
87 | // Non-owning link to the RULE entries. |
88 | __tz::__rules_storage_type* __rule_database_; |
89 | |
90 | seconds __stdoff; |
91 | |
92 | // The RULES is either a SAVE or a NAME. |
93 | // The size_t is used as cache. After loading the rules they are |
94 | // sorted and remain stable, then an index in the vector can be |
95 | // used. |
96 | // If this field contains - then standard time always |
97 | // applies. This is indicated by the monostate. |
98 | // TODO TZDB Investigate implantation the size_t based caching. |
99 | using __rules_t = variant<monostate, __tz::__save, string /*, size_t*/>; |
100 | |
101 | __rules_t __rules; |
102 | |
103 | string __format; |
104 | // TODO TZDB the until field can contain more than just a year. |
105 | // Parts of the UNTIL, the optional parts are default initialized |
106 | // optional<year> __until_; |
107 | year __year = chrono::year::min(); |
108 | month __in{January}; |
109 | __tz::__on __on{chrono::day{1}}; |
110 | __tz::__at __at{chrono::seconds{0}, __tz::__clock::__local}; |
111 | }; |
112 | |
113 | } // namespace chrono::__tz |
114 | |
115 | _LIBCPP_END_NAMESPACE_STD |
116 | |
117 | #endif // __LIBCPP_SRC_INCLUDE_TZDB_TYPES_PRIVATE_H |
118 | |