aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/libcxx/src
diff options
context:
space:
mode:
authorhiddenpath <hiddenpath@yandex-team.com>2024-02-21 23:16:42 +0300
committerhiddenpath <hiddenpath@yandex-team.com>2024-02-21 23:33:25 +0300
commit9052eb5cc304b8da8885fc4e3364ebddc16945f3 (patch)
tree3c252f6161dd0745c7732d74c9304c000645ab47 /contrib/libs/cxxsupp/libcxx/src
parentf5eb715f103692e7c7536e13bef3f281fd78e5e7 (diff)
downloadydb-9052eb5cc304b8da8885fc4e3364ebddc16945f3.tar.gz
Update libcxx to llvmorg-17.0.6
Update libcxx to llvmorg-17.0.6 c871ef572c71b4fef22d4a9e65bcebc57e625aea
Diffstat (limited to 'contrib/libs/cxxsupp/libcxx/src')
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/algorithm.cpp37
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/algorithm_old.cpp53
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/any.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/atomic.cpp14
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/charconv.cpp4
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/chrono.cpp69
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/condition_variable.cpp1
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/debug.cpp559
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/directory_entry.cpp74
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/directory_iterator.cpp18
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/error.h238
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/file_descriptor.h298
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_clock.cpp64
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_error.cpp37
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/format_string.h77
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp1166
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/path.cpp460
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/path_parser.h372
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h124
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/filesystem/time_utils.h (renamed from contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_common.h)382
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/format.cpp17
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/future.cpp4
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/apple_availability.h18
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/config_elast.h2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/ryu/common.h21
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/ryu/d2s_intrinsics.h16
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/ryu/ryu.h3
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/include/to_chars_floating_point.h24
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/ios.cpp8
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/ios.instantiations.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/iostream.cpp38
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/legacy_pointer_safety.cpp8
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/locale.cpp63
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/memory.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp15
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/mutex.cpp28
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/new.cpp93
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/new_handler.cpp39
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/new_helpers.cpp (renamed from contrib/libs/cxxsupp/libcxx/src/support/runtime/new_handler_fallback.ipp)28
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/optional.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/print.cpp62
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/random.cpp6
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/ryu/d2fixed.cpp47
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/ryu/d2s.cpp44
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/ryu/f2s.cpp44
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/shared_mutex.cpp128
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/std_stream.h447
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/stdexcept.cpp1
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/string.cpp17
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/strstream.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_fallback.ipp8
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_msvc.ipp8
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/support/solaris/README4
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/support/win32/locale_win32.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/system_error.cpp9
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/thread.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/utility.cpp15
-rw-r--r--contrib/libs/cxxsupp/libcxx/src/valarray.cpp4
60 files changed, 2731 insertions, 2603 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/src/algorithm.cpp b/contrib/libs/cxxsupp/libcxx/src/algorithm.cpp
index bd47e08b38..af9d60a8e2 100644
--- a/contrib/libs/cxxsupp/libcxx/src/algorithm.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/algorithm.cpp
@@ -7,11 +7,25 @@
//===----------------------------------------------------------------------===//
#include <algorithm>
+#include <bit>
_LIBCPP_BEGIN_NAMESPACE_STD
-// TODO(varconst): this currently doesn't benefit `ranges::sort` because it uses `ranges::less` instead of `__less`.
+template <class Comp, class RandomAccessIterator>
+void __sort(RandomAccessIterator first, RandomAccessIterator last, Comp comp) {
+ auto depth_limit = 2 * std::__bit_log2(static_cast<size_t>(last - first));
+ // Only use bitset partitioning for arithmetic types. We should also check
+ // that the default comparator is in use so that we are sure that there are no
+ // branches in the comparator.
+ std::__introsort<_ClassicAlgPolicy,
+ ranges::less,
+ RandomAccessIterator,
+ __use_branchless_sort<ranges::less, RandomAccessIterator>::value>(
+ first, last, ranges::less{}, depth_limit);
+}
+
+// clang-format off
template void __sort<__less<char>&, char*>(char*, char*, __less<char>&);
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
@@ -29,25 +43,6 @@ template void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned
template void __sort<__less<float>&, float*>(float*, float*, __less<float>&);
template void __sort<__less<double>&, double*>(double*, double*, __less<double>&);
template void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
-
-template bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&);
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&);
-#endif
-template bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&);
-template bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&);
-template bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&);
-template bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&);
-template bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&);
-template bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&);
-template bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&);
-template bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&);
-template bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&);
-template bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&);
-template bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&);
-template bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&);
-template bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&);
-
-template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
+// clang-format on
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/algorithm_old.cpp b/contrib/libs/cxxsupp/libcxx/src/algorithm_old.cpp
new file mode 100644
index 0000000000..90cb7785cd
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/algorithm_old.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <algorithm>
+
+namespace old_sort {
+
+// TODO(varconst): this currently doesn't benefit `ranges::sort` because it uses `ranges::less` instead of `__less`.
+
+template void __sort<std::__less<>&, char*>(char*, char*, std::__less<>&);
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template void __sort<std::__less<>&, wchar_t*>(wchar_t*, wchar_t*, std::__less<>&);
+#endif
+template void __sort<std::__less<>&, signed char*>(signed char*, signed char*, std::__less<>&);
+template void __sort<std::__less<>&, unsigned char*>(unsigned char*, unsigned char*, std::__less<>&);
+template void __sort<std::__less<>&, short*>(short*, short*, std::__less<>&);
+template void __sort<std::__less<>&, unsigned short*>(unsigned short*, unsigned short*, std::__less<>&);
+template void __sort<std::__less<>&, int*>(int*, int*, std::__less<>&);
+template void __sort<std::__less<>&, unsigned*>(unsigned*, unsigned*, std::__less<>&);
+template void __sort<std::__less<>&, long*>(long*, long*, std::__less<>&);
+template void __sort<std::__less<>&, unsigned long*>(unsigned long*, unsigned long*, std::__less<>&);
+template void __sort<std::__less<>&, long long*>(long long*, long long*, std::__less<>&);
+template void __sort<std::__less<>&, unsigned long long*>(unsigned long long*, unsigned long long*, std::__less<>&);
+template void __sort<std::__less<>&, float*>(float*, float*, std::__less<>&);
+template void __sort<std::__less<>&, double*>(double*, double*, std::__less<>&);
+template void __sort<std::__less<>&, long double*>(long double*, long double*, std::__less<>&);
+
+template bool __insertion_sort_incomplete<std::__less<>&, char*>(char*, char*, std::__less<>&);
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template bool __insertion_sort_incomplete<std::__less<>&, wchar_t*>(wchar_t*, wchar_t*, std::__less<>&);
+#endif
+template bool __insertion_sort_incomplete<std::__less<>&, signed char*>(signed char*, signed char*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, unsigned char*>(unsigned char*, unsigned char*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, short*>(short*, short*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, unsigned short*>(unsigned short*, unsigned short*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, int*>(int*, int*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, unsigned*>(unsigned*, unsigned*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, long*>(long*, long*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, unsigned long*>(unsigned long*, unsigned long*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, long long*>(long long*, long long*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, unsigned long long*>(unsigned long long*, unsigned long long*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, float*>(float*, float*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, double*>(double*, double*, std::__less<>&);
+template bool __insertion_sort_incomplete<std::__less<>&, long double*>(long double*, long double*, std::__less<>&);
+
+template unsigned __sort5<std::__less<>&, long double*>(long double*, long double*, long double*, long double*, long double*, std::__less<>&);
+
+} // namespace old_sort
diff --git a/contrib/libs/cxxsupp/libcxx/src/any.cpp b/contrib/libs/cxxsupp/libcxx/src/any.cpp
index 9a101b44a7..36f95c0ec4 100644
--- a/contrib/libs/cxxsupp/libcxx/src/any.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/any.cpp
@@ -21,7 +21,7 @@ const char* bad_any_cast::what() const noexcept {
// Even though it no longer exists in a header file
_LIBCPP_BEGIN_NAMESPACE_LFTS
-class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
{
public:
virtual const char* what() const noexcept;
diff --git a/contrib/libs/cxxsupp/libcxx/src/atomic.cpp b/contrib/libs/cxxsupp/libcxx/src/atomic.cpp
index 7777e888c0..a55249a15c 100644
--- a/contrib/libs/cxxsupp/libcxx/src/atomic.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/atomic.cpp
@@ -9,11 +9,14 @@
#include <__config>
#ifndef _LIBCPP_HAS_NO_THREADS
+#include <__thread/timed_backoff_policy.h>
#include <atomic>
#include <climits>
#include <functional>
#include <thread>
+#include "include/apple_availability.h"
+
#ifdef __linux__
#include <unistd.h>
@@ -77,20 +80,25 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo
const_cast<__cxx_atomic_contention_t*>(__ptr), 0);
}
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8
+/*
+ * Since __cxx_contention_t is int64_t even on 32bit FreeBSD
+ * platforms, we have to use umtx ops that work on the long type, and
+ * limit its use to architectures where long and int64_t are synonyms.
+ */
static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr,
__cxx_contention_t __val)
{
_umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
- UMTX_OP_WAIT_UINT_PRIVATE, __val, NULL, NULL);
+ UMTX_OP_WAIT, __val, NULL, NULL);
}
static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr,
bool __notify_one)
{
_umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
- UMTX_OP_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, NULL, NULL);
+ UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, NULL, NULL);
}
#else // <- Add other operating systems here
diff --git a/contrib/libs/cxxsupp/libcxx/src/charconv.cpp b/contrib/libs/cxxsupp/libcxx/src/charconv.cpp
index d01ecddc46..aa52220413 100644
--- a/contrib/libs/cxxsupp/libcxx/src/charconv.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/charconv.cpp
@@ -18,13 +18,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace __itoa
{
-_LIBCPP_FUNC_VIS char*
+_LIBCPP_EXPORTED_FROM_ABI char*
__u32toa(uint32_t value, char* buffer) noexcept
{
return __base_10_u32(buffer, value);
}
-_LIBCPP_FUNC_VIS char*
+_LIBCPP_EXPORTED_FROM_ABI char*
__u64toa(uint64_t value, char* buffer) noexcept
{
return __base_10_u64(buffer, value);
diff --git a/contrib/libs/cxxsupp/libcxx/src/chrono.cpp b/contrib/libs/cxxsupp/libcxx/src/chrono.cpp
index 0af89d6a52..f159613202 100644
--- a/contrib/libs/cxxsupp/libcxx/src/chrono.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/chrono.cpp
@@ -12,9 +12,9 @@
#define _LARGE_TIME_API
#endif
-#include <cerrno> // errno
+#include <__system_error/system_error.h>
+#include <cerrno> // errno
#include <chrono>
-#include <system_error> // __throw_system_error
#if defined(__MVS__)
#include <__support/ibm/gettod_zos.h> // gettimeofdayMonotonic
@@ -24,15 +24,15 @@
#include "include/apple_availability.h"
#if __has_include(<unistd.h>)
-# include <unistd.h>
+# include <unistd.h> // _POSIX_TIMERS
#endif
#if __has_include(<sys/time.h>)
# include <sys/time.h> // for gettimeofday and timeval
#endif
-#if !defined(__APPLE__) && defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
-# define _LIBCPP_USE_CLOCK_GETTIME
+#if defined(__APPLE__) || defined (__gnu_hurd__) || (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
+# define _LIBCPP_HAS_CLOCK_GETTIME
#endif
#if defined(_LIBCPP_WIN32API)
@@ -116,7 +116,7 @@ static system_clock::time_point __libcpp_system_clock_now() {
return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch));
}
-#elif defined(CLOCK_REALTIME) && defined(_LIBCPP_USE_CLOCK_GETTIME)
+#elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
static system_clock::time_point __libcpp_system_clock_now() {
struct timespec tp;
@@ -167,59 +167,6 @@ system_clock::from_time_t(time_t t) noexcept
#if defined(__APPLE__)
-// TODO(ldionne):
-// This old implementation of steady_clock is retained until Chrome drops supports
-// for macOS < 10.12. The issue is that they link libc++ statically into their
-// application, which means that libc++ must support being built for such deployment
-// targets. See https://llvm.org/D74489 for details.
-#if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
- (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
- (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
- (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
-# define _LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME
-#endif
-
-#if defined(_LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME)
-
-// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
-// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom
-// are run time constants supplied by the OS. This clock has no relationship
-// to the Gregorian calendar. It's main use is as a high resolution timer.
-
-// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize
-// for that case as an optimization.
-
-static steady_clock::rep steady_simplified() {
- return static_cast<steady_clock::rep>(mach_absolute_time());
-}
-static double compute_steady_factor() {
- mach_timebase_info_data_t MachInfo;
- mach_timebase_info(&MachInfo);
- return static_cast<double>(MachInfo.numer) / MachInfo.denom;
-}
-
-static steady_clock::rep steady_full() {
- static const double factor = compute_steady_factor();
- return static_cast<steady_clock::rep>(mach_absolute_time() * factor);
-}
-
-typedef steady_clock::rep (*FP)();
-
-static FP init_steady_clock() {
- mach_timebase_info_data_t MachInfo;
- mach_timebase_info(&MachInfo);
- if (MachInfo.numer == MachInfo.denom)
- return &steady_simplified;
- return &steady_full;
-}
-
-static steady_clock::time_point __libcpp_steady_clock_now() {
- static FP fp = init_steady_clock();
- return steady_clock::time_point(steady_clock::duration(fp()));
-}
-
-#else // vvvvv default behavior for Apple platforms vvvvv
-
// On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or
// mach_absolute_time are able to time functions in the nanosecond range.
// Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it
@@ -232,8 +179,6 @@ static steady_clock::time_point __libcpp_steady_clock_now() {
return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}
-#endif
-
#elif defined(_LIBCPP_WIN32API)
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says:
@@ -281,7 +226,7 @@ static steady_clock::time_point __libcpp_steady_clock_now() noexcept {
return steady_clock::time_point(nanoseconds(_zx_clock_get_monotonic()));
}
-# elif defined(CLOCK_MONOTONIC)
+# elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
static steady_clock::time_point __libcpp_steady_clock_now() {
struct timespec tp;
diff --git a/contrib/libs/cxxsupp/libcxx/src/condition_variable.cpp b/contrib/libs/cxxsupp/libcxx/src/condition_variable.cpp
index b17c4cf645..85f334e024 100644
--- a/contrib/libs/cxxsupp/libcxx/src/condition_variable.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/condition_variable.cpp
@@ -12,7 +12,6 @@
#include <condition_variable>
#include <thread>
-#include <system_error>
#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
# pragma comment(lib, "pthread")
diff --git a/contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp b/contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp
index c217a09394..333face19d 100644
--- a/contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/condition_variable_destructor.cpp
@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#ifdef NEEDS_CONDVAR_DESTRUCTOR
-class _LIBCPP_TYPE_VIS condition_variable
+class _LIBCPP_EXPORTED_FROM_ABI condition_variable
{
__libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
public:
diff --git a/contrib/libs/cxxsupp/libcxx/src/debug.cpp b/contrib/libs/cxxsupp/libcxx/src/debug.cpp
deleted file mode 100644
index 8f1d328f0e..0000000000
--- a/contrib/libs/cxxsupp/libcxx/src/debug.cpp
+++ /dev/null
@@ -1,559 +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
-//
-//===----------------------------------------------------------------------===//
-
-#include <__assert>
-#include <__config>
-#include <__debug>
-#include <__hash_table>
-#include <algorithm>
-#include <cstdio>
-#include <functional>
-#include <string>
-
-#ifndef _LIBCPP_HAS_NO_THREADS
-# include <mutex>
-# if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
-# pragma comment(lib, "pthread")
-# endif
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-_LIBCPP_FUNC_VIS
-__libcpp_db*
-__get_db()
-{
- static _LIBCPP_NO_DESTROY __libcpp_db db;
- return &db;
-}
-
-_LIBCPP_FUNC_VIS
-const __libcpp_db*
-__get_const_db()
-{
- return __get_db();
-}
-
-namespace
-{
-
-#ifndef _LIBCPP_HAS_NO_THREADS
-typedef mutex mutex_type;
-typedef lock_guard<mutex_type> WLock;
-typedef lock_guard<mutex_type> RLock;
-
-mutex_type&
-mut()
-{
- static _LIBCPP_NO_DESTROY mutex_type m;
- return m;
-}
-#endif // !_LIBCPP_HAS_NO_THREADS
-
-} // unnamed namespace
-
-__i_node::~__i_node()
-{
- if (__next_)
- {
- __next_->~__i_node();
- free(__next_);
- }
-}
-
-__c_node::~__c_node()
-{
- free(beg_);
- if (__next_)
- {
- __next_->~__c_node();
- free(__next_);
- }
-}
-
-__libcpp_db::__libcpp_db()
- : __cbeg_(nullptr),
- __cend_(nullptr),
- __csz_(0),
- __ibeg_(nullptr),
- __iend_(nullptr),
- __isz_(0)
-{
-}
-
-__libcpp_db::~__libcpp_db()
-{
- if (__cbeg_)
- {
- for (__c_node** p = __cbeg_; p != __cend_; ++p)
- {
- if (*p != nullptr)
- {
- (*p)->~__c_node();
- free(*p);
- }
- }
- free(__cbeg_);
- }
- if (__ibeg_)
- {
- for (__i_node** p = __ibeg_; p != __iend_; ++p)
- {
- if (*p != nullptr)
- {
- (*p)->~__i_node();
- free(*p);
- }
- }
- free(__ibeg_);
- }
-}
-
-void*
-__libcpp_db::__find_c_from_i(void* __i) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- RLock _(mut());
-#endif
- __i_node* i = __find_iterator(__i);
- _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database.");
- return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;
-}
-
-void
-__libcpp_db::__insert_ic(void* __i, const void* __c)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- WLock _(mut());
-#endif
- if (__cbeg_ == __cend_)
- return;
- size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
- __c_node* c = __cbeg_[hc];
- if (c == nullptr)
- return;
- while (c->__c_ != __c)
- {
- c = c->__next_;
- if (c == nullptr)
- return;
- }
- __i_node* i = __insert_iterator(__i);
- c->__add(i);
- i->__c_ = c;
-}
-
-void
-__libcpp_db::__insert_c(void* __c, __libcpp_db::_InsertConstruct *__fn)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- WLock _(mut());
-#endif
- if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))
- {
- size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);
- __c_node** cbeg = static_cast<__c_node**>(calloc(nc, sizeof(__c_node*)));
- if (cbeg == nullptr)
- __throw_bad_alloc();
-
- for (__c_node** p = __cbeg_; p != __cend_; ++p)
- {
- __c_node* q = *p;
- while (q != nullptr)
- {
- size_t h = hash<void*>()(q->__c_) % nc;
- __c_node* r = q->__next_;
- q->__next_ = cbeg[h];
- cbeg[h] = q;
- q = r;
- }
- }
- free(__cbeg_);
- __cbeg_ = cbeg;
- __cend_ = __cbeg_ + nc;
- }
- size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
- __c_node* p = __cbeg_[hc];
- void *buf = malloc(sizeof(__c_node));
- if (buf == nullptr)
- __throw_bad_alloc();
- __cbeg_[hc] = __fn(buf, __c, p);
-
- ++__csz_;
-}
-
-void
-__libcpp_db::__erase_i(void* __i)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- WLock _(mut());
-#endif
- if (__ibeg_ != __iend_)
- {
- size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
- __i_node* p = __ibeg_[hi];
- if (p != nullptr)
- {
- __i_node* q = nullptr;
- while (p->__i_ != __i)
- {
- q = p;
- p = p->__next_;
- if (p == nullptr)
- return;
- }
- if (q == nullptr)
- __ibeg_[hi] = p->__next_;
- else
- q->__next_ = p->__next_;
- __c_node* c = p->__c_;
- --__isz_;
- if (c != nullptr)
- c->__remove(p);
- free(p);
- }
- }
-}
-
-void
-__libcpp_db::__invalidate_all(void* __c)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- WLock _(mut());
-#endif
- if (__cend_ != __cbeg_)
- {
- size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
- __c_node* p = __cbeg_[hc];
- if (p == nullptr)
- return;
- while (p->__c_ != __c)
- {
- p = p->__next_;
- if (p == nullptr)
- return;
- }
- while (p->end_ != p->beg_)
- {
- --p->end_;
- (*p->end_)->__c_ = nullptr;
- }
- }
-}
-
-__c_node*
-__libcpp_db::__find_c_and_lock(void* __c) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- mut().lock();
-#endif
- if (__cend_ == __cbeg_)
- {
-#ifndef _LIBCPP_HAS_NO_THREADS
- mut().unlock();
-#endif
- return nullptr;
- }
- size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
- __c_node* p = __cbeg_[hc];
- if (p == nullptr)
- {
-#ifndef _LIBCPP_HAS_NO_THREADS
- mut().unlock();
-#endif
- return nullptr;
- }
- while (p->__c_ != __c)
- {
- p = p->__next_;
- if (p == nullptr)
- {
-#ifndef _LIBCPP_HAS_NO_THREADS
- mut().unlock();
-#endif
- return nullptr;
- }
- }
- return p;
-}
-
-__c_node*
-__libcpp_db::__find_c(void* __c) const
-{
- size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
- __c_node* p = __cbeg_[hc];
- _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A");
- while (p->__c_ != __c)
- {
- p = p->__next_;
- _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B");
- }
- return p;
-}
-
-void
-__libcpp_db::unlock() const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- mut().unlock();
-#endif
-}
-
-void
-__libcpp_db::__erase_c(void* __c)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- WLock _(mut());
-#endif
- if (__cend_ != __cbeg_)
- {
- size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
- __c_node* p = __cbeg_[hc];
- if (p == nullptr)
- return;
- __c_node* q = nullptr;
- _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
- while (p->__c_ != __c)
- {
- q = p;
- p = p->__next_;
- if (p == nullptr)
- return;
- _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
- }
- if (q == nullptr)
- __cbeg_[hc] = p->__next_;
- else
- q->__next_ = p->__next_;
- while (p->end_ != p->beg_)
- {
- --p->end_;
- (*p->end_)->__c_ = nullptr;
- }
- free(p->beg_);
- free(p);
- --__csz_;
- }
-}
-
-void
-__libcpp_db::__iterator_copy(void* __i, const void* __i0)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- WLock _(mut());
-#endif
- __i_node* i = __find_iterator(__i);
- __i_node* i0 = __find_iterator(__i0);
- __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
- if (i == nullptr && i0 != nullptr)
- i = __insert_iterator(__i);
- __c_node* c = i != nullptr ? i->__c_ : nullptr;
- if (c != c0)
- {
- if (c != nullptr)
- c->__remove(i);
- if (i != nullptr)
- {
- i->__c_ = nullptr;
- if (c0 != nullptr)
- {
- i->__c_ = c0;
- i->__c_->__add(i);
- }
- }
- }
-}
-
-bool
-__libcpp_db::__dereferenceable(const void* __i) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- RLock _(mut());
-#endif
- __i_node* i = __find_iterator(__i);
- return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
-}
-
-bool
-__libcpp_db::__decrementable(const void* __i) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- RLock _(mut());
-#endif
- __i_node* i = __find_iterator(__i);
- return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
-}
-
-bool
-__libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- RLock _(mut());
-#endif
- __i_node* i = __find_iterator(__i);
- return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
-}
-
-bool
-__libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- RLock _(mut());
-#endif
- __i_node* i = __find_iterator(__i);
- return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
-}
-
-bool
-__libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- RLock _(mut());
-#endif
- __i_node* i = __find_iterator(__i);
- __i_node* j = __find_iterator(__j);
- __c_node* ci = i != nullptr ? i->__c_ : nullptr;
- __c_node* cj = j != nullptr ? j->__c_ : nullptr;
- return ci == cj;
-}
-
-void
-__libcpp_db::swap(void* c1, void* c2)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- WLock _(mut());
-#endif
- size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
- __c_node* p1 = __cbeg_[hc];
- _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
- while (p1->__c_ != c1)
- {
- p1 = p1->__next_;
- _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B");
- }
- hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_);
- __c_node* p2 = __cbeg_[hc];
- _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C");
- while (p2->__c_ != c2)
- {
- p2 = p2->__next_;
- _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D");
- }
- std::swap(p1->beg_, p2->beg_);
- std::swap(p1->end_, p2->end_);
- std::swap(p1->cap_, p2->cap_);
- for (__i_node** p = p1->beg_; p != p1->end_; ++p)
- (*p)->__c_ = p1;
- for (__i_node** p = p2->beg_; p != p2->end_; ++p)
- (*p)->__c_ = p2;
-}
-
-void
-__libcpp_db::__insert_i(void* __i)
-{
-#ifndef _LIBCPP_HAS_NO_THREADS
- WLock _(mut());
-#endif
- __insert_iterator(__i);
-}
-
-void
-__c_node::__add(__i_node* i)
-{
- if (end_ == cap_)
- {
- size_t nc = 2*static_cast<size_t>(cap_ - beg_);
- if (nc == 0)
- nc = 1;
- __i_node** beg =
- static_cast<__i_node**>(malloc(nc * sizeof(__i_node*)));
- if (beg == nullptr)
- __throw_bad_alloc();
-
- if (nc > 1)
- memcpy(beg, beg_, nc/2*sizeof(__i_node*));
- free(beg_);
- beg_ = beg;
- end_ = beg_ + nc/2;
- cap_ = beg_ + nc;
- }
- *end_++ = i;
-}
-
-// private api
-
-_LIBCPP_HIDDEN
-__i_node*
-__libcpp_db::__insert_iterator(void* __i)
-{
- if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_))
- {
- size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1);
- __i_node** ibeg = static_cast<__i_node**>(calloc(nc, sizeof(__i_node*)));
- if (ibeg == nullptr)
- __throw_bad_alloc();
-
- for (__i_node** p = __ibeg_; p != __iend_; ++p)
- {
- __i_node* q = *p;
- while (q != nullptr)
- {
- size_t h = hash<void*>()(q->__i_) % nc;
- __i_node* r = q->__next_;
- q->__next_ = ibeg[h];
- ibeg[h] = q;
- q = r;
- }
- }
- free(__ibeg_);
- __ibeg_ = ibeg;
- __iend_ = __ibeg_ + nc;
- }
- size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
- __i_node* p = __ibeg_[hi];
- __i_node* r = __ibeg_[hi] =
- static_cast<__i_node*>(malloc(sizeof(__i_node)));
- if (r == nullptr)
- __throw_bad_alloc();
-
- ::new(r) __i_node(__i, p, nullptr);
- ++__isz_;
- return r;
-}
-
-_LIBCPP_HIDDEN
-__i_node*
-__libcpp_db::__find_iterator(const void* __i) const
-{
- __i_node* r = nullptr;
- if (__ibeg_ != __iend_)
- {
- size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
- for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_)
- {
- if (nd->__i_ == __i)
- {
- r = nd;
- break;
- }
- }
- }
- return r;
-}
-
-_LIBCPP_HIDDEN
-void
-__c_node::__remove(__i_node* p)
-{
- __i_node** r = find(beg_, end_, p);
- _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove");
- if (--end_ != r)
- memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*));
-}
-
-_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/directory_entry.cpp b/contrib/libs/cxxsupp/libcxx/src/filesystem/directory_entry.cpp
new file mode 100644
index 0000000000..4910d390d1
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/directory_entry.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <cstdint>
+#include <filesystem>
+#include <system_error>
+
+#include "file_descriptor.h"
+#include "posix_compat.h"
+#include "time_utils.h"
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+error_code directory_entry::__do_refresh() noexcept {
+ __data_.__reset();
+ error_code failure_ec;
+
+ detail::StatT full_st;
+ file_status st = detail::posix_lstat(__p_, full_st, &failure_ec);
+ if (!status_known(st)) {
+ __data_.__reset();
+ return failure_ec;
+ }
+
+ if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) {
+ __data_.__cache_type_ = directory_entry::_RefreshNonSymlink;
+ __data_.__type_ = st.type();
+ __data_.__non_sym_perms_ = st.permissions();
+ } else { // we have a symlink
+ __data_.__sym_perms_ = st.permissions();
+ // Get the information about the linked entity.
+ // Ignore errors from stat, since we don't want errors regarding symlink
+ // resolution to be reported to the user.
+ error_code ignored_ec;
+ st = detail::posix_stat(__p_, full_st, &ignored_ec);
+
+ __data_.__type_ = st.type();
+ __data_.__non_sym_perms_ = st.permissions();
+
+ // If we failed to resolve the link, then only partially populate the
+ // cache.
+ if (!status_known(st)) {
+ __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
+ return error_code{};
+ }
+ // Otherwise, we resolved the link, potentially as not existing.
+ // That's OK.
+ __data_.__cache_type_ = directory_entry::_RefreshSymlink;
+ }
+
+ if (_VSTD_FS::is_regular_file(st))
+ __data_.__size_ = static_cast<uintmax_t>(full_st.st_size);
+
+ if (_VSTD_FS::exists(st)) {
+ __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink);
+
+ // Attempt to extract the mtime, and fail if it's not representable using
+ // file_time_type. For now we ignore the error, as we'll report it when
+ // the value is actually used.
+ error_code ignored_ec;
+ __data_.__write_time_ =
+ detail::__extract_last_write_time(__p_, full_st, &ignored_ec);
+ }
+
+ return failure_ec;
+}
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/directory_iterator.cpp b/contrib/libs/cxxsupp/libcxx/src/filesystem/directory_iterator.cpp
index 8d069cc080..151fb2fb62 100644
--- a/contrib/libs/cxxsupp/libcxx/src/filesystem/directory_iterator.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/directory_iterator.cpp
@@ -11,8 +11,18 @@
#include <errno.h>
#include <filesystem>
#include <stack>
+#include <utility>
-#include "filesystem_common.h"
+#include "error.h"
+#include "file_descriptor.h"
+
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+#else
+# include <dirent.h> // for DIR & friends
+#endif
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
@@ -182,7 +192,7 @@ directory_iterator::directory_iterator(const path& p, error_code* ec,
}
directory_iterator& directory_iterator::__increment(error_code* ec) {
- _LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Attempting to increment an invalid iterator");
ErrorHandler<void> err("directory_iterator::operator++()", ec);
error_code m_ec;
@@ -196,7 +206,7 @@ directory_iterator& directory_iterator::__increment(error_code* ec) {
}
directory_entry const& directory_iterator::__dereference() const {
- _LIBCPP_ASSERT(__imp_, "Attempting to dereference an invalid iterator");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Attempting to dereference an invalid iterator");
return __imp_->__entry_;
}
@@ -225,7 +235,7 @@ recursive_directory_iterator::recursive_directory_iterator(
}
void recursive_directory_iterator::__pop(error_code* ec) {
- _LIBCPP_ASSERT(__imp_, "Popping the end iterator");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Popping the end iterator");
if (ec)
ec->clear();
__imp_->__stack_.pop();
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/error.h b/contrib/libs/cxxsupp/libcxx/src/filesystem/error.h
new file mode 100644
index 0000000000..965e0eadcd
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/error.h
@@ -0,0 +1,238 @@
+//===----------------------------------------------------------------------===////
+//
+// 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 FILESYSTEM_ERROR_H
+#define FILESYSTEM_ERROR_H
+
+#include <__assert>
+#include <__config>
+#include <cerrno>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdint>
+#include <filesystem>
+#include <string>
+#include <system_error>
+#include <utility> // __libcpp_unreachable
+
+#include "format_string.h"
+
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h> // ERROR_* macros
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+namespace detail {
+
+#if defined(_LIBCPP_WIN32API)
+
+inline errc __win_err_to_errc(int err) {
+ constexpr struct {
+ DWORD win;
+ errc errc;
+ } win_error_mapping[] = {
+ {ERROR_ACCESS_DENIED, errc::permission_denied},
+ {ERROR_ALREADY_EXISTS, errc::file_exists},
+ {ERROR_BAD_NETPATH, errc::no_such_file_or_directory},
+ {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory},
+ {ERROR_BAD_UNIT, errc::no_such_device},
+ {ERROR_BROKEN_PIPE, errc::broken_pipe},
+ {ERROR_BUFFER_OVERFLOW, errc::filename_too_long},
+ {ERROR_BUSY, errc::device_or_resource_busy},
+ {ERROR_BUSY_DRIVE, errc::device_or_resource_busy},
+ {ERROR_CANNOT_MAKE, errc::permission_denied},
+ {ERROR_CANTOPEN, errc::io_error},
+ {ERROR_CANTREAD, errc::io_error},
+ {ERROR_CANTWRITE, errc::io_error},
+ {ERROR_CURRENT_DIRECTORY, errc::permission_denied},
+ {ERROR_DEV_NOT_EXIST, errc::no_such_device},
+ {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy},
+ {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty},
+ {ERROR_DIRECTORY, errc::invalid_argument},
+ {ERROR_DISK_FULL, errc::no_space_on_device},
+ {ERROR_FILE_EXISTS, errc::file_exists},
+ {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory},
+ {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device},
+ {ERROR_INVALID_ACCESS, errc::permission_denied},
+ {ERROR_INVALID_DRIVE, errc::no_such_device},
+ {ERROR_INVALID_FUNCTION, errc::function_not_supported},
+ {ERROR_INVALID_HANDLE, errc::invalid_argument},
+ {ERROR_INVALID_NAME, errc::no_such_file_or_directory},
+ {ERROR_INVALID_PARAMETER, errc::invalid_argument},
+ {ERROR_LOCK_VIOLATION, errc::no_lock_available},
+ {ERROR_LOCKED, errc::no_lock_available},
+ {ERROR_NEGATIVE_SEEK, errc::invalid_argument},
+ {ERROR_NOACCESS, errc::permission_denied},
+ {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory},
+ {ERROR_NOT_READY, errc::resource_unavailable_try_again},
+ {ERROR_NOT_SAME_DEVICE, errc::cross_device_link},
+ {ERROR_NOT_SUPPORTED, errc::not_supported},
+ {ERROR_OPEN_FAILED, errc::io_error},
+ {ERROR_OPEN_FILES, errc::device_or_resource_busy},
+ {ERROR_OPERATION_ABORTED, errc::operation_canceled},
+ {ERROR_OUTOFMEMORY, errc::not_enough_memory},
+ {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory},
+ {ERROR_READ_FAULT, errc::io_error},
+ {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument},
+ {ERROR_RETRY, errc::resource_unavailable_try_again},
+ {ERROR_SEEK, errc::io_error},
+ {ERROR_SHARING_VIOLATION, errc::permission_denied},
+ {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open},
+ {ERROR_WRITE_FAULT, errc::io_error},
+ {ERROR_WRITE_PROTECT, errc::permission_denied},
+ };
+
+ for (const auto &pair : win_error_mapping)
+ if (pair.win == static_cast<DWORD>(err))
+ return pair.errc;
+ return errc::invalid_argument;
+}
+
+#endif // _LIBCPP_WIN32API
+
+inline error_code capture_errno() {
+ _LIBCPP_ASSERT_UNCATEGORIZED(errno != 0, "Expected errno to be non-zero");
+ return error_code(errno, generic_category());
+}
+
+#if defined(_LIBCPP_WIN32API)
+inline error_code make_windows_error(int err) {
+ return make_error_code(__win_err_to_errc(err));
+}
+#endif
+
+template <class T>
+T error_value();
+template <>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {}
+template <>
+inline bool error_value<bool>() {
+ return false;
+}
+#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__
+template <>
+inline size_t error_value<size_t>() {
+ return size_t(-1);
+}
+#endif
+template <>
+inline uintmax_t error_value<uintmax_t>() {
+ return uintmax_t(-1);
+}
+template <>
+inline _LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() {
+ return file_time_type::min();
+}
+template <>
+inline path error_value<path>() {
+ return {};
+}
+
+template <class T>
+struct ErrorHandler {
+ const char* func_name_;
+ error_code* ec_ = nullptr;
+ const path* p1_ = nullptr;
+ const path* p2_ = nullptr;
+
+ ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr,
+ const path* p2 = nullptr)
+ : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) {
+ if (ec_)
+ ec_->clear();
+ }
+
+ T report(const error_code& ec) const {
+ if (ec_) {
+ *ec_ = ec;
+ return error_value<T>();
+ }
+ string what = string("in ") + func_name_;
+ switch (bool(p1_) + bool(p2_)) {
+ case 0:
+ __throw_filesystem_error(what, ec);
+ case 1:
+ __throw_filesystem_error(what, *p1_, ec);
+ case 2:
+ __throw_filesystem_error(what, *p1_, *p2_, ec);
+ }
+ __libcpp_unreachable();
+ }
+
+ _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0)
+ void report_impl(const error_code& ec, const char* msg, va_list ap) const {
+ if (ec_) {
+ *ec_ = ec;
+ return;
+ }
+ string what =
+ string("in ") + func_name_ + ": " + detail::vformat_string(msg, ap);
+ switch (bool(p1_) + bool(p2_)) {
+ case 0:
+ __throw_filesystem_error(what, ec);
+ case 1:
+ __throw_filesystem_error(what, *p1_, ec);
+ case 2:
+ __throw_filesystem_error(what, *p1_, *p2_, ec);
+ }
+ __libcpp_unreachable();
+ }
+
+ _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
+ T report(const error_code& ec, const char* msg, ...) const {
+ va_list ap;
+ va_start(ap, msg);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ try {
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+ report_impl(ec, msg, ap);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ } catch (...) {
+ va_end(ap);
+ throw;
+ }
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+ va_end(ap);
+ return error_value<T>();
+ }
+
+ T report(errc const& err) const {
+ return report(make_error_code(err));
+ }
+
+ _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
+ T report(errc const& err, const char* msg, ...) const {
+ va_list ap;
+ va_start(ap, msg);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ try {
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+ report_impl(make_error_code(err), msg, ap);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ } catch (...) {
+ va_end(ap);
+ throw;
+ }
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+ va_end(ap);
+ return error_value<T>();
+ }
+
+private:
+ ErrorHandler(ErrorHandler const&) = delete;
+ ErrorHandler& operator=(ErrorHandler const&) = delete;
+};
+
+} // end namespace detail
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+
+#endif // FILESYSTEM_ERROR_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/file_descriptor.h b/contrib/libs/cxxsupp/libcxx/src/filesystem/file_descriptor.h
new file mode 100644
index 0000000000..d3a668fa2e
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/file_descriptor.h
@@ -0,0 +1,298 @@
+//===----------------------------------------------------------------------===////
+//
+// 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 FILESYSTEM_FILE_DESCRIPTOR_H
+#define FILESYSTEM_FILE_DESCRIPTOR_H
+
+#include <__config>
+#include <cstdint>
+#include <filesystem>
+#include <string_view>
+#include <system_error>
+#include <utility>
+
+#include "error.h"
+#include "posix_compat.h"
+#include "time_utils.h"
+
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+#else
+# include <dirent.h> // for DIR & friends
+# include <fcntl.h> // values for fchmodat
+# include <sys/stat.h>
+# include <sys/statvfs.h>
+# include <unistd.h>
+#endif // defined(_LIBCPP_WIN32API)
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+namespace detail {
+
+#if !defined(_LIBCPP_WIN32API)
+
+#if defined(DT_BLK)
+template <class DirEntT, class = decltype(DirEntT::d_type)>
+file_type get_file_type(DirEntT* ent, int) {
+ switch (ent->d_type) {
+ case DT_BLK:
+ return file_type::block;
+ case DT_CHR:
+ return file_type::character;
+ case DT_DIR:
+ return file_type::directory;
+ case DT_FIFO:
+ return file_type::fifo;
+ case DT_LNK:
+ return file_type::symlink;
+ case DT_REG:
+ return file_type::regular;
+ case DT_SOCK:
+ return file_type::socket;
+ // Unlike in lstat, hitting "unknown" here simply means that the underlying
+ // filesystem doesn't support d_type. Report is as 'none' so we correctly
+ // set the cache to empty.
+ case DT_UNKNOWN:
+ break;
+ }
+ return file_type::none;
+}
+#endif // defined(DT_BLK)
+
+template <class DirEntT>
+file_type get_file_type(DirEntT*, long) {
+ return file_type::none;
+}
+
+inline pair<string_view, file_type> posix_readdir(DIR* dir_stream,
+ error_code& ec) {
+ struct dirent* dir_entry_ptr = nullptr;
+ errno = 0; // zero errno in order to detect errors
+ ec.clear();
+ if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) {
+ if (errno)
+ ec = capture_errno();
+ return {};
+ } else {
+ return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)};
+ }
+}
+
+#else // _LIBCPP_WIN32API
+
+inline file_type get_file_type(const WIN32_FIND_DATAW& data) {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
+ data.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+ return file_type::symlink;
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ return file_type::directory;
+ return file_type::regular;
+}
+inline uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
+ return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow;
+}
+inline file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
+ ULARGE_INTEGER tmp;
+ const FILETIME& time = data.ftLastWriteTime;
+ tmp.u.LowPart = time.dwLowDateTime;
+ tmp.u.HighPart = time.dwHighDateTime;
+ return file_time_type(file_time_type::duration(tmp.QuadPart));
+}
+
+#endif // !_LIBCPP_WIN32API
+
+// POSIX HELPERS
+
+using value_type = path::value_type;
+using string_type = path::string_type;
+
+struct FileDescriptor {
+ const path& name;
+ int fd = -1;
+ StatT m_stat;
+ file_status m_status;
+
+ template <class... Args>
+ static FileDescriptor create(const path* p, error_code& ec, Args... args) {
+ ec.clear();
+ int fd;
+#ifdef _LIBCPP_WIN32API
+ // TODO: most of the filesystem implementation uses native Win32 calls
+ // (mostly via posix_compat.h). However, here we use the C-runtime APIs to
+ // open a file, because we subsequently pass the C-runtime fd to
+ // `std::[io]fstream::__open(int fd)` in order to implement copy_file.
+ //
+ // Because we're calling the windows C-runtime, win32 error codes are
+ // translated into C error numbers by the C runtime, and returned in errno,
+ // rather than being accessible directly via GetLastError.
+ //
+ // Ideally copy_file should be calling the Win32 CopyFile2 function, which
+ // works on paths, not open files -- at which point this FileDescriptor type
+ // will no longer be needed on windows at all.
+ fd = ::_wopen(p->c_str(), args...);
+#else
+ fd = open(p->c_str(), args...);
+#endif
+
+ if (fd == -1) {
+ ec = capture_errno();
+ return FileDescriptor{p};
+ }
+ return FileDescriptor(p, fd);
+ }
+
+ template <class... Args>
+ static FileDescriptor create_with_status(const path* p, error_code& ec,
+ Args... args) {
+ FileDescriptor fd = create(p, ec, args...);
+ if (!ec)
+ fd.refresh_status(ec);
+
+ return fd;
+ }
+
+ file_status get_status() const { return m_status; }
+ StatT const& get_stat() const { return m_stat; }
+
+ bool status_known() const { return _VSTD_FS::status_known(m_status); }
+
+ file_status refresh_status(error_code& ec);
+
+ void close() noexcept {
+ if (fd != -1) {
+#ifdef _LIBCPP_WIN32API
+ ::_close(fd);
+#else
+ ::close(fd);
+#endif
+ // FIXME: shouldn't this return an error_code?
+ }
+ fd = -1;
+ }
+
+ FileDescriptor(FileDescriptor&& other)
+ : name(other.name), fd(other.fd), m_stat(other.m_stat),
+ m_status(other.m_status) {
+ other.fd = -1;
+ other.m_status = file_status{};
+ }
+
+ ~FileDescriptor() { close(); }
+
+ FileDescriptor(FileDescriptor const&) = delete;
+ FileDescriptor& operator=(FileDescriptor const&) = delete;
+
+private:
+ explicit FileDescriptor(const path* p, int descriptor = -1) : name(*p), fd(descriptor) {}
+};
+
+inline perms posix_get_perms(const StatT& st) noexcept {
+ return static_cast<perms>(st.st_mode) & perms::mask;
+}
+
+inline file_status create_file_status(error_code& m_ec, path const& p,
+ const StatT& path_stat, error_code* ec) {
+ if (ec)
+ *ec = m_ec;
+ if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) {
+ return file_status(file_type::not_found);
+ } else if (m_ec) {
+ ErrorHandler<void> err("posix_stat", ec, &p);
+ err.report(m_ec, "failed to determine attributes for the specified path");
+ return file_status(file_type::none);
+ }
+ // else
+
+ file_status fs_tmp;
+ auto const mode = path_stat.st_mode;
+ if (S_ISLNK(mode))
+ fs_tmp.type(file_type::symlink);
+ else if (S_ISREG(mode))
+ fs_tmp.type(file_type::regular);
+ else if (S_ISDIR(mode))
+ fs_tmp.type(file_type::directory);
+ else if (S_ISBLK(mode))
+ fs_tmp.type(file_type::block);
+ else if (S_ISCHR(mode))
+ fs_tmp.type(file_type::character);
+ else if (S_ISFIFO(mode))
+ fs_tmp.type(file_type::fifo);
+ else if (S_ISSOCK(mode))
+ fs_tmp.type(file_type::socket);
+ else
+ fs_tmp.type(file_type::unknown);
+
+ fs_tmp.permissions(detail::posix_get_perms(path_stat));
+ return fs_tmp;
+}
+
+inline file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
+ error_code m_ec;
+ if (detail::stat(p.c_str(), &path_stat) == -1)
+ m_ec = detail::capture_errno();
+ return create_file_status(m_ec, p, path_stat, ec);
+}
+
+inline file_status posix_stat(path const& p, error_code* ec) {
+ StatT path_stat;
+ return posix_stat(p, path_stat, ec);
+}
+
+inline file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) {
+ error_code m_ec;
+ if (detail::lstat(p.c_str(), &path_stat) == -1)
+ m_ec = detail::capture_errno();
+ return create_file_status(m_ec, p, path_stat, ec);
+}
+
+inline file_status posix_lstat(path const& p, error_code* ec) {
+ StatT path_stat;
+ return posix_lstat(p, path_stat, ec);
+}
+
+// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
+inline bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
+ if (detail::ftruncate(fd.fd, to_size) == -1) {
+ ec = capture_errno();
+ return true;
+ }
+ ec.clear();
+ return false;
+}
+
+inline bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) {
+ if (detail::fchmod(fd.fd, st.st_mode) == -1) {
+ ec = capture_errno();
+ return true;
+ }
+ ec.clear();
+ return false;
+}
+
+inline bool stat_equivalent(const StatT& st1, const StatT& st2) {
+ return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
+}
+
+inline file_status FileDescriptor::refresh_status(error_code& ec) {
+ // FD must be open and good.
+ m_status = file_status{};
+ m_stat = {};
+ error_code m_ec;
+ if (detail::fstat(fd, &m_stat) == -1)
+ m_ec = capture_errno();
+ m_status = create_file_status(m_ec, name, m_stat, &ec);
+ return m_status;
+}
+
+} // end namespace detail
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+
+#endif // FILESYSTEM_FILE_DESCRIPTOR_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_clock.cpp b/contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_clock.cpp
new file mode 100644
index 0000000000..fbb19ac68d
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_clock.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <chrono>
+#include <filesystem>
+#include <time.h>
+
+#if defined(_LIBCPP_WIN32API)
+# include "time_utils.h"
+#endif
+
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+#endif
+
+#if __has_include(<unistd.h>)
+# include <unistd.h> // _POSIX_TIMERS
+#endif
+
+#if __has_include(<sys/time.h>)
+# include <sys/time.h> // for gettimeofday and timeval
+#endif
+
+#if defined(__APPLE__) || defined (__gnu_hurd__) || (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
+# define _LIBCPP_HAS_CLOCK_GETTIME
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+const bool _FilesystemClock::is_steady;
+
+_FilesystemClock::time_point _FilesystemClock::now() noexcept {
+ typedef chrono::duration<rep> __secs;
+#if defined(_LIBCPP_WIN32API)
+ typedef chrono::duration<rep, nano> __nsecs;
+ FILETIME time;
+ GetSystemTimeAsFileTime(&time);
+ detail::TimeSpec tp = detail::filetime_to_timespec(time);
+ return time_point(__secs(tp.tv_sec) +
+ chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
+#elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
+ typedef chrono::duration<rep, nano> __nsecs;
+ struct timespec tp;
+ if (0 != clock_gettime(CLOCK_REALTIME, &tp))
+ __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
+ return time_point(__secs(tp.tv_sec) +
+ chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
+#else
+ typedef chrono::duration<rep, micro> __microsecs;
+ timeval tv;
+ gettimeofday(&tv, 0);
+ return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_error.cpp b/contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_error.cpp
new file mode 100644
index 0000000000..5faed3b89e
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_error.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 <__utility/unreachable.h>
+#include <filesystem>
+#include <system_error>
+
+#include "format_string.h"
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+filesystem_error::~filesystem_error() {}
+
+void filesystem_error::__create_what(int __num_paths) {
+ const char* derived_what = system_error::what();
+ __storage_->__what_ = [&]() -> string {
+ switch (__num_paths) {
+ case 0:
+ return detail::format_string("filesystem error: %s", derived_what);
+ case 1:
+ return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]",
+ derived_what, path1().c_str());
+ case 2:
+ return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]",
+ derived_what, path1().c_str(), path2().c_str());
+ }
+ __libcpp_unreachable();
+ }();
+}
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/format_string.h b/contrib/libs/cxxsupp/libcxx/src/filesystem/format_string.h
new file mode 100644
index 0000000000..215d42421b
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/format_string.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===////
+//
+// 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 FILESYSTEM_FORMAT_STRING_H
+#define FILESYSTEM_FORMAT_STRING_H
+
+#include <__assert>
+#include <__config>
+#include <array>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdio>
+#include <string>
+
+#if defined(_LIBCPP_WIN32API)
+# define PATHSTR(x) (L##x)
+# define PATH_CSTR_FMT "\"%ls\""
+#else
+# define PATHSTR(x) (x)
+# define PATH_CSTR_FMT "\"%s\""
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+namespace detail {
+
+inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const char* msg, va_list ap) {
+ array<char, 256> buf;
+
+ va_list apcopy;
+ va_copy(apcopy, ap);
+ int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
+ va_end(apcopy);
+
+ string result;
+ if (static_cast<size_t>(ret) < buf.size()) {
+ result.assign(buf.data(), static_cast<size_t>(ret));
+ } else {
+ // we did not provide a long enough buffer on our first attempt. The
+ // return value is the number of bytes (excluding the null byte) that are
+ // needed for formatting.
+ 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");
+ }
+ return result;
+}
+
+inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) {
+ string ret;
+ va_list ap;
+ va_start(ap, msg);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ try {
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+ ret = detail::vformat_string(msg, ap);
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ } catch (...) {
+ va_end(ap);
+ throw;
+ }
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+ va_end(ap);
+ return ret;
+}
+
+} // end namespace detail
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+
+#endif // FILESYSTEM_FORMAT_STRING_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp b/contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp
index f9b74120e0..61f2cc572e 100644
--- a/contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/operations.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include <__assert>
+#include <__config>
#include <__utility/unreachable.h>
#include <array>
#include <climits>
@@ -17,9 +18,11 @@
#include <type_traits>
#include <vector>
-#include "filesystem_common.h"
-
+#include "error.h"
+#include "file_descriptor.h"
+#include "path_parser.h"
#include "posix_compat.h"
+#include "time_utils.h"
#if defined(_LIBCPP_WIN32API)
# define WIN32_LEAN_AND_MEAN
@@ -45,599 +48,12 @@
# define _LIBCPP_FILESYSTEM_USE_FSTREAM
#endif
-#if !defined(CLOCK_REALTIME) && !defined(_LIBCPP_WIN32API)
-# include <sys/time.h> // for gettimeofday and timeval
-#endif
-
#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
# pragma comment(lib, "rt")
#endif
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
-namespace {
-
-bool isSeparator(path::value_type C) {
- if (C == '/')
- return true;
-#if defined(_LIBCPP_WIN32API)
- if (C == '\\')
- return true;
-#endif
- return false;
-}
-
-bool isDriveLetter(path::value_type C) {
- return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z');
-}
-
-namespace parser {
-
-using string_view_t = path::__string_view;
-using string_view_pair = pair<string_view_t, string_view_t>;
-using PosPtr = path::value_type const*;
-
-struct PathParser {
- enum ParserState : unsigned char {
- // Zero is a special sentinel value used by default constructed iterators.
- PS_BeforeBegin = path::iterator::_BeforeBegin,
- PS_InRootName = path::iterator::_InRootName,
- PS_InRootDir = path::iterator::_InRootDir,
- PS_InFilenames = path::iterator::_InFilenames,
- PS_InTrailingSep = path::iterator::_InTrailingSep,
- PS_AtEnd = path::iterator::_AtEnd
- };
-
- const string_view_t Path;
- string_view_t RawEntry;
- ParserState State;
-
-private:
- PathParser(string_view_t P, ParserState State) noexcept : Path(P),
- State(State) {}
-
-public:
- PathParser(string_view_t P, string_view_t E, unsigned char S)
- : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) {
- // S cannot be '0' or PS_BeforeBegin.
- }
-
- static PathParser CreateBegin(string_view_t P) noexcept {
- PathParser PP(P, PS_BeforeBegin);
- PP.increment();
- return PP;
- }
-
- static PathParser CreateEnd(string_view_t P) noexcept {
- PathParser PP(P, PS_AtEnd);
- return PP;
- }
-
- PosPtr peek() const noexcept {
- auto TkEnd = getNextTokenStartPos();
- auto End = getAfterBack();
- return TkEnd == End ? nullptr : TkEnd;
- }
-
- void increment() noexcept {
- const PosPtr End = getAfterBack();
- const PosPtr Start = getNextTokenStartPos();
- if (Start == End)
- return makeState(PS_AtEnd);
-
- switch (State) {
- case PS_BeforeBegin: {
- PosPtr TkEnd = consumeRootName(Start, End);
- if (TkEnd)
- return makeState(PS_InRootName, Start, TkEnd);
- }
- _LIBCPP_FALLTHROUGH();
- case PS_InRootName: {
- PosPtr TkEnd = consumeAllSeparators(Start, End);
- if (TkEnd)
- return makeState(PS_InRootDir, Start, TkEnd);
- else
- return makeState(PS_InFilenames, Start, consumeName(Start, End));
- }
- case PS_InRootDir:
- return makeState(PS_InFilenames, Start, consumeName(Start, End));
-
- case PS_InFilenames: {
- PosPtr SepEnd = consumeAllSeparators(Start, End);
- if (SepEnd != End) {
- PosPtr TkEnd = consumeName(SepEnd, End);
- if (TkEnd)
- return makeState(PS_InFilenames, SepEnd, TkEnd);
- }
- return makeState(PS_InTrailingSep, Start, SepEnd);
- }
-
- case PS_InTrailingSep:
- return makeState(PS_AtEnd);
-
- case PS_AtEnd:
- __libcpp_unreachable();
- }
- }
-
- void decrement() noexcept {
- const PosPtr REnd = getBeforeFront();
- const PosPtr RStart = getCurrentTokenStartPos() - 1;
- if (RStart == REnd) // we're decrementing the begin
- return makeState(PS_BeforeBegin);
-
- switch (State) {
- case PS_AtEnd: {
- // Try to consume a trailing separator or root directory first.
- if (PosPtr SepEnd = consumeAllSeparators(RStart, REnd)) {
- if (SepEnd == REnd)
- return makeState(PS_InRootDir, Path.data(), RStart + 1);
- PosPtr TkStart = consumeRootName(SepEnd, REnd);
- if (TkStart == REnd)
- return makeState(PS_InRootDir, RStart, RStart + 1);
- return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1);
- } else {
- PosPtr TkStart = consumeRootName(RStart, REnd);
- if (TkStart == REnd)
- return makeState(PS_InRootName, TkStart + 1, RStart + 1);
- TkStart = consumeName(RStart, REnd);
- return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
- }
- }
- case PS_InTrailingSep:
- return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1,
- RStart + 1);
- case PS_InFilenames: {
- PosPtr SepEnd = consumeAllSeparators(RStart, REnd);
- if (SepEnd == REnd)
- return makeState(PS_InRootDir, Path.data(), RStart + 1);
- PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd);
- if (TkStart == REnd) {
- if (SepEnd)
- return makeState(PS_InRootDir, SepEnd + 1, RStart + 1);
- return makeState(PS_InRootName, TkStart + 1, RStart + 1);
- }
- TkStart = consumeName(SepEnd, REnd);
- return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1);
- }
- case PS_InRootDir:
- return makeState(PS_InRootName, Path.data(), RStart + 1);
- case PS_InRootName:
- case PS_BeforeBegin:
- __libcpp_unreachable();
- }
- }
-
- /// \brief Return a view with the "preferred representation" of the current
- /// element. For example trailing separators are represented as a '.'
- string_view_t operator*() const noexcept {
- switch (State) {
- case PS_BeforeBegin:
- case PS_AtEnd:
- return PATHSTR("");
- case PS_InRootDir:
- if (RawEntry[0] == '\\')
- return PATHSTR("\\");
- else
- return PATHSTR("/");
- case PS_InTrailingSep:
- return PATHSTR("");
- case PS_InRootName:
- case PS_InFilenames:
- return RawEntry;
- }
- __libcpp_unreachable();
- }
-
- explicit operator bool() const noexcept {
- return State != PS_BeforeBegin && State != PS_AtEnd;
- }
-
- PathParser& operator++() noexcept {
- increment();
- return *this;
- }
-
- PathParser& operator--() noexcept {
- decrement();
- return *this;
- }
-
- bool atEnd() const noexcept {
- return State == PS_AtEnd;
- }
-
- bool inRootDir() const noexcept {
- return State == PS_InRootDir;
- }
-
- bool inRootName() const noexcept {
- return State == PS_InRootName;
- }
-
- bool inRootPath() const noexcept {
- return inRootName() || inRootDir();
- }
-
-private:
- void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept {
- State = NewState;
- RawEntry = string_view_t(Start, End - Start);
- }
- void makeState(ParserState NewState) noexcept {
- State = NewState;
- RawEntry = {};
- }
-
- PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); }
-
- PosPtr getBeforeFront() const noexcept { return Path.data() - 1; }
-
- /// \brief Return a pointer to the first character after the currently
- /// lexed element.
- PosPtr getNextTokenStartPos() const noexcept {
- switch (State) {
- case PS_BeforeBegin:
- return Path.data();
- case PS_InRootName:
- case PS_InRootDir:
- case PS_InFilenames:
- return &RawEntry.back() + 1;
- case PS_InTrailingSep:
- case PS_AtEnd:
- return getAfterBack();
- }
- __libcpp_unreachable();
- }
-
- /// \brief Return a pointer to the first character in the currently lexed
- /// element.
- PosPtr getCurrentTokenStartPos() const noexcept {
- switch (State) {
- case PS_BeforeBegin:
- case PS_InRootName:
- return &Path.front();
- case PS_InRootDir:
- case PS_InFilenames:
- case PS_InTrailingSep:
- return &RawEntry.front();
- case PS_AtEnd:
- return &Path.back() + 1;
- }
- __libcpp_unreachable();
- }
-
- // Consume all consecutive separators.
- PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept {
- if (P == nullptr || P == End || !isSeparator(*P))
- return nullptr;
- const int Inc = P < End ? 1 : -1;
- P += Inc;
- while (P != End && isSeparator(*P))
- P += Inc;
- return P;
- }
-
- // Consume exactly N separators, or return nullptr.
- PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept {
- PosPtr Ret = consumeAllSeparators(P, End);
- if (Ret == nullptr)
- return nullptr;
- if (P < End) {
- if (Ret == P + N)
- return Ret;
- } else {
- if (Ret == P - N)
- return Ret;
- }
- return nullptr;
- }
-
- PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
- PosPtr Start = P;
- if (P == nullptr || P == End || isSeparator(*P))
- return nullptr;
- const int Inc = P < End ? 1 : -1;
- P += Inc;
- while (P != End && !isSeparator(*P))
- P += Inc;
- if (P == End && Inc < 0) {
- // Iterating backwards and consumed all the rest of the input.
- // Check if the start of the string would have been considered
- // a root name.
- PosPtr RootEnd = consumeRootName(End + 1, Start);
- if (RootEnd)
- return RootEnd - 1;
- }
- return P;
- }
-
- PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept {
- if (P == End)
- return nullptr;
- if (P < End) {
- if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':')
- return nullptr;
- return P + 2;
- } else {
- if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':')
- return nullptr;
- return P - 2;
- }
- }
-
- PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept {
- if (P == End)
- return nullptr;
- if (P < End)
- return consumeName(consumeNSeparators(P, End, 2), End);
- else
- return consumeNSeparators(consumeName(P, End), End, 2);
- }
-
-#if defined(_LIBCPP_WIN32API)
- PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept {
- if (PosPtr Ret = consumeDriveLetter(P, End))
- return Ret;
- if (PosPtr Ret = consumeNetworkRoot(P, End))
- return Ret;
- return nullptr;
- }
-#else
- PosPtr consumeRootName(PosPtr /*P*/, PosPtr /*End*/) const noexcept {
- return nullptr;
- }
-#endif
-};
-
-string_view_pair separate_filename(string_view_t const& s) {
- if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty())
- return string_view_pair{s, PATHSTR("")};
- auto pos = s.find_last_of('.');
- if (pos == string_view_t::npos || pos == 0)
- return string_view_pair{s, string_view_t{}};
- return string_view_pair{s.substr(0, pos), s.substr(pos)};
-}
-
-string_view_t createView(PosPtr S, PosPtr E) noexcept {
- return {S, static_cast<size_t>(E - S) + 1};
-}
-
-} // namespace parser
-} // namespace
-
-// POSIX HELPERS
-
-#if defined(_LIBCPP_WIN32API)
-namespace detail {
-
-errc __win_err_to_errc(int err) {
- constexpr struct {
- DWORD win;
- errc errc;
- } win_error_mapping[] = {
- {ERROR_ACCESS_DENIED, errc::permission_denied},
- {ERROR_ALREADY_EXISTS, errc::file_exists},
- {ERROR_BAD_NETPATH, errc::no_such_file_or_directory},
- {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory},
- {ERROR_BAD_UNIT, errc::no_such_device},
- {ERROR_BROKEN_PIPE, errc::broken_pipe},
- {ERROR_BUFFER_OVERFLOW, errc::filename_too_long},
- {ERROR_BUSY, errc::device_or_resource_busy},
- {ERROR_BUSY_DRIVE, errc::device_or_resource_busy},
- {ERROR_CANNOT_MAKE, errc::permission_denied},
- {ERROR_CANTOPEN, errc::io_error},
- {ERROR_CANTREAD, errc::io_error},
- {ERROR_CANTWRITE, errc::io_error},
- {ERROR_CURRENT_DIRECTORY, errc::permission_denied},
- {ERROR_DEV_NOT_EXIST, errc::no_such_device},
- {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy},
- {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty},
- {ERROR_DIRECTORY, errc::invalid_argument},
- {ERROR_DISK_FULL, errc::no_space_on_device},
- {ERROR_FILE_EXISTS, errc::file_exists},
- {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory},
- {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device},
- {ERROR_INVALID_ACCESS, errc::permission_denied},
- {ERROR_INVALID_DRIVE, errc::no_such_device},
- {ERROR_INVALID_FUNCTION, errc::function_not_supported},
- {ERROR_INVALID_HANDLE, errc::invalid_argument},
- {ERROR_INVALID_NAME, errc::no_such_file_or_directory},
- {ERROR_INVALID_PARAMETER, errc::invalid_argument},
- {ERROR_LOCK_VIOLATION, errc::no_lock_available},
- {ERROR_LOCKED, errc::no_lock_available},
- {ERROR_NEGATIVE_SEEK, errc::invalid_argument},
- {ERROR_NOACCESS, errc::permission_denied},
- {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory},
- {ERROR_NOT_READY, errc::resource_unavailable_try_again},
- {ERROR_NOT_SAME_DEVICE, errc::cross_device_link},
- {ERROR_NOT_SUPPORTED, errc::not_supported},
- {ERROR_OPEN_FAILED, errc::io_error},
- {ERROR_OPEN_FILES, errc::device_or_resource_busy},
- {ERROR_OPERATION_ABORTED, errc::operation_canceled},
- {ERROR_OUTOFMEMORY, errc::not_enough_memory},
- {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory},
- {ERROR_READ_FAULT, errc::io_error},
- {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument},
- {ERROR_RETRY, errc::resource_unavailable_try_again},
- {ERROR_SEEK, errc::io_error},
- {ERROR_SHARING_VIOLATION, errc::permission_denied},
- {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open},
- {ERROR_WRITE_FAULT, errc::io_error},
- {ERROR_WRITE_PROTECT, errc::permission_denied},
- };
-
- for (const auto &pair : win_error_mapping)
- if (pair.win == static_cast<DWORD>(err))
- return pair.errc;
- return errc::invalid_argument;
-}
-
-} // namespace detail
-#endif
-
-namespace detail {
-namespace {
-
-using value_type = path::value_type;
-using string_type = path::string_type;
-
-struct FileDescriptor {
- const path& name;
- int fd = -1;
- StatT m_stat;
- file_status m_status;
-
- template <class... Args>
- static FileDescriptor create(const path* p, error_code& ec, Args... args) {
- ec.clear();
- int fd;
- if ((fd = detail::open(p->c_str(), args...)) == -1) {
- ec = capture_errno();
- return FileDescriptor{p};
- }
- return FileDescriptor(p, fd);
- }
-
- template <class... Args>
- static FileDescriptor create_with_status(const path* p, error_code& ec,
- Args... args) {
- FileDescriptor fd = create(p, ec, args...);
- if (!ec)
- fd.refresh_status(ec);
-
- return fd;
- }
-
- file_status get_status() const { return m_status; }
- StatT const& get_stat() const { return m_stat; }
-
- bool status_known() const { return _VSTD_FS::status_known(m_status); }
-
- file_status refresh_status(error_code& ec);
-
- void close() noexcept {
- if (fd != -1)
- detail::close(fd);
- fd = -1;
- }
-
- FileDescriptor(FileDescriptor&& other)
- : name(other.name), fd(other.fd), m_stat(other.m_stat),
- m_status(other.m_status) {
- other.fd = -1;
- other.m_status = file_status{};
- }
-
- ~FileDescriptor() { close(); }
-
- FileDescriptor(FileDescriptor const&) = delete;
- FileDescriptor& operator=(FileDescriptor const&) = delete;
-
-private:
- explicit FileDescriptor(const path* p, int fd = -1) : name(*p), fd(fd) {}
-};
-
-perms posix_get_perms(const StatT& st) noexcept {
- return static_cast<perms>(st.st_mode) & perms::mask;
-}
-
-file_status create_file_status(error_code& m_ec, path const& p,
- const StatT& path_stat, error_code* ec) {
- if (ec)
- *ec = m_ec;
- if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) {
- return file_status(file_type::not_found);
- } else if (m_ec) {
- ErrorHandler<void> err("posix_stat", ec, &p);
- err.report(m_ec, "failed to determine attributes for the specified path");
- return file_status(file_type::none);
- }
- // else
-
- file_status fs_tmp;
- auto const mode = path_stat.st_mode;
- if (S_ISLNK(mode))
- fs_tmp.type(file_type::symlink);
- else if (S_ISREG(mode))
- fs_tmp.type(file_type::regular);
- else if (S_ISDIR(mode))
- fs_tmp.type(file_type::directory);
- else if (S_ISBLK(mode))
- fs_tmp.type(file_type::block);
- else if (S_ISCHR(mode))
- fs_tmp.type(file_type::character);
- else if (S_ISFIFO(mode))
- fs_tmp.type(file_type::fifo);
- else if (S_ISSOCK(mode))
- fs_tmp.type(file_type::socket);
- else
- fs_tmp.type(file_type::unknown);
-
- fs_tmp.permissions(detail::posix_get_perms(path_stat));
- return fs_tmp;
-}
-
-file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
- error_code m_ec;
- if (detail::stat(p.c_str(), &path_stat) == -1)
- m_ec = detail::capture_errno();
- return create_file_status(m_ec, p, path_stat, ec);
-}
-
-file_status posix_stat(path const& p, error_code* ec) {
- StatT path_stat;
- return posix_stat(p, path_stat, ec);
-}
-
-file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) {
- error_code m_ec;
- if (detail::lstat(p.c_str(), &path_stat) == -1)
- m_ec = detail::capture_errno();
- return create_file_status(m_ec, p, path_stat, ec);
-}
-
-file_status posix_lstat(path const& p, error_code* ec) {
- StatT path_stat;
- return posix_lstat(p, path_stat, ec);
-}
-
-// http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
-bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
- if (detail::ftruncate(fd.fd, to_size) == -1) {
- ec = capture_errno();
- return true;
- }
- ec.clear();
- return false;
-}
-
-bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) {
- if (detail::fchmod(fd.fd, st.st_mode) == -1) {
- ec = capture_errno();
- return true;
- }
- ec.clear();
- return false;
-}
-
-bool stat_equivalent(const StatT& st1, const StatT& st2) {
- return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
-}
-
-file_status FileDescriptor::refresh_status(error_code& ec) {
- // FD must be open and good.
- m_status = file_status{};
- m_stat = {};
- error_code m_ec;
- if (detail::fstat(fd, &m_stat) == -1)
- m_ec = capture_errno();
- m_status = create_file_status(m_ec, name, m_stat, &ec);
- return m_status;
-}
-} // namespace
-} // end namespace detail
-
using detail::capture_errno;
using detail::ErrorHandler;
using detail::StatT;
@@ -646,51 +62,6 @@ using parser::createView;
using parser::PathParser;
using parser::string_view_t;
-const bool _FilesystemClock::is_steady;
-
-_FilesystemClock::time_point _FilesystemClock::now() noexcept {
- typedef chrono::duration<rep> __secs;
-#if defined(_LIBCPP_WIN32API)
- typedef chrono::duration<rep, nano> __nsecs;
- FILETIME time;
- GetSystemTimeAsFileTime(&time);
- TimeSpec tp = detail::filetime_to_timespec(time);
- return time_point(__secs(tp.tv_sec) +
- chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
-#elif defined(CLOCK_REALTIME)
- typedef chrono::duration<rep, nano> __nsecs;
- struct timespec tp;
- if (0 != clock_gettime(CLOCK_REALTIME, &tp))
- __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
- return time_point(__secs(tp.tv_sec) +
- chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
-#else
- typedef chrono::duration<rep, micro> __microsecs;
- timeval tv;
- gettimeofday(&tv, 0);
- return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
-#endif // CLOCK_REALTIME
-}
-
-filesystem_error::~filesystem_error() {}
-
-void filesystem_error::__create_what(int __num_paths) {
- const char* derived_what = system_error::what();
- __storage_->__what_ = [&]() -> string {
- switch (__num_paths) {
- case 0:
- return detail::format_string("filesystem error: %s", derived_what);
- case 1:
- return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]",
- derived_what, path1().c_str());
- case 2:
- return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]",
- derived_what, path1().c_str(), path2().c_str());
- }
- __libcpp_unreachable();
- }();
-}
-
static path __do_absolute(const path& p, path* cwd, error_code* ec) {
if (ec)
ec->clear();
@@ -979,7 +350,7 @@ bool __copy_file(const path& from, const path& to, copy_options options,
return err.report(m_ec);
}
- if (!copy_file_impl(from_fd, to_fd, m_ec)) {
+ if (!detail::copy_file_impl(from_fd, to_fd, m_ec)) {
// FIXME: Remove the dest file if we failed, and it didn't exist previously.
return err.report(m_ec);
}
@@ -1108,7 +479,7 @@ path __current_path(error_code* ec) {
Deleter deleter = &::free;
#else
auto size = ::pathconf(".", _PC_PATH_MAX);
- _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size");
+ _LIBCPP_ASSERT_UNCATEGORIZED(size >= 0, "pathconf returned a 0 as max size");
auto buff = unique_ptr<path::value_type[]>(new path::value_type[size + 1]);
path::value_type* ptr = buff.get();
@@ -1197,18 +568,6 @@ bool __fs_is_empty(const path& p, error_code* ec) {
__libcpp_unreachable();
}
-static file_time_type __extract_last_write_time(const path& p, const StatT& st,
- error_code* ec) {
- using detail::fs_time;
- ErrorHandler<file_time_type> err("last_write_time", ec, &p);
-
- auto ts = detail::extract_mtime(st);
- if (!fs_time::is_representable(ts))
- return err.report(errc::value_too_large);
-
- return fs_time::convert_from_timespec(ts);
-}
-
file_time_type __last_write_time(const path& p, error_code* ec) {
using namespace chrono;
ErrorHandler<file_time_type> err("last_write_time", ec, &p);
@@ -1218,7 +577,7 @@ file_time_type __last_write_time(const path& p, error_code* ec) {
detail::posix_stat(p, st, &m_ec);
if (m_ec)
return err.report(m_ec);
- return __extract_last_write_time(p, st, ec);
+ return detail::__extract_last_write_time(p, st, ec);
}
void __last_write_time(const path& p, file_time_type new_time, error_code* ec) {
@@ -1268,7 +627,7 @@ void __permissions(const path& p, perms prms, perm_options opts,
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(
+ _LIBCPP_ASSERT_UNCATEGORIZED(
(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");
@@ -1282,7 +641,7 @@ void __permissions(const path& p, perms prms, perm_options opts,
set_sym_perms = is_symlink(st);
if (m_ec)
return err.report(m_ec);
- _LIBCPP_ASSERT(st.permissions() != perms::unknown,
+ _LIBCPP_ASSERT_UNCATEGORIZED(st.permissions() != perms::unknown,
"Permissions unexpectedly unknown");
if (add_perms)
prms |= st.permissions();
@@ -1328,7 +687,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(ret > 0, "TODO");
+ _LIBCPP_ASSERT_UNCATEGORIZED(ret > 0, "TODO");
if (static_cast<size_t>(ret) >= size)
return err.report(errc::value_too_large);
buff[ret] = 0;
@@ -1554,8 +913,13 @@ path __temp_directory_path(error_code* ec) {
for (auto& ep : env_paths)
if ((ret = getenv(ep)))
break;
- if (ret == nullptr)
+ if (ret == nullptr) {
+#if defined(__ANDROID__)
+ ret = "/data/local/tmp";
+#else
ret = "/tmp";
+#endif
+ }
path p(ret);
#endif
@@ -1608,500 +972,4 @@ path __weakly_canonical(const path& p, error_code* ec) {
return result.lexically_normal();
}
-///////////////////////////////////////////////////////////////////////////////
-// path definitions
-///////////////////////////////////////////////////////////////////////////////
-
-constexpr path::value_type path::preferred_separator;
-
-path& path::replace_extension(path const& replacement) {
- path p = extension();
- if (not p.empty()) {
- __pn_.erase(__pn_.size() - p.native().size());
- }
- if (!replacement.empty()) {
- if (replacement.native()[0] != '.') {
- __pn_ += PATHSTR(".");
- }
- __pn_.append(replacement.__pn_);
- }
- return *this;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// path.decompose
-
-string_view_t path::__root_name() const {
- auto PP = PathParser::CreateBegin(__pn_);
- if (PP.State == PathParser::PS_InRootName)
- return *PP;
- return {};
-}
-
-string_view_t path::__root_directory() const {
- auto PP = PathParser::CreateBegin(__pn_);
- if (PP.State == PathParser::PS_InRootName)
- ++PP;
- if (PP.State == PathParser::PS_InRootDir)
- return *PP;
- return {};
-}
-
-string_view_t path::__root_path_raw() const {
- auto PP = PathParser::CreateBegin(__pn_);
- if (PP.State == PathParser::PS_InRootName) {
- auto NextCh = PP.peek();
- if (NextCh && isSeparator(*NextCh)) {
- ++PP;
- return createView(__pn_.data(), &PP.RawEntry.back());
- }
- return PP.RawEntry;
- }
- if (PP.State == PathParser::PS_InRootDir)
- return *PP;
- return {};
-}
-
-static bool ConsumeRootName(PathParser *PP) {
- static_assert(PathParser::PS_BeforeBegin == 1 &&
- PathParser::PS_InRootName == 2,
- "Values for enums are incorrect");
- while (PP->State <= PathParser::PS_InRootName)
- ++(*PP);
- return PP->State == PathParser::PS_AtEnd;
-}
-
-static bool ConsumeRootDir(PathParser* PP) {
- static_assert(PathParser::PS_BeforeBegin == 1 &&
- PathParser::PS_InRootName == 2 &&
- PathParser::PS_InRootDir == 3, "Values for enums are incorrect");
- while (PP->State <= PathParser::PS_InRootDir)
- ++(*PP);
- return PP->State == PathParser::PS_AtEnd;
-}
-
-string_view_t path::__relative_path() const {
- auto PP = PathParser::CreateBegin(__pn_);
- if (ConsumeRootDir(&PP))
- return {};
- return createView(PP.RawEntry.data(), &__pn_.back());
-}
-
-string_view_t path::__parent_path() const {
- if (empty())
- return {};
- // Determine if we have a root path but not a relative path. In that case
- // return *this.
- {
- auto PP = PathParser::CreateBegin(__pn_);
- if (ConsumeRootDir(&PP))
- return __pn_;
- }
- // Otherwise remove a single element from the end of the path, and return
- // a string representing that path
- {
- auto PP = PathParser::CreateEnd(__pn_);
- --PP;
- if (PP.RawEntry.data() == __pn_.data())
- return {};
- --PP;
- return createView(__pn_.data(), &PP.RawEntry.back());
- }
-}
-
-string_view_t path::__filename() const {
- if (empty())
- return {};
- {
- PathParser PP = PathParser::CreateBegin(__pn_);
- if (ConsumeRootDir(&PP))
- return {};
- }
- return *(--PathParser::CreateEnd(__pn_));
-}
-
-string_view_t path::__stem() const {
- return parser::separate_filename(__filename()).first;
-}
-
-string_view_t path::__extension() const {
- return parser::separate_filename(__filename()).second;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// path.gen
-
-enum PathPartKind : unsigned char {
- PK_None,
- PK_RootSep,
- PK_Filename,
- PK_Dot,
- PK_DotDot,
- PK_TrailingSep
-};
-
-static PathPartKind ClassifyPathPart(string_view_t Part) {
- if (Part.empty())
- return PK_TrailingSep;
- if (Part == PATHSTR("."))
- return PK_Dot;
- if (Part == PATHSTR(".."))
- return PK_DotDot;
- if (Part == PATHSTR("/"))
- return PK_RootSep;
-#if defined(_LIBCPP_WIN32API)
- if (Part == PATHSTR("\\"))
- return PK_RootSep;
-#endif
- return PK_Filename;
-}
-
-path path::lexically_normal() const {
- if (__pn_.empty())
- return *this;
-
- using PartKindPair = pair<string_view_t, PathPartKind>;
- vector<PartKindPair> Parts;
- // Guess as to how many elements the path has to avoid reallocating.
- Parts.reserve(32);
-
- // Track the total size of the parts as we collect them. This allows the
- // resulting path to reserve the correct amount of memory.
- size_t NewPathSize = 0;
- auto AddPart = [&](PathPartKind K, string_view_t P) {
- NewPathSize += P.size();
- Parts.emplace_back(P, K);
- };
- auto LastPartKind = [&]() {
- if (Parts.empty())
- return PK_None;
- return Parts.back().second;
- };
-
- bool MaybeNeedTrailingSep = false;
- // Build a stack containing the remaining elements of the path, popping off
- // elements which occur before a '..' entry.
- for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) {
- auto Part = *PP;
- PathPartKind Kind = ClassifyPathPart(Part);
- switch (Kind) {
- case PK_Filename:
- case PK_RootSep: {
- // Add all non-dot and non-dot-dot elements to the stack of elements.
- AddPart(Kind, Part);
- MaybeNeedTrailingSep = false;
- break;
- }
- case PK_DotDot: {
- // Only push a ".." element if there are no elements preceding the "..",
- // or if the preceding element is itself "..".
- auto LastKind = LastPartKind();
- if (LastKind == PK_Filename) {
- NewPathSize -= Parts.back().first.size();
- Parts.pop_back();
- } else if (LastKind != PK_RootSep)
- AddPart(PK_DotDot, PATHSTR(".."));
- MaybeNeedTrailingSep = LastKind == PK_Filename;
- break;
- }
- case PK_Dot:
- case PK_TrailingSep: {
- MaybeNeedTrailingSep = true;
- break;
- }
- case PK_None:
- __libcpp_unreachable();
- }
- }
- // [fs.path.generic]p6.8: If the path is empty, add a dot.
- if (Parts.empty())
- return PATHSTR(".");
-
- // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any
- // trailing directory-separator.
- bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename;
-
- path Result;
- Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep);
- for (auto& PK : Parts)
- Result /= PK.first;
-
- if (NeedTrailingSep)
- Result /= PATHSTR("");
-
- Result.make_preferred();
- return Result;
-}
-
-static int DetermineLexicalElementCount(PathParser PP) {
- int Count = 0;
- for (; PP; ++PP) {
- auto Elem = *PP;
- if (Elem == PATHSTR(".."))
- --Count;
- else if (Elem != PATHSTR(".") && Elem != PATHSTR(""))
- ++Count;
- }
- return Count;
-}
-
-path path::lexically_relative(const path& base) const {
- { // perform root-name/root-directory mismatch checks
- auto PP = PathParser::CreateBegin(__pn_);
- auto PPBase = PathParser::CreateBegin(base.__pn_);
- auto CheckIterMismatchAtBase = [&]() {
- return PP.State != PPBase.State &&
- (PP.inRootPath() || PPBase.inRootPath());
- };
- if (PP.inRootName() && PPBase.inRootName()) {
- if (*PP != *PPBase)
- return {};
- } else if (CheckIterMismatchAtBase())
- return {};
-
- if (PP.inRootPath())
- ++PP;
- if (PPBase.inRootPath())
- ++PPBase;
- if (CheckIterMismatchAtBase())
- return {};
- }
-
- // Find the first mismatching element
- auto PP = PathParser::CreateBegin(__pn_);
- auto PPBase = PathParser::CreateBegin(base.__pn_);
- while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) {
- ++PP;
- ++PPBase;
- }
-
- // If there is no mismatch, return ".".
- if (!PP && !PPBase)
- return ".";
-
- // Otherwise, determine the number of elements, 'n', which are not dot or
- // dot-dot minus the number of dot-dot elements.
- int ElemCount = DetermineLexicalElementCount(PPBase);
- if (ElemCount < 0)
- return {};
-
- // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise
- if (ElemCount == 0 && (PP.atEnd() || *PP == PATHSTR("")))
- return PATHSTR(".");
-
- // return a path constructed with 'n' dot-dot elements, followed by the
- // elements of '*this' after the mismatch.
- path Result;
- // FIXME: Reserve enough room in Result that it won't have to re-allocate.
- while (ElemCount--)
- Result /= PATHSTR("..");
- for (; PP; ++PP)
- Result /= *PP;
- return Result;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// path.comparisons
-static int CompareRootName(PathParser *LHS, PathParser *RHS) {
- if (!LHS->inRootName() && !RHS->inRootName())
- return 0;
-
- auto GetRootName = [](PathParser *Parser) -> string_view_t {
- return Parser->inRootName() ? **Parser : PATHSTR("");
- };
- int res = GetRootName(LHS).compare(GetRootName(RHS));
- ConsumeRootName(LHS);
- ConsumeRootName(RHS);
- return res;
-}
-
-static int CompareRootDir(PathParser *LHS, PathParser *RHS) {
- if (!LHS->inRootDir() && RHS->inRootDir())
- return -1;
- else if (LHS->inRootDir() && !RHS->inRootDir())
- return 1;
- else {
- ConsumeRootDir(LHS);
- ConsumeRootDir(RHS);
- return 0;
- }
-}
-
-static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) {
- auto &LHS = *LHSPtr;
- auto &RHS = *RHSPtr;
-
- int res;
- while (LHS && RHS) {
- if ((res = (*LHS).compare(*RHS)) != 0)
- return res;
- ++LHS;
- ++RHS;
- }
- return 0;
-}
-
-static int CompareEndState(PathParser *LHS, PathParser *RHS) {
- if (LHS->atEnd() && !RHS->atEnd())
- return -1;
- else if (!LHS->atEnd() && RHS->atEnd())
- return 1;
- return 0;
-}
-
-int path::__compare(string_view_t __s) const {
- auto LHS = PathParser::CreateBegin(__pn_);
- auto RHS = PathParser::CreateBegin(__s);
- int res;
-
- if ((res = CompareRootName(&LHS, &RHS)) != 0)
- return res;
-
- if ((res = CompareRootDir(&LHS, &RHS)) != 0)
- return res;
-
- if ((res = CompareRelative(&LHS, &RHS)) != 0)
- return res;
-
- return CompareEndState(&LHS, &RHS);
-}
-
-////////////////////////////////////////////////////////////////////////////
-// path.nonmembers
-size_t hash_value(const path& __p) noexcept {
- auto PP = PathParser::CreateBegin(__p.native());
- size_t hash_value = 0;
- hash<string_view_t> hasher;
- while (PP) {
- hash_value = __hash_combine(hash_value, hasher(*PP));
- ++PP;
- }
- return hash_value;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// path.itr
-path::iterator path::begin() const {
- auto PP = PathParser::CreateBegin(__pn_);
- iterator it;
- it.__path_ptr_ = this;
- it.__state_ = static_cast<path::iterator::_ParserState>(PP.State);
- it.__entry_ = PP.RawEntry;
- it.__stashed_elem_.__assign_view(*PP);
- return it;
-}
-
-path::iterator path::end() const {
- iterator it{};
- it.__state_ = path::iterator::_AtEnd;
- it.__path_ptr_ = this;
- return it;
-}
-
-path::iterator& path::iterator::__increment() {
- PathParser PP(__path_ptr_->native(), __entry_, __state_);
- ++PP;
- __state_ = static_cast<_ParserState>(PP.State);
- __entry_ = PP.RawEntry;
- __stashed_elem_.__assign_view(*PP);
- return *this;
-}
-
-path::iterator& path::iterator::__decrement() {
- PathParser PP(__path_ptr_->native(), __entry_, __state_);
- --PP;
- __state_ = static_cast<_ParserState>(PP.State);
- __entry_ = PP.RawEntry;
- __stashed_elem_.__assign_view(*PP);
- return *this;
-}
-
-#if defined(_LIBCPP_WIN32API)
-////////////////////////////////////////////////////////////////////////////
-// Windows path conversions
-size_t __wide_to_char(const wstring &str, char *out, size_t outlen) {
- if (str.empty())
- return 0;
- ErrorHandler<size_t> err("__wide_to_char", nullptr);
- UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
- BOOL used_default = FALSE;
- int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out,
- outlen, nullptr, &used_default);
- if (ret <= 0 || used_default)
- return err.report(errc::illegal_byte_sequence);
- return ret;
-}
-
-size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) {
- if (str.empty())
- return 0;
- ErrorHandler<size_t> err("__char_to_wide", nullptr);
- UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
- int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(),
- str.size(), out, outlen);
- if (ret <= 0)
- return err.report(errc::illegal_byte_sequence);
- return ret;
-}
-#endif
-
-
-///////////////////////////////////////////////////////////////////////////////
-// directory entry definitions
-///////////////////////////////////////////////////////////////////////////////
-
-error_code directory_entry::__do_refresh() noexcept {
- __data_.__reset();
- error_code failure_ec;
-
- StatT full_st;
- file_status st = detail::posix_lstat(__p_, full_st, &failure_ec);
- if (!status_known(st)) {
- __data_.__reset();
- return failure_ec;
- }
-
- if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) {
- __data_.__cache_type_ = directory_entry::_RefreshNonSymlink;
- __data_.__type_ = st.type();
- __data_.__non_sym_perms_ = st.permissions();
- } else { // we have a symlink
- __data_.__sym_perms_ = st.permissions();
- // Get the information about the linked entity.
- // Ignore errors from stat, since we don't want errors regarding symlink
- // resolution to be reported to the user.
- error_code ignored_ec;
- st = detail::posix_stat(__p_, full_st, &ignored_ec);
-
- __data_.__type_ = st.type();
- __data_.__non_sym_perms_ = st.permissions();
-
- // If we failed to resolve the link, then only partially populate the
- // cache.
- if (!status_known(st)) {
- __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
- return error_code{};
- }
- // Otherwise, we resolved the link, potentially as not existing.
- // That's OK.
- __data_.__cache_type_ = directory_entry::_RefreshSymlink;
- }
-
- if (_VSTD_FS::is_regular_file(st))
- __data_.__size_ = static_cast<uintmax_t>(full_st.st_size);
-
- if (_VSTD_FS::exists(st)) {
- __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink);
-
- // Attempt to extract the mtime, and fail if it's not representable using
- // file_time_type. For now we ignore the error, as we'll report it when
- // the value is actually used.
- error_code ignored_ec;
- __data_.__write_time_ =
- __extract_last_write_time(__p_, full_st, &ignored_ec);
- }
-
- return failure_ec;
-}
-
_LIBCPP_END_NAMESPACE_FILESYSTEM
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/path.cpp b/contrib/libs/cxxsupp/libcxx/src/filesystem/path.cpp
new file mode 100644
index 0000000000..82f1ba7ba6
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/path.cpp
@@ -0,0 +1,460 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <filesystem>
+#include <vector>
+
+#include "error.h"
+#include "path_parser.h"
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+using detail::ErrorHandler;
+using parser::createView;
+using parser::PathParser;
+using parser::string_view_t;
+
+///////////////////////////////////////////////////////////////////////////////
+// path definitions
+///////////////////////////////////////////////////////////////////////////////
+
+constexpr path::value_type path::preferred_separator;
+
+path& path::replace_extension(path const& replacement) {
+ path p = extension();
+ if (not p.empty()) {
+ __pn_.erase(__pn_.size() - p.native().size());
+ }
+ if (!replacement.empty()) {
+ if (replacement.native()[0] != '.') {
+ __pn_ += PATHSTR(".");
+ }
+ __pn_.append(replacement.__pn_);
+ }
+ return *this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// path.decompose
+
+string_view_t path::__root_name() const {
+ auto PP = PathParser::CreateBegin(__pn_);
+ if (PP.State == PathParser::PS_InRootName)
+ return *PP;
+ return {};
+}
+
+string_view_t path::__root_directory() const {
+ auto PP = PathParser::CreateBegin(__pn_);
+ if (PP.State == PathParser::PS_InRootName)
+ ++PP;
+ if (PP.State == PathParser::PS_InRootDir)
+ return *PP;
+ return {};
+}
+
+string_view_t path::__root_path_raw() const {
+ auto PP = PathParser::CreateBegin(__pn_);
+ if (PP.State == PathParser::PS_InRootName) {
+ auto NextCh = PP.peek();
+ if (NextCh && isSeparator(*NextCh)) {
+ ++PP;
+ return createView(__pn_.data(), &PP.RawEntry.back());
+ }
+ return PP.RawEntry;
+ }
+ if (PP.State == PathParser::PS_InRootDir)
+ return *PP;
+ return {};
+}
+
+static bool ConsumeRootName(PathParser *PP) {
+ static_assert(PathParser::PS_BeforeBegin == 1 &&
+ PathParser::PS_InRootName == 2,
+ "Values for enums are incorrect");
+ while (PP->State <= PathParser::PS_InRootName)
+ ++(*PP);
+ return PP->State == PathParser::PS_AtEnd;
+}
+
+static bool ConsumeRootDir(PathParser* PP) {
+ static_assert(PathParser::PS_BeforeBegin == 1 &&
+ PathParser::PS_InRootName == 2 &&
+ PathParser::PS_InRootDir == 3, "Values for enums are incorrect");
+ while (PP->State <= PathParser::PS_InRootDir)
+ ++(*PP);
+ return PP->State == PathParser::PS_AtEnd;
+}
+
+string_view_t path::__relative_path() const {
+ auto PP = PathParser::CreateBegin(__pn_);
+ if (ConsumeRootDir(&PP))
+ return {};
+ return createView(PP.RawEntry.data(), &__pn_.back());
+}
+
+string_view_t path::__parent_path() const {
+ if (empty())
+ return {};
+ // Determine if we have a root path but not a relative path. In that case
+ // return *this.
+ {
+ auto PP = PathParser::CreateBegin(__pn_);
+ if (ConsumeRootDir(&PP))
+ return __pn_;
+ }
+ // Otherwise remove a single element from the end of the path, and return
+ // a string representing that path
+ {
+ auto PP = PathParser::CreateEnd(__pn_);
+ --PP;
+ if (PP.RawEntry.data() == __pn_.data())
+ return {};
+ --PP;
+ return createView(__pn_.data(), &PP.RawEntry.back());
+ }
+}
+
+string_view_t path::__filename() const {
+ if (empty())
+ return {};
+ {
+ PathParser PP = PathParser::CreateBegin(__pn_);
+ if (ConsumeRootDir(&PP))
+ return {};
+ }
+ return *(--PathParser::CreateEnd(__pn_));
+}
+
+string_view_t path::__stem() const {
+ return parser::separate_filename(__filename()).first;
+}
+
+string_view_t path::__extension() const {
+ return parser::separate_filename(__filename()).second;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.gen
+
+enum PathPartKind : unsigned char {
+ PK_None,
+ PK_RootSep,
+ PK_Filename,
+ PK_Dot,
+ PK_DotDot,
+ PK_TrailingSep
+};
+
+static PathPartKind ClassifyPathPart(string_view_t Part) {
+ if (Part.empty())
+ return PK_TrailingSep;
+ if (Part == PATHSTR("."))
+ return PK_Dot;
+ if (Part == PATHSTR(".."))
+ return PK_DotDot;
+ if (Part == PATHSTR("/"))
+ return PK_RootSep;
+#if defined(_LIBCPP_WIN32API)
+ if (Part == PATHSTR("\\"))
+ return PK_RootSep;
+#endif
+ return PK_Filename;
+}
+
+path path::lexically_normal() const {
+ if (__pn_.empty())
+ return *this;
+
+ using PartKindPair = pair<string_view_t, PathPartKind>;
+ vector<PartKindPair> Parts;
+ // Guess as to how many elements the path has to avoid reallocating.
+ Parts.reserve(32);
+
+ // Track the total size of the parts as we collect them. This allows the
+ // resulting path to reserve the correct amount of memory.
+ size_t NewPathSize = 0;
+ auto AddPart = [&](PathPartKind K, string_view_t P) {
+ NewPathSize += P.size();
+ Parts.emplace_back(P, K);
+ };
+ auto LastPartKind = [&]() {
+ if (Parts.empty())
+ return PK_None;
+ return Parts.back().second;
+ };
+
+ bool MaybeNeedTrailingSep = false;
+ // Build a stack containing the remaining elements of the path, popping off
+ // elements which occur before a '..' entry.
+ for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) {
+ auto Part = *PP;
+ PathPartKind Kind = ClassifyPathPart(Part);
+ switch (Kind) {
+ case PK_Filename:
+ case PK_RootSep: {
+ // Add all non-dot and non-dot-dot elements to the stack of elements.
+ AddPart(Kind, Part);
+ MaybeNeedTrailingSep = false;
+ break;
+ }
+ case PK_DotDot: {
+ // Only push a ".." element if there are no elements preceding the "..",
+ // or if the preceding element is itself "..".
+ auto LastKind = LastPartKind();
+ if (LastKind == PK_Filename) {
+ NewPathSize -= Parts.back().first.size();
+ Parts.pop_back();
+ } else if (LastKind != PK_RootSep)
+ AddPart(PK_DotDot, PATHSTR(".."));
+ MaybeNeedTrailingSep = LastKind == PK_Filename;
+ break;
+ }
+ case PK_Dot:
+ case PK_TrailingSep: {
+ MaybeNeedTrailingSep = true;
+ break;
+ }
+ case PK_None:
+ __libcpp_unreachable();
+ }
+ }
+ // [fs.path.generic]p6.8: If the path is empty, add a dot.
+ if (Parts.empty())
+ return PATHSTR(".");
+
+ // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any
+ // trailing directory-separator.
+ bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename;
+
+ path Result;
+ Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep);
+ for (auto& PK : Parts)
+ Result /= PK.first;
+
+ if (NeedTrailingSep)
+ Result /= PATHSTR("");
+
+ Result.make_preferred();
+ return Result;
+}
+
+static int DetermineLexicalElementCount(PathParser PP) {
+ int Count = 0;
+ for (; PP; ++PP) {
+ auto Elem = *PP;
+ if (Elem == PATHSTR(".."))
+ --Count;
+ else if (Elem != PATHSTR(".") && Elem != PATHSTR(""))
+ ++Count;
+ }
+ return Count;
+}
+
+path path::lexically_relative(const path& base) const {
+ { // perform root-name/root-directory mismatch checks
+ auto PP = PathParser::CreateBegin(__pn_);
+ auto PPBase = PathParser::CreateBegin(base.__pn_);
+ auto CheckIterMismatchAtBase = [&]() {
+ return PP.State != PPBase.State &&
+ (PP.inRootPath() || PPBase.inRootPath());
+ };
+ if (PP.inRootName() && PPBase.inRootName()) {
+ if (*PP != *PPBase)
+ return {};
+ } else if (CheckIterMismatchAtBase())
+ return {};
+
+ if (PP.inRootPath())
+ ++PP;
+ if (PPBase.inRootPath())
+ ++PPBase;
+ if (CheckIterMismatchAtBase())
+ return {};
+ }
+
+ // Find the first mismatching element
+ auto PP = PathParser::CreateBegin(__pn_);
+ auto PPBase = PathParser::CreateBegin(base.__pn_);
+ while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) {
+ ++PP;
+ ++PPBase;
+ }
+
+ // If there is no mismatch, return ".".
+ if (!PP && !PPBase)
+ return ".";
+
+ // Otherwise, determine the number of elements, 'n', which are not dot or
+ // dot-dot minus the number of dot-dot elements.
+ int ElemCount = DetermineLexicalElementCount(PPBase);
+ if (ElemCount < 0)
+ return {};
+
+ // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise
+ if (ElemCount == 0 && (PP.atEnd() || *PP == PATHSTR("")))
+ return PATHSTR(".");
+
+ // return a path constructed with 'n' dot-dot elements, followed by the
+ // elements of '*this' after the mismatch.
+ path Result;
+ // FIXME: Reserve enough room in Result that it won't have to re-allocate.
+ while (ElemCount--)
+ Result /= PATHSTR("..");
+ for (; PP; ++PP)
+ Result /= *PP;
+ return Result;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.comparisons
+static int CompareRootName(PathParser *LHS, PathParser *RHS) {
+ if (!LHS->inRootName() && !RHS->inRootName())
+ return 0;
+
+ auto GetRootName = [](PathParser *Parser) -> string_view_t {
+ return Parser->inRootName() ? **Parser : PATHSTR("");
+ };
+ int res = GetRootName(LHS).compare(GetRootName(RHS));
+ ConsumeRootName(LHS);
+ ConsumeRootName(RHS);
+ return res;
+}
+
+static int CompareRootDir(PathParser *LHS, PathParser *RHS) {
+ if (!LHS->inRootDir() && RHS->inRootDir())
+ return -1;
+ else if (LHS->inRootDir() && !RHS->inRootDir())
+ return 1;
+ else {
+ ConsumeRootDir(LHS);
+ ConsumeRootDir(RHS);
+ return 0;
+ }
+}
+
+static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) {
+ auto &LHS = *LHSPtr;
+ auto &RHS = *RHSPtr;
+
+ int res;
+ while (LHS && RHS) {
+ if ((res = (*LHS).compare(*RHS)) != 0)
+ return res;
+ ++LHS;
+ ++RHS;
+ }
+ return 0;
+}
+
+static int CompareEndState(PathParser *LHS, PathParser *RHS) {
+ if (LHS->atEnd() && !RHS->atEnd())
+ return -1;
+ else if (!LHS->atEnd() && RHS->atEnd())
+ return 1;
+ return 0;
+}
+
+int path::__compare(string_view_t __s) const {
+ auto LHS = PathParser::CreateBegin(__pn_);
+ auto RHS = PathParser::CreateBegin(__s);
+ int res;
+
+ if ((res = CompareRootName(&LHS, &RHS)) != 0)
+ return res;
+
+ if ((res = CompareRootDir(&LHS, &RHS)) != 0)
+ return res;
+
+ if ((res = CompareRelative(&LHS, &RHS)) != 0)
+ return res;
+
+ return CompareEndState(&LHS, &RHS);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.nonmembers
+size_t hash_value(const path& __p) noexcept {
+ auto PP = PathParser::CreateBegin(__p.native());
+ size_t hash_value = 0;
+ hash<string_view_t> hasher;
+ while (PP) {
+ hash_value = __hash_combine(hash_value, hasher(*PP));
+ ++PP;
+ }
+ return hash_value;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// path.itr
+path::iterator path::begin() const {
+ auto PP = PathParser::CreateBegin(__pn_);
+ iterator it;
+ it.__path_ptr_ = this;
+ it.__state_ = static_cast<path::iterator::_ParserState>(PP.State);
+ it.__entry_ = PP.RawEntry;
+ it.__stashed_elem_.__assign_view(*PP);
+ return it;
+}
+
+path::iterator path::end() const {
+ iterator it{};
+ it.__state_ = path::iterator::_AtEnd;
+ it.__path_ptr_ = this;
+ return it;
+}
+
+path::iterator& path::iterator::__increment() {
+ PathParser PP(__path_ptr_->native(), __entry_, __state_);
+ ++PP;
+ __state_ = static_cast<_ParserState>(PP.State);
+ __entry_ = PP.RawEntry;
+ __stashed_elem_.__assign_view(*PP);
+ return *this;
+}
+
+path::iterator& path::iterator::__decrement() {
+ PathParser PP(__path_ptr_->native(), __entry_, __state_);
+ --PP;
+ __state_ = static_cast<_ParserState>(PP.State);
+ __entry_ = PP.RawEntry;
+ __stashed_elem_.__assign_view(*PP);
+ return *this;
+}
+
+#if defined(_LIBCPP_WIN32API)
+////////////////////////////////////////////////////////////////////////////
+// Windows path conversions
+size_t __wide_to_char(const wstring &str, char *out, size_t outlen) {
+ if (str.empty())
+ return 0;
+ ErrorHandler<size_t> err("__wide_to_char", nullptr);
+ UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ BOOL used_default = FALSE;
+ int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out,
+ outlen, nullptr, &used_default);
+ if (ret <= 0 || used_default)
+ return err.report(errc::illegal_byte_sequence);
+ return ret;
+}
+
+size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) {
+ if (str.empty())
+ return 0;
+ ErrorHandler<size_t> err("__char_to_wide", nullptr);
+ UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(),
+ str.size(), out, outlen);
+ if (ret <= 0)
+ return err.report(errc::illegal_byte_sequence);
+ return ret;
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/path_parser.h b/contrib/libs/cxxsupp/libcxx/src/filesystem/path_parser.h
new file mode 100644
index 0000000000..630391fe6b
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/path_parser.h
@@ -0,0 +1,372 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 PATH_PARSER_H
+#define PATH_PARSER_H
+
+#include <__config>
+#include <__utility/unreachable.h>
+#include <cstddef>
+#include <filesystem>
+#include <utility>
+
+#include "format_string.h"
+
+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
+
+inline bool isSeparator(path::value_type C) {
+ if (C == '/')
+ return true;
+#if defined(_LIBCPP_WIN32API)
+ if (C == '\\')
+ return true;
+#endif
+ return false;
+}
+
+inline bool isDriveLetter(path::value_type C) {
+ return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z');
+}
+
+namespace parser {
+
+using string_view_t = path::__string_view;
+using string_view_pair = pair<string_view_t, string_view_t>;
+using PosPtr = path::value_type const*;
+
+struct PathParser {
+ enum ParserState : unsigned char {
+ // Zero is a special sentinel value used by default constructed iterators.
+ PS_BeforeBegin = path::iterator::_BeforeBegin,
+ PS_InRootName = path::iterator::_InRootName,
+ PS_InRootDir = path::iterator::_InRootDir,
+ PS_InFilenames = path::iterator::_InFilenames,
+ PS_InTrailingSep = path::iterator::_InTrailingSep,
+ PS_AtEnd = path::iterator::_AtEnd
+ };
+
+ const string_view_t Path;
+ string_view_t RawEntry;
+ ParserState State;
+
+private:
+ PathParser(string_view_t P, ParserState State) noexcept : Path(P),
+ State(State) {}
+
+public:
+ PathParser(string_view_t P, string_view_t E, unsigned char S)
+ : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) {
+ // S cannot be '0' or PS_BeforeBegin.
+ }
+
+ static PathParser CreateBegin(string_view_t P) noexcept {
+ PathParser PP(P, PS_BeforeBegin);
+ PP.increment();
+ return PP;
+ }
+
+ static PathParser CreateEnd(string_view_t P) noexcept {
+ PathParser PP(P, PS_AtEnd);
+ return PP;
+ }
+
+ PosPtr peek() const noexcept {
+ auto TkEnd = getNextTokenStartPos();
+ auto End = getAfterBack();
+ return TkEnd == End ? nullptr : TkEnd;
+ }
+
+ void increment() noexcept {
+ const PosPtr End = getAfterBack();
+ const PosPtr Start = getNextTokenStartPos();
+ if (Start == End)
+ return makeState(PS_AtEnd);
+
+ switch (State) {
+ case PS_BeforeBegin: {
+ PosPtr TkEnd = consumeRootName(Start, End);
+ if (TkEnd)
+ return makeState(PS_InRootName, Start, TkEnd);
+ }
+ _LIBCPP_FALLTHROUGH();
+ case PS_InRootName: {
+ PosPtr TkEnd = consumeAllSeparators(Start, End);
+ if (TkEnd)
+ return makeState(PS_InRootDir, Start, TkEnd);
+ else
+ return makeState(PS_InFilenames, Start, consumeName(Start, End));
+ }
+ case PS_InRootDir:
+ return makeState(PS_InFilenames, Start, consumeName(Start, End));
+
+ case PS_InFilenames: {
+ PosPtr SepEnd = consumeAllSeparators(Start, End);
+ if (SepEnd != End) {
+ PosPtr TkEnd = consumeName(SepEnd, End);
+ if (TkEnd)
+ return makeState(PS_InFilenames, SepEnd, TkEnd);
+ }
+ return makeState(PS_InTrailingSep, Start, SepEnd);
+ }
+
+ case PS_InTrailingSep:
+ return makeState(PS_AtEnd);
+
+ case PS_AtEnd:
+ __libcpp_unreachable();
+ }
+ }
+
+ void decrement() noexcept {
+ const PosPtr REnd = getBeforeFront();
+ const PosPtr RStart = getCurrentTokenStartPos() - 1;
+ if (RStart == REnd) // we're decrementing the begin
+ return makeState(PS_BeforeBegin);
+
+ switch (State) {
+ case PS_AtEnd: {
+ // Try to consume a trailing separator or root directory first.
+ if (PosPtr SepEnd = consumeAllSeparators(RStart, REnd)) {
+ if (SepEnd == REnd)
+ return makeState(PS_InRootDir, Path.data(), RStart + 1);
+ PosPtr TkStart = consumeRootName(SepEnd, REnd);
+ if (TkStart == REnd)
+ return makeState(PS_InRootDir, RStart, RStart + 1);
+ return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1);
+ } else {
+ PosPtr TkStart = consumeRootName(RStart, REnd);
+ if (TkStart == REnd)
+ return makeState(PS_InRootName, TkStart + 1, RStart + 1);
+ TkStart = consumeName(RStart, REnd);
+ return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
+ }
+ }
+ case PS_InTrailingSep:
+ return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1,
+ RStart + 1);
+ case PS_InFilenames: {
+ PosPtr SepEnd = consumeAllSeparators(RStart, REnd);
+ if (SepEnd == REnd)
+ return makeState(PS_InRootDir, Path.data(), RStart + 1);
+ PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd);
+ if (TkStart == REnd) {
+ if (SepEnd)
+ return makeState(PS_InRootDir, SepEnd + 1, RStart + 1);
+ return makeState(PS_InRootName, TkStart + 1, RStart + 1);
+ }
+ TkStart = consumeName(SepEnd, REnd);
+ return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1);
+ }
+ case PS_InRootDir:
+ return makeState(PS_InRootName, Path.data(), RStart + 1);
+ case PS_InRootName:
+ case PS_BeforeBegin:
+ __libcpp_unreachable();
+ }
+ }
+
+ /// \brief Return a view with the "preferred representation" of the current
+ /// element. For example trailing separators are represented as a '.'
+ string_view_t operator*() const noexcept {
+ switch (State) {
+ case PS_BeforeBegin:
+ case PS_AtEnd:
+ return PATHSTR("");
+ case PS_InRootDir:
+ if (RawEntry[0] == '\\')
+ return PATHSTR("\\");
+ else
+ return PATHSTR("/");
+ case PS_InTrailingSep:
+ return PATHSTR("");
+ case PS_InRootName:
+ case PS_InFilenames:
+ return RawEntry;
+ }
+ __libcpp_unreachable();
+ }
+
+ explicit operator bool() const noexcept {
+ return State != PS_BeforeBegin && State != PS_AtEnd;
+ }
+
+ PathParser& operator++() noexcept {
+ increment();
+ return *this;
+ }
+
+ PathParser& operator--() noexcept {
+ decrement();
+ return *this;
+ }
+
+ bool atEnd() const noexcept {
+ return State == PS_AtEnd;
+ }
+
+ bool inRootDir() const noexcept {
+ return State == PS_InRootDir;
+ }
+
+ bool inRootName() const noexcept {
+ return State == PS_InRootName;
+ }
+
+ bool inRootPath() const noexcept {
+ return inRootName() || inRootDir();
+ }
+
+private:
+ void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept {
+ State = NewState;
+ RawEntry = string_view_t(Start, End - Start);
+ }
+ void makeState(ParserState NewState) noexcept {
+ State = NewState;
+ RawEntry = {};
+ }
+
+ PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); }
+
+ PosPtr getBeforeFront() const noexcept { return Path.data() - 1; }
+
+ /// \brief Return a pointer to the first character after the currently
+ /// lexed element.
+ PosPtr getNextTokenStartPos() const noexcept {
+ switch (State) {
+ case PS_BeforeBegin:
+ return Path.data();
+ case PS_InRootName:
+ case PS_InRootDir:
+ case PS_InFilenames:
+ return &RawEntry.back() + 1;
+ case PS_InTrailingSep:
+ case PS_AtEnd:
+ return getAfterBack();
+ }
+ __libcpp_unreachable();
+ }
+
+ /// \brief Return a pointer to the first character in the currently lexed
+ /// element.
+ PosPtr getCurrentTokenStartPos() const noexcept {
+ switch (State) {
+ case PS_BeforeBegin:
+ case PS_InRootName:
+ return &Path.front();
+ case PS_InRootDir:
+ case PS_InFilenames:
+ case PS_InTrailingSep:
+ return &RawEntry.front();
+ case PS_AtEnd:
+ return &Path.back() + 1;
+ }
+ __libcpp_unreachable();
+ }
+
+ // Consume all consecutive separators.
+ PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept {
+ if (P == nullptr || P == End || !isSeparator(*P))
+ return nullptr;
+ const int Inc = P < End ? 1 : -1;
+ P += Inc;
+ while (P != End && isSeparator(*P))
+ P += Inc;
+ return P;
+ }
+
+ // Consume exactly N separators, or return nullptr.
+ PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept {
+ PosPtr Ret = consumeAllSeparators(P, End);
+ if (Ret == nullptr)
+ return nullptr;
+ if (P < End) {
+ if (Ret == P + N)
+ return Ret;
+ } else {
+ if (Ret == P - N)
+ return Ret;
+ }
+ return nullptr;
+ }
+
+ PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
+ PosPtr Start = P;
+ if (P == nullptr || P == End || isSeparator(*P))
+ return nullptr;
+ const int Inc = P < End ? 1 : -1;
+ P += Inc;
+ while (P != End && !isSeparator(*P))
+ P += Inc;
+ if (P == End && Inc < 0) {
+ // Iterating backwards and consumed all the rest of the input.
+ // Check if the start of the string would have been considered
+ // a root name.
+ PosPtr RootEnd = consumeRootName(End + 1, Start);
+ if (RootEnd)
+ return RootEnd - 1;
+ }
+ return P;
+ }
+
+ PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept {
+ if (P == End)
+ return nullptr;
+ if (P < End) {
+ if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':')
+ return nullptr;
+ return P + 2;
+ } else {
+ if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':')
+ return nullptr;
+ return P - 2;
+ }
+ }
+
+ PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept {
+ if (P == End)
+ return nullptr;
+ if (P < End)
+ return consumeName(consumeNSeparators(P, End, 2), End);
+ else
+ return consumeNSeparators(consumeName(P, End), End, 2);
+ }
+
+#if defined(_LIBCPP_WIN32API)
+ PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept {
+ if (PosPtr Ret = consumeDriveLetter(P, End))
+ return Ret;
+ if (PosPtr Ret = consumeNetworkRoot(P, End))
+ return Ret;
+ return nullptr;
+ }
+#else
+ PosPtr consumeRootName(PosPtr /*P*/, PosPtr /*End*/) const noexcept {
+ return nullptr;
+ }
+#endif
+};
+
+inline string_view_pair separate_filename(string_view_t const& s) {
+ if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty())
+ return string_view_pair{s, PATHSTR("")};
+ auto pos = s.find_last_of('.');
+ if (pos == string_view_t::npos || pos == 0)
+ return string_view_pair{s, string_view_t{}};
+ return string_view_pair{s.substr(0, pos), s.substr(pos)};
+}
+
+inline string_view_t createView(PosPtr S, PosPtr E) noexcept {
+ return {S, static_cast<size_t>(E - S) + 1};
+}
+
+} // namespace parser
+
+_LIBCPP_END_NAMESPACE_FILESYSTEM
+
+#endif // PATH_PARSER_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h b/contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h
index 36116ec5a3..f11f41552e 100644
--- a/contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/posix_compat.h
@@ -24,9 +24,11 @@
#define POSIX_COMPAT_H
#include <__assert>
+#include <__config>
#include <filesystem>
-#include "filesystem_common.h"
+#include "error.h"
+#include "time_utils.h"
#if defined(_LIBCPP_WIN32API)
# define WIN32_LEAN_AND_MEAN
@@ -35,10 +37,13 @@
# include <io.h>
# include <winioctl.h>
#else
+# include <fcntl.h>
# include <unistd.h>
# include <sys/stat.h>
# include <sys/statvfs.h>
+# include <sys/time.h>
#endif
+#include <stdlib.h>
#include <time.h>
#if defined(_LIBCPP_WIN32API)
@@ -74,7 +79,6 @@ struct LIBCPP_REPARSE_DATA_BUFFER {
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail {
-namespace {
#if defined(_LIBCPP_WIN32API)
@@ -118,36 +122,7 @@ namespace {
#define O_NONBLOCK 0
-
-// There were 369 years and 89 leap days from the Windows epoch
-// (1601) to the Unix epoch (1970).
-#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60))
-
-TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
- TimeSpec ret;
- ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS;
- ret.tv_nsec = (li.QuadPart % 10000000) * 100;
- return ret;
-}
-
-TimeSpec filetime_to_timespec(FILETIME ft) {
- LARGE_INTEGER li;
- li.LowPart = ft.dwLowDateTime;
- li.HighPart = ft.dwHighDateTime;
- return filetime_to_timespec(li);
-}
-
-FILETIME timespec_to_filetime(TimeSpec ts) {
- LARGE_INTEGER li;
- li.QuadPart =
- ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
- FILETIME ft;
- ft.dwLowDateTime = li.LowPart;
- ft.dwHighDateTime = li.HighPart;
- return ft;
-}
-
-int set_errno(int e = GetLastError()) {
+inline int set_errno(int e = GetLastError()) {
errno = static_cast<int>(__win_err_to_errc(e));
return -1;
}
@@ -170,7 +145,7 @@ private:
HANDLE h;
};
-int stat_handle(HANDLE h, StatT *buf) {
+inline int stat_handle(HANDLE h, StatT *buf) {
FILE_BASIC_INFO basic;
if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
return set_errno();
@@ -208,7 +183,7 @@ int stat_handle(HANDLE h, StatT *buf) {
return 0;
}
-int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
+inline int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
WinHandle h(path, FILE_READ_ATTRIBUTES, flags);
if (!h)
return set_errno();
@@ -216,24 +191,26 @@ int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
return ret;
}
-int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }
+inline int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }
-int lstat(const wchar_t *path, StatT *buf) {
+inline int lstat(const wchar_t *path, StatT *buf) {
return stat_file(path, buf, FILE_FLAG_OPEN_REPARSE_POINT);
}
-int fstat(int fd, StatT *buf) {
+inline int fstat(int fd, StatT *buf) {
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
return stat_handle(h, buf);
}
-int mkdir(const wchar_t *path, int permissions) {
+inline int mkdir(const wchar_t *path, int permissions) {
(void)permissions;
- return _wmkdir(path);
+ if (!CreateDirectoryW(path, nullptr))
+ return set_errno();
+ return 0;
}
-int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
- bool is_dir) {
+inline int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
+ bool is_dir) {
path dest(oldname);
dest.make_preferred();
oldname = dest.c_str();
@@ -249,21 +226,21 @@ int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
return set_errno();
}
-int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
+inline int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
return symlink_file_dir(oldname, newname, false);
}
-int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
+inline int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
return symlink_file_dir(oldname, newname, true);
}
-int link(const wchar_t *oldname, const wchar_t *newname) {
+inline int link(const wchar_t *oldname, const wchar_t *newname) {
if (CreateHardLinkW(newname, oldname, nullptr))
return 0;
return set_errno();
}
-int remove(const wchar_t *path) {
+inline int remove(const wchar_t *path) {
detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT);
if (!h)
return set_errno();
@@ -274,7 +251,7 @@ int remove(const wchar_t *path) {
return 0;
}
-int truncate_handle(HANDLE h, off_t length) {
+inline int truncate_handle(HANDLE h, off_t length) {
LARGE_INTEGER size_param;
size_param.QuadPart = length;
if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN))
@@ -284,19 +261,19 @@ int truncate_handle(HANDLE h, off_t length) {
return 0;
}
-int ftruncate(int fd, off_t length) {
+inline int ftruncate(int fd, off_t length) {
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
return truncate_handle(h, length);
}
-int truncate(const wchar_t *path, off_t length) {
+inline int truncate(const wchar_t *path, off_t length) {
detail::WinHandle h(path, GENERIC_WRITE, 0);
if (!h)
return set_errno();
return truncate_handle(h, length);
}
-int rename(const wchar_t *from, const wchar_t *to) {
+inline int rename(const wchar_t *from, const wchar_t *to) {
if (!(MoveFileExW(from, to,
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING |
MOVEFILE_WRITE_THROUGH)))
@@ -304,11 +281,11 @@ int rename(const wchar_t *from, const wchar_t *to) {
return 0;
}
-template <class... Args> int open(const wchar_t *filename, Args... args) {
- return _wopen(filename, args...);
+inline int chdir(const wchar_t* path) {
+ if (!SetCurrentDirectoryW(path))
+ return set_errno();
+ return 0;
}
-int close(int fd) { return _close(fd); }
-int chdir(const wchar_t *path) { return _wchdir(path); }
struct StatVFS {
uint64_t f_frsize;
@@ -317,7 +294,7 @@ struct StatVFS {
uint64_t f_bavail;
};
-int statvfs(const wchar_t *p, StatVFS *buf) {
+inline int statvfs(const wchar_t *p, StatVFS *buf) {
path dir = p;
while (true) {
error_code local_ec;
@@ -343,11 +320,29 @@ int statvfs(const wchar_t *p, StatVFS *buf) {
return 0;
}
-wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); }
+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(in_buf == nullptr, "Windows getcwd() assumes in_buf==nullptr");
+ _LIBCPP_ASSERT(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);
+ DWORD retval = GetCurrentDirectoryW(buff_size, buff.get());
+ if (retval > buff_size) {
+ buff_size = retval;
+ buff.reset(static_cast<wchar_t*>(malloc(buff_size * sizeof(wchar_t))));
+ retval = GetCurrentDirectoryW(buff_size, buff.get());
+ }
+ if (!retval) {
+ set_errno();
+ return nullptr;
+ }
+ return buff.release();
+}
-wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
+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(resolved_name == nullptr,
+ _LIBCPP_ASSERT_UNCATEGORIZED(resolved_name == nullptr,
"Windows realpath() assumes a null resolved_name");
WinHandle h(path, FILE_READ_ATTRIBUTES, 0);
@@ -386,7 +381,7 @@ wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
#define AT_SYMLINK_NOFOLLOW 1
using ModeT = int;
-int fchmod_handle(HANDLE h, int perms) {
+inline int fchmod_handle(HANDLE h, int perms) {
FILE_BASIC_INFO basic;
if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
return set_errno();
@@ -400,7 +395,7 @@ int fchmod_handle(HANDLE h, int perms) {
return 0;
}
-int fchmodat(int fd, const wchar_t *path, int perms, int flag) {
+inline int fchmodat(int /*fd*/, const wchar_t *path, int perms, int flag) {
DWORD attributes = GetFileAttributesW(path);
if (attributes == INVALID_FILE_ATTRIBUTES)
return set_errno();
@@ -427,7 +422,7 @@ int fchmodat(int fd, const wchar_t *path, int perms, int flag) {
return 0;
}
-int fchmod(int fd, int perms) {
+inline int fchmod(int fd, int perms) {
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
return fchmod_handle(h, perms);
}
@@ -435,7 +430,7 @@ int fchmod(int fd, int perms) {
#define MAX_SYMLINK_SIZE MAXIMUM_REPARSE_DATA_BUFFER_SIZE
using SSizeT = ::int64_t;
-SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
+inline SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT);
if (!h)
@@ -479,14 +474,13 @@ SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
}
#else
-int symlink_file(const char *oldname, const char *newname) {
+inline int symlink_file(const char *oldname, const char *newname) {
return ::symlink(oldname, newname);
}
-int symlink_dir(const char *oldname, const char *newname) {
+inline int symlink_dir(const char *oldname, const char *newname) {
return ::symlink(oldname, newname);
}
using ::chdir;
-using ::close;
using ::fchmod;
#if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD)
using ::fchmodat;
@@ -497,7 +491,6 @@ using ::getcwd;
using ::link;
using ::lstat;
using ::mkdir;
-using ::open;
using ::readlink;
using ::realpath;
using ::remove;
@@ -514,7 +507,6 @@ using SSizeT = ::ssize_t;
#endif
-} // namespace
} // end namespace detail
_LIBCPP_END_NAMESPACE_FILESYSTEM
diff --git a/contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_common.h b/contrib/libs/cxxsupp/libcxx/src/filesystem/time_utils.h
index 0e71569d87..9177e1013d 100644
--- a/contrib/libs/cxxsupp/libcxx/src/filesystem/filesystem_common.h
+++ b/contrib/libs/cxxsupp/libcxx/src/filesystem/time_utils.h
@@ -6,54 +6,35 @@
//
//===----------------------------------------------------------------------===////
-#ifndef FILESYSTEM_COMMON_H
-#define FILESYSTEM_COMMON_H
+#ifndef FILESYSTEM_TIME_UTILS_H
+#define FILESYSTEM_TIME_UTILS_H
-#include <__assert>
#include <__config>
#include <array>
#include <chrono>
-#include <climits>
-#include <cstdarg>
-#include <ctime>
#include <filesystem>
+#include <limits>
#include <ratio>
#include <system_error>
+#include <type_traits>
#include <utility>
+#include "error.h"
+#include "format_string.h"
+
#if defined(_LIBCPP_WIN32API)
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include <windows.h>
#else
-# include <dirent.h> // for DIR & friends
-# include <fcntl.h> /* values for fchmodat */
+# include <fcntl.h>
# include <sys/stat.h>
-# include <sys/statvfs.h>
# include <sys/time.h> // for ::utimes as used in __last_write_time
-# include <unistd.h>
-#endif // defined(_LIBCPP_WIN32API)
-
-#include "../include/apple_availability.h"
-
-#if !defined(__APPLE__)
-// We can use the presence of UTIME_OMIT to detect platforms that provide
-// utimensat.
-#if defined(UTIME_OMIT)
-#define _LIBCPP_USE_UTIMENSAT
#endif
-#endif
-
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function")
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function")
-#if defined(_LIBCPP_WIN32API)
-# define PATHSTR(x) (L##x)
-# define PATH_CSTR_FMT "\"%ls\""
-#else
-# define PATHSTR(x) (x)
-# define PATH_CSTR_FMT "\"%s\""
+// We can use the presence of UTIME_OMIT to detect platforms that provide utimensat.
+#if defined(UTIME_OMIT)
+# define _LIBCPP_USE_UTIMENSAT
#endif
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
@@ -61,198 +42,11 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail {
#if defined(_LIBCPP_WIN32API)
-// Non anonymous, to allow access from two translation units.
-errc __win_err_to_errc(int err);
-#endif
-
-namespace {
-
-static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string
-format_string_impl(const char* msg, va_list ap) {
- array<char, 256> buf;
-
- va_list apcopy;
- va_copy(apcopy, ap);
- int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
- va_end(apcopy);
-
- string result;
- if (static_cast<size_t>(ret) < buf.size()) {
- result.assign(buf.data(), static_cast<size_t>(ret));
- } else {
- // we did not provide a long enough buffer on our first attempt. The
- // return value is the number of bytes (excluding the null byte) that are
- // needed for formatting.
- 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(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
- }
- return result;
-}
-
-static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string
-format_string(const char* msg, ...) {
- string ret;
- va_list ap;
- va_start(ap, msg);
-#ifndef _LIBCPP_NO_EXCEPTIONS
- try {
-#endif // _LIBCPP_NO_EXCEPTIONS
- ret = format_string_impl(msg, ap);
-#ifndef _LIBCPP_NO_EXCEPTIONS
- } catch (...) {
- va_end(ap);
- throw;
- }
-#endif // _LIBCPP_NO_EXCEPTIONS
- va_end(ap);
- return ret;
-}
-
-error_code capture_errno() {
- _LIBCPP_ASSERT(errno != 0, "Expected errno to be non-zero");
- return error_code(errno, generic_category());
-}
-
-#if defined(_LIBCPP_WIN32API)
-error_code make_windows_error(int err) {
- return make_error_code(__win_err_to_errc(err));
-}
-#endif
-
-template <class T>
-T error_value();
-template <>
-_LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {}
-template <>
-bool error_value<bool>() {
- return false;
-}
-#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__
-template <>
-size_t error_value<size_t>() {
- return size_t(-1);
-}
-#endif
-template <>
-uintmax_t error_value<uintmax_t>() {
- return uintmax_t(-1);
-}
-template <>
-_LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() {
- return file_time_type::min();
-}
-template <>
-path error_value<path>() {
- return {};
-}
-
-template <class T>
-struct ErrorHandler {
- const char* func_name_;
- error_code* ec_ = nullptr;
- const path* p1_ = nullptr;
- const path* p2_ = nullptr;
-
- ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr,
- const path* p2 = nullptr)
- : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) {
- if (ec_)
- ec_->clear();
- }
-
- T report(const error_code& ec) const {
- if (ec_) {
- *ec_ = ec;
- return error_value<T>();
- }
- string what = string("in ") + func_name_;
- switch (bool(p1_) + bool(p2_)) {
- case 0:
- __throw_filesystem_error(what, ec);
- case 1:
- __throw_filesystem_error(what, *p1_, ec);
- case 2:
- __throw_filesystem_error(what, *p1_, *p2_, ec);
- }
- __libcpp_unreachable();
- }
-
- _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0)
- void report_impl(const error_code& ec, const char* msg, va_list ap) const {
- if (ec_) {
- *ec_ = ec;
- return;
- }
- string what =
- string("in ") + func_name_ + ": " + format_string_impl(msg, ap);
- switch (bool(p1_) + bool(p2_)) {
- case 0:
- __throw_filesystem_error(what, ec);
- case 1:
- __throw_filesystem_error(what, *p1_, ec);
- case 2:
- __throw_filesystem_error(what, *p1_, *p2_, ec);
- }
- __libcpp_unreachable();
- }
-
- _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
- T report(const error_code& ec, const char* msg, ...) const {
- va_list ap;
- va_start(ap, msg);
-#ifndef _LIBCPP_NO_EXCEPTIONS
- try {
-#endif // _LIBCPP_NO_EXCEPTIONS
- report_impl(ec, msg, ap);
-#ifndef _LIBCPP_NO_EXCEPTIONS
- } catch (...) {
- va_end(ap);
- throw;
- }
-#endif // _LIBCPP_NO_EXCEPTIONS
- va_end(ap);
- return error_value<T>();
- }
-
- T report(errc const& err) const {
- return report(make_error_code(err));
- }
-
- _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
- T report(errc const& err, const char* msg, ...) const {
- va_list ap;
- va_start(ap, msg);
-#ifndef _LIBCPP_NO_EXCEPTIONS
- try {
-#endif // _LIBCPP_NO_EXCEPTIONS
- report_impl(make_error_code(err), msg, ap);
-#ifndef _LIBCPP_NO_EXCEPTIONS
- } catch (...) {
- va_end(ap);
- throw;
- }
-#endif // _LIBCPP_NO_EXCEPTIONS
- va_end(ap);
- return error_value<T>();
- }
-
-private:
- ErrorHandler(ErrorHandler const&) = delete;
- ErrorHandler& operator=(ErrorHandler const&) = delete;
-};
-
-using chrono::duration;
-using chrono::duration_cast;
-
-#if defined(_LIBCPP_WIN32API)
// Various C runtime versions (UCRT, or the legacy msvcrt.dll used by
// some mingw toolchains) provide different stat function implementations,
// with a number of limitations with respect to what we want from the
-// stat function. Instead provide our own (in the anonymous detail namespace
-// in posix_compat.h) which does exactly what we want, along with our own
-// stat structure and flag macros.
+// stat function. Instead provide our own which does exactly what we want,
+// along with our own stat structure and flag macros.
struct TimeSpec {
int64_t tv_sec;
@@ -276,12 +70,56 @@ struct StatT {
uintmax_t st_size;
};
+// There were 369 years and 89 leap days from the Windows epoch
+// (1601) to the Unix epoch (1970).
+#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60))
+
+inline TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
+ TimeSpec ret;
+ ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS;
+ ret.tv_nsec = (li.QuadPart % 10000000) * 100;
+ return ret;
+}
+
+inline TimeSpec filetime_to_timespec(FILETIME ft) {
+ LARGE_INTEGER li;
+ li.LowPart = ft.dwLowDateTime;
+ li.HighPart = ft.dwHighDateTime;
+ return filetime_to_timespec(li);
+}
+
+inline FILETIME timespec_to_filetime(TimeSpec ts) {
+ LARGE_INTEGER li;
+ li.QuadPart =
+ ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
+ FILETIME ft;
+ ft.dwLowDateTime = li.LowPart;
+ ft.dwHighDateTime = li.HighPart;
+ return ft;
+}
+
#else
using TimeSpec = struct timespec;
using TimeVal = struct timeval;
using StatT = struct stat;
+
+inline TimeVal make_timeval(TimeSpec const& ts) {
+ using namespace chrono;
+ auto Convert = [](long nsec) {
+ using int_type = decltype(std::declval<TimeVal>().tv_usec);
+ auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
+ return static_cast<int_type>(dur);
+ };
+ TimeVal TV = {};
+ TV.tv_sec = ts.tv_sec;
+ TV.tv_usec = Convert(ts.tv_nsec);
+ return TV;
+}
#endif
+using chrono::duration;
+using chrono::duration_cast;
+
template <class FileTimeT, class TimeT,
bool IsFloat = is_floating_point<typename FileTimeT::rep>::value>
struct time_util_base {
@@ -309,7 +147,7 @@ struct time_util_base {
.count();
private:
- static _LIBCPP_CONSTEXPR_SINCE_CXX14 fs_duration get_min_nsecs() {
+ static _LIBCPP_CONSTEXPR fs_duration get_min_nsecs() {
return duration_cast<fs_duration>(
fs_nanoseconds(min_nsec_timespec) -
duration_cast<fs_nanoseconds>(fs_seconds(1)));
@@ -329,7 +167,9 @@ private:
return max_seconds >= numeric_limits<TimeT>::max() &&
min_seconds <= numeric_limits<TimeT>::min();
}
+#if _LIBCPP_STD_VER >= 14
static_assert(check_range(), "the representable range is unacceptable small");
+#endif
};
template <class FileTimeT, class TimeT>
@@ -489,20 +329,9 @@ inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
#endif
-#if !defined(_LIBCPP_WIN32API)
-inline TimeVal make_timeval(TimeSpec const& ts) {
- using namespace chrono;
- auto Convert = [](long nsec) {
- using int_type = decltype(std::declval<TimeVal>().tv_usec);
- auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
- return static_cast<int_type>(dur);
- };
- TimeVal TV = {};
- TV.tv_sec = ts.tv_sec;
- TV.tv_usec = Convert(ts.tv_nsec);
- return TV;
-}
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM
+#if !defined(_LIBCPP_WIN32API)
inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
error_code& ec) {
TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])};
@@ -514,8 +343,8 @@ inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
}
#if defined(_LIBCPP_USE_UTIMENSAT)
-bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
- error_code& ec) {
+inline bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
+ error_code& ec) {
if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) {
ec = capture_errno();
return true;
@@ -524,8 +353,8 @@ bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
}
#endif
-bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
- error_code& ec) {
+inline bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
+ error_code& ec) {
#if !defined(_LIBCPP_USE_UTIMENSAT)
return posix_utimes(p, TS, ec);
#else
@@ -533,81 +362,24 @@ bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
#endif
}
-#if defined(DT_BLK)
-template <class DirEntT, class = decltype(DirEntT::d_type)>
-static file_type get_file_type(DirEntT* ent, int) {
- switch (ent->d_type) {
- case DT_BLK:
- return file_type::block;
- case DT_CHR:
- return file_type::character;
- case DT_DIR:
- return file_type::directory;
- case DT_FIFO:
- return file_type::fifo;
- case DT_LNK:
- return file_type::symlink;
- case DT_REG:
- return file_type::regular;
- case DT_SOCK:
- return file_type::socket;
- // Unlike in lstat, hitting "unknown" here simply means that the underlying
- // filesystem doesn't support d_type. Report is as 'none' so we correctly
- // set the cache to empty.
- case DT_UNKNOWN:
- break;
- }
- return file_type::none;
-}
-#endif // defined(DT_BLK)
+#endif // !_LIBCPP_WIN32API
-template <class DirEntT>
-static file_type get_file_type(DirEntT*, long) {
- return file_type::none;
-}
+inline file_time_type __extract_last_write_time(const path& p, const StatT& st,
+ error_code* ec) {
+ using detail::fs_time;
+ ErrorHandler<file_time_type> err("last_write_time", ec, &p);
-static pair<string_view, file_type> posix_readdir(DIR* dir_stream,
- error_code& ec) {
- struct dirent* dir_entry_ptr = nullptr;
- errno = 0; // zero errno in order to detect errors
- ec.clear();
- if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) {
- if (errno)
- ec = capture_errno();
- return {};
- } else {
- return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)};
- }
-}
-
-#else // _LIBCPP_WIN32API
+ auto ts = detail::extract_mtime(st);
+ if (!fs_time::is_representable(ts))
+ return err.report(errc::value_too_large);
-static file_type get_file_type(const WIN32_FIND_DATAW& data) {
- if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
- data.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
- return file_type::symlink;
- if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- return file_type::directory;
- return file_type::regular;
-}
-static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
- return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow;
-}
-static file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
- ULARGE_INTEGER tmp;
- const FILETIME& time = data.ftLastWriteTime;
- tmp.u.LowPart = time.dwLowDateTime;
- tmp.u.HighPart = time.dwHighDateTime;
- return file_time_type(file_time_type::duration(tmp.QuadPart));
+ return fs_time::convert_from_timespec(ts);
}
-#endif // !_LIBCPP_WIN32API
+#endif // !_LIBCPP_HAS_NO_FILESYSTEM
-} // namespace
} // end namespace detail
_LIBCPP_END_NAMESPACE_FILESYSTEM
-_LIBCPP_DIAGNOSTIC_POP
-
-#endif // FILESYSTEM_COMMON_H
+#endif // FILESYSTEM_TIME_UTILS_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/format.cpp b/contrib/libs/cxxsupp/libcxx/src/format.cpp
deleted file mode 100644
index 401cccf172..0000000000
--- a/contrib/libs/cxxsupp/libcxx/src/format.cpp
+++ /dev/null
@@ -1,17 +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
-//
-//===----------------------------------------------------------------------===//
-
-#include <format>
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR
-format_error::~format_error() noexcept = default;
-#endif
-
-_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/future.cpp b/contrib/libs/cxxsupp/libcxx/src/future.cpp
index cdaa938275..f8f466bd5a 100644
--- a/contrib/libs/cxxsupp/libcxx/src/future.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/future.cpp
@@ -197,12 +197,12 @@ promise<void>::~promise()
{
if (__state_)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
if (!__state_->__has_value() && __state_->use_count() > 1)
__state_->set_exception(make_exception_ptr(
future_error(make_error_code(future_errc::broken_promise))
));
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
__state_->__release_shared();
}
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/apple_availability.h b/contrib/libs/cxxsupp/libcxx/src/include/apple_availability.h
index 75bf79658d..c8d158e990 100644
--- a/contrib/libs/cxxsupp/libcxx/src/include/apple_availability.h
+++ b/contrib/libs/cxxsupp/libcxx/src/include/apple_availability.h
@@ -12,24 +12,6 @@
#if defined(__APPLE__)
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
-#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101300
-#define _LIBCPP_USE_UTIMENSAT
-#endif
-#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
-#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 110000
-#define _LIBCPP_USE_UTIMENSAT
-#endif
-#elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__)
-#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 110000
-#define _LIBCPP_USE_UTIMENSAT
-#endif
-#elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__)
-#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 40000
-#define _LIBCPP_USE_UTIMENSAT
-#endif
-#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__
-
-#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500
#define _LIBCPP_USE_ULOCK
#endif
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/config_elast.h b/contrib/libs/cxxsupp/libcxx/src/include/config_elast.h
index bef26ec501..a772ea7a01 100644
--- a/contrib/libs/cxxsupp/libcxx/src/include/config_elast.h
+++ b/contrib/libs/cxxsupp/libcxx/src/include/config_elast.h
@@ -35,8 +35,6 @@
#define _LIBCPP_ELAST 4095
#elif defined(__APPLE__)
// No _LIBCPP_ELAST needed on Apple
-#elif defined(__sun__)
-#define _LIBCPP_ELAST ESTALE
#elif defined(__MVS__)
#define _LIBCPP_ELAST 1160
#elif defined(_LIBCPP_MSVCRT_LIKE)
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/ryu/common.h b/contrib/libs/cxxsupp/libcxx/src/include/ryu/common.h
index c24115c233..23cb7d3b77 100644
--- a/contrib/libs/cxxsupp/libcxx/src/include/ryu/common.h
+++ b/contrib/libs/cxxsupp/libcxx/src/include/ryu/common.h
@@ -43,7 +43,8 @@
// clang-format off
#include <__assert>
-#include "__config"
+#include <__config>
+#include <cstring>
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -51,7 +52,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// Function precondition: __v is not a 10-digit number.
// (f2s: 9 digits are sufficient for round-tripping.)
// (d2fixed: We print 9-digit blocks.)
- _LIBCPP_ASSERT(__v < 1000000000, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__v < 1000000000, "");
if (__v >= 100000000) { return 9; }
if (__v >= 10000000) { return 8; }
if (__v >= 1000000) { return 7; }
@@ -68,36 +69,36 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// This approximation works up to the point that the multiplication overflows at __e = 3529.
// If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater
// than 2^9297.
- _LIBCPP_ASSERT(__e >= 0, "");
- _LIBCPP_ASSERT(__e <= 3528, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 3528, "");
return static_cast<int32_t>(((static_cast<uint32_t>(__e) * 1217359) >> 19) + 1);
}
// Returns floor(log_10(2^__e)).
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow2(const int32_t __e) {
// The first value this approximation fails for is 2^1651 which is just greater than 10^297.
- _LIBCPP_ASSERT(__e >= 0, "");
- _LIBCPP_ASSERT(__e <= 1650, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 1650, "");
return (static_cast<uint32_t>(__e) * 78913) >> 18;
}
// Returns floor(log_10(5^__e)).
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow5(const int32_t __e) {
// The first value this approximation fails for is 5^2621 which is just greater than 10^1832.
- _LIBCPP_ASSERT(__e >= 0, "");
- _LIBCPP_ASSERT(__e <= 2620, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 2620, "");
return (static_cast<uint32_t>(__e) * 732923) >> 20;
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __float_to_bits(const float __f) {
uint32_t __bits = 0;
- _VSTD::memcpy(&__bits, &__f, sizeof(float));
+ std::memcpy(&__bits, &__f, sizeof(float));
return __bits;
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __double_to_bits(const double __d) {
uint64_t __bits = 0;
- _VSTD::memcpy(&__bits, &__d, sizeof(double));
+ std::memcpy(&__bits, &__d, sizeof(double));
return __bits;
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/ryu/d2s_intrinsics.h b/contrib/libs/cxxsupp/libcxx/src/include/ryu/d2s_intrinsics.h
index 762763f9b9..7697c32ff6 100644
--- a/contrib/libs/cxxsupp/libcxx/src/include/ryu/d2s_intrinsics.h
+++ b/contrib/libs/cxxsupp/libcxx/src/include/ryu/d2s_intrinsics.h
@@ -63,7 +63,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// (The shift value is in the range [49, 58].)
// Check this here in case a future change requires larger shift
// values. In this case this function needs to be adjusted.
- _LIBCPP_ASSERT(__dist < 64, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
return __shiftright128(__lo, __hi, static_cast<unsigned char>(__dist));
}
@@ -85,7 +85,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// (The shift value is in the range [49, 58].)
// Check this here in case a future change requires larger shift
// values. In this case this function needs to be adjusted.
- _LIBCPP_ASSERT(__dist < 64, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
auto __temp = __lo | ((unsigned __int128)__hi << 64);
// For x64 128-bit shfits using the `shrd` instruction and two 64-bit
// registers, the shift value is modulo 64. Thus the `& 63` is free.
@@ -126,13 +126,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_shiftright128(const uint64_t __lo, const uint64_t __hi, const uint32_t __dist) {
// We don't need to handle the case __dist >= 64 here (see above).
- _LIBCPP_ASSERT(__dist < 64, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
#ifdef _LIBCPP_64_BIT
- _LIBCPP_ASSERT(__dist > 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__dist > 0, "");
return (__hi << (64 - __dist)) | (__lo >> __dist);
#else // ^^^ 64-bit ^^^ / vvv 32-bit vvv
// Avoid a 64-bit shift by taking advantage of the range of shift values.
- _LIBCPP_ASSERT(__dist >= 32, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__dist >= 32, "");
return (__hi << (64 - __dist)) | (static_cast<uint32_t>(__lo >> 32) >> (__dist - 32));
#endif // ^^^ 32-bit ^^^
}
@@ -227,7 +227,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint64_t __value) {
uint32_t __count = 0;
for (;;) {
- _LIBCPP_ASSERT(__value != 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
const uint64_t __q = __div5(__value);
const uint32_t __r = static_cast<uint32_t>(__value) - 5 * static_cast<uint32_t>(__q);
if (__r != 0) {
@@ -247,8 +247,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// Returns true if __value is divisible by 2^__p.
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint64_t __value, const uint32_t __p) {
- _LIBCPP_ASSERT(__value != 0, "");
- _LIBCPP_ASSERT(__p < 64, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__p < 64, "");
// __builtin_ctzll doesn't appear to be faster here.
return (__value & ((1ull << __p) - 1)) == 0;
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/include/ryu/ryu.h b/contrib/libs/cxxsupp/libcxx/src/include/ryu/ryu.h
index cb44bd3fef..3f4afa5d60 100644
--- a/contrib/libs/cxxsupp/libcxx/src/include/ryu/ryu.h
+++ b/contrib/libs/cxxsupp/libcxx/src/include/ryu/ryu.h
@@ -47,8 +47,7 @@
#include <__charconv/chars_format.h>
#include <__charconv/to_chars_result.h>
#include <__config>
-#include <__debug>
-#include <__errc>
+#include <__system_error/errc.h>
#include <cstdint>
#include <cstring>
#include <type_traits>
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 b99d790f65..e2409338b9 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(_Nibble < 3, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_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(_Number_of_bits_remaining >= 4, "");
- _LIBCPP_ASSERT(_Number_of_bits_remaining % 4 == 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_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(_Nibble < 16, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_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(_Number_of_bits_remaining >= 4, "");
- _LIBCPP_ASSERT(_Number_of_bits_remaining % 4 == 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_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(_Nibble < 16, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_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 = _VSTD::min(_Precision - (_Scientific_exponent_X + 1), _Max_fixed_precision);
const to_chars_result _Buf_result =
_Floating_to_chars_fixed_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision);
- _LIBCPP_ASSERT(_Buf_result.ec == errc{}, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
_Significand_last = _Buf_result.ptr;
} else {
_Effective_precision = _VSTD::min(_Precision - 1, _Max_scientific_precision);
const to_chars_result _Buf_result =
_Floating_to_chars_scientific_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision);
- _LIBCPP_ASSERT(_Buf_result.ec == errc{}, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, "");
_Significand_last = _VSTD::find(_Buffer, _Buf_result.ptr, 'e');
_Exponent_first = _Significand_last;
_Exponent_last = _Buf_result.ptr;
@@ -992,10 +992,10 @@ 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(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally
} else {
- _LIBCPP_ASSERT(_Fmt == chars_format::general || _Fmt == chars_format::scientific || _Fmt == chars_format::fixed
- || _Fmt == chars_format::hex,
+ _LIBCPP_ASSERT_UNCATEGORIZED(_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/ios.cpp b/contrib/libs/cxxsupp/libcxx/src/ios.cpp
index 870406b554..bb62eb9948 100644
--- a/contrib/libs/cxxsupp/libcxx/src/ios.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/ios.cpp
@@ -413,20 +413,20 @@ void
ios_base::__set_badbit_and_consider_rethrow()
{
__rdstate_ |= badbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
if (__exceptions_ & badbit)
throw;
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
void
ios_base::__set_failbit_and_consider_rethrow()
{
__rdstate_ |= failbit;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
if (__exceptions_ & failbit)
throw;
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
bool
diff --git a/contrib/libs/cxxsupp/libcxx/src/ios.instantiations.cpp b/contrib/libs/cxxsupp/libcxx/src/ios.instantiations.cpp
index ca77ce11fd..01fe199acb 100644
--- a/contrib/libs/cxxsupp/libcxx/src/ios.instantiations.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/ios.instantiations.cpp
@@ -37,7 +37,7 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream<char>
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istringstream<char>;
-#ifndef _LIBCPP_HAS_NO_FSTREAM
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf<char>;
diff --git a/contrib/libs/cxxsupp/libcxx/src/iostream.cpp b/contrib/libs/cxxsupp/libcxx/src/iostream.cpp
index 79dbd9a52b..b0686c9099 100644
--- a/contrib/libs/cxxsupp/libcxx/src/iostream.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/iostream.cpp
@@ -7,10 +7,14 @@
//===----------------------------------------------------------------------===//
#include <__locale>
-#include <__std_stream>
+#include "std_stream.h"
#include <new>
#include <string>
+#ifdef _LIBCPP_MSVCRT_LIKE
+# include <__locale_dir/locale_base_api/locale_guard.h>
+#endif
+
#define _str(s) #s
#define str(s) _str(s)
#define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)
@@ -19,9 +23,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
_ALIGNAS_TYPE (istream) char _cin [sizeof(istream)];
-_LIBCPP_FUNC_VIS istream& cin = *reinterpret_cast<istream*>(_cin);
+_LIBCPP_EXPORTED_FROM_ABI istream& cin = *reinterpret_cast<istream*>(_cin);
#else
-_ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)]
+_ALIGNAS_TYPE (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
@@ -33,9 +37,9 @@ 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)];
-_LIBCPP_FUNC_VIS wistream& wcin = *reinterpret_cast<wistream*>(_wcin);
+_LIBCPP_EXPORTED_FROM_ABI wistream& wcin = *reinterpret_cast<wistream*>(_wcin);
#else
-_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin[sizeof(wistream)]
+_ALIGNAS_TYPE (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
@@ -47,9 +51,9 @@ static mbstate_t mb_wcin;
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
_ALIGNAS_TYPE (ostream) char _cout[sizeof(ostream)];
-_LIBCPP_FUNC_VIS ostream& cout = *reinterpret_cast<ostream*>(_cout);
+_LIBCPP_EXPORTED_FROM_ABI ostream& cout = *reinterpret_cast<ostream*>(_cout);
#else
-_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)]
+_ALIGNAS_TYPE (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
@@ -61,9 +65,9 @@ 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)];
-_LIBCPP_FUNC_VIS wostream& wcout = *reinterpret_cast<wostream*>(_wcout);
+_LIBCPP_EXPORTED_FROM_ABI wostream& wcout = *reinterpret_cast<wostream*>(_wcout);
#else
-_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)]
+_ALIGNAS_TYPE (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
@@ -75,9 +79,9 @@ static mbstate_t mb_wcout;
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
_ALIGNAS_TYPE (ostream) char _cerr[sizeof(ostream)];
-_LIBCPP_FUNC_VIS ostream& cerr = *reinterpret_cast<ostream*>(_cerr);
+_LIBCPP_EXPORTED_FROM_ABI ostream& cerr = *reinterpret_cast<ostream*>(_cerr);
#else
-_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)]
+_ALIGNAS_TYPE (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
@@ -89,9 +93,9 @@ 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)];
-_LIBCPP_FUNC_VIS wostream& wcerr = *reinterpret_cast<wostream*>(_wcerr);
+_LIBCPP_EXPORTED_FROM_ABI wostream& wcerr = *reinterpret_cast<wostream*>(_wcerr);
#else
-_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)]
+_ALIGNAS_TYPE (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
@@ -103,9 +107,9 @@ static mbstate_t mb_wcerr;
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
_ALIGNAS_TYPE (ostream) char _clog[sizeof(ostream)];
-_LIBCPP_FUNC_VIS ostream& clog = *reinterpret_cast<ostream*>(_clog);
+_LIBCPP_EXPORTED_FROM_ABI ostream& clog = *reinterpret_cast<ostream*>(_clog);
#else
-_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)]
+_ALIGNAS_TYPE (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
@@ -115,9 +119,9 @@ __asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_tra
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(__clang__)
_ALIGNAS_TYPE (wostream) char _wclog[sizeof(wostream)];
-_LIBCPP_FUNC_VIS wostream& wclog = *reinterpret_cast<wostream*>(_wclog);
+_LIBCPP_EXPORTED_FROM_ABI wostream& wclog = *reinterpret_cast<wostream*>(_wclog);
#else
-_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)]
+_ALIGNAS_TYPE (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
diff --git a/contrib/libs/cxxsupp/libcxx/src/legacy_pointer_safety.cpp b/contrib/libs/cxxsupp/libcxx/src/legacy_pointer_safety.cpp
index 5d2b04c121..a9361ca879 100644
--- a/contrib/libs/cxxsupp/libcxx/src/legacy_pointer_safety.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/legacy_pointer_safety.cpp
@@ -15,9 +15,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-_LIBCPP_FUNC_VIS void declare_reachable(void*) {}
-_LIBCPP_FUNC_VIS void declare_no_pointers(char*, size_t) {}
-_LIBCPP_FUNC_VIS void undeclare_no_pointers(char*, size_t) {}
-_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* p) { return p; }
+_LIBCPP_EXPORTED_FROM_ABI void declare_reachable(void*) {}
+_LIBCPP_EXPORTED_FROM_ABI void declare_no_pointers(char*, size_t) {}
+_LIBCPP_EXPORTED_FROM_ABI void undeclare_no_pointers(char*, size_t) {}
+_LIBCPP_EXPORTED_FROM_ABI void* __undeclare_reachable(void* p) { return p; }
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/locale.cpp b/contrib/libs/cxxsupp/libcxx/src/locale.cpp
index c756c6fadf..e274ede995 100644
--- a/contrib/libs/cxxsupp/libcxx/src/locale.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/locale.cpp
@@ -6,13 +6,8 @@
//
//===----------------------------------------------------------------------===//
-// On Solaris, we need to define something to make the C99 parts of localeconv
-// visible.
-#ifdef __sun__
-#define _LCONV_C99
-#endif
-
#include <__utility/unreachable.h>
+#include <__verbose_abort>
#include <algorithm>
#include <clocale>
#include <codecvt>
@@ -118,16 +113,27 @@ countof(const T * const begin, const T * const end)
_LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
throw runtime_error(msg);
#else
- (void)msg;
- _VSTD::abort();
+ _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg.c_str());
#endif
}
}
+string
+build_name(const string& other, const string& one, locale::category c) {
+ if (other == "*" || one == "*")
+ return "*";
+ if (c == locale::none || other == one)
+ return other;
+
+ // FIXME: Handle the more complicated cases, such as when the locale has
+ // different names for different categories.
+ return "*";
+}
+
const locale::category locale::none;
const locale::category locale::collate;
const locale::category locale::ctype;
@@ -236,10 +242,10 @@ locale::__imp::__imp(const string& name, size_t refs)
facets_(N),
name_(name)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
facets_ = locale::classic().__locale_->facets_;
for (unsigned i = 0; i < facets_.size(); ++i)
if (facets_[i])
@@ -286,7 +292,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
install(new messages_byname<wchar_t>(name_));
#endif
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
@@ -295,7 +301,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
facets_[i]->__release_shared();
throw;
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
locale::__imp::__imp(const __imp& other)
@@ -309,17 +315,16 @@ locale::__imp::__imp(const __imp& other)
}
locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
- : facets_(N),
- name_("*")
+ : facets_(N), name_(build_name(other.name_, name, c))
{
facets_ = other.facets_;
for (unsigned i = 0; i < facets_.size(); ++i)
if (facets_[i])
facets_[i]->__add_shared();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
if (c & locale::collate)
{
install(new collate_byname<char>(name));
@@ -380,7 +385,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
install(new messages_byname<wchar_t>(name));
#endif
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
@@ -389,7 +394,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
facets_[i]->__release_shared();
throw;
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
template<class F>
@@ -402,17 +407,16 @@ locale::__imp::install_from(const locale::__imp& one)
}
locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
- : facets_(N),
- name_("*")
+ : facets_(N), name_(build_name(other.name_, one.name_, c))
{
facets_ = other.facets_;
for (unsigned i = 0; i < facets_.size(); ++i)
if (facets_[i])
facets_[i]->__add_shared();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
if (c & locale::collate)
{
install_from<_VSTD::collate<char> >(one);
@@ -489,7 +493,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
install_from<_VSTD::messages<wchar_t> >(one);
#endif
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
@@ -498,7 +502,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
facets_[i]->__release_shared();
throw;
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
locale::__imp::__imp(const __imp& other, facet* f, long id)
@@ -1197,8 +1201,6 @@ ctype<char>::classic_table() noexcept
return _C_ctype_tab_ + 1;
#elif defined(__GLIBC__)
return _LIBCPP_GET_C_LOCALE->__ctype_b;
-#elif defined(__sun__)
- return __ctype_mask;
#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
return __pctype_func();
#elif defined(__EMSCRIPTEN__)
@@ -1421,10 +1423,8 @@ ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask*
if (iswxdigit_l(ch, __l_))
*vec |= xdigit;
#endif
-#if !defined(__sun__)
if (iswblank_l(ch, __l_))
*vec |= blank;
-#endif
}
}
return low;
@@ -6556,11 +6556,10 @@ void __do_nothing(void*) {}
void __throw_runtime_error(const char* msg)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
throw runtime_error(msg);
#else
- (void)msg;
- _VSTD::abort();
+ _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg);
#endif
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/memory.cpp b/contrib/libs/cxxsupp/libcxx/src/memory.cpp
index 9c0ee5d6f3..4682f1267a 100644
--- a/contrib/libs/cxxsupp/libcxx/src/memory.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/memory.cpp
@@ -29,8 +29,6 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-const allocator_arg_t allocator_arg = allocator_arg_t();
-
bad_weak_ptr::~bad_weak_ptr() noexcept {}
const char*
diff --git a/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp b/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp
index e00611dd1c..3a80b84efa 100644
--- a/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/memory_resource.cpp
@@ -37,7 +37,7 @@ static bool is_aligned_to(void* ptr, size_t align) {
}
#endif
-class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp : public memory_resource {
+class _LIBCPP_EXPORTED_FROM_ABI __new_delete_memory_resource_imp : public memory_resource {
void* do_allocate(size_t bytes, size_t align) override {
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
return std::__libcpp_allocate(bytes, align);
@@ -60,7 +60,7 @@ class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp : public memory_resource
// null_memory_resource()
-class _LIBCPP_TYPE_VIS __null_memory_resource_imp : public memory_resource {
+class _LIBCPP_EXPORTED_FROM_ABI __null_memory_resource_imp : public memory_resource {
void* do_allocate(size_t, size_t) override { __throw_bad_alloc(); }
void do_deallocate(void*, size_t, size_t) override {}
bool do_is_equal(const memory_resource& other) const noexcept override { return &other == this; }
@@ -107,7 +107,7 @@ static memory_resource* __default_memory_resource(bool set = false, memory_resou
new_res = new_res ? new_res : new_delete_resource();
lock_guard<mutex> guard(res_lock);
memory_resource* old_res = res;
- res = new_res;
+ res = new_res;
return old_res;
} else {
lock_guard<mutex> guard(res_lock);
@@ -175,7 +175,7 @@ void* unsynchronized_pool_resource::__adhoc_pool::__do_allocate(memory_resource*
void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate(
memory_resource* upstream, void* p, size_t bytes, size_t align) {
- _LIBCPP_ASSERT(__first_ != nullptr, "deallocating a block that was not allocated with this allocator");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != nullptr, "deallocating a block that was not allocated with this allocator");
if (__first_->__start_ == p) {
__chunk_footer* next = __first_->__next_;
upstream->deallocate(p, __first_->__allocation_size(), __first_->__align_);
@@ -189,7 +189,7 @@ void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate(
return;
}
}
- _LIBCPP_ASSERT(false, "deallocating a block that was not allocated with this allocator");
+ _LIBCPP_ASSERT_UNCATEGORIZED(false, "deallocating a block that was not allocated with this allocator");
}
}
@@ -230,7 +230,7 @@ public:
}
void* __allocate_in_new_chunk(memory_resource* upstream, size_t block_size, size_t chunk_size) {
- _LIBCPP_ASSERT(chunk_size % block_size == 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(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), "");
@@ -401,7 +401,8 @@ void unsynchronized_pool_resource::do_deallocate(void* p, size_t bytes, size_t a
if (i == __num_fixed_pools_)
return __adhoc_pool_.__do_deallocate(__res_, p, bytes, align);
else {
- _LIBCPP_ASSERT(__fixed_pools_ != nullptr, "deallocating a block that was not allocated with this allocator");
+ _LIBCPP_ASSERT_UNCATEGORIZED(
+ __fixed_pools_ != nullptr, "deallocating a block that was not allocated with this allocator");
__fixed_pools_[i].__evacuate(p);
}
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/mutex.cpp b/contrib/libs/cxxsupp/libcxx/src/mutex.cpp
index f738cc013b..e304b97e6e 100644
--- a/contrib/libs/cxxsupp/libcxx/src/mutex.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/mutex.cpp
@@ -7,9 +7,9 @@
//===----------------------------------------------------------------------===//
#include <__assert>
+#include <__thread/id.h>
#include <limits>
#include <mutex>
-#include <system_error>
#if !defined(_LIBCPP_ABI_MICROSOFT)
#include "include/atomic_support.h"
@@ -28,10 +28,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_HAS_NO_THREADS
-const defer_lock_t defer_lock{};
-const try_to_lock_t try_to_lock{};
-const adopt_lock_t adopt_lock{};
-
// ~mutex is defined elsewhere
void
@@ -53,7 +49,7 @@ mutex::unlock() noexcept
{
int ec = __libcpp_mutex_unlock(&__m_);
(void)ec;
- _LIBCPP_ASSERT(ec == 0, "call to mutex::unlock failed");
+ _LIBCPP_ASSERT_UNCATEGORIZED(ec == 0, "call to mutex::unlock failed");
}
// recursive_mutex
@@ -69,7 +65,7 @@ recursive_mutex::~recursive_mutex()
{
int e = __libcpp_recursive_mutex_destroy(&__m_);
(void)e;
- _LIBCPP_ASSERT(e == 0, "call to ~recursive_mutex() failed");
+ _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to ~recursive_mutex() failed");
}
void
@@ -85,7 +81,7 @@ recursive_mutex::unlock() noexcept
{
int e = __libcpp_recursive_mutex_unlock(&__m_);
(void)e;
- _LIBCPP_ASSERT(e == 0, "call to recursive_mutex::unlock() failed");
+ _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to recursive_mutex::unlock() failed");
}
bool
@@ -218,21 +214,21 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
#if defined(_LIBCPP_HAS_NO_THREADS)
if (flag == 0)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
flag = 1;
func(arg);
flag = ~once_flag::_State_type(0);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
flag = 0;
throw;
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
#else // !_LIBCPP_HAS_NO_THREADS
__libcpp_mutex_lock(&mut);
@@ -240,10 +236,10 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
__libcpp_condvar_wait(&cv, &mut);
if (flag == 0)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
#ifdef _LIBCPP_ABI_MICROSOFT
flag.store(once_flag::_State_type(1));
#else
@@ -260,7 +256,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
#endif
__libcpp_mutex_unlock(&mut);
__libcpp_condvar_broadcast(&cv);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
@@ -274,7 +270,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
__libcpp_condvar_broadcast(&cv);
throw;
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
else
__libcpp_mutex_unlock(&mut);
diff --git a/contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp b/contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp
index 6850b6e6f4..d366a4e1b3 100644
--- a/contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/mutex_destructor.cpp
@@ -28,7 +28,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#ifdef NEEDS_MUTEX_DESTRUCTOR
-class _LIBCPP_TYPE_VIS mutex
+class _LIBCPP_EXPORTED_FROM_ABI mutex
{
__libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
diff --git a/contrib/libs/cxxsupp/libcxx/src/new.cpp b/contrib/libs/cxxsupp/libcxx/src/new.cpp
index 4351923cb5..6d5b221198 100644
--- a/contrib/libs/cxxsupp/libcxx/src/new.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/new.cpp
@@ -6,53 +6,16 @@
//
//===----------------------------------------------------------------------===//
+#include <__memory/aligned_alloc.h>
+#include <cstdlib>
#include <new>
-#include <stdlib.h>
-#include "include/atomic_support.h"
+#if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME)
-#if defined(_LIBCPP_ABI_MICROSOFT)
-# if !defined(_LIBCPP_ABI_VCRUNTIME)
-# include "support/runtime/new_handler_fallback.ipp"
-# endif
-#elif defined(LIBCXX_BUILDING_LIBCXXABI)
-# include <cxxabi.h>
-#elif defined(LIBCXX_BUILDING_LIBCXXRT)
-# include <cxxabi.h>
-# include "support/runtime/new_handler_fallback.ipp"
-#elif defined(__GLIBCXX__)
- // nothing to do
-#else
-# include "support/runtime/new_handler_fallback.ipp"
-#endif
-
-namespace std
-{
-
-#ifndef __GLIBCXX__
-const nothrow_t nothrow{};
-#endif
-
-#ifndef LIBSTDCXX
-
-void
-__throw_bad_alloc()
-{
-#ifndef _LIBCPP_NO_EXCEPTIONS
- throw bad_alloc();
-#else
- _VSTD::abort();
-#endif
-}
-
-#endif // !LIBSTDCXX
-
-} // std
-
-#if !defined(__GLIBCXX__) && \
- !defined(_LIBCPP_ABI_VCRUNTIME) && \
- !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
+// 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.
+// ------------------ 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.
@@ -64,7 +27,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
if (size == 0)
size = 1;
void* p;
- while ((p = ::malloc(size)) == nullptr)
+ while ((p = std::malloc(size)) == nullptr)
{
// If malloc fails and there is a new_handler,
// call it to try free up memory.
@@ -72,7 +35,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
if (nh)
nh();
else
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
throw std::bad_alloc();
#else
#ifdef __EMSCRIPTEN__
@@ -95,17 +58,17 @@ void*
operator new(size_t size, const std::nothrow_t&) noexcept
{
void* p = nullptr;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
p = ::operator new(size);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
return p;
}
@@ -121,17 +84,17 @@ void*
operator new[](size_t size, const std::nothrow_t&) noexcept
{
void* p = nullptr;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
p = ::operator new[](size);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
return p;
}
@@ -139,7 +102,7 @@ _LIBCPP_WEAK
void
operator delete(void* ptr) noexcept
{
- ::free(ptr);
+ std::free(ptr);
}
_LIBCPP_WEAK
@@ -201,7 +164,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
if (nh)
nh();
else {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
throw std::bad_alloc();
#else
break;
@@ -216,17 +179,17 @@ void*
operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
{
void* p = nullptr;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
p = ::operator new(size, alignment);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
return p;
}
@@ -242,17 +205,17 @@ void*
operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
{
void* p = nullptr;
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
p = ::operator new[](size, alignment);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
return p;
}
@@ -299,4 +262,6 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
}
#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
-#endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS
+// ------------------ END COPY ------------------
+
+#endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME
diff --git a/contrib/libs/cxxsupp/libcxx/src/new_handler.cpp b/contrib/libs/cxxsupp/libcxx/src/new_handler.cpp
new file mode 100644
index 0000000000..49c21d85f5
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/new_handler.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <new>
+
+#include "include/atomic_support.h"
+
+#if defined(_LIBCPP_ABI_MICROSOFT)
+# if !defined(_LIBCPP_ABI_VCRUNTIME)
+# define _LIBPCPP_DEFINE_NEW_HANDLER
+# endif
+#elif defined(LIBCXX_BUILDING_LIBCXXABI)
+// nothing to do, we use the one from libc++abi
+#elif defined(LIBCXXRT)
+# define _LIBPCPP_DEFINE_NEW_HANDLER
+#elif defined(__GLIBCXX__)
+// nothing to do, we use the one from libstdc++/libsupc++
+#else
+# define _LIBPCPP_DEFINE_NEW_HANDLER
+#endif
+
+#if defined(_LIBPCPP_DEFINE_NEW_HANDLER)
+
+namespace std { // purposefully not versioned
+
+static constinit std::new_handler __new_handler = nullptr;
+
+new_handler set_new_handler(new_handler handler) noexcept { return __libcpp_atomic_exchange(&__new_handler, handler); }
+
+new_handler get_new_handler() noexcept { return __libcpp_atomic_load(&__new_handler); }
+
+} // namespace std
+
+#endif // _LIBPCPP_DEFINE_NEW_HANDLER
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/runtime/new_handler_fallback.ipp b/contrib/libs/cxxsupp/libcxx/src/new_helpers.cpp
index 2ec408327d..45a0a661db 100644
--- a/contrib/libs/cxxsupp/libcxx/src/support/runtime/new_handler_fallback.ipp
+++ b/contrib/libs/cxxsupp/libcxx/src/new_helpers.cpp
@@ -1,4 +1,3 @@
-// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -7,20 +6,25 @@
//
//===----------------------------------------------------------------------===//
-namespace std {
+#include <cstdlib>
+#include <new>
-static constinit std::new_handler __new_handler = nullptr;
+namespace std { // purposefully not versioned
-new_handler
-set_new_handler(new_handler handler) noexcept
-{
- return __libcpp_atomic_exchange(&__new_handler, handler);
-}
+#ifndef __GLIBCXX__
+const nothrow_t nothrow{};
+#endif
+
+#ifndef LIBSTDCXX
-new_handler
-get_new_handler() noexcept
-{
- return __libcpp_atomic_load(&__new_handler);
+void __throw_bad_alloc() {
+# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ throw bad_alloc();
+# else
+ std::abort();
+# endif
}
+#endif // !LIBSTDCXX
+
} // namespace std
diff --git a/contrib/libs/cxxsupp/libcxx/src/optional.cpp b/contrib/libs/cxxsupp/libcxx/src/optional.cpp
index e2b5ccef99..d0214981a2 100644
--- a/contrib/libs/cxxsupp/libcxx/src/optional.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/optional.cpp
@@ -27,7 +27,7 @@ const char* bad_optional_access::what() const noexcept {
// Even though it no longer exists in a header file
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
-class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
+class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
: public std::logic_error
{
public:
diff --git a/contrib/libs/cxxsupp/libcxx/src/print.cpp b/contrib/libs/cxxsupp/libcxx/src/print.cpp
new file mode 100644
index 0000000000..3d8a4c291e
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/print.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <cstdlib>
+#include <print>
+
+#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"
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifdef _WIN32
+_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.
+ //
+ // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170
+ // https://learn.microsoft.com/en-us/windows/console/getconsolemode
+ intptr_t __handle = _get_osfhandle(fileno(__stream));
+ if (__handle == -1)
+ return false;
+
+ unsigned long __mode;
+ return GetConsoleMode(reinterpret_cast<void*>(__handle), &__mode);
+}
+
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+_LIBCPP_EXPORTED_FROM_ABI void
+__write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wstring_view __view) {
+ // https://learn.microsoft.com/en-us/windows/console/writeconsole
+ if (WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fileno(__stream))), // clang-format aid
+ __view.data(),
+ __view.size(),
+ nullptr,
+ nullptr) == 0) {
+# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+ // There is no __throw_system_error overload that takes an error code.
+ throw system_error{filesystem::detail::make_windows_error(GetLastError()), "failed to write formatted output"};
+# else // _LIBCPP_HAS_NO_EXCEPTIONS
+ std::abort();
+# endif // _LIBCPP_HAS_NO_EXCEPTIONS
+ }
+}
+# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+#endif // _WIN32
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/random.cpp b/contrib/libs/cxxsupp/libcxx/src/random.cpp
index 38732462cf..dfac89f75b 100644
--- a/contrib/libs/cxxsupp/libcxx/src/random.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/random.cpp
@@ -13,13 +13,9 @@
# define _CRT_RAND_S
#endif // defined(_LIBCPP_USING_WIN32_RANDOM)
+#include <__system_error/system_error.h>
#include <limits>
#include <random>
-#include <system_error>
-
-#if defined(__sun__)
-# define rename solaris_headers_are_broken
-#endif // defined(__sun__)
#include <errno.h>
#include <stdio.h>
diff --git a/contrib/libs/cxxsupp/libcxx/src/ryu/d2fixed.cpp b/contrib/libs/cxxsupp/libcxx/src/ryu/d2fixed.cpp
index c1a1f6cf9e..3ae515d1dc 100644
--- a/contrib/libs/cxxsupp/libcxx/src/ryu/d2fixed.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/ryu/d2fixed.cpp
@@ -43,7 +43,6 @@
#include <__config>
#include <charconv>
#include <cstring>
-#include <system_error>
#include "include/ryu/common.h"
#include "include/ryu/d2fixed.h"
@@ -103,8 +102,8 @@ inline constexpr int __POW10_ADDITIONAL_BITS = 120;
const uint64_t __s1low = __low2 + __high1 + __c1; // 128
const uint32_t __c2 = __s1low < __low2; // __high1 + __c1 can't overflow, so compare against __low2
const uint64_t __s1high = __high2 + __c2; // 192
- _LIBCPP_ASSERT(__j >= 128, "");
- _LIBCPP_ASSERT(__j <= 180, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__j >= 128, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__j <= 180, "");
#ifdef _LIBCPP_INTRINSIC128
const uint32_t __dist = static_cast<uint32_t>(__j - 128); // __dist: [0, 52]
const uint64_t __shiftedhigh = __s1high >> __dist;
@@ -135,19 +134,19 @@ void __append_n_digits(const uint32_t __olength, uint32_t __digits, char* const
__digits /= 10000;
const uint32_t __c0 = (__c % 100) << 1;
const uint32_t __c1 = (__c / 100) << 1;
- _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
- _VSTD::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
+ std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2);
+ std::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2);
__i += 4;
}
if (__digits >= 100) {
const uint32_t __c = (__digits % 100) << 1;
__digits /= 100;
- _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
+ std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
__i += 2;
}
if (__digits >= 10) {
const uint32_t __c = __digits << 1;
- _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
+ std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2);
} else {
__result[0] = static_cast<char>('0' + __digits);
}
@@ -164,14 +163,14 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_d_digits(const uint32_t __olength, ui
__digits /= 10000;
const uint32_t __c0 = (__c % 100) << 1;
const uint32_t __c1 = (__c / 100) << 1;
- _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
- _VSTD::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
+ std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2);
+ std::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2);
__i += 4;
}
if (__digits >= 100) {
const uint32_t __c = (__digits % 100) << 1;
__digits /= 100;
- _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
+ std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2);
__i += 2;
}
if (__digits >= 10) {
@@ -190,7 +189,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint
for (; __i < __count - 1; __i += 2) {
const uint32_t __c = (__digits % 100) << 1;
__digits /= 100;
- _VSTD::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
+ std::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2);
}
if (__i < __count) {
const char __c = static_cast<char>('0' + (__digits % 10));
@@ -200,7 +199,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint
void __append_nine_digits(uint32_t __digits, char* const __result) {
if (__digits == 0) {
- _VSTD::memset(__result, '0', 9);
+ std::memset(__result, '0', 9);
return;
}
@@ -213,8 +212,8 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
__digits /= 10000;
const uint32_t __c0 = (__c % 100) << 1;
const uint32_t __c1 = (__c / 100) << 1;
- _VSTD::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
- _VSTD::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
+ std::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2);
+ std::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2);
}
__result[0] = static_cast<char>('0' + __digits);
}
@@ -251,7 +250,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
*_First++ = '0';
if (__precision > 0) {
*_First++ = '.';
- _VSTD::memset(_First, '0', __precision);
+ std::memset(_First, '0', __precision);
_First += __precision;
}
return { _First, errc{} };
@@ -322,14 +321,14 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
return { _Last, errc::value_too_large };
}
- _VSTD::memset(_First, '0', __precision);
+ std::memset(_First, '0', __precision);
_First += __precision;
} else if (__i < __MIN_BLOCK_2[__idx]) {
__i = __MIN_BLOCK_2[__idx];
if (_Last - _First < static_cast<ptrdiff_t>(9 * __i)) {
return { _Last, errc::value_too_large };
}
- _VSTD::memset(_First, '0', 9 * __i);
+ std::memset(_First, '0', 9 * __i);
_First += 9 * __i;
}
for (; __i < __blocks; ++__i) {
@@ -342,7 +341,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
if (_Last - _First < static_cast<ptrdiff_t>(__fill)) {
return { _Last, errc::value_too_large };
}
- _VSTD::memset(_First, '0', __fill);
+ std::memset(_First, '0', __fill);
_First += __fill;
break;
}
@@ -416,7 +415,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
if (_Last - _First < static_cast<ptrdiff_t>(__precision)) {
return { _Last, errc::value_too_large };
}
- _VSTD::memset(_First, '0', __precision);
+ std::memset(_First, '0', __precision);
_First += __precision;
}
return { _First, errc{} };
@@ -440,10 +439,10 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
*_First++ = '0';
if (__precision > 0) {
*_First++ = '.';
- _VSTD::memset(_First, '0', __precision);
+ std::memset(_First, '0', __precision);
_First += __precision;
}
- _VSTD::memcpy(_First, "e+00", 4);
+ std::memcpy(_First, "e+00", 4);
_First += 4;
return { _First, errc{} };
}
@@ -589,7 +588,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
return { _Last, errc::value_too_large };
}
if (__digits == 0) {
- _VSTD::memset(_First, '0', __maximum);
+ std::memset(_First, '0', __maximum);
} else {
__append_c_digits(__maximum, __digits, _First);
}
@@ -654,11 +653,11 @@ void __append_nine_digits(uint32_t __digits, char* const __result) {
if (__exp >= 100) {
const int32_t __c = __exp % 10;
- _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
+ std::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2);
_First[2] = static_cast<char>('0' + __c);
_First += 3;
} else {
- _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
+ std::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2);
_First += 2;
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/ryu/d2s.cpp b/contrib/libs/cxxsupp/libcxx/src/ryu/d2s.cpp
index 245c2eb590..86d0b61848 100644
--- a/contrib/libs/cxxsupp/libcxx/src/ryu/d2s.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/ryu/d2s.cpp
@@ -154,7 +154,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// The average output length is 16.38 digits, so we check high-to-low.
// Function precondition: __v is not an 18, 19, or 20-digit number.
// (17 digits are sufficient for round-tripping.)
- _LIBCPP_ASSERT(__v < 100000000000000000u, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__v < 100000000000000000u, "");
if (__v >= 10000000000000000u) { return 17; }
if (__v >= 1000000000000000u) { return 16; }
if (__v >= 100000000000000u) { return 15; }
@@ -527,10 +527,10 @@ struct __floating_decimal_64 {
const uint32_t __d0 = (__d % 100) << 1;
const uint32_t __d1 = (__d / 100) << 1;
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2);
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2);
}
uint32_t __output2 = static_cast<uint32_t>(_Output);
while (__output2 >= 10000) {
@@ -542,35 +542,35 @@ struct __floating_decimal_64 {
__output2 /= 10000;
const uint32_t __c0 = (__c % 100) << 1;
const uint32_t __c1 = (__c / 100) << 1;
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
}
if (__output2 >= 100) {
const uint32_t __c = (__output2 % 100) << 1;
__output2 /= 100;
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
}
if (__output2 >= 10) {
const uint32_t __c = __output2 << 1;
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
} else {
*--_Mid = static_cast<char>('0' + __output2);
}
if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu
// Performance note: it might be more efficient to do this immediately after setting _Mid.
- _VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
+ std::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
} else if (_Ryu_exponent == 0) { // case "1729"
// Done!
} else if (_Whole_digits > 0) { // case "17.29"
// Performance note: moving digits might not be optimal.
- _VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
+ std::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
_First[_Whole_digits] = '.';
} else { // case "0.001729"
// Performance note: a larger memset() followed by overwriting '.' might be more efficient.
_First[0] = '0';
_First[1] = '.';
- _VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
+ std::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
}
return { _First + _Total_fixed_length, errc{} };
@@ -602,10 +602,10 @@ struct __floating_decimal_64 {
const uint32_t __c1 = (__c / 100) << 1;
const uint32_t __d0 = (__d % 100) << 1;
const uint32_t __d1 = (__d / 100) << 1;
- _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
- _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
- _VSTD::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2);
- _VSTD::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2);
+ std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
+ std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
+ std::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2);
+ std::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2);
__i += 8;
}
uint32_t __output2 = static_cast<uint32_t>(_Output);
@@ -618,14 +618,14 @@ struct __floating_decimal_64 {
__output2 /= 10000;
const uint32_t __c0 = (__c % 100) << 1;
const uint32_t __c1 = (__c / 100) << 1;
- _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
- _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
+ std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
+ std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
__i += 4;
}
if (__output2 >= 100) {
const uint32_t __c = (__output2 % 100) << 1;
__output2 /= 100;
- _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
+ std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
__i += 2;
}
if (__output2 >= 10) {
@@ -657,11 +657,11 @@ struct __floating_decimal_64 {
if (_Scientific_exponent >= 100) {
const int32_t __c = _Scientific_exponent % 10;
- _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2);
+ std::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2);
__result[__index + 2] = static_cast<char>('0' + __c);
__index += 3;
} else {
- _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
+ std::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
__index += 2;
}
@@ -713,7 +713,7 @@ struct __floating_decimal_64 {
return { _Last, errc::value_too_large };
}
- _VSTD::memcpy(_First, "0e+00", 5);
+ std::memcpy(_First, "0e+00", 5);
return { _First + 5, errc{} };
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/ryu/f2s.cpp b/contrib/libs/cxxsupp/libcxx/src/ryu/f2s.cpp
index 3bcfe462c8..7470dc63d7 100644
--- a/contrib/libs/cxxsupp/libcxx/src/ryu/f2s.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/ryu/f2s.cpp
@@ -86,7 +86,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint32_t __value) {
uint32_t __count = 0;
for (;;) {
- _LIBCPP_ASSERT(__value != 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
const uint32_t __q = __value / 5;
const uint32_t __r = __value % 5;
if (__r != 0) {
@@ -105,14 +105,14 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
// Returns true if __value is divisible by 2^__p.
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint32_t __value, const uint32_t __p) {
- _LIBCPP_ASSERT(__value != 0, "");
- _LIBCPP_ASSERT(__p < 32, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__p < 32, "");
// __builtin_ctz doesn't appear to be faster here.
return (__value & ((1u << __p) - 1)) == 0;
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift(const uint32_t __m, const uint64_t __factor, const int32_t __shift) {
- _LIBCPP_ASSERT(__shift > 32, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__shift > 32, "");
// The casts here help MSVC to avoid calls to the __allmul library
// function.
@@ -134,7 +134,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
#else // ^^^ 32-bit ^^^ / vvv 64-bit vvv
const uint64_t __sum = (__bits0 >> 32) + __bits1;
const uint64_t __shiftedSum = __sum >> (__shift - 32);
- _LIBCPP_ASSERT(__shiftedSum <= UINT32_MAX, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(__shiftedSum <= UINT32_MAX, "");
return static_cast<uint32_t>(__shiftedSum);
#endif // ^^^ 64-bit ^^^
}
@@ -309,8 +309,8 @@ struct __floating_decimal_32 {
// Performance note: Long division appears to be faster than losslessly widening float to double and calling
// __d2fixed_buffered_n(). If __f2fixed_buffered_n() is implemented, it might be faster than long division.
- _LIBCPP_ASSERT(_Exponent2 > 0, "");
- _LIBCPP_ASSERT(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 > 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254
// Manually represent _Mantissa2 * 2^_Exponent2 as a large integer. _Mantissa2 is always 24 bits
// (due to the implicit bit), while _Exponent2 indicates a shift of at most 104 bits.
@@ -328,7 +328,7 @@ struct __floating_decimal_32 {
// _Maxidx is the index of the most significant nonzero element.
uint32_t _Maxidx = ((24 + static_cast<uint32_t>(_Exponent2) + 31) / 32) - 1;
- _LIBCPP_ASSERT(_Maxidx < _Data_size, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Maxidx < _Data_size, "");
const uint32_t _Bit_shift = static_cast<uint32_t>(_Exponent2) % 32;
if (_Bit_shift <= 8) { // _Mantissa2's 24 bits don't cross an element boundary
@@ -388,9 +388,9 @@ struct __floating_decimal_32 {
}
}
- _LIBCPP_ASSERT(_Data[0] != 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Data[0] != 0, "");
for (uint32_t _Idx = 1; _Idx < _Data_size; ++_Idx) {
- _LIBCPP_ASSERT(_Data[_Idx] == 0, "");
+ _LIBCPP_ASSERT_UNCATEGORIZED(_Data[_Idx] == 0, "");
}
const uint32_t _Data_olength = _Data[0] >= 1000000000 ? 10 : __decimalLength9(_Data[0]);
@@ -565,35 +565,35 @@ struct __floating_decimal_32 {
_Output /= 10000;
const uint32_t __c0 = (__c % 100) << 1;
const uint32_t __c1 = (__c / 100) << 1;
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2);
}
if (_Output >= 100) {
const uint32_t __c = (_Output % 100) << 1;
_Output /= 100;
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
}
if (_Output >= 10) {
const uint32_t __c = _Output << 1;
- _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
+ std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2);
} else {
*--_Mid = static_cast<char>('0' + _Output);
}
if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu
// Performance note: it might be more efficient to do this immediately after setting _Mid.
- _VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
+ std::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent));
} else if (_Ryu_exponent == 0) { // case "1729"
// Done!
} else if (_Whole_digits > 0) { // case "17.29"
// Performance note: moving digits might not be optimal.
- _VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
+ std::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits));
_First[_Whole_digits] = '.';
} else { // case "0.001729"
// Performance note: a larger memset() followed by overwriting '.' might be more efficient.
_First[0] = '0';
_First[1] = '.';
- _VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
+ std::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits));
}
return { _First + _Total_fixed_length, errc{} };
@@ -617,14 +617,14 @@ struct __floating_decimal_32 {
_Output /= 10000;
const uint32_t __c0 = (__c % 100) << 1;
const uint32_t __c1 = (__c / 100) << 1;
- _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
- _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
+ std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2);
+ std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2);
__i += 4;
}
if (_Output >= 100) {
const uint32_t __c = (_Output % 100) << 1;
_Output /= 100;
- _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
+ std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2);
__i += 2;
}
if (_Output >= 10) {
@@ -654,7 +654,7 @@ struct __floating_decimal_32 {
__result[__index++] = '+';
}
- _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
+ std::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2);
__index += 2;
return { _First + _Total_scientific_length, errc{} };
@@ -673,7 +673,7 @@ struct __floating_decimal_32 {
return { _Last, errc::value_too_large };
}
- _VSTD::memcpy(_First, "0e+00", 5);
+ std::memcpy(_First, "0e+00", 5);
return { _First + 5, errc{} };
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/shared_mutex.cpp b/contrib/libs/cxxsupp/libcxx/src/shared_mutex.cpp
index 73d4dc1c1c..49a51e0271 100644
--- a/contrib/libs/cxxsupp/libcxx/src/shared_mutex.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/shared_mutex.cpp
@@ -10,106 +10,86 @@
#ifndef _LIBCPP_HAS_NO_THREADS
-#include <shared_mutex>
-#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
-# pragma comment(lib, "pthread")
-#endif
+# include <mutex>
+# include <shared_mutex>
+# if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
+# pragma comment(lib, "pthread")
+# endif
_LIBCPP_BEGIN_NAMESPACE_STD
// Shared Mutex Base
-__shared_mutex_base::__shared_mutex_base()
- : __state_(0)
-{
-}
+__shared_mutex_base::__shared_mutex_base() : __state_(0) {}
// Exclusive ownership
-void
-__shared_mutex_base::lock()
-{
- unique_lock<mutex> lk(__mut_);
- while (__state_ & __write_entered_)
- __gate1_.wait(lk);
- __state_ |= __write_entered_;
- while (__state_ & __n_readers_)
- __gate2_.wait(lk);
+void __shared_mutex_base::lock() {
+ unique_lock<mutex> lk(__mut_);
+ while (__state_ & __write_entered_)
+ __gate1_.wait(lk);
+ __state_ |= __write_entered_;
+ while (__state_ & __n_readers_)
+ __gate2_.wait(lk);
}
-bool
-__shared_mutex_base::try_lock()
-{
- unique_lock<mutex> lk(__mut_);
- if (__state_ == 0)
- {
- __state_ = __write_entered_;
- return true;
- }
- return false;
+bool __shared_mutex_base::try_lock() {
+ unique_lock<mutex> lk(__mut_);
+ if (__state_ == 0) {
+ __state_ = __write_entered_;
+ return true;
+ }
+ return false;
}
-void
-__shared_mutex_base::unlock()
-{
- lock_guard<mutex> _(__mut_);
- __state_ = 0;
- __gate1_.notify_all();
+void __shared_mutex_base::unlock() {
+ lock_guard<mutex> _(__mut_);
+ __state_ = 0;
+ __gate1_.notify_all();
}
// Shared ownership
-void
-__shared_mutex_base::lock_shared()
-{
- unique_lock<mutex> lk(__mut_);
- while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
- __gate1_.wait(lk);
- unsigned num_readers = (__state_ & __n_readers_) + 1;
- __state_ &= ~__n_readers_;
- __state_ |= num_readers;
-}
-
-bool
-__shared_mutex_base::try_lock_shared()
-{
- unique_lock<mutex> lk(__mut_);
- unsigned num_readers = __state_ & __n_readers_;
- if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
- {
- ++num_readers;
- __state_ &= ~__n_readers_;
- __state_ |= num_readers;
- return true;
- }
- return false;
+void __shared_mutex_base::lock_shared() {
+ unique_lock<mutex> lk(__mut_);
+ while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
+ __gate1_.wait(lk);
+ unsigned num_readers = (__state_ & __n_readers_) + 1;
+ __state_ &= ~__n_readers_;
+ __state_ |= num_readers;
}
-void
-__shared_mutex_base::unlock_shared()
-{
- lock_guard<mutex> _(__mut_);
- unsigned num_readers = (__state_ & __n_readers_) - 1;
+bool __shared_mutex_base::try_lock_shared() {
+ unique_lock<mutex> lk(__mut_);
+ unsigned num_readers = __state_ & __n_readers_;
+ if (!(__state_ & __write_entered_) && num_readers != __n_readers_) {
+ ++num_readers;
__state_ &= ~__n_readers_;
__state_ |= num_readers;
- if (__state_ & __write_entered_)
- {
- if (num_readers == 0)
- __gate2_.notify_one();
- }
- else
- {
- if (num_readers == __n_readers_ - 1)
- __gate1_.notify_one();
- }
+ return true;
+ }
+ return false;
}
+void __shared_mutex_base::unlock_shared() {
+ lock_guard<mutex> _(__mut_);
+ unsigned num_readers = (__state_ & __n_readers_) - 1;
+ __state_ &= ~__n_readers_;
+ __state_ |= num_readers;
+ if (__state_ & __write_entered_) {
+ if (num_readers == 0)
+ __gate2_.notify_one();
+ } else {
+ if (num_readers == __n_readers_ - 1)
+ __gate1_.notify_one();
+ }
+}
// Shared Timed Mutex
// These routines are here for ABI stability
shared_timed_mutex::shared_timed_mutex() : __base_() {}
-void shared_timed_mutex::lock() { return __base_.lock(); }
+void shared_timed_mutex::lock() { return __base_.lock(); }
bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }
-void shared_timed_mutex::unlock() { return __base_.unlock(); }
+void shared_timed_mutex::unlock() { return __base_.unlock(); }
void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }
bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }
void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }
diff --git a/contrib/libs/cxxsupp/libcxx/src/std_stream.h b/contrib/libs/cxxsupp/libcxx/src/std_stream.h
new file mode 100644
index 0000000000..0febf42c9f
--- /dev/null
+++ b/contrib/libs/cxxsupp/libcxx/src/std_stream.h
@@ -0,0 +1,447 @@
+// -*- 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_STD_STREAM_H
+#define _LIBCPP_STD_STREAM_H
+
+#include <__config>
+#include <__locale>
+#include <cstdio>
+#include <istream>
+#include <ostream>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+static const int __limit = 8;
+
+// __stdinbuf
+
+template <class _CharT>
+class _LIBCPP_HIDDEN __stdinbuf
+ : public basic_streambuf<_CharT, char_traits<_CharT> >
+{
+public:
+ typedef _CharT char_type;
+ typedef char_traits<char_type> traits_type;
+ typedef typename traits_type::int_type int_type;
+ typedef typename traits_type::pos_type pos_type;
+ typedef typename traits_type::off_type off_type;
+ typedef typename traits_type::state_type state_type;
+
+ __stdinbuf(FILE* __fp, state_type* __st);
+
+protected:
+ virtual int_type underflow();
+ virtual int_type uflow();
+ virtual int_type pbackfail(int_type __c = traits_type::eof());
+ virtual void imbue(const locale& __loc);
+
+private:
+
+ FILE* __file_;
+ const codecvt<char_type, char, state_type>* __cv_;
+ state_type* __st_;
+ int __encoding_;
+ int_type __last_consumed_;
+ bool __last_consumed_is_next_;
+ bool __always_noconv_;
+
+#if defined(_LIBCPP_WIN32API)
+ static constexpr bool __is_win32api_wide_char = !is_same_v<_CharT, char>;
+#else
+ static constexpr bool __is_win32api_wide_char = false;
+#endif
+
+ __stdinbuf(const __stdinbuf&);
+ __stdinbuf& operator=(const __stdinbuf&);
+
+ int_type __getchar(bool __consume);
+};
+
+template <class _CharT>
+__stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st)
+ : __file_(__fp),
+ __st_(__st),
+ __last_consumed_(traits_type::eof()),
+ __last_consumed_is_next_(false)
+{
+ imbue(this->getloc());
+ // On Windows, in wchar_t mode, ignore the codecvt from the locale by
+ // default and assume noconv; this passes wchar_t through unmodified from
+ // getwc. If the user sets a custom locale with imbue(), that gets honored,
+ // the IO is done with getc() and converted with the provided codecvt.
+ if constexpr (__is_win32api_wide_char)
+ __always_noconv_ = true;
+}
+
+template <class _CharT>
+void
+__stdinbuf<_CharT>::imbue(const locale& __loc)
+{
+ __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
+ __encoding_ = __cv_->encoding();
+ __always_noconv_ = __cv_->always_noconv();
+ if (__encoding_ > __limit)
+ __throw_runtime_error("unsupported locale for standard input");
+}
+
+template <class _CharT>
+typename __stdinbuf<_CharT>::int_type
+__stdinbuf<_CharT>::underflow()
+{
+ return __getchar(false);
+}
+
+template <class _CharT>
+typename __stdinbuf<_CharT>::int_type
+__stdinbuf<_CharT>::uflow()
+{
+ return __getchar(true);
+}
+
+static bool __do_getc(FILE *__fp, char *__pbuf) {
+ int __c = getc(__fp);
+ if (__c == EOF)
+ return false;
+ *__pbuf = static_cast<char>(__c);
+ return true;
+}
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+static bool __do_getc(FILE *__fp, wchar_t *__pbuf) {
+ wint_t __c = getwc(__fp);
+ if (__c == WEOF)
+ return false;
+ *__pbuf = static_cast<wchar_t>(__c);
+ return true;
+}
+#endif
+
+static bool __do_ungetc(int __c, FILE *__fp, char __dummy) {
+ if (ungetc(__c, __fp) == EOF)
+ return false;
+ return true;
+}
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+static bool __do_ungetc(std::wint_t __c, FILE *__fp, wchar_t __dummy) {
+ if (ungetwc(__c, __fp) == WEOF)
+ return false;
+ return true;
+}
+#endif
+
+template <class _CharT>
+typename __stdinbuf<_CharT>::int_type
+__stdinbuf<_CharT>::__getchar(bool __consume)
+{
+ if (__last_consumed_is_next_)
+ {
+ int_type __result = __last_consumed_;
+ if (__consume)
+ {
+ __last_consumed_ = traits_type::eof();
+ __last_consumed_is_next_ = false;
+ }
+ return __result;
+ }
+ if (__always_noconv_) {
+ char_type __1buf;
+ if (!__do_getc(__file_, &__1buf))
+ return traits_type::eof();
+ if (!__consume)
+ {
+ if (!__do_ungetc(traits_type::to_int_type(__1buf), __file_, __1buf))
+ return traits_type::eof();
+ }
+ else
+ __last_consumed_ = traits_type::to_int_type(__1buf);
+ return traits_type::to_int_type(__1buf);
+ }
+
+ char __extbuf[__limit];
+ int __nread = _VSTD::max(1, __encoding_);
+ for (int __i = 0; __i < __nread; ++__i)
+ {
+ int __c = getc(__file_);
+ if (__c == EOF)
+ return traits_type::eof();
+ __extbuf[__i] = static_cast<char>(__c);
+ }
+ char_type __1buf;
+ const char* __enxt;
+ char_type* __inxt;
+ codecvt_base::result __r;
+ do
+ {
+ state_type __sv_st = *__st_;
+ __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt,
+ &__1buf, &__1buf + 1, __inxt);
+ switch (__r)
+ {
+ case _VSTD::codecvt_base::ok:
+ break;
+ case codecvt_base::partial:
+ *__st_ = __sv_st;
+ if (__nread == sizeof(__extbuf))
+ return traits_type::eof();
+ {
+ int __c = getc(__file_);
+ if (__c == EOF)
+ return traits_type::eof();
+ __extbuf[__nread] = static_cast<char>(__c);
+ }
+ ++__nread;
+ break;
+ case codecvt_base::error:
+ return traits_type::eof();
+ case _VSTD::codecvt_base::noconv:
+ __1buf = static_cast<char_type>(__extbuf[0]);
+ break;
+ }
+ } while (__r == _VSTD::codecvt_base::partial);
+ if (!__consume)
+ {
+ for (int __i = __nread; __i > 0;)
+ {
+ if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF)
+ return traits_type::eof();
+ }
+ }
+ else
+ __last_consumed_ = traits_type::to_int_type(__1buf);
+ return traits_type::to_int_type(__1buf);
+}
+
+template <class _CharT>
+typename __stdinbuf<_CharT>::int_type
+__stdinbuf<_CharT>::pbackfail(int_type __c)
+{
+ if (traits_type::eq_int_type(__c, traits_type::eof()))
+ {
+ if (!__last_consumed_is_next_)
+ {
+ __c = __last_consumed_;
+ __last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_,
+ traits_type::eof());
+ }
+ return __c;
+ }
+ if (__always_noconv_ && __last_consumed_is_next_) {
+ if (!__do_ungetc(__last_consumed_, __file_,
+ traits_type::to_char_type(__last_consumed_)))
+ return traits_type::eof();
+ } else if (__last_consumed_is_next_) {
+ char __extbuf[__limit];
+ char* __enxt;
+ const char_type __ci = traits_type::to_char_type(__last_consumed_);
+ const char_type* __inxt;
+ switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt,
+ __extbuf, __extbuf + sizeof(__extbuf), __enxt))
+ {
+ case _VSTD::codecvt_base::ok:
+ break;
+ case _VSTD::codecvt_base::noconv:
+ __extbuf[0] = static_cast<char>(__last_consumed_);
+ __enxt = __extbuf + 1;
+ break;
+ case codecvt_base::partial:
+ case codecvt_base::error:
+ return traits_type::eof();
+ }
+ while (__enxt > __extbuf)
+ if (ungetc(*--__enxt, __file_) == EOF)
+ return traits_type::eof();
+ }
+ __last_consumed_ = __c;
+ __last_consumed_is_next_ = true;
+ return __c;
+}
+
+// __stdoutbuf
+
+template <class _CharT>
+class _LIBCPP_HIDDEN __stdoutbuf
+ : public basic_streambuf<_CharT, char_traits<_CharT> >
+{
+public:
+ typedef _CharT char_type;
+ typedef char_traits<char_type> traits_type;
+ typedef typename traits_type::int_type int_type;
+ typedef typename traits_type::pos_type pos_type;
+ typedef typename traits_type::off_type off_type;
+ typedef typename traits_type::state_type state_type;
+
+ __stdoutbuf(FILE* __fp, state_type* __st);
+
+protected:
+ virtual int_type overflow (int_type __c = traits_type::eof());
+ virtual streamsize xsputn(const char_type* __s, streamsize __n);
+ virtual int sync();
+ virtual void imbue(const locale& __loc);
+
+private:
+ FILE* __file_;
+ const codecvt<char_type, char, state_type>* __cv_;
+ state_type* __st_;
+ bool __always_noconv_;
+
+#if defined(_LIBCPP_WIN32API)
+ static constexpr bool __is_win32api_wide_char = !is_same_v<_CharT, char>;
+#else
+ static constexpr bool __is_win32api_wide_char = false;
+#endif
+
+ __stdoutbuf(const __stdoutbuf&);
+ __stdoutbuf& operator=(const __stdoutbuf&);
+};
+
+template <class _CharT>
+__stdoutbuf<_CharT>::__stdoutbuf(FILE* __fp, state_type* __st)
+ : __file_(__fp),
+ __cv_(&use_facet<codecvt<char_type, char, state_type> >(this->getloc())),
+ __st_(__st),
+ __always_noconv_(__cv_->always_noconv())
+{
+ // On Windows, in wchar_t mode, ignore the codecvt from the locale by
+ // default and assume noconv; this passes wchar_t through unmodified to
+ // fputwc, which handles it correctly depending on the actual mode of the
+ // output stream. If the user sets a custom locale with imbue(), that
+ // gets honored.
+ if constexpr (__is_win32api_wide_char)
+ __always_noconv_ = true;
+}
+
+static bool __do_fputc(char __c, FILE* __fp) {
+ if (fwrite(&__c, sizeof(__c), 1, __fp) != 1)
+ return false;
+ return true;
+}
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+static bool __do_fputc(wchar_t __c, FILE* __fp) {
+ // fputwc works regardless of wide/narrow mode of stdout, while
+ // fwrite of wchar_t only works if the stream actually has been set
+ // into wide mode.
+ if (fputwc(__c, __fp) == WEOF)
+ return false;
+ return true;
+}
+#endif
+
+template <class _CharT>
+typename __stdoutbuf<_CharT>::int_type
+__stdoutbuf<_CharT>::overflow(int_type __c)
+{
+ char __extbuf[__limit];
+ char_type __1buf;
+ if (!traits_type::eq_int_type(__c, traits_type::eof()))
+ {
+ __1buf = traits_type::to_char_type(__c);
+ if (__always_noconv_)
+ {
+ if (!__do_fputc(__1buf, __file_))
+ return traits_type::eof();
+ }
+ else
+ {
+ char* __extbe = __extbuf;
+ codecvt_base::result __r;
+ char_type* pbase = &__1buf;
+ char_type* pptr = pbase + 1;
+ do
+ {
+ const char_type* __e;
+ __r = __cv_->out(*__st_, pbase, pptr, __e,
+ __extbuf,
+ __extbuf + sizeof(__extbuf),
+ __extbe);
+ if (__e == pbase)
+ return traits_type::eof();
+ if (__r == codecvt_base::noconv)
+ {
+ if (fwrite(pbase, 1, 1, __file_) != 1)
+ return traits_type::eof();
+ }
+ else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
+ {
+ size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);
+ if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)
+ return traits_type::eof();
+ if (__r == codecvt_base::partial)
+ {
+ pbase = const_cast<char_type*>(__e);
+ }
+ }
+ else
+ return traits_type::eof();
+ } while (__r == codecvt_base::partial);
+ }
+ }
+ return traits_type::not_eof(__c);
+}
+
+template <class _CharT>
+streamsize
+__stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n)
+{
+ // For wchar_t on Windows, don't call fwrite(), but write characters one
+ // at a time with fputwc(); that works both when stdout is in the default
+ // mode and when it is set to Unicode mode.
+ if (__always_noconv_ && !__is_win32api_wide_char)
+ return fwrite(__s, sizeof(char_type), __n, __file_);
+ streamsize __i = 0;
+ for (; __i < __n; ++__i, ++__s)
+ if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof())
+ break;
+ return __i;
+}
+
+template <class _CharT>
+int
+__stdoutbuf<_CharT>::sync()
+{
+ char __extbuf[__limit];
+ codecvt_base::result __r;
+ do
+ {
+ char* __extbe;
+ __r = __cv_->unshift(*__st_, __extbuf,
+ __extbuf + sizeof(__extbuf),
+ __extbe);
+ size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);
+ if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)
+ return -1;
+ } while (__r == codecvt_base::partial);
+ if (__r == codecvt_base::error)
+ return -1;
+ if (fflush(__file_))
+ return -1;
+ return 0;
+}
+
+template <class _CharT>
+void
+__stdoutbuf<_CharT>::imbue(const locale& __loc)
+{
+ sync();
+ __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
+ __always_noconv_ = __cv_->always_noconv();
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_STD_STREAM_H
diff --git a/contrib/libs/cxxsupp/libcxx/src/stdexcept.cpp b/contrib/libs/cxxsupp/libcxx/src/stdexcept.cpp
index d08b6740db..d5c9173576 100644
--- a/contrib/libs/cxxsupp/libcxx/src/stdexcept.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/stdexcept.cpp
@@ -9,7 +9,6 @@
#include <new>
#include <stdexcept>
#include <string>
-#include <system_error>
#ifdef _LIBCPP_ABI_VCRUNTIME
#include "support/runtime/stdexcept_vcruntime.ipp"
diff --git a/contrib/libs/cxxsupp/libcxx/src/string.cpp b/contrib/libs/cxxsupp/libcxx/src/string.cpp
index db211b2242..4f3de555e3 100644
--- a/contrib/libs/cxxsupp/libcxx/src/string.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/string.cpp
@@ -12,7 +12,6 @@
#include <cstdlib>
#include <limits>
#include <stdexcept>
-#include <stdio.h>
#include <string>
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -61,22 +60,12 @@ template string operator+<char, char_traits<char>, allocator<char>>(char const*,
namespace
{
-template<typename T>
-inline void throw_helper(const string& msg) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
- throw T(msg);
-#else
- fprintf(stderr, "%s\n", msg.c_str());
- _VSTD::abort();
-#endif
-}
-
inline void throw_from_string_out_of_range(const string& func) {
- throw_helper<out_of_range>(func + ": out of range");
+ std::__throw_out_of_range((func + ": out of range").c_str());
}
inline void throw_from_string_invalid_arg(const string& func) {
- throw_helper<invalid_argument>(func + ": no conversion");
+ std::__throw_invalid_argument((func + ": no conversion").c_str());
}
// as_integer
@@ -357,7 +346,7 @@ S i_to_string(V v) {
constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10
char buf[bufsize];
const auto res = to_chars(buf, buf + bufsize, v);
- _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value");
+ _LIBCPP_ASSERT_INTERNAL(res.ec == errc(), "bufsize must be large enough to accomodate the value");
return S(buf, res.ptr);
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/strstream.cpp b/contrib/libs/cxxsupp/libcxx/src/strstream.cpp
index 87c235a97a..bc56cafa8f 100644
--- a/contrib/libs/cxxsupp/libcxx/src/strstream.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/strstream.cpp
@@ -173,7 +173,7 @@ strstreambuf::overflow(int_type __c)
if (buf == nullptr)
return int_type(EOF);
if (old_size != 0) {
- _LIBCPP_ASSERT(eback(), "overflow copying from NULL");
+ _LIBCPP_ASSERT_UNCATEGORIZED(eback(), "overflow copying from NULL");
memcpy(buf, eback(), static_cast<size_t>(old_size));
}
ptrdiff_t ninp = gptr() - eback();
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_fallback.ipp b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_fallback.ipp
index 100ee6da5e..c14c375338 100644
--- a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_fallback.ipp
+++ b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_fallback.ipp
@@ -52,15 +52,15 @@ _LIBCPP_NORETURN
void
terminate() noexcept
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
(*get_terminate())();
// handler should not return
fprintf(stderr, "terminate_handler unexpectedly returned\n");
::abort();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
@@ -68,7 +68,7 @@ terminate() noexcept
fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
::abort();
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
#endif // !__EMSCRIPTEN__
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_msvc.ipp b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_msvc.ipp
index 7e36c7068a..0114d5adee 100644
--- a/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_msvc.ipp
+++ b/contrib/libs/cxxsupp/libcxx/src/support/runtime/exception_msvc.ipp
@@ -57,15 +57,15 @@ terminate_handler get_terminate() noexcept {
_LIBCPP_NORETURN
void terminate() noexcept
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
(*get_terminate())();
// handler should not return
fprintf(stderr, "terminate_handler unexpectedly returned\n");
::abort();
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
@@ -73,7 +73,7 @@ void terminate() noexcept
fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
::abort();
}
-#endif // _LIBCPP_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/solaris/README b/contrib/libs/cxxsupp/libcxx/src/support/solaris/README
deleted file mode 100644
index 89c887a3b4..0000000000
--- a/contrib/libs/cxxsupp/libcxx/src/support/solaris/README
+++ /dev/null
@@ -1,4 +0,0 @@
-This directory contains a partial implementation of the xlocale APIs for
-Solaris. Some portions are lifted from FreeBSD libc, and so are covered by a
-2-clause BSD license instead of the MIT/UUIC license that the rest of libc++ is
-distributed under.
diff --git a/contrib/libs/cxxsupp/libcxx/src/support/win32/locale_win32.cpp b/contrib/libs/cxxsupp/libcxx/src/support/win32/locale_win32.cpp
index 67f4d1341a..2543686c90 100644
--- a/contrib/libs/cxxsupp/libcxx/src/support/win32/locale_win32.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/support/win32/locale_win32.cpp
@@ -11,6 +11,8 @@
#include <memory>
#include <type_traits>
+#include <__locale_dir/locale_base_api/locale_guard.h>
+
int __libcpp_vasprintf(char **sptr, const char *__restrict fmt, va_list ap);
using std::__libcpp_locale_guard;
diff --git a/contrib/libs/cxxsupp/libcxx/src/system_error.cpp b/contrib/libs/cxxsupp/libcxx/src/system_error.cpp
index ba5fa8f30b..7875f59d88 100644
--- a/contrib/libs/cxxsupp/libcxx/src/system_error.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/system_error.cpp
@@ -12,6 +12,7 @@
#endif
#include <__assert>
+#include <__verbose_abort>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
@@ -103,7 +104,7 @@ handle_strerror_r_return(int strerror_return, char *buffer) {
if (new_errno == EINVAL)
return "";
- _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerror_r");
+ _LIBCPP_ASSERT_UNCATEGORIZED(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();
@@ -286,12 +287,10 @@ system_error::~system_error() noexcept
void
__throw_system_error(int ev, const char* what_arg)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
throw system_error(error_code(ev, system_category()), what_arg);
#else
- (void)ev;
- (void)what_arg;
- _VSTD::abort();
+ _LIBCPP_VERBOSE_ABORT("system_error was thrown in -fno-exceptions mode with error %i and message \"%s\"", ev, what_arg);
#endif
}
diff --git a/contrib/libs/cxxsupp/libcxx/src/thread.cpp b/contrib/libs/cxxsupp/libcxx/src/thread.cpp
index ec4f65f982..184b5ae8a1 100644
--- a/contrib/libs/cxxsupp/libcxx/src/thread.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/thread.cpp
@@ -10,6 +10,8 @@
#ifndef _LIBCPP_HAS_NO_THREADS
+#include <__thread/poll_with_backoff.h>
+#include <__thread/timed_backoff_policy.h>
#include <exception>
#include <future>
#include <limits>
diff --git a/contrib/libs/cxxsupp/libcxx/src/utility.cpp b/contrib/libs/cxxsupp/libcxx/src/utility.cpp
deleted file mode 100644
index 44433d11d7..0000000000
--- a/contrib/libs/cxxsupp/libcxx/src/utility.cpp
+++ /dev/null
@@ -1,15 +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
-//
-//===----------------------------------------------------------------------===//
-
-#include <utility>
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-const piecewise_construct_t piecewise_construct{};
-
-_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/libs/cxxsupp/libcxx/src/valarray.cpp b/contrib/libs/cxxsupp/libcxx/src/valarray.cpp
index 5d63bc1184..f377e0f4e8 100644
--- a/contrib/libs/cxxsupp/libcxx/src/valarray.cpp
+++ b/contrib/libs/cxxsupp/libcxx/src/valarray.cpp
@@ -12,8 +12,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// These two symbols are part of the v1 ABI but not part of the >=v2 ABI.
#if _LIBCPP_ABI_VERSION == 1
-template _LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t);
-template _LIBCPP_FUNC_VIS valarray<size_t>::~valarray();
+template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::valarray(size_t);
+template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::~valarray();
#endif
template void valarray<size_t>::resize(size_t, size_t);