brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.9 KiB · 8db687a Raw
229 lines · c
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-exception7//8//===----------------------------------------------------------------------===//9 10// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html11 12#ifndef _LIBCPP___CHRONO_ZONED_TIME_H13#define _LIBCPP___CHRONO_ZONED_TIME_H14 15#include <version>16// Enable the contents of the header only when libc++ was built with experimental features enabled.17#if _LIBCPP_HAS_EXPERIMENTAL_TZDB18 19#  include <__chrono/calendar.h>20#  include <__chrono/duration.h>21#  include <__chrono/sys_info.h>22#  include <__chrono/system_clock.h>23#  include <__chrono/time_zone.h>24#  include <__chrono/tzdb_list.h>25#  include <__concepts/constructible.h>26#  include <__config>27#  include <__type_traits/common_type.h>28#  include <__type_traits/conditional.h>29#  include <__type_traits/remove_cvref.h>30#  include <__utility/declval.h>31#  include <__utility/move.h>32#  include <string_view>33 34#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)35#    pragma GCC system_header36#  endif37 38_LIBCPP_PUSH_MACROS39#  include <__undef_macros>40 41_LIBCPP_BEGIN_NAMESPACE_STD42 43#  if _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION44 45namespace chrono {46 47template <class>48struct zoned_traits {};49 50template <>51struct zoned_traits<const time_zone*> {52  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static const time_zone* default_zone() { return chrono::locate_zone("UTC"); }53  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static const time_zone* locate_zone(string_view __name) {54    return chrono::locate_zone(__name);55  }56};57 58template <class _Duration, class _TimeZonePtr = const time_zone*>59class zoned_time {60  // [time.zone.zonedtime.ctor]/261  static_assert(__is_duration_v<_Duration>,62                "the program is ill-formed since _Duration is not a specialization of std::chrono::duration");63 64  // The wording uses the constraints like65  //   constructible_from<zoned_time, decltype(__traits::locate_zone(string_view{}))>66  // Using these constraints in the code causes the compiler to give an67  // error that the constraint depends on itself. To avoid that issue use68  // the fact it is possible to create this object from a _TimeZonePtr.69  using __traits _LIBCPP_NODEBUG = zoned_traits<_TimeZonePtr>;70 71public:72  using duration = common_type_t<_Duration, seconds>;73 74  _LIBCPP_HIDE_FROM_ABI zoned_time()75    requires requires { __traits::default_zone(); }76      : __zone_{__traits::default_zone()}, __tp_{} {}77 78  _LIBCPP_HIDE_FROM_ABI zoned_time(const zoned_time&)            = default;79  _LIBCPP_HIDE_FROM_ABI zoned_time& operator=(const zoned_time&) = default;80 81  _LIBCPP_HIDE_FROM_ABI zoned_time(const sys_time<_Duration>& __tp)82    requires requires { __traits::default_zone(); }83      : __zone_{__traits::default_zone()}, __tp_{__tp} {}84 85  _LIBCPP_HIDE_FROM_ABI explicit zoned_time(_TimeZonePtr __zone) : __zone_{std::move(__zone)}, __tp_{} {}86 87  _LIBCPP_HIDE_FROM_ABI explicit zoned_time(string_view __name)88    requires(requires { __traits::locate_zone(string_view{}); } &&89             constructible_from<_TimeZonePtr, decltype(__traits::locate_zone(string_view{}))>)90      : __zone_{__traits::locate_zone(__name)}, __tp_{} {}91 92  template <class _Duration2>93  _LIBCPP_HIDE_FROM_ABI zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& __zt)94    requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>95      : __zone_{__zt.get_time_zone()}, __tp_{__zt.get_sys_time()} {}96 97  _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const sys_time<_Duration>& __tp)98      : __zone_{std::move(__zone)}, __tp_{__tp} {}99 100  _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const sys_time<_Duration>& __tp)101    requires requires { _TimeZonePtr{__traits::locate_zone(string_view{})}; }102      : zoned_time{__traits::locate_zone(__name), __tp} {}103 104  _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const local_time<_Duration>& __tp)105    requires(is_convertible_v<decltype(std::declval<_TimeZonePtr&>() -> to_sys(local_time<_Duration>{})),106                              sys_time<duration>>)107      : __zone_{std::move(__zone)}, __tp_{__zone_->to_sys(__tp)} {}108 109  _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const local_time<_Duration>& __tp)110    requires(requires {111      _TimeZonePtr{__traits::locate_zone(string_view{})};112    } && is_convertible_v<decltype(std::declval<_TimeZonePtr&>() -> to_sys(local_time<_Duration>{})),113                          sys_time<duration>>)114      : zoned_time{__traits::locate_zone(__name), __tp} {}115 116  _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const local_time<_Duration>& __tp, choose __c)117    requires(is_convertible_v<118                decltype(std::declval<_TimeZonePtr&>() -> to_sys(local_time<_Duration>{}, choose::earliest)),119                sys_time<duration>>)120      : __zone_{std::move(__zone)}, __tp_{__zone_->to_sys(__tp, __c)} {}121 122  _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const local_time<_Duration>& __tp, choose __c)123    requires(requires {124      _TimeZonePtr{__traits::locate_zone(string_view{})};125    } && is_convertible_v<decltype(std::declval<_TimeZonePtr&>() -> to_sys(local_time<_Duration>{}, choose::earliest)),126                          sys_time<duration>>)127      : zoned_time{__traits::locate_zone(__name), __tp, __c} {}128 129  template <class _Duration2, class _TimeZonePtr2>130  _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const zoned_time<_Duration2, _TimeZonePtr2>& __zt)131    requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>132      : __zone_{std::move(__zone)}, __tp_{__zt.get_sys_time()} {}133 134  // per wording choose has no effect135  template <class _Duration2, class _TimeZonePtr2>136  _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const zoned_time<_Duration2, _TimeZonePtr2>& __zt, choose)137    requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>138      : __zone_{std::move(__zone)}, __tp_{__zt.get_sys_time()} {}139 140  template <class _Duration2, class _TimeZonePtr2>141  _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const zoned_time<_Duration2, _TimeZonePtr2>& __zt)142    requires(requires {143      _TimeZonePtr{__traits::locate_zone(string_view{})};144    } && is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>)145      : zoned_time{__traits::locate_zone(__name), __zt} {}146 147  template <class _Duration2, class _TimeZonePtr2>148  _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const zoned_time<_Duration2, _TimeZonePtr2>& __zt, choose __c)149    requires(requires {150      _TimeZonePtr{__traits::locate_zone(string_view{})};151    } && is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>)152      : zoned_time{__traits::locate_zone(__name), __zt, __c} {}153 154  _LIBCPP_HIDE_FROM_ABI zoned_time& operator=(const sys_time<_Duration>& __tp) {155    __tp_ = __tp;156    return *this;157  }158 159  _LIBCPP_HIDE_FROM_ABI zoned_time& operator=(const local_time<_Duration>& __tp) {160    // TODO TZDB This seems wrong.161    // Assigning a non-existent or ambiguous time will throw and not satisfy162    // the post condition. This seems quite odd; I constructed an object with163    // choose::earliest and that choice is not respected.164    // what did LEWG do with this.165    // MSVC STL and libstdc++ behave the same166    __tp_ = __zone_->to_sys(__tp);167    return *this;168  }169 170  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI operator sys_time<duration>() const { return get_sys_time(); }171  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit operator local_time<duration>() const { return get_local_time(); }172 173  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _TimeZonePtr get_time_zone() const { return __zone_; }174  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_time<duration> get_local_time() const { return __zone_->to_local(__tp_); }175  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time<duration> get_sys_time() const { return __tp_; }176  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_info get_info() const { return __zone_->get_info(__tp_); }177 178private:179  _TimeZonePtr __zone_;180  sys_time<duration> __tp_;181};182 183zoned_time() -> zoned_time<seconds>;184 185template <class _Duration>186zoned_time(sys_time<_Duration>) -> zoned_time<common_type_t<_Duration, seconds>>;187 188template <class _TimeZonePtrOrName>189using __time_zone_representation _LIBCPP_NODEBUG =190    conditional_t<is_convertible_v<_TimeZonePtrOrName, string_view>,191                  const time_zone*,192                  remove_cvref_t<_TimeZonePtrOrName>>;193 194template <class _TimeZonePtrOrName>195zoned_time(_TimeZonePtrOrName&&) -> zoned_time<seconds, __time_zone_representation<_TimeZonePtrOrName>>;196 197template <class _TimeZonePtrOrName, class _Duration>198zoned_time(_TimeZonePtrOrName&&, sys_time<_Duration>)199    -> zoned_time<common_type_t<_Duration, seconds>, __time_zone_representation<_TimeZonePtrOrName>>;200 201template <class _TimeZonePtrOrName, class _Duration>202zoned_time(_TimeZonePtrOrName&&, local_time<_Duration>, choose = choose::earliest)203    -> zoned_time<common_type_t<_Duration, seconds>, __time_zone_representation<_TimeZonePtrOrName>>;204 205template <class _Duration, class _TimeZonePtrOrName, class _TimeZonePtr2>206zoned_time(_TimeZonePtrOrName&&, zoned_time<_Duration, _TimeZonePtr2>, choose = choose::earliest)207    -> zoned_time<common_type_t<_Duration, seconds>, __time_zone_representation<_TimeZonePtrOrName>>;208 209using zoned_seconds = zoned_time<seconds>;210 211template <class _Duration1, class _Duration2, class _TimeZonePtr>212_LIBCPP_HIDE_FROM_ABI bool213operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_Duration2, _TimeZonePtr>& __rhs) {214  return __lhs.get_time_zone() == __rhs.get_time_zone() && __lhs.get_sys_time() == __rhs.get_sys_time();215}216 217} // namespace chrono218 219#  endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM &&220         // _LIBCPP_HAS_LOCALIZATION221 222_LIBCPP_END_NAMESPACE_STD223 224_LIBCPP_POP_MACROS225 226#endif // _LIBCPP_HAS_EXPERIMENTAL_TZDB227 228#endif // _LIBCPP___CHRONO_ZONED_TIME_H229