1e78f53d1SNikolas Klauser // -*- C++ -*- 2e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 3e78f53d1SNikolas Klauser // 4e78f53d1SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5e78f53d1SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 6e78f53d1SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7e78f53d1SNikolas Klauser // 8e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 9e78f53d1SNikolas Klauser 10e78f53d1SNikolas Klauser // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html 11e78f53d1SNikolas Klauser 12*ce777190SNikolas Klauser #ifndef _LIBCPP___CXX03___CHRONO_EXCEPTION_H 13*ce777190SNikolas Klauser #define _LIBCPP___CXX03___CHRONO_EXCEPTION_H 14e78f53d1SNikolas Klauser 1573fbae83SNikolas Klauser #include <__cxx03/version> 16e78f53d1SNikolas Klauser // Enable the contents of the header only when libc++ was built with experimental features enabled. 17e78f53d1SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) 18e78f53d1SNikolas Klauser 1973fbae83SNikolas Klauser # include <__cxx03/__chrono/calendar.h> 2073fbae83SNikolas Klauser # include <__cxx03/__chrono/local_info.h> 2173fbae83SNikolas Klauser # include <__cxx03/__chrono/time_point.h> 2273fbae83SNikolas Klauser # include <__cxx03/__config> 2373fbae83SNikolas Klauser # include <__cxx03/__configuration/availability.h> 2473fbae83SNikolas Klauser # include <__cxx03/__verbose_abort> 2573fbae83SNikolas Klauser # include <__cxx03/format> 2673fbae83SNikolas Klauser # include <__cxx03/stdexcept> 2773fbae83SNikolas Klauser # include <__cxx03/string> 28e78f53d1SNikolas Klauser 29e78f53d1SNikolas Klauser # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 30e78f53d1SNikolas Klauser # pragma GCC system_header 31e78f53d1SNikolas Klauser # endif 32e78f53d1SNikolas Klauser 33e78f53d1SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 34e78f53d1SNikolas Klauser 35e78f53d1SNikolas Klauser # if _LIBCPP_STD_VER >= 20 36e78f53d1SNikolas Klauser 37e78f53d1SNikolas Klauser namespace chrono { 38e78f53d1SNikolas Klauser 39e78f53d1SNikolas Klauser class nonexistent_local_time : public runtime_error { 40e78f53d1SNikolas Klauser public: 41e78f53d1SNikolas Klauser template <class _Duration> 42e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI nonexistent_local_time(const local_time<_Duration>& __time, const local_info& __info) 43e78f53d1SNikolas Klauser : runtime_error{__create_message(__time, __info)} { 44e78f53d1SNikolas Klauser // [time.zone.exception.nonexist]/2 45e78f53d1SNikolas Klauser // Preconditions: i.result == local_info::nonexistent is true. 46e78f53d1SNikolas Klauser // The value of __info.result is not used. 47e78f53d1SNikolas Klauser _LIBCPP_ASSERT_PEDANTIC(__info.result == local_info::nonexistent, 48e78f53d1SNikolas Klauser "creating an nonexistent_local_time from a local_info that is not non-existent"); 49e78f53d1SNikolas Klauser } 50e78f53d1SNikolas Klauser 51e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI nonexistent_local_time(const nonexistent_local_time&) = default; 52e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI nonexistent_local_time& operator=(const nonexistent_local_time&) = default; 53e78f53d1SNikolas Klauser 54e78f53d1SNikolas Klauser _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI ~nonexistent_local_time() override; // exported as key function 55e78f53d1SNikolas Klauser 56e78f53d1SNikolas Klauser private: 57e78f53d1SNikolas Klauser template <class _Duration> 58e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI string __create_message(const local_time<_Duration>& __time, const local_info& __info) { 59e78f53d1SNikolas Klauser return std::format( 60e78f53d1SNikolas Klauser R"({} is in a gap between 61e78f53d1SNikolas Klauser {} {} and 62e78f53d1SNikolas Klauser {} {} which are both equivalent to 63e78f53d1SNikolas Klauser {} UTC)", 64e78f53d1SNikolas Klauser __time, 65e78f53d1SNikolas Klauser local_seconds{__info.first.end.time_since_epoch()} + __info.first.offset, 66e78f53d1SNikolas Klauser __info.first.abbrev, 67e78f53d1SNikolas Klauser local_seconds{__info.second.begin.time_since_epoch()} + __info.second.offset, 68e78f53d1SNikolas Klauser __info.second.abbrev, 69e78f53d1SNikolas Klauser __info.first.end); 70e78f53d1SNikolas Klauser } 71e78f53d1SNikolas Klauser }; 72e78f53d1SNikolas Klauser 73e78f53d1SNikolas Klauser template <class _Duration> 74e78f53d1SNikolas Klauser _LIBCPP_NORETURN _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI void __throw_nonexistent_local_time( 75e78f53d1SNikolas Klauser [[maybe_unused]] const local_time<_Duration>& __time, [[maybe_unused]] const local_info& __info) { 76e78f53d1SNikolas Klauser # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 77e78f53d1SNikolas Klauser throw nonexistent_local_time(__time, __info); 78e78f53d1SNikolas Klauser # else 79e78f53d1SNikolas Klauser _LIBCPP_VERBOSE_ABORT("nonexistent_local_time was thrown in -fno-exceptions mode"); 80e78f53d1SNikolas Klauser # endif 81e78f53d1SNikolas Klauser } 82e78f53d1SNikolas Klauser 83e78f53d1SNikolas Klauser class ambiguous_local_time : public runtime_error { 84e78f53d1SNikolas Klauser public: 85e78f53d1SNikolas Klauser template <class _Duration> 86e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI ambiguous_local_time(const local_time<_Duration>& __time, const local_info& __info) 87e78f53d1SNikolas Klauser : runtime_error{__create_message(__time, __info)} { 88e78f53d1SNikolas Klauser // [time.zone.exception.ambig]/2 89e78f53d1SNikolas Klauser // Preconditions: i.result == local_info::ambiguous is true. 90e78f53d1SNikolas Klauser // The value of __info.result is not used. 91e78f53d1SNikolas Klauser _LIBCPP_ASSERT_PEDANTIC(__info.result == local_info::ambiguous, 92e78f53d1SNikolas Klauser "creating an ambiguous_local_time from a local_info that is not ambiguous"); 93e78f53d1SNikolas Klauser } 94e78f53d1SNikolas Klauser 95e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI ambiguous_local_time(const ambiguous_local_time&) = default; 96e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI ambiguous_local_time& operator=(const ambiguous_local_time&) = default; 97e78f53d1SNikolas Klauser 98e78f53d1SNikolas Klauser _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI ~ambiguous_local_time() override; // exported as key function 99e78f53d1SNikolas Klauser 100e78f53d1SNikolas Klauser private: 101e78f53d1SNikolas Klauser template <class _Duration> 102e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI string __create_message(const local_time<_Duration>& __time, const local_info& __info) { 103e78f53d1SNikolas Klauser return std::format( 104e78f53d1SNikolas Klauser // There are two spaces after the full-stop; this has been verified 105e78f53d1SNikolas Klauser // in the sources of the Standard. 106e78f53d1SNikolas Klauser R"({0} is ambiguous. It could be 107e78f53d1SNikolas Klauser {0} {1} == {2} UTC or 108e78f53d1SNikolas Klauser {0} {3} == {4} UTC)", 109e78f53d1SNikolas Klauser __time, 110e78f53d1SNikolas Klauser __info.first.abbrev, 111e78f53d1SNikolas Klauser __time - __info.first.offset, 112e78f53d1SNikolas Klauser __info.second.abbrev, 113e78f53d1SNikolas Klauser __time - __info.second.offset); 114e78f53d1SNikolas Klauser } 115e78f53d1SNikolas Klauser }; 116e78f53d1SNikolas Klauser 117e78f53d1SNikolas Klauser template <class _Duration> 118e78f53d1SNikolas Klauser _LIBCPP_NORETURN _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI void __throw_ambiguous_local_time( 119e78f53d1SNikolas Klauser [[maybe_unused]] const local_time<_Duration>& __time, [[maybe_unused]] const local_info& __info) { 120e78f53d1SNikolas Klauser # ifndef _LIBCPP_HAS_NO_EXCEPTIONS 121e78f53d1SNikolas Klauser throw ambiguous_local_time(__time, __info); 122e78f53d1SNikolas Klauser # else 123e78f53d1SNikolas Klauser _LIBCPP_VERBOSE_ABORT("ambiguous_local_time was thrown in -fno-exceptions mode"); 124e78f53d1SNikolas Klauser # endif 125e78f53d1SNikolas Klauser } 126e78f53d1SNikolas Klauser 127e78f53d1SNikolas Klauser } // namespace chrono 128e78f53d1SNikolas Klauser 129e78f53d1SNikolas Klauser # endif // _LIBCPP_STD_VER >= 20 130e78f53d1SNikolas Klauser 131e78f53d1SNikolas Klauser _LIBCPP_END_NAMESPACE_STD 132e78f53d1SNikolas Klauser 133e78f53d1SNikolas Klauser #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) 134e78f53d1SNikolas Klauser 135*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03___CHRONO_EXCEPTION_H 136