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 { operator__constrained_weekday36 [[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