summaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/libcxx/src
diff options
context:
space:
mode:
authormikhnenko <[email protected]>2025-01-20 01:34:08 +0300
committermikhnenko <[email protected]>2025-01-20 01:51:09 +0300
commit2ab2ef14e493133a483a7210a0133c1d8918eee2 (patch)
treeb25a613d75999386160a0ffe41a4f69282a592b3 /contrib/libs/cxxsupp/libcxx/src
parent11def371ff569cef09101fa40c00e6180c3885bc (diff)
Update libcxx to 5 Mar 2024 80f9458cf30d13eef21b09042ea590945c5e64db
commit_hash:c45aa2ed98c2a01fa86b69bac97f40a32bd68ae2
Diffstat (limited to 'contrib/libs/cxxsupp/libcxx/src')
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/atomic.cpp1
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/call_once.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/error.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/format_string.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp31
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h6
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/fstream.cpp37
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/overridable_function.h119
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/to_chars_floating_point.h22
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/tzdb/time_zone_link_private.h27
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/tzdb/time_zone_private.h48
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/tzdb/types_private.h106
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/tzdb/tzdb_list_private.h104
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/tzdb/tzdb_private.h28
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/iostream.cpp90
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/locale.cpp4
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp5
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/mutex.cpp8
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/new.cpp124
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/ostream.cpp42
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/print.cpp25
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/std_stream.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/strstream.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/support/ibm/xlocale_zos.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp8
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp8
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp6
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/support/win32/thread_win32.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/system_error.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/time_zone.cpp32
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/tz.cpp146
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/tzdb.cpp641
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/tzdb_list.cpp70
35 files changed, 1408 insertions, 350 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/src/atomic.cpp b/contrib/libs/cxxsupp/libcxx/src/atomic.cpp
index 2f0389ae697..2b67685c8a0 100644
--- a/contrib/libs/cxxsupp/libcxx/src/atomic.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/atomic.cpp
@@ -178,6 +178,7 @@ _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t
_LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile* __location) {
__libcpp_contention_notify(&__libcpp_contention_state(__location)->__contention_state, __location, false);
}
+// This function is never used, but still exported for ABI compatibility.
_LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile* __location) {
return __libcpp_contention_monitor_for_wait(&__libcpp_contention_state(__location)->__contention_state, __location);
diff --git a/contrib/libs/cxxsupp/libcxx/src/call_once.cpp b/contrib/libs/cxxsupp/libcxx/src/call_once.cpp
index 7f5aef1db5c..2b981b69ab8 100644
--- a/contrib/libs/cxxsupp/libcxx/src/call_once.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/call_once.cpp
@@ -10,7 +10,7 @@
#include <__utility/exception_guard.h>
#ifndef _LIBCPP_HAS_NO_THREADS
-# include <__threading_support>
+# include <__thread/support.h>
#endif
#include "include/atomic_support.h"
diff --git a/contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp b/contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp
index 8b62d418401..59811ed7ff3 100644
--- a/contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp
@@ -12,7 +12,7 @@
// definition is only provided for ABI compatibility.
#include <__config>
-#include <__threading_support>
+#include <__thread/support.h>
#if _LIBCPP_ABI_VERSION == 1 || !defined(_LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION)
# define NEEDS_CONDVAR_DESTRUCTOR
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/error.h b/contrib/libs/cxxsupp/libcxx/src/filesystem/error.h
index b86f4ed4107..572cc73292a 100644
--- a/contrib/libs/cxxsupp/libcxx/src/filesystem/error.h
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/error.h
@@ -99,7 +99,7 @@ inline errc __win_err_to_errc(int err) {
#endif // _LIBCPP_WIN32API
inline error_code capture_errno() {
- _LIBCPP_ASSERT_UNCATEGORIZED(errno != 0, "Expected errno to be non-zero");
+ _LIBCPP_ASSERT_INTERNAL(errno != 0, "Expected errno to be non-zero");
return error_code(errno, generic_category());
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/format_string.h b/contrib/libs/cxxsupp/libcxx/src/filesystem/format_string.h
index 215d42421b2..a44def86f53 100644
--- a/contrib/libs/cxxsupp/libcxx/src/filesystem/format_string.h
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/format_string.h
@@ -47,7 +47,7 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const ch
size_t size_with_null = static_cast<size_t>(ret) + 1;
result.__resize_default_init(size_with_null - 1);
ret = ::vsnprintf(&result[0], size_with_null, msg, ap);
- _LIBCPP_ASSERT_UNCATEGORIZED(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
+ _LIBCPP_ASSERT_INTERNAL(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
}
return result;
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp b/contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp
index 1b9f2605805..fa31f05b2d2 100644
--- a/contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp
@@ -460,8 +460,21 @@ path __current_path(error_code* ec) {
typedef decltype(&::free) Deleter;
Deleter deleter = &::free;
#else
+ errno = 0; // Note: POSIX mandates that modifying `errno` is thread-safe.
auto size = ::pathconf(".", _PC_PATH_MAX);
- _LIBCPP_ASSERT_UNCATEGORIZED(size >= 0, "pathconf returned a 0 as max size");
+ if (size == -1) {
+ if (errno != 0) {
+ return err.report(capture_errno(), "call to pathconf failed");
+
+ // `pathconf` returns `-1` without an error to indicate no limit.
+ } else {
+# if defined(__MVS__) && !defined(PATH_MAX)
+ size = _XOPEN_PATH_MAX + 1;
+# else
+ size = PATH_MAX + 1;
+# endif
+ }
+ }
auto buff = unique_ptr<path::value_type[]>(new path::value_type[size + 1]);
path::value_type* ptr = buff.get();
@@ -608,10 +621,9 @@ void __permissions(const path& p, perms prms, perm_options opts, error_code* ec)
const bool resolve_symlinks = !has_opt(perm_options::nofollow);
const bool add_perms = has_opt(perm_options::add);
const bool remove_perms = has_opt(perm_options::remove);
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
(add_perms + remove_perms + has_opt(perm_options::replace)) == 1,
- "One and only one of the perm_options constants replace, add, or remove "
- "is present in opts");
+ "One and only one of the perm_options constants 'replace', 'add', or 'remove' must be present in opts");
bool set_sym_perms = false;
prms &= perms::mask;
@@ -621,7 +633,9 @@ void __permissions(const path& p, perms prms, perm_options opts, error_code* ec)
set_sym_perms = is_symlink(st);
if (m_ec)
return err.report(m_ec);
- _LIBCPP_ASSERT_UNCATEGORIZED(st.permissions() != perms::unknown, "Permissions unexpectedly unknown");
+ // TODO(hardening): double-check this assertion -- it might be a valid (if rare) case when the permissions are
+ // unknown.
+ _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(st.permissions() != perms::unknown, "Permissions unexpectedly unknown");
if (add_perms)
prms |= st.permissions();
else if (remove_perms)
@@ -668,7 +682,7 @@ path __read_symlink(const path& p, error_code* ec) {
detail::SSizeT ret;
if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1)
return err.report(capture_errno());
- _LIBCPP_ASSERT_UNCATEGORIZED(ret > 0, "TODO");
+ // Note that `ret` returning `0` would work, resulting in a valid empty string being returned.
if (static_cast<size_t>(ret) >= size)
return err.report(errc::value_too_large);
buff[ret] = 0;
@@ -801,8 +815,9 @@ uintmax_t remove_all_impl(int parent_directory, const path& p, error_code& ec) {
// If opening `p` failed because it wasn't a directory, remove it as
// a normal file instead. Note that `openat()` can return either ENOTDIR
- // or ELOOP depending on the exact reason of the failure.
- if (ec == errc::not_a_directory || ec == errc::too_many_symbolic_link_levels) {
+ // or ELOOP depending on the exact reason of the failure. On FreeBSD it
+ // may return EMLINK instead of ELOOP, contradicting POSIX.
+ if (ec == errc::not_a_directory || ec == errc::too_many_symbolic_link_levels || ec == errc::too_many_links) {
ec.clear();
if (::unlinkat(parent_directory, p.c_str(), /* flags = */ 0) == -1) {
ec = detail::capture_errno();
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h b/contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h
index ec2de49960b..760cdb65dae 100644
--- a/contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h
@@ -318,8 +318,8 @@ inline int statvfs(const wchar_t* p, StatVFS* buf) {
inline wchar_t* getcwd([[maybe_unused]] wchar_t* in_buf, [[maybe_unused]] size_t in_size) {
// Only expected to be used with us allocating the buffer.
- _LIBCPP_ASSERT_UNCATEGORIZED(in_buf == nullptr, "Windows getcwd() assumes in_buf==nullptr");
- _LIBCPP_ASSERT_UNCATEGORIZED(in_size == 0, "Windows getcwd() assumes in_size==0");
+ _LIBCPP_ASSERT_INTERNAL(in_buf == nullptr, "Windows getcwd() assumes in_buf==nullptr");
+ _LIBCPP_ASSERT_INTERNAL(in_size == 0, "Windows getcwd() assumes in_size==0");
size_t buff_size = MAX_PATH + 10;
std::unique_ptr<wchar_t, decltype(&::free)> buff(static_cast<wchar_t*>(malloc(buff_size * sizeof(wchar_t))), &::free);
@@ -338,7 +338,7 @@ inline wchar_t* getcwd([[maybe_unused]] wchar_t* in_buf, [[maybe_unused]] size_t
inline wchar_t* realpath(const wchar_t* path, [[maybe_unused]] wchar_t* resolved_name) {
// Only expected to be used with us allocating the buffer.
- _LIBCPP_ASSERT_UNCATEGORIZED(resolved_name == nullptr, "Windows realpath() assumes a null resolved_name");
+ _LIBCPP_ASSERT_INTERNAL(resolved_name == nullptr, "Windows realpath() assumes a null resolved_name");
WinHandle h(path, FILE_READ_ATTRIBUTES, 0);
if (!h) {
diff --git a/contrib/libs/cxxsupp/libcxx/src/fstream.cpp b/contrib/libs/cxxsupp/libcxx/src/fstream.cpp
new file mode 100644
index 00000000000..55a4442b9c7
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/fstream.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <__config>
+#include <cstdio>
+#include <fstream>
+
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <io.h>
+# include <windows.h>
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if defined(_LIBCPP_WIN32API)
+
+// Confirm that `HANDLE` is `void*` as implemented in `basic_filebuf`
+static_assert(std::same_as<HANDLE, void*>);
+
+_LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) noexcept {
+ // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170
+ intptr_t __handle = _get_osfhandle(fileno(__file));
+ if (__handle == -1)
+ return nullptr;
+ return reinterpret_cast<void*>(__handle);
+}
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/overridable_function.h b/contrib/libs/cxxsupp/libcxx/src/include/overridable_function.h
new file mode 100644
index 00000000000..7b0fba10f47
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/include/overridable_function.h
@@ -0,0 +1,119 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SRC_INCLUDE_OVERRIDABLE_FUNCTION_H
+#define _LIBCPP_SRC_INCLUDE_OVERRIDABLE_FUNCTION_H
+
+#include <__config>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+//
+// This file provides the std::__is_function_overridden utility, which allows checking
+// whether an overridable function (typically a weak symbol) like `operator new`
+// has been overridden by a user or not.
+//
+// This is a low-level utility which does not work on all platforms, since it needs
+// to make assumptions about the object file format in use. Furthermore, it requires
+// the "base definition" of the function (the one we want to check whether it has been
+// overridden) to be annotated with the _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro.
+//
+// This currently works with Mach-O files (used on Darwin) and with ELF files (used on Linux
+// and others). On platforms where we know how to implement this detection, the macro
+// _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION is defined to 1, and it is defined to 0 on
+// other platforms. The _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro is defined to
+// nothing on unsupported platforms so that it can be used to decorate functions regardless
+// of whether detection is actually supported.
+//
+// How does this work?
+// -------------------
+//
+// Let's say we want to check whether a weak function `f` has been overridden by the user.
+// The general mechanism works by placing `f`'s definition (in the libc++ built library)
+// inside a special section, which we do using the `__section__` attribute via the
+// _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro.
+//
+// Then, when comes the time to check whether the function has been overridden, we take
+// the address of the function and we check whether it falls inside the special function
+// we created. This can be done by finding pointers to the start and the end of the section
+// (which is done differently for ELF and Mach-O), and then checking whether `f` falls
+// within those bounds. If it falls within those bounds, then `f` is still inside the
+// special section and so it is the version we defined in the libc++ built library, i.e.
+// it was not overridden. Otherwise, it was overridden by the user because it falls
+// outside of the section.
+//
+// Important note
+// --------------
+//
+// This mechanism should never be used outside of the libc++ built library. In particular,
+// attempting to use this within the libc++ headers will not work at all because we don't
+// want to be defining special sections inside user's executables which use our headers.
+// This is provided inside libc++'s include tree solely to make it easier to share with
+// libc++abi, which needs the same mechanism.
+//
+
+#if defined(_LIBCPP_OBJECT_FORMAT_MACHO)
+
+# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
+# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE \
+ __attribute__((__section__("__TEXT,__lcxx_override,regular,pure_instructions")))
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Ret, class... _Args>
+_LIBCPP_HIDE_FROM_ABI bool __is_function_overridden(_Ret (*__fptr)(_Args...)) noexcept {
+ // Declare two dummy bytes and give them these special `__asm` values. These values are
+ // defined by the linker, which means that referring to `&__lcxx_override_start` will
+ // effectively refer to the address where the section starts (and same for the end).
+ extern char __lcxx_override_start __asm("section$start$__TEXT$__lcxx_override");
+ extern char __lcxx_override_end __asm("section$end$__TEXT$__lcxx_override");
+
+ // Now get a uintptr_t out of these locations, and out of the function pointer.
+ uintptr_t __start = reinterpret_cast<uintptr_t>(&__lcxx_override_start);
+ uintptr_t __end = reinterpret_cast<uintptr_t>(&__lcxx_override_end);
+ uintptr_t __ptr = reinterpret_cast<uintptr_t>(__fptr);
+
+ // Finally, the function was overridden if it falls outside of the section's bounds.
+ return __ptr < __start || __ptr > __end;
+}
+_LIBCPP_END_NAMESPACE_STD
+
+#elif defined(_LIBCPP_OBJECT_FORMAT_ELF)
+
+# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
+# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE __attribute__((__section__("__lcxx_override")))
+
+// This is very similar to what we do for Mach-O above. The ELF linker will implicitly define
+// variables with those names corresponding to the start and the end of the section.
+//
+// See https://stackoverflow.com/questions/16552710/how-do-you-get-the-start-and-end-addresses-of-a-custom-elf-section
+extern char __start___lcxx_override;
+extern char __stop___lcxx_override;
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Ret, class... _Args>
+_LIBCPP_HIDE_FROM_ABI bool __is_function_overridden(_Ret (*__fptr)(_Args...)) noexcept {
+ uintptr_t __start = reinterpret_cast<uintptr_t>(&__start___lcxx_override);
+ uintptr_t __end = reinterpret_cast<uintptr_t>(&__stop___lcxx_override);
+ uintptr_t __ptr = reinterpret_cast<uintptr_t>(__fptr);
+
+ return __ptr < __start || __ptr > __end;
+}
+_LIBCPP_END_NAMESPACE_STD
+
+#else
+
+# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 0
+# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE /* nothing */
+
+#endif
+
+#endif // _LIBCPP_SRC_INCLUDE_OVERRIDABLE_FUNCTION_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/to_chars_floating_point.h b/contrib/libs/cxxsupp/libcxx/src/include/to_chars_floating_point.h
index 3110bc20e16..01c26181697 100644
--- a/contrib/libs/cxxsupp/libcxx/src/include/to_chars_floating_point.h
+++ b/contrib/libs/cxxsupp/libcxx/src/include/to_chars_floating_point.h
@@ -269,7 +269,7 @@ to_chars_result _Floating_to_chars_hex_precision(
// * Print the leading hexit, then mask it away.
{
const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Adjusted_explicit_bits);
- _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 3, "");
+ _LIBCPP_ASSERT_INTERNAL(_Nibble < 3, "");
const char _Leading_hexit = static_cast<char>('0' + _Nibble);
*_First++ = _Leading_hexit;
@@ -288,12 +288,12 @@ to_chars_result _Floating_to_chars_hex_precision(
int32_t _Number_of_bits_remaining = _Adjusted_explicit_bits; // 24 for float, 52 for double
for (;;) {
- _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
- _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, "");
+ _LIBCPP_ASSERT_INTERNAL(_Number_of_bits_remaining >= 4, "");
+ _LIBCPP_ASSERT_INTERNAL(_Number_of_bits_remaining % 4 == 0, "");
_Number_of_bits_remaining -= 4;
const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining);
- _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, "");
+ _LIBCPP_ASSERT_INTERNAL(_Nibble < 16, "");
const char _Hexit = __itoa::_Charconv_digits[_Nibble];
*_First++ = _Hexit;
@@ -415,12 +415,12 @@ to_chars_result _Floating_to_chars_hex_shortest(
// '0' hexits, the same condition works (as we print the final hexit and mask it away); we don't need to test
// _Number_of_bits_remaining.
do {
- _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
- _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, "");
+ _LIBCPP_ASSERT_INTERNAL(_Number_of_bits_remaining >= 4, "");
+ _LIBCPP_ASSERT_INTERNAL(_Number_of_bits_remaining % 4 == 0, "");
_Number_of_bits_remaining -= 4;
const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining);
- _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, "");
+ _LIBCPP_ASSERT_INTERNAL(_Nibble < 16, "");
const char _Hexit = __itoa::_Charconv_digits[_Nibble];
if (_First == _Last) {
@@ -940,13 +940,13 @@ to_chars_result _Floating_to_chars_general_precision(
_Effective_precision = std::min(_Precision - (_Scientific_exponent_X + 1), _Max_fixed_precision);
const to_chars_result _Buf_result =
_Floating_to_chars_fixed_precision(_Buffer, std::end(_Buffer), _Value, _Effective_precision);
- _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
+ _LIBCPP_ASSERT_INTERNAL(_Buf_result.ec == errc{}, "");
_Significand_last = _Buf_result.ptr;
} else {
_Effective_precision = std::min(_Precision - 1, _Max_scientific_precision);
const to_chars_result _Buf_result =
_Floating_to_chars_scientific_precision(_Buffer, std::end(_Buffer), _Value, _Effective_precision);
- _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
+ _LIBCPP_ASSERT_INTERNAL(_Buf_result.ec == errc{}, "");
_Significand_last = std::find(_Buffer, _Buf_result.ptr, 'e');
_Exponent_first = _Significand_last;
_Exponent_last = _Buf_result.ptr;
@@ -992,9 +992,9 @@ to_chars_result _Floating_to_chars(
char* _First, char* const _Last, _Floating _Value, const chars_format _Fmt, const int _Precision) noexcept {
if constexpr (_Overload == _Floating_to_chars_overload::_Plain) {
- _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally
+ _LIBCPP_ASSERT_INTERNAL(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally
} else {
- _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format::general || _Fmt == chars_format::scientific
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(_Fmt == chars_format::general || _Fmt == chars_format::scientific
|| _Fmt == chars_format::fixed || _Fmt == chars_format::hex,
"invalid format in to_chars()");
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/tzdb/time_zone_link_private.h b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/time_zone_link_private.h
new file mode 100644
index 00000000000..13923762527
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/time_zone_link_private.h
@@ -0,0 +1,27 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
+
+#ifndef _LIBCPP_SRC_INCLUDE_TZDB_TIME_ZONE_LINK_PRIVATE_H
+#define _LIBCPP_SRC_INCLUDE_TZDB_TIME_ZONE_LINK_PRIVATE_H
+
+#include <chrono>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono {
+
+struct time_zone_link::__constructor_tag {};
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_SRC_INCLUDE_TZDB_TIME_ZONE_LINK_PRIVATE_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/tzdb/time_zone_private.h b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/time_zone_private.h
new file mode 100644
index 00000000000..039a3b0ffeb
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/time_zone_private.h
@@ -0,0 +1,48 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
+
+#ifndef _LIBCPP_SRC_INCLUDE_TZDB_TIME_ZONE_PRIVATE_H
+#define _LIBCPP_SRC_INCLUDE_TZDB_TIME_ZONE_PRIVATE_H
+
+#include <chrono>
+#include <string>
+#include <vector>
+
+#include "types_private.h"
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono {
+
+class time_zone::__impl {
+public:
+ explicit _LIBCPP_HIDE_FROM_ABI __impl(string&& __name) : __name_(std::move(__name)) {}
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view __name() const noexcept { return __name_; }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI vector<__tz::__continuation>& __continuations() { return __continuations_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const vector<__tz::__continuation>& __continuations() const {
+ return __continuations_;
+ }
+
+private:
+ string __name_;
+ // Note the first line has a name + __continuation, the other lines
+ // are just __continuations. So there is always at least one item in
+ // the vector.
+ vector<__tz::__continuation> __continuations_;
+};
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_SRC_INCLUDE_TZDB_TIME_ZONE_PRIVATE_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/tzdb/types_private.h b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/types_private.h
new file mode 100644
index 00000000000..4604b9fc881
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/types_private.h
@@ -0,0 +1,106 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
+
+#ifndef __LIBCPP_SRC_INCLUDE_TZDB_TYPES_PRIVATE_H
+#define __LIBCPP_SRC_INCLUDE_TZDB_TYPES_PRIVATE_H
+
+#include <chrono>
+#include <string>
+#include <utility>
+#include <variant>
+#include <vector>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// TODO TZDB
+// The helper classes in this header have no constructor but are loaded with
+// dedicated parse functions. In the original design this header was public and
+// the parsing was done in the dylib. In that design having constructors would
+// expand the ABI interface. Since this header is now in the dylib that design
+// should be reconsidered. (For now the design is kept as is, in case this
+// header needs to be public for unforseen reasons.)
+
+namespace chrono::__tz {
+
+// Sun>=8 first Sunday on or after the eighth
+// Sun<=25 last Sunday on or before the 25th
+struct __constrained_weekday {
+ /* year_month_day operator()(year __year, month __month);*/ // needed but not implemented
+
+ weekday __weekday;
+ enum __comparison_t { __le, __ge } __comparison;
+ day __day;
+};
+
+// The on field has a few alternative presentations
+// 5 the fifth of the month
+// lastSun the last Sunday in the month
+// lastMon the last Monday in the month
+// Sun>=8 first Sunday on or after the eighth
+// Sun<=25 last Sunday on or before the 25th
+using __on = variant<day, weekday_last, __constrained_weekday>;
+
+enum class __clock { __local, __standard, __universal };
+
+struct __at {
+ seconds __time{0};
+ __tz::__clock __clock{__tz::__clock::__local};
+};
+
+struct __save {
+ seconds __time;
+ bool __is_dst;
+};
+
+// The names of the fields match the fields of a Rule.
+struct __rule {
+ year __from;
+ year __to;
+ month __in;
+ __tz::__on __on;
+ __tz::__at __at;
+ __tz::__save __save;
+ string __letters;
+};
+
+using __rules_storage_type = std::vector<std::pair<string, vector<__tz::__rule>>>; // TODO TZDB use flat_map;
+
+struct __continuation {
+ // Non-owning link to the RULE entries.
+ __tz::__rules_storage_type* __rule_database_;
+
+ seconds __stdoff;
+
+ // The RULES is either a SAVE or a NAME.
+ // The size_t is used as cache. After loading the rules they are
+ // sorted and remain stable, then an index in the vector can be
+ // used.
+ // If this field contains - then standard time always
+ // applies. This is indicated by the monostate.
+ using __rules_t = variant<monostate, __tz::__save, string, size_t>;
+
+ __rules_t __rules;
+
+ string __format;
+ // TODO TZDB the until field can contain more than just a year.
+ // Parts of the UNTIL, the optional parts are default initialized
+ // optional<year> __until_;
+ year __year = chrono::year::min();
+ month __in{January};
+ __tz::__on __on{chrono::day{1}};
+ __tz::__at __at{chrono::seconds{0}, __tz::__clock::__local};
+};
+
+} // namespace chrono::__tz
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // __LIBCPP_SRC_INCLUDE_TZDB_TYPES_PRIVATE_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/tzdb/tzdb_list_private.h b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/tzdb_list_private.h
new file mode 100644
index 00000000000..f43d7d8ea77
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/tzdb_list_private.h
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
+
+#ifndef _LIBCPP_SRC_INCLUDE_TZDB_TZDB_LIST_PRIVATE_H
+#define _LIBCPP_SRC_INCLUDE_TZDB_TZDB_LIST_PRIVATE_H
+
+#include <__mutex/unique_lock.h>
+#include <forward_list>
+
+// When threads are not available the locking is not required.
+#ifndef _LIBCPP_HAS_NO_THREADS
+# include <shared_mutex>
+#endif
+
+#include "types_private.h"
+#include "tzdb_private.h"
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono {
+
+//===----------------------------------------------------------------------===//
+// Private API
+//===----------------------------------------------------------------------===//
+
+// The tzdb_list stores a list of "tzdb" entries.
+//
+// The public tzdb database does not store the RULE entries of the IANA
+// database. These entries are considered an implementation detail. Since most
+// of the tzdb_list interface is exposed as "a list of tzdb entries" it's not
+// possible to use a helper struct that stores a tzdb and the RULE database.
+// Instead this class stores these in parallel forward lists.
+//
+// Since the nodes of a forward_list are stable it's possible to store pointers
+// and references to these nodes.
+class tzdb_list::__impl {
+public:
+ __impl() { __load_no_lock(); }
+
+ [[nodiscard]] const tzdb& __load() {
+#ifndef _LIBCPP_HAS_NO_THREADS
+ unique_lock __lock{__mutex_};
+#endif
+ __load_no_lock();
+ return __tzdb_.front();
+ }
+
+ using const_iterator = tzdb_list::const_iterator;
+
+ const tzdb& front() const noexcept {
+#ifndef _LIBCPP_HAS_NO_THREADS
+ shared_lock __lock{__mutex_};
+#endif
+ return __tzdb_.front();
+ }
+
+ const_iterator erase_after(const_iterator __p) {
+#ifndef _LIBCPP_HAS_NO_THREADS
+ unique_lock __lock{__mutex_};
+#endif
+
+ __rules_.erase_after(std::next(__rules_.cbegin(), std::distance(__tzdb_.cbegin(), __p)));
+ return __tzdb_.erase_after(__p);
+ }
+
+ const_iterator begin() const noexcept {
+#ifndef _LIBCPP_HAS_NO_THREADS
+ shared_lock __lock{__mutex_};
+#endif
+ return __tzdb_.begin();
+ }
+ const_iterator end() const noexcept {
+ // forward_list<T>::end does not access the list, so no need to take a lock.
+ return __tzdb_.end();
+ }
+
+ const_iterator cbegin() const noexcept { return begin(); }
+ const_iterator cend() const noexcept { return end(); }
+
+private:
+ // Loads the tzdbs
+ // pre: The caller ensures the locking, if needed, is done.
+ void __load_no_lock() { chrono::__init_tzdb(__tzdb_.emplace_front(), __rules_.emplace_front()); }
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+ mutable shared_mutex __mutex_;
+#endif
+ forward_list<tzdb> __tzdb_;
+
+ forward_list<__tz::__rules_storage_type> __rules_;
+};
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_SRC_INCLUDE_TZDB_TZDB_LIST_PRIVATE_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/tzdb/tzdb_private.h b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/tzdb_private.h
new file mode 100644
index 00000000000..8ec3f890ef6
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/include/tzdb/tzdb_private.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
+
+#ifndef _LIBCPP_SRC_INCLUDE_TZDB_TZ_PRIVATE_H
+#define _LIBCPP_SRC_INCLUDE_TZDB_TZ_PRIVATE_H
+
+#include <chrono>
+
+#include "types_private.h"
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono {
+
+void __init_tzdb(tzdb& __tzdb, __tz::__rules_storage_type& __rules);
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_SRC_INCLUDE_TZDB_TZ_PRIVATE_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/iostream.cpp b/contrib/libs/cxxsupp/libcxx/src/iostream.cpp
index 93edf3a0d57..029de4a6806 100644
--- a/contrib/libs/cxxsupp/libcxx/src/iostream.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/iostream.cpp
@@ -22,127 +22,119 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
-_ALIGNAS_TYPE(istream) char _cin[sizeof(istream)];
+alignas(istream) char _cin[sizeof(istream)];
_LIBCPP_EXPORTED_FROM_ABI istream& cin = *reinterpret_cast<istream*>(_cin);
#else
-_ALIGNAS_TYPE(istream)
-_LIBCPP_EXPORTED_FROM_ABI char cin[sizeof(istream)]
-# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
+alignas(istream) _LIBCPP_EXPORTED_FROM_ABI char cin[sizeof(istream)]
+#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
__asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
-# endif
+#endif
;
#endif
-_ALIGNAS_TYPE(__stdinbuf<char>) static char __cin[sizeof(__stdinbuf<char>)];
+alignas(__stdinbuf<char>) static char __cin[sizeof(__stdinbuf<char>)];
static mbstate_t mb_cin;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
-_ALIGNAS_TYPE(wistream) char _wcin[sizeof(wistream)];
+alignas(wistream) char _wcin[sizeof(wistream)];
_LIBCPP_EXPORTED_FROM_ABI wistream& wcin = *reinterpret_cast<wistream*>(_wcin);
# else
-_ALIGNAS_TYPE(wistream)
-_LIBCPP_EXPORTED_FROM_ABI char wcin[sizeof(wistream)]
-# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
+alignas(wistream) _LIBCPP_EXPORTED_FROM_ABI char wcin[sizeof(wistream)]
+# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
__asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
-# endif
- ;
# endif
-_ALIGNAS_TYPE(__stdinbuf<wchar_t>) static char __wcin[sizeof(__stdinbuf<wchar_t>)];
+ ;
+#endif
+alignas(__stdinbuf<wchar_t>) static char __wcin[sizeof(__stdinbuf<wchar_t>)];
static mbstate_t mb_wcin;
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
-_ALIGNAS_TYPE(ostream) char _cout[sizeof(ostream)];
+alignas(ostream) char _cout[sizeof(ostream)];
_LIBCPP_EXPORTED_FROM_ABI ostream& cout = *reinterpret_cast<ostream*>(_cout);
#else
-_ALIGNAS_TYPE(ostream)
-_LIBCPP_EXPORTED_FROM_ABI char cout[sizeof(ostream)]
-# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
+alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char cout[sizeof(ostream)]
+#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
__asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
-# endif
+#endif
;
#endif
-_ALIGNAS_TYPE(__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
+alignas(__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
static mbstate_t mb_cout;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
-_ALIGNAS_TYPE(wostream) char _wcout[sizeof(wostream)];
+alignas(wostream) char _wcout[sizeof(wostream)];
_LIBCPP_EXPORTED_FROM_ABI wostream& wcout = *reinterpret_cast<wostream*>(_wcout);
# else
-_ALIGNAS_TYPE(wostream)
-_LIBCPP_EXPORTED_FROM_ABI char wcout[sizeof(wostream)]
-# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
+alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wcout[sizeof(wostream)]
+# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
__asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
-# endif
- ;
# endif
-_ALIGNAS_TYPE(__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];
+ ;
+#endif
+alignas(__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];
static mbstate_t mb_wcout;
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
-_ALIGNAS_TYPE(ostream) char _cerr[sizeof(ostream)];
+alignas(ostream) char _cerr[sizeof(ostream)];
_LIBCPP_EXPORTED_FROM_ABI ostream& cerr = *reinterpret_cast<ostream*>(_cerr);
#else
-_ALIGNAS_TYPE(ostream)
-_LIBCPP_EXPORTED_FROM_ABI char cerr[sizeof(ostream)]
-# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
+alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char cerr[sizeof(ostream)]
+#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
__asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
-# endif
+#endif
;
#endif
-_ALIGNAS_TYPE(__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
+alignas(__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
static mbstate_t mb_cerr;
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
-_ALIGNAS_TYPE(wostream) char _wcerr[sizeof(wostream)];
+alignas(wostream) char _wcerr[sizeof(wostream)];
_LIBCPP_EXPORTED_FROM_ABI wostream& wcerr = *reinterpret_cast<wostream*>(_wcerr);
# else
-_ALIGNAS_TYPE(wostream)
-_LIBCPP_EXPORTED_FROM_ABI char wcerr[sizeof(wostream)]
-# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
+alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wcerr[sizeof(wostream)]
+# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
__asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
-# endif
+# endif
;
# endif
-_ALIGNAS_TYPE(__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];
+alignas(__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];
static mbstate_t mb_wcerr;
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
-_ALIGNAS_TYPE(ostream) char _clog[sizeof(ostream)];
+alignas(ostream) char _clog[sizeof(ostream)];
_LIBCPP_EXPORTED_FROM_ABI ostream& clog = *reinterpret_cast<ostream*>(_clog);
#else
-_ALIGNAS_TYPE(ostream)
-_LIBCPP_EXPORTED_FROM_ABI char clog[sizeof(ostream)]
-# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
+alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char clog[sizeof(ostream)]
+#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
__asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
-# endif
+#endif
;
#endif
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
-_ALIGNAS_TYPE(wostream) char _wclog[sizeof(wostream)];
+alignas(wostream) char _wclog[sizeof(wostream)];
_LIBCPP_EXPORTED_FROM_ABI wostream& wclog = *reinterpret_cast<wostream*>(_wclog);
# else
-_ALIGNAS_TYPE(wostream)
-_LIBCPP_EXPORTED_FROM_ABI char wclog[sizeof(wostream)]
-# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
+alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wclog[sizeof(wostream)]
+# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)
__asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR
"@std@@@12@A")
-# endif
- ;
# endif
+ ;
+#endif
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
// Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority
diff --git a/contrib/libs/cxxsupp/libcxx/src/locale.cpp b/contrib/libs/cxxsupp/libcxx/src/locale.cpp
index 433394d58f6..1b937dcf970 100644
--- a/contrib/libs/cxxsupp/libcxx/src/locale.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/locale.cpp
@@ -34,9 +34,7 @@
# define _CTYPE_DISABLE_MACROS
#endif
-#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
-# include "__support/win32/locale_win32.h"
-#elif !defined(__BIONIC__) && !defined(__NuttX__)
+#if !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__) && !defined(__BIONIC__) && !defined(__NuttX__)
# include <langinfo.h>
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp b/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp
index afd1b892086..2117238e634 100644
--- a/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp
@@ -189,7 +189,8 @@ void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate(
return;
}
}
- _LIBCPP_ASSERT_UNCATEGORIZED(false, "deallocating a block that was not allocated with this allocator");
+ // The request to deallocate memory ends up being a no-op, likely resulting in a memory leak.
+ _LIBCPP_ASSERT_VALID_DEALLOCATION(false, "deallocating a block that was not allocated with this allocator");
}
}
@@ -230,7 +231,7 @@ public:
}
void* __allocate_in_new_chunk(memory_resource* upstream, size_t block_size, size_t chunk_size) {
- _LIBCPP_ASSERT_UNCATEGORIZED(chunk_size % block_size == 0, "");
+ _LIBCPP_ASSERT_INTERNAL(chunk_size % block_size == 0, "");
static_assert(__default_alignment >= alignof(std::max_align_t), "");
static_assert(__default_alignment >= alignof(__chunk_footer), "");
static_assert(__default_alignment >= alignof(__vacancy_header), "");
diff --git a/contrib/libs/cxxsupp/libcxx/src/mutex.cpp b/contrib/libs/cxxsupp/libcxx/src/mutex.cpp
index 13c63247f1a..26b26b691a2 100644
--- a/contrib/libs/cxxsupp/libcxx/src/mutex.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/mutex.cpp
@@ -38,7 +38,8 @@ bool mutex::try_lock() noexcept { return __libcpp_mutex_trylock(&__m_); }
void mutex::unlock() noexcept {
int ec = __libcpp_mutex_unlock(&__m_);
(void)ec;
- _LIBCPP_ASSERT_UNCATEGORIZED(ec == 0, "call to mutex::unlock failed");
+ _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(
+ ec == 0, "call to mutex::unlock failed. A possible reason is that the mutex wasn't locked");
}
// recursive_mutex
@@ -52,7 +53,7 @@ recursive_mutex::recursive_mutex() {
recursive_mutex::~recursive_mutex() {
int e = __libcpp_recursive_mutex_destroy(&__m_);
(void)e;
- _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to ~recursive_mutex() failed");
+ _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(e == 0, "call to ~recursive_mutex() failed");
}
void recursive_mutex::lock() {
@@ -64,7 +65,8 @@ void recursive_mutex::lock() {
void recursive_mutex::unlock() noexcept {
int e = __libcpp_recursive_mutex_unlock(&__m_);
(void)e;
- _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to recursive_mutex::unlock() failed");
+ _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(
+ e == 0, "call to recursive_mutex::unlock() failed. A possible reason is that the mutex wasn't locked");
}
bool recursive_mutex::try_lock() noexcept { return __libcpp_recursive_mutex_trylock(&__m_); }
diff --git a/contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp b/contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp
index d5ac257f94d..a6ceaaaf23f 100644
--- a/contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp
@@ -17,7 +17,7 @@
// _LIBCPP_BUILDING_LIBRARY to change the definition in the headers.
#include <__config>
-#include <__threading_support>
+#include <__thread/support.h>
#if _LIBCPP_ABI_VERSION == 1 || !defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION)
# define NEEDS_MUTEX_DESTRUCTOR
diff --git a/contrib/libs/cxxsupp/libcxx/src/new.cpp b/contrib/libs/cxxsupp/libcxx/src/new.cpp
index e9a4adcfdf4..7f1cc671f15 100644
--- a/contrib/libs/cxxsupp/libcxx/src/new.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/new.cpp
@@ -6,7 +6,10 @@
//
//===----------------------------------------------------------------------===//
+#include "include/overridable_function.h"
+#include <__assert>
#include <__memory/aligned_alloc.h>
+#include <cstddef>
#include <cstdlib>
#include <new>
@@ -15,12 +18,22 @@
// The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp
// file. The version in this file is the canonical one.
+inline void __throw_bad_alloc_shim() {
+# ifdef __EMSCRIPTEN__
+ abort();
+#else
+ std::__throw_bad_alloc();
+#endif
+}
+
+# define _LIBCPP_ASSERT_SHIM(expr, str) _LIBCPP_ASSERT(expr, str)
+
// ------------------ BEGIN COPY ------------------
// Implement all new and delete operators as weak definitions
// in this shared library, so that they can be overridden by programs
// that define non-weak copies of the functions.
-static void* operator_new_impl(std::size_t size) noexcept {
+static void* operator_new_impl(std::size_t size) {
if (size == 0)
size = 1;
void* p;
@@ -36,51 +49,63 @@ static void* operator_new_impl(std::size_t size) noexcept {
return p;
}
-_LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
void* p = operator_new_impl(size);
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
- if (p == nullptr)
- throw std::bad_alloc();
-# else
-# ifdef __EMSCRIPTEN__
if (p == nullptr)
- // Abort here so that when exceptions are disabled, we do not just
- // return 0 when malloc returns 0.
- // We could also do this with set_new_handler, but that adds a
- // global constructor and a table entry, overhead that we can avoid
- // by doing it this way.
- abort();
-# endif
-# endif
+ __throw_bad_alloc_shim();
return p;
}
_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
+# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
+ _LIBCPP_ASSERT_SHIM(
+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)),
+ "libc++ was configured with exceptions disabled and `operator new(size_t)` has been overridden, "
+ "but `operator new(size_t, nothrow_t)` has not been overridden. This is problematic because "
+ "`operator new(size_t, nothrow_t)` must call `operator new(size_t)`, which will terminate in case "
+ "it fails to allocate, making it impossible for `operator new(size_t, nothrow_t)` to fulfill its "
+ "contract (since it should return nullptr upon failure). Please make sure you override "
+ "`operator new(size_t, nothrow_t)` as well.");
+# endif
+
+ return operator_new_impl(size);
+# else
void* p = nullptr;
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try {
-# endif // _LIBCPP_HAS_NO_EXCEPTIONS
p = ::operator new(size);
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
} catch (...) {
}
-# endif // _LIBCPP_HAS_NO_EXCEPTIONS
return p;
+# endif
}
-_LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC { return ::operator new(size); }
+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC {
+ return ::operator new(size);
+}
_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
+# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
+ _LIBCPP_ASSERT_SHIM(
+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])),
+ "libc++ was configured with exceptions disabled and `operator new[](size_t)` has been overridden, "
+ "but `operator new[](size_t, nothrow_t)` has not been overridden. This is problematic because "
+ "`operator new[](size_t, nothrow_t)` must call `operator new[](size_t)`, which will terminate in case "
+ "it fails to allocate, making it impossible for `operator new[](size_t, nothrow_t)` to fulfill its "
+ "contract (since it should return nullptr upon failure). Please make sure you override "
+ "`operator new[](size_t, nothrow_t)` as well.");
+# endif
+
+ return operator_new_impl(size);
+# else
void* p = nullptr;
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try {
-# endif // _LIBCPP_HAS_NO_EXCEPTIONS
p = ::operator new[](size);
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
} catch (...) {
}
-# endif // _LIBCPP_HAS_NO_EXCEPTIONS
return p;
+# endif
}
_LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); }
@@ -97,7 +122,7 @@ _LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator del
# if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
-static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept {
+static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) {
if (size == 0)
size = 1;
if (static_cast<size_t>(alignment) < sizeof(void*))
@@ -117,43 +142,66 @@ static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignm
return p;
}
-_LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*
+operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
void* p = operator_new_aligned_impl(size, alignment);
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
if (p == nullptr)
- throw std::bad_alloc();
-# endif
+ __throw_bad_alloc_shim();
return p;
}
_LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
+ _LIBCPP_ASSERT_SHIM(
+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)),
+ "libc++ was configured with exceptions disabled and `operator new(size_t, align_val_t)` has been overridden, "
+ "but `operator new(size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "
+ "`operator new(size_t, align_val_t, nothrow_t)` must call `operator new(size_t, align_val_t)`, which will "
+ "terminate in case it fails to allocate, making it impossible for `operator new(size_t, align_val_t, nothrow_t)` "
+ "to fulfill its contract (since it should return nullptr upon failure). Please make sure you override "
+ "`operator new(size_t, align_val_t, nothrow_t)` as well.");
+# endif
+
+ return operator_new_aligned_impl(size, alignment);
+# else
void* p = nullptr;
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try {
-# endif // _LIBCPP_HAS_NO_EXCEPTIONS
p = ::operator new(size, alignment);
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
} catch (...) {
}
-# endif // _LIBCPP_HAS_NO_EXCEPTIONS
return p;
+# endif
}
-_LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*
+operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
return ::operator new(size, alignment);
}
_LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
+ _LIBCPP_ASSERT_SHIM(
+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])),
+ "libc++ was configured with exceptions disabled and `operator new[](size_t, align_val_t)` has been overridden, "
+ "but `operator new[](size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "
+ "`operator new[](size_t, align_val_t, nothrow_t)` must call `operator new[](size_t, align_val_t)`, which will "
+ "terminate in case it fails to allocate, making it impossible for `operator new[](size_t, align_val_t, "
+ "nothrow_t)` to fulfill its contract (since it should return nullptr upon failure). Please make sure you "
+ "override "
+ "`operator new[](size_t, align_val_t, nothrow_t)` as well.");
+# endif
+
+ return operator_new_aligned_impl(size, alignment);
+# else
void* p = nullptr;
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try {
-# endif // _LIBCPP_HAS_NO_EXCEPTIONS
p = ::operator new[](size, alignment);
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
} catch (...) {
}
-# endif // _LIBCPP_HAS_NO_EXCEPTIONS
return p;
+# endif
}
_LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); }
diff --git a/contrib/libs/cxxsupp/libcxx/src/ostream.cpp b/contrib/libs/cxxsupp/libcxx/src/ostream.cpp
new file mode 100644
index 00000000000..443dce9a390
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/ostream.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <__availability>
+#include <__config>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM
+# include <fstream>
+#endif
+#include <ostream>
+
+#include "std_stream.h"
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_EXPORTED_FROM_ABI FILE* __get_ostream_file(ostream& __os) {
+ // dynamic_cast requires RTTI, this only affects users whose vendor builds
+ // the dylib with RTTI disabled. It does not affect users who build with RTTI
+ // disabled but use a dylib where the RTTI is enabled.
+ //
+ // Returning a nullptr means the stream is not considered a terminal and the
+ // special terminal handling is not done. The terminal handling is mainly of
+ // importance on Windows.
+#ifndef _LIBCPP_HAS_NO_RTTI
+ auto* __rdbuf = __os.rdbuf();
+# ifndef _LIBCPP_HAS_NO_FILESYSTEM
+ if (auto* __buffer = dynamic_cast<filebuf*>(__rdbuf))
+ return __buffer->__file_;
+# endif
+
+ if (auto* __buffer = dynamic_cast<__stdoutbuf<char>*>(__rdbuf))
+ return __buffer->__file_;
+#endif // _LIBCPP_HAS_NO_RTTI
+
+ return nullptr;
+}
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/print.cpp b/contrib/libs/cxxsupp/libcxx/src/print.cpp
index 3692187a595..8fa59fdd097 100644
--- a/contrib/libs/cxxsupp/libcxx/src/print.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/print.cpp
@@ -8,22 +8,26 @@
#include <__config>
-#if defined(_LIBCPP_WIN32API)
+#include <cstdlib>
+#include <print>
+
+#include <__system_error/system_error.h>
-# include <cstdlib>
-# include <print>
+#include "filesystem/error.h"
+#if defined(_LIBCPP_WIN32API)
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include <io.h>
# include <windows.h>
-
-# include <__system_error/system_error.h>
-
-# include "filesystem/error.h"
+#elif __has_include(<unistd.h>)
+# include <unistd.h>
+#endif
_LIBCPP_BEGIN_NAMESPACE_STD
+#if defined(_LIBCPP_WIN32API)
+
_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream) {
// Note the Standard does this in one call, but it's unclear whether
// an invalid handle is allowed when calling GetConsoleMode.
@@ -52,6 +56,9 @@ __write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wst
}
# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_END_NAMESPACE_STD
+#elif __has_include(<unistd.h>) // !_LIBCPP_WIN32API
-#endif // !_LIBCPP_WIN32API
+_LIBCPP_EXPORTED_FROM_ABI bool __is_posix_terminal(FILE* __stream) { return isatty(fileno(__stream)); }
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/std_stream.h b/contrib/libs/cxxsupp/libcxx/src/std_stream.h
index c4e9733601d..e55cd0b6b77 100644
--- a/contrib/libs/cxxsupp/libcxx/src/std_stream.h
+++ b/contrib/libs/cxxsupp/libcxx/src/std_stream.h
@@ -269,6 +269,8 @@ private:
__stdoutbuf(const __stdoutbuf&);
__stdoutbuf& operator=(const __stdoutbuf&);
+
+ _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
};
template <class _CharT>
diff --git a/contrib/libs/cxxsupp/libcxx/src/strstream.cpp b/contrib/libs/cxxsupp/libcxx/src/strstream.cpp
index a9b5989ec49..70374191c6a 100644
--- a/contrib/libs/cxxsupp/libcxx/src/strstream.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/strstream.cpp
@@ -120,7 +120,7 @@ strstreambuf::int_type strstreambuf::overflow(int_type __c) {
if (buf == nullptr)
return int_type(EOF);
if (old_size != 0) {
- _LIBCPP_ASSERT_UNCATEGORIZED(eback(), "overflow copying from NULL");
+ _LIBCPP_ASSERT_INTERNAL(eback(), "strstreambuf::overflow reallocating but the get area is a null pointer");
memcpy(buf, eback(), static_cast<size_t>(old_size));
}
ptrdiff_t ninp = gptr() - eback();
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/ibm/xlocale_zos.cpp b/contrib/libs/cxxsupp/libcxx/src/support/ibm/xlocale_zos.cpp
index 4c20997b4eb..9a90e08e11c 100644
--- a/contrib/libs/cxxsupp/libcxx/src/support/ibm/xlocale_zos.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/support/ibm/xlocale_zos.cpp
@@ -103,7 +103,7 @@ locale_t uselocale(locale_t newloc) {
tokenized.push_back(s);
}
- _LIBCPP_ASSERT_UNCATEGORIZED(tokenized.size() >= _NCAT, "locale-name list is too short");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(tokenized.size() >= _NCAT, "locale-name list is too short");
previous_loc->lc_collate = tokenized[LC_COLLATE];
previous_loc->lc_ctype = tokenized[LC_CTYPE];
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
index c07de5838b1..bdb17b9996b 100644
--- a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
+++ b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
@@ -28,6 +28,14 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
return *this;
}
+exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
+ exception_ptr ptr;
+ ptr.__ptr_ = __e;
+ __cxa_increment_exception_refcount(ptr.__ptr_);
+
+ return ptr;
+}
+
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
nested_exception::~nested_exception() noexcept {}
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
index 8e0e63cd4d4..6dad248f9e1 100644
--- a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
+++ b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
@@ -23,6 +23,7 @@ namespace __exception_ptr {
struct exception_ptr {
void* __ptr_;
+ explicit exception_ptr(void*) noexcept;
exception_ptr(const exception_ptr&) noexcept;
exception_ptr& operator=(const exception_ptr&) noexcept;
~exception_ptr() noexcept;
@@ -45,6 +46,13 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
return *this;
}
+exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
+ exception_ptr ptr{};
+ new (reinterpret_cast<void*>(&ptr)) __exception_ptr::exception_ptr(__e);
+
+ return ptr;
+}
+
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
_LIBCPP_NORETURN void nested_exception::rethrow_nested() const {
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
index de0605d7774..e12b0caf419 100644
--- a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
+++ b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
@@ -30,6 +30,12 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
::abort();
}
+exception_ptr exception_ptr::__from_native_exception_pointer(void *__e) noexcept {
+#warning exception_ptr not yet implemented
+ fprintf(stderr, "exception_ptr not yet implemented\n");
+ ::abort();
+}
+
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
#if !defined(__GLIBCXX__)
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/win32/thread_win32.cpp b/contrib/libs/cxxsupp/libcxx/src/support/win32/thread_win32.cpp
index 8736a532073..a2585c0b89f 100644
--- a/contrib/libs/cxxsupp/libcxx/src/support/win32/thread_win32.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/support/win32/thread_win32.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <__threading_support>
+#include <__thread/support/windows.h>
#include <chrono>
#define NOMINMAX
diff --git a/contrib/libs/cxxsupp/libcxx/src/system_error.cpp b/contrib/libs/cxxsupp/libcxx/src/system_error.cpp
index 034b73c5480..f518b480a27 100644
--- a/contrib/libs/cxxsupp/libcxx/src/system_error.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/system_error.cpp
@@ -68,7 +68,7 @@ __attribute__((unused)) const char* handle_strerror_r_return(int strerror_return
if (new_errno == EINVAL)
return "";
- _LIBCPP_ASSERT_UNCATEGORIZED(new_errno == ERANGE, "unexpected error from ::strerror_r");
+ _LIBCPP_ASSERT_INTERNAL(new_errno == ERANGE, "unexpected error from ::strerror_r");
// FIXME maybe? 'strerror_buff_size' is likely to exceed the
// maximum error size so ERANGE shouldn't be returned.
std::abort();
diff --git a/contrib/libs/cxxsupp/libcxx/src/time_zone.cpp b/contrib/libs/cxxsupp/libcxx/src/time_zone.cpp
new file mode 100644
index 00000000000..b6bf06a116f
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/time_zone.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
+
+#include <chrono>
+
+#include "include/tzdb/time_zone_private.h"
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono {
+
+[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI time_zone time_zone::__create(unique_ptr<time_zone::__impl>&& __p) {
+ _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "initialized time_zone without a valid pimpl object");
+ time_zone result;
+ result.__impl_ = std::move(__p);
+ return result;
+}
+
+_LIBCPP_EXPORTED_FROM_ABI time_zone::~time_zone() = default;
+
+[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view time_zone::__name() const noexcept { return __impl_->__name(); }
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/tz.cpp b/contrib/libs/cxxsupp/libcxx/src/tz.cpp
deleted file mode 100644
index 4425f0e6b91..00000000000
--- a/contrib/libs/cxxsupp/libcxx/src/tz.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
-
-#include <chrono>
-#include <filesystem>
-#include <fstream>
-#include <stdexcept>
-#include <string>
-
-// Contains a parser for the IANA time zone data files.
-//
-// These files can be found at https://data.iana.org/time-zones/ and are in the
-// public domain. Information regarding the input can be found at
-// https://data.iana.org/time-zones/tz-how-to.html and
-// https://man7.org/linux/man-pages/man8/zic.8.html.
-//
-// As indicated at https://howardhinnant.github.io/date/tz.html#Installation
-// For Windows another file seems to be required
-// https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml
-// This file seems to contain the mapping of Windows time zone name to IANA
-// time zone names.
-//
-// However this article mentions another way to do the mapping on Windows
-// https://devblogs.microsoft.com/oldnewthing/20210527-00/?p=105255
-// This requires Windows 10 Version 1903, which was released in May of 2019
-// and considered end of life in December 2020
-// https://learn.microsoft.com/en-us/lifecycle/announcements/windows-10-1903-end-of-servicing
-//
-// TODO TZDB Implement the Windows mapping in tzdb::current_zone
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-namespace chrono {
-
-// This function is weak so it can be overriden in the tests. The
-// declaration is in the test header test/support/test_tzdb.h
-_LIBCPP_WEAK string_view __libcpp_tzdb_directory() {
-#if defined(__linux__)
- return "/usr/share/zoneinfo/";
-#else
-# error "unknown path to the IANA Time Zone Database"
-#endif
-}
-
-[[nodiscard]] static bool __is_whitespace(int __c) { return __c == ' ' || __c == '\t'; }
-
-static void __skip_optional_whitespace(istream& __input) {
- while (chrono::__is_whitespace(__input.peek()))
- __input.get();
-}
-
-static void __skip_mandatory_whitespace(istream& __input) {
- if (!chrono::__is_whitespace(__input.get()))
- std::__throw_runtime_error("corrupt tzdb: expected whitespace");
-
- chrono::__skip_optional_whitespace(__input);
-}
-
-static void __matches(istream& __input, char __expected) {
- if (std::tolower(__input.get()) != __expected)
- std::__throw_runtime_error((string("corrupt tzdb: expected character '") + __expected + '\'').c_str());
-}
-
-static void __matches(istream& __input, string_view __expected) {
- for (auto __c : __expected)
- if (std::tolower(__input.get()) != __c)
- std::__throw_runtime_error((string("corrupt tzdb: expected string '") + string(__expected) + '\'').c_str());
-}
-
-[[nodiscard]] static string __parse_string(istream& __input) {
- string __result;
- while (true) {
- int __c = __input.get();
- switch (__c) {
- case ' ':
- case '\t':
- case '\n':
- __input.unget();
- [[fallthrough]];
- case istream::traits_type::eof():
- if (__result.empty())
- std::__throw_runtime_error("corrupt tzdb: expected a string");
-
- return __result;
-
- default:
- __result.push_back(__c);
- }
- }
-}
-
-static string __parse_version(istream& __input) {
- // The first line in tzdata.zi contains
- // # version YYYYw
- // The parser expects this pattern
- // #\s*version\s*\(.*)
- // This part is not documented.
- chrono::__matches(__input, '#');
- chrono::__skip_optional_whitespace(__input);
- chrono::__matches(__input, "version");
- chrono::__skip_mandatory_whitespace(__input);
- return chrono::__parse_string(__input);
-}
-
-static tzdb __make_tzdb() {
- tzdb __result;
-
- filesystem::path __root = chrono::__libcpp_tzdb_directory();
- ifstream __tzdata{__root / "tzdata.zi"};
-
- __result.version = chrono::__parse_version(__tzdata);
- return __result;
-}
-
-//===----------------------------------------------------------------------===//
-// Public API
-//===----------------------------------------------------------------------===//
-
-_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list() {
- static tzdb_list __result{chrono::__make_tzdb()};
- return __result;
-}
-
-_LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb() {
- if (chrono::remote_version() == chrono::get_tzdb().version)
- return chrono::get_tzdb();
-
- return chrono::get_tzdb_list().__emplace_front(chrono::__make_tzdb());
-}
-
-_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version() {
- filesystem::path __root = chrono::__libcpp_tzdb_directory();
- ifstream __tzdata{__root / "tzdata.zi"};
- return chrono::__parse_version(__tzdata);
-}
-
-} // namespace chrono
-
-_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/tzdb.cpp b/contrib/libs/cxxsupp/libcxx/src/tzdb.cpp
new file mode 100644
index 00000000000..2bb801e4869
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/tzdb.cpp
@@ -0,0 +1,641 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
+
+#include <algorithm>
+#include <chrono>
+#include <filesystem>
+#include <fstream>
+#include <stdexcept>
+#include <string>
+
+#include "include/tzdb/time_zone_link_private.h"
+#include "include/tzdb/time_zone_private.h"
+#include "include/tzdb/types_private.h"
+#include "include/tzdb/tzdb_list_private.h"
+#include "include/tzdb/tzdb_private.h"
+
+// Contains a parser for the IANA time zone data files.
+//
+// These files can be found at https://data.iana.org/time-zones/ and are in the
+// public domain. Information regarding the input can be found at
+// https://data.iana.org/time-zones/tz-how-to.html and
+// https://man7.org/linux/man-pages/man8/zic.8.html.
+//
+// As indicated at https://howardhinnant.github.io/date/tz.html#Installation
+// For Windows another file seems to be required
+// https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml
+// This file seems to contain the mapping of Windows time zone name to IANA
+// time zone names.
+//
+// However this article mentions another way to do the mapping on Windows
+// https://devblogs.microsoft.com/oldnewthing/20210527-00/?p=105255
+// This requires Windows 10 Version 1903, which was released in May of 2019
+// and considered end of life in December 2020
+// https://learn.microsoft.com/en-us/lifecycle/announcements/windows-10-1903-end-of-servicing
+//
+// TODO TZDB Implement the Windows mapping in tzdb::current_zone
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono {
+
+// This function is weak so it can be overriden in the tests. The
+// declaration is in the test header test/support/test_tzdb.h
+_LIBCPP_WEAK string_view __libcpp_tzdb_directory() {
+#if defined(__linux__)
+ return "/usr/share/zoneinfo/";
+#else
+# error "unknown path to the IANA Time Zone Database"
+#endif
+}
+
+//===----------------------------------------------------------------------===//
+// Details
+//===----------------------------------------------------------------------===//
+
+[[nodiscard]] static bool __is_whitespace(int __c) { return __c == ' ' || __c == '\t'; }
+
+static void __skip_optional_whitespace(istream& __input) {
+ while (chrono::__is_whitespace(__input.peek()))
+ __input.get();
+}
+
+static void __skip_mandatory_whitespace(istream& __input) {
+ if (!chrono::__is_whitespace(__input.get()))
+ std::__throw_runtime_error("corrupt tzdb: expected whitespace");
+
+ chrono::__skip_optional_whitespace(__input);
+}
+
+[[nodiscard]] static bool __is_eol(int __c) { return __c == '\n' || __c == std::char_traits<char>::eof(); }
+
+static void __skip_line(istream& __input) {
+ while (!chrono::__is_eol(__input.peek())) {
+ __input.get();
+ }
+ __input.get();
+}
+
+static void __skip(istream& __input, char __suffix) {
+ if (std::tolower(__input.peek()) == __suffix)
+ __input.get();
+}
+
+static void __skip(istream& __input, string_view __suffix) {
+ for (auto __c : __suffix)
+ if (std::tolower(__input.peek()) == __c)
+ __input.get();
+}
+
+static void __matches(istream& __input, char __expected) {
+ if (std::tolower(__input.get()) != __expected)
+ std::__throw_runtime_error((string("corrupt tzdb: expected character '") + __expected + '\'').c_str());
+}
+
+static void __matches(istream& __input, string_view __expected) {
+ for (auto __c : __expected)
+ if (std::tolower(__input.get()) != __c)
+ std::__throw_runtime_error((string("corrupt tzdb: expected string '") + string(__expected) + '\'').c_str());
+}
+
+[[nodiscard]] static string __parse_string(istream& __input) {
+ string __result;
+ while (true) {
+ int __c = __input.get();
+ switch (__c) {
+ case ' ':
+ case '\t':
+ case '\n':
+ __input.unget();
+ [[fallthrough]];
+ case istream::traits_type::eof():
+ if (__result.empty())
+ std::__throw_runtime_error("corrupt tzdb: expected a string");
+
+ return __result;
+
+ default:
+ __result.push_back(__c);
+ }
+ }
+}
+
+[[nodiscard]] static int64_t __parse_integral(istream& __input, bool __leading_zero_allowed) {
+ int64_t __result = __input.get();
+ if (__leading_zero_allowed) {
+ if (__result < '0' || __result > '9')
+ std::__throw_runtime_error("corrupt tzdb: expected a digit");
+ } else {
+ if (__result < '1' || __result > '9')
+ std::__throw_runtime_error("corrupt tzdb: expected a non-zero digit");
+ }
+ __result -= '0';
+ while (true) {
+ if (__input.peek() < '0' || __input.peek() > '9')
+ return __result;
+
+ // In order to avoid possible overflows we limit the accepted range.
+ // Most values parsed are expected to be very small:
+ // - 8784 hours in a year
+ // - 31 days in a month
+ // - year no real maximum, these values are expected to be less than
+ // the range of the year type.
+ //
+ // However the leapseconds use a seconds after epoch value. Using an
+ // int would run into an overflow in 2038. By using a 64-bit value
+ // the range is large enough for the bilions of years. Limiting that
+ // range slightly to make the code easier is not an issue.
+ if (__result > (std::numeric_limits<int64_t>::max() / 16))
+ std::__throw_runtime_error("corrupt tzdb: integral too large");
+
+ __result *= 10;
+ __result += __input.get() - '0';
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Calendar
+//===----------------------------------------------------------------------===//
+
+[[nodiscard]] static day __parse_day(istream& __input) {
+ unsigned __result = chrono::__parse_integral(__input, false);
+ if (__result > 31)
+ std::__throw_runtime_error("corrupt tzdb day: value too large");
+ return day{__result};
+}
+
+[[nodiscard]] static weekday __parse_weekday(istream& __input) {
+ // TZDB allows the shortest unique name.
+ switch (std::tolower(__input.get())) {
+ case 'f':
+ chrono::__skip(__input, "riday");
+ return Friday;
+
+ case 'm':
+ chrono::__skip(__input, "onday");
+ return Monday;
+
+ case 's':
+ switch (std::tolower(__input.get())) {
+ case 'a':
+ chrono::__skip(__input, "turday");
+ return Saturday;
+
+ case 'u':
+ chrono::__skip(__input, "nday");
+ return Sunday;
+ }
+ break;
+
+ case 't':
+ switch (std::tolower(__input.get())) {
+ case 'h':
+ chrono::__skip(__input, "ursday");
+ return Thursday;
+
+ case 'u':
+ chrono::__skip(__input, "esday");
+ return Tuesday;
+ }
+ break;
+ case 'w':
+ chrono::__skip(__input, "ednesday");
+ return Wednesday;
+ }
+
+ std::__throw_runtime_error("corrupt tzdb weekday: invalid name");
+}
+
+[[nodiscard]] static month __parse_month(istream& __input) {
+ // TZDB allows the shortest unique name.
+ switch (std::tolower(__input.get())) {
+ case 'a':
+ switch (std::tolower(__input.get())) {
+ case 'p':
+ chrono::__skip(__input, "ril");
+ return April;
+
+ case 'u':
+ chrono::__skip(__input, "gust");
+ return August;
+ }
+ break;
+
+ case 'd':
+ chrono::__skip(__input, "ecember");
+ return December;
+
+ case 'f':
+ chrono::__skip(__input, "ebruary");
+ return February;
+
+ case 'j':
+ switch (std::tolower(__input.get())) {
+ case 'a':
+ chrono::__skip(__input, "nuary");
+ return January;
+
+ case 'u':
+ switch (std::tolower(__input.get())) {
+ case 'n':
+ chrono::__skip(__input, 'e');
+ return June;
+
+ case 'l':
+ chrono::__skip(__input, 'y');
+ return July;
+ }
+ }
+ break;
+
+ case 'm':
+ if (std::tolower(__input.get()) == 'a')
+ switch (std::tolower(__input.get())) {
+ case 'y':
+ return May;
+
+ case 'r':
+ chrono::__skip(__input, "ch");
+ return March;
+ }
+ break;
+
+ case 'n':
+ chrono::__skip(__input, "ovember");
+ return November;
+
+ case 'o':
+ chrono::__skip(__input, "ctober");
+ return October;
+
+ case 's':
+ chrono::__skip(__input, "eptember");
+ return September;
+ }
+ std::__throw_runtime_error("corrupt tzdb month: invalid name");
+}
+
+[[nodiscard]] static year __parse_year_value(istream& __input) {
+ bool __negative = __input.peek() == '-';
+ if (__negative) [[unlikely]]
+ __input.get();
+
+ int64_t __result = __parse_integral(__input, true);
+ if (__result > static_cast<int>(year::max())) {
+ if (__negative)
+ std::__throw_runtime_error("corrupt tzdb year: year is less than the minimum");
+
+ std::__throw_runtime_error("corrupt tzdb year: year is greater than the maximum");
+ }
+
+ return year{static_cast<int>(__negative ? -__result : __result)};
+}
+
+[[nodiscard]] static year __parse_year(istream& __input) {
+ if (std::tolower(__input.peek()) != 'm') [[likely]]
+ return chrono::__parse_year_value(__input);
+
+ __input.get();
+ switch (std::tolower(__input.peek())) {
+ case 'i':
+ __input.get();
+ chrono::__skip(__input, 'n');
+ [[fallthrough]];
+
+ case ' ':
+ // The m is minimum, even when that is ambiguous.
+ return year::min();
+
+ case 'a':
+ __input.get();
+ chrono::__skip(__input, 'x');
+ return year::max();
+ }
+
+ std::__throw_runtime_error("corrupt tzdb year: expected 'min' or 'max'");
+}
+
+//===----------------------------------------------------------------------===//
+// TZDB fields
+//===----------------------------------------------------------------------===//
+
+[[nodiscard]] static year __parse_to(istream& __input, year __only) {
+ if (std::tolower(__input.peek()) != 'o')
+ return chrono::__parse_year(__input);
+
+ __input.get();
+ chrono::__skip(__input, "nly");
+ return __only;
+}
+
+[[nodiscard]] static __tz::__constrained_weekday::__comparison_t __parse_comparison(istream& __input) {
+ switch (__input.get()) {
+ case '>':
+ chrono::__matches(__input, '=');
+ return __tz::__constrained_weekday::__ge;
+
+ case '<':
+ chrono::__matches(__input, '=');
+ return __tz::__constrained_weekday::__le;
+ }
+ std::__throw_runtime_error("corrupt tzdb on: expected '>=' or '<='");
+}
+
+[[nodiscard]] static __tz::__on __parse_on(istream& __input) {
+ if (std::isdigit(__input.peek()))
+ return chrono::__parse_day(__input);
+
+ if (std::tolower(__input.peek()) == 'l') {
+ chrono::__matches(__input, "last");
+ return weekday_last(chrono::__parse_weekday(__input));
+ }
+
+ return __tz::__constrained_weekday{
+ chrono::__parse_weekday(__input), chrono::__parse_comparison(__input), chrono::__parse_day(__input)};
+}
+
+[[nodiscard]] static seconds __parse_duration(istream& __input) {
+ seconds __result{0};
+ int __c = __input.peek();
+ bool __negative = __c == '-';
+ if (__negative) {
+ __input.get();
+ // Negative is either a negative value or a single -.
+ // The latter means 0 and the parsing is complete.
+ if (!std::isdigit(__input.peek()))
+ return __result;
+ }
+
+ __result += hours(__parse_integral(__input, true));
+ if (__input.peek() != ':')
+ return __negative ? -__result : __result;
+
+ __input.get();
+ __result += minutes(__parse_integral(__input, true));
+ if (__input.peek() != ':')
+ return __negative ? -__result : __result;
+
+ __input.get();
+ __result += seconds(__parse_integral(__input, true));
+ if (__input.peek() != '.')
+ return __negative ? -__result : __result;
+
+ __input.get();
+ (void)__parse_integral(__input, true); // Truncate the digits.
+
+ return __negative ? -__result : __result;
+}
+
+[[nodiscard]] static __tz::__clock __parse_clock(istream& __input) {
+ switch (__input.get()) { // case sensitive
+ case 'w':
+ return __tz::__clock::__local;
+ case 's':
+ return __tz::__clock::__standard;
+
+ case 'u':
+ case 'g':
+ case 'z':
+ return __tz::__clock::__universal;
+ }
+
+ __input.unget();
+ return __tz::__clock::__local;
+}
+
+[[nodiscard]] static bool __parse_dst(istream& __input, seconds __offset) {
+ switch (__input.get()) { // case sensitive
+ case 's':
+ return false;
+
+ case 'd':
+ return true;
+ }
+
+ __input.unget();
+ return __offset != 0s;
+}
+
+[[nodiscard]] static __tz::__at __parse_at(istream& __input) {
+ return {__parse_duration(__input), __parse_clock(__input)};
+}
+
+[[nodiscard]] static __tz::__save __parse_save(istream& __input) {
+ seconds __time = chrono::__parse_duration(__input);
+ return {__time, chrono::__parse_dst(__input, __time)};
+}
+
+[[nodiscard]] static string __parse_letters(istream& __input) {
+ string __result = __parse_string(__input);
+ // Canonicalize "-" to "" since they are equivalent in the specification.
+ return __result != "-" ? __result : "";
+}
+
+[[nodiscard]] static __tz::__continuation::__rules_t __parse_rules(istream& __input) {
+ int __c = __input.peek();
+ // A single - is not a SAVE but a special case.
+ if (__c == '-') {
+ __input.get();
+ if (chrono::__is_whitespace(__input.peek()))
+ return monostate{};
+ __input.unget();
+ return chrono::__parse_save(__input);
+ }
+
+ if (std::isdigit(__c) || __c == '+')
+ return chrono::__parse_save(__input);
+
+ return chrono::__parse_string(__input);
+}
+
+[[nodiscard]] static __tz::__continuation __parse_continuation(__tz::__rules_storage_type& __rules, istream& __input) {
+ __tz::__continuation __result;
+
+ __result.__rule_database_ = std::addressof(__rules);
+
+ // Note STDOFF is specified as
+ // This field has the same format as the AT and SAVE fields of rule lines;
+ // These fields have different suffix letters, these letters seem
+ // not to be used so do not allow any of them.
+
+ __result.__stdoff = chrono::__parse_duration(__input);
+ chrono::__skip_mandatory_whitespace(__input);
+ __result.__rules = chrono::__parse_rules(__input);
+ chrono::__skip_mandatory_whitespace(__input);
+ __result.__format = chrono::__parse_string(__input);
+ chrono::__skip_optional_whitespace(__input);
+
+ if (chrono::__is_eol(__input.peek()))
+ return __result;
+ __result.__year = chrono::__parse_year(__input);
+ chrono::__skip_optional_whitespace(__input);
+
+ if (chrono::__is_eol(__input.peek()))
+ return __result;
+ __result.__in = chrono::__parse_month(__input);
+ chrono::__skip_optional_whitespace(__input);
+
+ if (chrono::__is_eol(__input.peek()))
+ return __result;
+ __result.__on = chrono::__parse_on(__input);
+ chrono::__skip_optional_whitespace(__input);
+
+ if (chrono::__is_eol(__input.peek()))
+ return __result;
+ __result.__at = __parse_at(__input);
+
+ return __result;
+}
+
+//===----------------------------------------------------------------------===//
+// Time Zone Database entries
+//===----------------------------------------------------------------------===//
+
+static string __parse_version(istream& __input) {
+ // The first line in tzdata.zi contains
+ // # version YYYYw
+ // The parser expects this pattern
+ // #\s*version\s*\(.*)
+ // This part is not documented.
+ chrono::__matches(__input, '#');
+ chrono::__skip_optional_whitespace(__input);
+ chrono::__matches(__input, "version");
+ chrono::__skip_mandatory_whitespace(__input);
+ return chrono::__parse_string(__input);
+}
+
+static void __parse_rule(tzdb& __tzdb, __tz::__rules_storage_type& __rules, istream& __input) {
+ chrono::__skip_mandatory_whitespace(__input);
+ string __name = chrono::__parse_string(__input);
+
+ if (__rules.empty() || __rules.back().first != __name)
+ __rules.emplace_back(__name, vector<__tz::__rule>{});
+
+ __tz::__rule& __rule = __rules.back().second.emplace_back();
+
+ chrono::__skip_mandatory_whitespace(__input);
+ __rule.__from = chrono::__parse_year(__input);
+ chrono::__skip_mandatory_whitespace(__input);
+ __rule.__to = chrono::__parse_to(__input, __rule.__from);
+ chrono::__skip_mandatory_whitespace(__input);
+ chrono::__matches(__input, '-');
+ chrono::__skip_mandatory_whitespace(__input);
+ __rule.__in = chrono::__parse_month(__input);
+ chrono::__skip_mandatory_whitespace(__input);
+ __rule.__on = chrono::__parse_on(__input);
+ chrono::__skip_mandatory_whitespace(__input);
+ __rule.__at = __parse_at(__input);
+ chrono::__skip_mandatory_whitespace(__input);
+ __rule.__save = __parse_save(__input);
+ chrono::__skip_mandatory_whitespace(__input);
+ __rule.__letters = chrono::__parse_letters(__input);
+ chrono::__skip_line(__input);
+}
+
+static void __parse_zone(tzdb& __tzdb, __tz::__rules_storage_type& __rules, istream& __input) {
+ chrono::__skip_mandatory_whitespace(__input);
+ auto __p = std::make_unique<time_zone::__impl>(chrono::__parse_string(__input));
+ vector<__tz::__continuation>& __continuations = __p->__continuations();
+ chrono::__skip_mandatory_whitespace(__input);
+
+ do {
+ // The first line must be valid, continuations are optional.
+ __continuations.emplace_back(__parse_continuation(__rules, __input));
+ chrono::__skip_line(__input);
+ chrono::__skip_optional_whitespace(__input);
+ } while (std::isdigit(__input.peek()) || __input.peek() == '-');
+
+ __tzdb.zones.emplace_back(time_zone::__create(std::move(__p)));
+}
+
+static void __parse_link(tzdb& __tzdb, istream& __input) {
+ chrono::__skip_mandatory_whitespace(__input);
+ string __target = chrono::__parse_string(__input);
+ chrono::__skip_mandatory_whitespace(__input);
+ string __name = chrono::__parse_string(__input);
+ chrono::__skip_line(__input);
+
+ __tzdb.links.emplace_back(time_zone_link::__constructor_tag{}, std::move(__name), std::move(__target));
+}
+
+static void __parse_tzdata(tzdb& __db, __tz::__rules_storage_type& __rules, istream& __input) {
+ while (true) {
+ int __c = std::tolower(__input.get());
+
+ switch (__c) {
+ case istream::traits_type::eof():
+ return;
+
+ case ' ':
+ case '\t':
+ case '\n':
+ break;
+
+ case '#':
+ chrono::__skip_line(__input);
+ break;
+
+ case 'r':
+ chrono::__skip(__input, "ule");
+ chrono::__parse_rule(__db, __rules, __input);
+ break;
+
+ case 'z':
+ chrono::__skip(__input, "one");
+ chrono::__parse_zone(__db, __rules, __input);
+ break;
+
+ case 'l':
+ chrono::__skip(__input, "ink");
+ chrono::__parse_link(__db, __input);
+ break;
+
+ default:
+ std::__throw_runtime_error("corrupt tzdb: unexpected input");
+ }
+ }
+}
+
+void __init_tzdb(tzdb& __tzdb, __tz::__rules_storage_type& __rules) {
+ filesystem::path __root = chrono::__libcpp_tzdb_directory();
+ ifstream __tzdata{__root / "tzdata.zi"};
+
+ __tzdb.version = chrono::__parse_version(__tzdata);
+ chrono::__parse_tzdata(__tzdb, __rules, __tzdata);
+ std::ranges::sort(__tzdb.zones);
+ std::ranges::sort(__tzdb.links);
+ std::ranges::sort(__rules, {}, [](const auto& p) { return p.first; });
+}
+
+//===----------------------------------------------------------------------===//
+// Public API
+//===----------------------------------------------------------------------===//
+
+_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list() {
+ static tzdb_list __result{new tzdb_list::__impl()};
+ return __result;
+}
+
+_LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb() {
+ if (chrono::remote_version() == chrono::get_tzdb().version)
+ return chrono::get_tzdb();
+
+ return chrono::get_tzdb_list().__implementation().__load();
+}
+
+_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version() {
+ filesystem::path __root = chrono::__libcpp_tzdb_directory();
+ ifstream __tzdata{__root / "tzdata.zi"};
+ return chrono::__parse_version(__tzdata);
+}
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/tzdb_list.cpp b/contrib/libs/cxxsupp/libcxx/src/tzdb_list.cpp
index 7eaaedc6eda..d3ee8b58f98 100644
--- a/contrib/libs/cxxsupp/libcxx/src/tzdb_list.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/tzdb_list.cpp
@@ -10,76 +10,12 @@
#include <chrono>
-#include <__mutex/unique_lock.h>
-#include <forward_list>
-
-// When threads are not available the locking is not required.
-#ifndef _LIBCPP_HAS_NO_THREADS
-# include <shared_mutex>
-#endif
+#include "include/tzdb/tzdb_list_private.h"
_LIBCPP_BEGIN_NAMESPACE_STD
namespace chrono {
-//===----------------------------------------------------------------------===//
-// Private API
-//===----------------------------------------------------------------------===//
-
-class tzdb_list::__impl {
-public:
- explicit __impl(tzdb&& __tzdb) { __tzdb_.push_front(std::move(__tzdb)); }
-
- using const_iterator = tzdb_list::const_iterator;
-
- const tzdb& front() const noexcept {
-#ifndef _LIBCPP_HAS_NO_THREADS
- shared_lock __lock{__mutex_};
-#endif
- return __tzdb_.front();
- }
-
- const_iterator erase_after(const_iterator __p) {
-#ifndef _LIBCPP_HAS_NO_THREADS
- unique_lock __lock{__mutex_};
-#endif
- return __tzdb_.erase_after(__p);
- }
-
- tzdb& __emplace_front(tzdb&& __tzdb) {
-#ifndef _LIBCPP_HAS_NO_THREADS
- unique_lock __lock{__mutex_};
-#endif
- return __tzdb_.emplace_front(std::move(__tzdb));
- }
-
- const_iterator begin() const noexcept {
-#ifndef _LIBCPP_HAS_NO_THREADS
- shared_lock __lock{__mutex_};
-#endif
- return __tzdb_.begin();
- }
- const_iterator end() const noexcept {
- // forward_list<T>::end does not access the list, so no need to take a lock.
- return __tzdb_.end();
- }
-
- const_iterator cbegin() const noexcept { return begin(); }
- const_iterator cend() const noexcept { return end(); }
-
-private:
-#ifndef _LIBCPP_HAS_NO_THREADS
- mutable shared_mutex __mutex_;
-#endif
- forward_list<tzdb> __tzdb_;
-};
-
-//===----------------------------------------------------------------------===//
-// Public API
-//===----------------------------------------------------------------------===//
-
-_LIBCPP_EXPORTED_FROM_ABI tzdb_list::tzdb_list(tzdb&& __tzdb) : __impl_{new __impl(std::move(__tzdb))} {}
-
_LIBCPP_EXPORTED_FROM_ABI tzdb_list::~tzdb_list() { delete __impl_; }
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const tzdb& tzdb_list::front() const noexcept {
@@ -90,10 +26,6 @@ _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::erase_after(const
return __impl_->erase_after(__p);
}
-_LIBCPP_EXPORTED_FROM_ABI tzdb& tzdb_list::__emplace_front(tzdb&& __tzdb) {
- return __impl_->__emplace_front(std::move(__tzdb));
-}
-
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::begin() const noexcept {
return __impl_->begin();
}