From: robert Date: Fri, 26 Jan 2024 11:47:53 +0000 (+0000) Subject: import of libcxx-16.0.6 X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=4bdff4bed0e3d54e55670334c7d0077db4170f86;p=openbsd import of libcxx-16.0.6 --- diff --git a/gnu/llvm/libcxx/.clang-format b/gnu/llvm/libcxx/.clang-format index cfa0c289635..77ffa23435c 100644 --- a/gnu/llvm/libcxx/.clang-format +++ b/gnu/llvm/libcxx/.clang-format @@ -1,16 +1,88 @@ BasedOnStyle: LLVM ---- +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: Consecutive +AlignConsecutiveBitFields: Consecutive +AlignEscapedNewlines: Right +AlignOperands: AlignAfterOperator +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortFunctionsOnASingleLine: true +AllowShortLambdasOnASingleLine: All +AttributeMacros: ['_LIBCPP_HIDE_FROM_ABI', + '_LIBCPP_CONSTEXPR', + '_LIBCPP_CONSTEXPR_SINCE_CXX14', + '_LIBCPP_CONSTEXPR_SINCE_CXX17', + '_LIBCPP_CONSTEXPR_SINCE_CXX20', + '_LIBCPP_CONSTEXPR_SINCE_CXX23', + '_LIBCPP_ALIGNOF', + '_ALIGNAS_TYPE', + '_ALIGNAS', + '_LIBCPP_NORETURN', + '_LIBCPP_ALWAYS_INLINE', + '_LIBCPP_DISABLE_EXTENTSION_WARNING', + '_LIBCPP_HIDDEN', + '_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS', + '_LIBCPP_FUNC_VIS', + '_LIBCPP_TYPE_VIS', + '_LIBCPP_TEMPLATE_VIS', + '_LIBCPP_TEMPLATE_DATA_VIS', + '_LIBCPP_EXPORTED_FROM_ABI', + '_LIBCPP_OVERRIDABLE_FUNC_VIS', + '_LIBCPP_EXCEPTION_ABI', + '_LIBCPP_ENUM_VIS', + '_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS', + '_LIBCPP_INTERNAL_LINKAGE', + '_LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION', + '_LIBCPP_HIDE_FROM_ABI_AFTER_V1', + '_LIBCPP_INLINE_VISIBILITY', + '_LIBCPP_CONSTEVAL', + '_LIBCPP_NOALIAS', + '_LIBCPP_USING_IF_EXISTS', + '_LIBCPP_DEPRECATED', + '_LIBCPP_DEPRECATED_IN_CXX11', + '_LIBCPP_DEPRECATED_IN_CXX14', + '_LIBCPP_DEPRECATED_IN_CXX17', + '_LIBCPP_DEPRECATED_IN_CXX20', + '_LIBCPP_NODISCARD', + '_LIBCPP_NODISCARD_EXT', + '_LIBCPP_NO_DESTROY', + '_LIBCPP_WEAK', + '_LIBCPP_CONSTINIT', + '_LIBCPP_FALLTHROUGH', + '_LIBCPP_STANDALONE_DEBUG', + '_LIBCPP_NO_UNIQUE_ADDRESS', + ] +BinPackArguments: false +BinPackParameters: false +BreakBeforeConceptDeclarations: true +BreakInheritanceList: BeforeColon +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: Always +IndentWrappedFunctionNames: false +IndentRequires: true +InsertTrailingCommas: Wrapped +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 +PackConstructorInitializers: NextLine + +PenaltyIndentedWhitespace: 2 + Language: Cpp -Standard: Cpp03 +Standard: c++20 +SpacesInAngles: Leave AlwaysBreakTemplateDeclarations: true PointerAlignment: Left + # Disable formatting options which may break tests. SortIncludes: false ReflowComments: false +# libc++'s preferred indentions of preprocessor statements. +IndentPPDirectives: AfterHash + # libc++ has some long names so we need more than the 80 column limit imposed by LLVM style, for sensible formatting ColumnLimit: 120 ---- diff --git a/gnu/llvm/libcxx/.clang-tidy b/gnu/llvm/libcxx/.clang-tidy new file mode 100644 index 00000000000..4bc25c3ae60 --- /dev/null +++ b/gnu/llvm/libcxx/.clang-tidy @@ -0,0 +1,67 @@ +Checks: > + bugprone-copy-constructor-init, + bugprone-dangling-handle, + bugprone-infinite-loop, + bugprone-stringview-nullptr, + bugprone-use-after-move, + + llvm-include-order, + llvm-namespace-comment, + + misc-definitions-in-headers, + misc-misplaced-const, + misc-non-copyable-objects, + misc-uniqueptr-reset-release, + + modernize-loop-convert, + modernize-redundant-void-arg, + modernize-use-override, + + readability-duplicate-include, + readability-identifier-naming, + readability-function-cognitive-complexity, + readability-function-size, + readability-misplaced-array-index, + readability-redundant-control-flow, + readability-redundant-function-ptr-dereference, + readability-redundant-preprocessor, + readability-simplify-boolean-expr, + readability-simplify-subscript-expr, + readability-uniqueptr-delete-release, + +CheckOptions: + - key: readability-function-cognitive-complexity.Threshold + value: 143 # TODO: bring that number down + - key: readability-function-size.LineThreshold + value: 194 # TODO: bring that number down + - key: readability-identifier-naming.GetConfigPerFile + value: false + - key: readability-identifier-naming.ParameterCase + value: lower_case + - key: readability-identifier-naming.ParameterPrefix + value: __ + - key: readability-identifier-naming.PrivateMemberCase + value: lower_case + - key: readability-identifier-naming.PrivateMemberPrefix + value: __ + - key: readability-identifier-naming.PrivateMemberSuffix + value: _ + +# TODO: investigate these checks +# bugprone-branch-clone, +# bugprone-macro-parentheses, +# cppcoreguidelines-prefer-member-initializer, +# misc-unused-parameters, +# modernize-use-bool-literals, +# modernize-use-default-member-init, +# modernize-use-equals-default, +# modernize-use-equals-delete, +# modernize-use-nullptr, +# portability-restrict-system-includes, +# readability-function-cognitive-complexity, +# readability-implicit-bool-conversion, +# readability-isolate-declaration, +# readability-redundant-access-specifiers, +# readability-redundant-declaration, +# readability-redundant-member-init, +# diff --git a/gnu/llvm/libcxx/CMakeLists.txt b/gnu/llvm/libcxx/CMakeLists.txt index b1e25358d41..f3b2c10ff4d 100644 --- a/gnu/llvm/libcxx/CMakeLists.txt +++ b/gnu/llvm/libcxx/CMakeLists.txt @@ -1,20 +1,19 @@ # See https://libcxx.llvm.org/docs/BuildingLibcxx.html for instructions on how # to build libcxx with CMake. -if (NOT IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../libcxxabi") - message(FATAL_ERROR "libc++ now requires being built in a monorepo layout with libcxxabi available") -endif() - #=============================================================================== # Setup Project #=============================================================================== cmake_minimum_required(VERSION 3.13.4) +set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") + # Add path for custom modules -set(CMAKE_MODULE_PATH +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" - ${CMAKE_MODULE_PATH} + "${LLVM_COMMON_CMAKE_UTILS}" + "${LLVM_COMMON_CMAKE_UTILS}/Modules" ) set(CMAKE_FOLDER "libc++") @@ -23,40 +22,7 @@ set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(LIBCXX_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(LIBCXX_BINARY_INCLUDE_DIR "${LIBCXX_BINARY_DIR}/include/c++build") -if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBCXX_STANDALONE_BUILD) - project(libcxx CXX C) - - set(PACKAGE_NAME libcxx) - set(PACKAGE_VERSION 13.0.0git) - set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") - set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") - - # In a standalone build, we don't have llvm to automatically generate the - # llvm-lit script for us. So we need to provide an explicit directory that - # the configurator should write the script into. - set(LIBCXX_STANDALONE_BUILD 1) - set(LLVM_LIT_OUTPUT_DIR "${LIBCXX_BINARY_DIR}/bin") - - # Find the LLVM sources and simulate LLVM CMake options. - include(HandleOutOfTreeLLVM) -endif() - -if (LIBCXX_STANDALONE_BUILD) - find_package(Python3 COMPONENTS Interpreter) - if(NOT Python3_Interpreter_FOUND) - message(WARNING "Python3 not found, using python2 as a fallback") - find_package(Python2 COMPONENTS Interpreter REQUIRED) - if(Python2_VERSION VERSION_LESS 2.7) - message(SEND_ERROR "Python 2.7 or newer is required") - endif() - - # Treat python2 as python3 - add_executable(Python3::Interpreter IMPORTED) - set_target_properties(Python3::Interpreter PROPERTIES - IMPORTED_LOCATION ${Python2_EXECUTABLE}) - set(Python3_EXECUTABLE ${Python2_EXECUTABLE}) - endif() -endif() +include(GNUInstallDirs) # Require out of source build. include(MacroEnsureOutOfSourceBuild) @@ -83,10 +49,12 @@ include(CMakeDependentOption) include(HandleCompilerRT) # Basic options --------------------------------------------------------------- -option(LIBCXX_ENABLE_ASSERTIONS "Enable assertions independent of build mode." OFF) +option(LIBCXX_ENABLE_ASSERTIONS + "Enable assertions inside the compiled library, and at the same time make it the + default when compiling user code. Note that assertions can be enabled or disabled + by users in their own code regardless of this option." OFF) option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON) option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON) -option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ON) set(ENABLE_FILESYSTEM_DEFAULT ON) if (WIN32 AND NOT MINGW) # Filesystem is buildable for windows, but it requires __int128 helper @@ -99,11 +67,11 @@ option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of the main libc++ lib ${ENABLE_FILESYSTEM_DEFAULT}) option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS}) option(LIBCXX_ENABLE_PARALLEL_ALGORITHMS "Enable the parallel algorithms library. This requires the PSTL to be available." OFF) -option(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT - "Whether to include support for libc++'s debugging mode in the library. - By default, this is turned on. If you turn it off and try to enable the - debug mode when compiling a program against libc++, it will fail to link - since the required support isn't provided in the library." ON) +option(LIBCXX_ENABLE_DEBUG_MODE + "Whether to build libc++ with the debug mode enabled. + By default, this is turned off. Turning it on results in a different ABI (additional + symbols but also potentially different layouts of types), and one should not mix code + built against a dylib that has debug mode and code built against a regular dylib." OFF) option(LIBCXX_ENABLE_RANDOM_DEVICE "Whether to include support for std::random_device in the library. Disabling this can be useful when building the library for platforms that don't have @@ -116,6 +84,18 @@ option(LIBCXX_ENABLE_LOCALIZATION the C locale API (e.g. embedded). When localization is not supported, several parts of the library will be disabled: , , will be completely unusable, and other parts may be only partly available." ON) +option(LIBCXX_ENABLE_FSTREAM + "Whether to include support for ." ON) # TODO: Consider rolling that into LIBCXX_ENABLE_FILESYSTEM +option(LIBCXX_ENABLE_UNICODE + "Whether to include support for Unicode in the library. Disabling Unicode can + be useful when porting to platforms that don't support UTF-8 encoding (e.g. + embedded)." ON) +option(LIBCXX_ENABLE_WIDE_CHARACTERS + "Whether to include support for wide characters in the library. Disabling + wide character support can be useful when porting to platforms that don't + support the C functionality for wide characters. When wide characters are + not supported, several parts of the library will be disabled, notably the + wide character specializations of std::basic_string." ON) option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS "Whether to turn on vendor availability annotations on declarations that depend on definitions in a shared library. By default, we assume that we're not building @@ -123,13 +103,32 @@ option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS to provide compile-time errors when using features unavailable on some version of the shared library they shipped should turn this on and see `include/__availability` for more details." OFF) -option(LIBCXX_ENABLE_INCOMPLETE_FEATURES - "Whether to enable support for incomplete library features. Incomplete features - are new library features under development. These features don't guarantee - ABI stability nor the quality of completed library features. Vendors - shipping the library may want to disable this option." ON) -set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/legacy.cfg.in" CACHE STRING - "The Lit testing configuration to use when running the tests.") +option(LIBCXX_ENABLE_CLANG_TIDY "Whether to compile and run clang-tidy checks" OFF) + +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-gcc.cfg.in") +elseif(MINGW) + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-mingw.cfg.in") +elseif(WIN32) # clang-cl + if (LIBCXX_ENABLE_SHARED) + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-clangcl.cfg.in") + else() + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static-clangcl.cfg.in") + endif() +else() + if (LIBCXX_ENABLE_SHARED) + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared.cfg.in") + else() + set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-static.cfg.in") + endif() +endif() +set(LIBCXX_TEST_CONFIG "${LIBCXX_DEFAULT_TEST_CONFIG}" CACHE STRING + "The path to the Lit testing configuration to use when running the tests. + If a relative path is provided, it is assumed to be relative to '/libcxx/test/configs'.") +if (NOT IS_ABSOLUTE "${LIBCXX_TEST_CONFIG}") + set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/${LIBCXX_TEST_CONFIG}") +endif() +message(STATUS "Using libc++ testing configuration: ${LIBCXX_TEST_CONFIG}") set(LIBCXX_TEST_PARAMS "" CACHE STRING "A list of parameters to run the Lit test suite with.") @@ -165,13 +164,25 @@ cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY cmake_dependent_option(LIBCXX_INSTALL_SHARED_LIBRARY "Install the shared libc++ library." ON "LIBCXX_ENABLE_SHARED;LIBCXX_INSTALL_LIBRARY" OFF) -cmake_dependent_option(LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY - "Install libc++experimental.a" ON - "LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY;LIBCXX_INSTALL_LIBRARY" OFF) -set(LIBCXX_ABI_VERSION "1" CACHE STRING "ABI version of libc++. Can be either 1 or 2, where 2 is currently not stable. Defaults to 1.") -set(LIBCXX_ABI_NAMESPACE "" CACHE STRING "The inline ABI namespace used by libc++. It defaults to __n where `n` is the current ABI version.") -option(LIBCXX_ABI_UNSTABLE "Unstable ABI of libc++." OFF) +option(LIBCXX_ABI_UNSTABLE "Use the unstable ABI of libc++. This is equivalent to specifying LIBCXX_ABI_VERSION=n, where n is the not-yet-stable version." OFF) +if (LIBCXX_ABI_UNSTABLE) + set(abi_version "2") +else() + set(abi_version "1") +endif() +set(LIBCXX_ABI_VERSION "${abi_version}" CACHE STRING + "ABI version of libc++. Can be either 1 or 2, where 2 is currently the unstable ABI. + Defaults to 1 unless LIBCXX_ABI_UNSTABLE is specified, in which case this is 2.") +set(LIBCXX_LIBRARY_VERSION "${LIBCXX_ABI_VERSION}.0" CACHE STRING + "Version of libc++. This will be reflected in the name of the shared library produced. + For example, -DLIBCXX_LIBRARY_VERSION=x.y will result in the library being named + libc++.x.y.dylib, along with the usual symlinks pointing to that. On Apple platforms, + this also controls the linker's 'current_version' property.") +set(LIBCXX_ABI_NAMESPACE "__${LIBCXX_ABI_VERSION}" CACHE STRING "The inline ABI namespace used by libc++. It defaults to __n where `n` is the current ABI version.") +if (NOT LIBCXX_ABI_NAMESPACE MATCHES "__.*") + message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE must be a reserved identifier, got '${LIBCXX_ABI_NAMESPACE}'.") +endif() option(LIBCXX_ABI_FORCE_ITANIUM "Ignore auto-detection and force use of the Itanium ABI.") option(LIBCXX_ABI_FORCE_MICROSOFT "Ignore auto-detection and force use of the Microsoft ABI.") @@ -188,54 +199,52 @@ if (NOT ("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" IN_LIST TYPEINFO_COMPARI LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION") endif() -option(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT "Enable per TU ABI insulation by default. To be used by vendors." OFF) set(LIBCXX_ABI_DEFINES "" CACHE STRING "A semicolon separated list of ABI macros to define in the site config header.") +option(LIBCXX_EXTRA_SITE_DEFINES "Extra defines to add into __config_site") option(LIBCXX_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF) -set(LIBCXX_LIBCPPABI_VERSION "2" CACHE STRING "Version of libc++abi's ABI to re-export from libc++ when re-exporting is enabled. - Note that this is not related to the version of libc++'s ABI itself!") -# ABI Library options --------------------------------------------------------- -set(LIBCXX_CXX_ABI "default" CACHE STRING "Specify C++ ABI library to use.") -set(CXXABIS none default libcxxabi libcxxrt libstdc++ libsupc++ vcruntime) -set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS}) +option(LIBCXX_ENABLE_BACKWARDS_COMPATIBILITY_DEBUG_MODE_SYMBOLS + "Whether to include the old Debug mode symbols in the compiled library. This + is provided for backwards compatibility since the compiled library used to + always contain those symbols, regardless of whether the library was built + with the debug mode enabled. This is OFF by default, please contact the libc++ + developers if you need to turn this on, as this will be removed in LLVM 16." OFF) -# Setup the default options if LIBCXX_CXX_ABI is not specified. -if (LIBCXX_CXX_ABI STREQUAL "default") - if (LIBCXX_TARGETING_MSVC) - # FIXME: Figure out how to configure the ABI library on Windows. - set(LIBCXX_CXX_ABI_LIBNAME "vcruntime") - elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - set(LIBCXX_CXX_ABI_LIBNAME "libcxxrt") - elseif (NOT LIBCXX_STANDALONE_BUILD OR HAVE_LIBCXXABI) - set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi") - else() - set(LIBCXX_CXX_ABI_LIBNAME "default") - endif() +# ABI Library options --------------------------------------------------------- +if (LIBCXX_TARGETING_MSVC) + set(LIBCXX_DEFAULT_ABI_LIBRARY "vcruntime") +elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + set(LIBCXX_DEFAULT_ABI_LIBRARY "libcxxrt") else() - set(LIBCXX_CXX_ABI_LIBNAME "${LIBCXX_CXX_ABI}") + set(LIBCXX_DEFAULT_ABI_LIBRARY "libcxxabi") +endif() + +set(LIBCXX_SUPPORTED_ABI_LIBRARIES none libcxxabi system-libcxxabi libcxxrt libstdc++ libsupc++ vcruntime) +set(LIBCXX_CXX_ABI "${LIBCXX_DEFAULT_ABI_LIBRARY}" CACHE STRING "Specify C++ ABI library to use. Supported values are ${LIBCXX_SUPPORTED_ABI_LIBRARIES}.") +if (NOT "${LIBCXX_CXX_ABI}" IN_LIST LIBCXX_SUPPORTED_ABI_LIBRARIES) + message(FATAL_ERROR "Unsupported C++ ABI library: '${LIBCXX_CXX_ABI}'. Supported values are ${LIBCXX_SUPPORTED_ABI_LIBRARIES}.") endif() option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "Use a static copy of the ABI library when linking libc++. This option cannot be used with LIBCXX_ENABLE_ABI_LINKER_SCRIPT." OFF) -cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY - "Statically link the ABI library to static library" ON - "LIBCXX_ENABLE_STATIC_ABI_LIBRARY;LIBCXX_ENABLE_STATIC" OFF) +option(LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY + "Statically link the ABI library to static library" + ${LIBCXX_ENABLE_STATIC_ABI_LIBRARY}) -cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY - "Statically link the ABI library to shared library" ON - "LIBCXX_ENABLE_STATIC_ABI_LIBRARY;LIBCXX_ENABLE_SHARED" OFF) +option(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY + "Statically link the ABI library to shared library" + ${LIBCXX_ENABLE_STATIC_ABI_LIBRARY}) # Generate and install a linker script inplace of libc++.so. The linker script # will link libc++ to the correct ABI library. This option is on by default -# on UNIX platforms other than Apple unless 'LIBCXX_ENABLE_STATIC_ABI_LIBRARY' -# is on. This option is also disabled when the ABI library is not specified -# or is specified to be "none". +# on UNIX platforms other than Apple unless +# 'LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY' is on. This option is also +# disabled when the ABI library is not specified or is specified to be "none". set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE OFF) if (LLVM_HAVE_LINK_VERSION_SCRIPT AND NOT LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY - AND NOT LIBCXX_CXX_ABI_LIBNAME STREQUAL "none" - AND NOT LIBCXX_CXX_ABI_LIBNAME STREQUAL "default" + AND NOT LIBCXX_CXX_ABI STREQUAL "none" AND Python3_EXECUTABLE AND LIBCXX_ENABLE_SHARED) set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE ON) @@ -255,19 +264,15 @@ option(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS option(LIBCXXABI_USE_LLVM_UNWINDER "Build and use the LLVM unwinder." OFF) # Target options -------------------------------------------------------------- -option(LIBCXX_BUILD_32_BITS "Build 32 bit libc++." ${LLVM_BUILD_32_BITS}) -set(LIBCXX_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}" CACHE STRING "Use alternate target triple.") -set(LIBCXX_SYSROOT "" CACHE STRING "Use alternate sysroot.") -set(LIBCXX_GCC_TOOLCHAIN "" CACHE STRING "Use alternate GCC toolchain.") +option(LIBCXX_BUILD_32_BITS "Build 32 bit multilib libc++. This option is not supported anymore when building the runtimes. Please specify a full triple instead." ${LLVM_BUILD_32_BITS}) +if (LIBCXX_BUILD_32_BITS) + message(FATAL_ERROR "LIBCXX_BUILD_32_BITS is not supported anymore when building the runtimes, please specify a full triple instead.") +endif() # Feature options ------------------------------------------------------------- option(LIBCXX_ENABLE_EXCEPTIONS "Use exceptions." ON) option(LIBCXX_ENABLE_RTTI "Use run time type information." ON) -option(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE "Build libc++ with support for the global filesystem namespace." ON) -option(LIBCXX_ENABLE_STDIN "Build libc++ with support for stdin/std::cin." ON) -option(LIBCXX_ENABLE_STDOUT "Build libc++ with support for stdout/std::cout." ON) option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." ON) -option(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS "Build libc++ with support for thread-unsafe C functions" ON) option(LIBCXX_ENABLE_MONOTONIC_CLOCK "Build libc++ with support for a monotonic clock. This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON) @@ -299,8 +304,12 @@ endif() option(LIBCXX_CONFIGURE_IDE "Configure libcxx for use within an IDE" ${LIBCXX_CONFIGURE_IDE_DEFAULT}) +set(LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT OFF) +if (WIN32) + set(LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT ON) +endif() option(LIBCXX_HERMETIC_STATIC_LIBRARY - "Do not export any symbols from the static library." OFF) + "Do not export any symbols from the static library." ${LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT}) #=============================================================================== # Check option configurations @@ -365,24 +374,6 @@ if (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE) message(FATAL_ERROR "LLVM_USE_SANITIZER cannot be used with LIBCXX_GENERATE_COVERAGE") endif() -# Set LIBCXX_BUILD_32_BITS to (LIBCXX_BUILD_32_BITS OR LLVM_BUILD_32_BITS) -# and check that we can build with 32 bits if requested. -if (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32) - if (LIBCXX_BUILD_32_BITS AND NOT LLVM_BUILD_32_BITS) # Don't duplicate the output from LLVM - message(STATUS "Building 32 bits executables and libraries.") - endif() -elseif(LIBCXX_BUILD_32_BITS) - message(FATAL_ERROR "LIBCXX_BUILD_32_BITS=ON is not supported on this platform.") -endif() - -# Warn users that LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option. -if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY) - message(WARNING "LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option") - if (LIBCXX_ENABLE_STATIC AND NOT Python3_EXECUTABLE) - message(FATAL_ERROR "LIBCXX_ENABLE_STATIC_ABI_LIBRARY requires python but it was not found.") - endif() -endif() - if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT) if (APPLE) message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT cannot be used on APPLE targets") @@ -394,7 +385,7 @@ endif() if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT) message(FATAL_ERROR "Conflicting options given. - LIBCXX_ENABLE_STATIC_ABI_LIBRARY cannot be specified with + LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY cannot be specified with LIBCXX_ENABLE_ABI_LINKER_SCRIPT") endif() @@ -408,38 +399,38 @@ endif () # TODO: Projects that depend on libc++ should use LIBCXX_GENERATED_INCLUDE_DIR # instead of hard-coding include/c++/v1. + +set(LIBCXX_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1" CACHE PATH + "Path where target-agnostic libc++ headers should be installed.") +set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH + "Path where built libc++ runtime libraries should be installed.") + +set(LIBCXX_SHARED_OUTPUT_NAME "c++" CACHE STRING "Output name for the shared libc++ runtime library.") +set(LIBCXX_STATIC_OUTPUT_NAME "c++" CACHE STRING "Output name for the static libc++ runtime library.") + if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1") set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH "Path where built libc++ libraries should be installed.") - set(LIBCXX_INSTALL_INCLUDE_DIR "include/c++/v1" CACHE PATH - "Path where target-agnostic libc++ headers should be installed.") - set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1" CACHE PATH + set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1" CACHE PATH "Path where target-specific libc++ headers should be installed.") if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) endif() -elseif(LLVM_LIBRARY_OUTPUT_INTDIR) - set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) - set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") - set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}") - set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH - "Path where built libc++ libraries should be installed.") - set(LIBCXX_INSTALL_INCLUDE_DIR "include/c++/v1" CACHE PATH - "Path where target-agnostic libc++ headers should be installed.") - set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}" CACHE PATH - "Path where target-specific libc++ headers should be installed.") else() - set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) - set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1") + if(LLVM_LIBRARY_OUTPUT_INTDIR) + set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) + set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") + else() + set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) + set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1") + endif() set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}") set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH "Path where built libc++ libraries should be installed.") - set(LIBCXX_INSTALL_INCLUDE_DIR "include/c++/v1" CACHE PATH - "Path where target-agnostic libc++ headers should be installed.") set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}" CACHE PATH "Path where target-specific libc++ headers should be installed.") endif() @@ -459,6 +450,10 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR}) set(LIBCXX_COMPILE_FLAGS "") set(LIBCXX_LINK_FLAGS "") set(LIBCXX_LIBRARIES "") +set(LIBCXX_ADDITIONAL_COMPILE_FLAGS "" CACHE STRING + "Additional Compile only flags which can be provided in cache") +set(LIBCXX_ADDITIONAL_LIBRARIES "" CACHE STRING + "Additional libraries libc++ is linked to which can be provided in cache") # Include macros for adding and removing libc++ flags. include(HandleLibcxxFlags) @@ -467,22 +462,10 @@ include(HandleLibcxxFlags) # These flags get added to CMAKE_CXX_FLAGS and CMAKE_C_FLAGS so that # 'config-ix' use them during feature checks. It also adds them to both # 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS' -add_target_flags_if(LIBCXX_BUILD_32_BITS "-m32") -if(LIBCXX_TARGET_TRIPLE) - add_target_flags_if_supported("--target=${LIBCXX_TARGET_TRIPLE}") -elseif(CMAKE_CXX_COMPILER_TARGET) - set(LIBCXX_TARGET_TRIPLE "${CMAKE_CXX_COMPILER_TARGET}") -endif() -if(LIBCXX_SYSROOT) - add_target_flags_if_supported("--sysroot=${LIBCXX_SYSROOT}") -elseif(CMAKE_SYSROOT) - set(LIBCXX_SYSROOT "${CMAKE_SYSROOT}") -endif() -if(LIBCXX_GCC_TOOLCHAIN) - add_target_flags_if_supported("--gcc-toolchain=${LIBCXX_GCC_TOOLCHAIN}") -elseif(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN) - set(LIBCXX_GCC_TOOLCHAIN "${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}") +if (${CMAKE_SYSTEM_NAME} MATCHES "AIX") + add_target_flags_if_supported("-mdefault-visibility-export-mapping=explicit") + set(CMAKE_AIX_EXPORT_ALL_SYMBOLS OFF) endif() # Configure compiler. @@ -507,13 +490,6 @@ endif() include(HandleLibCXXABI) # Setup the ABI library flags -if (NOT LIBCXX_STANDALONE_BUILD) - # Remove flags that may have snuck in. - remove_flags(-DNDEBUG -UNDEBUG -D_DEBUG - -lc++abi) -endif() -remove_flags(--stdlib=libc++ -stdlib=libc++ --stdlib=libstdc++ -stdlib=libstdc++) - # FIXME: Remove all debug flags and flags that change which Windows # default libraries are linked. Currently we only support linking the # non-debug DLLs @@ -531,12 +507,12 @@ function(cxx_add_basic_build_flags target) # in the dylib. C++20 is needed to use char8_t. set_target_properties(${target} PROPERTIES CXX_STANDARD 20 - CXX_STANDARD_REQUIRED NO + CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO) # When building the dylib, don't warn for unavailable aligned allocation # functions based on the deployment target -- they are always available - # because they are provided by the dylib itself with the excepton of z/OS. + # because they are provided by the dylib itself with the exception of z/OS. if (ZOS) target_add_compile_flags_if_supported(${target} PRIVATE -fno-aligned-allocation) else() @@ -575,7 +551,7 @@ function(cxx_add_basic_build_flags target) target_compile_definitions(${target} PRIVATE -D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS) endif() - if (LIBCXX_HAS_COMMENT_LIB_PRAGMA) + if (C_SUPPORTS_COMMENT_LIB_PRAGMA) if (LIBCXX_HAS_PTHREAD_LIB) target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_PTHREAD_LIB) endif() @@ -583,6 +559,7 @@ function(cxx_add_basic_build_flags target) target_compile_definitions(${target} PRIVATE -D_LIBCPP_LINK_RT_LIB) endif() endif() + target_compile_options(${target} PUBLIC "${LIBCXX_ADDITIONAL_COMPILE_FLAGS}") endfunction() # Warning flags =============================================================== @@ -597,13 +574,13 @@ function(cxx_add_warning_flags target) endif() target_add_compile_flags_if_supported(${target} PRIVATE -Wextra -W -Wwrite-strings -Wno-unused-parameter -Wno-long-long - -Werror=return-type -Wextra-semi -Wundef) + -Werror=return-type -Wextra-semi -Wundef + -Wformat-nonliteral) if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") target_add_compile_flags_if_supported(${target} PRIVATE -Wno-user-defined-literals -Wno-covered-switch-default -Wno-suggest-override - -Wno-ignored-attributes # FIXME: Caused by _LIBCPP_NODEBUG_TYPE not being supported on older clangs ) if (LIBCXX_TARGETING_CLANG_CL) target_add_compile_flags_if_supported(${target} PRIVATE @@ -625,6 +602,7 @@ function(cxx_add_warning_flags target) endif() elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") target_add_compile_flags_if_supported(${target} PRIVATE + -Wno-attributes -Wno-literal-suffix -Wno-c++14-compat -Wno-noexcept-type @@ -641,9 +619,6 @@ function(cxx_add_warning_flags target) if (LIBCXX_ENABLE_PEDANTIC) target_add_compile_flags_if_supported(${target} PRIVATE -pedantic) endif() - if (LIBCXX_DISABLE_MACRO_CONFLICT_WARNINGS) - target_compile_definitions(${target} PRIVATE -D_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) - endif() endfunction() # Exception flags ============================================================= @@ -678,9 +653,6 @@ if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY AND LIBCXX_ENABLE_SHARED) endif() # Assertion flags ============================================================= -define_if(LIBCXX_ENABLE_ASSERTIONS -UNDEBUG) -define_if_not(LIBCXX_ENABLE_ASSERTIONS -DNDEBUG) -define_if(LIBCXX_ENABLE_ASSERTIONS -D_LIBCPP_DEBUG=0) define_if(LIBCXX_DEBUG_BUILD -D_DEBUG) if (LIBCXX_ENABLE_ASSERTIONS AND NOT LIBCXX_DEBUG_BUILD) # MSVC doesn't like _DEBUG on release builds. See PR 4379. @@ -716,6 +688,8 @@ function(get_sanitizer_flags OUT_VAR USE_SANITIZER) endif() if (USE_SANITIZER STREQUAL "Address") append_flags(SANITIZER_FLAGS "-fsanitize=address") + elseif (USE_SANITIZER STREQUAL "HWAddress") + append_flags(SANITIZER_FLAGS "-fsanitize=hwaddress") elseif (USE_SANITIZER MATCHES "Memory(WithOrigins)?") append_flags(SANITIZER_FLAGS -fsanitize=memory) if (USE_SANITIZER STREQUAL "MemoryWithOrigins") @@ -739,16 +713,7 @@ function(get_sanitizer_flags OUT_VAR USE_SANITIZER) set(${OUT_VAR} "${SANITIZER_FLAGS}" PARENT_SCOPE) endfunction() -# Configure for sanitizers. If LIBCXX_STANDALONE_BUILD then we have to do -# the flag translation ourselves. Othewise LLVM's CMakeList.txt will handle it. -if (LIBCXX_STANDALONE_BUILD) - set(LLVM_USE_SANITIZER "" CACHE STRING - "Define the sanitizer used to build the library and tests") -endif() get_sanitizer_flags(SANITIZER_FLAGS "${LLVM_USE_SANITIZER}") -if (LIBCXX_STANDALONE_BUILD AND SANITIZER_FLAGS) - add_flags(${SANITIZER_FLAGS}) -endif() # Link system libraries ======================================================= function(cxx_link_system_libraries target) @@ -758,7 +723,7 @@ function(cxx_link_system_libraries target) # Unfortunately this cannot be used universally because for example g++ supports # only -nodefaultlibs in which case all libraries will be removed and # all libraries but c++ have to be added in manually. - if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG) + if (CXX_SUPPORTS_NOSTDLIBXX_FLAG) target_add_link_flags_if_supported(${target} PRIVATE "-nostdlib++") else() target_add_link_flags_if_supported(${target} PRIVATE "-nodefaultlibs") @@ -766,6 +731,13 @@ function(cxx_link_system_libraries target) target_add_link_flags_if_supported(${target} PRIVATE "/nodefaultlib") endif() + if (CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG AND LIBCXXABI_USE_LLVM_UNWINDER) + # If we're linking directly against the libunwind that we're building + # in the same invocation, don't try to link in the toolchain's + # default libunwind (which may be missing still). + target_add_link_flags_if_supported(${target} PRIVATE "--unwindlib=none") + endif() + if (LIBCXX_HAS_SYSTEM_LIB) target_link_libraries(${target} PRIVATE System) endif() @@ -824,6 +796,7 @@ function(cxx_link_system_libraries target) if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21) target_link_libraries(${target} PUBLIC android_support) endif() + target_link_libraries(${target} PUBLIC "${LIBCXX_ADDITIONAL_LIBRARIES}") endfunction() # Windows-related flags ======================================================= @@ -848,32 +821,24 @@ function(cxx_add_windows_flags target) # Use the ISO conforming behaviour for conversion # in printf, scanf. _CRT_STDIO_ISO_WIDE_SPECIFIERS) + # Clang-cl shared builds don't support the experimental library. + # To avoid linker errors the format_error destructor is inlined for the + # dylib. Users can never use format in this mode. + # TODO FMT Remove when format becomes mainline. + if (LIBCXX_ENABLE_SHARED) + target_compile_definitions(${target} PRIVATE + _LIBCPP_INLINE_FORMAT_ERROR_DTOR) + endif() endif() endfunction() # Configuration file flags ===================================================== -if (NOT LIBCXX_ABI_VERSION EQUAL 1) - config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION) -endif() -if (NOT LIBCXX_ABI_NAMESPACE STREQUAL "") - if (NOT LIBCXX_ABI_NAMESPACE MATCHES "__.*") - message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE must be a reserved identifier.") - endif() - if (LIBCXX_ABI_NAMESPACE MATCHES "__[0-9]+$") - message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE '${LIBCXX_ABI_NAMESPACE}' is reserved for use by libc++.") - endif() - config_define(${LIBCXX_ABI_NAMESPACE} _LIBCPP_ABI_NAMESPACE) -endif() -config_define_if(LIBCXX_ABI_UNSTABLE _LIBCPP_ABI_UNSTABLE) +config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION) +config_define(${LIBCXX_ABI_NAMESPACE} _LIBCPP_ABI_NAMESPACE) config_define_if(LIBCXX_ABI_FORCE_ITANIUM _LIBCPP_ABI_FORCE_ITANIUM) config_define_if(LIBCXX_ABI_FORCE_MICROSOFT _LIBCPP_ABI_FORCE_MICROSOFT) -config_define_if(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT) -config_define_if_not(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE) -config_define_if_not(LIBCXX_ENABLE_STDIN _LIBCPP_HAS_NO_STDIN) -config_define_if_not(LIBCXX_ENABLE_STDOUT _LIBCPP_HAS_NO_STDOUT) config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS) config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK) -config_define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS) if (NOT LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION STREQUAL "default") config_define("${LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION}" _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION) endif() @@ -887,11 +852,16 @@ config_define_if(LIBCXX_ENABLE_PARALLEL_ALGORITHMS _LIBCPP_HAS_PARALLEL_ALGORITH config_define_if_not(LIBCXX_ENABLE_FILESYSTEM _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE) config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION) +config_define_if_not(LIBCXX_ENABLE_FSTREAM _LIBCPP_HAS_NO_FSTREAM) +config_define_if_not(LIBCXX_ENABLE_UNICODE _LIBCPP_HAS_NO_UNICODE) +config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTERS) config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) -# Incomplete features get their own specific disabling flags. This makes it -# easier to grep for target specific flags once the feature is complete. -config_define_if_not(LIBCXX_ENABLE_INCOMPLETE_FEATURES _LIBCPP_HAS_NO_INCOMPLETE_FORMAT) -config_define_if_not(LIBCXX_ENABLE_INCOMPLETE_FEATURES _LIBCPP_HAS_NO_INCOMPLETE_RANGES) +config_define_if(LIBCXX_ENABLE_DEBUG_MODE _LIBCPP_ENABLE_DEBUG_MODE) +if (LIBCXX_ENABLE_ASSERTIONS) + config_define(1 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT) +else() + config_define(0 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT) +endif() if (LIBCXX_ABI_DEFINES) set(abi_defines) @@ -905,6 +875,17 @@ if (LIBCXX_ABI_DEFINES) config_define(${abi_defines} _LIBCPP_ABI_DEFINES) endif() +if (LIBCXX_EXTRA_SITE_DEFINES) + set(extra_site_defines) + foreach (extra_site_define ${LIBCXX_EXTRA_SITE_DEFINES}) + # Allow defines such as DEFINE=VAL, transformed into "#define DEFINE VAL". + string(REPLACE "=" " " extra_site_define "${extra_site_define}") + list(APPEND extra_site_defines "#define ${extra_site_define}") + endforeach() + string(REPLACE ";" "\n" extra_site_defines "${extra_site_defines}") + config_define(${extra_site_defines} _LIBCPP_EXTRA_SITE_DEFINES) +endif() + # By default libc++ on Windows expects to use a shared library, which requires # the headers to use DLL import/export semantics. However when building a # static library only we modify the headers to disable DLL import/export. @@ -937,16 +918,16 @@ add_subdirectory(include) add_subdirectory(src) add_subdirectory(utils) -set(LIBCXX_TEST_DEPS "") - -if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) - list(APPEND LIBCXX_TEST_DEPS cxx_experimental) -endif() +set(LIBCXX_TEST_DEPS "cxx_experimental") if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY) list(APPEND LIBCXX_TEST_DEPS cxx_external_threads) endif() +if (LIBCXX_ENABLE_CLANG_TIDY) + list(APPEND LIBCXX_TEST_DEPS cxx-tidy) +endif() + if (LIBCXX_INCLUDE_BENCHMARKS) add_subdirectory(benchmarks) endif() @@ -954,15 +935,6 @@ endif() if (LIBCXX_INCLUDE_TESTS) add_subdirectory(test) add_subdirectory(lib/abi) - if (LIBCXX_STANDALONE_BUILD) - include(AddLLVM) # for get_llvm_lit_path - # Make sure the llvm-lit script is generated into the bin directory, and - # do it after adding all tests, since the generated script will only work - # correctly discovered tests against test locations from the source tree - # that have already been discovered. - add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/llvm-lit - ${CMAKE_CURRENT_BINARY_DIR}/llvm-lit) - endif() endif() if (LIBCXX_INCLUDE_DOCS) diff --git a/gnu/llvm/libcxx/CREDITS.TXT b/gnu/llvm/libcxx/CREDITS.TXT index 49f095d2964..cd5bc08a60f 100644 --- a/gnu/llvm/libcxx/CREDITS.TXT +++ b/gnu/llvm/libcxx/CREDITS.TXT @@ -12,6 +12,13 @@ N: Saleem Abdulrasool E: compnerd@compnerd.org D: Minor patches and Linux fixes. +N: Ulf Adams +D: Invented the Ryu and Ryu Printf algorithms used in floating-point to_chars, and wrote the initial code. + +N: Muiez Ahmed +E: muiez@ibm.com +D: z/OS port. + N: Dan Albert E: danalbert@google.com D: Android support and test runner improvements. @@ -24,9 +31,8 @@ N: Holger Arnold E: holgerar@gmail.com D: Minor fix. -N: Ruben Van Boxem -E: vanboxem dot ruben at gmail dot com -D: Initial Windows patches. +N: Jorg Brown +D: Ported floating-point to_chars from MSVC to libc++. N: David Chisnall E: theraven at theravensnest dot org @@ -41,6 +47,10 @@ N: Jonathan B Coe E: jbcoe@me.com D: Implementation of propagate_const. +N: Matthew Dempsky +E: matthew@dempsky.org +D: Minor patches and bug fixes. + N: Christopher Di Bella E: cjdb@google.com E: cjdb.ns@gmail.com @@ -58,10 +68,6 @@ N: Bill Fisher E: william.w.fisher@gmail.com D: Regex bug fixes. -N: Matthew Dempsky -E: matthew@dempsky.org -D: Minor patches and bug fixes. - N: Google Inc. D: Copyright owner and contributor of the CityHash algorithm @@ -81,6 +87,14 @@ N: Argyrios Kyrtzidis E: kyrtzidis@apple.com D: Bug fixes. +N: Stephan T. Lavavej +E: stl@microsoft.com +E: stl@nuwen.net +D: Implemented floating-point to_chars. + +N: Microsoft Corporation +D: Contributed floating-point to_chars. + N: Bruce Mitchener, Jr. E: bruce.mitchener@gmail.com D: Emscripten-related changes. @@ -113,6 +127,10 @@ N: Jon Roelofs E: jroelofS@jroelofs.com D: Remote testing, Newlib port, baremetal/single-threaded support. +N: Kent Ross +E: k@mad.cash +D: Patches for operator<=> support + N: Jonathan Sauer D: Minor patches, mostly related to constexpr @@ -131,6 +149,10 @@ N: Stephan Tolksdorf E: st@quanttec.com D: Minor fix +N: Ruben Van Boxem +E: vanboxem dot ruben at gmail dot com +D: Initial Windows patches. + N: Michael van der Westhuizen E: r1mikey at gmail dot com @@ -141,6 +163,11 @@ N: Klaas de Vries E: klaas at klaasgaaf dot nl D: Minor bug fix. +N: Mark de Wever +E: koraq at xs4all dot nl +D: Format library support. +D: Finalized the porting of MSVC's to_chars to libc++. + N: Zhang Xiongpang E: zhangxiongpang@gmail.com D: Minor patches and bug fixes. @@ -149,11 +176,11 @@ N: Xing Xue E: xingxue@ca.ibm.com D: AIX port -N: Zhihao Yuan -E: lichray@gmail.com -D: Standard compatibility fixes. - N: Jeffrey Yasskin E: jyasskin@gmail.com E: jyasskin@google.com D: Linux fixes. + +N: Zhihao Yuan +E: lichray@gmail.com +D: Standard compatibility fixes. diff --git a/gnu/llvm/libcxx/TODO.TXT b/gnu/llvm/libcxx/TODO.TXT index cf489d29149..bc785546b48 100644 --- a/gnu/llvm/libcxx/TODO.TXT +++ b/gnu/llvm/libcxx/TODO.TXT @@ -16,60 +16,8 @@ Test Suite Tasks * Improve the quality and portability of the locale test data. * Convert failure tests to use Clang Verify. -Filesystem Tasks -================ -* P0492r2 - Implement National body comments for Filesystem - * INCOMPLETE - US 25: has_filename() is equivalent to just !empty() - * INCOMPLETE - US 31: Everything is defined in terms of one implicit host system - * INCOMPLETE - US 32: Meaning of 27.10.2.1 unclear - * INCOMPLETE - US 33: Definition of canonical path problematic - * INCOMPLETE - US 34: Are there attributes of a file that are not an aspect of the file system? - * INCOMPLETE - US 35: What synchronization is required to avoid a file system race? - * INCOMPLETE - US 36: Symbolic links themselves are attached to a directory via (hard) links - * INCOMPLETE - US 37: The term “redundant current directory (dot) elements” is not defined - * INCOMPLETE - US 38: Duplicates §17.3.16 - * INCOMPLETE - US 39: Remove note: Dot and dot-dot are not directories - * INCOMPLETE - US 40: Not all directories have a parent. - * INCOMPLETE - US 41: The term “parent directory” for a (non-directory) file is unusual - * INCOMPLETE - US 42: Pathname resolution does not always resolve a symlink - * INCOMPLETE - US 43: Concerns about encoded character types - * INCOMPLETE - US 44: Definition of path in terms of a string requires leaky abstraction - * INCOMPLETE - US 45: Generic format portability compromised by unspecified root-name - * INCOMPLETE - US 46: filename can be empty so productions for relative-path are redundant - * INCOMPLETE - US 47: “.” and “..” already match the name production - * INCOMPLETE - US 48: Multiple separators are often meaningful in a root-name - * INCOMPLETE - US 49: What does “method of conversion method” mean? - * INCOMPLETE - US 50: 27.10.8.1 ¶ 1.4 largely redundant with ¶ 1.3 - * INCOMPLETE - US 51: Failing to add / when appending empty string prevents useful apps - * INCOMPLETE - US 52: remove_filename() postcondition is not by itself a definition - * INCOMPLETE - US 53: remove_filename()'s name does not correspond to its behavior - * INCOMPLETE - US 54: remove_filename() is broken - * INCOMPLETE - US 55: replace_extension()'s use of path as parameter is inappropriate - * INCOMPLETE - US 56: Remove replace_extension()'s conditional addition of period - * INCOMPLETE - US 57: On Windows, absolute paths will sort in among relative paths - * INCOMPLETE - US 58: parent_path() behavior for root paths is useless - * INCOMPLETE - US 59: filename() returning path for single path components is bizarre - * INCOMPLETE - US 60: path("/foo/").filename()==path(".") is surprising - * INCOMPLETE - US 61: Leading dots in filename() should not begin an extension - * INCOMPLETE - US 62: It is important that stem()+extension()==filename() - * INCOMPLETE - US 63: lexically_normal() inconsistently treats trailing "/" but not "/.." as directory - * INCOMPLETE - US 73, CA 2: root-name is effectively implementation defined - * INCOMPLETE - US 74, CA 3: The term “pathname” is ambiguous in some contexts - * INCOMPLETE - US 75, CA 4: Extra flag in path constructors is needed - * INCOMPLETE - US 76, CA 5: root-name definition is over-specified. - * INCOMPLETE - US 77, CA 6: operator/ and other appends not useful if arg has root-name - * INCOMPLETE - US 78, CA 7: Member absolute() in 27.10.4.1 is overspecified for non-POSIX-like O/S - * INCOMPLETE - US 79, CA 8: Some operation functions are overspecified for implementation-defined file types - * INCOMPLETE - US 185: Fold error_code and non-error_code signatures into one signature - * INCOMPLETE - FI 14: directory_entry comparisons are members - * INCOMPLETE - Late 36: permissions() error_code overload should be noexcept - * INCOMPLETE - Late 37: permissions() actions should be separate parameter - * INCOMPLETE - Late 42: resize_file() Postcondition missing argument - Misc Tasks ========== * Find all sequences of >2 underscores and eradicate them. * run clang-tidy on libc++ * Document the "conditionally-supported" bits of libc++ -* Look at basic_string's move assignment operator, re LWG 2063 and POCMA -* Put a static_assert in std::allocator to deny const/volatile types (LWG 2447) diff --git a/gnu/llvm/libcxx/appveyor.yml b/gnu/llvm/libcxx/appveyor.yml index ae7c7ad7cf6..ea2c88e5fda 100644 --- a/gnu/llvm/libcxx/appveyor.yml +++ b/gnu/llvm/libcxx/appveyor.yml @@ -45,7 +45,7 @@ build_script: ############################################################################# - cmake -G "%GENERATOR%" %CMAKE_OPTIONS% "-DCMAKE_BUILD_TYPE=%configuration%" - "-DLLVM_PATH=C:\projects\deps\llvm" -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF + "-DLLVM_PATH=C:\projects\deps\llvm" -DLLVM_LIT_ARGS="-sv --show-xfail --show-unsupported" %APPVEYOR_BUILD_FOLDER% diff --git a/gnu/llvm/libcxx/benchmarks/CMakeLists.txt b/gnu/llvm/libcxx/benchmarks/CMakeLists.txt index c4b8247da63..7eb76ac6370 100644 --- a/gnu/llvm/libcxx/benchmarks/CMakeLists.txt +++ b/gnu/llvm/libcxx/benchmarks/CMakeLists.txt @@ -1,3 +1,8 @@ +if (CMAKE_VERSION VERSION_LESS 3.17) + message(WARNING "The libc++ benchmarks won't be available because the version of CMake is too old to support them.") + return() +endif() + include(ExternalProject) include(CheckCXXCompilerFlag) @@ -30,7 +35,7 @@ ExternalProject_Add(google-benchmark-libcxx EXCLUDE_FROM_ALL ON DEPENDS cxx cxx-headers PREFIX benchmark-libcxx - SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark + SOURCE_DIR ${LLVM_THIRD_PARTY_DIR}/benchmark INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} @@ -47,7 +52,7 @@ ExternalProject_Add(google-benchmark-libcxx set(BENCHMARK_NATIVE_TARGET_FLAGS) if (LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN) set(BENCHMARK_NATIVE_TARGET_FLAGS - -gcc-toolchain ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN}) + --gcc-toolchain=${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN}) endif() split_list(BENCHMARK_NATIVE_TARGET_FLAGS) @@ -55,7 +60,7 @@ if (LIBCXX_BENCHMARK_NATIVE_STDLIB) ExternalProject_Add(google-benchmark-native EXCLUDE_FROM_ALL ON PREFIX benchmark-native - SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark + SOURCE_DIR ${LLVM_THIRD_PARTY_DIR}/benchmark INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} @@ -75,56 +80,42 @@ set(BENCHMARK_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(BENCHMARK_LIBCXX_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx) set(BENCHMARK_NATIVE_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native) - -set(BENCHMARK_TEST_COMPILE_FLAGS - -O2 - -fsized-deallocation - -I${BENCHMARK_LIBCXX_INSTALL}/include - -I${LIBCXX_SOURCE_DIR}/test/support -) -set(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS - ${BENCHMARK_TEST_COMPILE_FLAGS} - ${SANITIZER_FLAGS} - -Wno-user-defined-literals - -Wno-suggest-override -) - -set(BENCHMARK_TEST_LIBCXX_LINK_FLAGS - -nodefaultlibs - -L${BENCHMARK_LIBCXX_INSTALL}/lib/ - ${SANITIZER_FLAGS} -) -set(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS - ${BENCHMARK_NATIVE_TARGET_FLAGS} - ${BENCHMARK_TEST_COMPILE_FLAGS} -) -set(BENCHMARK_TEST_NATIVE_LINK_FLAGS - ${BENCHMARK_NATIVE_TARGET_FLAGS} - -L${BENCHMARK_NATIVE_INSTALL}/lib -) -split_list(BENCHMARK_TEST_COMPILE_FLAGS) -split_list(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS) -split_list(BENCHMARK_TEST_LIBCXX_LINK_FLAGS) -split_list(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS) -split_list(BENCHMARK_TEST_NATIVE_LINK_FLAGS) - +add_library( cxx-benchmarks-flags INTERFACE) +target_compile_features( cxx-benchmarks-flags INTERFACE cxx_std_20) +target_compile_options( cxx-benchmarks-flags INTERFACE -fsized-deallocation -nostdinc++) +target_include_directories(cxx-benchmarks-flags INTERFACE "${LIBCXX_GENERATED_INCLUDE_DIR}" + INTERFACE "${BENCHMARK_LIBCXX_INSTALL}/include" + INTERFACE "${LIBCXX_SOURCE_DIR}/test/support") + +add_library( cxx-benchmarks-flags-native INTERFACE) +target_link_libraries( cxx-benchmarks-flags-native INTERFACE cxx-benchmarks-flags) +target_compile_options(cxx-benchmarks-flags-native INTERFACE ${BENCHMARK_NATIVE_TARGET_FLAGS}) +target_link_options( cxx-benchmarks-flags-native INTERFACE ${BENCHMARK_NATIVE_TARGET_FLAGS} "-L${BENCHMARK_NATIVE_INSTALL}/lib") if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++") find_library(LIBSTDCXX_FILESYSTEM_TEST stdc++fs PATHS ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN} PATH_SUFFIXES lib lib64 DOC "The libstdc++ filesystem library used by the benchmarks" ) - if (NOT "${LIBSTDCXX_FILESYSTEM_TEST}" STREQUAL "LIBSTDCXX_FILESYSTEM_TEST-NOTFOUND") - set(LIBSTDCXX_FILESYSTEM_LIB "stdc++fs") - endif() + if (LIBSTDCXX_FILESYSTEM_TEST) + target_link_libraries(cxx-benchmarks-flags-native INTERFACE -lstdc++fs) + endif() +else() + target_link_libraries(cxx-benchmarks-flags-native INTERFACE -lc++fs -lc++experimental) endif() +add_library( cxx-benchmarks-flags-libcxx INTERFACE) +target_link_libraries( cxx-benchmarks-flags-libcxx INTERFACE cxx-benchmarks-flags) +target_compile_options(cxx-benchmarks-flags-libcxx INTERFACE ${SANITIZER_FLAGS} -Wno-user-defined-literals -Wno-suggest-override) +target_link_options( cxx-benchmarks-flags-libcxx INTERFACE -nodefaultlibs "-L${BENCHMARK_LIBCXX_INSTALL}/lib" ${SANITIZER_FLAGS}) + set(libcxx_benchmark_targets) function(add_benchmark_test name source_file) set(libcxx_target ${name}_libcxx) list(APPEND libcxx_benchmark_targets ${libcxx_target}) add_executable(${libcxx_target} EXCLUDE_FROM_ALL ${source_file}) + target_link_libraries(${libcxx_target} PRIVATE cxx-benchmarks-flags-libcxx) add_dependencies(${libcxx_target} cxx google-benchmark-libcxx) add_dependencies(cxx-benchmarks ${libcxx_target}) if (LIBCXX_ENABLE_SHARED) @@ -132,10 +123,7 @@ function(add_benchmark_test name source_file) else() target_link_libraries(${libcxx_target} PRIVATE cxx_static) endif() - if (TARGET cxx_experimental) - target_link_libraries(${libcxx_target} PRIVATE cxx_experimental) - endif() - target_link_libraries(${libcxx_target} PRIVATE -lbenchmark) + target_link_libraries(${libcxx_target} PRIVATE cxx_experimental benchmark) if (LLVM_USE_SANITIZER) target_link_libraries(${libcxx_target} PRIVATE -ldl) endif() @@ -143,27 +131,15 @@ function(add_benchmark_test name source_file) PROPERTIES OUTPUT_NAME "${name}.libcxx.out" RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}" - COMPILE_FLAGS "${BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS}" - LINK_FLAGS "${BENCHMARK_TEST_LIBCXX_LINK_FLAGS}" - CXX_STANDARD 17 - CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO) cxx_link_system_libraries(${libcxx_target}) if (LIBCXX_BENCHMARK_NATIVE_STDLIB) - if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++" AND NOT DEFINED LIBSTDCXX_FILESYSTEM_LIB - AND "${name}" STREQUAL "filesystem") - return() - endif() set(native_target ${name}_native) add_executable(${native_target} EXCLUDE_FROM_ALL ${source_file}) + target_link_libraries(${native_target} PRIVATE cxx-benchmarks-flags-native) add_dependencies(${native_target} google-benchmark-native google-benchmark-libcxx) target_link_libraries(${native_target} PRIVATE -lbenchmark) - if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++") - target_link_libraries(${native_target} PRIVATE ${LIBSTDCXX_FILESYSTEM_LIB}) - elseif (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++") - target_link_libraries(${native_target} PRIVATE -lc++fs -lc++experimental) - endif() if (LIBCXX_HAS_PTHREAD_LIB) target_link_libraries(${native_target} PRIVATE -pthread) endif() @@ -172,11 +148,6 @@ function(add_benchmark_test name source_file) PROPERTIES OUTPUT_NAME "${name}.native.out" RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}" - INCLUDE_DIRECTORIES "" - COMPILE_FLAGS "${BENCHMARK_TEST_NATIVE_COMPILE_FLAGS}" - LINK_FLAGS "${BENCHMARK_TEST_NATIVE_LINK_FLAGS}" - CXX_STANDARD 17 - CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO) endif() endfunction() @@ -185,7 +156,51 @@ endfunction() #============================================================================== # Register Benchmark tests #============================================================================== -file(GLOB BENCHMARK_TESTS "*.bench.cpp") +set(BENCHMARK_TESTS + algorithms.partition_point.bench.cpp + algorithms/lower_bound.bench.cpp + algorithms/make_heap.bench.cpp + algorithms/make_heap_then_sort_heap.bench.cpp + algorithms/min_max_element.bench.cpp + algorithms/pop_heap.bench.cpp + algorithms/push_heap.bench.cpp + algorithms/ranges_make_heap.bench.cpp + algorithms/ranges_make_heap_then_sort_heap.bench.cpp + algorithms/ranges_pop_heap.bench.cpp + algorithms/ranges_push_heap.bench.cpp + algorithms/ranges_sort.bench.cpp + algorithms/ranges_sort_heap.bench.cpp + algorithms/ranges_stable_sort.bench.cpp + algorithms/sort.bench.cpp + algorithms/sort_heap.bench.cpp + algorithms/stable_sort.bench.cpp + allocation.bench.cpp + deque.bench.cpp + deque_iterator.bench.cpp + filesystem.bench.cpp + format_to_n.bench.cpp + format_to.bench.cpp + format.bench.cpp + formatted_size.bench.cpp + formatter_float.bench.cpp + formatter_int.bench.cpp + function.bench.cpp + join_view.bench.cpp + map.bench.cpp + monotonic_buffer.bench.cpp + ordered_set.bench.cpp + std_format_spec_string_unicode.bench.cpp + string.bench.cpp + stringstream.bench.cpp + to_chars.bench.cpp + unordered_set_operations.bench.cpp + util_smartptr.bench.cpp + variant_visit_1.bench.cpp + variant_visit_2.bench.cpp + variant_visit_3.bench.cpp + vector_operations.bench.cpp + ) + foreach(test_path ${BENCHMARK_TESTS}) get_filename_component(test_file "${test_path}" NAME) string(REPLACE ".bench.cpp" "" test_name "${test_file}") @@ -194,7 +209,7 @@ foreach(test_path ${BENCHMARK_TESTS}) # Only report the adding of the benchmark once. set(${test_name}_REPORTED ON CACHE INTERNAL "") endif() - add_benchmark_test(${test_name} ${test_file}) + add_benchmark_test(${test_name} ${test_path}) endforeach() if (LIBCXX_INCLUDE_TESTS) diff --git a/gnu/llvm/libcxx/benchmarks/ContainerBenchmarks.h b/gnu/llvm/libcxx/benchmarks/ContainerBenchmarks.h index d2061f28853..f64869adc99 100644 --- a/gnu/llvm/libcxx/benchmarks/ContainerBenchmarks.h +++ b/gnu/llvm/libcxx/benchmarks/ContainerBenchmarks.h @@ -135,6 +135,20 @@ static void BM_FindRehash(benchmark::State& st, Container c, GenInputs gen) { } } +template +static void BM_Rehash(benchmark::State& st, Container c, GenInputs gen) { + auto in = gen(st.range(0)); + c.max_load_factor(3.0); + c.insert(in.begin(), in.end()); + benchmark::DoNotOptimize(c); + const auto bucket_count = c.bucket_count(); + while (st.KeepRunning()) { + c.rehash(bucket_count + 1); + c.rehash(bucket_count); + benchmark::ClobberMemory(); + } +} + } // end namespace ContainerBenchmarks #endif // BENCHMARK_CONTAINER_BENCHMARKS_H diff --git a/gnu/llvm/libcxx/benchmarks/GenerateInput.h b/gnu/llvm/libcxx/benchmarks/GenerateInput.h index e4f131c628f..3e63f841330 100644 --- a/gnu/llvm/libcxx/benchmarks/GenerateInput.h +++ b/gnu/llvm/libcxx/benchmarks/GenerateInput.h @@ -36,10 +36,9 @@ inline char getRandomChar() { } template -inline IntT getRandomInteger(IntT Min = 0, - IntT Max = std::numeric_limits::max()) { - std::uniform_int_distribution dist(Min, Max); - return dist(getRandomEngine()); +inline IntT getRandomInteger(IntT Min, IntT Max) { + std::uniform_int_distribution dist(Min, Max); + return static_cast(dist(getRandomEngine())); } inline std::string getRandomString(std::size_t Len) { @@ -102,7 +101,7 @@ template std::vector getRandomIntegerInputs(size_t N) { std::vector inputs; for (size_t i=0; i < N; ++i) { - inputs.push_back(getRandomInteger()); + inputs.push_back(getRandomInteger(0, std::numeric_limits::max())); } return inputs; } diff --git a/gnu/llvm/libcxx/benchmarks/algorithms.partition_point.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms.partition_point.bench.cpp index 840cf0391ee..8192f97206d 100644 --- a/gnu/llvm/libcxx/benchmarks/algorithms.partition_point.bench.cpp +++ b/gnu/llvm/libcxx/benchmarks/algorithms.partition_point.bench.cpp @@ -30,7 +30,7 @@ struct TestIntBase { static std::vector generateInput(size_t size) { std::vector Res(size); std::generate(Res.begin(), Res.end(), - [] { return getRandomInteger(); }); + [] { return getRandomInteger(0, std::numeric_limits::max()); }); return Res; } }; diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/common.h b/gnu/llvm/libcxx/benchmarks/algorithms/common.h new file mode 100644 index 00000000000..ffa39e26be5 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/common.h @@ -0,0 +1,244 @@ +//===----------------------------------------------------------------------===// +// +// 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 LIBCXX_ALGORITHMS_COMMON_H +#define LIBCXX_ALGORITHMS_COMMON_H + +#include +#include +#include +#include + +#include "../CartesianBenchmarks.h" +#include "../GenerateInput.h" + +enum class ValueType { Uint32, Uint64, Pair, Tuple, String, Float }; +struct AllValueTypes : EnumValuesAsTuple { + static constexpr const char* Names[] = {"uint32", "uint64", "pair", "tuple", + "string", "float"}; +}; + +using Types = std::tuple< uint32_t, uint64_t, std::pair, std::tuple, + std::string, float >; + +template +using Value = std::tuple_element_t<(int)V::value, Types>; + +enum class Order { + Random, + Ascending, + Descending, + SingleElement, + PipeOrgan, + Heap, + QuickSortAdversary, +}; +struct AllOrders : EnumValuesAsTuple { + static constexpr const char* Names[] = {"Random", "Ascending", + "Descending", "SingleElement", + "PipeOrgan", "Heap", + "QuickSortAdversary"}; +}; + +// fillAdversarialQuickSortInput fills the input vector with N int-like values. +// These values are arranged in such a way that they would invoke O(N^2) +// behavior on any quick sort implementation that satisifies certain conditions. +// Details are available in the following paper: +// "A Killer Adversary for Quicksort", M. D. McIlroy, Software-Practice & +// Experience Volume 29 Issue 4 April 10, 1999 pp 341-344. +// https://dl.acm.org/doi/10.5555/311868.311871. +template +void fillAdversarialQuickSortInput(T& V, size_t N) { + assert(N > 0); + // If an element is equal to gas, it indicates that the value of the element + // is still to be decided and may change over the course of time. + const unsigned int gas = N - 1; + V.resize(N); + for (unsigned int i = 0; i < N; ++i) { + V[i] = gas; + } + // Candidate for the pivot position. + int candidate = 0; + int nsolid = 0; + // Populate all positions in the generated input to gas. + std::vector ascVals(V.size()); + // Fill up with ascending values from 0 to V.size()-1. These will act as + // indices into V. + std::iota(ascVals.begin(), ascVals.end(), 0); + std::sort(ascVals.begin(), ascVals.end(), [&](int x, int y) { + if (V[x] == gas && V[y] == gas) { + // We are comparing two inputs whose value is still to be decided. + if (x == candidate) { + V[x] = nsolid++; + } else { + V[y] = nsolid++; + } + } + if (V[x] == gas) { + candidate = x; + } else if (V[y] == gas) { + candidate = y; + } + return V[x] < V[y]; + }); +} + +template +void fillValues(std::vector& V, size_t N, Order O) { + if (O == Order::SingleElement) { + V.resize(N, 0); + } else if (O == Order::QuickSortAdversary) { + fillAdversarialQuickSortInput(V, N); + } else { + while (V.size() < N) + V.push_back(V.size()); + } +} + +template +void fillValues(std::vector >& V, size_t N, Order O) { + if (O == Order::SingleElement) { + V.resize(N, std::make_pair(0, 0)); + } else { + while (V.size() < N) + // Half of array will have the same first element. + if (V.size() % 2) { + V.push_back(std::make_pair(V.size(), V.size())); + } else { + V.push_back(std::make_pair(0, V.size())); + } + } +} + +template +void fillValues(std::vector >& V, size_t N, Order O) { + if (O == Order::SingleElement) { + V.resize(N, std::make_tuple(0, 0, 0)); + } else { + while (V.size() < N) + // One third of array will have the same first element. + // One third of array will have the same first element and the same second element. + switch (V.size() % 3) { + case 0: + V.push_back(std::make_tuple(V.size(), V.size(), V.size())); + break; + case 1: + V.push_back(std::make_tuple(0, V.size(), V.size())); + break; + case 2: + V.push_back(std::make_tuple(0, 0, V.size())); + break; + } + } +} + +inline void fillValues(std::vector& V, size_t N, Order O) { + if (O == Order::SingleElement) { + V.resize(N, getRandomString(64)); + } else { + while (V.size() < N) + V.push_back(getRandomString(64)); + } +} + +template +void sortValues(T& V, Order O) { + switch (O) { + case Order::Random: { + std::random_device R; + std::mt19937 M(R()); + std::shuffle(V.begin(), V.end(), M); + break; + } + case Order::Ascending: + std::sort(V.begin(), V.end()); + break; + case Order::Descending: + std::sort(V.begin(), V.end(), std::greater<>()); + break; + case Order::SingleElement: + // Nothing to do + break; + case Order::PipeOrgan: + std::sort(V.begin(), V.end()); + std::reverse(V.begin() + V.size() / 2, V.end()); + break; + case Order::Heap: + std::make_heap(V.begin(), V.end()); + break; + case Order::QuickSortAdversary: + // Nothing to do + break; + } +} + +constexpr size_t TestSetElements = +#if !TEST_HAS_FEATURE(memory_sanitizer) + 1 << 18; +#else + 1 << 14; +#endif + +template +std::vector > > makeOrderedValues(size_t N, + Order O) { + std::vector > > Ret; + const size_t NumCopies = std::max(size_t{1}, TestSetElements / N); + Ret.resize(NumCopies); + for (auto& V : Ret) { + fillValues(V, N, O); + sortValues(V, O); + } + return Ret; +} + +template +TEST_ALWAYS_INLINE void resetCopies(benchmark::State& state, T& Copies, + U& Orig) { + state.PauseTiming(); + for (auto& Copy : Copies) + Copy = Orig; + state.ResumeTiming(); +} + +enum class BatchSize { + CountElements, + CountBatch, +}; + +template +void runOpOnCopies(benchmark::State& state, size_t Quantity, Order O, + BatchSize Count, F Body) { + auto Copies = makeOrderedValues(Quantity, O); + auto Orig = Copies; + + const size_t Batch = Count == BatchSize::CountElements + ? Copies.size() * Quantity + : Copies.size(); + while (state.KeepRunningBatch(Batch)) { + for (auto& Copy : Copies) { + Body(Copy); + benchmark::DoNotOptimize(Copy); + } + state.PauseTiming(); + Copies = Orig; + state.ResumeTiming(); + } +} + + +const std::vector Quantities = {1 << 0, 1 << 2, 1 << 4, 1 << 6, + 1 << 8, 1 << 10, 1 << 14, + // Running each benchmark in parallel consumes too much memory with MSAN + // and can lead to the test process being killed. +#if !TEST_HAS_FEATURE(memory_sanitizer) + 1 << 18 +#endif +}; + +#endif // LIBCXX_ALGORITHMS_COMMON_H diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/lower_bound.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/lower_bound.bench.cpp new file mode 100644 index 00000000000..ce366d5e9d4 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/lower_bound.bench.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include + +#include "common.h" + +namespace { +template +struct LowerBound { + size_t Quantity; + + mutable std::mt19937_64 rng { std::random_device{}() }; + + void run(benchmark::State& state) const { + runOpOnCopies(state, Quantity, Order::Ascending, BatchSize::CountBatch, [&](auto& Copy) { + auto result = std::lower_bound(Copy.begin(), Copy.end(), Copy[rng() % Copy.size()]); + benchmark::DoNotOptimize(result); + }); + } + + std::string name() const { + return "BM_LowerBound" + ValueType::name() + "_" + std::to_string(Quantity); + } +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/make_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/make_heap.bench.cpp new file mode 100644 index 00000000000..e2caf84d137 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/make_heap.bench.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 + +#include "common.h" + +namespace { +template +struct MakeHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { std::make_heap(Copy.begin(), Copy.end()); }); + } + + std::string name() const { + return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.cpp new file mode 100644 index 00000000000..5254c261e3e --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.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 + +#include "common.h" + +namespace { +template +struct MakeThenSortHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies(state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { + std::make_heap(Copy.begin(), Copy.end()); + std::sort_heap(Copy.begin(), Copy.end()); + }); + } + + std::string name() const { + return "BM_MakeThenSortHeap" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/min_max_element.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/min_max_element.bench.cpp new file mode 100644 index 00000000000..e2c64236561 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/min_max_element.bench.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +#include "common.h" + +namespace { +template +struct MinMaxElement { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies(state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) { + benchmark::DoNotOptimize(std::minmax_element(Copy.begin(), Copy.end())); + }); + } + + std::string name() const { + return "BM_MinMaxElement" + ValueType::name() + Order::name() + "_" + std::to_string(Quantity); + } +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/pop_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/pop_heap.bench.cpp new file mode 100644 index 00000000000..ef6e5a66974 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/pop_heap.bench.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 + +#include "common.h" + +namespace { +template +struct PopHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) { + for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) { + std::pop_heap(B, I); + } + }); + } + + std::string name() const { + return "BM_PopHeap" + ValueType::name() + "_" + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/push_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/push_heap.bench.cpp new file mode 100644 index 00000000000..8c333240f7c --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/push_heap.bench.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +#include "common.h" + +namespace { +template +struct PushHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) { + for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) { + std::push_heap(Copy.begin(), I + 1); + } + }); + } + + bool skip() const { return Order() == ::Order::Heap; } + + std::string name() const { + return "BM_PushHeap" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/ranges_make_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_make_heap.bench.cpp new file mode 100644 index 00000000000..b5b6132382d --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_make_heap.bench.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 + +#include "common.h" + +namespace { +template +struct RangesMakeHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { std::ranges::make_heap(Copy); }); + } + + std::string name() const { + return "BM_RangesMakeHeap" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/ranges_make_heap_then_sort_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_make_heap_then_sort_heap.bench.cpp new file mode 100644 index 00000000000..f2869513530 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_make_heap_then_sort_heap.bench.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 + +#include "common.h" + +namespace { +template +struct RangesMakeThenSortHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies(state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { + std::ranges::make_heap(Copy); + std::ranges::sort_heap(Copy); + }); + } + + std::string name() const { + return "BM_RangesMakeThenSortHeap" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/ranges_pop_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_pop_heap.bench.cpp new file mode 100644 index 00000000000..b26ccdd97a7 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_pop_heap.bench.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 + +#include "common.h" + +namespace { +template +struct RangesPopHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) { + for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) { + std::ranges::pop_heap(B, I); + } + }); + } + + std::string name() const { + return "BM_RangesPopHeap" + ValueType::name() + "_" + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/ranges_push_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_push_heap.bench.cpp new file mode 100644 index 00000000000..28ccf41b964 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_push_heap.bench.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +#include "common.h" + +namespace { +template +struct RangesPushHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) { + for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) { + std::ranges::push_heap(Copy.begin(), I + 1); + } + }); + } + + bool skip() const { return Order() == ::Order::Heap; } + + std::string name() const { + return "BM_RangesPushHeap" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/ranges_sort.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_sort.bench.cpp new file mode 100644 index 00000000000..b9299d3fe14 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_sort.bench.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 + +#include "common.h" + +namespace { +template +struct Sort { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { std::ranges::sort(Copy); }); + } + + bool skip() const { return Order() == ::Order::Heap; } + + std::string name() const { + return "BM_RangesSort" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + } +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/ranges_sort_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_sort_heap.bench.cpp new file mode 100644 index 00000000000..12828a02958 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_sort_heap.bench.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +#include "common.h" + +namespace { +template +struct RangesSortHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order::Heap, BatchSize::CountElements, + [](auto& Copy) { std::ranges::sort_heap(Copy); }); + } + + std::string name() const { + return "BM_RangesSortHeap" + ValueType::name() + "_" + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/ranges_stable_sort.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_stable_sort.bench.cpp new file mode 100644 index 00000000000..94f80032afc --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/ranges_stable_sort.bench.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 + +#include "common.h" + +namespace { +template +struct StableSort { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { std::ranges::stable_sort(Copy); }); + } + + bool skip() const { return Order() == ::Order::Heap; } + + std::string name() const { + return "BM_RangesStableSort" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + } +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/sort.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/sort.bench.cpp new file mode 100644 index 00000000000..6f8b12efe45 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/sort.bench.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 + +#include "common.h" + +namespace { +template +struct Sort { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { std::sort(Copy.begin(), Copy.end()); }); + } + + bool skip() const { return Order() == ::Order::Heap; } + + std::string name() const { + return "BM_Sort" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/sort_heap.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/sort_heap.bench.cpp new file mode 100644 index 00000000000..a217211a2f8 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/sort_heap.bench.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +#include "common.h" + +namespace { +template +struct SortHeap { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order::Heap, BatchSize::CountElements, + [](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); }); + } + + std::string name() const { + return "BM_SortHeap" + ValueType::name() + "_" + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/algorithms/stable_sort.bench.cpp b/gnu/llvm/libcxx/benchmarks/algorithms/stable_sort.bench.cpp new file mode 100644 index 00000000000..1ef55ce9fe9 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/algorithms/stable_sort.bench.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 + +#include "common.h" + +namespace { +template +struct StableSort { + size_t Quantity; + + void run(benchmark::State& state) const { + runOpOnCopies( + state, Quantity, Order(), BatchSize::CountElements, + [](auto& Copy) { std::stable_sort(Copy.begin(), Copy.end()); }); + } + + bool skip() const { return Order() == ::Order::Heap; } + + std::string name() const { + return "BM_StableSort" + ValueType::name() + Order::name() + "_" + + std::to_string(Quantity); + }; +}; +} // namespace + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + makeCartesianProductBenchmark(Quantities); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/allocation.bench.cpp b/gnu/llvm/libcxx/benchmarks/allocation.bench.cpp index 236e74044a5..ad962de5bf1 100644 --- a/gnu/llvm/libcxx/benchmarks/allocation.bench.cpp +++ b/gnu/llvm/libcxx/benchmarks/allocation.bench.cpp @@ -97,7 +97,6 @@ static void BM_DeallocateOnly(benchmark::State& st) { const size_t alloc_size = st.range(0); const auto NumAllocs = st.max_iterations; - using PtrT = void*; std::vector Pointers(NumAllocs); for (auto& p : Pointers) { p = AllocWrapper::Allocate(alloc_size); diff --git a/gnu/llvm/libcxx/benchmarks/deque.bench.cpp b/gnu/llvm/libcxx/benchmarks/deque.bench.cpp index 0025a335ccf..61b45cbf4ec 100644 --- a/gnu/llvm/libcxx/benchmarks/deque.bench.cpp +++ b/gnu/llvm/libcxx/benchmarks/deque.bench.cpp @@ -1,4 +1,3 @@ -// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. diff --git a/gnu/llvm/libcxx/benchmarks/deque_iterator.bench.cpp b/gnu/llvm/libcxx/benchmarks/deque_iterator.bench.cpp new file mode 100644 index 00000000000..0eb23f2f3be --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/deque_iterator.bench.cpp @@ -0,0 +1,232 @@ +//===----------------------------------------------------------------------===// +// +// 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 +#include + +#include "benchmark/benchmark.h" + +namespace { +void run_sizes(auto benchmark) { + benchmark->Arg(0) + ->Arg(1) + ->Arg(2) + ->Arg(64) + ->Arg(512) + ->Arg(1024) + ->Arg(4000) + ->Arg(4096) + ->Arg(5500) + ->Arg(64000) + ->Arg(65536) + ->Arg(70000); +} + +template +void benchmark_containers(benchmark::State& state, FromContainer& d, ToContainer& v, Func&& func) { + for (auto _ : state) { + benchmark::DoNotOptimize(v); + benchmark::DoNotOptimize(d); + func(d.begin(), d.end(), v.begin()); + } +} + +template +void benchmark_deque_vector(benchmark::State& state, Func&& func) { + auto size = state.range(0); + std::deque d; + d.resize(size); + std::ranges::fill(d, 10); + std::vector v; + v.resize(size); + benchmark_containers(state, d, v, func); +} + +template +void benchmark_deque_deque(benchmark::State& state, Func&& func) { + auto size = state.range(0); + std::deque d; + d.resize(size); + std::ranges::fill(d, 10); + std::deque v; + v.resize(size); + benchmark_containers(state, d, v, func); +} + +template +void benchmark_vector_deque(benchmark::State& state, Func&& func) { + auto size = state.range(0); + std::vector d; + d.resize(size); + std::ranges::fill(d, 10); + std::deque v; + v.resize(size); + benchmark_containers(state, d, v, func); +} + +template +void benchmark_containers_backward(benchmark::State& state, FromContainer& d, ToContainer& v, Func&& func) { + for (auto _ : state) { + benchmark::DoNotOptimize(v); + benchmark::DoNotOptimize(d); + func(d.begin(), d.end(), v.end()); + } +} + +template +void benchmark_deque_vector_backward(benchmark::State& state, Func&& func) { + auto size = state.range(0); + std::deque d; + d.resize(size); + std::ranges::fill(d, 10); + std::vector v; + v.resize(size); + benchmark_containers_backward(state, d, v, func); +} + +template +void benchmark_deque_deque_backward(benchmark::State& state, Func&& func) { + auto size = state.range(0); + std::deque d; + d.resize(size); + std::ranges::fill(d, 10); + std::deque v; + v.resize(size); + benchmark_containers_backward(state, d, v, func); +} + +template +void benchmark_vector_deque_backward(benchmark::State& state, Func&& func) { + auto size = state.range(0); + std::vector d; + d.resize(size); + std::ranges::fill(d, 10); + std::deque v; + v.resize(size); + benchmark_containers_backward(state, d, v, func); +} + +struct CopyFunctor { + template + auto operator()(Args... args) const { + std::copy(std::forward(args)...); + } +} copy; + +struct MoveFunctor { + template + auto operator()(Args... args) const { + std::move(std::forward(args)...); + } +} move; + +struct CopyBackwardFunctor { + template + auto operator()(Args... args) const { + std::copy_backward(std::forward(args)...); + } +} copy_backward; + +struct MoveBackwardFunctor { + template + auto operator()(Args... args) const { + std::move_backward(std::forward(args)...); + } +} move_backward; + +// copy +void BM_deque_vector_copy(benchmark::State& state) { benchmark_deque_vector(state, copy); } +BENCHMARK(BM_deque_vector_copy)->Apply(run_sizes); + +void BM_deque_vector_ranges_copy(benchmark::State& state) { benchmark_deque_vector(state, std::ranges::copy); } +BENCHMARK(BM_deque_vector_ranges_copy)->Apply(run_sizes); + +void BM_deque_deque_copy(benchmark::State& state) { benchmark_deque_deque(state, copy); } +BENCHMARK(BM_deque_deque_copy)->Apply(run_sizes); + +void BM_deque_deque_ranges_copy(benchmark::State& state) { benchmark_deque_deque(state, std::ranges::copy); } +BENCHMARK(BM_deque_deque_ranges_copy)->Apply(run_sizes); + +void BM_vector_deque_copy(benchmark::State& state) { benchmark_vector_deque(state, copy); } +BENCHMARK(BM_vector_deque_copy)->Apply(run_sizes); + +void BM_vector_deque_ranges_copy(benchmark::State& state) { benchmark_vector_deque(state, std::ranges::copy); } +BENCHMARK(BM_vector_deque_ranges_copy)->Apply(run_sizes); + +// move +void BM_deque_vector_move(benchmark::State& state) { benchmark_deque_vector(state, move); } +BENCHMARK(BM_deque_vector_move)->Apply(run_sizes); + +void BM_deque_vector_ranges_move(benchmark::State& state) { benchmark_deque_vector(state, std::ranges::move); } +BENCHMARK(BM_deque_vector_ranges_move)->Apply(run_sizes); + +void BM_deque_deque_move(benchmark::State& state) { benchmark_deque_deque(state, move); } +BENCHMARK(BM_deque_deque_move)->Apply(run_sizes); + +void BM_deque_deque_ranges_move(benchmark::State& state) { benchmark_deque_deque(state, std::ranges::move); } +BENCHMARK(BM_deque_deque_ranges_move)->Apply(run_sizes); + +void BM_vector_deque_move(benchmark::State& state) { benchmark_vector_deque(state, move); } +BENCHMARK(BM_vector_deque_move)->Apply(run_sizes); + +void BM_vector_deque_ranges_move(benchmark::State& state) { benchmark_vector_deque(state, std::ranges::move); } +BENCHMARK(BM_vector_deque_ranges_move)->Apply(run_sizes); + +// copy_backward +void BM_deque_vector_copy_backward(benchmark::State& state) { benchmark_deque_vector_backward(state, copy_backward); } +BENCHMARK(BM_deque_vector_copy_backward)->Apply(run_sizes); + +void BM_deque_vector_ranges_copy_backward(benchmark::State& state) { + benchmark_deque_vector_backward(state, std::ranges::copy_backward); +} +BENCHMARK(BM_deque_vector_ranges_copy_backward)->Apply(run_sizes); + +void BM_deque_deque_copy_backward(benchmark::State& state) { benchmark_deque_deque_backward(state, copy_backward); } +BENCHMARK(BM_deque_deque_copy_backward)->Apply(run_sizes); + +void BM_deque_deque_ranges_copy_backward(benchmark::State& state) { + benchmark_deque_deque_backward(state, std::ranges::copy_backward); +} +BENCHMARK(BM_deque_deque_ranges_copy_backward)->Apply(run_sizes); + +void BM_vector_deque_copy_backward(benchmark::State& state) { benchmark_vector_deque_backward(state, copy_backward); } +BENCHMARK(BM_vector_deque_copy_backward)->Apply(run_sizes); + +void BM_vector_deque_ranges_copy_backward(benchmark::State& state) { + benchmark_vector_deque_backward(state, std::ranges::copy_backward); +} +BENCHMARK(BM_vector_deque_ranges_copy_backward)->Apply(run_sizes); + +// move_backward +void BM_deque_vector_move_backward(benchmark::State& state) { benchmark_deque_vector_backward(state, move_backward); } +BENCHMARK(BM_deque_vector_move_backward)->Apply(run_sizes); + +void BM_deque_vector_ranges_move_backward(benchmark::State& state) { + benchmark_deque_vector_backward(state, std::ranges::move_backward); +} +BENCHMARK(BM_deque_vector_ranges_move_backward)->Apply(run_sizes); + +void BM_deque_deque_move_backward(benchmark::State& state) { benchmark_deque_deque_backward(state, move_backward); } +BENCHMARK(BM_deque_deque_move_backward)->Apply(run_sizes); + +void BM_deque_deque_ranges_move_backward(benchmark::State& state) { + benchmark_deque_deque_backward(state, std::ranges::move_backward); +} +BENCHMARK(BM_deque_deque_ranges_move_backward)->Apply(run_sizes); + +void BM_vector_deque_move_backward(benchmark::State& state) { benchmark_vector_deque_backward(state, move_backward); } +BENCHMARK(BM_vector_deque_move_backward)->Apply(run_sizes); + +void BM_vector_deque_ranges_move_backward(benchmark::State& state) { + benchmark_vector_deque_backward(state, std::ranges::move_backward); +} +BENCHMARK(BM_vector_deque_ranges_move_backward)->Apply(run_sizes); + +} // namespace + +BENCHMARK_MAIN(); diff --git a/gnu/llvm/libcxx/benchmarks/filesystem.bench.cpp b/gnu/llvm/libcxx/benchmarks/filesystem.bench.cpp index 95aecd50473..4fe4fc503ca 100644 --- a/gnu/llvm/libcxx/benchmarks/filesystem.bench.cpp +++ b/gnu/llvm/libcxx/benchmarks/filesystem.bench.cpp @@ -83,7 +83,7 @@ void BM_PathIterateMultipleTimes(benchmark::State &st, GenInputs gen) { PP /= Part; benchmark::DoNotOptimize(PP.native().data()); while (st.KeepRunning()) { - for (auto &E : PP) { + for (auto const& E : PP) { benchmark::DoNotOptimize(E.native().data()); } benchmark::ClobberMemory(); @@ -104,7 +104,7 @@ void BM_PathIterateOnce(benchmark::State &st, GenInputs gen) { benchmark::DoNotOptimize(PP.native().data()); while (st.KeepRunning()) { const path P = PP.native(); - for (auto &E : P) { + for (auto const& E : P) { benchmark::DoNotOptimize(E.native().data()); } benchmark::ClobberMemory(); diff --git a/gnu/llvm/libcxx/benchmarks/format.bench.cpp b/gnu/llvm/libcxx/benchmarks/format.bench.cpp new file mode 100644 index 00000000000..89f113253ea --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/format.bench.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// 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 + +#include + +#include "benchmark/benchmark.h" +#include "make_string.h" + +#define CSTR(S) MAKE_CSTRING(CharT, S) + +template +static void BM_format_string(benchmark::State& state) { + size_t size = state.range(0); + std::basic_string str(size, CharT('*')); + + while (state.KeepRunningBatch(str.size())) + benchmark::DoNotOptimize(std::format(CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} +BENCHMARK_TEMPLATE(BM_format_string, char)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_string, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/format_to.bench.cpp b/gnu/llvm/libcxx/benchmarks/format_to.bench.cpp new file mode 100644 index 00000000000..4d6489786b9 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/format_to.bench.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// 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 + +#include +#include +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" +#include "make_string.h" + +#define CSTR(S) MAKE_CSTRING(CharT, S) + +/*** Back inserter ***/ + +template +static void BM_format_to_string_back_inserter(benchmark::State& state) { + using CharT = typename Container::value_type; + size_t size = state.range(0); + auto str = std::basic_string(size, CharT('*')); + + for (auto _ : state) { + Container output; + benchmark::DoNotOptimize(std::format_to(std::back_inserter(output), CSTR("{}"), str)); + } + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Begin ***/ + +template +static void BM_format_to_string_begin(benchmark::State& state) { + using CharT = typename Container::value_type; + size_t size = state.range(0); + auto str = std::basic_string(size, CharT('*')); + + Container output(size, CharT('-')); + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(std::begin(output), CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Pointer ***/ + +template +static void BM_format_to_string_span(benchmark::State& state) { + size_t size = state.range(0); + auto str = std::basic_string(size, CharT('*')); + + auto buffer = std::basic_string(size, CharT('-')); + std::span output{buffer}; + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(std::begin(output), CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +template +static void BM_format_to_string_pointer(benchmark::State& state) { + size_t size = state.range(0); + auto str = std::basic_string(size, CharT('*')); + + auto buffer = std::basic_string(size, CharT('-')); + CharT* output = buffer.data(); + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(output, CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Main ***/ + +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::string)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::string)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_span, char)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_pointer, char)->RangeMultiplier(2)->Range(1, 1 << 20); + +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_back_inserter, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_begin, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_span, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_string_pointer, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/format_to_n.bench.cpp b/gnu/llvm/libcxx/benchmarks/format_to_n.bench.cpp new file mode 100644 index 00000000000..c1e52b0104b --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/format_to_n.bench.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// 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 + +#include +#include +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" +#include "make_string.h" + +#define CSTR(S) MAKE_CSTRING(CharT, S) + +/*** Back inserter ***/ + +template +static void BM_format_to_n_string_back_inserter(benchmark::State& state) { + using CharT = typename Container::value_type; + size_t size = state.range(0); + auto str = std::basic_string(2 * size, CharT('*')); + + for (auto _ : state) { + Container output; + benchmark::DoNotOptimize(std::format_to_n(std::back_inserter(output), size, CSTR("{}"), str)); + } + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Begin ***/ + +template +static void BM_format_to_n_string_begin(benchmark::State& state) { + using CharT = typename Container::value_type; + size_t size = state.range(0); + auto str = std::basic_string(2 * size, CharT('*')); + + Container output(size, CharT('-')); + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to_n(std::begin(output), size, CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Pointer ***/ + +template +static void BM_format_to_n_string_span(benchmark::State& state) { + size_t size = state.range(0); + auto str = std::basic_string(2 * size, CharT('*')); + + auto buffer = std::basic_string(size, CharT('-')); + std::span output{buffer}; + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to_n(std::begin(output), size, CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +template +static void BM_format_to_n_string_pointer(benchmark::State& state) { + size_t size = state.range(0); + auto str = std::basic_string(2 * size, CharT('*')); + + auto buffer = std::basic_string(size, CharT('-')); + CharT* output = buffer.data(); + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to_n(output, size, CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} + +/*** Main ***/ + +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::string)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::string)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_span, char)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_pointer, char)->RangeMultiplier(2)->Range(1, 1 << 20); + +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_back_inserter, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::wstring)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::vector)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_begin, std::list)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_span, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_format_to_n_string_pointer, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/formatted_size.bench.cpp b/gnu/llvm/libcxx/benchmarks/formatted_size.bench.cpp new file mode 100644 index 00000000000..de67dae719a --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/formatted_size.bench.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// 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 + +#include + +#include "benchmark/benchmark.h" +#include "make_string.h" + +#define CSTR(S) MAKE_CSTRING(CharT, S) + +template +static void BM_formatted_size_string(benchmark::State& state) { + size_t size = state.range(0); + std::basic_string str(size, CharT('*')); + + while (state.KeepRunningBatch(str.size())) + benchmark::DoNotOptimize(std::formatted_size(CSTR("{}"), str)); + + state.SetBytesProcessed(state.iterations() * size * sizeof(CharT)); +} +BENCHMARK_TEMPLATE(BM_formatted_size_string, char)->RangeMultiplier(2)->Range(1, 1 << 20); +BENCHMARK_TEMPLATE(BM_formatted_size_string, wchar_t)->RangeMultiplier(2)->Range(1, 1 << 20); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/formatter_float.bench.cpp b/gnu/llvm/libcxx/benchmarks/formatter_float.bench.cpp new file mode 100644 index 00000000000..09963b6108f --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/formatter_float.bench.cpp @@ -0,0 +1,251 @@ +//===----------------------------------------------------------------------===// +// 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 + +#include +#include +#include +#include + +#include "CartesianBenchmarks.h" +#include "benchmark/benchmark.h" + +// *** Localization *** +enum class LocalizationE { False, True }; +struct AllLocalizations : EnumValuesAsTuple { + static constexpr const char* Names[] = {"LocFalse", "LocTrue"}; +}; + +template +struct Localization {}; + +template <> +struct Localization { + static constexpr const char* fmt = ""; +}; + +template <> +struct Localization { + static constexpr const char* fmt = "L"; +}; + +// *** Types *** +enum class TypeE { Float, Double, LongDouble }; +// TODO FMT Set to 3 after to_chars has long double suport. +struct AllTypes : EnumValuesAsTuple { + static constexpr const char* Names[] = {"Float", "Double", "LongDouble"}; +}; + +template +struct Type {}; + +template <> +struct Type { + using type = float; +}; + +template <> +struct Type { + using type = double; +}; + +template <> +struct Type { + using type = long double; +}; + +// *** Values *** +enum class ValueE { Inf, Random }; +struct AllValues : EnumValuesAsTuple { + static constexpr const char* Names[] = {"Inf", "Random"}; +}; + +template +struct Value {}; + +template <> +struct Value { + template + static std::array make_data() { + std::array result; + std::fill(result.begin(), result.end(), -std::numeric_limits::infinity()); + return result; + } +}; + +template <> +struct Value { + template + static std::array make_data() { + std::random_device seed; + std::mt19937 generator(seed()); + std::uniform_int_distribution> distribution; + + std::array result; + std::generate(result.begin(), result.end(), [&] { + while (true) { + auto result = std::bit_cast(distribution(generator)); + if (std::isfinite(result)) + return result; + } + }); + return result; + } +}; + +// *** Display Type *** +enum class DisplayTypeE { + Default, + Hex, + Scientific, + Fixed, + General, +}; +struct AllDisplayTypes : EnumValuesAsTuple { + static constexpr const char* Names[] = {"DisplayDefault", "DisplayHex", "DisplayScientific", "DisplayFixed", + "DisplayGeneral"}; +}; + +template +struct DisplayType {}; + +template <> +struct DisplayType { + static constexpr const char* fmt = ""; +}; + +template <> +struct DisplayType { + static constexpr const char* fmt = "a"; +}; + +template <> +struct DisplayType { + static constexpr const char* fmt = "e"; +}; + +template <> +struct DisplayType { + static constexpr const char* fmt = "f"; +}; + +template <> +struct DisplayType { + static constexpr const char* fmt = "g"; +}; + +// *** Alignment *** +enum class AlignmentE { None, Left, Center, Right, ZeroPadding }; +struct AllAlignments : EnumValuesAsTuple { + static constexpr const char* Names[] = {"AlignNone", "AlignmentLeft", "AlignmentCenter", "AlignmentRight", + "ZeroPadding"}; +}; + +template +struct Alignment {}; + +template <> +struct Alignment { + static constexpr const char* fmt = ""; +}; + +template <> +struct Alignment { + // Width > PrecisionE::Huge + static constexpr const char* fmt = "0<17500"; +}; + +template <> +struct Alignment { + // Width > PrecisionE::Huge + static constexpr const char* fmt = "0^17500"; +}; + +template <> +struct Alignment { + // Width > PrecisionE::Huge + static constexpr const char* fmt = "0>17500"; +}; + +template <> +struct Alignment { + // Width > PrecisionE::Huge + static constexpr const char* fmt = "017500"; +}; + +enum class PrecisionE { None, Zero, Small, Huge }; +struct AllPrecisions : EnumValuesAsTuple { + static constexpr const char* Names[] = {"PrecNone", "PrecZero", "PrecSmall", "PrecHuge"}; +}; + +template +struct Precision {}; + +template <> +struct Precision { + static constexpr const char* fmt = ""; +}; + +template <> +struct Precision { + static constexpr const char* fmt = ".0"; +}; + +template <> +struct Precision { + static constexpr const char* fmt = ".10"; +}; + +template <> +struct Precision { + // The maximum precision for a minimal sub normal long double is +/- 0x1p-16494. + // This value is always larger than that value forcing the trailing zero path + // to be executed. + static constexpr const char* fmt = ".17000"; +}; + +template +struct FloatingPoint { + using F = typename Type::type; + + void run(benchmark::State& state) const { + std::array data{Value::template make_data()}; + std::array output; + + while (state.KeepRunningBatch(1000)) + for (F value : data) + benchmark::DoNotOptimize(std::format_to(output.begin(), std::string_view{fmt.data(), fmt.size()}, value)); + } + + std::string name() const { + return "FloatingPoint" + L::name() + DT::name() + T::name() + V::name() + A::name() + P::name(); + } + + static constexpr std::string make_fmt() { + return std::string("{:") + Alignment::fmt + Precision::fmt + Localization::fmt + + DisplayType::fmt + "}"; + } + + static constexpr auto fmt = []() { + constexpr size_t s = make_fmt().size(); + std::array r; + std::ranges::copy(make_fmt(), r.begin()); + return r; + }(); +}; + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + makeCartesianProductBenchmark(); + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/formatter_int.bench.cpp b/gnu/llvm/libcxx/benchmarks/formatter_int.bench.cpp new file mode 100644 index 00000000000..a42d96491a2 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/formatter_int.bench.cpp @@ -0,0 +1,208 @@ +//===----------------------------------------------------------------------===// +// 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 +#include +#include + +#include "benchmark/benchmark.h" +#include "CartesianBenchmarks.h" + +// Tests the full range of the value. +template +static std::array +generate(std::uniform_int_distribution distribution = std::uniform_int_distribution{ + std::numeric_limits::min(), std::numeric_limits::max()}) { + std::mt19937 generator; + std::array result; + std::generate_n(result.begin(), result.size(), [&] { return distribution(generator); }); + return result; +} + +template +static void BM_Basic(benchmark::State& state) { + std::array data{generate()}; + std::array output; + + while (state.KeepRunningBatch(data.size())) + for (auto value : data) + benchmark::DoNotOptimize(std::format_to(output.begin(), "{}", value)); +} +BENCHMARK_TEMPLATE(BM_Basic, uint32_t); +BENCHMARK_TEMPLATE(BM_Basic, int32_t); +BENCHMARK_TEMPLATE(BM_Basic, uint64_t); +BENCHMARK_TEMPLATE(BM_Basic, int64_t); + +// Ideally the low values of a 128-bit value are all dispatched to a 64-bit routine. +template +static void BM_BasicLow(benchmark::State& state) { + using U = std::conditional_t, int64_t, uint64_t>; + std::array data{ + generate(std::uniform_int_distribution{std::numeric_limits::min(), std::numeric_limits::max()})}; + std::array output; + + while (state.KeepRunningBatch(data.size())) + for (auto value : data) + benchmark::DoNotOptimize(std::format_to(output.begin(), "{}", value)); +} +BENCHMARK_TEMPLATE(BM_BasicLow, __uint128_t); +BENCHMARK_TEMPLATE(BM_BasicLow, __int128_t); + +BENCHMARK_TEMPLATE(BM_Basic, __uint128_t); +BENCHMARK_TEMPLATE(BM_Basic, __int128_t); + +// *** Localization *** +enum class LocalizationE { False, True }; +struct AllLocalizations : EnumValuesAsTuple { + static constexpr const char* Names[] = {"LocFalse", "LocTrue"}; +}; + +template +struct Localization {}; + +template <> +struct Localization { + static constexpr const char* fmt = ""; +}; + +template <> +struct Localization { + static constexpr const char* fmt = "L"; +}; + +// *** Base *** +enum class BaseE { + Binary, + Octal, + Decimal, + Hex, + HexUpper, +}; +struct AllBases : EnumValuesAsTuple { + static constexpr const char* Names[] = {"BaseBin", "BaseOct", "BaseDec", "BaseHex", "BaseHexUpper"}; +}; + +template +struct Base {}; + +template <> +struct Base { + static constexpr const char* fmt = "b"; +}; + +template <> +struct Base { + static constexpr const char* fmt = "o"; +}; + +template <> +struct Base { + static constexpr const char* fmt = "d"; +}; + +template <> +struct Base { + static constexpr const char* fmt = "x"; +}; + +template <> +struct Base { + static constexpr const char* fmt = "X"; +}; + +// *** Types *** +enum class TypeE { Int64, Uint64 }; +struct AllTypes : EnumValuesAsTuple { + static constexpr const char* Names[] = {"Int64", "Uint64"}; +}; + +template +struct Type {}; + +template <> +struct Type { + using type = int64_t; + + static std::array make_data() { return generate(); } +}; + +template <> +struct Type { + using type = uint64_t; + + static std::array make_data() { return generate(); } +}; + +// *** Alignment *** +enum class AlignmentE { None, Left, Center, Right, ZeroPadding }; +struct AllAlignments : EnumValuesAsTuple { + static constexpr const char* Names[] = { + "AlignNone", "AlignmentLeft", "AlignmentCenter", "AlignmentRight", "ZeroPadding"}; +}; + +template +struct Alignment {}; + +template <> +struct Alignment { + static constexpr const char* fmt = ""; +}; + +template <> +struct Alignment { + static constexpr const char* fmt = "0<512"; +}; + +template <> +struct Alignment { + static constexpr const char* fmt = "0^512"; +}; + +template <> +struct Alignment { + static constexpr const char* fmt = "0>512"; +}; + +template <> +struct Alignment { + static constexpr const char* fmt = "0512"; +}; + +template +struct Integral { + void run(benchmark::State& state) const { + std::array data{Type::make_data()}; + std::array output; + + while (state.KeepRunningBatch(data.size())) + for (auto value : data) + benchmark::DoNotOptimize(std::format_to(output.begin(), std::string_view{fmt.data(), fmt.size()}, value)); + } + + std::string name() const { return "Integral" + L::name() + B::name() + A::name() + T::name(); } + + static constexpr std::string make_fmt() { + return std::string("{:") + Alignment::fmt + Localization::fmt + Base::fmt + "}"; + } + + static constexpr auto fmt = []() { + constexpr size_t s = make_fmt().size(); + std::array r; + std::ranges::copy(make_fmt(), r.begin()); + return r; + }(); +}; + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + makeCartesianProductBenchmark(); + + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/gnu/llvm/libcxx/benchmarks/join_view.bench.cpp b/gnu/llvm/libcxx/benchmarks/join_view.bench.cpp new file mode 100644 index 00000000000..c789a39a8e2 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/join_view.bench.cpp @@ -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 +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +#include "benchmark/benchmark.h" + +namespace { +void run_sizes(auto benchmark) { + benchmark->Arg(0) + ->Arg(1) + ->Arg(2) + ->Arg(64) + ->Arg(512) + ->Arg(1024) + ->Arg(4000) + ->Arg(4096) + ->Arg(5500) + ->Arg(64000) + ->Arg(65536) + ->Arg(70000); +} + +void BM_join_view_in_vectors(benchmark::State& state) { + auto size = state.range(0); + std::vector> input(size, std::vector(32)); + std::ranges::fill(input | std::views::join, 10); + std::vector output; + output.resize(size * 32); + + for (auto _ : state) { + benchmark::DoNotOptimize(input); + benchmark::DoNotOptimize(output); + std::ranges::copy(input | std::views::join, output.begin()); + } +} +BENCHMARK(BM_join_view_in_vectors)->Apply(run_sizes); + +void BM_join_view_out_vectors(benchmark::State& state) { + auto size = state.range(0); + std::vector> output(size, std::vector(32)); + std::vector input; + input.resize(size * 32); + std::ranges::fill(input, 10); + + for (auto _ : state) { + benchmark::DoNotOptimize(output); + benchmark::DoNotOptimize(input); + std::ranges::copy(input, (output | std::views::join).begin()); + } +} +BENCHMARK(BM_join_view_out_vectors)->Apply(run_sizes); + +void BM_join_view_deques(benchmark::State& state) { + auto size = state.range(0); + std::deque> deque(size, std::deque(32)); + std::ranges::fill(deque | std::views::join, 10); + std::vector output; + output.resize(size * 32); + + for (auto _ : state) { + benchmark::DoNotOptimize(deque); + benchmark::DoNotOptimize(output); + std::ranges::copy(deque | std::views::join, output.begin()); + } +} +BENCHMARK(BM_join_view_deques)->Apply(run_sizes); +} // namespace + +BENCHMARK_MAIN(); diff --git a/gnu/llvm/libcxx/benchmarks/monotonic_buffer.bench.cpp b/gnu/llvm/libcxx/benchmarks/monotonic_buffer.bench.cpp new file mode 100644 index 00000000000..cfedbe582de --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/monotonic_buffer.bench.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include "benchmark/benchmark.h" + +static void bm_list(benchmark::State& state) { + char buffer[16384]; + std::pmr::monotonic_buffer_resource resource(buffer, sizeof(buffer)); + for (auto _ : state) { + std::pmr::list l(&resource); + for (size_t i = 0; i != state.range(); ++i) { + l.push_back(1); + benchmark::DoNotOptimize(l); + } + resource.release(); + } +} +BENCHMARK(bm_list)->Range(1, 2048); + +BENCHMARK_MAIN(); diff --git a/gnu/llvm/libcxx/benchmarks/random.bench.cpp b/gnu/llvm/libcxx/benchmarks/random.bench.cpp new file mode 100644 index 00000000000..e437849321d --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/random.bench.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// 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 +#include +#include +#include +#include + +#include "benchmark/benchmark.h" + +constexpr std::size_t MAX_BUFFER_LEN = 256; +constexpr std::size_t MAX_SEED_LEN = 16; + +static void BM_SeedSeq_Generate(benchmark::State& state) { + std::array buffer; + std::array seeds; + { + std::random_device rd; + std::generate(std::begin(seeds), std::begin(seeds) + state.range(0), [&]() { return rd(); }); + } + std::seed_seq seed(std::begin(seeds), std::begin(seeds) + state.range(0)); + for (auto _ : state) { + seed.generate(std::begin(buffer), std::begin(buffer) + state.range(1)); + } +} +BENCHMARK(BM_SeedSeq_Generate)->Ranges({{1, MAX_SEED_LEN}, {1, MAX_BUFFER_LEN}}); + +BENCHMARK_MAIN(); diff --git a/gnu/llvm/libcxx/benchmarks/std_format_spec_string_unicode.bench.cpp b/gnu/llvm/libcxx/benchmarks/std_format_spec_string_unicode.bench.cpp new file mode 100644 index 00000000000..3769e964269 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/std_format_spec_string_unicode.bench.cpp @@ -0,0 +1,300 @@ +// 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_HAS_NO_UNICODE + +# include +# include + +# include "benchmark/benchmark.h" + +# include "make_string.h" + +# define SV(S) MAKE_STRING_VIEW(CharT, S) + +// generated with https://generator.lorem-ipsum.info/_latin + +template +std::basic_string_view ascii_text() { + return SV( + R"( Lorem ipsum dolor sit amet, ne sensibus evertitur aliquando his. +Iuvaret fabulas qui ex, ex iriure iisque nostrum mea. Solum +pericula qui ad. Elitr oporteat ius ad. + +Quas rationibus ad mel. Appellantur intellegebat ad mei, ius audire volumus +consectetuer id. Ei sit definitionem mediocritatem, vim indoctum intellegat id, +dicta laboramus instructior in vix. Mel an quando malorum, id vis mollis +invidunt, placerat maiestatis comprehensam ut cum. Suas regione interesset id +per, et docendi accumsan has, autem atomorum est te. + +Cu debitis ancillae sea, alii definitiones ex cum, vim no erat antiopam. Eam et +unum quas scriptorem. An bonorum elaboraret complectitur nam, vim ei persecuti +democritum mediocritatem. Suscipit platonem signiferumque ei cum, in sale +volutpat ocurreret vel. Te vel nihil nominavi adipiscing, stet ancillae mel ea. +Sit detraxit menandri platonem ea, cum at tale viris virtute. + +Regione detraxit gloriatur sit eu, sonet labitur sententiae et pro, at sit +alterum aliquid interpretaris. Sonet voluptua duo id, vix ea accumsan +liberavisse. Nam id commune probatus contentiones. Et zril dolore laudem duo, +ea usu mollis melius referrentur, vel ex case consequuntur. Id nam illum mollis +ponderum. Quis tamquam ullamcorper sed ne, legimus vituperatoribus est id. + +Et eum probo consulatu. At eos errem aliquando theophrastus, sea ad eius omnis. +No vis iusto scriptorem adversarium, dicat viderer ea sit. Et veri euripidis +sea, justo putent iudicabit vim id. Sea suas tincidunt vituperatoribus in. Ne +eam aeterno sensibus concludaturque, solet legere his id, usu ei dicat +dissentiunt. Est et autem erant. + +Per quod laboramus an. Dico voluptua at mea, an animal minimum eum. Pri an +option salutatus, causae feugiat menandri an sed. Voluptaria dissentiet vix ut, +alii solet te quo, in facer ceteros eos. Ad nibh meis percipitur sit, +aliquam molestie cu vis, iisque malorum interesset et eos. + +Eos in feugiat insolens abhorreant. Ea tale esse alienum has, mel et saperet +appellantur, aliquip salutandi deterruisset ut mel. Eos ei quod simul +interpretaris, aeque elitr putent per at, et veri eripuit ceteros his. Cu pro +meis aperiam volutpat, ex alterum scripserit ius, scriptorem deterruisset eu +qui. Graeco debitis lobortis cu mea. + +Alii corpora id ius, cu quo oblique eloquentiam. Et duis civibus atomorum sea, +veniam utroque scriptorem vim cu. Ut oratio eruditi mediocritatem est. Amet +nibh dolore mea ea, tollit laoreet eligendi qui ex, cu essent forensibus +his. + +Usu ex ipsum apeirian, eos congue scripserit omittantur et. Ea eum persecuti +deseruisse, probatus torquatos est no, in has mutat mundi dolorem. Albucius +sensibus ex cum. Ferri virtute referrentur an per, est choro option bonorum ex. + +Quando accusam vis te, tale mazim et pro. Magna dolorem tincidunt +nec te, albucius adipisci ad pri. Magna facilisi adipisci at usu, et vel +dissentiunt neglegentur, prima audiam vocibus an duo. Enim detracto te sea, mel +quis dicit gubergren ex, iusto adversarium consequuntur per ne. + +)"); +} + +template +std::basic_string_view unicode_text() { + return SV( + R"(Lōrem ipsūm dolor sīt æmeÞ, ea vel nostrud feuġǣit, muciūs tēmporiȝus +refērrēnÞur no mel, quo placērǽt consecÞetuer cū. Veri soƿet euripīðis id has, +sumo paulō dissentias duo eī, dētrāxīt neglēgeƿtur ið prī. Sēd option oporÞerē +no. Nec ēū nēmore mentitum. Veri prōȝo faċilis āt vīm. + +Ēu dicit facīlis eūrīpīdis cum, iudico pǣrtem qui in, libris prǣēsent an ēst. +Æt sit quoðsi impētus, nec ex qūaeque honestǣtīs. Fiērēƿt ƿōluisse verterem iƿ +ēst. Meī eæ apēriæm fierent peÞentīūm. Eæm officiīs reprehēndunt nē. + +Ut vel quodsī contentioƿes, his eū dignissim īnstruċÞior. Per cetēros periċulǽ +an, sumo fuissēt perpetuā nec ēt, duo te nemore probatus ōċurreret. Mel ǣd +civībus ocūrreret. Ex nostro ǣliquam usu, ex Þātīon adipiscī qui. Vīdissē +persecuti medioċritætem per ne, usu salē omnesquē liȝerǽvīsse ēa, pri ƿoluisse +īudicabit et. No summo quiðǣm nec, vim ēi nūmqūam sænctus concepÞǣm. Reque +doceƿdi īn īus, porro eripuiÞ intērprētaris pri in. + +Idquē hǣbēmus nominati vix cū. AÞ prō ǽmēt elit periculæ. Has virīs viderer ān. +Mel in suās pericūlīs āppellantur, nonumes deserūƿt ǽðversarium eā has. ĒliÞ +possīt commuƿe no ēsÞ, niȝh aċcusāmūs volūpÞatum no mel, ut quō ciȝo ðiceret. +Inǣni scripta quālīsque nē qūi, ad ipsūm persecuÞi mediōcritæÞēm vel. + +Ǣppetere definitiōnes mel id. Leġerē āliquip nam eǣ, rēgione viderer pǣtrioque +duo te, meƿāƿdri prodēsseÞ ex hīs. Solum quidam eæ iūs, mēl ǣt sapientem +expliċari. Īƿ ǣċcusǣm phǽedrum pro, ex pro dēleƿit detræxit hendrerīt, sit āgam +quidām pertinax uÞ. Ēssent rætionibus eǽ vēl, quo ān labore nusquæm nominǣti. + +Te alii cōnseÞetur ƿam, eam ēt puteƿÞ ðissentiæs. Qūi alii dicānt repuðiære ēā, +nō mel ferri nūsquam. Ea vim impedīt vertērem, ǣn per veri Þīmeam. SiÞ ōmitÞǽm +necēssitǣÞibus ex, ƿe vis inǣni pærtem invenire. Īd ðolores ċonsēċÞeÞuer usu, +īd vis nisl dēnique luptǣtūm. Pro ǽd ēverti option dēserūƿt, nec te ōðiō +cīvībūs. + +Ēæ nibh æccommodarē eum. Ne etiæm īudico dicunt duo, quo tēmpor populo insōlens +nē. Ēos eÞ ēirmod prǽēsēƿt. Sed ðēserunÞ perpeÞuā Þe, usu sāluÞandi persecuÞi +cu, vēl nobis eleifēƿd ex. + +Ƿe zrīl ūtīnam lǣtīne eǣm, eā vim rebum omitÞǣm aðipisciƿg. Amet inermis +epiċūri ut est, eu duo hīnc periċulis. Mel no reque simul volupÞātum, ex mutat +lāudem tacīmatēs cum. Te hǣs summo iƿteġre recteque. No iūs dicerēt +ðisputǽtioƿi. Vim ōmnis deleƿiÞi honestātis ēǽ. + +Nec detrǣcto pērcipitur ne. Ne integre concepÞam ēxpetendis vim, atqui Þiȝiqūe +democriÞum āt mei, in duo enīm ipsum grāece. Rebum ðefīnīÞionem āt pri, ēt sit +brute periculis. Ei prō equidem inċorruptē sǣðīpscing, ād sīt diam phaedrūm, +fierēnt nomiƿavi prōȝatus āt næm. Wisi ƿæÞūm coƿsecteÞuer usū ea. +)"); +} + +template +std::basic_string_view cyrillic_text() { + return SV( + R"(Лорем ипсум долор сит амет, еу диам тамяуам принципес вис, еяуидем +цонцептам диспутандо яуи цу, иус ад натум нулла граеци. Цибо дицит омниум нец +цу, еу бруте номинави диссентиет яуо. Омниум лаборамус еу хас. Дицат +диспутатиони вис еу, цу еос миним атоморум инцидеринт. Пер хабео рецтеяуе +дигниссим ан, ех яуо сенсибус торяуатос, ан. + +Ут перпетуа партиендо принципес хис. Ат симул ностер аппареат пер. Пурто вирис +ет хис, мазим дицерет при ет. Хис саперет тибияуе сцаевола еу, сит солет +вивендум цонсеяуат те. Ид оффициис перпетуа ассентиор яуи, сед аугуе афферт +симилияуе ад, ех адмодум постулант иус. + +Про дицунт волуптатум диспутатиони ат. Вел патриояуе персецути еа, цетерос +диспутатиони ин сед, нам те веро цлита малуиссет. Цу неглегентур инструцтиор +интерпретарис еам, ипсум фабулас еи вел. Еи адхуц деленити нам, аугуе +демоцритум при ан. Вим мелиоре проприае ид, албуциус волуптуа цоррумпит дуо ан. +Латине иуварет пер ут, иус еа мунере ерипуит санцтус. + +Модус тритани иус не, вим ут мелиоре мандамус, лабитур опортере дуо но. Ад нец +витае фацилис инцоррупте, цу сед толлит сцрипторем. Сит лудус инимицус +волуптариа не. Иисяуе антиопам сапиентем сед еу. Путент волуптуа сит ех, ат иус +ребум епицури, яуи моллис елигенди ех. Проприае нолуиссе цу сеа, путент поссит +адверсариум про не. + +Ид яуо прима бонорум, дуо форенсибус яуаерендум еи, еум бруте мунере те. Еам +риденс граецо ех, аеяуе санцтус маиорум ан вел. Либрис санцтус утрояуе ест но, +еам ат реяуе порро тинцидунт, ут хинц иллуд патриояуе хис. Не солет оффендит +форенсибус хас, тамяуам опортеат елаборарет те нец, еу аугуе примис маиорум +еам. Аутем вениам импедит вис ин, прима елитр пхаедрум ест еу.)"); +} + +template +std::basic_string_view japanese_text() { + return SV( + R"(入ト年媛ろ舗学ラロ準募ケカ社金スノ屋検れう策他セヲシ引口ぎ集7独ぱクふ出車ぽでぱ円輪ルノ受打わ。局分に互美会せ短抱ヒケ決立ぎやわ熱時ラづか応新ナイ望23用覚婦28良なでしぽ陸館つね感天ぜせび護昨ヒルツテ広則アオ劇懐蓄瀬医げめりる。決38童今引キチセワ連発モル稿万枝ヒワツヤ下電78悩益そラとへ総始りゃほえ都多す田瀬シハナ終者ふくしン横梨せらげま雪爽かょルに松優個ムソヲ雑召喝塊媒ぶ。 + +紙ヤ景異ミノオ誤求レ移著ヤエヨメ広庫テハヌサ君検あ必参ワ火面るね声著ン間売力を数20談すがス禁化ッを。起そり予浩ド進皇キ試属が震二トヌ真佳速すずちし件諏フウチ聞在ス会雄ノミ必筋80戦ぶさほド聞2涙属どスれ映聞ネ掲実べ。 + +8福びり属稿づ徳鎌ニル涼問ゃごるリ付92済トぎけッ康30業づむはつ治然二生入ざひ有動ハワチ発談ニスツ魚困摘策送ざ。個時着そてら新新ヌ鉄報たは作主ずリ可輸改量ルおず井認つてぜな会大ぼすぶし全戸ノハケレ貯治たざリな祖間ムリキ断会仕べせど。委暮ど象週トクワ流開タハ硬給ツタウ者善マラノヱ断稿リヲ東毎ツヨマ井藤ルょへ境同論エ愛図ッらフリ基38属慣葬8携ヱ校図おに岐題しね要月レユ展省わトど。 + +担がは顔研リ目問いぽべ挙介ん入番ネヌイ栄県し改治ラス健第モム得続加ホウ嘉宿置首本やぞ。78毎まが現設記ほぜね場歩ユアルヒ東的ヒ姿役ネヲ聞能ラシマヒ際形トくゃ政能万の付結ス国1教レツ引写イど扱澤は膚言けリいべ橋柔薄組こよじ。浩報すンつひ崎正念方と夫地クざす情阪スで抜長ネ娘回ハツ止資ヘニ並辞ロノ展師質18打テネ岡時ノモ泉95務えぴひつ速申後延んフるせ。 + +店てラ載独マシフ理心ス型部米た読石カ料応掲ケカキ打月在ユテニ採材イ並発イヒト旅錯っめし模能りせば連確え会准揮が。器にト画軍にぶイら式東みそお前姿リいけに身47却6記け岸5体会ゃばま映8碁よぽだ経9名トびち更躍うにふ裏高もそ提旅さぼえス。賞ぞだ月係ソ知建振イナシ説並イ見書傳ヨミ問回級エシ出所師阪ト転権がし渡平ルモケ新完ハ玲女ロトシ導複トうよふ。 + +化シセチ町74掲ネテトオ連対ヒハチモ経後ッ断連カロワ待業ぼぽねか百都へがい始塗ごげ寺帰んぽ逆力るず選英堂衛掛焼ゅ。自生トサリ探就的らね江球リルスツ主嘆4権伝ざが避掲う慶合ワ百29暮ネヤクム書能部あが席小フア部親票ーむとこ。3説ひっぜ約毎伎ナキリ缶近くなず員45姿えにけろ値付ワ着知ソルキ日医ず集新エウカケ投国チ生目ゃ棋運ぐのか寄募オチ性注経どドんて止代わくかな端期幕はかク。 +)"); +} + +template +std::basic_string_view emoji_text() { + return SV( + R"( +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF + +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 + +\U0001F636\u200D\U0001F32B\uFE0F + +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF + +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 + +\U0001F984 + +)"); +} + +template +void BM_text(benchmark::State& state, std::basic_string_view input) { + CharT buffer[5'000]; + + if constexpr (std::same_as) { + // Make sure the output buffer is large enough. + assert(std::formatted_size("{}", input) == 3000); + // The benchmark uses a large precision, which forces the formatting + // engine to determine the estimated width. (There's no direct way to call + // this function in portable code.) + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(buffer, "{:.10000}", input)); + } else { + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(buffer, L"{:.10000}", input)); + } +} + +template +void BM_ascii_text(benchmark::State& state) { + BM_text(state, ascii_text()); +} + +template +void BM_unicode_text(benchmark::State& state) { + BM_text(state, unicode_text()); +} + +template +void BM_cyrillic_text(benchmark::State& state) { + BM_text(state, cyrillic_text()); +} + +template +void BM_japanese_text(benchmark::State& state) { + BM_text(state, japanese_text()); +} + +template +void BM_emoji_text(benchmark::State& state) { + BM_text(state, emoji_text()); +} + +BENCHMARK_TEMPLATE(BM_ascii_text, char); +BENCHMARK_TEMPLATE(BM_unicode_text, char); +BENCHMARK_TEMPLATE(BM_cyrillic_text, char); +BENCHMARK_TEMPLATE(BM_japanese_text, char); +BENCHMARK_TEMPLATE(BM_emoji_text, char); + +BENCHMARK_TEMPLATE(BM_ascii_text, wchar_t); +BENCHMARK_TEMPLATE(BM_unicode_text, wchar_t); +BENCHMARK_TEMPLATE(BM_cyrillic_text, wchar_t); +BENCHMARK_TEMPLATE(BM_japanese_text, wchar_t); +BENCHMARK_TEMPLATE(BM_emoji_text, wchar_t); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} +#else +int main(int, char**) { return 0; } +#endif diff --git a/gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp b/gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp index e0030d6c473..acabc73f30f 100644 --- a/gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp +++ b/gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp @@ -104,6 +104,27 @@ struct UInt64Hash2 { } }; +// The sole purpose of this comparator is to be used in BM_Rehash, where +// we need something slow enough to be easily noticable in benchmark results. +// The default implementation of operator== for strings seems to be a little +// too fast for that specific benchmark to reliably show a noticeable +// improvement, but unoptimized bytewise comparison fits just right. +// Early return is there just for convenience, since we only compare strings +// of equal length in BM_Rehash. +struct SlowStringEq { + SlowStringEq() = default; + inline TEST_ALWAYS_INLINE + bool operator()(const std::string& lhs, const std::string& rhs) const { + if (lhs.size() != rhs.size()) return false; + + bool eq = true; + for (size_t i = 0; i < lhs.size(); ++i) { + eq &= lhs[i] == rhs[i]; + } + return eq; + } +}; + //----------------------------------------------------------------------------// // BM_Hash // ---------------------------------------------------------------------------// @@ -266,6 +287,20 @@ BENCHMARK_CAPTURE(BM_FindRehash, std::unordered_set{}, getRandomStringInputs)->Arg(TestNumInputs); +//----------------------------------------------------------------------------// +// BM_Rehash +// ---------------------------------------------------------------------------// + +BENCHMARK_CAPTURE(BM_Rehash, + unordered_set_string_arg, + std::unordered_set, SlowStringEq>{}, + getRandomStringInputs)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_Rehash, + unordered_set_int_arg, + std::unordered_set{}, + getRandomIntegerInputs)->Arg(TestNumInputs); + /////////////////////////////////////////////////////////////////////////////// BENCHMARK_CAPTURE(BM_InsertDuplicate, unordered_set_int, diff --git a/gnu/llvm/libcxx/cmake/Modules/HandleLibCXXABI.cmake b/gnu/llvm/libcxx/cmake/Modules/HandleLibCXXABI.cmake index 5a8a4a270a1..20fb81837f9 100644 --- a/gnu/llvm/libcxx/cmake/Modules/HandleLibCXXABI.cmake +++ b/gnu/llvm/libcxx/cmake/Modules/HandleLibCXXABI.cmake @@ -1,142 +1,182 @@ - -#=============================================================================== -# Add an ABI library if appropriate #=============================================================================== - +# Define targets for linking against the selected ABI library # -# _setup_abi: Set up the build to use an ABI library -# -# Parameters: -# abidefines: A list of defines needed to compile libc++ with the ABI library -# abishared : The shared ABI library to link against. -# abistatic : The static ABI library to link against. -# abifiles : A list of files (which may be relative paths) to copy into the -# libc++ build tree for the build. These files will be copied -# twice: once into include/, so the libc++ build itself can find -# them, and once into include/c++/v1, so that a clang built into -# the same build area will find them. These files will also be -# installed alongside the libc++ headers. -# abidirs : A list of relative paths to create under an include directory -# in the libc++ build directory. +# After including this file, the following targets are defined: +# - libcxx-abi-headers: An interface target that allows getting access to the +# headers of the selected ABI library. +# - libcxx-abi-shared: A target representing the selected shared ABI library. +# - libcxx-abi-static: A target representing the selected static ABI library. # +# Furthermore, some ABI libraries also define the following target: +# - libcxx-abi-shared-objects: An object library representing a set of object files +# constituting the ABI library, suitable for bundling +# into a shared library. +# - libcxx-abi-static-objects: An object library representing a set of object files +# constituting the ABI library, suitable for bundling +# into a static library. +#=============================================================================== + +include(GNUInstallDirs) -macro(setup_abi_lib abidefines abishared abistatic abifiles abidirs) - list(APPEND LIBCXX_COMPILE_FLAGS ${abidefines}) - set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_CXX_ABI_INCLUDE_PATHS}" - CACHE PATH - "Paths to C++ ABI header directories separated by ';'." FORCE - ) - set(LIBCXX_CXX_ABI_LIBRARY_PATH "${LIBCXX_CXX_ABI_LIBRARY_PATH}" - CACHE PATH - "Paths to C++ ABI library directory" - ) - set(LIBCXX_CXX_SHARED_ABI_LIBRARY ${abishared}) - set(LIBCXX_CXX_STATIC_ABI_LIBRARY ${abistatic}) - set(LIBCXX_ABILIB_FILES ${abifiles}) - - foreach(fpath ${LIBCXX_ABILIB_FILES}) +# This function copies the provided headers to a private directory and adds that +# path to the given INTERFACE target. That target can then be linked against to +# get access to those headers (and only those). +# +# The problem this solves is that when building against a system-provided ABI library, +# the ABI headers might live side-by-side with an actual C++ Standard Library +# installation. For that reason, we can't just add `-I `, +# since we would end up also adding the system-provided C++ Standard Library to +# the search path. Instead, what we do is copy just the ABI library headers to +# a private directory and add just that path when we build libc++. +function(import_private_headers target include_dirs headers) + foreach(header ${headers}) set(found FALSE) - foreach(incpath ${LIBCXX_CXX_ABI_INCLUDE_PATHS}) - message(STATUS "Looking for ${fpath} in ${incpath}") - if (EXISTS "${incpath}/${fpath}") + foreach(incpath ${include_dirs}) + if (EXISTS "${incpath}/${header}") set(found TRUE) - message(STATUS "Looking for ${fpath} in ${incpath} - found") - get_filename_component(dstdir ${fpath} PATH) - get_filename_component(ifile ${fpath} NAME) - set(src ${incpath}/${fpath}) + message(STATUS "Looking for ${header} in ${incpath} - found") + get_filename_component(dstdir ${header} PATH) + get_filename_component(header_file ${header} NAME) + set(src ${incpath}/${header}) + set(dst "${LIBCXX_BINARY_DIR}/private-abi-headers/${dstdir}/${header_file}") - set(dst ${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}/${ifile}) add_custom_command(OUTPUT ${dst} DEPENDS ${src} + COMMAND ${CMAKE_COMMAND} -E make_directory "${LIBCXX_BINARY_DIR}/private-abi-headers/${dstdir}" COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} - COMMENT "Copying C++ ABI header ${fpath}...") + COMMENT "Copying C++ ABI header ${header}") list(APPEND abilib_headers "${dst}") - - # TODO: libc++ shouldn't be responsible for copying the libc++abi - # headers into the right location. - set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${dstdir}/${fpath}") - add_custom_command(OUTPUT ${dst} - DEPENDS ${src} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} - COMMENT "Copying C++ ABI header ${fpath}...") - list(APPEND abilib_headers "${dst}") - - if (LIBCXX_INSTALL_HEADERS) - install(FILES "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}" - DESTINATION include/c++/v1/${dstdir} - COMPONENT cxx-headers - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ - ) - endif() else() - message(STATUS "Looking for ${fpath} in ${incpath} - not found") + message(STATUS "Looking for ${header} in ${incpath} - not found") endif() endforeach() if (NOT found) - message(WARNING "Failed to find ${fpath} in ${LIBCXX_CXX_ABI_INCLUDE_PATHS}") + message(WARNING "Failed to find ${header} in ${include_dirs}") endif() endforeach() - include_directories("${LIBCXX_BINARY_INCLUDE_DIR}") - add_custom_target(cxx_abi_headers ALL DEPENDS ${abilib_headers}) - set(LIBCXX_CXX_ABI_HEADER_TARGET "cxx_abi_headers") -endmacro() - - -# Configure based on the selected ABI library. -if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR - "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libsupc++") - set(_LIBSUPCXX_INCLUDE_FILES - cxxabi.h bits/c++config.h bits/os_defines.h bits/cpu_defines.h - bits/cxxabi_tweaks.h bits/cxxabi_forced.h - ) - if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++") - set(_LIBSUPCXX_DEFINES "-DLIBSTDCXX") - set(_LIBSUPCXX_LIBNAME stdc++) - else() - set(_LIBSUPCXX_DEFINES "") - set(_LIBSUPCXX_LIBNAME supc++) + # Work around https://gitlab.kitware.com/cmake/cmake/-/issues/18399 + add_library(${target}-generate-private-headers OBJECT ${abilib_headers}) + set_target_properties(${target}-generate-private-headers PROPERTIES LINKER_LANGUAGE CXX) + + target_link_libraries(${target} INTERFACE ${target}-generate-private-headers) + target_include_directories(${target} INTERFACE "${LIBCXX_BINARY_DIR}/private-abi-headers") +endfunction() + +# This function creates an imported static library named . +# It imports a library named searched at the given . +function(import_static_library target path name) + add_library(${target} STATIC IMPORTED GLOBAL) + find_library(file + NAMES "${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}" + PATHS "${path}" + NO_CACHE) + set_target_properties(${target} PROPERTIES IMPORTED_LOCATION "${file}") +endfunction() + +# This function creates an imported shared (interface) library named +# for the given library . +function(import_shared_library target name) + add_library(${target} INTERFACE IMPORTED GLOBAL) + set_target_properties(${target} PROPERTIES IMPORTED_LIBNAME "${name}") +endfunction() + +# Link against a system-provided libstdc++ +if ("${LIBCXX_CXX_ABI}" STREQUAL "libstdc++") + add_library(libcxx-abi-headers INTERFACE) + import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}" + "cxxabi.h;bits/c++config.h;bits/os_defines.h;bits/cpu_defines.h;bits/cxxabi_tweaks.h;bits/cxxabi_forced.h") + target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBSTDCXX" "-D__GLIBCXX__") + + import_shared_library(libcxx-abi-shared stdc++) + target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers) + + import_static_library(libcxx-abi-static "${LIBCXX_CXX_ABI_LIBRARY_PATH}" stdc++) + target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers) + +# Link against a system-provided libsupc++ +elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libsupc++") + add_library(libcxx-abi-headers INTERFACE) + import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}" + "cxxabi.h;bits/c++config.h;bits/os_defines.h;bits/cpu_defines.h;bits/cxxabi_tweaks.h;bits/cxxabi_forced.h") + target_compile_definitions(libcxx-abi-headers INTERFACE "-D__GLIBCXX__") + + import_shared_library(libcxx-abi-shared supc++) + target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers) + + import_static_library(libcxx-abi-static "${LIBCXX_CXX_ABI_LIBRARY_PATH}" supc++) + target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers) + +# Link against the in-tree libc++abi +elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxabi") + add_library(libcxx-abi-headers INTERFACE) + target_link_libraries(libcxx-abi-headers INTERFACE cxxabi-headers) + target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXX_BUILDING_LIBCXXABI") + + if (TARGET cxxabi_shared) + add_library(libcxx-abi-shared ALIAS cxxabi_shared) endif() - setup_abi_lib( - "-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}" - "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits" - ) -elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi") - if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS) - set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_SOURCE_DIR}/../libcxxabi/include") + + if (TARGET cxxabi_static) + add_library(libcxx-abi-static ALIAS cxxabi_static) endif() - if(LIBCXX_STANDALONE_BUILD AND NOT (LIBCXX_CXX_ABI_INTREE OR HAVE_LIBCXXABI)) - set(shared c++abi) - set(static c++abi) - else() - set(shared cxxabi_shared) - set(static cxxabi_static) + if (TARGET cxxabi_shared_objects) + add_library(libcxx-abi-shared-objects ALIAS cxxabi_shared_objects) endif() - setup_abi_lib( - "-DLIBCXX_BUILDING_LIBCXXABI" - "${shared}" "${static}" "cxxabi.h;__cxxabi_config.h" "") -elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt") - if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS) - set(LIBCXX_CXX_ABI_INCLUDE_PATHS "/usr/include/c++/v1") + if (TARGET cxxabi_static_objects) + add_library(libcxx-abi-static-objects ALIAS cxxabi_static_objects) endif() + +# Link against a system-provided libc++abi +elseif ("${LIBCXX_CXX_ABI}" STREQUAL "system-libcxxabi") + add_library(libcxx-abi-headers INTERFACE) + import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}" "cxxabi.h;__cxxabi_config.h") + target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXX_BUILDING_LIBCXXABI") + + import_shared_library(libcxx-abi-shared c++abi) + target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers) + + import_static_library(libcxx-abi-static "${LIBCXX_CXX_ABI_LIBRARY_PATH}" c++abi) + target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers) + +# Link against a system-provided libcxxrt +elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxrt") # libcxxrt does not provide aligned new and delete operators + # TODO: We're keeping this for backwards compatibility, but this doesn't belong here. set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON) - setup_abi_lib( - "-DLIBCXXRT" - "cxxrt" "cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" "" - ) -elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "vcruntime") - # Nothing to do -elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none") - list(APPEND LIBCXX_COMPILE_FLAGS "-D_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY") -elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "default") - # Nothing to do -else() - message(FATAL_ERROR - "Unsupported c++ abi: '${LIBCXX_CXX_ABI_LIBNAME}'. \ - Currently libstdc++, libsupc++, libcxxabi, libcxxrt, default and none are - supported for c++ abi." - ) -endif () + + if(NOT LIBCXX_CXX_ABI_INCLUDE_PATHS) + message(STATUS "LIBCXX_CXX_ABI_INCLUDE_PATHS not set, using /usr/include/c++/v1") + set(LIBCXX_CXX_ABI_INCLUDE_PATHS "/usr/include/c++/v1") + endif() + add_library(libcxx-abi-headers INTERFACE) + import_private_headers(libcxx-abi-headers "${LIBCXX_CXX_ABI_INCLUDE_PATHS}" + "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h") + target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXXRT") + + import_shared_library(libcxx-abi-shared cxxrt) + target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers) + + import_static_library(libcxx-abi-static "${LIBCXX_CXX_ABI_LIBRARY_PATH}" cxxrt) + target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers) + +# Link against a system-provided vcruntime +# FIXME: Figure out how to configure the ABI library on Windows. +elseif ("${LIBCXX_CXX_ABI}" STREQUAL "vcruntime") + add_library(libcxx-abi-headers INTERFACE) + add_library(libcxx-abi-shared INTERFACE) + add_library(libcxx-abi-static INTERFACE) + +# Don't link against any ABI library +elseif ("${LIBCXX_CXX_ABI}" STREQUAL "none") + add_library(libcxx-abi-headers INTERFACE) + target_compile_definitions(libcxx-abi-headers INTERFACE "-D_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY") + + add_library(libcxx-abi-shared INTERFACE) + target_link_libraries(libcxx-abi-shared INTERFACE libcxx-abi-headers) + + add_library(libcxx-abi-static INTERFACE) + target_link_libraries(libcxx-abi-static INTERFACE libcxx-abi-headers) +endif() diff --git a/gnu/llvm/libcxx/cmake/Modules/HandleLibcxxFlags.cmake b/gnu/llvm/libcxx/cmake/Modules/HandleLibcxxFlags.cmake index 859cfc4a515..72512544e63 100644 --- a/gnu/llvm/libcxx/cmake/Modules/HandleLibcxxFlags.cmake +++ b/gnu/llvm/libcxx/cmake/Modules/HandleLibcxxFlags.cmake @@ -42,7 +42,7 @@ endmacro(remove_flags) macro(check_flag_supported flag) mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") + check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") endmacro() macro(append_flags DEST) @@ -63,8 +63,8 @@ endmacro() macro(append_flags_if_supported DEST) foreach(flag ${ARGN}) mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") - append_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${DEST} ${flag}) + check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") + append_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${DEST} ${flag}) endforeach() endmacro() @@ -127,8 +127,8 @@ endmacro() macro(add_target_flags_if_supported) foreach(flag ${ARGN}) mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") - add_target_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag}) + check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") + add_target_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag}) endforeach() endmacro() @@ -154,8 +154,8 @@ endmacro() macro(add_flags_if_supported) foreach(flag ${ARGN}) mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") - add_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag}) + check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") + add_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag}) endforeach() endmacro() @@ -179,8 +179,8 @@ endmacro() macro(add_compile_flags_if_supported) foreach(flag ${ARGN}) mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") - add_compile_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag}) + check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") + add_compile_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag}) endforeach() endmacro() @@ -204,8 +204,8 @@ endmacro() macro(add_link_flags_if_supported) foreach(flag ${ARGN}) mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") - add_link_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag}) + check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") + add_link_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag}) endforeach() endmacro() @@ -234,8 +234,8 @@ endmacro() function(target_add_link_flags_if_supported target visibility) foreach(flag ${ARGN}) mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") - if (LIBCXX_SUPPORTS_${flagname}_FLAG) + check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") + if (CXX_SUPPORTS_${flagname}_FLAG) target_link_libraries(${target} ${visibility} ${flag}) endif() endforeach() @@ -246,8 +246,8 @@ endfunction() function(target_add_compile_flags_if_supported target visibility) foreach(flag ${ARGN}) mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG") - if (LIBCXX_SUPPORTS_${flagname}_FLAG) + check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") + if (CXX_SUPPORTS_${flagname}_FLAG) target_compile_options(${target} ${visibility} ${flag}) endif() endforeach() diff --git a/gnu/llvm/libcxx/cmake/caches/AArch64.cmake b/gnu/llvm/libcxx/cmake/caches/AArch64.cmake index 33356a7ee02..fa802d3de63 100644 --- a/gnu/llvm/libcxx/cmake/caches/AArch64.cmake +++ b/gnu/llvm/libcxx/cmake/caches/AArch64.cmake @@ -1,2 +1,2 @@ set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") -set(LIBCXX_TARGET_TRIPLE "aarch64-linux-gnu" CACHE STRING "") +set(CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/caches/AIX.cmake b/gnu/llvm/libcxx/cmake/caches/AIX.cmake new file mode 100644 index 00000000000..76cf1779130 --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/AIX.cmake @@ -0,0 +1,19 @@ +set(CMAKE_BUILD_TYPE Release CACHE STRING "") +set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "") +set(CMAKE_C_FLAGS "-D__LIBC_NO_CPP_MATH_OVERLOADS__" CACHE STRING "") +set(CMAKE_CXX_FLAGS "-D__LIBC_NO_CPP_MATH_OVERLOADS__" CACHE STRING "") +set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-G -Wl,-bcdtors:all:-2147483548:s" CACHE STRING "") +set(CMAKE_AR "/usr/bin/ar" CACHE FILEPATH "") + +set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") +set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "") +set(LIBCXX_ABI_VERSION "1" CACHE STRING "") +set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") +set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "") +set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") +set(LIBUNWIND_ENABLE_SHARED ON CACHE BOOL "") +set(LIBUNWIND_ENABLE_STATIC OFF CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Apple.cmake b/gnu/llvm/libcxx/cmake/caches/Apple.cmake index c884eb561d0..5224e04687a 100644 --- a/gnu/llvm/libcxx/cmake/caches/Apple.cmake +++ b/gnu/llvm/libcxx/cmake/caches/Apple.cmake @@ -4,17 +4,18 @@ set(CMAKE_POSITION_INDEPENDENT_CODE OFF CACHE BOOL "") set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") set(LIBCXX_ENABLE_ASSERTIONS OFF CACHE BOOL "") set(LIBCXX_ABI_VERSION "1" CACHE STRING "") -set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "") set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "") -set(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT ON CACHE BOOL "") -set(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT OFF CACHE BOOL "") set(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS ON CACHE BOOL "") -set(LIBCXX_ENABLE_INCOMPLETE_FEATURES OFF CACHE BOOL "") set(LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") set(LIBCXXABI_ENABLE_ASSERTIONS OFF CACHE BOOL "") set(LIBCXXABI_ENABLE_FORGIVING_DYNAMIC_CAST ON CACHE BOOL "") + +set(LIBCXX_TEST_CONFIG "apple-libc++-shared.cfg.in" CACHE STRING "") +set(LIBCXXABI_TEST_CONFIG "apple-libc++abi-shared.cfg.in" CACHE STRING "") +set(LIBCXX_TEST_PARAMS "stdlib=apple-libc++" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/caches/Armv7Arm.cmake b/gnu/llvm/libcxx/cmake/caches/Armv7Arm.cmake index 8b2b54eba13..4d18d08fefc 100644 --- a/gnu/llvm/libcxx/cmake/caches/Armv7Arm.cmake +++ b/gnu/llvm/libcxx/cmake/caches/Armv7Arm.cmake @@ -1,4 +1,4 @@ set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") -set(LIBCXX_TARGET_TRIPLE "armv7-linux-gnueabihf" CACHE STRING "") +set(CMAKE_CXX_COMPILER_TARGET "armv7l-linux-gnueabihf" CACHE STRING "") set(CMAKE_CXX_FLAGS "-marm" CACHE STRING "") set(CMAKE_C_FLAGS "-marm" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/caches/Armv7Thumb-noexceptions.cmake b/gnu/llvm/libcxx/cmake/caches/Armv7Thumb-noexceptions.cmake index 67ec43b93f2..71173af106b 100644 --- a/gnu/llvm/libcxx/cmake/caches/Armv7Thumb-noexceptions.cmake +++ b/gnu/llvm/libcxx/cmake/caches/Armv7Thumb-noexceptions.cmake @@ -1,5 +1,5 @@ set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") -set(LIBCXX_TARGET_TRIPLE "armv7-linux-gnueabihf" CACHE STRING "") +set(CMAKE_CXX_COMPILER_TARGET "armv7l-linux-gnueabihf" CACHE STRING "") set(CMAKE_CXX_FLAGS "-mthumb" CACHE STRING "") set(CMAKE_C_FLAGS "-mthumb" CACHE STRING "") set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Armv8Arm.cmake b/gnu/llvm/libcxx/cmake/caches/Armv8Arm.cmake index 55dfa908b3d..5055582fdaf 100644 --- a/gnu/llvm/libcxx/cmake/caches/Armv8Arm.cmake +++ b/gnu/llvm/libcxx/cmake/caches/Armv8Arm.cmake @@ -1,4 +1,4 @@ set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") -set(LIBCXX_TARGET_TRIPLE "armv8-linux-gnueabihf" CACHE STRING "") +set(CMAKE_CXX_COMPILER_TARGET "armv8l-linux-gnueabihf" CACHE STRING "") set(CMAKE_CXX_FLAGS "-marm" CACHE STRING "") set(CMAKE_C_FLAGS "-marm" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/caches/Armv8Thumb-noexceptions.cmake b/gnu/llvm/libcxx/cmake/caches/Armv8Thumb-noexceptions.cmake index fb1d10efadd..316edd31490 100644 --- a/gnu/llvm/libcxx/cmake/caches/Armv8Thumb-noexceptions.cmake +++ b/gnu/llvm/libcxx/cmake/caches/Armv8Thumb-noexceptions.cmake @@ -1,5 +1,5 @@ set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") -set(LIBCXX_TARGET_TRIPLE "armv8-linux-gnueabihf" CACHE STRING "") +set(CMAKE_CXX_COMPILER_TARGET "armv8l-linux-gnueabihf" CACHE STRING "") set(CMAKE_CXX_FLAGS "-mthumb" CACHE STRING "") set(CMAKE_C_FLAGS "-mthumb" CACHE STRING "") set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-abi-unstable.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-abi-unstable.cmake new file mode 100644 index 00000000000..c87c11490cf --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/Generic-abi-unstable.cmake @@ -0,0 +1 @@ +set(LIBCXX_ABI_UNSTABLE ON CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-asan.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-asan.cmake index cf919765c3a..a86b3474855 100644 --- a/gnu/llvm/libcxx/cmake/caches/Generic-asan.cmake +++ b/gnu/llvm/libcxx/cmake/caches/Generic-asan.cmake @@ -1 +1,3 @@ set(LLVM_USE_SANITIZER "Address" CACHE STRING "") +# This is a temporary (hopefully) workaround for an ASan issue (see https://llvm.org/D119410). +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -asan-use-private-alias=1" CACHE INTERNAL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-assertions.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-assertions.cmake index e8ef72ad16e..a1d348ea9b3 100644 --- a/gnu/llvm/libcxx/cmake/caches/Generic-assertions.cmake +++ b/gnu/llvm/libcxx/cmake/caches/Generic-assertions.cmake @@ -1 +1,2 @@ set(LIBCXX_ENABLE_ASSERTIONS ON CACHE BOOL "") +set(LIBCXXABI_ENABLE_ASSERTIONS ON CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-debug-mode.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-debug-mode.cmake new file mode 100644 index 00000000000..1908da98b18 --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/Generic-debug-mode.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_DEBUG_MODE ON CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-merged.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-merged.cmake new file mode 100644 index 00000000000..b2e02f73105 --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/Generic-merged.cmake @@ -0,0 +1,12 @@ +# Build a libc++ shared library, but merge libc++abi and libunwind into it. +set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") +set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") +set(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY ON CACHE BOOL "") + +set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") +set(LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "") +set(LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY ON CACHE BOOL "") + +set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-no-experimental.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-no-experimental.cmake new file mode 100644 index 00000000000..f33ed014189 --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/Generic-no-experimental.cmake @@ -0,0 +1,2 @@ +set(LIBCXX_TEST_PARAMS "enable_experimental=False" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-no-fstream.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-no-fstream.cmake new file mode 100644 index 00000000000..000d300fe76 --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/Generic-no-fstream.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_FSTREAM OFF CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-no-threads.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-no-threads.cmake new file mode 100644 index 00000000000..616baef1be7 --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/Generic-no-threads.cmake @@ -0,0 +1,3 @@ +set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_THREADS OFF CACHE BOOL "") +set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-no-unicode.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-no-unicode.cmake new file mode 100644 index 00000000000..01160bf2189 --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/Generic-no-unicode.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_UNICODE OFF CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/Generic-no-wide-characters.cmake b/gnu/llvm/libcxx/cmake/caches/Generic-no-wide-characters.cmake new file mode 100644 index 00000000000..728d41086a3 --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/Generic-no-wide-characters.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "") diff --git a/gnu/llvm/libcxx/cmake/caches/MinGW.cmake b/gnu/llvm/libcxx/cmake/caches/MinGW.cmake new file mode 100644 index 00000000000..a5927096d8f --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/MinGW.cmake @@ -0,0 +1,13 @@ +set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "") +set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") + +set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") + +set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") +set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") +set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") + +# Without this flag, 'long double' (which is 80 bit on x86 mingw, but +# 64 bit in MSVC) isn't handled correctly in printf. +set(LIBCXX_EXTRA_SITE_DEFINES "__USE_MINGW_ANSI_STDIO=1" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/caches/s390x-ibm-zos-ascii.cmake b/gnu/llvm/libcxx/cmake/caches/s390x-ibm-zos-ascii.cmake new file mode 100644 index 00000000000..95b7cbe776e --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/s390x-ibm-zos-ascii.cmake @@ -0,0 +1,22 @@ +# Common +set(CMAKE_BUILD_TYPE Release CACHE STRING "") + +set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") +set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXX_INCLUDE_TESTS OFF CACHE BOOL "") +set(LIBCXX_INSTALL_HEADERS OFF CACHE BOOL "") +set(LIBCXX_INCLUDE_BENCHMARKS OFF CACHE BOOL "") + +set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXXABI_INCLUDE_TESTS OFF CACHE BOOL "") + +# Target Specific +set(LIBCXX_DLL_NAME CRTEQCXS CACHE STRING "") +set(LIBCXX_SHARED_OUTPUT_NAME "c++_a" CACHE STRING + "Output name for the shared libc++ runtime library.") +set(LIBCXX_CXX_ABI system-libcxxabi CACHE STRING "") + +set(LIBCXX_ADDITIONAL_COMPILE_FLAGS "-fzos-le-char-mode=ascii" CACHE STRING "") +set(LIBCXX_ADDITIONAL_LIBRARIES "-L../s390x-ibm-zos/lib -Wl,../s390x-ibm-zos/lib/libunwind.x" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/caches/s390x-ibm-zos.cmake b/gnu/llvm/libcxx/cmake/caches/s390x-ibm-zos.cmake new file mode 100644 index 00000000000..3eaed3e67fc --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/s390x-ibm-zos.cmake @@ -0,0 +1,17 @@ +set(CMAKE_BUILD_TYPE Release CACHE STRING "") + +# Common +set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") +set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXX_INCLUDE_TESTS ON CACHE BOOL "") + +set(LIBCXXABI_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXXABI_INCLUDE_TESTS ON CACHE BOOL "") + +# Target Specific +set(LIBCXX_DLL_NAME CRTEQCXE CACHE STRING "") + +set(LIBCXXABI_DLL_NAME CRTEQCXA CACHE STRING "") +set(LIBCXXABI_ADDITIONAL_LIBRARIES "-Wl,lib/libunwind.x" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/caches/s390x32-ibm-zos-ascii.cmake b/gnu/llvm/libcxx/cmake/caches/s390x32-ibm-zos-ascii.cmake new file mode 100644 index 00000000000..9ee03e1b29a --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/s390x32-ibm-zos-ascii.cmake @@ -0,0 +1,22 @@ +# Common +set(CMAKE_BUILD_TYPE Release CACHE STRING "") + +set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") +set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXX_INCLUDE_TESTS OFF CACHE BOOL "") +set(LIBCXX_INSTALL_HEADERS OFF CACHE BOOL "") +set(LIBCXX_INCLUDE_BENCHMARKS OFF CACHE BOOL "") + +set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXXABI_INCLUDE_TESTS OFF CACHE BOOL "") + +# Target Specific +set(LIBCXX_DLL_NAME CRTEHCXS CACHE STRING "") +set(LIBCXX_SHARED_OUTPUT_NAME "c++_a" CACHE STRING + "Output name for the shared libc++ runtime library.") +set(LIBCXX_CXX_ABI system-libcxxabi CACHE STRING "") + +set(LIBCXX_ADDITIONAL_COMPILE_FLAGS "-fzos-le-char-mode=ascii" CACHE STRING "") +set(LIBCXX_ADDITIONAL_LIBRARIES "-L../s390x32-ibm-zos/lib -Wl,../s390x32-ibm-zos/lib/libunwind.x" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/caches/s390x32-ibm-zos.cmake b/gnu/llvm/libcxx/cmake/caches/s390x32-ibm-zos.cmake new file mode 100644 index 00000000000..3e57e0ad838 --- /dev/null +++ b/gnu/llvm/libcxx/cmake/caches/s390x32-ibm-zos.cmake @@ -0,0 +1,18 @@ +# Common +set(CMAKE_BUILD_TYPE Release CACHE STRING "") + +set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") +set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXX_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXX_INCLUDE_TESTS ON CACHE BOOL "") + +set(LIBCXXABI_ENABLE_SHARED ON CACHE BOOL "") +set(LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "") +set(LIBCXXABI_INCLUDE_TESTS ON CACHE BOOL "") + +# Target Specific +set(LIBCXX_DLL_NAME CRTEHCXE CACHE STRING "") + +set(LIBCXXABI_DLL_NAME CRTEHCXA CACHE STRING "") + +set(LIBCXXABI_ADDITIONAL_LIBRARIES "-Wl,lib/libunwind.x" CACHE STRING "") diff --git a/gnu/llvm/libcxx/cmake/config-ix.cmake b/gnu/llvm/libcxx/cmake/config-ix.cmake index a2f1ff9f1a3..3bae5364368 100644 --- a/gnu/llvm/libcxx/cmake/config-ix.cmake +++ b/gnu/llvm/libcxx/cmake/config-ix.cmake @@ -1,9 +1,19 @@ include(CMakePushCheckState) include(CheckLibraryExists) +include(LLVMCheckCompilerLinkerFlag) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include(CheckCSourceCompiles) +# The compiler driver may be implicitly trying to link against libunwind. +# This is normally ok (libcxx relies on an unwinder), but if libunwind is +# built in the same cmake invocation as libcxx and we've got +# LIBCXXABI_USE_LLVM_UNWINDER set, we'd be linking against the just-built +# libunwind (and the compiler implicit -lunwind wouldn't succeed as the newly +# built libunwind isn't installed yet). For those cases, it'd be good to +# link with --uwnindlib=none. Check if that option works. +llvm_check_compiler_linker_flag(C "--unwindlib=none" CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG) + if(WIN32 AND NOT MINGW) # NOTE(compnerd) this is technically a lie, there is msvcrt, but for now, lets # let the default linking take care of that. @@ -33,24 +43,29 @@ endif() # required for the link to go through. We remove sanitizers from the # configuration checks to avoid spurious link errors. -check_c_compiler_flag(-nostdlib++ LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG) -if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG) +check_cxx_compiler_flag(-nostdlib++ CXX_SUPPORTS_NOSTDLIBXX_FLAG) +if (CXX_SUPPORTS_NOSTDLIBXX_FLAG) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++") else() - check_c_compiler_flag(-nodefaultlibs LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) - if (LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) + check_c_compiler_flag(-nodefaultlibs C_SUPPORTS_NODEFAULTLIBS_FLAG) + if (C_SUPPORTS_NODEFAULTLIBS_FLAG) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs") endif() endif() -if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG OR LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) +if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) if (LIBCXX_HAS_C_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES c) endif () if (LIBCXX_USE_COMPILER_RT) - list(APPEND CMAKE_REQUIRED_FLAGS -rtlib=compiler-rt) - find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY) - list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBCXX_BUILTINS_LIBRARY}") + include(HandleCompilerRT) + find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY + FLAGS ${LIBCXX_COMPILE_FLAGS}) + if (LIBCXX_BUILTINS_LIBRARY) + list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBCXX_BUILTINS_LIBRARY}") + else() + message(WARNING "Could not find builtins library from libc++") + endif() elseif (LIBCXX_HAS_GCC_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES gcc) elseif (LIBCXX_HAS_GCC_S_LIB) @@ -73,7 +88,7 @@ if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG OR LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all") endif () if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fsanitize-coverage=0") endif () endif () @@ -83,8 +98,8 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unknown-pragmas") check_c_source_compiles(" #pragma comment(lib, \"c\") -int main() { return 0; } -" LIBCXX_HAS_COMMENT_LIB_PRAGMA) +int main(void) { return 0; } +" C_SUPPORTS_COMMENT_LIB_PRAGMA) cmake_pop_check_state() endif() diff --git a/gnu/llvm/libcxx/docs/AddingNewCIJobs.rst b/gnu/llvm/libcxx/docs/AddingNewCIJobs.rst index bd94a9d7092..f9428f85a45 100644 --- a/gnu/llvm/libcxx/docs/AddingNewCIJobs.rst +++ b/gnu/llvm/libcxx/docs/AddingNewCIJobs.rst @@ -34,9 +34,7 @@ An example of a job definition is: queue: "libcxx-builders" os: "linux" retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 + [...] If you create your own agents, put them in the ``libcxx-builders`` queue and use agent tags to allow targetting your agents from the Buildkite pipeline @@ -48,6 +46,9 @@ it's possible to reproduce CI issues locally with ease, understanding of course that some setups may require access to special hardware that is not available. +Finally, add your contact info to ``libcxx/utils/ci/BOT_OWNERS.txt``. This will +be used to contact you when there are issues with the bot. + Testing Your New Job ==================== diff --git a/gnu/llvm/libcxx/docs/BuildingLibcxx.rst b/gnu/llvm/libcxx/docs/BuildingLibcxx.rst index a29a05b8f7f..59c695efe44 100644 --- a/gnu/llvm/libcxx/docs/BuildingLibcxx.rst +++ b/gnu/llvm/libcxx/docs/BuildingLibcxx.rst @@ -25,50 +25,58 @@ libc++ :ref:`here `. The default build ================= -By default, libc++ and libc++abi are built as sub-projects of the LLVM project. -This can be achieved with the usual CMake invocation: +The default way of building libc++, libc++abi and libunwind is to root the CMake +invocation at ``/runtimes``. While those projects are under the LLVM +umbrella, they are different in nature from other build tools, so it makes sense +to treat them as a separate set of entities. The default build can be achieved +with the following CMake invocation: .. code-block:: bash $ git clone https://github.com/llvm/llvm-project.git $ cd llvm-project $ mkdir build - $ cmake -G Ninja -S llvm -B build -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" # Configure - $ ninja -C build cxx cxxabi # Build - $ ninja -C build check-cxx check-cxxabi # Test - $ ninja -C build install-cxx install-cxxabi # Install + $ cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" # Configure + $ ninja -C build cxx cxxabi unwind # Build + $ ninja -C build check-cxx check-cxxabi check-unwind # Test + $ ninja -C build install-cxx install-cxxabi install-unwind # Install .. note:: See :ref:`CMake Options` below for more configuration options. -After building the ``install-cxx`` and ``install-cxxabi`` targets, shared libraries -for libc++ and libc++abi should now be present in ``/lib``, and -headers in ``/include/c++/v1``. See :ref:`using an alternate -libc++ installation ` for information on how to use this libc++ over -the default one. +After building the various ``install-XXX`` targets, shared libraries for libc++, libc++abi and +libunwind should now be present in ``/lib``, and headers in +``/include/c++/v1``. See :ref:`using an alternate libc++ installation +` for information on how to use this libc++ over the default one. -In the default configuration, libc++ and libc++abi will be built using the compiler available -by default on your system. It is also possible to bootstrap Clang and build libc++ with it. +In the default configuration, the runtimes will be built using the compiler available by default +on your system. Of course, you can change what compiler is being used with the usual CMake +variables. If you wish to build the runtimes from a just-built Clang, the bootstrapping build +explained below makes this task easy. Bootstrapping build =================== -It is also possible to build Clang and then build libc++ and libc++abi using that -just-built compiler. This is the correct way to build libc++ when putting together -a toolchain, or when the system compiler is not adequate to build libc++ (too old, -unsupported, etc.). This type of build is also commonly called a "Runtimes build": +It is possible to build Clang and then build the runtimes using that just-built compiler in a +single CMake invocation. This is usually the correct way to build the runtimes when putting together +a toolchain, or when the system compiler is not adequate to build them (too old, unsupported, etc.). +To do this, use the following CMake invocation, and in particular notice how we're now rooting the +CMake invocation at ``/llvm``: .. code-block:: bash $ mkdir build - $ cmake -G Ninja -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang" \ # Configure - -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ + $ cmake -G Ninja -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang" \ # Configure + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ -DLLVM_RUNTIME_TARGETS="" - $ ninja -C build runtimes # Build - $ ninja -C build check-runtimes # Test - $ ninja -C build install-runtimes # Install + $ ninja -C build runtimes # Build + $ ninja -C build check-runtimes # Test + $ ninja -C build install-runtimes # Install +.. note:: + This type of build is also commonly called a "Runtimes build", but we would like to move + away from that terminology, which is too confusing. Support for Windows =================== @@ -87,11 +95,11 @@ it is the simplest way to build. .. code-block:: batch - > cmake -G "Visual Studio 16 2019" -S libcxx -B build ^ - -T "ClangCL" ^ - -DLIBCXX_ENABLE_SHARED=YES ^ - -DLIBCXX_ENABLE_STATIC=NO ^ - -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO + > cmake -G "Visual Studio 16 2019" -S runtimes -B build ^ + -T "ClangCL" ^ + -DLLVM_ENABLE_RUNTIMES=libcxx ^ + -DLIBCXX_ENABLE_SHARED=YES ^ + -DLIBCXX_ENABLE_STATIC=NO > cmake --build build CMake + ninja (MSVC) @@ -119,16 +127,16 @@ In either case, then run: .. code-block:: batch - > cmake -G Ninja -S libcxx -B build ^ + > cmake -G Ninja -S runtimes -B build ^ -DCMAKE_C_COMPILER=clang-cl ^ -DCMAKE_CXX_COMPILER=clang-cl ^ - -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO + -DLLVM_ENABLE_RUNTIMES=libcxx > ninja -C build cxx > ninja -C build check-cxx If you are running in an MSYS2 shell and you have installed the MSYS2-provided clang package (which defaults to a non-MSVC target), you -should add e.g. ``-DLIBCXX_TARGET_TRIPLE=x86_64-windows-msvc`` (replacing +should add e.g. ``-DCMAKE_CXX_COMPILER_TARGET=x86_64-windows-msvc`` (replacing ``x86_64`` with the architecture you're targeting) to the ``cmake`` command line above. This will instruct ``check-cxx`` to use the right target triple when invoking ``clang++``. @@ -145,12 +153,11 @@ e.g. the ``mingw-w64-x86_64-clang`` package), together with CMake and ninja. .. code-block:: bash - > cmake -G Ninja -S libcxx -B build \ + > cmake -G Ninja -S runtimes -B build \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ - -DLIBCXX_HAS_WIN32_THREAD_API=ON \ - -DLIBCXX_CXX_ABI=libstdc++ \ - -DLIBCXX_TARGET_INFO="libcxx.test.target_info.MingwLocalTI" + -DLLVM_ENABLE_RUNTIMES=libcxx \ + -DLIBCXX_CXX_ABI=libstdc++ > ninja -C build cxx > cp /mingw64/bin/{libstdc++-6,libgcc_s_seh-1,libwinpthread-1}.dll lib > ninja -C build check-cxx @@ -208,13 +215,10 @@ libc++ specific options **Default**: ``OFF`` - Build libc++ with assertions enabled. - -.. option:: LIBCXX_BUILD_32_BITS:BOOL - - **Default**: ``OFF`` - - Build libc++ as a 32 bit library. Also see `LLVM_BUILD_32_BITS`. + Build libc++ with assertions enabled in the compiled library, and enable assertions + by default when building user code as well. Assertions can be turned off by users + by defining ``_LIBCPP_ENABLE_ASSERTIONS=0``. For details, see + :ref:`the documentation `. .. option:: LIBCXX_ENABLE_SHARED:BOOL @@ -251,14 +255,14 @@ libc++ specific options This option can be used to enable or disable the filesystem components on platforms that may not support them. For example on Windows when using MSVC. -.. option:: LIBCXX_ENABLE_INCOMPLETE_FEATURES:BOOL +.. option:: LIBCXX_ENABLE_WIDE_CHARACTERS:BOOL - **Default**: ``ON`` + **Default**: ``ON`` - Whether to enable support for incomplete library features. Incomplete features - are new library features under development. These features don't guarantee - ABI stability nor the quality of completed library features. Vendors - shipping the library may want to disable this option. + This option can be used to disable support for ``wchar_t`` in the library. It also + allows the library to work on top of a C Standard Library that does not provide + support for ``wchar_t``. This is especially useful in embedded settings where + C Standard Libraries don't always provide all the usual bells and whistles. .. option:: LIBCXX_INSTALL_LIBRARY_DIR:PATH @@ -282,22 +286,23 @@ libc++ specific options Path where target-specific libc++ headers should be installed. If a relative path, relative to ``CMAKE_INSTALL_PREFIX``. -.. _libc++experimental options: +.. option:: LIBCXX_SHARED_OUTPUT_NAME:STRING -libc++experimental Specific Options ------------------------------------- + **Default**: ``c++`` -.. option:: LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL + Output name for the shared libc++ runtime library. - **Default**: ``ON`` +.. option:: LIBCXX_ADDITIONAL_COMPILE_FLAGS:STRING - Build and test libc++experimental.a. + **Default**: ``""`` -.. option:: LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY:BOOL + Additional Compile only flags which can be provided in cache. - **Default**: ``LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY AND LIBCXX_INSTALL_LIBRARY`` +.. option:: LIBCXX_ADDITIONAL_LIBRARIES:STRING - Install libc++experimental.a alongside libc++. + **Default**: ``""`` + + Additional libraries libc++ is linked to which can be provided in cache. .. _ABI Library Specific Options: @@ -307,7 +312,7 @@ ABI Library Specific Options .. option:: LIBCXX_CXX_ABI:STRING - **Values**: ``none``, ``libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``. + **Values**: ``none``, ``libcxxabi``, ``system-libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``, ``vcruntime``. Select the ABI library to build libc++ against. @@ -317,7 +322,8 @@ ABI Library Specific Options .. option:: LIBCXX_CXX_ABI_LIBRARY_PATH:PATH - Provide the path to the ABI library that libc++ should link against. + Provide the path to the ABI library that libc++ should link against. This is only + useful when linking against an out-of-tree ABI library. .. option:: LIBCXX_ENABLE_STATIC_ABI_LIBRARY:BOOL @@ -341,6 +347,18 @@ ABI Library Specific Options Build and use the LLVM unwinder. Note: This option can only be used when libc++abi is the C++ ABI library used. +.. option:: LIBCXXABI_ADDITIONAL_COMPILE_FLAGS:STRING + + **Default**: ``""`` + + Additional Compile only flags which can be provided in cache. + +.. option:: LIBCXXABI_ADDITIONAL_LIBRARIES:STRING + + **Default**: ``""`` + + Additional libraries libc++abi is linked to which can be provided in cache. + libc++ Feature Options ---------------------- @@ -395,15 +413,6 @@ libc++ Feature Options Use the specified GCC toolchain and standard library when building the native stdlib benchmark tests. -.. option:: LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT:BOOL - - **Default**: ``OFF`` - - Pick the default for whether to constrain ABI-unstable symbols to - each individual translation unit. This setting controls whether - `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined by default -- - see the documentation of that macro for details. - libc++ ABI Feature Options -------------------------- @@ -432,10 +441,10 @@ The following options allow building libc++ for a different ABI version. with other libc++ versions. .. warning:: - When providing a custom namespace, it's the users responsibility to ensure the name won't cause + When providing a custom namespace, it's the user's responsibility to ensure the name won't cause conflicts with other names defined by libc++, both now and in the future. In particular, inline - namespaces of the form ``__[0-9]+`` are strictly reserved by libc++ and may not be used by users. - Doing otherwise could cause conflicts and hinder libc++ ABI evolution. + namespaces of the form ``__[0-9]+`` could cause conflicts with future versions of the library, + and so should be avoided. .. option:: LIBCXX_ABI_DEFINES:STRING @@ -512,8 +521,8 @@ We can now run CMake: .. code-block:: bash - $ cmake -G Ninja -S llvm -B build \ - -DLLVM_ENABLE_PROJECTS="libcxx" \ + $ cmake -G Ninja -S runtimes -B build \ + -DLLVM_ENABLE_RUNTIMES="libcxx" \ -DLIBCXX_CXX_ABI=libstdc++ \ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/" $ ninja -C build install-cxx @@ -538,8 +547,8 @@ We can now run CMake like: .. code-block:: bash - $ cmake -G Ninja -S llvm -B build \ - -DLLVM_ENABLE_PROJECTS="libcxx" \ + $ cmake -G Ninja -S runtimes -B build \ + -DLLVM_ENABLE_RUNTIMES="libcxx" \ -DLIBCXX_CXX_ABI=libcxxrt \ -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxrt-sources/src $ ninja -C build install-cxx diff --git a/gnu/llvm/libcxx/docs/Contributing.rst b/gnu/llvm/libcxx/docs/Contributing.rst index 9d52445c368..186ac6695a8 100644 --- a/gnu/llvm/libcxx/docs/Contributing.rst +++ b/gnu/llvm/libcxx/docs/Contributing.rst @@ -12,6 +12,9 @@ For libc++, please make sure you follow `these instructions `__. + Looking for pre-existing reviews ================================ @@ -34,7 +37,7 @@ sure you don't forget anything: - Did you mark all functions and type declarations with the :ref:`proper visibility macro `? - If you added a header: - - Did you add it to ``include/module.modulemap``? + - Did you add it to ``include/module.modulemap.in``? - Did you add it to ``include/CMakeLists.txt``? - If it's a public header, did you add a test under ``test/libcxx`` that the new header defines ``_LIBCPP_VERSION``? See ``test/libcxx/algorithms/version.pass.cpp`` for an example. NOTE: This should be automated. - If it's a public header, did you update ``utils/generate_header_inclusion_tests.py``? @@ -42,14 +45,33 @@ sure you don't forget anything: - Did you add the relevant feature test macro(s) for your feature? Did you update the ``generate_feature_test_macro_components.py`` script with it? - Did you run the ``libcxx-generate-files`` target and verify its output? +The review process +================== + +After uploading your patch, you should see that the "libc++" review group is automatically +added as a reviewer for your patch. Once the group is marked as having approved your patch, +you can commit it. However, if you get an approval very quickly for a significant patch, +please try to wait a couple of business days before committing to give the opportunity for +other reviewers to chime in. If you need someone else to commit the patch for you, please +mention it and provide your ``Name `` for us to attribute the commit properly. + +Note that the rule for accepting as the "libc++" review group is to wait for two members +of the group to have approved the patch, excluding the patch author. This is not a hard +rule -- for very simple patches, use your judgement. The `"libc++" review group `__ +consists of frequent libc++ contributors with a good understanding of the project's +guidelines -- if you would like to be added to it, please reach out on Discord. + Post-release check list ======================= After branching for an LLVM release: -1. Update ``_LIBCPP_VERSION`` in ``include/__config`` -2. Update the ``include/__libcpp_version`` file -3. Update the version number in ``docs/conf.py`` +1. Update ``_LIBCPP_VERSION`` in ``libcxx/include/__config`` +2. Update the version number in ``libcxx/docs/conf.py`` +3. Update ``_LIBCPPABI_VERSION`` in ``libcxxabi/include/cxxabi.h`` +4. Update ``_LIBUNWIND_VERSION`` in ``libunwind/include/__libunwind_config.h`` +5. Update the list of supported clang versions in ``libcxx/docs/index.rst`` +6. Remove the in-progress warning from ``libcxx/docs/ReleaseNotes.rst`` Exporting new symbols from the library ====================================== @@ -64,5 +86,136 @@ updated list from the failed build at Look for the failed build and select the ``artifacts`` tab. There, download the abilist for the platform, e.g.: -* C++20 for the Linux platform. -* MacOS C++20 for the Apple platform. +* C++. +* MacOS X86_64 and MacOS arm64 for the Apple platform. + + +Pre-commit CI +============= + +Introduction +------------ + +Unlike most parts of the LLVM project, libc++ uses a pre-commit CI [#]_. This +CI is hosted on `Buildkite `__ and +the build results are visible in the review on Phabricator. Please make sure +the CI is green before committing a patch. + +The CI tests libc++ for all :ref:`supported platforms `. +The build is started for every diff uploaded to Phabricator. A complete CI run +takes approximately one hour. To reduce the load: + +* The build is cancelled when a new diff for the same revision is uploaded. +* The build is done in several stages and cancelled when a stage fails. + +Typically, the libc++ jobs use a Ubuntu Docker image. This image contains +recent `nightly builds `__ of all supported versions of +Clang and the current version of the ``main`` branch. These versions of Clang +are used to build libc++ and execute its tests. + +Unless specified otherwise, the configurations: + +* use a nightly build of the ``main`` branch of Clang, +* execute the tests using the language C++. This is the version + "developed" by the C++ committee. + +.. note:: Updating the Clang nightly builds in the Docker image is a manual + process and is done at an irregular interval on purpose. When you need to + have the latest nightly build to test recent Clang changes, ask in the + ``#libcxx`` channel on `LLVM's Discord server + `__. + +.. [#] There's `LLVM Dev Meeting talk `__ + explaining the benefits of libc++'s pre-commit CI. + +Builds +------ + +Below is a short description of the most interesting CI builds [#]_: + +* ``Format`` runs ``clang-format`` and uploads its output as an artifact. At the + moment this build is a soft error and doesn't fail the build. +* ``Generated output`` runs the ``libcxx-generate-files`` build target and + tests for non-ASCII characters in libcxx. Some files are excluded since they + use Unicode, mainly tests. The output of these commands are uploaded as + artifact. +* ``Documentation`` builds the documentation. (This is done early in the build + process since it is cheap to run.) +* ``C++`` these build steps test the various C++ versions, making sure all + C++ language versions work with the changes made. +* ``Clang `` these build steps test whether the changes work with all + supported Clang versions. +* ``Booststrapping build`` builds Clang using the revision of the patch and + uses that Clang version to build and test libc++. This validates the current + Clang and lib++ are compatible. + + When a crash occurs in this build, the crash reproducer is available as an + artifact. + +* ``Modular build`` tests libc++ using Clang modules [#]_. +* ``GCC `` tests libc++ with the latest stable GCC version. Only C++11 + and the latest C++ version are tested. +* ``Santitizers`` tests libc++ using the Clang sanitizers. +* ``Parts disabled`` tests libc++ with certain libc++ features disabled. +* ``Windows`` tests libc++ using MinGW and clang-cl. +* ``Apple`` tests libc++ on MacOS. +* ``ARM`` tests libc++ on various Linux ARM platforms. +* ``AIX`` tests libc++ on AIX. + +.. [#] Not all all steps are listed: steps are added and removed when the need + arises. +.. [#] Clang modules are not the same as C++20's modules. + +Infrastructure +-------------- + +All files of the CI infrastructure are in the directory ``libcxx/utils/ci``. +Note that quite a bit of this infrastructure is heavily Linux focused. This is +the platform used by most of libc++'s Buildkite runners and developers. + +Dockerfile +~~~~~~~~~~ + +Contains the Docker image for the Ubuntu CI. Because the same Docker image is +used for the ``main`` and ``release`` branch, it should contain no hard-coded +versions. It contains the used versions of Clang, various clang-tools, +GCC, and CMake. + +.. note:: This image is pulled from Docker hub and not rebuild when changing + the Dockerfile. + +run-buildbot-container +~~~~~~~~~~~~~~~~~~~~~~ + +Helper script that pulls and runs the Docker image. This image mounts the LLVM +monorepo at ``/llvm``. This can be used to test with compilers not available on +your system. + +run-buildbot +~~~~~~~~~~~~ + +Contains the buld script executed on Buildkite. This script can be executed +locally or inside ``run-buildbot-container``. The script must be called with +the target to test. For example, ``run-buildbot generic-cxx20`` will build +libc++ and test it using C++20. + +.. warning:: This script will overwrite the directory ``/build/XX`` + where ``XX`` is the target of ``run-buildbot``. + +This script contains as little version information as possible. This makes it +easy to use the script with a different compiler. This allows testing a +combination not in the libc++ CI. It can be used to add a new (temporary) +job to the CI. For example, testing the C++17 build with Clang-14 can be done +like: + +.. code-block:: bash + + CC=clang-14 CXX=clang++-14 run-buildbot generic-cxx17 + +buildkite-pipeline.yml +~~~~~~~~~~~~~~~~~~~~~~ + +Contains the jobs executed in the CI. This file contains the version +information of the jobs being executed. Since this script differs between the +``main`` and ``release`` branch, both branches can use different compiler +versions. diff --git a/gnu/llvm/libcxx/docs/DesignDocs/CapturingConfigInfo.rst b/gnu/llvm/libcxx/docs/DesignDocs/CapturingConfigInfo.rst index 8f2d0cd2dd6..402f4c7197c 100644 --- a/gnu/llvm/libcxx/docs/DesignDocs/CapturingConfigInfo.rst +++ b/gnu/llvm/libcxx/docs/DesignDocs/CapturingConfigInfo.rst @@ -1,6 +1,6 @@ -======================================================= -Capturing configuration information during installation -======================================================= +================================================== +Capturing configuration information in the headers +================================================== .. contents:: :local: @@ -8,79 +8,61 @@ Capturing configuration information during installation The Problem =========== -Currently the libc++ supports building the library with a number of different -configuration options. Unfortunately all of that configuration information is -lost when libc++ is installed. In order to support "persistent" -configurations libc++ needs a mechanism to capture the configuration options -in the INSTALLED headers. +libc++ supports building the library with a number of different configuration options. +In order to support persistent configurations and reduce arbitrary preprocessor logic +in the headers, libc++ has a mechanism to capture configuration options in the +installed headers so they can be used in the rest of the code. Design Goals ============ -* The solution should not INSTALL any additional headers. We don't want an extra - #include slowing everybody down. +* The solution should be simple, consistent and robust to avoid subtle bugs. -* The solution should not unduly affect libc++ developers. The problem is limited - to installed versions of libc++ and the solution should be as well. +* Developers should test the code the same way it will be deployed -- in other words, + the headers used to run tests should be the same that we install in order + to avoid bugs creeping up. -* The solution should not modify any existing headers EXCEPT during installation. - It makes developers lives harder if they have to regenerate the libc++ headers - every time they are modified. - -* The solution should not make any of the libc++ headers dependent on - files generated by the build system. The headers should be able to compile - out of the box without any modification. - -* The solution should not have ANY effect on users who don't need special - configuration options. The vast majority of users will never need this so it - shouldn't cost them. +* It should allow different targets or flavors of the library to use a different + configuration without having to duplicate all the libc++ headers. The Solution ============ -When you first configure libc++ using CMake we check to see if we need to -capture any options. If we haven't been given any "persistent" options then -we do NOTHING. - -Otherwise we create a custom installation rule that modifies the installed __config -header. The rule first generates a dummy "__config_site" header containing the required -#defines. The contents of the dummy header are then prepended to the installed -__config header. By manually prepending the files we avoid the cost of an -extra #include and we allow the __config header to be ignorant of the extra -configuration all together. An example "__config" header generated when --DLIBCXX_ENABLE_THREADS=OFF is given to CMake would look something like: - -.. code-block:: cpp - - //===----------------------------------------------------------------------===// - // - // 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_CONFIG_SITE - #define _LIBCPP_CONFIG_SITE - - /* #undef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE */ - /* #undef _LIBCPP_HAS_NO_STDIN */ - /* #undef _LIBCPP_HAS_NO_STDOUT */ - #define _LIBCPP_HAS_NO_THREADS - /* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */ - /* #undef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS */ - - #endif - // -*- C++ -*- - //===--------------------------- __config ---------------------------------===// - // - // 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_CONFIG - #define _LIBCPP_CONFIG +When you first configure libc++ using CMake, a ``__config_site`` file is generated +to capture the various configuration options you selected. The ``__config`` header +used by all other headers includes this ``__config_site`` header first in order to +get the correct configuration. + +The ``__config_site`` header is hence the only place where persistent configuration +is stored in the library. That header essentially reflects how the vendor configured +the library. As we evolve the library, we can lift configuration options into that +header in order to reduce arbitrary hardcoded choices elsewhere in the code. For +example, instead of assuming that a specific platform doesn't provide some functionality, +we can create a generic macro to guard it and vendors can define the macro when +configuring the library on that platform. This makes the "carve off" reusable in +other circumstances instead of tying it tightly to a single platform. + +Furthermore, the Clang driver now looks for headers in a target-specific directory +for libc++. By installing the ``__config_site`` header (and only that header) to +this target-specific directory, it is possible to share the libc++ headers for +multiple targets, and only duplicate the persistent information located in the +``__config_site`` header. For example: + +.. code-block:: bash + + include/c++/v1/ + vector + map + etc... + + include//c++/v1/ + __config_site + + include//c++/v1/ + __config_site + +When compiling for ``targetA``, Clang will use the ``__config_site`` inside +``include//c++/v1/``, and the corresponding ``__config_site`` for +``targetB``. diff --git a/gnu/llvm/libcxx/docs/DesignDocs/DebugMode.rst b/gnu/llvm/libcxx/docs/DesignDocs/DebugMode.rst index abcd5e5c8c6..5c8c4900c88 100644 --- a/gnu/llvm/libcxx/docs/DesignDocs/DebugMode.rst +++ b/gnu/llvm/libcxx/docs/DesignDocs/DebugMode.rst @@ -12,40 +12,46 @@ Using the debug mode Libc++ provides a debug mode that enables special debugging checks meant to detect incorrect usage of the standard library. These checks are disabled by default, but -they can be enabled using the ``_LIBCPP_DEBUG`` macro. +they can be enabled by vendors when building the library by using ``LIBCXX_ENABLE_DEBUG_MODE``. + +Since the debug mode has ABI implications, users should compile their whole program, +including any dependent libraries, against a Standard library configured identically +with respect to the debug mode. In other words, they should not mix code built against +a Standard library with the debug mode enabled with code built against a Standard library +where the debug mode is disabled. + +Furthermore, users should not rely on a stable ABI being provided when the debug mode is +enabled -- we reserve the right to change the ABI at any time. If you need a stable ABI +and still want some level of hardening, you should look into enabling :ref:`assertions ` +instead. + +The debug mode provides various checks to aid application debugging. + +Comparator consistency checks +----------------------------- +Libc++ provides some checks for the consistency of comparators passed to algorithms. Specifically, +many algorithms such as ``binary_search``, ``merge``, ``next_permutation``, and ``sort``, wrap the +user-provided comparator to assert that `!comp(y, x)` whenever `comp(x, y)`. This can cause the +user-provided comparator to be evaluated up to twice as many times as it would be without the +debug mode, and causes the library to violate some of the Standard's complexity clauses. + +Iterator bounds checking +------------------------ +The library provides iterators that ensure they are within the bounds of their container when dereferenced. +Arithmetic can be performed on these iterators to create out-of-bounds iterators, but they cannot be dereferenced +when out-of-bounds. The following classes currently provide iterators that have bounds checking: -Note that using the debug mode discussed in this document requires that the library -has been compiled with support for the debug mode (see ``LIBCXX_ENABLE_DEBUG_MODE_SUPPORT``). - -Also note that while the debug mode has no effect on libc++'s ABI, it does have broad ODR -implications. Users should compile their whole program at the same debugging level. - -The various levels of checking provided by the debug mode follow. - -No debugging checks (``_LIBCPP_DEBUG`` not defined) ---------------------------------------------------- -When ``_LIBCPP_DEBUG`` is not defined, there are no debugging checks performed by -the library. This is the default. - -Basic checks (``_LIBCPP_DEBUG == 0``) -------------------------------------- -When ``_LIBCPP_DEBUG`` is defined to ``0`` (to be understood as level ``0``), some -debugging checks are enabled. The non-exhaustive list of things is: - -- Many algorithms, such as ``binary_search``, ``merge``, ``next_permutation``, and ``sort``, - wrap the user-provided comparator to assert that `!comp(y, x)` whenever - `comp(x, y)`. This can cause the user-provided comparator to be evaluated - up to twice as many times as it would be without ``_LIBCPP_DEBUG``, and - causes the library to violate some of the Standard's complexity clauses. - -- FIXME: Update this list +- ``std::string`` +- ``std::vector`` (``T != bool``) +- ``std::span`` -Iterator debugging checks (``_LIBCPP_DEBUG == 1``) --------------------------------------------------- -Defining ``_LIBCPP_DEBUG`` to ``1`` enables "iterator debugging", which provides -additional assertions about the validity of iterators used by the program. +.. TODO: Add support for iterator bounds checking in ``std::string_view`` and ``std::array`` -The following containers and classes support iterator debugging: +Iterator ownership checking +--------------------------- +The library provides iterator ownership checking, which allows catching cases where e.g. +an iterator from container ``X`` is used as a position to insert into container ``Y``. +The following classes support iterator ownership checking: - ``std::string`` - ``std::vector`` (``T != bool``) @@ -55,28 +61,11 @@ The following containers and classes support iterator debugging: - ``std::unordered_set`` - ``std::unordered_multiset`` -The remaining containers do not currently support iterator debugging. -Patches welcome. - -Handling Assertion Failures -=========================== -When a debug assertion fails the assertion handler is called via the -``std::__libcpp_debug_function`` function pointer. It is possible to override -this function pointer using a different handler function. Libc++ provides a -the default handler, ``std::__libcpp_abort_debug_handler``, which aborts the -program. The handler may not return. Libc++ can be changed to use a custom -assertion handler as follows. - -.. code-block:: cpp - - #define _LIBCPP_DEBUG 1 - #include - void my_handler(std::__libcpp_debug_info const&); - int main(int, char**) { - std::__libcpp_debug_function = &my_handler; - - std::string::iterator bad_it; - std::string str("hello world"); - str.insert(bad_it, '!'); // causes debug assertion - // control flow doesn't return - } +Randomizing unspecified behavior +-------------------------------- +The library supports the randomization of unspecified behavior. For example, randomizing +the relative order of equal elements in ``std::sort`` or randomizing both parts of the +partition after calling ``std::nth_element``. This effort helps migrating to potential +future faster versions of these algorithms that might not have the exact same behavior. +In particular, it makes it easier to deflake tests that depend on unspecified behavior. +A seed can be used to make such failures reproducible: use ``_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED=seed``. diff --git a/gnu/llvm/libcxx/docs/DesignDocs/ExperimentalFeatures.rst b/gnu/llvm/libcxx/docs/DesignDocs/ExperimentalFeatures.rst index 2241496d594..defe0e4e242 100644 --- a/gnu/llvm/libcxx/docs/DesignDocs/ExperimentalFeatures.rst +++ b/gnu/llvm/libcxx/docs/DesignDocs/ExperimentalFeatures.rst @@ -143,7 +143,8 @@ Most (but not all) of the features of the LFTS were accepted into C++17. `FileSystem TS `__ ------------------------------------------- The FileSystem TS was accepted (in totality) for C++17. -The FileSystem TS implementation was shipped in namespace ``std`` in LLVM 7.0, and will be removed in LLVM 11.0 (due to the lack of deprecation warnings before LLVM 9.0). +The FileSystem TS implementation was shipped in namespace ``std`` in LLVM 7.0, and was +removed in LLVM 11.0 (due to the lack of deprecation warnings before LLVM 9.0). Parallelism TS `V1 `__ and `V2 `__ ------------------------------------------------------------------------------------ @@ -152,8 +153,10 @@ We have not yet shipped an implementation of the Parallelism TS. `Coroutines TS `__ ------------------------------------------- -The Coroutines TS is not yet part of a shipping standard. -We are shipping (as of v5.0) an implementation of the Coroutines TS in namespace ``std::experimental``. +The Coroutines TS was accepted for C++20. +An implementation of the Coroutines TS was shipped in LLVM 5.0 in namespace ``std::experimental``, +and C++20 Coroutines shipped in LLVM 14.0. The implementation of the Coroutines TS in ``std::experimental`` +will be removed in LLVM 16.0. `Networking TS `__ ------------------------------------------- @@ -162,13 +165,15 @@ We have not yet shipped an implementation of the Networking TS. `Ranges TS `__ --------------------------------------- -The Ranges TS is not yet part of a shipping standard. -We have not yet shipped an implementation of the Ranges TS. +The Ranges TS was accepted for C++20. +We will not ship an implementation of the Ranges TS, however we are actively working on +the implementation of C++20 Ranges. `Concepts TS `__ ----------------------------------------- -The Concepts TS is not yet part of a shipping standard, but it has been adopted into the C++20 working draft. -We have not yet shipped an implementation of the Concepts TS. +The Concepts TS was accepted for C++20. +We will not ship an implementation of the Concepts TS, however we are shipping an +implementation of C++20 Concepts. `Concurrency TS `__ -------------------------------------------- diff --git a/gnu/llvm/libcxx/docs/DesignDocs/ExtendedCXX03Support.rst b/gnu/llvm/libcxx/docs/DesignDocs/ExtendedCXX03Support.rst index e9e3fc4d230..213cf2dab01 100644 --- a/gnu/llvm/libcxx/docs/DesignDocs/ExtendedCXX03Support.rst +++ b/gnu/llvm/libcxx/docs/DesignDocs/ExtendedCXX03Support.rst @@ -27,12 +27,12 @@ libc++ expects Clang to provide are: * Alias templates * defaulted and deleted Functions. * reference qualified Functions +* ``auto`` There are also features that Clang *does not* provide as an extension in C++03 mode. These include: * ``constexpr`` and ``noexcept`` -* ``auto`` * Trailing return types. * ``>>`` without a space. diff --git a/gnu/llvm/libcxx/docs/DesignDocs/HeaderRemovalPolicy.rst b/gnu/llvm/libcxx/docs/DesignDocs/HeaderRemovalPolicy.rst new file mode 100644 index 00000000000..02cbc162318 --- /dev/null +++ b/gnu/llvm/libcxx/docs/DesignDocs/HeaderRemovalPolicy.rst @@ -0,0 +1,61 @@ +===================== +Header Removal Policy +===================== + +Policy +------ + +Libc++ is in the process of splitting larger headers into smaller modular +headers. This makes it possible to remove these large headers from other +headers. For example, instead of including ```` entirely it is +possible to only include the headers for the algorithms used. When the +Standard indirectly adds additional header includes, using the smaller headers +aids reducing the growth of top-level headers. For example ```` uses +``std::chrono::nanoseconds`` and included ````. In C++20 ```` +requires ```` which adds several other headers (like ````, +````, ````) which are not needed in ````. + +The benefit of using minimal headers is that the size of libc++'s top-level +headers becomes smaller. This improves the compilation time when users include +a top-level header. It also avoids header inclusion cycles and makes it easier +to port headers to platforms with reduced functionality. + +A disadvantage is that users unknowingly depend on these transitive includes. +Thus removing an include might break their build after upgrading a newer +version of libc++. For example, ```` is often forgotten but using +algorithms will still work through those transitive includes. This problem is +solved by modules, however in practice most people do not use modules (yet). + +To ease the removal of transitive includes in libc++, libc++ will remove +unnecessary transitive includes in newly supported C++ versions. This means +that users will have to fix their missing includes in order to upgrade to a +newer version of the Standard. Libc++ also reserves the right to remove +transitive includes at any other time, however new language versions will be +used as a convenient way to perform bulk removals of transitive includes. + +For libc++ developers, this means that any transitive include removal must be +guarded by something of the form: + +.. code-block:: cpp + + #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 + # include + # include + # include + #endif + +When users define ``_LIBCPP_REMOVE_TRANSITIVE_INCLUDES``, libc++ will not +include transitive headers, regardless of the language version. This can be +useful for users to aid the transition to a newer language version, or by users +who simply want to make sure they include what they use in their code. + + +Rationale +--------- + +Removing headers is not only an issue for software developers, but also for +vendors. When a vendor updates libc++ several of their upstream packages might +fail to compile, forcing them to fix these packages or file a bug with their +upstream packages. Usually upgrading software to a new language standard is +done explicitly by software developers. This means they most likely will +discover and fix the missing includes, lessening the burden for the vendors. diff --git a/gnu/llvm/libcxx/docs/DesignDocs/NoexceptPolicy.rst b/gnu/llvm/libcxx/docs/DesignDocs/NoexceptPolicy.rst index 8dc5e14e486..74c8ca406ed 100644 --- a/gnu/llvm/libcxx/docs/DesignDocs/NoexceptPolicy.rst +++ b/gnu/llvm/libcxx/docs/DesignDocs/NoexceptPolicy.rst @@ -1,9 +1,9 @@ -==================== +=================== ``noexcept`` Policy -==================== +=================== Extended applications of ``noexcept`` ------------------------------------------- +------------------------------------- As of version 13 libc++ may mark functions that do not throw (i.e., "Throws: Nothing") as ``noexcept``. This has two primary consequences: diff --git a/gnu/llvm/libcxx/docs/DesignDocs/UniquePtrTrivialAbi.rst b/gnu/llvm/libcxx/docs/DesignDocs/UniquePtrTrivialAbi.rst index a0f260a44e8..1af0b342636 100644 --- a/gnu/llvm/libcxx/docs/DesignDocs/UniquePtrTrivialAbi.rst +++ b/gnu/llvm/libcxx/docs/DesignDocs/UniquePtrTrivialAbi.rst @@ -36,7 +36,7 @@ Design ====== * Annotate the two definitions of ``std::unique_ptr`` with ``clang::trivial_abi`` attribute. -* Put the attribuate behind a flag because this change has potential compilation and runtime breakages. +* Put the attribute behind a flag because this change has potential compilation and runtime breakages. This comes with some side effects: diff --git a/gnu/llvm/libcxx/docs/DesignDocs/UnspecifiedBehaviorRandomization.rst b/gnu/llvm/libcxx/docs/DesignDocs/UnspecifiedBehaviorRandomization.rst new file mode 100644 index 00000000000..7e92e27120b --- /dev/null +++ b/gnu/llvm/libcxx/docs/DesignDocs/UnspecifiedBehaviorRandomization.rst @@ -0,0 +1,86 @@ +================================== +Unspecified Behavior Randomization +================================== + +Background +========== + +Consider the follow snippet which steadily happens in tests: + + +.. code-block:: cpp + + std::vector> v(SomeData()); + std::sort(v.begin(), v.end(), [](const auto& lhs, const auto& rhs) { + return lhs.first < rhs.first; + }); + +Under this assumption all elements in the vector whose first elements are equal +do not guarantee any order. Unfortunately, this prevents libcxx introducing +other implementatiosn because tests might silently fail and the users might +heavily depend on the stability of implementations. + +Goal +=================== + +Provide functionality for randomizing the unspecified behavior so that the users +can test and migrate their components and libcxx can introduce new sorting +algorithms and optimizations to the containers. + +For example, as of LLVM version 13, libcxx sorting algorithm takes +`O(n^2) worst case `_ but according +to the standard its worst case should be `O(n log n)`. This effort helps users +to gradually fix their tests while updating to new faster algorithms. + +Design +====== + +* Introduce new macro ``_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY`` which should + be a part of the libcxx config. +* This macro randomizes the unspecified behavior of algorithms and containers. + For example, for sorting algorithm the input range is shuffled and then + sorted. +* This macro is off by default because users should enable it only for testing + purposes and/or migrations if they happen to libcxx. +* This feature is only available for C++11 and further because of + ``std::shuffle`` availability. +* We may use `ASLR `_ or + static ``std::random_device`` for seeding the random number generator. This + guarantees the same stability guarantee within a run but not through different + runs, for example, for tests become flaky and eventually be seen as broken. + For platforms which do not support ASLR, the seed is fixed during build. +* The users can fix the seed of the random number generator by providing + ``_LIBCPP_RANDOMIZE_UNSPECIFIED_STABILITY_SEED=seed`` definition. + +This comes with some side effects if any of the flags is on: + +* Computation penalty, we think users are OK with that if they use this feature. +* Non reproducible results if they don't use the fixed seed. + + +Impact +------------------ + +Google has measured couple of thousands of tests to be dependent on the +stability of sorting and selection algorithms. As we also plan on updating +(or least, providing under flag more) sorting algorithms, this effort helps +doing it gradually and sustainably. This is also bad for users to depend on the +unspecified behavior in their tests, this effort helps to turn this flag in +debug mode. + +Potential breakages +------------------- + +None if the flag is off. If the flag is on, it may lead to some non-reproducible +results, for example, for caching. + +Currently supported randomization +--------------------------------- + +* ``std::sort``, there is no guarantee on the order of equal elements +* ``std::partial_sort``, there is no guarantee on the order of equal elements and + on the order of the remaining part +* ``std::nth_element``, there is no guarantee on the order from both sides of the + partition + +Patches welcome. diff --git a/gnu/llvm/libcxx/docs/DesignDocs/VisibilityMacros.rst b/gnu/llvm/libcxx/docs/DesignDocs/VisibilityMacros.rst index e5aa50097dd..d1c162682b6 100644 --- a/gnu/llvm/libcxx/docs/DesignDocs/VisibilityMacros.rst +++ b/gnu/llvm/libcxx/docs/DesignDocs/VisibilityMacros.rst @@ -65,41 +65,6 @@ Visibility Macros ABI, we should create a new _LIBCPP_HIDE_FROM_ABI_AFTER_XXX macro, and we can use it to start removing symbols from the ABI after that stable version. -**_LIBCPP_HIDE_FROM_ABI_PER_TU** - This macro controls whether symbols hidden from the ABI with `_LIBCPP_HIDE_FROM_ABI` - are local to each translation unit in addition to being local to each final - linked image. This macro is defined to either 0 or 1. When it is defined to - 1, translation units compiled with different versions of libc++ can be linked - together, since all non ABI-facing functions are local to each translation unit. - This allows static archives built with different versions of libc++ to be linked - together. This also means that functions marked with `_LIBCPP_HIDE_FROM_ABI` - are not guaranteed to have the same address across translation unit boundaries. - - When the macro is defined to 0, there is no guarantee that translation units - compiled with different versions of libc++ can interoperate. However, this - leads to code size improvements, since non ABI-facing functions can be - deduplicated across translation unit boundaries. - - This macro can be defined by users to control the behavior they want from - libc++. The default value of this macro (0 or 1) is controlled by whether - `_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT` is defined, which is intended to - be used by vendors only (see below). - -**_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT** - This macro controls the default value for `_LIBCPP_HIDE_FROM_ABI_PER_TU`. - When the macro is defined, per TU ABI insulation is enabled by default, and - `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 1 unless overridden by users. - Otherwise, per TU ABI insulation is disabled by default, and - `_LIBCPP_HIDE_FROM_ABI_PER_TU` is defined to 0 unless overridden by users. - - This macro is intended for vendors to control whether they want to ship - libc++ with per TU ABI insulation enabled by default. Users can always - control the behavior they want by defining `_LIBCPP_HIDE_FROM_ABI_PER_TU` - appropriately. - - By default, this macro is not defined, which means that per TU ABI insulation - is not provided unless explicitly overridden by users. - **_LIBCPP_TYPE_VIS** Mark a type's typeinfo, vtable and members as having default visibility. This attribute cannot be used on class templates. @@ -130,7 +95,7 @@ Visibility Macros **_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS** Mark the member functions, typeinfo, and vtable of the type named in - a `_LIBCPP_EXTERN_TEMPLATE` declaration as being exported by the libc++ library. + an extern template declaration as being exported by the libc++ library. This attribute must be specified on all extern class template declarations. This macro is used to override the `_LIBCPP_TEMPLATE_VIS` attribute @@ -194,22 +159,6 @@ Visibility Macros versioning namespace. This allows throwing and catching some exception types between libc++ and libstdc++. -**_LIBCPP_INTERNAL_LINKAGE** - Mark the affected entity as having internal linkage (i.e. the `static` - keyword in C). This is only a best effort: when the `internal_linkage` - attribute is not available, we fall back to forcing the function to be - inlined, which approximates internal linkage since an externally visible - symbol is never generated for that function. This is an internal macro - used as an implementation detail by other visibility macros. Never mark - a function or a class with this macro directly. - -**_LIBCPP_ALWAYS_INLINE** - Forces inlining of the function it is applied to. For visibility purposes, - this macro is used to make sure that an externally visible symbol is never - generated in an object file when the `internal_linkage` attribute is not - available. This is an internal macro used by other visibility macros, and - it should not be used directly. - Links ===== diff --git a/gnu/llvm/libcxx/docs/FeatureTestMacroTable.rst b/gnu/llvm/libcxx/docs/FeatureTestMacroTable.rst index c2690e72eea..556994a67d1 100644 --- a/gnu/llvm/libcxx/docs/FeatureTestMacroTable.rst +++ b/gnu/llvm/libcxx/docs/FeatureTestMacroTable.rst @@ -18,8 +18,8 @@ Status ====== .. table:: Current Status - :name: feature-status-table - :widths: auto + :name: feature-status-table + :widths: auto ================================================= ================= Macro Name Value @@ -84,7 +84,7 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_bool_constant`` ``201505L`` ------------------------------------------------- ----------------- - ``__cpp_lib_boyer_moore_searcher`` *unimplemented* + ``__cpp_lib_boyer_moore_searcher`` ``201603L`` ------------------------------------------------- ----------------- ``__cpp_lib_byte`` ``201603L`` ------------------------------------------------- ----------------- @@ -100,7 +100,7 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_gcd_lcm`` ``201606L`` ------------------------------------------------- ----------------- - ``__cpp_lib_hardware_interference_size`` *unimplemented* + ``__cpp_lib_hardware_interference_size`` ``201703L`` ------------------------------------------------- ----------------- ``__cpp_lib_has_unique_object_representations`` ``201606L`` ------------------------------------------------- ----------------- @@ -126,7 +126,7 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_math_special_functions`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_memory_resource`` *unimplemented* + ``__cpp_lib_memory_resource`` ``201603L`` ------------------------------------------------- ----------------- ``__cpp_lib_node_extract`` ``201606L`` ------------------------------------------------- ----------------- @@ -170,7 +170,7 @@ Status ------------------------------------------------------------------- ``__cpp_lib_array_constexpr`` ``201811L`` ------------------------------------------------- ----------------- - ``__cpp_lib_assume_aligned`` *unimplemented* + ``__cpp_lib_assume_aligned`` ``201811L`` ------------------------------------------------- ----------------- ``__cpp_lib_atomic_flag_test`` ``201907L`` ------------------------------------------------- ----------------- @@ -190,19 +190,19 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_bind_front`` ``201907L`` ------------------------------------------------- ----------------- - ``__cpp_lib_bit_cast`` *unimplemented* + ``__cpp_lib_bit_cast`` ``201806L`` ------------------------------------------------- ----------------- ``__cpp_lib_bitops`` *unimplemented* ------------------------------------------------- ----------------- ``__cpp_lib_bounded_array_traits`` ``201902L`` ------------------------------------------------- ----------------- - ``__cpp_lib_char8_t`` ``201811L`` + ``__cpp_lib_char8_t`` ``201907L`` ------------------------------------------------- ----------------- ``__cpp_lib_concepts`` ``202002L`` ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_algorithms`` ``201806L`` ------------------------------------------------- ----------------- - ``__cpp_lib_constexpr_complex`` *unimplemented* + ``__cpp_lib_constexpr_complex`` ``201711L`` ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_dynamic_alloc`` ``201907L`` ------------------------------------------------- ----------------- @@ -214,7 +214,7 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_numeric`` ``201911L`` ------------------------------------------------- ----------------- - ``__cpp_lib_constexpr_string`` ``201811L`` + ``__cpp_lib_constexpr_string`` ``201907L`` ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_string_view`` ``201811L`` ------------------------------------------------- ----------------- @@ -222,9 +222,9 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_utility`` ``201811L`` ------------------------------------------------- ----------------- - ``__cpp_lib_constexpr_vector`` *unimplemented* + ``__cpp_lib_constexpr_vector`` ``201907L`` ------------------------------------------------- ----------------- - ``__cpp_lib_coroutine`` *unimplemented* + ``__cpp_lib_coroutine`` ``201902L`` ------------------------------------------------- ----------------- ``__cpp_lib_destroying_delete`` ``201806L`` ------------------------------------------------- ----------------- @@ -260,19 +260,21 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_math_constants`` ``201907L`` ------------------------------------------------- ----------------- - ``__cpp_lib_polymorphic_allocator`` *unimplemented* + ``__cpp_lib_polymorphic_allocator`` ``201902L`` ------------------------------------------------- ----------------- - ``__cpp_lib_ranges`` *unimplemented* + ``__cpp_lib_ranges`` ``202106L`` ------------------------------------------------- ----------------- ``__cpp_lib_remove_cvref`` ``201711L`` ------------------------------------------------- ----------------- ``__cpp_lib_semaphore`` ``201907L`` ------------------------------------------------- ----------------- + ``__cpp_lib_shared_ptr_arrays`` ``201707L`` + ------------------------------------------------- ----------------- ``__cpp_lib_shift`` ``201806L`` ------------------------------------------------- ----------------- ``__cpp_lib_smart_ptr_for_overwrite`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_source_location`` *unimplemented* + ``__cpp_lib_source_location`` ``201907L`` ------------------------------------------------- ----------------- ``__cpp_lib_span`` ``202002L`` ------------------------------------------------- ----------------- @@ -290,18 +292,78 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_to_array`` ``201907L`` ------------------------------------------------- ----------------- + ``__cpp_lib_type_identity`` ``201806L`` + ------------------------------------------------- ----------------- ``__cpp_lib_unwrap_ref`` ``201811L`` ------------------------------------------------- ----------------- **C++ 2b** ------------------------------------------------------------------- + ``__cpp_lib_adaptor_iterator_pair_constructor`` ``202106L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_allocate_at_least`` ``202106L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_associative_heterogeneous_erasure`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_bind_back`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_byteswap`` ``202110L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_bitset`` ``202207L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_charconv`` ``202207L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_cmath`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_memory`` ``202202L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_typeinfo`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_expected`` ``202202L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_forward_like`` ``202207L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_invoke_r`` *unimplemented* + ------------------------------------------------- ----------------- ``__cpp_lib_is_scoped_enum`` ``202011L`` ------------------------------------------------- ----------------- + ``__cpp_lib_move_only_function`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_optional`` ``202110L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_out_ptr`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_as_rvalue`` ``202207L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_chunk`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_chunk_by`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_iota`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_join_with`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_slide`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_starts_ends_with`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_to_container`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_ranges_zip`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_reference_from_temporary`` *unimplemented* + ------------------------------------------------- ----------------- + ``__cpp_lib_spanstream`` *unimplemented* + ------------------------------------------------- ----------------- ``__cpp_lib_stacktrace`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_stdatomic_h`` *unimplemented* + ``__cpp_lib_stdatomic_h`` ``202011L`` ------------------------------------------------- ----------------- ``__cpp_lib_string_contains`` ``202011L`` ------------------------------------------------- ----------------- + ``__cpp_lib_string_resize_and_overwrite`` ``202110L`` + ------------------------------------------------- ----------------- ``__cpp_lib_to_underlying`` ``202102L`` + ------------------------------------------------- ----------------- + ``__cpp_lib_unreachable`` ``202202L`` ================================================= ================= diff --git a/gnu/llvm/libcxx/docs/Helpers/Styles.rst b/gnu/llvm/libcxx/docs/Helpers/Styles.rst index 9bba3bf69db..31352efde60 100644 --- a/gnu/llvm/libcxx/docs/Helpers/Styles.rst +++ b/gnu/llvm/libcxx/docs/Helpers/Styles.rst @@ -1,31 +1,57 @@ -.. raw:: html - - - -.. role:: nothingtodo -.. role:: inprogress -.. role:: partial -.. role:: complete - - -.. |Nothing To Do| replace:: :nothingtodo:`Nothing To Do` -.. |In Progress| replace:: :inprogress:`In Progress` -.. |Partial| replace:: :partial:`Partial` -.. |Complete| replace:: :complete:`Complete` - -.. |sect| unicode:: U+00A7 -.. |hellip| unicode:: U+2026 +.. raw:: html + + + +.. role:: notstarted +.. role:: nothingtodo +.. role:: inprogress +.. role:: inreview +.. role:: partial +.. role:: complete + +.. |Not Started| replace:: :notstarted:`Not Started` +.. |Nothing To Do| replace:: :nothingtodo:`Nothing To Do` +.. |In Progress| replace:: :inprogress:`In Progress` +.. |Review| replace:: :inreview:`Review` +.. |Partial| replace:: :partial:`Partial` +.. |Complete| replace:: :complete:`Complete` + +.. role:: chrono +.. role:: format +.. role:: ranges +.. role:: spaceship +.. role:: fc +.. role:: concurrency + +.. |chrono| replace:: :chrono:`chrono` +.. |format| replace:: :format:`format` +.. |ranges| replace:: :ranges:`ranges` +.. |spaceship| replace:: :spaceship:`spaceship` +.. |flat_containers| replace:: :fc:`flat containers` +.. |concurrency TS| replace:: :concurrency:`concurrency TS` + +.. |sect| unicode:: U+00A7 +.. |hellip| unicode:: U+2026 diff --git a/gnu/llvm/libcxx/docs/ReleaseNotes.rst b/gnu/llvm/libcxx/docs/ReleaseNotes.rst index 85b7016485f..d78c4702060 100644 --- a/gnu/llvm/libcxx/docs/ReleaseNotes.rst +++ b/gnu/llvm/libcxx/docs/ReleaseNotes.rst @@ -1,5 +1,5 @@ ========================================= -Libc++ 13.0.0 (In-Progress) Release Notes +Libc++ 16.0.0 (In-Progress) Release Notes ========================================= .. contents:: @@ -10,7 +10,7 @@ Written by the `Libc++ Team `_ .. warning:: - These are in-progress notes for the upcoming libc++ 13 release. + These are in-progress notes for the upcoming libc++ 16 release. Release notes for previous releases can be found on `the Download Page `_. @@ -18,7 +18,7 @@ Introduction ============ This document contains the release notes for the libc++ C++ Standard Library, -part of the LLVM Compiler Infrastructure, release 13.0.0. Here we describe the +part of the LLVM Compiler Infrastructure, release 16.0.0. Here we describe the status of libc++ in some detail, including major improvements from the previous release and new feature work. For the general LLVM release notes, see `the LLVM documentation `_. All LLVM releases may @@ -32,72 +32,161 @@ main Libc++ web page, this document applies to the *next* release, not the current one. To see the release notes for a specific release, please see the `releases page `_. -What's New in Libc++ 13.0.0? +What's New in Libc++ 16.0.0? ============================ -- Support for older compilers has been removed. Several additional platforms - are now officially supported. :ref:`platform_and_compiler_support` contains - the complete overview of platforms and compilers supported by libc++. -- The large headers ````, ````, and ```` have - been split in more granular headers. This reduces the size of included code - when using libc++. This may lead to missing includes after upgrading to - libc++13. - -New Features ------------- - -- ``std::filesystem`` is now feature complete for the Windows platform using - MinGW. MSVC isn't supported since it lacks 128-bit integer support. -- The implementation of the C++20 concepts library has been completed. -- Several C++20 ``constexpr`` papers have been completed: - - - `P0879R0 `_ ``constexpr`` for ``std::swap()`` - and swap related functions - - `P1032R1 `_ Misc ``constexpr`` bits - - `P0883 `_ Fixing Atomic Initialization - -- More C++20 features have been implemented. :doc:`Status/Cxx20` has the full - overview of libc++'s C++20 implementation status. -- More C++2b features have been implemented. :doc:`Status/Cxx2b` has the - full overview of libc++'s C++2b implementation status. -- The CMake option ``LIBCXX_ENABLE_INCOMPLETE_FEATURES`` has been added. This - option allows libc++ vendors to disable headers that aren't production - quality yet. Currently, turning the option off disables the headers - ```` and ````. -- The documentation conversion from html to restructured text has been - completed. +The main focus of the libc++ team has been to implement new C++20 and C++23 +features. + +The C++20 format library has improved but it not yet considered stable. The +main improvements are additional formatters for the chrono calendar types. Work +on formatting ranges has started. + +The C++20 ranges library has been completed and is no longer experimental (with +the exception of `ranges::join_view` which is still marked as experimental +because it is about to undergo an ABI-breaking change in the Standard due to +`D2770 `_). Work on C++23 ranges +has started. + +The C++20 spaceship operator has been added to more types, the work is still +ongoing. + +`D139235 `_ made ``copy`` and ``move`` +algorithms and their variations (``copy_backward``, etc.) apply optimizations +for trivial types more often. This has the potential to expose bugs in code +using these algorithms that currently relies on undefined behavior (this +includes indirect usage -- for example, these algorithms are used in the +implementation of some standard containers). This change also made the +algorithms check the given iterator types for conformance more strictly. + +Implemented Papers +------------------ +- P2499R0 - ``string_view`` range constructor should be ``explicit`` +- P2417R2 - A more constexpr bitset +- P2445R1 - ``std::forward_like`` +- P2273R3 - Making ``std::unique_ptr`` constexpr +- P0591R4 - Utility functions to implement uses-allocator construction +- P2291R3 - Add Constexpr Modifiers to Functions ``to_chars`` and + ``from_chars`` for Integral Types in ```` Header +- P0220R1 - Adopt Library Fundamentals V1 TS Components for C++17 +- P0482R6 - char8_t: A type for UTF-8 characters and strings +- P2438R2 - ``std::string::substr() &&`` +- P0600R1 - ``nodiscard`` in the library +- P0339R6 - ``polymorphic_allocator<>`` as a vocabulary type +- P1169R4 - ``static operator()`` +- P0415R1 - ``constexpr`` for ``std::complex`` +- P1208R6 - ``std::source_location`` +- P0323R12 - ``std::expected`` +- P1035R7 - Input Range Adaptors +- P2325R3 - Views should not be required to be default constructible +- P2446R2 - ``views::as_rvalue`` +- P1020R1 - Smart pointer creation with default initialization +- P2210R2 - Superior String Splitting +- P2286R8 - Formatting Ranges + +Improvements and New Features +----------------------------- +- Declarations of ``std::c8rtomb()`` and ``std::mbrtoc8()`` from P0482R6 are + now provided when implementations in the global namespace are provided by + the C library. +- Implemented ```` header from C++17 +- The ``ranges`` versions of ``copy``, ``move``, ``copy_backward`` and ``move_backward`` are now also optimized for + ``std::deque<>::iterator``, which can lead to up to 20x performance improvements on certain algorithms. +- The ``std`` and ``ranges`` versions of ``copy``, ``move``, ``copy_backward`` and ``move_backward`` are now also + optimized for ``join_view::iterator``, which can lead to up to 20x performance improvements on certain combinations of + iterators and algorithms. + +Deprecations and Removals +------------------------- +- ``unary_function`` and ``binary_function`` are no longer provided in C++17 and newer Standard modes. + They can be re-enabled with ``_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION``. + +- Several incidental transitive includes have been removed from libc++. Those + includes are removed based on the language version used. Incidental transitive + inclusions of the following headers have been removed: + + - C++11, C++14, C++17, and C++20: ``chrono`` + - C++2b: ``algorithm``, ``array``, ``atomic``, ``bit``, ``chrono``, + ``climits``, ``cmath``, ``compare``, ``concepts``, ``cstdarg``, ``cstddef``, + ``cstdint``, ``cstdlib``, ``cstring``, ``ctime``, ``exception``, + ``functional``, ``initializer_list``, ``iosfwd``, ``iterator``, ``limits``, + ``memory``, ``new``, ``numeric``, ``optional``, ``ratio``, ``stdexcept``, + ``string``, ``tuple``, ``type_traits``, ``typeinfo``, ``unordered_map``, + ``utility``, ``variant``, ``vector``. + + Users can also remove all incidental transitive includes by defining + ``_LIBCPP_REMOVE_TRANSITIVE_INCLUDES`` regardless of the language version + in use. Note that in the future, libc++ reserves the right to remove + incidental transitive includes more aggressively, in particular regardless + of the language version in use. + +- The legacy testing system for libc++, libc++abi, and libunwind has been removed. + All known clients have been migrated to the new configuration system, but please + reach out to the libc++ developers if you find something missing in the new + configuration system. + +- The functions ``to_chars`` and ``from_chars`` for integral types are + available starting with C++17. Libc++ offered these functions in C++11 and + C++14 as an undocumented extension. This extension makes it hard to implement + the C++23 paper that makes these functions ``constexpr``, therefore the + extension has been removed. + +- The ``_LIBCPP_ENABLE_CXX03_FUNCTION`` macro that allowed re-enabling the now-deprecated C++03 implementation of + ``std::function`` has been removed. Users who need to use ``std::function`` should switch to C++11 and above. + +- The contents of ```` are now deprecated since libc++ ships ```` now. + Please migrate to ```` instead. Per libc++'s TS deprecation policy, + ```` will be removed in LLVM 18. + +- The ``_LIBCPP_DEBUG`` macro is not honored anymore, and it is an error to try to use it. Please migrate to + ``_LIBCPP_ENABLE_DEBUG_MODE`` instead. + +Upcoming Deprecations and Removals +---------------------------------- +- The base template for ``std::char_traits`` has been marked as deprecated and will be removed in LLVM 18. If + you are using ``std::char_traits`` with types other than ``char``, ``wchar_t``, ``char8_t``, ``char16_t``, + ``char32_t`` or a custom character type for which you specialized ``std::char_traits``, your code will stop + working when we remove the base template. The Standard does not mandate that a base template is provided, + and such a base template is bound to be incorrect for some types, which could currently cause unexpected + behavior while going undetected. + +- The ``_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED`` macro will not be honored anymore in LLVM 18. + Please see the updated documentation about the safe libc++ mode and in particular the ``_LIBCPP_VERBOSE_ABORT`` + macro for details. API Changes ----------- - -- There has been several changes in the tuple constructors provided by libc++. - Those changes were made as part of an effort to regularize libc++'s tuple - implementation, which contained several subtle bugs due to these extensions. - If you notice a build breakage when initializing a tuple, make sure you - properly initialize all the tuple elements - this is probably the culprit. - - In particular, the extension allowing tuples to be constructed from fewer - elements than the number of elements in the tuple (in which case the remaining - elements would be default-constructed) has been removed. See https://godbolt.org/z/sqozjd. - - Also, the extension allowing a tuple to be constructed from an array has been - removed. See https://godbolt.org/z/5esqbW. - -- The ``std::pointer_safety`` utility and related functions are not available - in C++03 anymore. Furthermore, in other standard modes, it has changed from - a struct to a scoped enumeration, which is an ABI break. Finally, the - ``std::get_pointer_safety`` function was previously in the dylib, but it - is now defined as inline in the headers. - - While this is technically both an API and an ABI break, we do not expect - ``std::pointer_safety`` to have been used at all in real code, since we - never implemented the underlying support for garbage collection. - -- The `LIBCXXABI_ENABLE_PIC` CMake option was removed. If you are building your - own libc++abi from source and were using `LIBCXXABI_ENABLE_PIC`, please use - `CMAKE_POSITION_INDEPENDENT_CODE=ON` instead. - -- When the header is included, it will no longer include transitively. - -- The ``std::result_of`` and ``std::is_literal_type`` type traits have been removed in - C++20 mode. +- The comparison operators on ``thread::id`` are now defined as free-standing + functions instead of as hidden friends, in conformance with the C++ standard. + Also see `issue 56187 `_. + +- ``_LIBCPP_ENABLE_NODISCARD`` and ``_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17`` are no longer respected. + Any standards-required ``[[nodiscard]]`` applications in C++20 are now always enabled. Any extended applications + are now enabled by default and can be disabled by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``. + +- ``_LIBCPP_VERSION`` was previously defined to e.g. ``15001`` to represent LLVM 15.0.01, but this value had been + left undocumented. Starting with LLVM 16, ``_LIBCPP_VERSION`` will contain the version of LLVM represented as + ``XXYYZZ``. In other words, ``_LIBCPP_VERSION`` is gaining a digit. This should not be an issue for existing + code, since using e.g. ``_LIBCPP_VERSION > 15000`` will still give the right answer now that ``_LIBCPP_VERSION`` + is defined as e.g. ``160000`` (with one more digit). + +ABI Affecting Changes +--------------------- +- In freestanding mode, ``atomic`` does not contain a lock byte anymore if the platform + can implement lockfree atomics for that size. More specifically, in LLVM <= 11.0.1, an ``atomic`` + would not contain a lock byte. This was broken in LLVM >= 12.0.0, where it started including a lock byte despite + the platform supporting lockfree atomics for that size. Starting in LLVM 15.0.1, the ABI for these types has been + restored to what it used to be (no lock byte), which is the most efficient implementation. + + This ABI break only affects users that compile with ``-ffreestanding``, and only for ``atomic`` where ``T`` + is a non-builtin type that could be lockfree on the platform. See https://llvm.org/D133377 for more details. + +- When building libc++ against newlib/picolibc, the type of ``regex_type_traits::char_class_type`` was changed to + ``uint16_t`` since all values of ``ctype_base::mask`` are taken. This is technically an ABI break, but including + `` `` has triggered a ``static_assert`` failure since libc++ 14, so it is unlikely that this causes + problems for existing users. + +Build System Changes +-------------------- +- Support for ``libcxx``, ``libcxxabi`` and ``libunwind`` in ``LLVM_ENABLE_PROJECTS`` has officially + been removed. Instead, please build according to :ref:`these instructions `. diff --git a/gnu/llvm/libcxx/docs/Status/Cxx14.rst b/gnu/llvm/libcxx/docs/Status/Cxx14.rst index fc3aeeec36a..0557bdc285d 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx14.rst +++ b/gnu/llvm/libcxx/docs/Status/Cxx14.rst @@ -1,52 +1,50 @@ -.. _cxx14-status: - -================================ -libc++ C++14 Status -================================ - -.. include:: ../Helpers/Styles.rst - -.. contents:: - :local: - - -Overview -================================ - -In April 2013, the C++ standard committee approved the draft for the next version of the C++ standard, initially known as "C++1y". - -The draft standard includes papers and issues that were voted on at the previous three meetings (Kona, Portland, and Bristol). - -In August 2014, this draft was approved by ISO as C++14. - -This page shows the status of libc++; the status of clang's support of the language features is `here `__. - -The groups that have contributed papers: - -- CWG - Core Language Working group -- LWG - Library working group -- SG1 - Study group #1 (Concurrency working group) - - -.. _paper-status-cxx14: - -Paper Status -==================================== - -.. csv-table:: - :file: Cxx14Papers.csv - :header-rows: 1 - :widths: auto - - -.. _issues-status-cxx14: - -Library Working Group Issues Status -==================================== - -.. csv-table:: - :file: Cxx14Issues.csv - :header-rows: 1 - :widths: auto - -Last Updated: 25-Mar-2014 +.. _cxx14-status: + +================================ +libc++ C++14 Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +In April 2013, the C++ standard committee approved the draft for the next version of the C++ standard, initially known as "C++1y". + +The draft standard includes papers and issues that were voted on at the previous three meetings (Kona, Portland, and Bristol). + +In August 2014, this draft was approved by ISO as C++14. + +This page shows the status of libc++; the status of clang's support of the language features is `here `__. + +The groups that have contributed papers: + +- CWG - Core Language Working group +- LWG - Library working group +- SG1 - Study group #1 (Concurrency working group) + + +.. _paper-status-cxx14: + +Paper Status +==================================== + +.. csv-table:: + :file: Cxx14Papers.csv + :header-rows: 1 + :widths: auto + + +.. _issues-status-cxx14: + +Library Working Group Issues Status +==================================== + +.. csv-table:: + :file: Cxx14Issues.csv + :header-rows: 1 + :widths: auto diff --git a/gnu/llvm/libcxx/docs/Status/Cxx17.rst b/gnu/llvm/libcxx/docs/Status/Cxx17.rst index 9076b9cf4b3..96c010cf47e 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx17.rst +++ b/gnu/llvm/libcxx/docs/Status/Cxx17.rst @@ -1,57 +1,55 @@ -.. _cxx17-status: - -================================ -libc++ C++17 Status -================================ - -.. include:: ../Helpers/Styles.rst - -.. contents:: - :local: - - -Overview -================================ - -In November 2014, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++1z". -In February 2017, the C++ standard committee approved this draft, and sent it to ISO for approval as C++17. - -This page shows the status of libc++; the status of clang's support of the language features is `here `__. - -.. attention:: Features in unreleased drafts of the standard are subject to change. - -The groups that have contributed papers: - -- CWG - Core Language Working group -- LWG - Library working group -- SG1 - Study group #1 (Concurrency working group) - -.. note:: "Nothing to do" means that no library changes were needed to implement this change. - -.. _paper-status-cxx17: - -Paper Status -==================================== - -.. csv-table:: - :file: Cxx17Papers.csv - :header-rows: 1 - :widths: auto - -.. note:: - - .. [#note-P0433] P0433: So far, only the ````, sequence containers, container adaptors and ```` portions of P0433 have been implemented. - .. [#note-P0607] P0607: The parts of P0607 that are not done are the ```` bits. - - -.. _issues-status-cxx17: - -Library Working Group Issues Status -==================================== - -.. csv-table:: - :file: Cxx17Issues.csv - :header-rows: 1 - :widths: auto - -Last Updated: 17-Nov-2020 +.. _cxx17-status: + +================================ +libc++ C++17 Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +In November 2014, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++1z". +In February 2017, the C++ standard committee approved this draft, and sent it to ISO for approval as C++17. + +This page shows the status of libc++; the status of clang's support of the language features is `here `__. + +.. attention:: Features in unreleased drafts of the standard are subject to change. + +The groups that have contributed papers: + +- CWG - Core Language Working group +- LWG - Library working group +- SG1 - Study group #1 (Concurrency working group) + +.. note:: "Nothing to do" means that no library changes were needed to implement this change. + +.. _paper-status-cxx17: + +Paper Status +==================================== + +.. csv-table:: + :file: Cxx17Papers.csv + :header-rows: 1 + :widths: auto + +.. note:: + + .. [#note-P0067] P0067: ``std::(to|from)_chars`` for integrals has been available since version 7.0. ``std::to_chars`` for ``float`` and ``double`` since version 14.0 ``std::to_chars`` for ``long double`` uses the implementation for ``double``. + .. [#note-P0607] P0607: The parts of P0607 that are not done are the ```` bits. + .. [#note-P0154] P0154: This is currently not implemented for clang because clang does not implement the required macros. + +.. _issues-status-cxx17: + +Library Working Group Issues Status +==================================== + +.. csv-table:: + :file: Cxx17Issues.csv + :header-rows: 1 + :widths: auto diff --git a/gnu/llvm/libcxx/docs/Status/Cxx17Issues.csv b/gnu/llvm/libcxx/docs/Status/Cxx17Issues.csv index 090e12ffd9a..8bcdbd7fa04 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx17Issues.csv +++ b/gnu/llvm/libcxx/docs/Status/Cxx17Issues.csv @@ -114,7 +114,7 @@ "`2557 `__","Logical operator traits are broken in the zero-argument case","Jacksonville","|Complete|","" "`2558 `__","[fund.ts.v2] Logical operator traits are broken in the zero-argument case","Jacksonville","|Complete|","" "`2559 `__","Error in LWG 2234's resolution","Jacksonville","|Complete|","" -"`2560 `__","``is_constructible``\ underspecified when applied to a function type","Jacksonville","Broken in 3.6; See r261653.","" +"`2560 `__","``is_constructible``\ underspecified when applied to a function type","Jacksonville","|Complete|","" "`2565 `__","``std::function``\ 's move constructor should guarantee nothrow for ``reference_wrapper``\ s and function pointers","Jacksonville","|Complete|","" "`2566 `__","Requirements on the first template parameter of container adaptors","Jacksonville","|Complete|","" "`2571 `__","|sect|\ [map.modifiers]/2 imposes nonsensical requirement on ``insert(InputIterator, InputIterator)``\ ","Jacksonville","|Complete|","" @@ -176,7 +176,7 @@ "`2720 `__","permissions function incorrectly specified for symlinks","Oulu","|Complete|","" "`2721 `__","remove_all has incorrect post conditions","Oulu","|Complete|","" "`2723 `__","Do directory_iterator and recursive_directory_iterator become the end iterator upon error?","Oulu","|Complete|","" -"`2724 `__","The protected virtual member functions of memory_resource should be private","Oulu","","" +"`2724 `__","The protected virtual member functions of memory_resource should be private","Oulu","|Complete|","16.0" "`2725 `__","filesystem::exists(const path&, error_code&) error reporting","Oulu","|Complete|","" "`2726 `__","``[recursive_]directory_iterator::increment(error_code&)`` is underspecified","Oulu","|Complete|","" "`2727 `__","Parallel algorithms with constexpr specifier","Oulu","","" @@ -199,7 +199,7 @@ "`2521 `__","[fund.ts.v2] weak_ptr's converting move constructor should be modified as well for array support","Issaquah","","" "`2525 `__","[fund.ts.v2] get_memory_resource should be const and noexcept","Issaquah","","" "`2527 `__","[fund.ts.v2] ALLOCATOR_OF for function::operator= has incorrect default","Issaquah","","" -"`2531 `__","future::get should explicitly state that the shared state is released","Issaquah","","" +"`2531 `__","future::get should explicitly state that the shared state is released","Issaquah","|Nothing To Do|","" "`2534 `__","Constrain rvalue stream operators","Issaquah","|Complete|","" "`2536 `__","What should do?","Issaquah","|Complete|","" "`2540 `__","unordered_multimap::insert hint iterator","Issaquah","|Complete|","" @@ -208,13 +208,13 @@ "`2556 `__","Wide contract for future::share()","Issaquah","|Complete|","" "`2562 `__","Consistent total ordering of pointers by comparison functors","Issaquah","","" "`2567 `__","Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","|Complete|","" -"`2568 `__","[fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","","" -"`2569 `__","conjunction and disjunction requirements are too strict","Issaquah","|Complete|","" +"`2568 `__","[fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","|Complete|","15.0" +"`2569 `__","conjunction and disjunction requirements are too strict","Issaquah","|Complete|","15.0" "`2570 `__","[fund.ts.v2] conjunction and disjunction requirements are too strict","Issaquah","","" "`2578 `__","Iterator requirements should reference iterator traits","Issaquah","|Complete|","" "`2584 `__"," ECMAScript IdentityEscape is ambiguous","Issaquah","","" "`2587 `__","""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","Resolved by 2567","" -"`2588 `__","[fund.ts.v2] ""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","","" +"`2588 `__","[fund.ts.v2] ""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","Resolved by 2568","" "`2589 `__","match_results can't satisfy the requirements of a container","Issaquah","|Complete|","" "`2591 `__","std::function's member template target() should not lead to undefined behaviour","Issaquah","|Complete|","" "`2598 `__","addressof works on temporaries","Issaquah","|Complete|","" @@ -247,7 +247,7 @@ "`2748 `__","swappable traits for optionals","Issaquah","|Complete|","" "`2749 `__","swappable traits for variants","Issaquah","|Complete|","" "`2750 `__","[fund.ts.v2] LWG 2451 conversion constructor constraint","Issaquah","|Nothing To Do|","" -"`2752 `__","""Throws:"" clauses of async and packaged_task are unimplementable","Issaquah","","" +"`2752 `__","""Throws:"" clauses of async and packaged_task are unimplementable","Issaquah","|Nothing To Do|","" "`2755 `__","[string.view.io] uses non-existent basic_string_view::to_string function","Issaquah","|Complete|","" "`2756 `__","C++ WP optional should 'forward' T's implicit conversions","Issaquah","|Complete|","" "`2758 `__","std::string{}.assign(""ABCDE"", 0, 1) is ambiguous","Issaquah","|Complete|","" @@ -301,7 +301,7 @@ "`2873 `__","Add noexcept to several shared_ptr related functions","Kona","|Complete|","" "`2874 `__","Constructor ``shared_ptr::shared_ptr(Y*)``\ should be constrained","Kona","|Complete|","13.0" "`2875 `__","shared_ptr::shared_ptr(Y\*, D, [|hellip|\ ]) constructors should be constrained","Kona","|Complete|","" -"`2876 `__","``shared_ptr::shared_ptr(const weak_ptr&)``\ constructor should be constrained","Kona","","" +"`2876 `__","``shared_ptr::shared_ptr(const weak_ptr&)``\ constructor should be constrained","Kona","|Complete|","14.0" "`2878 `__","Missing DefaultConstructible requirement for istream_iterator default constructor","Kona","|Complete|","" "`2890 `__","The definition of 'object state' applies only to class types","Kona","|Complete|","" "`2900 `__","The copy and move constructors of optional are not constexpr","Kona","|Complete|","" diff --git a/gnu/llvm/libcxx/docs/Status/Cxx17Papers.csv b/gnu/llvm/libcxx/docs/Status/Cxx17Papers.csv index a015529feed..b68eb26faa8 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx17Papers.csv +++ b/gnu/llvm/libcxx/docs/Status/Cxx17Papers.csv @@ -2,7 +2,7 @@ "`N3911 `__","LWG","TransformationTrait Alias ``void_t``\ .","Urbana","|Complete|","3.6" "`N4089 `__","LWG","Safe conversions in ``unique_ptr``\ .","Urbana","|In Progress|","3.9" "`N4169 `__","LWG","A proposal to add invoke function template","Urbana","|Complete|","3.7" -"`N4190 `__","LWG","Removing auto_ptr, random_shuffle(), And Old Stuff.","Urbana","|In Progress|","" +"`N4190 `__","LWG","Removing auto_ptr, random_shuffle(), And Old Stuff.","Urbana","|Complete|","15.0" "`N4258 `__","LWG","Cleaning-up noexcept in the Library.","Urbana","|In Progress|","3.7" "`N4259 `__","CWG","Wording for std::uncaught_exceptions","Urbana","|Complete|","3.7" "`N4277 `__","LWG","TriviallyCopyable ``reference_wrapper``\ .","Urbana","|Complete|","3.2" @@ -27,7 +27,7 @@ "","","","","","" "`P0024R2 `__","LWG","The Parallelism TS Should be Standardized","Jacksonville","","" "`P0226R1 `__","LWG","Mathematical Special Functions for C++17","Jacksonville","","" -"`P0220R1 `__","LWG","Adopt Library Fundamentals V1 TS Components for C++17","Jacksonville","|In Progress|","" +"`P0220R1 `__","LWG","Adopt Library Fundamentals V1 TS Components for C++17","Jacksonville","|Complete|","16.0" "`P0218R1 `__","LWG","Adopt the File System TS for C++17","Jacksonville","|Complete|","7.0" "`P0033R1 `__","LWG","Re-enabling shared_from_this","Jacksonville","|Complete|","3.9" "`P0005R4 `__","LWG","Adopt not_fn from Library Fundamentals 2 for C++17","Jacksonville","|Complete|","3.9" @@ -35,7 +35,7 @@ "`P0185R1 `__","LWG","Adding [nothrow-]swappable traits","Jacksonville","|Complete|","3.9" "`P0253R1 `__","LWG","Fixing a design mistake in the searchers interface","Jacksonville","|Complete|","3.9" "`P0025R0 `__","LWG","An algorithm to ""clamp"" a value between a pair of boundary values","Jacksonville","|Complete|","3.9" -"`P0154R1 `__","LWG","constexpr std::hardware_{constructive,destructive}_interference_size","Jacksonville","","" +"`P0154R1 `__","LWG","constexpr std::hardware_{constructive,destructive}_interference_size","Jacksonville","|Partial| [#note-P0154]_","15.0" "`P0030R1 `__","LWG","Proposal to Introduce a 3-Argument Overload to std::hypot","Jacksonville","|Complete|","3.9" "`P0031R0 `__","LWG","A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access","Jacksonville","|Complete|","4.0" "`P0272R1 `__","LWG","Give ``std::string``\ a non-const ``.data()``\ member function","Jacksonville","|Complete|","3.9" @@ -50,7 +50,7 @@ "`p0088r3 `__","LWG","Variant: a type-safe union for C++17","Oulu","|Complete|","4.0" "`p0137r1 `__","CWG","Core Issue 1776: Replacement of class objects containing reference members","Oulu","|Complete|","6.0" "`p0163r0 `__","LWG","shared_ptr::weak_type","Oulu","|Complete|","3.9" -"`p0174r2 `__","LWG","Deprecating Vestigial Library Parts in C++17","Oulu","|Partial|","" +"`p0174r2 `__","LWG","Deprecating Vestigial Library Parts in C++17","Oulu","|Complete|","15.0" "`p0175r1 `__","LWG","Synopses for the C library","Oulu","","" "`p0180r2 `__","LWG","Reserve a New Library Namespace for Future Standardization","Oulu","|Nothing To Do|","n/a" "`p0181r1 `__","LWG","Ordered by Default","Oulu","*Removed in Kona*","n/a" @@ -71,7 +71,7 @@ "`P0394r4 `__","LWG","Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling","Oulu","","" "","","","","","" "`P0003R5 `__","LWG","Removing Deprecated Exception Specifications from C++17","Issaquah","|Complete|","5.0" -"`P0067R5 `__","LWG","Elementary string conversions, revision 5","Issaquah","|Partial|","" +"`P0067R5 `__","LWG","Elementary string conversions, revision 5","Issaquah","|Partial| [#note-P0067]_","" "`P0403R1 `__","LWG","Literal suffixes for ``basic_string_view``\ ","Issaquah","|Complete|","4.0" "`P0414R2 `__","LWG","Merging shared_ptr changes from Library Fundamentals to C++17","Issaquah","|Complete|","11.0" "`P0418R2 `__","LWG","Fail or succeed: there is no atomic lattice","Issaquah","","" @@ -94,19 +94,19 @@ "`P0298R3 `__","CWG","A byte type definition","Kona","|Complete|","5.0" "`P0317R1 `__","LWG","Directory Entry Caching for Filesystem","Kona","|Complete|","7.0" "`P0430R2 `__","LWG","File system library on non-POSIX-like operating systems","Kona","|Complete|","7.0" -"`P0433R2 `__","LWG","Toward a resolution of US7 and US14: Integrating template deduction for class templates into the standard library","Kona","|In Progress| [#note-P0433]_","7.0" +"`P0433R2 `__","LWG","Toward a resolution of US7 and US14: Integrating template deduction for class templates into the standard library","Kona","|Complete|","14.0" "`P0452R1 `__","LWG","Unifying Parallel Algorithms","Kona","","" "`P0467R2 `__","LWG","Iterator Concerns for Parallel Algorithms","Kona","","" "`P0492R2 `__","LWG","Proposed Resolution of C++17 National Body Comments for Filesystems","Kona","|Complete|","7.0" "`P0518R1 `__","LWG","Allowing copies as arguments to function objects given to parallel algorithms in response to CH11","Kona","","" "`P0523R1 `__","LWG","Wording for CH 10: Complexity of parallel algorithms","Kona","","" "`P0548R1 `__","LWG","common_type and duration","Kona","|Complete|","5.0" -"`P0558R1 `__","LWG","Resolving atomic named base class inconsistencies","Kona","","" +"`P0558R1 `__","LWG","Resolving atomic named base class inconsistencies","Kona","|Complete|","" "`P0574R1 `__","LWG","Algorithm Complexity Constraints and Parallel Overloads","Kona","","" "`P0599R1 `__","LWG","noexcept for hash functions","Kona","|Complete|","5.0" "`P0604R0 `__","LWG","Resolving GB 55, US 84, US 85, US 86","Kona","|Complete|","" "`P0607R0 `__","LWG","Inline Variables for the Standard Library","Kona","|In Progress| [#note-P0607]_","6.0" -"`P0618R0 `__","LWG","Deprecating ","Kona","","" +"`P0618R0 `__","LWG","Deprecating ","Kona","|Complete|","15.0" "`P0623R0 `__","LWG","Final C++17 Parallel Algorithms Fixes","Kona","","" "","","","","","" "`P0682R1 `__","LWG","Repairing elementary string conversions","Toronto","","" diff --git a/gnu/llvm/libcxx/docs/Status/Cxx20.rst b/gnu/llvm/libcxx/docs/Status/Cxx20.rst index 69e607cb7e5..11cd7c40bf5 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx20.rst +++ b/gnu/llvm/libcxx/docs/Status/Cxx20.rst @@ -1,59 +1,61 @@ -.. _cxx20-status: - -================================ -libc++ C++20 Status -================================ - -.. include:: ../Helpers/Styles.rst - -.. contents:: - :local: - - -Overview -================================ - -In July 2017, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++2a". -In September 2020, the C++ standard committee approved this draft, and sent it to ISO for approval as C++20. - -This page shows the status of libc++; the status of clang's support of the language features is `here `__. - -.. attention:: Features in unreleased drafts of the standard are subject to change. - -The groups that have contributed papers: - -- CWG - Core Language Working group -- LWG - Library working group -- SG1 - Study group #1 (Concurrency working group) - -.. note:: "Nothing to do" means that no library changes were needed to implement this change. - -.. _paper-status-cxx20: - -Paper Status -==================================== - -.. csv-table:: - :file: Cxx20Papers.csv - :header-rows: 1 - :widths: auto - -.. note:: - - .. [#note-P0600] P0600: The missing bits in P0600 are in |sect|\ [mem.res.class], |sect|\ [mem.poly.allocator.class], and |sect|\ [container.node.overview]. - .. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 `__. - .. [#note-P0619] P0619: Only sections D.8, D.9, D.10 and D.13 are implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone. - .. [#note-P0883] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet. - - -.. _issues-status-cxx20: - -Library Working Group Issues Status -==================================== - -.. csv-table:: - :file: Cxx20Issues.csv - :header-rows: 1 - :widths: auto - -Last Updated: 24-May-2021 +.. _cxx20-status: + +================================ +libc++ C++20 Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +In July 2017, the C++ standard committee created a draft for the next version of the C++ standard, initially known as "C++2a". +In September 2020, the C++ standard committee approved this draft, and sent it to ISO for approval as C++20. + +This page shows the status of libc++; the status of clang's support of the language features is `here `__. + +.. attention:: Features in unreleased drafts of the standard are subject to change. + +The groups that have contributed papers: + +- CWG - Core Language Working group +- LWG - Library working group +- SG1 - Study group #1 (Concurrency working group) + +.. note:: "Nothing to do" means that no library changes were needed to implement this change. + +.. _paper-status-cxx20: + +Paper Status +==================================== + +.. csv-table:: + :file: Cxx20Papers.csv + :header-rows: 1 + :widths: auto + +.. note:: + + .. [#note-P0591] P0591: The changes in [mem.poly.allocator.mem] are missing. + .. [#note-P0645] P0645: The paper is implemented but still marked as an incomplete feature + (the feature-test macro is not set and the libary is only available when built with ``-fexperimental-library``). + Not yet implemented LWG-issues will cause API and ABI breakage. + .. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 `__. + .. [#note-P0619] P0619: Only sections D.8, D.9, D.10 and D.13 are implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone. + .. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet. + .. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0. + .. [#note-P2231] P2231: Optional is complete. The changes to variant haven't been implemented yet. + +.. _issues-status-cxx20: + +Library Working Group Issues Status +==================================== + +.. csv-table:: + :file: Cxx20Issues.csv + :header-rows: 1 + :widths: auto diff --git a/gnu/llvm/libcxx/docs/Status/Cxx20Issues.csv b/gnu/llvm/libcxx/docs/Status/Cxx20Issues.csv index 2437cc24707..2d2318af228 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx20Issues.csv +++ b/gnu/llvm/libcxx/docs/Status/Cxx20Issues.csv @@ -1,4 +1,4 @@ -"Issue #","Issue Name","Meeting","Status","First released version" +"Issue #","Issue Name","Meeting","Status","First released version","Labels" "`2070 `__","``allocate_shared``\ should use ``allocator_traits::construct``\ ","Toronto","Resolved by `P0674R1 `__","" "`2444 `__","Inconsistent complexity for ``std::sort_heap``\ ","Toronto","","" "`2593 `__","Moved-from state of Allocators","Toronto","","" @@ -6,13 +6,13 @@ "`2783 `__","``stack::emplace()``\ and ``queue::emplace()``\ should return ``decltype(auto)``\ ","Toronto","|Complete|","" "`2932 `__","Constraints on parallel algorithm implementations are underspecified","Toronto","","" "`2937 `__","Is ``equivalent(""existing_thing"", ""not_existing_thing"")``\ an error","Toronto","|Complete|","" -"`2940 `__","``result_of``\ specification also needs a little cleanup","Toronto","","" +"`2940 `__","``result_of``\ specification also needs a little cleanup","Toronto","|Nothing To Do|","" "`2942 `__","LWG 2873's resolution missed ``weak_ptr::owner_before``\ ","Toronto","|Complete|","" "`2954 `__","Specialization of the convenience variable templates should be prohibited","Toronto","|Complete|","" -"`2961 `__","Bad postcondition for ``set_default_resource``\ ","Toronto","","" +"`2961 `__","Bad postcondition for ``set_default_resource``\ ","Toronto","|Complete|","16.0" "`2966 `__","Incomplete resolution of US 74","Toronto","|Nothing To Do|","" "`2974 `__","Diagnose out of bounds ``tuple_element/variant_alternative``\ ","Toronto","|Complete|","" -"","","","","" +"","","","","","" "`2779 `__","[networking.ts] Relax requirements on buffer sequence iterators","Albuquerque","","" "`2870 `__","Default value of parameter theta of polar should be dependent","Albuquerque","|Complete|","" "`2935 `__","What should create_directories do when p already exists but is not a directory?","Albuquerque","|Nothing To Do|","" @@ -23,23 +23,23 @@ "`2950 `__","std::byte operations are misspecified","Albuquerque","|Complete|","" "`2952 `__","iterator_traits should work for pointers to cv T","Albuquerque","|Complete|","" "`2953 `__","LWG 2853 should apply to deque::erase too","Albuquerque","|Complete|","" -"`2958 `__","Moves improperly defined as deleted","Albuquerque","*We already do this*","" +"`2958 `__","Moves improperly defined as deleted","Albuquerque","|Complete|","" "`2964 `__","Apparently redundant requirement for dynamic_pointer_cast","Albuquerque","","" "`2965 `__","Non-existing path::native_string() in filesystem_error::what() specification","Albuquerque","|Nothing To Do|","" "`2972 `__","What is ``is_trivially_destructible_v``\ ?","Albuquerque","|Complete|","" "`2976 `__","Dangling uses_allocator specialization for packaged_task","Albuquerque","|Complete|","" "`2977 `__","unordered_meow::merge() has incorrect Throws: clause","Albuquerque","|Nothing To Do|","" -"`2978 `__","Hash support for pmr::string and friends","Albuquerque","","" +"`2978 `__","Hash support for pmr::string and friends","Albuquerque","|Complete|","16.0" "`2979 `__","aligned_union should require complete object types","Albuquerque","|Complete|","" "`2980 `__","Cannot compare_exchange empty pointers","Albuquerque","","" -"`2981 `__","Remove redundant deduction guides from standard library","Albuquerque","","" +"`2981 `__","Remove redundant deduction guides from standard library","Albuquerque","|Nothing To Do|","" "`2982 `__","Making size_type consistent in associative container deduction guides","Albuquerque","","" -"`2988 `__","Clause 32 cleanup missed one typename","Albuquerque","","" +"`2988 `__","Clause 32 cleanup missed one typename","Albuquerque","|Complete|","13.0" "`2993 `__","reference_wrapper conversion from T&&","Albuquerque","|Complete|","13.0" "`2998 `__","Requirements on function objects passed to {``forward_``,}list-specific algorithms","Albuquerque","|Nothing To Do|","" -"`3001 `__","weak_ptr::element_type needs remove_extent_t","Albuquerque","","" +"`3001 `__","weak_ptr::element_type needs remove_extent_t","Albuquerque","|Complete|","14.0" "`3024 `__","variant's copies must be deleted instead of disabled via SFINAE","Albuquerque","|Complete|","" -"","","","","" +"","","","","","" "`2164 `__","What are the semantics of ``vector.emplace(vector.begin(), vector.back())``\ ?","Jacksonville","|Complete|","" "`2243 `__","``istream::putback``\ problem","Jacksonville","|Complete|","" "`2816 `__","``resize_file``\ has impossible postcondition","Jacksonville","|Nothing To Do|","" @@ -50,7 +50,7 @@ "`2969 `__","``polymorphic_allocator::construct()``\ shouldn't pass ``resource()``\ ","Jacksonville","|Complete|","" "`2975 `__","Missing case for ``pair``\ construction in scoped and polymorphic allocators","Jacksonville","","" "`2989 `__","``path``\ 's stream insertion operator lets you insert everything under the sun","Jacksonville","|Complete|","" -"`3000 `__","``monotonic_memory_resource::do_is_equal``\ uses ``dynamic_cast``\ unnecessarily","Jacksonville","","" +"`3000 `__","``monotonic_memory_resource::do_is_equal``\ uses ``dynamic_cast``\ unnecessarily","Jacksonville","|Complete|","16.0" "`3002 `__","[networking.ts] ``basic_socket_acceptor::is_open()``\ isn't ``noexcept``\ ","Jacksonville","","" "`3004 `__","|sect|\ [string.capacity] and |sect|\ [vector.capacity] should specify time complexity for ``capacity()``\ ","Jacksonville","|Nothing To Do|","" "`3005 `__","Destruction order of arrays by ``make_shared/allocate_shared``\ only recommended?","Jacksonville","","" @@ -70,11 +70,11 @@ "`3041 `__","Unnecessary ``decay``\ in ``reference_wrapper``\ ","Jacksonville","|Complete|","" "`3042 `__","``is_literal_type_v``\ should be inline","Jacksonville","|Complete|","" "`3043 `__","Bogus postcondition for ``filesystem_error``\ constructor","Jacksonville","|Complete|","" -"`3045 `__","``atomic<*floating-point*>``\ doesn't have ``value_type``\ or ``difference_type``\ ","Jacksonville","","" +"`3045 `__","``atomic``\ doesn't have ``value_type``\ or ``difference_type``\ ","Jacksonville","","" "`3048 `__","``transform_reduce(exec, first1, last1, first2, init)``\ discards execution policy","Jacksonville","","" "`3051 `__","Floating point classifications were inadvertently changed in P0175","Jacksonville","|Nothing To Do|","" "`3075 `__","``basic_string``\ needs deduction guides from ``basic_string_view``\ ","Jacksonville","|Complete|","" -"","","","","" +"","","","","","" "`2139 `__","What is a user-defined type?","Rapperswil","","" "`2970 `__","Return type of std::visit misspecified","Rapperswil","","" "`3058 `__","Parallel adjacent_difference shouldn't require creating temporaries","Rapperswil","","" @@ -90,7 +90,7 @@ "`3100 `__","Unnecessary and confusing ""empty span"" wording","Rapperswil","|Nothing To Do|","" "`3102 `__","Clarify span iterator and ``const_iterator`` behavior","Rapperswil","|Complete|","" "`3104 `__","Fixing duration division","Rapperswil","|Complete|","" -"","","","","" +"","","","","","" "`2183 `__","Muddled allocator requirements for ``match_results``\ constructors","San Diego","|Complete|","" "`2184 `__","Muddled allocator requirements for ``match_results``\ assignments","San Diego","|Complete|","" "`2412 `__","``promise::set_value()``\ and ``promise::get_future()``\ should not race","San Diego","","" @@ -103,31 +103,32 @@ "`2960 `__","[fund.ts.v3] ``nonesuch``\ is insufficiently useless","San Diego","|Complete|","" "`2995 `__","``basic_stringbuf``\ default constructor forbids it from using SSO capacity","San Diego","","" "`2996 `__","Missing rvalue overloads for ``shared_ptr``\ operations","San Diego","","" -"`3008 `__","``make_shared``\ (sub)object destruction semantics are not specified","San Diego","","" +"`3008 `__","``make_shared``\ (sub)object destruction semantics are not specified","San Diego","|Complete|","16.0" "`3022 `__","``is_convertible``\ may lead to ODR","San Diego","Resolved by 1285R0","" "`3025 `__","Map-like container deduction guides should use ``pair``\ , not ``pair``\ ","San Diego","|Complete|","" "`3031 `__","Algorithms and predicates with non-const reference arguments","San Diego","","" -"`3037 `__","``polymorphic_allocator``\ and incomplete types","San Diego","","" -"`3038 `__","``polymorphic_allocator::allocate``\ should not allow integer overflow to create vulnerabilities","San Diego","","" -"`3054 `__","``uninitialized_copy``\ appears to not be able to meet its exception-safety guarantee","San Diego","","" +"`3037 `__","``polymorphic_allocator``\ and incomplete types","San Diego","|Complete|","16.0" +"`3038 `__","``polymorphic_allocator::allocate``\ should not allow integer overflow to create vulnerabilities","San Diego","|Complete|","14.0" +"`3054 `__","``uninitialized_copy``\ appears to not be able to meet its exception-safety guarantee","San Diego","|Nothing To Do|","" "`3065 `__","LWG 2989 missed that all ``path``\ 's other operators should be hidden friends as well","San Diego","|Complete|","" "`3096 `__","``path::lexically_relative``\ is confused by trailing slashes","San Diego","|Complete|","" -"`3116 `__","``*OUTERMOST_ALLOC_TRAITS*``\ needs ``remove_reference_t``\ ","San Diego","","" +"`3116 `__","``OUTERMOST_ALLOC_TRAITS``\ needs ``remove_reference_t``\ ","San Diego","","" "`3122 `__","``__cpp_lib_chrono_udls``\ was accidentally dropped","San Diego","|Complete|","" -"`3127 `__","``basic_osyncstream::rdbuf``\ needs a ````const_cast````\ ","San Diego","","" -"`3128 `__","``strstream::rdbuf``\ needs a ````const_cast````\ ","San Diego","|Nothing To Do|","" +"`3127 `__","``basic_osyncstream::rdbuf``\ needs a ``const_cast``\ ","San Diego","","" +"`3128 `__","``strstream::rdbuf``\ needs a ``const_cast``\ ","San Diego","|Nothing To Do|","" "`3129 `__","``regex_token_iterator``\ constructor uses wrong pointer arithmetic","San Diego","","" "`3130 `__","|sect|\ [input.output] needs many ``addressof``\ ","San Diego","","" "`3131 `__","``addressof``\ all the things","San Diego","","" "`3132 `__","Library needs to ban macros named ``expects``\ or ``ensures``\ ","San Diego","|Nothing To Do|","" "`3134 `__","[fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961","San Diego","Resolved by P1210R0","" "`3137 `__","Header for ``__cpp_lib_to_chars``\ ","San Diego","|Complete|","" +"`3140 `__","``COMMON_REF``\ is unimplementable as specified","San Diego","|Nothing To Do|","" "`3145 `__","``file_clock``\ breaks ABI for C++17 implementations","San Diego","|Complete|","" "`3147 `__","Definitions of ""likely"" and ""unlikely"" are likely to cause problems","San Diego","","" "`3148 `__","````\ should be freestanding","San Diego","","" -"`3153 `__","``Common``\ and ``common_type``\ have too little in common","San Diego","","" -"`3154 `__","``Common``\ and ``CommonReference``\ have a common defect","San Diego","","" -"","","","","" +"`3153 `__","``Common``\ and ``common_type``\ have too little in common","San Diego","|Complete|","13.0" +"`3154 `__","``Common``\ and ``CommonReference``\ have a common defect","San Diego","|Nothing To Do|","" +"","","","","","" "`3012 `__","``atomic``\ is unimplementable for non-``is_trivially_copy_constructible T``\ ","Kona","","" "`3040 `__","``basic_string_view::starts_with``\ *Effects* are incorrect","Kona","|Complete|","" "`3077 `__","``(push|emplace)_back``\ should invalidate the ``end``\ iterator","Kona","|Nothing To Do|","" @@ -136,22 +137,22 @@ "`3112 `__","``system_error``\ and ``filesystem_error``\ constructors taking a ``string``\ may not be able to meet their postconditions","Kona","","" "`3119 `__","Program-definedness of closure types","Kona","|Nothing To Do|","" "`3133 `__","Modernizing numeric type requirements","Kona","","" -"`3144 `__","``span``\ does not have a ````const_pointer````\ typedef","Kona","|Complete|","" -"`3173 `__","Enable CTAD for *``ref-view``*\ ","Kona","","" -"`3179 `__","``subrange``\ should always model ``Range``\ ","Kona","","" -"`3180 `__","Inconsistently named return type for ``ranges::minmax_element``\ ","Kona","","" -"`3182 `__","Specification of ``Same``\ could be clearer","Kona","","" -"","","","","" +"`3144 `__","``span``\ does not have a ``const_pointer``\ typedef","Kona","|Complete|","" +"`3173 `__","Enable CTAD for ``ref-view``\ ","Kona","|Complete|","15.0","|ranges|" +"`3179 `__","``subrange``\ should always model ``Range``\ ","Kona","|Nothing To Do|","","|ranges|" +"`3180 `__","Inconsistently named return type for ``ranges::minmax_element``\ ","Kona","|Complete|","15.0","|ranges|" +"`3182 `__","Specification of ``Same``\ could be clearer","Kona","|Complete|","15.0" +"","","","","","" "`2899 `__","``is_(nothrow_)move_constructible``\ and ``tuple``\ , ``optional``\ and ``unique_ptr``\ ","Cologne","","" "`3055 `__","``path::operator+=(*single-character*)``\ misspecified","Cologne","|Complete|","7.0" -"`3158 `__","``tuple(allocator_arg_t, const Alloc&)``\ should be conditionally explicit","Cologne","","" -"`3169 `__","``ranges``\ permutation generators discard useful information","Cologne","","" -"`3183 `__","Normative permission to specialize Ranges variable templates","Cologne","","" +"`3158 `__","``tuple(allocator_arg_t, const Alloc&)``\ should be conditionally explicit","Cologne","|Complete|","10.0" +"`3169 `__","``ranges``\ permutation generators discard useful information","Cologne","|Complete|","15.0","|ranges|" +"`3183 `__","Normative permission to specialize Ranges variable templates","Cologne","|Nothing To Do|","","|ranges|" "`3184 `__","Inconsistencies in ``bind_front``\ wording","Cologne","|Complete|","13.0" -"`3185 `__","Uses-allocator construction functions missing ``constexpr``\ and ``noexcept``\ ","Cologne","","" -"`3186 `__","``ranges``\ removal, partition, and ``partial_sort_copy``\ algorithms discard useful information","Cologne","","" +"`3185 `__","Uses-allocator construction functions missing ``constexpr``\ and ``noexcept``\ ","Cologne","|Complete|","16.0" +"`3186 `__","``ranges``\ removal, partition, and ``partial_sort_copy``\ algorithms discard useful information","Cologne","|Complete|","15.0","|ranges|" "`3187 `__","`P0591R4 `__ reverted DR 2586 fixes to ``scoped_allocator_adaptor::construct()``\ ","Cologne","","" -"`3191 `__","``std::ranges::shuffle``\ synopsis does not match algorithm definition","Cologne","","" +"`3191 `__","``std::ranges::shuffle``\ synopsis does not match algorithm definition","Cologne","|Complete|","15.0","|ranges|" "`3196 `__","``std::optional``\ is ill-formed is ``T``\ is an array","Cologne","|Complete|","" "`3198 `__","Bad constraint on ``std::span::span()``\ ","Cologne","|Complete|","" "`3199 `__","``istream >> bitset<0>``\ fails","Cologne","","" @@ -159,142 +160,142 @@ "`3206 `__","``year_month_day``\ conversion to ``sys_days``\ uses not-existing member function","Cologne","|Complete|","" "`3208 `__","``Boolean``\ 's expression requirements are ordered inconsistently","Cologne","|Nothing To Do|","" "`3209 `__","Expression in ``year::ok()``\ returns clause is ill-formed","Cologne","|Complete|","" -"","","","","" +"","","","","","" "`3231 `__","``year_month_day_last::day``\ specification does not cover ``!ok()``\ values","Belfast","|Nothing To Do|","" -"`3225 `__","``zoned_time``\ converting constructor shall not be ``noexcept``\ ","Belfast","","" -"`3190 `__","``std::allocator::allocate``\ sometimes returns too little storage","Belfast","","" -"`3218 `__","Modifier for ``%d``\ parse flag does not match POSIX and ``format``\ specification","Belfast","","" -"`3224 `__","``zoned_time``\ constructor from ``TimeZonePtr``\ does not specify initialization of ``tp_``\ ","Belfast","","" -"`3230 `__","Format specifier ``%y/%Y``\ is missing locale alternative versions","Belfast","","" -"`3232 `__","Inconsistency in ``zoned_time``\ deduction guides","Belfast","","" +"`3225 `__","``zoned_time``\ converting constructor shall not be ``noexcept``\ ","Belfast","","","|chrono|" +"`3190 `__","``std::allocator::allocate``\ sometimes returns too little storage","Belfast","|Complete|","14.0" +"`3218 `__","Modifier for ``%d``\ parse flag does not match POSIX and ``format``\ specification","Belfast","","","|chrono| |format|" +"`3224 `__","``zoned_time``\ constructor from ``TimeZonePtr``\ does not specify initialization of ``tp_``\ ","Belfast","","","|chrono|" +"`3230 `__","Format specifier ``%y/%Y``\ is missing locale alternative versions","Belfast","|Complete|","16.0","|chrono| |format|" +"`3232 `__","Inconsistency in ``zoned_time``\ deduction guides","Belfast","","","|chrono|" "`3222 `__","P0574R1 introduced preconditions on non-existent parameters","Belfast","","" "`3221 `__","Result of ``year_month``\ arithmetic with ``months``\ is ambiguous","Belfast","|Complete|","8.0" "`3235 `__","``parse``\ manipulator without abbreviation is not callable","Belfast","","" -"`3246 `__","What are the constraints on the template parameter of ``basic_format_arg``\ ?","Belfast","","" +"`3246 `__","What are the constraints on the template parameter of ``basic_format_arg``\ ?","Belfast","","","|format|" "`3253 `__","``basic_syncbuf::basic_syncbuf()``\ should not be explicit","Belfast","","" -"`3245 `__","Unnecessary restriction on ``'%p'``\ parse specifier","Belfast","","" +"`3245 `__","Unnecessary restriction on ``'%p'``\ parse specifier","Belfast","","","|chrono|" "`3244 `__","Constraints for ``Source``\ in |sect|\ [fs.path.req] insufficiently constrainty","Belfast","","" -"`3241 `__","``chrono-spec``\ grammar ambiguity in |sect|\ [time.format]","Belfast","","" +"`3241 `__","``chrono-spec``\ grammar ambiguity in |sect|\ [time.format]","Belfast","|Complete|","16.0","|chrono| |format|" "`3257 `__","Missing feature testing macro update from P0858","Belfast","","" "`3256 `__","Feature testing macro for ``constexpr``\ algorithms","Belfast","|Complete|","13.0" -"`3273 `__","Specify ``weekday_indexed``\ to range of ``[0, 7]``\ ","Belfast","","" +"`3273 `__","Specify ``weekday_indexed``\ to range of ``[0, 7]``\ ","Belfast","|Complete|","16.0","|chrono|" "`3070 `__","``path::lexically_relative``\ causes surprising results if a filename can also be a *root-name*","Belfast","","" -"`3266 `__","``to_chars(bool)``\ should be deleted","Belfast","","" -"`3272 `__","``%I%p``\ should parse/format ``duration``\ since midnight","Belfast","","" -"`3259 `__","The definition of *constexpr iterators* should be adjusted","Belfast","","" +"`3266 `__","``to_chars(bool)``\ should be deleted","Belfast","|Complete|","14.0" +"`3272 `__","``%I%p``\ should parse/format ``duration``\ since midnight","Belfast","","","|chrono| |format|" +"`3259 `__","The definition of *constexpr iterators* should be adjusted","Belfast","|Nothing To Do|","" "`3103 `__","Errors in taking subview of ``span``\ should be ill-formed where possible","Belfast","","" -"`3274 `__","Missing feature test macro for ````\ ","Belfast","","" -"`3276 `__","Class ``split_view::outer_iterator::value_type``\ should inherit from ``view_interface``\ ","Belfast","","" -"`3277 `__","Pre-increment on prvalues is not a requirement of ``weakly_incrementable``\ ","Belfast","","" +"`3274 `__","Missing feature test macro for ````\ ","Belfast","|Complete|","11.0" +"`3276 `__","Class ``split_view::outer_iterator::value_type``\ should inherit from ``view_interface``\ ","Belfast","|Complete|","15.0","|ranges|" +"`3277 `__","Pre-increment on prvalues is not a requirement of ``weakly_incrementable``\ ","Belfast","|Nothing To Do|","","|ranges|" "`3149 `__","``DefaultConstructible``\ should require default initialization","Belfast","|Complete|","13.0" -"","","","","" +"","","","","","" "`1203 `__","More useful rvalue stream insertion","Prague","|Complete|","12.0" "`2859 `__","Definition of *reachable* in [ptr.launder] misses pointer arithmetic from pointer-interconvertible object","Prague","","" "`3018 `__","``shared_ptr``\ of function type","Prague","","" -"`3050 `__","Conversion specification problem in ``chrono::duration``\ constructor","Prague","","" +"`3050 `__","Conversion specification problem in ``chrono::duration``\ constructor","Prague","","","|chrono|" "`3141 `__","``CopyConstructible``\ doesn't preserve source values","Prague","|Nothing to do|","" -"`3150 `__","``UniformRandomBitGenerator``\ should validate ``min``\ and ``max``\ ","Prague","|Complete|","13.0" +"`3150 `__","``UniformRandomBitGenerator``\ should validate ``min``\ and ``max``\ ","Prague","|Complete|","13.0","|ranges|" "`3175 `__","The ``CommonReference``\ requirement of concept ``SwappableWith``\ is not satisfied in the example","Prague","|Complete|","13.0" "`3194 `__","``ConvertibleTo``\ prose does not match code","Prague","|Complete|","13.0" "`3200 `__","``midpoint``\ should not constrain ``T``\ is complete","Prague","|Nothing To Do|","" "`3201 `__","``lerp``\ should be marked as ``noexcept``\ ","Prague","|Complete|","" -"`3226 `__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time``\ ","Prague","","" +"`3226 `__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time``\ ","Prague","","","|chrono|" "`3233 `__","Broken requirements for ``shared_ptr``\ converting constructors","Prague","","" -"`3237 `__","LWG 3038 and 3190 have inconsistent PRs","Prague","","" +"`3237 `__","LWG 3038 and 3190 have inconsistent PRs","Prague","|Complete|","16.0" "`3238 `__","Insufficiently-defined behavior of ``std::function``\ deduction guides","Prague","","" -"`3242 `__","``std::format``\ : missing rules for ``arg-id``\ in ``width``\ and ``precision``\ ","Prague","","" -"`3243 `__","``std::format``\ and negative zeroes","Prague","","" -"`3247 `__","``ranges::iter_move``\ should perform ADL-only lookup of ``iter_move``\ ","Prague","","" -"`3248 `__","``std::format``\ ``#b``\ , ``#B``\ , ``#o``\ , ``#x``\ , and ``#X``\ presentation types misformat negative numbers","Prague","","" -"`3250 `__","``std::format``\ : ``#``\ (alternate form) for NaN and inf","Prague","","" -"`3251 `__","Are ``std::format``\ alignment specifiers applied to string arguments?","Prague","","" -"`3252 `__","Parse locale's aware modifiers for commands are not consistent with POSIX spec","Prague","","" +"`3242 `__","``std::format``\ : missing rules for ``arg-id``\ in ``width``\ and ``precision``\ ","Prague","|Complete|","Clang 14","|format|" +"`3243 `__","``std::format``\ and negative zeroes","Prague","|Complete|","14.0","|format|" +"`3247 `__","``ranges::iter_move``\ should perform ADL-only lookup of ``iter_move``\ ","Prague","|Complete|","15.0","|ranges|" +"`3248 `__","``std::format``\ ``#b``\ , ``#B``\ , ``#o``\ , ``#x``\ , and ``#X``\ presentation types misformat negative numbers","Prague","|Complete|","14.0","|format|" +"`3250 `__","``std::format``\ : ``#``\ (alternate form) for NaN and inf","Prague","|Complete|","14.0","|format|" +"`3251 `__","Are ``std::format``\ alignment specifiers applied to string arguments?","Prague","|Complete|","14.0","|format|" +"`3252 `__","Parse locale's aware modifiers for commands are not consistent with POSIX spec","Prague","","","|chrono|" "`3254 `__","Strike ``stop_token``\ 's ``operator!=``\ ","Prague","","" "`3255 `__","``span``\ 's ``array``\ constructor is too strict","Prague","|Complete|","" -"`3260 `__","``year_month*``\ arithmetic rejects durations convertible to years","Prague","","" -"`3262 `__","Formatting of negative durations is not specified","Prague","","" -"`3264 `__","``sized_range``\ and ``ranges::size``\ redundantly use ``disable_sized_range``\ ","Prague","","" -"`3269 `__","Parse manipulators do not specify the result of the extraction from stream","Prague","","" -"`3270 `__","Parsing and formatting ``%j``\ with ``duration``\ s","Prague","","" -"`3280 `__","View converting constructors can cause constraint recursion and are unneeded","Prague","","" -"`3281 `__","Conversion from ``*pair-like*``\ types to ``subrange``\ is a silent semantic promotion","Prague","","" -"`3282 `__","``subrange``\ converting constructor should disallow derived to base conversions","Prague","","" -"`3284 `__","``random_access_iterator``\ semantic constraints accidentally promote difference type using unary negate","Prague","","" -"`3285 `__","The type of a customization point object shall satisfy ``semiregular``\ ","Prague","","" -"`3286 `__","``ranges::size``\ is not required to be valid after a call to ``ranges::begin``\ on an input range","Prague","","" -"`3291 `__","``iota_view::iterator``\ has the wrong ``iterator_category``\ ","Prague","","" -"`3292 `__","``iota_view``\ is under-constrained","Prague","","" -"`3294 `__","``zoned_time``\ deduction guides misinterprets ``string``\ /``char*``\ ","Prague","","" +"`3260 `__","``year_month*``\ arithmetic rejects durations convertible to years","Prague","","","|chrono|" +"`3262 `__","Formatting of negative durations is not specified","Prague","|Complete|","16.0","|chrono| |format|" +"`3264 `__","``sized_range``\ and ``ranges::size``\ redundantly use ``disable_sized_range``\ ","Prague","|Complete|","15.0","|ranges|" +"`3269 `__","Parse manipulators do not specify the result of the extraction from stream","Prague","","","|chrono|" +"`3270 `__","Parsing and formatting ``%j``\ with ``duration``\ s","Prague","|Partial|","","|chrono| |format|" +"`3280 `__","View converting constructors can cause constraint recursion and are unneeded","Prague","|Complete|","15.0","|ranges|" +"`3281 `__","Conversion from ``*pair-like*``\ types to ``subrange``\ is a silent semantic promotion","Prague","|Complete|","15.0","|ranges|" +"`3282 `__","``subrange``\ converting constructor should disallow derived to base conversions","Prague","|Complete|","15.0","|ranges|" +"`3284 `__","``random_access_iterator``\ semantic constraints accidentally promote difference type using unary negate","Prague","|Nothing To Do|","","|ranges|" +"`3285 `__","The type of a customization point object shall satisfy ``semiregular``\ ","Prague","|Nothing To Do|","","|ranges|" +"`3286 `__","``ranges::size``\ is not required to be valid after a call to ``ranges::begin``\ on an input range","Prague","|Complete|","15.0","|ranges|" +"`3291 `__","``iota_view::iterator``\ has the wrong ``iterator_category``\ ","Prague","|Complete|","15.0","|ranges|" +"`3292 `__","``iota_view``\ is under-constrained","Prague","|Complete|","15.0","|ranges|" +"`3294 `__","``zoned_time``\ deduction guides misinterprets ``string``\ /``char*``\ ","Prague","","","|chrono|" "`3296 `__","Inconsistent default argument for ``basic_regex<>::assign``\ ","Prague","|Complete|","" -"`3299 `__","Pointers don't need customized iterator behavior","Prague","","" -"`3300 `__","Non-array ``ssize``\ overload is underconstrained","Prague","","" -"`3301 `__","``transform_view::iterator``\ has incorrect ``iterator_category``\ ","Prague","","" -"`3302 `__","Range adaptor objects ``keys``\ and ``values``\ are unspecified","Prague","","" +"`3299 `__","Pointers don't need customized iterator behavior","Prague","|Complete|","15.0","|ranges|" +"`3300 `__","Non-array ``ssize``\ overload is underconstrained","Prague","|Nothing To Do|","" +"`3301 `__","``transform_view::iterator``\ has incorrect ``iterator_category``\ ","Prague","|Complete|","15.0","|ranges|" +"`3302 `__","Range adaptor objects ``keys``\ and ``values``\ are unspecified","Prague","|Complete|","16.0","|ranges|" "`3303 `__","Bad ""``constexpr``\ "" marker for ``destroy/destroy_n``\ ","Prague","","" -"`3304 `__","Allocate functions of ``std::polymorphic_allocator``\ should require ``[[nodiscard]]``\ ","Prague","","" +"`3304 `__","Allocate functions of ``std::polymorphic_allocator``\ should require ``[[nodiscard]]``\ ","Prague","|Complete|","16.0" "`3307 `__","``std::allocator().allocate(n)``\ ","Prague","","" -"`3310 `__","Replace ``SIZE_MAX``\ with ``numeric_limits::max()``\ ","Prague","","" -"`3313 `__","``join_view::iterator::operator--``\ is incorrectly constrained","Prague","","" -"`3314 `__","Is stream insertion behavior locale dependent when ``Period::type``\ is ``micro``\ ?","Prague","","" +"`3310 `__","Replace ``SIZE_MAX``\ with ``numeric_limits::max()``\ ","Prague","|Complete|","16.0" +"`3313 `__","``join_view::iterator::operator--``\ is incorrectly constrained","Prague","|Complete|","14.0","|ranges|" +"`3314 `__","Is stream insertion behavior locale dependent when ``Period::type``\ is ``micro``\ ?","Prague","|Complete|","16.0","|chrono|" "`3315 `__","Correct Allocator Default Behavior","Prague","","" -"`3316 `__","Correctly define epoch for ``utc_clock``\ / ``utc_timepoint``\ ","Prague","","" -"`3317 `__","Incorrect ``operator<<``\ for floating-point durations","Prague","","" -"`3318 `__","Clarify whether clocks can represent time before their epoch","Prague","","" -"`3319 `__","Properly reference specification of IANA time zone database","Prague","","" +"`3316 `__","Correctly define epoch for ``utc_clock``\ / ``utc_timepoint``\ ","Prague","","","|chrono|" +"`3317 `__","Incorrect ``operator<<``\ for floating-point durations","Prague","","","|chrono|" +"`3318 `__","Clarify whether clocks can represent time before their epoch","Prague","","","|chrono|" +"`3319 `__","Properly reference specification of IANA time zone database","Prague","","","|chrono|" "`3320 `__","``span::cbegin/cend``\ methods produce different results than ``std::[ranges::]cbegin/cend``\ ","Prague","|Complete|","" -"`3321 `__","``uninitialized_construct_using_allocator``\ should use ``construct_at``\ ","Prague","","" -"`3323 `__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","","" -"`3324 `__","Special-case ``std::strong/weak/partial_order``\ for pointers","Prague","","" -"`3325 `__","Constrain return type of transformation function for ``transform_view``\ ","Prague","","" -"`3326 `__","``enable_view``\ has false positives","Prague","|In progress|","" -"`3327 `__","Format alignment specifiers vs. text direction","Prague","|Nothing To Do|","" +"`3321 `__","``uninitialized_construct_using_allocator``\ should use ``construct_at``\ ","Prague","|Complete|","16.0" +"`3323 `__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","|Complete|","16.0","|ranges|" +"`3324 `__","Special-case ``std::strong/weak/partial_order``\ for pointers","Prague","|Complete|","14.0","|spaceship|" +"`3325 `__","Constrain return type of transformation function for ``transform_view``\ ","Prague","|Complete|","15.0","|ranges|" +"`3326 `__","``enable_view``\ has false positives","Prague","|Complete|","15.0","|ranges|" +"`3327 `__","Format alignment specifiers vs. text direction","Prague","|Nothing To Do|","","|format|" "`3328 `__","Clarify that ``std::string``\ is not good for UTF-8","Prague","","" "`3329 `__","``totally_ordered_with``\ both directly and indirectly requires ``common_reference_with``\ ","Prague","|Complete|","13.0" -"`3330 `__","Include ````\ from most library headers","Prague","","" -"`3331 `__","Define ``totally_ordered/_with``\ in terms of ``*partially-ordered-with*``\ ","Prague","|Complete|","13.0" -"`3332 `__","Issue in |sect|\ [time.format]","Prague","","" +"`3330 `__","Include ````\ from most library headers","Prague","|Complete|","13.0","|spaceship|" +"`3331 `__","Define ``totally_ordered/_with``\ in terms of ``partially-ordered-with``\ ","Prague","|Complete|","13.0" +"`3332 `__","Issue in |sect|\ [time.format]","Prague","|Complete|","16.0","|chrono| |format|" "`3334 `__","``basic_osyncstream``\ move assignment and destruction calls ``basic_syncbuf::emit()``\ twice","Prague","","" -"`3335 `__","Resolve C++20 NB comments US 273 and GB 274","Prague","","" +"`3335 `__","Resolve C++20 NB comments US 273 and GB 274","Prague","|Complete|","15.0","|ranges|" "`3338 `__","Rename ``default_constructible``\ to ``default_initializable``\ ","Prague","|Complete|","13.0" -"`3340 `__","Formatting functions should throw on argument/format string mismatch in |sect|\ [format.functions]","Prague","","" +"`3340 `__","Formatting functions should throw on argument/format string mismatch in |sect|\ [format.functions]","Prague","|Complete|","14.0","|format|" "`3346 `__","``pair``\ and ``tuple``\ copy and move constructor have backwards specification","Prague","","" "`3347 `__","``std::pair``\ now requires ``T``\ and ``U``\ to be less-than-comparable","Prague","","" -"`3348 `__","``__cpp_lib_unwrap_ref``\ in wrong header","Prague","","" -"`3349 `__","Missing ``__cpp_lib_constexpr_complex``\ for P0415R1","Prague","","" -"`3350 `__","Simplify return type of ``lexicographical_compare_three_way``\ ","Prague","","" -"`3351 `__","``ranges::enable_safe_range``\ should not be constrained","Prague","","" -"`3352 `__","``strong_equality``\ isn't a thing","Prague","","" -"`3354 `__","``has_strong_structural_equality``\ has a meaningless definition","Prague","","" -"`3355 `__","The memory algorithms should support move-only input iterators introduced by P1207","Prague","","" -"`3356 `__","``__cpp_lib_nothrow_convertible``\ should be ``__cpp_lib_is_nothrow_convertible``\ ","Prague","","" +"`3348 `__","``__cpp_lib_unwrap_ref``\ in wrong header","Prague","|Complete|","12.0" +"`3349 `__","Missing ``__cpp_lib_constexpr_complex``\ for P0415R1","Prague","|Complete|","16.0" +"`3350 `__","Simplify return type of ``lexicographical_compare_three_way``\ ","Prague","","","|spaceship|" +"`3351 `__","``ranges::enable_safe_range``\ should not be constrained","Prague","|Complete|","15.0","|ranges|" +"`3352 `__","``strong_equality``\ isn't a thing","Prague","|Nothing To Do|","","|spaceship|" +"`3354 `__","``has_strong_structural_equality``\ has a meaningless definition","Prague","|Nothing To Do|","","|spaceship|" +"`3355 `__","The memory algorithms should support move-only input iterators introduced by P1207","Prague","|Complete|","15.0","|ranges|" +"`3356 `__","``__cpp_lib_nothrow_convertible``\ should be ``__cpp_lib_is_nothrow_convertible``\ ","Prague","|Complete|","12.0" "`3358 `__","|sect|\ [span.cons] is mistaken that ``to_address``\ can throw","Prague","","" -"`3359 `__","````\ leap second support should allow for negative leap seconds","Prague","","" -"`3360 `__","``three_way_comparable_with``\ is inconsistent with similar concepts","Prague","","" +"`3359 `__","````\ leap second support should allow for negative leap seconds","Prague","","","|chrono|" +"`3360 `__","``three_way_comparable_with``\ is inconsistent with similar concepts","Prague","|Nothing To Do|","","|spaceship|" "`3362 `__","Strike ``stop_source``\ 's ``operator!=``\ ","Prague","","" -"`3363 `__","``drop_while_view``\ should opt-out of ``sized_range``\ ","Prague","","" -"`3364 `__","Initialize data members of ranges and their iterators","Prague","","" -"`3367 `__","Integer-class conversions should not throw","Prague","","" -"`3369 `__","``span``\ 's deduction-guide for built-in arrays doesn't work","Prague","","" -"`3371 `__","``visit_format_arg``\ and ``make_format_args``\ are not hidden friends","Prague","","" -"`3372 `__","``vformat_to``\ should not try to deduce ``Out``\ twice","Prague","","" -"`3373 `__","``{to,from}_chars_result``\ and ``format_to_n_result``\ need the ""we really mean what we say"" wording","Prague","","" +"`3363 `__","``drop_while_view``\ should opt-out of ``sized_range``\ ","Prague","|Nothing To Do|","","|ranges|" +"`3364 `__","Initialize data members of ranges and their iterators","Prague","|Complete|","16.0","|ranges|" +"`3367 `__","Integer-class conversions should not throw","Prague","|Nothing To Do|","" +"`3369 `__","``span``\ 's deduction-guide for built-in arrays doesn't work","Prague","|Complete|","14.0" +"`3371 `__","``visit_format_arg``\ and ``make_format_args``\ are not hidden friends","Prague","|Complete|","14.0","|format|" +"`3372 `__","``vformat_to``\ should not try to deduce ``Out``\ twice","Prague","|Complete|","14.0","|format|" +"`3373 `__","``{to,from}_chars_result``\ and ``format_to_n_result``\ need the ""we really mean what we say"" wording","Prague","|Complete|","14.0","|format|" "`3374 `__","P0653 + P1006 should have made the other ``std::to_address``\ overload ``constexpr``\ ","Prague","|Complete|","12.0" -"`3375 `__","``decay``\ in ``viewable_range``\ should be ``remove_cvref``\ ","Prague","","" -"`3377 `__","``elements_view::iterator``\ befriends a specialization of itself","Prague","","" -"`3379 `__","""``safe``\ "" in several library names is misleading","Prague","|In Progress|","" -"`3380 `__","``common_type``\ and comparison categories","Prague","","" -"`3381 `__","``begin``\ and ``data``\ must agree for ``contiguous_range``\ ","Prague","","" +"`3375 `__","``decay``\ in ``viewable_range``\ should be ``remove_cvref``\ ","Prague","|Complete|","15.0","|ranges|" +"`3377 `__","``elements_view::iterator``\ befriends a specialization of itself","Prague","|Nothing To Do|","","|ranges|" +"`3379 `__","""``safe``\ "" in several library names is misleading","Prague","|Complete|","15.0","|ranges|" +"`3380 `__","``common_type``\ and comparison categories","Prague","|Complete|","15.0","|spaceship|" +"`3381 `__","``begin``\ and ``data``\ must agree for ``contiguous_range``\ ","Prague","|Nothing To Do|","","|ranges|" "`3382 `__","NTTP for ``pair``\ and ``array``\ ","Prague","","" -"`3383 `__","|sect|\ [time.zone.leap.nonmembers] ``sys_seconds``\ should be replaced with ``seconds``\ ","Prague","","" -"`3384 `__","``transform_view::*sentinel*``\ has an incorrect ``operator-``\ ","Prague","","" -"`3385 `__","``common_iterator``\ is not sufficiently constrained for non-copyable iterators","Prague","","" -"`3387 `__","|sect|\ [range.reverse.view] ``reverse_view``\ unintentionally requires ``range``\ ","Prague","","" -"`3388 `__","``view``\ iterator types have ill-formed ``<=>``\ operators","Prague","","" -"`3389 `__","A move-only iterator still does not have a ``counted_iterator``\ ","Prague","","" -"`3390 `__","``make_move_iterator()``\ cannot be used to construct a ``move_iterator``\ for a move-only iterator","Prague","","" -"`3393 `__","Missing/incorrect feature test macro for coroutines","Prague","","" -"`3395 `__","Definition for three-way comparison needs to be updated (US 152)","Prague","","" -"`3396 `__","Clarify point of reference for ``source_location::current()``\ (DE 169)","Prague","","" -"`3397 `__","``ranges::basic_istream_view::iterator``\ should not provide ``iterator_category``\ ","Prague","","" -"`3398 `__","``tuple_element_t``\ is also wrong for ``const subrange``\ ","Prague","","" -"`3446 `__","``indirectly_readable_traits``\ ambiguity for types with both ``value_type``\ and ``element_type``\ ","November virtual meeting","|Complete|","13.0" +"`3383 `__","|sect|\ [time.zone.leap.nonmembers] ``sys_seconds``\ should be replaced with ``seconds``\ ","Prague","","","|chrono|" +"`3384 `__","``transform_view::*sentinel*``\ has an incorrect ``operator-``\ ","Prague","|Complete|","15.0","|ranges|" +"`3385 `__","``common_iterator``\ is not sufficiently constrained for non-copyable iterators","Prague","|Complete|","15.0","|ranges|" +"`3387 `__","|sect|\ [range.reverse.view] ``reverse_view``\ unintentionally requires ``range``\ ","Prague","|Complete|","15.0","|ranges|" +"`3388 `__","``view``\ iterator types have ill-formed ``<=>``\ operators","Prague","|Complete|","16.0","|ranges|" +"`3389 `__","A move-only iterator still does not have a ``counted_iterator``\ ","Prague","|Complete|","15.0","|ranges|" +"`3390 `__","``make_move_iterator()``\ cannot be used to construct a ``move_iterator``\ for a move-only iterator","Prague","|Complete|","14.0","|ranges|" +"`3393 `__","Missing/incorrect feature test macro for coroutines","Prague","|Complete|","14.0" +"`3395 `__","Definition for three-way comparison needs to be updated (US 152)","Prague","","","|spaceship|" +"`3396 `__","Clarify point of reference for ``source_location::current()``\ (DE 169)","Prague","|Nothing To Do|","16.0" +"`3397 `__","``ranges::basic_istream_view::iterator``\ should not provide ``iterator_category``\ ","Prague","|Complete|","16.0","|ranges|" +"`3398 `__","``tuple_element_t``\ is also wrong for ``const subrange``\ ","Prague","|Complete|","14.0","|ranges|" +"`3446 `__","``indirectly_readable_traits``\ ambiguity for types with both ``value_type``\ and ``element_type``\ ","November virtual meeting","|Complete|","13.0","|ranges|" diff --git a/gnu/llvm/libcxx/docs/Status/Cxx20Papers.csv b/gnu/llvm/libcxx/docs/Status/Cxx20Papers.csv index 7915b7929ea..6b01966b698 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx20Papers.csv +++ b/gnu/llvm/libcxx/docs/Status/Cxx20Papers.csv @@ -1,15 +1,15 @@ -"Paper #","Group","Paper Name","Meeting","Status","First released version" +"Paper #","Group","Paper Name","Meeting","Status","First released version","Labels" "`P0463R1 `__","LWG","Endian just Endian","Toronto","|Complete|","7.0" -"`P0674R1 `__","LWG","Extending make_shared to Support Arrays","Toronto","","" -"","","","","","" +"`P0674R1 `__","LWG","Extending make_shared to Support Arrays","Toronto","|Complete|","15.0" +"","","","","","","" "`P0020R6 `__","LWG","Floating Point Atomic","Albuquerque","","" "`P0053R7 `__","LWG","C++ Synchronized Buffered Ostream","Albuquerque","","" "`P0202R3 `__","LWG","Add constexpr modifiers to functions in and Headers","Albuquerque","|Complete|","12.0" -"`P0415R1 `__","LWG","Constexpr for ``std::complex``\ ","Albuquerque","|In Progress|","7.0" +"`P0415R1 `__","LWG","Constexpr for ``std::complex``\ ","Albuquerque","|Complete|","16.0" "`P0439R0 `__","LWG","Make ``std::memory_order``\ a scoped enumeration","Albuquerque","|Complete|","" "`P0457R2 `__","LWG","String Prefix and Suffix Checking","Albuquerque","|Complete|","6.0" "`P0550R2 `__","LWG","Transformation Trait ``remove_cvref``\ ","Albuquerque","|Complete|","6.0" -"`P0600R1 `__","LWG","nodiscard in the Library","Albuquerque","|In Progress| [#note-P0600]_","7.0" +"`P0600R1 `__","LWG","nodiscard in the Library","Albuquerque","|Complete|","16.0" "`P0616R0 `__","LWG","de-pessimize legacy algorithms with std::move","Albuquerque","|Complete|","12.0" "`P0653R2 `__","LWG","Utility to convert a pointer to a raw pointer","Albuquerque","|Complete|","6.0" "`P0718R2 `__","LWG","Atomic shared_ptr","Albuquerque","","" @@ -22,14 +22,14 @@ "`P0753R2 `__","LWG","Manipulators for C++ Synchronized Buffered Ostream","Jacksonville","","" "`P0754R2 `__","LWG","","Jacksonville","|Complete|","7.0" "`P0809R0 `__","LWG","Comparing Unordered Containers","Jacksonville","|Nothing To Do|","" -"`P0858R0 `__","LWG","Constexpr iterator requirements","Jacksonville","","" +"`P0858R0 `__","LWG","Constexpr iterator requirements","Jacksonville","|Complete|","12.0" "`P0905R1 `__","CWG","Symmetry for spaceship","Jacksonville","","" "`P0966R1 `__","LWG","``string::reserve``\ Should Not Shrink","Jacksonville","|Complete| [#note-P0966]_","12.0" -"","","","","","" +"","","","","","","" "`P0019R8 `__","LWG","Atomic Ref","Rapperswil","","" "`P0458R2 `__","LWG","Checking for Existence of an Element in Associative Containers","Rapperswil","|Complete|","13.0" "`P0475R1 `__","LWG","LWG 2511: guaranteed copy elision for piecewise construction","Rapperswil","|Complete|","" -"`P0476R2 `__","LWG","Bit-casting object representations","Rapperswil","","" +"`P0476R2 `__","LWG","Bit-casting object representations","Rapperswil","|Complete|","14.0" "`P0528R3 `__","CWG","The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange","Rapperswil","","" "`P0542R5 `__","CWG","Support for contract based programming in C++","Rapperswil","*Removed in Cologne*","n/a" "`P0556R3 `__","LWG","Integral power-of-2 operations","Rapperswil","|Complete|","9.0" @@ -49,38 +49,38 @@ "`P1023R0 `__","LWG","constexpr comparison operators for std::array","Rapperswil","|Complete|","8.0" "`P1025R1 `__","CWG","Update The Reference To The Unicode Standard","Rapperswil","","" "`P1120R0 `__","CWG","Consistency improvements for <=> and other comparison operators","Rapperswil","","" -"","","","","","" +"","","","","","","" "`P0318R1 `__","LWG","unwrap_ref_decay and unwrap_reference","San Diego","|Complete|","8.0" "`P0356R5 `__","LWG","Simplified partial function application","San Diego","|Complete|","13.0" "`P0357R3 `__","LWG","reference_wrapper for incomplete types","San Diego","|Complete|","8.0" -"`P0482R6 `__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|In Progress|","" +"`P0482R6 `__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|Complete|","16.0" "`P0487R1 `__","LWG","Fixing ``operator>>(basic_istream&, CharT*)``\ (LWG 2499)","San Diego","|Complete|","8.0" -"`P0591R4 `__","LWG","Utility functions to implement uses-allocator construction","San Diego","* *","" -"`P0595R2 `__","CWG","P0595R2 std::is_constant_evaluated()","San Diego","|Complete|","9.0" +"`P0591R4 `__","LWG","Utility functions to implement uses-allocator construction","San Diego","|Partial| [#note-P0591]_","" +"`P0595R2 `__","CWG","std::is_constant_evaluated()","San Diego","|Complete|","9.0" "`P0602R4 `__","LWG","variant and optional should propagate copy/move triviality","San Diego","|Complete|","8.0" "`P0608R3 `__","LWG","A sane variant converting constructor","San Diego","|Complete|","9.0" "`P0655R1 `__","LWG","visit: Explicit Return Type for visit","San Diego","|Complete|","12.0" "`P0771R1 `__","LWG","std::function move constructor should be noexcept","San Diego","|Complete|","6.0" -"`P0896R4 `__","LWG","The One Ranges Proposal","San Diego","|In Progress|","" +"`P0896R4 `__","LWG","The One Ranges Proposal","San Diego","|Complete|","15.0","|ranges|" "`P0899R1 `__","LWG","P0899R1 - LWG 3016 is not a defect","San Diego","|Nothing To Do|","" "`P0919R3 `__","LWG","Heterogeneous lookup for unordered containers","San Diego","|Complete|","12.0" "`P0972R0 `__","LWG"," ``zero()``\ , ``min()``\ , and ``max()``\ should be noexcept","San Diego","|Complete|","8.0" "`P1006R1 `__","LWG","Constexpr in std::pointer_traits","San Diego","|Complete|","8.0" -"`P1007R3 `__","LWG","``std::assume_aligned``\ ","San Diego","* *","" -"`P1020R1 `__","LWG","Smart pointer creation with default initialization","San Diego","* *","" +"`P1007R3 `__","LWG","``std::assume_aligned``\ ","San Diego","|Complete|","15.0" +"`P1020R1 `__","LWG","Smart pointer creation with default initialization","San Diego","|Complete|","16.0" "`P1032R1 `__","LWG","Misc constexpr bits","San Diego","|Complete|","13.0" "`P1085R2 `__","LWG","Should Span be Regular?","San Diego","|Complete|","8.0" "`P1123R0 `__","LWG","Editorial Guidance for merging P0019r8 and P0528r3","San Diego","* *","" "`P1148R0 `__","LWG","Cleaning up Clause 20","San Diego","* *","" -"`P1165R1 `__","LWG","Make stateful allocator propagation more consistent for ``operator+(basic_string)``\ ","San Diego","* *","" +"`P1165R1 `__","LWG","Make stateful allocator propagation more consistent for ``operator+(basic_string)``\ ","San Diego","|Complete|","15.0" "`P1209R0 `__","LWG","Adopt Consistent Container Erasure from Library Fundamentals 2 for C++20","San Diego","|Complete|","8.0" "`P1210R0 `__","LWG","Completing the Rebase of Library Fundamentals, Version 3, Working Draft","San Diego","* *","" "`P1236R1 `__","CWG","Alternative Wording for P0907R4 Signed Integers are Two's Complement","San Diego","* *","" "`P1248R1 `__","LWG","Remove CommonReference requirement from StrictWeakOrdering (a.k.a Fixing Relations)","San Diego","|Complete|","13.0" "`P1285R0 `__","LWG","Improving Completeness Requirements for Type Traits","San Diego","* *","" "`P1353R0 `__","CWG","Missing feature test macros","San Diego","* *","" -"","","","","","" -"`P0339R6 `__","LWG","polymorphic_allocator<> as a vocabulary type","Kona","","" +"","","","","","","" +"`P0339R6 `__","LWG","polymorphic_allocator<> as a vocabulary type","Kona","|Complete|","16.0" "`P0340R3 `__","LWG","Making std::underlying_type SFINAE-friendly","Kona","|Complete|","9.0" "`P0738R2 `__","LWG","I Stream, You Stream, We All Stream for istream_iterator","Kona","","" "`P0811R3 `__","LWG","Well-behaved interpolation for numbers and pointers","Kona","|Complete|","9.0" @@ -89,7 +89,7 @@ "`P1024R3 `__","LWG","Usability Enhancements for std::span","Kona","|Complete|","9.0" "`P1164R1 `__","LWG","Make create_directory() Intuitive","Kona","|Complete|","12.0" "`P1227R2 `__","LWG","Signed ssize() functions, unsigned size() functions","Kona","|Complete|","9.0" -"`P1252R2 `__","LWG","Ranges Design Cleanup","Kona","","" +"`P1252R2 `__","LWG","Ranges Design Cleanup","Kona","|Complete|","15.0","|ranges|" "`P1286R2 `__","CWG","Contra CWG DR1778","Kona","","" "`P1357R1 `__","LWG","Traits for [Un]bounded Arrays","Kona","|Complete|","9.0" "`P1458R1 `__","LWG","Mandating the Standard Library: Clause 16 - Language support library","Kona","|Complete|","9.0" @@ -97,106 +97,110 @@ "`P1462R1 `__","LWG","Mandating the Standard Library: Clause 20 - Strings library","Kona","|Complete|","9.0" "`P1463R1 `__","LWG","Mandating the Standard Library: Clause 21 - Containers library","Kona","","" "`P1464R1 `__","LWG","Mandating the Standard Library: Clause 22 - Iterators library","Kona","|Complete|","9.0" +"","","","","","","" +"`P0325R4 `__","LWG","to_array from LFTS with updates","Cologne","|Complete|","10.0" +"`P0408R7 `__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","","" +"`P0466R5 `__","LWG","Layout-compatibility and Pointer-interconvertibility Traits","Cologne","","" +"`P0553R4 `__","LWG","Bit operations","Cologne","|Complete|","9.0" +"`P0631R8 `__","LWG","Math Constants","Cologne","|Complete|","11.0" +"`P0645R10 `__","LWG","Text Formatting","Cologne","|Complete| [#note-P0645]_","14.0" +"`P0660R10 `__","LWG","Stop Token and Joining Thread, Rev 10","Cologne","","" +"`P0784R7 `__","CWG","More constexpr containers","Cologne","|Complete|","12.0" +"`P0980R1 `__","LWG","Making std::string constexpr","Cologne","|Complete|","15.0" +"`P1004R2 `__","LWG","Making std::vector constexpr","Cologne","|Complete|","15.0" +"`P1035R7 `__","LWG","Input Range Adaptors","Cologne","|Complete|","16.0","|ranges|" +"`P1065R2 `__","LWG","Constexpr INVOKE","Cologne","|Complete|","12.0" +"`P1135R6 `__","LWG","The C++20 Synchronization Library","Cologne","|Complete|","11.0" +"`P1207R4 `__","LWG","Movability of Single-pass Iterators","Cologne","|Complete|","15.0","|ranges|" +"`P1208R6 `__","LWG","Adopt source_location for C++20","Cologne","|Complete|","16.0" +"`P1355R2 `__","LWG","Exposing a narrow contract for ceil2","Cologne","|Complete|","9.0" +"`P1361R2 `__","LWG","Integration of chrono with text formatting","Cologne","|Partial|","" +"`P1423R3 `__","LWG","char8_t backward compatibility remediation","Cologne","|Complete|","15.0" +"`P1424R1 `__","LWG","'constexpr' feature macro concerns","Cologne","Superseded by `P1902 `__","" +"`P1466R3 `__","LWG","Miscellaneous minor fixes for chrono","Cologne","","" +"`P1474R1 `__","LWG","Helpful pointers for ContiguousIterator","Cologne","|Complete|","15.0","|ranges|" +"`P1502R1 `__","LWG","Standard library header units for C++20","Cologne","","" +"`P1522R1 `__","LWG","Iterator Difference Type and Integer Overflow","Cologne","|Complete|","15.0","|ranges|" +"`P1523R1 `__","LWG","Views and Size Types","Cologne","|Complete|","15.0","|ranges|" +"`P1612R1 `__","LWG","Relocate Endian's Specification","Cologne","|Complete|","10.0" +"`P1614R2 `__","LWG","The Mothership has Landed","Cologne","|In Progress|","" +"`P1638R1 `__","LWG","basic_istream_view::iterator should not be copyable","Cologne","|Complete|","16.0","|ranges|" +"`P1643R1 `__","LWG","Add wait/notify to atomic_ref","Cologne","","" +"`P1644R0 `__","LWG","Add wait/notify to atomic","Cologne","","" +"`P1650R0 `__","LWG","Output std::chrono::days with 'd' suffix","Cologne","|Complete|","16.0" +"`P1651R0 `__","LWG","bind_front should not unwrap reference_wrapper","Cologne","|Complete|","13.0" +"`P1652R1 `__","LWG","Printf corner cases in std::format","Cologne","|Complete|","14.0" +"`P1661R1 `__","LWG","Remove dedicated precalculated hash lookup interface","Cologne","|Nothing To Do|","" +"`P1754R1 `__","LWG","Rename concepts to standard_case for C++20, while we still can","Cologne","|Complete|","15.0","|ranges|" "","","","","","" -"`P0325 `__","LWG","to_array from LFTS with updates","Cologne","|Complete|","10.0" -"`P0408 `__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","","" -"`P0466 `__","LWG","Layout-compatibility and Pointer-interconvertibility Traits","Cologne","","" -"`P0553 `__","LWG","Bit operations","Cologne","|Complete|","9.0" -"`P0631 `__","LWG","Math Constants","Cologne","|Complete|","11.0" -"`P0645 `__","LWG","Text Formatting","Cologne","|In Progress|","" -"`P0660 `__","LWG","Stop Token and Joining Thread, Rev 10","Cologne","","" -"`P0784 `__","CWG","More constexpr containers","Cologne","|Complete|","12.0" -"`P0980 `__","LWG","Making std::string constexpr","Cologne","","" -"`P1004 `__","LWG","Making std::vector constexpr","Cologne","","" -"`P1035 `__","LWG","Input Range Adaptors","Cologne","","" -"`P1065 `__","LWG","Constexpr INVOKE","Cologne","|Complete|","12.0" -"`P1135 `__","LWG","The C++20 Synchronization Library","Cologne","|Complete|","11.0" -"`P1207 `__","LWG","Movability of Single-pass Iterators","Cologne","","" -"`P1208 `__","LWG","Adopt source_location for C++20","Cologne","","" -"`P1355 `__","LWG","Exposing a narrow contract for ceil2","Cologne","|Complete|","9.0" -"`P1361 `__","LWG","Integration of chrono with text formatting","Cologne","","" -"`P1423 `__","LWG","char8_t backward compatibility remediation","Cologne","|In Progress|","" -"`P1424 `__","LWG","'constexpr' feature macro concerns","Cologne","Superseded by `P1902 `__","" -"`P1466 `__","LWG","Miscellaneous minor fixes for chrono","Cologne","","" -"`P1474 `__","LWG","Helpful pointers for ContiguousIterator","Cologne","","" -"`P1502 `__","LWG","Standard library header units for C++20","Cologne","","" -"`P1522 `__","LWG","Iterator Difference Type and Integer Overflow","Cologne","","" -"`P1523 `__","LWG","Views and Size Types","Cologne","","" -"`P1612 `__","LWG","Relocate Endian's Specification","Cologne","|Complete|","10.0" -"`P1614 `__","LWG","The Mothership has Landed","Cologne","|In Progress|","" -"`P1638 `__","LWG","basic_istream_view::iterator should not be copyable","Cologne","","" -"`P1643 `__","LWG","Add wait/notify to atomic_ref","Cologne","","" -"`P1644 `__","LWG","Add wait/notify to atomic","Cologne","","" -"`P1650 `__","LWG","Output std::chrono::days with 'd' suffix","Cologne","","" -"`P1651 `__","LWG","bind_front should not unwrap reference_wrapper","Cologne","|Complete|","13.0" -"`P1652 `__","LWG","Printf corner cases in std::format","Cologne","","" -"`P1661 `__","LWG","Remove dedicated precalculated hash lookup interface","Cologne","|Nothing To Do|","" -"`P1754 `__","LWG","Rename concepts to standard_case for C++20, while we still can","Cologne","|In Progress|","" -"","","","","","" -"`P0883 `__","LWG","Fixing Atomic Initialization","Belfast","|Complete| [#note-P0883]_","13.0" -"`P1391 `__","LWG","Range constructor for std::string_view","Belfast","* *","" -"`P1394 `__","LWG","Range constructor for std::span","Belfast","* *","" -"`P1456 `__","LWG","Move-only views","Belfast","* *","" -"`P1622 `__","LWG","Mandating the Standard Library: Clause 32 - Thread support library","Belfast","* *","" -"`P1645 `__","LWG","constexpr for numeric algorithms","Belfast","|Complete|","12.0" -"`P1664 `__","LWG","reconstructible_range - a concept for putting ranges back together","Belfast","* *","" -"`P1686 `__","LWG","Mandating the Standard Library: Clause 27 - Time library","Belfast","* *","" -"`P1690 `__","LWG","Refinement Proposal for P0919 Heterogeneous lookup for unordered containers","Belfast","|Complete|","12.0" -"`P1716 `__","LWG","ranges compare algorithm are over-constrained","Belfast","* *","" -"`P1718 `__","LWG","Mandating the Standard Library: Clause 25 - Algorithms library","Belfast","* *","" -"`P1719 `__","LWG","Mandating the Standard Library: Clause 26 - Numerics library","Belfast","* *","" -"`P1720 `__","LWG","Mandating the Standard Library: Clause 28 - Localization library","Belfast","* *","" -"`P1721 `__","LWG","Mandating the Standard Library: Clause 29 - Input/Output library","Belfast","* *","" -"`P1722 `__","LWG","Mandating the Standard Library: Clause 30 - Regular Expression library","Belfast","* *","" -"`P1723 `__","LWG","Mandating the Standard Library: Clause 31 - Atomics library","Belfast","* *","" -"`P1855 `__","LWG","Make ````\ freestanding","Belfast","* *","" -"`P1862 `__","LWG","Ranges adaptors for non-copyable iterators","Belfast","* *","" -"`P1865 `__","LWG","Add max() to latch and barrier","Belfast","|Complete|","11.0" -"`P1869 `__","LWG","Rename 'condition_variable_any' interruptible wait methods","Belfast","* *","" -"`P1870 `__","LWG","forwarding-range is too subtle","Belfast","|In Progress|","" -"`P1871 `__","LWG","Should concepts be enabled or disabled?","Belfast","* *","" -"`P1872 `__","LWG","span should have size_type, not index_type","Belfast","|Complete|","10.0" -"`P1878 `__","LWG","Constraining Readable Types","Belfast","* *","" -"`P1892 `__","LWG","Extended locale-specific presentation specifiers for std::format","Belfast","* *","" -"`P1902 `__","LWG","Missing feature-test macros 2018-2019","Belfast","* *","" -"`P1959 `__","LWG","Remove std::weak_equality and std::strong_equality","Belfast","* *","" -"`P1960 `__","LWG","NB Comment Changes Reviewed by SG1","Belfast","* *","" -"`P1961 `__","LWG","Harmonizing the definitions of total order for pointers","Belfast","* *","" -"`P1965 `__","LWG","Blanket Wording for Specifying ""Hidden Friends""","Belfast","* *","" -"","","","","","" -"`P0586 `__","LWG","Safe integral comparisons","Prague","|Complete|","13.0" -"`P0593 `__","CWG","Implicit creation of objects for low-level object manipulation","Prague","* *","" -"`P1115 `__","LWG","Improving the Return Value of Erase-Like Algorithms II: Free erase/erase if","Prague","|Complete|","11.0" -"`P1243 `__","LWG","Rangify New Algorithms","Prague","* *","" -"`P1460 `__","LWG","Mandating the Standard Library: Clause 20 - Utilities library","Prague","* *","" -"`P1739 `__","LWG","Avoid template bloat for safe_ranges in combination with ""subrange-y"" view adaptors","Prague","* *","" -"`P1831 `__","LWG","Deprecating volatile: library","Prague","* *","" -"`P1868 `__","LWG","width: clarifying units of width and precision in std::format","Prague","* *","" -"`P1908 `__","CWG","Reserving Attribute Namespaces for Future Use","Prague","* *","" -"`P1937 `__","CWG","Fixing inconsistencies between constexpr and consteval functions","Prague","* *","" -"`P1956 `__","LWG","On the names of low-level bit manipulation functions","Prague","|Complete|","12.0" -"`P1957 `__","CWG","Converting from ``T*``\ to bool should be considered narrowing (re: US 212)","Prague","* *","" -"`P1963 `__","LWG","Fixing US 313","Prague","* *","" -"`P1964 `__","LWG","Wording for boolean-testable","Prague","|Complete|","13.0" -"`P1970 `__","LWG","Consistency for size() functions: Add ranges::ssize","Prague","* *","" -"`P1973 `__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","* *","" -"`P1976 `__","LWG","Fixed-size span construction from dynamic range","Prague","|Complete|","11.0" -"`P1981 `__","LWG","Rename leap to leap_second","Prague","* *","" -"`P1982 `__","LWG","Rename link to time_zone_link","Prague","* *","" -"`P1983 `__","LWG","Wording for GB301, US296, US292, US291, and US283","Prague","* *","" -"`P1994 `__","LWG","elements_view needs its own sentinel","Prague","* *","" -"`P2002 `__","CWG","Defaulted comparison specification cleanups","Prague","* *","" -"`P2045 `__","LWG","Missing Mandates for the standard library","Prague","* *","" -"`P2085 `__","CWG","Consistent defaulted comparisons","Prague","* *","" -"`P2091 `__","LWG","Issues with range access CPOs","Prague","* *","" -"`P2101 `__","LWG","'Models' subsumes 'satisfies' (Wording for US298 and US300)","Prague","* *","" -"`P2102 `__","LWG","Make 'implicit expression variations' more explicit (Wording for US185)","Prague","* *","" -"`P2106 `__","LWG","Alternative wording for GB315 and GB316","Prague","* *","" -"`P2116 `__","LWG","Remove tuple-like protocol support from fixed-extent span","Prague","|Complete|","11.0" -"`P2231 `__","LWG","Missing constexpr in std::optional and std::variant","February 2021","|In progress|","13.0" -"`P2325 `__","LWG","Views should not be required to be default constructible","June 2021","|In progress|","" -"`P2210R2 `__","LWG",Superior String Splitting,"June 2021","","" -"`P2216R3 `__","LWG",std::format improvements,"June 2021","","" -"`P2281R1 `__","LWG",Clarifying range adaptor objects,"June 2021","","" -"`P2328R1 `__","LWG",join_view should join all views of ranges,"June 2021","","" -"`P2367R0 `__","LWG",Remove misuses of list-initialization from Clause 24,"June 2021","","" \ No newline at end of file +"`P0883R2 `__","LWG","Fixing Atomic Initialization","Belfast","|Complete| [#note-P0883.1]_ [#note-P0883.2]_","14.0" +"`P1391R4 `__","LWG","Range constructor for std::string_view","Belfast","|Complete|","14.0","|ranges|" +"`P1394R4 `__","LWG","Range constructor for std::span","Belfast","|Complete|","14.0","|ranges|" +"`P1456R1 `__","LWG","Move-only views","Belfast","|Complete|","15.0","|ranges|" +"`P1622R3 `__","LWG","Mandating the Standard Library: Clause 32 - Thread support library","Belfast","* *","" +"`P1645R1 `__","LWG","constexpr for numeric algorithms","Belfast","|Complete|","12.0" +"`P1686R2 `__","LWG","Mandating the Standard Library: Clause 27 - Time library","Belfast","* *","" +"`P1690R1 `__","LWG","Refinement Proposal for P0919 Heterogeneous lookup for unordered containers","Belfast","|Complete|","12.0" +"`P1716R3 `__","LWG","ranges compare algorithm are over-constrained","Belfast","|Complete|","15.0","|ranges|" +"`P1718R2 `__","LWG","Mandating the Standard Library: Clause 25 - Algorithms library","Belfast","* *","" +"`P1719R2 `__","LWG","Mandating the Standard Library: Clause 26 - Numerics library","Belfast","* *","" +"`P1720R2 `__","LWG","Mandating the Standard Library: Clause 28 - Localization library","Belfast","* *","" +"`P1721R2 `__","LWG","Mandating the Standard Library: Clause 29 - Input/Output library","Belfast","* *","" +"`P1722R2 `__","LWG","Mandating the Standard Library: Clause 30 - Regular Expression library","Belfast","* *","" +"`P1723R2 `__","LWG","Mandating the Standard Library: Clause 31 - Atomics library","Belfast","* *","" +"`P1855R0 `__","LWG","Make ````\ freestanding","Belfast","* *","" +"`P1862R1 `__","LWG","Ranges adaptors for non-copyable iterators","Belfast","|Complete|","16.0","|ranges|" +"`P1865R1 `__","LWG","Add max() to latch and barrier","Belfast","|Complete|","11.0" +"`P1869R1 `__","LWG","Rename 'condition_variable_any' interruptible wait methods","Belfast","* *","" +"`P1870R1 `__","LWG","forwarding-range is too subtle","Belfast","|Complete|","15.0","|ranges|" +"`P1871R1 `__","LWG","Concept traits should be named after concepts","Belfast","|Complete|","14.0","|ranges|" +"`P1872R0 `__","LWG","span should have size_type, not index_type","Belfast","|Complete|","10.0" +"`P1878R1 `__","LWG","Constraining Readable Types","Belfast","|Complete|","15.0","|ranges|" +"`P1892R1 `__","LWG","Extended locale-specific presentation specifiers for std::format","Belfast","|Complete|","14.0" +"`P1902R1 `__","LWG","Missing feature-test macros 2018-2019","Belfast","* *","" +"`P1959R0 `__","LWG","Remove std::weak_equality and std::strong_equality","Belfast","|Nothing To Do|","" +"`P1960R0 `__","LWG","NB Comment Changes Reviewed by SG1","Belfast","* *","" +"`P1961R0 `__","LWG","Harmonizing the definitions of total order for pointers","Belfast","* *","" +"`P1965R0 `__","LWG","Blanket Wording for Specifying ""Hidden Friends""","Belfast","* *","" +"","","","","","","" +"`P0586R2 `__","LWG","Safe integral comparisons","Prague","|Complete|","13.0" +"`P0593R6 `__","CWG","Implicit creation of objects for low-level object manipulation","Prague","* *","" +"`P1115R3 `__","LWG","Improving the Return Value of Erase-Like Algorithms II: Free erase/erase if","Prague","|Complete|","11.0" +"`P1243R4 `__","LWG","Rangify New Algorithms","Prague","|Complete|","15.0","|ranges|" +"`P1460R1 `__","LWG","Mandating the Standard Library: Clause 20 - Utilities library","Prague","* *","" +"`P1739R4 `__","LWG","Avoid template bloat for safe_ranges in combination with ""subrange-y"" view adaptors","Prague","|Complete|","15.0","|ranges|" +"`P1831R1 `__","LWG","Deprecating volatile: library","Prague","* *","" +"`P1868R2 `__","LWG","width: clarifying units of width and precision in std::format","Prague","|Complete|","14.0" +"`P1937R2 `__","CWG","Fixing inconsistencies between constexpr and consteval functions","Prague","* *","" +"`P1956R1 `__","LWG","On the names of low-level bit manipulation functions","Prague","|Complete|","12.0" +"`P1957R2 `__","CWG","Converting from ``T*``\ to bool should be considered narrowing (re: US 212)","Prague","* *","" +"`P1963R0 `__","LWG","Fixing US 313","Prague","* *","","" +"`P1964R2 `__","LWG","Wording for boolean-testable","Prague","|Complete|","13.0" +"`P1970R2 `__","LWG","Consistency for size() functions: Add ranges::ssize","Prague","|Complete|","15.0","|ranges|" +"`P1973R1 `__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","|Complete|","16.0" +"`P1976R2 `__","LWG","Fixed-size span construction from dynamic range","Prague","|Complete|","11.0","|ranges|" +"`P1981R0 `__","LWG","Rename leap to leap_second","Prague","* *","" +"`P1982R0 `__","LWG","Rename link to time_zone_link","Prague","* *","" +"`P1983R0 `__","LWG","Wording for GB301, US296, US292, US291, and US283","Prague","|Complete|","15.0","|ranges|" +"`P1994R1 `__","LWG","elements_view needs its own sentinel","Prague","|Complete|","16.0","|ranges|" +"`P2002R1 `__","CWG","Defaulted comparison specification cleanups","Prague","* *","" +"`P2045R1 `__","LWG","Missing Mandates for the standard library","Prague","* *","" +"`P2085R0 `__","CWG","Consistent defaulted comparisons","Prague","* *","" +"`P2091R0 `__","LWG","Issues with range access CPOs","Prague","|Complete|","15.0","|ranges|" +"`P2101R0 `__","LWG","'Models' subsumes 'satisfies' (Wording for US298 and US300)","Prague","* *","" +"`P2102R0 `__","LWG","Make 'implicit expression variations' more explicit (Wording for US185)","Prague","* *","" +"`P2106R0 `__","LWG","Alternative wording for GB315 and GB316","Prague","|Complete|","15.0","|ranges|" +"`P2116R0 `__","LWG","Remove tuple-like protocol support from fixed-extent span","Prague","|Complete|","11.0" +"","","","","","","" +"`P2231R1 `__","LWG","Missing constexpr in std::optional and std::variant","June 2021","|Partial| [#note-P2231]_","13.0" +"`P2325R3 `__","LWG","Views should not be required to be default constructible","June 2021","|Complete|","16.0","|ranges|" +"`P2210R2 `__","LWG","Superior String Splitting","June 2021","|Complete|","16.0","|ranges|" +"`P2216R3 `__","LWG","std::format improvements","June 2021","|Complete|","15.0" +"`P2281R1 `__","LWG","Clarifying range adaptor objects","June 2021","|Complete|","14.0","|ranges|" +"`P2328R1 `__","LWG","join_view should join all views of ranges","June 2021","|Complete|","15.0","|ranges|" +"`P2367R0 `__","LWG","Remove misuses of list-initialization from Clause 24","June 2021","|Complete|","15.0","|ranges|" +"","","","","","","" +"`P2372R3 `__","LWG","Fixing locale handling in chrono formatters","October 2021","|In Progress|","" +"`P2415R2 `__","LWG","What is a ``view``","October 2021","|Complete|","14.0","|ranges|" +"`P2418R2 `__","LWG","Add support for ``std::generator``-like types to ``std::format``","October 2021","|Complete|","15.0" +"`P2432R1 `__","LWG","Fix ``istream_view``","October 2021","|Complete|","16.0","|ranges|" diff --git a/gnu/llvm/libcxx/docs/Status/Cxx2b.rst b/gnu/llvm/libcxx/docs/Status/Cxx2b.rst index cdd1b9c2e29..e79ed285c64 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx2b.rst +++ b/gnu/llvm/libcxx/docs/Status/Cxx2b.rst @@ -1,50 +1,54 @@ -.. _cxx2b-status: - -================================ -libc++ C++2b Status -================================ - -.. include:: ../Helpers/Styles.rst - -.. contents:: - :local: - - -Overview -================================ - -In November 2020, the C++ standard committee adopted the first changes to the next version of the C++ standard, known here as "C++2b" (probably to be C++23). - -This page shows the status of libc++; the status of clang's support of the language features is `here `__. - -.. attention:: Features in unreleased drafts of the standard are subject to change. - -The groups that have contributed papers: - -- CWG - Core Language Working group -- LWG - Library working group -- SG1 - Study group #1 (Concurrency working group) - -.. note:: "Nothing to do" means that no library changes were needed to implement this change. - -.. _paper-status-cxx2b: - -Paper Status -==================================== - -.. csv-table:: - :file: Cxx2bPapers.csv - :header-rows: 1 - :widths: auto - -.. _issues-status-cxx2b: - -Library Working Group Issues Status -==================================== - -.. csv-table:: - :file: Cxx2bIssues.csv - :header-rows: 1 - :widths: auto - -Last Updated: 22-July-2021 +.. _cxx2b-status: + +================================ +libc++ C++2b Status +================================ + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +In November 2020, the C++ standard committee adopted the first changes to the next version of the C++ standard, known here as "C++2b" (probably to be C++23). + +This page shows the status of libc++; the status of clang's support of the language features is `here `__. + +.. attention:: Features in unreleased drafts of the standard are subject to change. + +The groups that have contributed papers: + +- CWG - Core Language Working group +- LWG - Library working group +- SG1 - Study group #1 (Concurrency working group) + +.. note:: "Nothing to do" means that no library changes were needed to implement this change. + +.. _paper-status-cxx2b: + +Paper Status +==================================== + +.. csv-table:: + :file: Cxx2bPapers.csv + :header-rows: 1 + :widths: auto + +.. note:: + + .. [#note-P0533R9] P0533R9: ``isfinite``, ``isinf``, ``isnan`` and ``isnormal`` are implemented. + .. [#note-P1413R3] P1413R3: ``std::aligned_storage_t`` and ``std::aligned_union_t`` are marked deprecated, but + clang doesn't issue a diagnostic for deprecated using template declarations. + +.. _issues-status-cxx2b: + +Library Working Group Issues Status +==================================== + +.. csv-table:: + :file: Cxx2bIssues.csv + :header-rows: 1 + :widths: auto diff --git a/gnu/llvm/libcxx/docs/Status/Cxx2bIssues.csv b/gnu/llvm/libcxx/docs/Status/Cxx2bIssues.csv index 3e745c599aa..b2cc710151f 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx2bIssues.csv +++ b/gnu/llvm/libcxx/docs/Status/Cxx2bIssues.csv @@ -1,99 +1,250 @@ -"Issue #","Issue Name","Meeting","Status","First released version" -"`2839 `__","Self-move-assignment of library types, again","November 2020","","" -"`3117 `__","Missing ``packaged_task`` deduction guides","November 2020","","" +"Issue #","Issue Name","Meeting","Status","First released version","Labels" +"`2839 `__","Self-move-assignment of library types, again","November 2020","|Nothing To Do|","" +"`3117 `__","Missing ``packaged_task`` deduction guides","November 2020","|Complete|","16.0" "`3143 `__","``monotonic_buffer_resource`` growth policy is unclear","November 2020","","" -"`3195 `__","What is the stored pointer value of an empty weak_ptr?","November 2020","","" -"`3211 `__","``std::tuple<>`` should be trivially constructible","November 2020","","" -"`3236 `__","Random access iterator requirements lack limiting relational operators domain to comparing those from the same range","November 2020","","" +"`3195 `__","What is the stored pointer value of an empty ``weak_ptr``?","November 2020","|Nothing To Do|","" +"`3211 `__","``std::tuple<>`` should be trivially constructible","November 2020","|Complete|","9.0" +"`3236 `__","Random access iterator requirements lack limiting relational operators domain to comparing those from the same range","November 2020","|Nothing To Do|","" "`3265 `__","``move_iterator``'s conversions are more broken after P1207","November 2020","Fixed by `LWG3435 `__","" "`3435 `__","``three_way_comparable_with, reverse_iterator>``","November 2020","|Complete|","13.0" -"`3432 `__","Missing requirement for comparison_category","November 2020","","" -"`3447 `__","Deduction guides for ``take_view`` and ``drop_view`` have different constraints","November 2020","","" -"`3450 `__","The const overloads of ``take_while_view::begin/end`` are underconstrained","November 2020","","" +"`3432 `__","Missing requirement for ``comparison_category``","November 2020","|Complete|","16.0","|spaceship|" +"`3447 `__","Deduction guides for ``take_view`` and ``drop_view`` have different constraints","November 2020","|Complete|","14.0","|ranges|" +"`3450 `__","The const overloads of ``take_while_view::begin/end`` are underconstrained","November 2020","|Complete|","16.0","|ranges|" "`3464 `__","``istream::gcount()`` can overflow","November 2020","","" -"`2731 `__","Existence of ``lock_guard::mutex_type`` typedef unclear","November 2020","","" -"`2743 `__","P0083R3 ``node_handle`` private members missing ""exposition only"" comment","November 2020","","" -"`2820 `__","Clarify ```` macros","November 2020","","" +"`2731 `__","Existence of ``lock_guard::mutex_type`` typedef unclear","November 2020","|Complete|","5.0" +"`2743 `__","P0083R3 ``node_handle`` private members missing ""exposition only"" comment","November 2020","|Nothing To Do|","" +"`2820 `__","Clarify ```` macros","November 2020","|Nothing To Do|","" "`3120 `__","Unclear behavior of ``monotonic_buffer_resource::release()``","November 2020","","" "`3170 `__","``is_always_equal`` added to ``std::allocator`` makes the standard library treat derived types as always equal","November 2020","","" "`3036 `__","``polymorphic_allocator::destroy`` is extraneous","November 2020","","" -"`3171 `__","LWG2989 breaks ``directory_entry`` stream insertion","November 2020","","" -"`3306 `__","``ranges::advance`` violates its preconditions","November 2020","","" -"`3403 `__","Domain of ``ranges::ssize(E)`` doesn't ``match ranges::size(E)``","November 2020","","" -"`3404 `__","Finish removing subrange's conversions from pair-like","November 2020","","" -"`3405 `__","``common_view``'s converting constructor is bad, too","November 2020","","" -"`3406 `__","``elements_view::begin()`` and ``elements_view::end()`` have incompatible constraints","November 2020","","" -"`3419 `__","[algorithms.requirements]/15 doesn't reserve as many rights as it intends to","November 2020","","" -"`3420 `__","cpp17-iterator should check that the type looks like an iterator first","November 2020","","" -"`3421 `__","Imperfect ADL emulation for boolean-testable","November 2020","","" -"`3425 `__","``condition_variable_any`` fails to constrain its Lock parameters","November 2020","","" -"`3426 `__","``operator<=>(const unique_ptr&, nullptr_t)`` can't get no satisfaction","November 2020","","" -"`3427 `__","``operator<=>(const shared_ptr&, nullptr_t)`` definition ill-formed","November 2020","","" -"`3428 `__","``single_view``'s in place constructor should be explicit","November 2020","","" -"`3434 `__","``ios_base`` never reclaims memory for iarray and parray","November 2020","","" -"`3437 `__","``__cpp_lib_polymorphic_allocator`` is in the wrong header","November 2020","","" -"`3446 `__","``indirectly_readable_traits`` ambiguity for types with both ``value_type`` and ``element_type``","November 2020","","" -"`3448 `__","``transform_view``'s sentinel not comparable with ``iterator``","November 2020","","" -"`3449 `__","take_view and take_while_view's ``sentinel`` not comparable with their const iterator","November 2020","","" -"`3453 `__","Generic code cannot call ``ranges::advance(i, s)``","November 2020","","" +"`3171 `__","LWG2989 breaks ``directory_entry`` stream insertion","November 2020","|Complete|","14.0" +"`3306 `__","``ranges::advance`` violates its preconditions","November 2020","|Complete|","14.0","|ranges|" +"`3403 `__","Domain of ``ranges::ssize(E)`` doesn't ``match ranges::size(E)``","November 2020","","","|ranges|" +"`3404 `__","Finish removing subrange's conversions from pair-like","November 2020","","","|ranges|" +"`3405 `__","``common_view``'s converting constructor is bad, too","November 2020","|Complete|","14.0","|ranges|" +"`3406 `__","``elements_view::begin()`` and ``elements_view::end()`` have incompatible constraints","November 2020","|Complete|","16.0","|ranges|" +"`3419 `__","[algorithms.requirements]/15 doesn't reserve as many rights as it intends to","November 2020","|Nothing To Do|","" +"`3420 `__","cpp17-iterator should check that the type looks like an iterator first","November 2020","|Complete|","14.0","|ranges|" +"`3421 `__","Imperfect ADL emulation for boolean-testable","November 2020","|Nothing To Do|","","|ranges|" +"`3425 `__","``condition_variable_any`` fails to constrain its Lock parameters","November 2020","|Nothing To Do|","" +"`3426 `__","``operator<=>(const unique_ptr&, nullptr_t)`` can't get no satisfaction","November 2020","|Complete|","16.0","|spaceship|" +"`3427 `__","``operator<=>(const shared_ptr&, nullptr_t)`` definition ill-formed","November 2020","|Complete|","16.0","|spaceship|" +"`3428 `__","``single_view``'s in place constructor should be explicit","November 2020","|Complete|","14.0","|ranges|" +"`3434 `__","``ios_base`` never reclaims memory for iarray and parray","November 2020","|Nothing To Do|","" +"`3437 `__","``__cpp_lib_polymorphic_allocator`` is in the wrong header","November 2020","|Complete|","14.0" +"`3446 `__","``indirectly_readable_traits`` ambiguity for types with both ``value_type`` and ``element_type``","November 2020","|Complete|","14.0","|ranges|" +"`3448 `__","``transform_view``'s ``sentinel`` not comparable with ``iterator``","November 2020","","","|ranges|" +"`3449 `__","``take_view`` and ``take_while_view``'s ``sentinel`` not comparable with their ``const iterator``","November 2020","|Complete|","16.0","|ranges|" +"`3453 `__","Generic code cannot call ``ranges::advance(i, s)``","November 2020","|Nothing To Do|","","|ranges|" "`3455 `__","Incorrect Postconditions on ``unique_ptr`` move assignment","November 2020","|Nothing To Do|","" -"`3460 `__","Unimplementable ``noop_coroutine_handle`` guarantees","November 2020","","" -"`3461 `__","``convertible_to``'s description mishandles cv-qualified void","November 2020","","" -"`3465 `__","compare_partial_order_fallback requires ``F < E``","November 2020","","" -"`3466 `__","Specify the requirements for ``promise``/``future``/``shared_future`` consistently","November 2020","","" -"`3467 `__","``bool`` can't be an integer-like type","November 2020","","" -"`3472 `__","``counted_iterator`` is missing preconditions","November 2020","","" -"`3473 `__","Normative encouragement in non-normative note","November 2020","","" -"`3474 `__","Nesting ``join_views`` is broken because of CTAD","November 2020","","" +"`3460 `__","Unimplementable ``noop_coroutine_handle`` guarantees","November 2020","|Complete|","14.0" +"`3461 `__","``convertible_to``'s description mishandles cv-qualified ``void``","November 2020","|Nothing To Do|","" +"`3465 `__","``compare_partial_order_fallback`` requires ``F < E``","November 2020","|Complete|","14.0","|spaceship|" +"`3466 `__","Specify the requirements for ``promise``/``future``/``shared_future`` consistently","November 2020","|Nothing To Do|","" +"`3467 `__","``bool`` can't be an integer-like type","November 2020","|Complete|","14.0","|ranges|" +"`3472 `__","``counted_iterator`` is missing preconditions","November 2020","|Complete|","14.0","|ranges|" +"`3473 `__","Normative encouragement in non-normative note","November 2020","|Complete|","15.0","|format|" +"`3474 `__","Nesting ``join_views`` is broken because of CTAD","November 2020","|Complete|","15.0","|ranges|" "`3476 `__","``thread`` and ``jthread`` constructors require that the parameters be move-constructible but never move construct the parameters","November 2020","","" -"`3477 `__","Simplify constraints for semiregular-box","November 2020","","" -"`3482 `__","``drop_view``'s const begin should additionally require sized_range","November 2020","","" -"`3483 `__","``transform_view::iterator``'s difference is overconstrained","November 2020","","" -"","","","","" -"`3391 `__","Problems with ``counted_iterator``/``move_iterator::base() const &``","February 2021","","" -"`3433 `__","``subrange::advance(n)`` has UB when ``n < 0``","February 2021","","" -"`3490 `__","``ranges::drop_while_view::begin()`` is missing a precondition","February 2021","","" -"`3492 `__","Minimal improvements to ``elements_view::iterator``","February 2021","","" -"`3494 `__","Allow ranges to be conditionally borrowed","February 2021","Superseded by `P2017R1 `__","" -"`3495 `__","``constexpr launder`` makes pointers to inactive members of unions usable","February 2021","","" -"`3500 `__","``join_view::iterator::operator->()`` is bogus","February 2021","","" -"`3502 `__","``elements_view`` should not be allowed to return dangling reference","February 2021","","" -"`3505 `__","``split_view::outer-iterator::operator++`` misspecified","February 2021","","" -"","","","","" +"`3477 `__","Simplify constraints for ``semiregular-box``","November 2020","","","|ranges|" +"`3482 `__","``drop_view``'s const begin should additionally require ``sized_range``","November 2020","|Complete|","14.0","|ranges|" +"`3483 `__","``transform_view::iterator``'s difference is overconstrained","November 2020","|Complete|","14.0","|ranges|" +"","","","","","" +"`3391 `__","Problems with ``counted_iterator``/``move_iterator::base() const &``","February 2021","","","|ranges|" +"`3433 `__","``subrange::advance(n)`` has UB when ``n < 0``","February 2021","|Complete|","14.0","|ranges|" +"`3490 `__","``ranges::drop_while_view::begin()`` is missing a precondition","February 2021","|Nothing To Do|","","|ranges|" +"`3492 `__","Minimal improvements to ``elements_view::iterator``","February 2021","|Complete|","16.0","|ranges|" +"`3494 `__","Allow ranges to be conditionally borrowed","February 2021","Superseded by `P2017R1 `__","","|ranges|" +"`3495 `__","``constexpr launder`` makes pointers to inactive members of unions usable","February 2021","|Nothing To Do|","" +"`3500 `__","``join_view::iterator::operator->()`` is bogus","February 2021","|Complete|","14.0","|ranges|" +"`3502 `__","``elements_view`` should not be allowed to return dangling reference","February 2021","|Complete|","16.0","|ranges|" +"`3505 `__","``split_view::outer-iterator::operator++`` misspecified","February 2021","","","|ranges|" +"","","","","","" `2774 `__,"``std::function`` construction vs assignment","June 2021","","" -`2818 `__,"``::std::`` everywhere rule needs tweaking","June 2021","","" +`2818 `__,"``::std::`` everywhere rule needs tweaking","June 2021","|Nothing To Do|","" `2997 `__,"LWG 491 and the specification of ``{forward_,}list::unique``","June 2021","","" -`3410 `__,"``lexicographical_compare_three_way`` is overspecified","June 2021","","" +`3410 `__,"``lexicographical_compare_three_way`` is overspecified","June 2021","","","|spaceship|" `3430 `__,"``std::fstream`` & co. should be constructible from string_view","June 2021","","" -`3462 `__,"§[formatter.requirements]: Formatter requirements forbid use of ``fc.arg()``","June 2021","","" -`3481 `__,"``viewable_range`` mishandles lvalue move-only views","June 2021","","" -`3506 `__,"Missing allocator-extended constructors for ``priority_queue``","June 2021","","" -`3517 `__,"``join_view::iterator``'s ``iter_swap`` is underconstrained","June 2021","","" -`3518 `__,"Exception requirements on char trait operations unclear","June 2021","","" -`3519 `__,"Incomplete synopses for classes","June 2021","","" -`3520 `__,"``iter_move`` and ``iter_swap`` are inconsistent for ``transform_view::iterator``","June 2021","","" -`3521 `__,"Overly strict requirements on ``qsort`` and ``bsearch``","June 2021","","" -`3522 `__,"Missing requirement on ``InputIterator`` template parameter for ``priority_queue`` constructors","June 2021","","" -`3523 `__,"``iota_view::sentinel`` is not always ``iota_view``'s sentinel","June 2021","","" +`3462 `__,"§[formatter.requirements]: Formatter requirements forbid use of ``fc.arg()``","June 2021","","","|format|" +`3481 `__,"``viewable_range`` mishandles lvalue move-only views","June 2021","Superseded by `P2415R2 `__","","|ranges|" +`3506 `__,"Missing allocator-extended constructors for ``priority_queue``","June 2021","|Complete|","14.0" +`3517 `__,"``join_view::iterator``'s ``iter_swap`` is underconstrained","June 2021","|Complete|","14.0","|ranges|" +`3518 `__,"Exception requirements on char trait operations unclear","June 2021","|Nothing To Do|","" +`3519 `__,"Incomplete synopses for ```` classes","June 2021","","" +`3520 `__,"``iter_move`` and ``iter_swap`` are inconsistent for ``transform_view::iterator``","June 2021","|Complete|","14.0","|ranges|" +`3521 `__,"Overly strict requirements on ``qsort`` and ``bsearch``","June 2021","|Nothing To Do|","" +`3522 `__,"Missing requirement on ``InputIterator`` template parameter for ``priority_queue`` constructors","June 2021","|Complete|","14.0" +`3523 `__,"``iota_view::sentinel`` is not always ``iota_view``'s sentinel","June 2021","","","|ranges|" `3526 `__,"Return types of ``uses_allocator_construction_args`` unspecified","June 2021","","" `3527 `__,"``uses_allocator_construction_args`` handles rvalue pairs of rvalue references incorrectly","June 2021","","" `3528 `__,"``make_from_tuple`` can perform (the equivalent of) a C-style cast","June 2021","","" -`3529 `__,"``priority_queue(first, last)`` should construct ``c`` with ``(first, last)``","June 2021","","" +`3529 `__,"``priority_queue(first, last)`` should construct ``c`` with ``(first, last)``","June 2021","|Complete|","14.0" `3530 `__,"``BUILTIN-PTR-MEOW`` should not opt the type out of syntactic checks","June 2021","","" -`3532 `__,"``split_view::inner-iterator::operator++(int)`` should depend on ``Base``","June 2021","","" -`3533 `__,"Make ``base() const &`` consistent across iterator wrappers that supports ``input_iterators``","June 2021","","" -`3536 `__,"Should ``chrono::from_stream()`` assign zero to duration for failure?","June 2021","","" -`3539 `__,"``format_to`` must not copy models of ``output_iterator``","June 2021","","" -`3540 `__,"§[format.arg] There should be no const in ``basic_format_arg(const T* p)``","June 2021","","" -`3541 `__,"``indirectly_readable_traits`` should be SFINAE-friendly for all types","June 2021","","" -`3542 `__,"``basic_format_arg`` mishandles ``basic_string_view`` with custom traits","June 2021","","" -`3543 `__,"Definition of when ``counted_iterators`` refer to the same sequence isn't quite right","June 2021","","" -`3544 `__,"``format-arg-store::args`` is unintentionally not exposition-only","June 2021","","" -`3546 `__,"``common_iterator``'s postfix-proxy is not quite right","June 2021","","" -`3548 `__,"``shared_ptr`` construction from ``unique_ptr`` should move (not copy) the deleter","June 2021","","" -`3549 `__,"``view_interface`` is overspecified to derive from ``view_base``","June 2021","","" -`3551 `__,"``borrowed_{iterator,subrange}_t`` are overspecified","June 2021","","" +`3532 `__,"``split_view::inner-iterator::operator++(int)`` should depend on ``Base``","June 2021","","","|ranges|" +`3533 `__,"Make ``base() const &`` consistent across iterator wrappers that supports ``input_iterators``","June 2021","|Complete|","14.0","|ranges|" +`3536 `__,"Should ``chrono::from_stream()`` assign zero to duration for failure?","June 2021","","","|chrono|" +`3539 `__,"``format_to`` must not copy models of ``output_iterator``","June 2021","|Complete|","14.0","|format|" +`3540 `__,"§[format.arg] There should be no const in ``basic_format_arg(const T* p)``","June 2021","|Complete|","14.0","|format|" +`3541 `__,"``indirectly_readable_traits`` should be SFINAE-friendly for all types","June 2021","|Complete|","14.0","|ranges|" +`3542 `__,"``basic_format_arg`` mishandles ``basic_string_view`` with custom traits","June 2021","|Complete|","14.0","|format|" +`3543 `__,"Definition of when ``counted_iterators`` refer to the same sequence isn't quite right","June 2021","|Nothing To Do|","","|ranges|" +`3544 `__,"``format-arg-store::args`` is unintentionally not exposition-only","June 2021","|Complete|","14.0","|format|" +`3546 `__,"``common_iterator``'s postfix-proxy is not quite right","June 2021","","","|ranges|" +`3548 `__,"``shared_ptr`` construction from ``unique_ptr`` should move (not copy) the deleter","June 2021","|Complete|","15.0" +`3549 `__,"``view_interface`` is overspecified to derive from ``view_base``","June 2021","|Complete|","14.0","|ranges|" +`3551 `__,"``borrowed_{iterator,subrange}_t`` are overspecified","June 2021","|Nothing To Do|","","|ranges|" `3552 `__,"Parallel specialized memory algorithms should require forward iterators","June 2021","","" -`3553 `__,"Useless constraint in ``split_view::outer-iterator::value_type::begin()``","June 2021","","" -`3555 `__,"``{transform,elements}_view::iterator::iterator_concept`` should consider const-qualification of the underlying range","June 2021","","" -"","","","","" +`3553 `__,"Useless constraint in ``split_view::outer-iterator::value_type::begin()``","June 2021","","","|ranges|" +`3555 `__,"``{transform,elements}_view::iterator::iterator_concept`` should consider const-qualification of the underlying range","June 2021","","","|ranges|" +"","","","","","" +`2191 `__,"Incorrect specification of ``match_results(match_results&&)``","October 2021","|Nothing To Do|","" +`2381 `__,"Inconsistency in parsing floating point numbers","October 2021","","" +`2762 `__,"``unique_ptr operator*()`` should be ``noexcept``","October 2021","","" +`3121 `__,"``tuple`` constructor constraints for ``UTypes&&...`` overloads","October 2021","","" +`3123 `__,"``duration`` constructor from representation shouldn't be effectively non-throwing","October 2021","","","|chrono|" +`3146 `__,"Excessive unwrapping in ``std::ref/cref``","October 2021","|Complete|","14.0" +`3152 `__,"``common_type`` and ``common_reference`` have flaws in common","October 2021","","" +`3293 `__,"``move_iterator operator+()`` has incorrect constraints","October 2021","|Complete|","15.0" +`3361 `__,"``safe_range`` case","October 2021","|Nothing To Do|","","|ranges|" +`3392 `__,"``ranges::distance()`` cannot be used on a move-only iterator with a sized sentinel","October 2021","|Complete|","14.0","|ranges|" +`3407 `__,"Some problems with the wording changes of P1739R4","October 2021","|Complete|","15.0","|ranges|" +`3422 `__,"Issues of ``seed_seq``'s constructors","October 2021","|Complete|","14.0" +`3470 `__,"``convertible-to-non-slicing`` seems to reject valid case","October 2021","|Complete|","14.0","|ranges|" +`3480 `__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","October 2021","|Complete|","14.0","|ranges|" +`3498 `__,"Inconsistent ``noexcept``-specifiers for ``basic_syncbuf``","October 2021","","" +`3535 `__,"``join_view::iterator::iterator_category`` and ``::iterator_concept`` lie","October 2021","|Complete|","15.0","|ranges|" +`3554 `__,"``chrono::parse`` needs ``const charT*`` and ``basic_string_view`` overloads","October 2021","","","|chrono|" +`3557 `__,"The ``static_cast`` expression in ``convertible_to`` has the wrong operand","October 2021","|Complete|","14.0" +`3559 `__,"Semantic requirements of ``sized_range`` is circular","October 2021","|Nothing To Do|","","|ranges|" +`3560 `__,"``ranges::equal`` and ``ranges::is_permutation`` should short-circuit for ``sized_ranges``","October 2021","","","|ranges|" +`3561 `__,"Issue with internal counter in ``discard_block_engine``","October 2021","","" +`3563 `__,"``keys_view`` example is broken","October 2021","","","|ranges|" +`3566 `__,"Constraint recursion for ``operator<=>(optional, U)``","October 2021","","","|spaceship|" +`3567 `__,"Formatting move-only iterators take two","October 2021","|Complete|","16.0","|format| |ranges|" +`3568 `__,"``basic_istream_view`` needs to initialize ``value_``","October 2021","|Complete|","16.0","|ranges|" +`3570 `__,"``basic_osyncstream::emit`` should be an unformatted output function","October 2021","","" +`3571 `__,"``flush_emit`` should set ``badbit`` if the ``emit`` call fails","October 2021","","" +`3572 `__,"``copyable-box`` should be fully ``constexpr``","October 2021","|Complete|","14.0","|ranges|" +`3573 `__,"Missing Throws element for ``basic_string_view(It begin, End end)``","October 2021","|Complete|","14.0" +`3574 `__,"``common_iterator`` should be completely ``constexpr``-able","October 2021","|Complete|","14.0","|ranges|" +`3580 `__,"``iota_view``'s ``iterator``'s binary ``operator+`` should be improved","October 2021","|Complete|","14.0","|ranges|" +`3581 `__,"The range constructor makes ``basic_string_view`` not trivially move constructible","October 2021","|Complete|","14.0","|ranges|" +`3585 `__,"``variant`` converting assignment with immovable alternative","October 2021","","" +`3589 `__,"The ``const`` lvalue reference overload of ``get`` for ``subrange`` does not constrain ``I`` to be ``copyable`` when ``N == 0``","October 2021","|Complete|","14.0","|ranges|" +`3590 `__,"``split_view::base() const &`` is overconstrained","October 2021","|Complete|","16.0","|ranges|" +`3591 `__,"``lazy_split_view::inner-iterator::base() &&`` invalidates outer iterators","October 2021","","","|ranges|" +`3592 `__,"``lazy_split_view`` needs to check the simpleness of Pattern","October 2021","","","|ranges|" +`3593 `__,"Several iterators' ``base() const &`` and ``lazy_split_view::outer-iterator::value_type::end()`` missing ``noexcept``","October 2021","","","|ranges|" +`3595 `__,"Exposition-only classes proxy and postfix-proxy for ``common_iterator`` should be fully ``constexpr``","October 2021","|Complete|","14.0","|ranges|" +"","","","","","" +"`3088 `__","``forward_list::merge`` behaviour unclear when passed ``*this``","February 2022","","" +"`3471 `__","``polymorphic_allocator::allocate`` does not satisfy ``Cpp17Allocator`` requirements","February 2022","","" +"`3525 `__","``uses_allocator_construction_args`` fails to handle types convertible to ``pair``","February 2022","","" +"`3598 `__","``system_category().default_error_condition(0)`` is underspecified","February 2022","","" +"`3601 `__","common_iterator's postfix-proxy needs ``indirectly_readable`` ","February 2022","","","|ranges|" +"`3607 `__","``contiguous_iterator`` should not be allowed to have custom ``iter_move`` and ``iter_swap`` behavior","February 2022","|Nothing to do|","","|ranges|" +"`3610 `__","``iota_view::size`` sometimes rejects integer-class types","February 2022","","","|ranges|" +"`3612 `__","Inconsistent pointer alignment in ``std::format`` ","February 2022","|Complete|","14.0","|format|" +"`3616 `__","LWG 3498 seems to miss the non-member ``swap`` for ``basic_syncbuf`` ","February 2022","","" +"`3618 `__","Unnecessary ``iter_move`` for ``transform_view::iterator`` ","February 2022","","","|ranges|" +"`3619 `__","Specification of ``vformat_to`` contains ill-formed ``formatted_size`` calls","February 2022","|Nothing to do|","","|format|" +"`3621 `__","Remove feature-test macro ``__cpp_lib_monadic_optional`` ","February 2022","|Complete|","15.0" +"`3632 `__","``unique_ptr`` ""Mandates: This constructor is not selected by class template argument deduction""","February 2022","|Nothing to do|","" +"`3643 `__","Missing ``constexpr`` in ``std::counted_iterator`` ","February 2022","","","|ranges|" +"`3648 `__","``format`` should not print ``bool`` with ``'c'`` ","February 2022","|Complete|","15.0","|format|" +"`3649 `__","[fund.ts.v2] Reinstate and bump ``__cpp_lib_experimental_memory_resource`` feature test macro","February 2022","","" +"`3650 `__","Are ``std::basic_string`` 's ``iterator`` and ``const_iterator`` constexpr iterators?","February 2022","|Nothing to do|","" +"`3654 `__","``basic_format_context::arg(size_t)`` should be ``noexcept`` ","February 2022","|Complete|","15.0","|format|" +"`3657 `__","``std::hash`` is not enabled","February 2022","","" +"`3660 `__","``iterator_traits::pointer`` should conform to §[iterator.traits]","February 2022","|Complete|","14.0","|ranges|" +"`3661 `__","``constinit atomic> a(nullptr);`` should work","February 2022","","" +"","","","","","" +"`3564 `__","``transform_view::iterator::value_type`` and ``iterator_category`` should use ``const F&``","July 2022","","","|ranges|" +"`3617 `__","``function``/``packaged_task`` deduction guides and deducing ``this``","July 2022","","" +"`3656 `__","Inconsistent bit operations returning a count","July 2022","|Complete|","15.0","" +"`3659 `__","Consider ``ATOMIC_FLAG_INIT`` undeprecation","July 2022","|Complete|","15.0" +"`3670 `__","``Cpp17InputIterators`` don't have integer-class difference types","July 2022","","","|ranges|" +"`3671 `__","``atomic_fetch_xor`` missing from ``stdatomic.h``","July 2022","","" +"`3672 `__","``common_iterator::operator->()`` should return by value","July 2022","","","|ranges|" +"`3683 `__","``operator==`` for ``polymorphic_allocator`` cannot deduce template argument in common cases","July 2022","","" +"`3687 `__","``expected`` move constructor should move","July 2022","|Complete|","16.0" +"`3692 `__","``zip_view::iterator``'s ``operator<=>`` is overconstrained","July 2022","","","|ranges| |spaceship|" +"`3701 `__","Make ``formatter, charT>`` requirement explicit","July 2022","","","|format|" +"`3702 `__","Should ``zip_transform_view::iterator`` remove ``operator<``","July 2022","","","|ranges| |spaceship|" +"`3703 `__","Missing requirements for ``expected`` requires ``is_void``","July 2022","|Complete|","16.0" +"`3704 `__","LWG 2059 added overloads that might be ill-formed for sets","July 2022","","" +"`3705 `__","Hashability shouldn't depend on basic_string's allocator","July 2022","|Complete|","16.0" +"`3707 `__","chunk_view::outer-iterator::value_type::size should return unsigned type","July 2022","","","|ranges|" +"`3708 `__","``take_while_view::sentinel``'s conversion constructor should move","July 2022","|Complete|","16.0","|ranges|" +"`3709 `__","LWG-3703 was underly ambitious","July 2022","","" +"`3710 `__","The ``end`` of ``chunk_view`` for input ranges can be ``const``","July 2022","","","|ranges|" +"`3711 `__","Missing preconditions for slide_view constructor","July 2022","","","|ranges|" +"`3712 `__","``chunk_view`` and ``slide_view`` should not be ``default_initializable``","July 2022","","","|ranges|" +"`3713 `__","Sorted with respect to comparator (only)","July 2022","","" +"`3715 `__","``view_interface::empty`` is overconstrained","July 2022","","","|ranges|" +"`3719 `__","Directory iterators should be usable with default sentinel","July 2022","","","|ranges|" +"`3721 `__","Allow an ``arg-id`` with a value of zero for ``width`` in ``std-format-spec``","July 2022","|Complete|","16.0","|format|" +"`3724 `__","``decay-copy`` should be constrained","July 2022","|Complete|","14.0" +"","","","","","" +"`3028 `__","Container requirements tables should distinguish ``const`` and non-``const`` variables", "November 2022","","","" +"`3118 `__","``fpos`` equality comparison unspecified", "November 2022","","","" +"`3177 `__","Limit permission to specialize variable templates to program-defined types", "November 2022","|Nothing to do|","","" +"`3515 `__","§[stacktrace.basic.nonmem]: ``operator<<`` should be less templatized", "November 2022","","","" +"`3545 `__","``std::pointer_traits`` should be SFINAE-friendly", "November 2022","","","" +"`3569 `__","``join_view`` fails to support ranges of ranges with non-default_initializable iterators", "November 2022","","","|ranges|" +"`3594 `__","``inout_ptr`` — inconsistent ``release()`` in destructor", "November 2022","","","" +"`3597 `__","Unsigned integer types don't model advanceable", "November 2022","","","|ranges|" +"`3600 `__","Making ``istream_iterator`` copy constructor trivial is an ABI break", "November 2022","","","" +"`3629 `__","``make_error_code`` and ``make_error_condition`` are customization points","November 2022","|Complete|","16.0","" +"`3636 `__","``formatter::format`` should be ``const``-qualified","November 2022","|Complete|","16.0","|format|" +"`3646 `__","``std::ranges::view_interface::size`` returns a signed type","November 2022","|Complete|","16.0","|ranges|" +"`3677 `__","Is a cv-qualified ``pair`` specially handled in uses-allocator construction?", "November 2022","","","" +"`3717 `__","``common_view::end`` should improve ``random_access_range`` case", "November 2022","","","|ranges|" +"`3732 `__","``prepend_range`` and ``append_range`` can't be amortized constant time", "November 2022","|Nothing to do|","","|ranges|" +"`3736 `__","``move_iterator`` missing ``disable_sized_sentinel_for`` specialization", "November 2022","","","|ranges|" +"`3737 `__","``take_view::sentinel`` should provide ``operator-``", "November 2022","","","|ranges|" +"`3738 `__","Missing preconditions for ``take_view`` constructor", "November 2022","|Complete|","16.0","|ranges|" +"`3743 `__","``ranges::to``'s reserve may be ill-formed", "November 2022","","","|ranges|" +"`3745 `__","``std::atomic_wait`` and its friends lack ``noexcept``", "November 2022","|Complete|","16.0","" +"`3746 `__","``optional``'s spaceship with ``U`` with a type derived from optional causes infinite constraint meta-recursion", "November 2022","","","|spaceship|" +"`3747 `__","``ranges::uninitialized_copy_n``, ``ranges::uninitialized_move_n``, and ``ranges::destroy_n`` should use ``std::move``", "November 2022","","","|ranges|" +"`3750 `__","Too many papers bump ``__cpp_lib_format``", "November 2022","","","|format|" +"`3751 `__","Missing feature macro for ``flat_set``", "November 2022","","","|flat_containers|" +"`3753 `__","Clarify entity vs. freestanding entity", "November 2022","","","" +"`3754 `__","Class template expected synopsis contains declarations that do not match the detailed description", "November 2022","","","" +"`3755 `__","``tuple-for-each`` can call ``user-defined`` ``operator,``", "November 2022","","","" +"`3757 `__","What's the effect of ``std::forward_like(x)``?", "November 2022","","","" +"`3759 `__","``ranges::rotate_copy`` should use ``std::move``", "November 2022","","","|ranges|" +"`3760 `__","``cartesian_product_view::iterator``'s ``parent_`` is never valid", "November 2022","","","|ranges|" +"`3761 `__","``cartesian_product_view::iterator::operator-`` should pass by reference", "November 2022","","","|ranges|" +"`3762 `__","``generator::iterator::operator==`` should pass by reference", "November 2022","","","" +"`3764 `__","``reference_wrapper::operator()`` should propagate noexcept", "November 2022","","","" +"`3765 `__","``const_sentinel`` should be constrained", "November 2022","","","|ranges|" +"`3766 `__","``view_interface::cbegin`` is underconstrained", "November 2022","","","|ranges|" +"`3770 `__","``const_sentinel_t`` is missing", "November 2022","","","|ranges|" +"`3773 `__","``views::zip_transform`` still requires ``F`` to be ``copy_constructible`` when empty pack", "November 2022","","","|ranges|" +"`3774 `__","```` should include ````", "November 2022","","","|flat_containers|" +"`3775 `__","Broken dependencies in the ``Cpp17Allocator`` requirements", "November 2022","","","" +"`3778 `__","``vector`` missing exception specifications", "November 2022","","","" +"`3781 `__","The exposition-only alias templates ``cont-key-type`` and ``cont-mapped-type`` should be removed", "November 2022","","","" +"`3782 `__","Should ```` declare ``::lerp``?", "November 2022","","","" +"`3784 `__","std.compat should not provide ``::byte`` and its friends", "November 2022","","","" +"`3785 `__","``ranges::to`` is over-constrained on the destination type being a range", "November 2022","","","|ranges|" +"`3788 `__","``jthread::operator=(jthread&&)`` postconditions are unimplementable under self-assignment", "November 2022","","","" +"`3792 `__","``__cpp_lib_constexpr_algorithms`` should also be defined in ````", "November 2022","|Complete|","16.0","" +"`3795 `__","Self-move-assignment of ``std::future`` and ``std::shared_future`` have unimplementable postconditions", "November 2022","","","" +"`3796 `__","``movable-box`` as member should use ``default-initialization`` instead of ``copy-initialization``", "November 2022","","","|ranges|" +"`3798 `__","Rvalue reference and ``iterator_category``", "November 2022","","","" +"`3801 `__","``cartesian_product_view::iterator::distance-from`` ignores the size of last underlying range", "November 2022","","","|ranges|" +"`3814 `__","Add freestanding items requested by NB comments", "November 2022","","","" +"`3816 `__","``flat_map`` and ``flat_multimap`` should impose sequence container requirements", "November 2022","","","|flat_containers|" +"`3817 `__","Missing preconditions on ``forward_list`` modifiers", "November 2022","","","" +"`3818 `__","Exposition-only concepts are not described in library intro", "November 2022","|Nothing to do|","","" +"`3822 `__","Avoiding normalization in ``filesystem::weakly_canonical``", "November 2022","","","" +"`3823 `__","Unnecessary precondition for ``is_aggregate``", "November 2022","","","" +"`3824 `__","Number of ``bind`` placeholders is underspecified", "November 2022","|Nothing to do|","","" +"`3826 `__","Redundant specification [for overload of yield_value]", "November 2022","","","" +"","","","","","" +"`3631 `__","``basic_format_arg(T&&)`` should use ``remove_cvref_t`` throughout","Not voted in","|Complete|","15.0","" +"`3645 `__","``resize_and_overwrite`` is overspecified to call its callback with lvalues","Not voted in","|Complete|","14.0","" +"`3343 `__","Ordering of calls to ``unlock()`` and ``notify_all()`` in Effects element of ``notify_all_at_thread_exit()`` should be reversed","Not Yet Adopted","|Complete|","16.0","" diff --git a/gnu/llvm/libcxx/docs/Status/Cxx2bPapers.csv b/gnu/llvm/libcxx/docs/Status/Cxx2bPapers.csv index 4df0bfcddbf..e3f39d42505 100644 --- a/gnu/llvm/libcxx/docs/Status/Cxx2bPapers.csv +++ b/gnu/llvm/libcxx/docs/Status/Cxx2bPapers.csv @@ -1,25 +1,106 @@ -"Paper #","Group","Paper Name","Meeting","Status","First released version" +"Paper #","Group","Paper Name","Meeting","Status","First released version","Labels" "`P0881R7 `__","LWG","A Proposal to add stacktrace library","Autumn 2020","","" -"`P0943R6 `__","LWG","Support C atomics in C++","Autumn 2020","","" +"`P0943R6 `__","LWG","Support C atomics in C++","Autumn 2020","|Complete|","15.0" "`P1048R1 `__","LWG","A proposal for a type trait to detect scoped enumerations","Autumn 2020","|Complete|","12.0" "`P1679R3 `__","LWG","string contains function","Autumn 2020","|Complete|","12.0" -"","","","","","" +"","","","","","","" "`P1682R3 `__","LWG","std::to_underlying for enumerations","February 2021","|Complete|","13.0" -"`P2017R1 `__","LWG","Conditionally borrowed ranges","February 2021","","" +"`P2017R1 `__","LWG","Conditionally borrowed ranges","February 2021","","","|ranges|" "`P2160R1 `__","LWG","Locks lock lockables","February 2021","","" "`P2162R2 `__","LWG","Inheriting from std::variant","February 2021","|Complete|","13.0" "`P2212R2 `__","LWG","Relax Requirements for time_point::clock","February 2021","","" -"`P2259R1 `__","LWG","Repairing input range adaptors and counted_iterator","February 2021","","" -"","","","","","" -"`P0401R6 `__","LWG","Providing size feedback in the Allocator interface","June 2021","", +"`P2259R1 `__","LWG","Repairing input range adaptors and counted_iterator","February 2021","","","|ranges|" +"","","","","","","" +"`P0401R6 `__","LWG","Providing size feedback in the Allocator interface","June 2021","|Complete|","15.0" "`P0448R4 `__","LWG","A strstream replacement using span as buffer","June 2021","","" "`P1132R8 `__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","","" "`P1328R1 `__","LWG","Making std::type_info::operator== constexpr","June 2021","","" -"`P1425R4 `__","LWG","Iterators pair constructors for stack and queue","June 2021","","" +"`P1425R4 `__","LWG","Iterators pair constructors for stack and queue","June 2021","|Complete|","14.0","|ranges|" "`P1518R2 `__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0" -"`P1659R3 `__","LWG","starts_with and ends_with","June 2021","","" -"`P1951R1 `__","LWG","Default Arguments for pair Forwarding Constructor","June 2021","","" -"`P1989R2 `__","LWG","Range constructor for std::string_view","June 2021","","" +"`P1659R3 `__","LWG","starts_with and ends_with","June 2021","","","|ranges|" +"`P1951R1 `__","LWG","Default Arguments for pair Forwarding Constructor","June 2021","|Complete|","14.0" +"`P1989R2 `__","LWG","Range constructor for std::string_view","June 2021","|Complete|","14.0","|ranges|" "`P2136R3 `__","LWG","invoke_r","June 2021","","" "`P2166R1 `__","LWG","A Proposal to Prohibit std::basic_string and std::basic_string_view construction from nullptr","June 2021","|Complete|","13.0" -"","","","","","" \ No newline at end of file +"","","","","","","" +"`P0288R9 `__","LWG","``any_invocable``","October 2021","","" +"`P0798R8 `__","LWG","Monadic operations for ``std::optional``","October 2021","|Complete|","14.0" +"`P0849R8 `__","LWG","``auto(x)``: ``DECAY_COPY`` in the language","October 2021","|Complete|","14.0" +"`P1072R10 `__","LWG","``basic_string::resize_and_overwrite``","October 2021","|Complete|","14.0" +"`P1147R1 `__","LWG","Printing ``volatile`` Pointers","October 2021","|Complete|","14.0" +"`P1272R4 `__","LWG","Byteswapping for fun&&nuf","October 2021","|Complete|","14.0" +"`P1675R2 `__","LWG","``rethrow_exception`` must be allowed to copy","October 2021","","" +"`P2077R3 `__","LWG","Heterogeneous erasure overloads for associative containers","October 2021","","" +"`P2251R1 `__","LWG","Require ``span`` & ``basic_string_view`` to be Trivially Copyable","October 2021","|Complete|","14.0" +"`P2301R1 `__","LWG","Add a ``pmr`` alias for ``std::stacktrace``","October 2021","","" +"`P2321R2 `__","LWG","``zip``","October 2021","|In Progress|","","|ranges|" +"`P2340R1 `__","LWG","Clarifying the status of the 'C headers'","October 2021","","" +"`P2393R1 `__","LWG","Cleaning up ``integer``-class types","October 2021","","" +"`P2401R0 `__","LWG","Add a conditional ``noexcept`` specification to ``std::exchange``","October 2021","|Complete|","14.0" +"","","","","","","" +"`P0323R12 `__","LWG","``std::expected``","February 2022","|Complete|","16.0" +"`P0533R9 `__","LWG","``constexpr`` for ```` and ````","February 2022","|In progress| [#note-P0533R9]_","" +"`P0627R6 `__","LWG","Function to mark unreachable code","February 2022","|Complete|","15.0" +"`P1206R7 `__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","","","|ranges|" +"`P1413R3 `__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","|Complete| [#note-P1413R3]_","" +"`P2255R2 `__","LWG","A type trait to detect reference binding to temporary","February 2022","","" +"`P2273R3 `__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Complete|","16.0" +"`P2387R3 `__","LWG","Pipe support for user-defined range adaptors","February 2022","","","|ranges|" +"`P2440R1 `__","LWG","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","February 2022","","","|ranges|" +"`P2441R2 `__","LWG","``views::join_with``","February 2022","","","|ranges|" +"`P2442R1 `__","LWG","Windowing range adaptors: ``views::chunk`` and ``views::slide``","February 2022","","","|ranges|" +"`P2443R1 `__","LWG","``views::chunk_by``","February 2022","","","|ranges|" +"","","","","","","" +"`P0009R18 `__","LWG","mdspan: A Non-Owning Multidimensional Array Reference","July 2022","","" +"`P0429R9 `__","LWG","A Standard ``flat_map``","July 2022","","" +"`P1169R4 `__","LWG","``static operator()``","July 2022","|Complete|","16.0" +"`P1222R4 `__","LWG","A Standard ``flat_set``","July 2022","","" +"`P1223R5 `__","LWG","``ranges::find_last()``, ``ranges::find_last_if()``, and ``ranges::find_last_if_not()``","July 2022","","","|ranges|" +"`P1467R9 `__","LWG","Extended ``floating-point`` types and standard names","July 2022","","" +"`P1642R11 `__","LWG","Freestanding ``[utilities]``, ``[ranges]``, and ``[iterators]``","July 2022","","" +"`P1899R3 `__","LWG","``stride_view``","July 2022","","","|ranges|" +"`P2093R14 `__","LWG","Formatted output","July 2022","","" +"`P2165R4 `__","LWG","Compatibility between ``tuple``, ``pair`` and ``tuple-like`` objects","July 2022","","" +"`P2278R4 `__","LWG","``cbegin`` should always return a constant iterator","July 2022","","","|ranges|" +"`P2286R8 `__","LWG","Formatting Ranges","July 2022","|Complete|","16.0","|format| |ranges|" +"`P2291R3 `__","LWG","Add Constexpr Modifiers to Functions ``to_chars`` and ``from_chars`` for Integral Types in ```` Header","July 2022","|Complete|","16.0" +"`P2302R4 `__","LWG","``std::ranges::contains``","July 2022","","","|ranges|" +"`P2322R6 `__","LWG","``ranges::fold``","July 2022","","","|ranges|" +"`P2374R4 `__","LWG","``views::cartesian_product``","July 2022","","","|ranges|" +"`P2404R3 `__","LWG","Move-only types for ``equality_comparable_with``, ``totally_ordered_with``, and ``three_way_comparable_with``","July 2022","","" +"`P2408R5 `__","LWG","Ranges iterators as inputs to non-Ranges algorithms","July 2022","","","|ranges|" +"`P2417R2 `__","LWG","A more ``constexpr`` ``bitset``","July 2022","|Complete|","16.0" +"`P2419R2 `__","LWG","Clarify handling of encodings in localized formatting of chrono types","July 2022","","" +"`P2438R2 `__","LWG","``std::string::substr() &&``","July 2022","|Complete|","16.0" +"`P2445R1 `__","LWG","``forward_like``","July 2022","|Complete|","16.0" +"`P2446R2 `__","LWG","``views::as_rvalue``","July 2022","|Complete|","16.0","|ranges|" +"`P2460R2 `__","LWG","Relax requirements on ``wchar_t`` to match existing practices","July 2022","","" +"`P2465R3 `__","LWG","Standard Library Modules ``std`` and ``std.compat``","July 2022","","" +"`P2467R1 `__","LWG","Support exclusive mode for ``fstreams``","July 2022","","" +"`P2474R2 `__","LWG","``views::repeat``","July 2022","","","|ranges|" +"`P2494R2 `__","LWG","Relaxing range adaptors to allow for move only types","July 2022","","","|ranges|" +"`P2499R0 `__","LWG","``string_view`` range constructor should be ``explicit``","July 2022","|Complete|","16.0","|ranges|" +"`P2502R2 `__","LWG","``std::generator``: Synchronous Coroutine Generator for Ranges","July 2022","","","|ranges|" +"`P2508R1 `__","LWG","Exposing ``std::basic-format-string``","July 2022","|Complete|","15.0" +"`P2513R4 `__","LWG","``char8_t`` Compatibility and Portability Fixes","July 2022","","" +"`P2517R1 `__","LWG","Add a conditional ``noexcept`` specification to ``std::apply``","July 2022","","" +"`P2520R0 `__","LWG","``move_iterator`` should be a random access iterator","July 2022","","","|ranges|" +"`P2540R1 `__","LWG","Empty Product for certain Views","July 2022","","","|ranges|" +"`P2549R1 `__","LWG","``std::unexpected`` should have ``error()`` as member accessor","July 2022","|Complete|","16.0" +"`P2553R1 `__","LWG","Make ``mdspan`` ``size_type`` controllable","July 2022","","" +"`P2554R0 `__","LWG","C-Array Interoperability of MDSpan","July 2022","","" +"`P2585R0 `__","LWG","Improving default container formatting","July 2022","|Partial|","" +"`P2590R2 `__","LWG","Explicit lifetime management","July 2022","","" +"`P2599R2 `__","LWG","``mdspan::size_type`` should be ``index_type``","July 2022","","" +"`P2604R0 `__","LWG","mdspan: rename pointer and contiguous","July 2022","","" +"`P2613R1 `__","LWG","Add the missing ``empty`` to ``mdspan``","July 2022","","" +"","","","","","","" +"`P1202R5 `__","LWG", "Asymmetric Fences", "November 2022","","","|concurrency TS|" +"`P1264R2 `__","LWG", "Revising the wording of ``stream`` input operations", "November 2022","|Complete|","9.0","" +"`P1478R8 `__","LWG", "``Byte-wise`` ``atomic`` ``memcpy``", "November 2022","","","|concurrency TS|" +"`P2167R3 `__","LWG", "Improved Proposed Wording for LWG 2114", "November 2022","","","" +"`P2396R1 `__","LWG", "Concurrency TS 2 fixes ", "November 2022","","","|concurrency TS|" +"`P2505R5 `__","LWG", "Monadic Functions for ``std::expected``", "November 2022","","","" +"`P2539R4 `__","LWG", "Should the output of ``std::print`` to a terminal be synchronized with the underlying stream?", "November 2022","","","|format|" +"`P2602R2 `__","LWG", "Poison Pills are Too Toxic", "November 2022","","","|ranges|" +"`P2708R1 `__","LWG", "No Further Fundamentals TSes", "November 2022","|Nothing to do|","","" diff --git a/gnu/llvm/libcxx/docs/Status/Format.rst b/gnu/llvm/libcxx/docs/Status/Format.rst index 948b1b744ae..8203cc1a5f7 100644 --- a/gnu/llvm/libcxx/docs/Status/Format.rst +++ b/gnu/llvm/libcxx/docs/Status/Format.rst @@ -13,7 +13,7 @@ libc++ Format Status Overview ======== -This document contains the status of the C++20 Format library in libc++. It is used to +This document contains the status of the Format library in libc++. It is used to track both the status of the sub-projects of the Format library and who is assigned to these sub-projects. This is imperative to effective implementation so that work is not duplicated and implementors are not blocked by each other. @@ -39,10 +39,6 @@ Misc. Items and TODOs (Please mark all Format-related TODO comments with the string ``TODO FMT``, so we can find them easily.) - * C++23 may break the ABI with `P2216 `_. - This ABI break may be backported to C++20. Therefore the library will not - be available on platforms where the ABI break is an issue. - Paper and Issue Status ====================== diff --git a/gnu/llvm/libcxx/docs/Status/FormatIssues.csv b/gnu/llvm/libcxx/docs/Status/FormatIssues.csv index 7f4218d33f0..3299b6db66e 100644 --- a/gnu/llvm/libcxx/docs/Status/FormatIssues.csv +++ b/gnu/llvm/libcxx/docs/Status/FormatIssues.csv @@ -1,31 +1,17 @@ -Number,Name,Assignee,Patch,Status,First released version -`P0645 `_,"Text Formatting",Mark de Wever,,|partial|, -`P1652 `_,"Printf corner cases in std::format",Mark de Wever,`D103433 `__,Review, -`P1892 `_,"Extended locale-specific presentation specifiers for std::format",Mark de Wever,`D103368 `__,Review, -`P1868 `_,"width: clarifying units of width and precision in std::format (Implements the unicode support.)",Mark de Wever,"`D103413 `__ `D103425 `__ `D103670 `__",Review, -`P2216 `_,"std::format improvements",,,, -`LWG-3242 `_,"std::format: missing rules for arg-id in width and precision",Mark de Wever,`D103368 `__,Review, -`LWG-3243 `_,"std::format and negative zeroes",,,, -`LWG-3246 `_,"What are the constraints on the template parameter of basic_format_arg?",,,, -`LWG-3248 `_,"std::format #b, #B, #o, #x, and #X presentation types misformat negative numbers",Mark de Wever,`D103433 `__,Review, -`LWG-3250 `_,"std::format: # (alternate form) for NaN and inf",,,, -`LWG-3327 `_,"Format alignment specifiers vs. text direction",,,|Nothing To Do|, -`LWG-3340 `_,"Formatting functions should throw on argument/format string mismatch in [format.functions]",,,, -`LWG-3371 `_,"visit_format_arg and make_format_args are not hidden friends",Mark de Wever,`D103357 `__,Review, -`LWG-3372 `_,"vformat_to should not try to deduce Out twice",,,, -`LWG-3373 `_,"{to,from}_chars_result and format_to_n_result need the 'we really mean what we say'",,,, -`LWG-3462 `_,"§[formatter.requirements]: Formatter requirements forbid use of fc.arg()",,,, -`LWG-3539 `_,"format_to must not copy models of output_iterator",,,, -`LWG-3540 `_,"§[format.arg] There should be no const in basic_format_arg(const T* p)",,,, -`LWG-3541 `_,"indirectly_readable_traits should be SFINAE-friendly for all types",,,, -`LWG-3542 `_,"basic_format_arg mishandles basic_string_view with custom traits",,,, -`LWG-3544 `_,"format-arg-store::args is unintentionally not exposition-only",,,, +Number,Name,Standard,Assignee,Status,First released version +`P0645 `_,"Text Formatting","C++20",Mark de Wever,|Complete|,Clang 14 +`P1652 `_,"Printf corner cases in std::format","C++20",Mark de Wever,|Complete|,Clang 14 +`P1892 `_,"Extended locale-specific presentation specifiers for std::format","C++20",Mark de Wever,|Complete|,Clang 14 +`P1868 `_,"width: clarifying units of width and precision in std::format (Implements the unicode support.)","C++20",Mark de Wever,|Complete|,Clang 14 +`P2216 `_,"std::format improvements","C++20",Mark de Wever,|Complete|,Clang 15 +`P2418 `__,"Add support for ``std::generator``-like types to ``std::format``","C++20",Mark de Wever,|Complete|, Clang 15 +"`P2093R14 `__","Formatted output","C++23" +"`P2286R8 `__","Formatting Ranges","C++23","Mark de Wever","|Complete|",Clang 16 +"`P2508R1 `__","Exposing ``std::basic-format-string``","C++23","Mark de Wever","|Complete|", Clang 15 +"`P2585R0 `__","Improving default container formatting","C++23","Mark de Wever","|In progress|" +"`P2539R4 `__","Should the output of ``std::print`` to a terminal be synchronized with the underlying stream?","C++23" + +`P1361 `_,"Integration of chrono with text formatting","C++20",Mark de Wever,|In Progress|, +`P2372 `__,"Fixing locale handling in chrono formatters","C++20",Mark de Wever,|In Progress|, +"`P2419R2 `__","Clarify handling of encodings in localized formatting of chrono types","C++23", -`P1361 `_,"Integration of chrono with text formatting",,,, -`LWG-3218 `_,"Modifier for %d parse flag does not match POSIX and format specification",,,, -`LWG-3230 `_,"Format specifier %y/%Y is missing locale alternative versions",,,, -`LWG-3241 `_,"chrono-spec grammar ambiguity in [time.format]",,,, -`LWG-3262 `_,"Formatting of negative durations is not specified",,,, -`LWG-3270 `_,"Parsing and formatting %j with durations",,,, -`LWG-3272 `_,"%I%p should parse/format duration since midnight",,,, -`LWG-3332 `_,"Issue in [time.format]",,,, diff --git a/gnu/llvm/libcxx/docs/Status/FormatPaper.csv b/gnu/llvm/libcxx/docs/Status/FormatPaper.csv index afdf88355c5..01585c00130 100644 --- a/gnu/llvm/libcxx/docs/Status/FormatPaper.csv +++ b/gnu/llvm/libcxx/docs/Status/FormatPaper.csv @@ -1,48 +1,40 @@ -Section,Description,Dependencies,Assignee,Patch,Status,First released version -[charconv.to.chars],"Fix integral conformance",,Mark de Wever,`D100722 `__,|Complete|,Clang 13 -[charconv.to.chars],"Add floating-point conversion",`D100722 `__,"Mark de Wever (Code provided by Stephan T. Lavavej of Microsoft)",`D70631 `__,In progress, -[format.error],"Class format_error",,Mark de Wever,`D92214 `__,|Complete|,Clang 13 -[format.parse.ctx],"Class template basic_format_parse_context",,Mark de Wever,`D93166 `__,|Complete|,Clang 13 -[format.context],"Class template basic_format_context",,Mark de Wever,`D103357 `__,Review, -[format.args],"Class template basic_format_args",,Mark de Wever,`D103357 `__,Review, -[format.arg],"Class template basic_format_arg",,Mark de Wever,`D103357 `__,Review, -[format.arg],"Class template basic_format_arg - handle",,,,,, -[format.arg],"Class template basic_format_arg - pointers",,,,,, -[format.arg.store],"Class template format-arg-store",,Mark de Wever,`D103357 `__,Review, -[format.formatter.spec],"Formatter specializations - character types",,Mark de Wever,"`D96664 `__ `D103466 `__",Review, -[format.formatter.spec],"Formatter specializations - string types",,Mark de Wever,"`D96664 `__ `D103425 `__",Review, -[format.formatter.spec],"Formatter specializations - boolean type",,Mark de Wever,"`D96664 `__ `D103670 `__",Review, -[format.formatter.spec],"Formatter specializations - integral types",,Mark de Wever,"`D96664 `__ `D103433 `__",Review, -[format.formatter.spec],"Formatter specializations - floating-point types",`D70631 `__,Mark de Wever,`D96664 `__,Review, -[format.formatter.spec],"Formatter specializations - pointer types",,,,,, -[format.string.std],"Standard format specifiers - character types",,Mark de Wever,`D103368 `__,Review, -[format.string.std],"Standard format specifiers - string types",`D103379 `__,Mark de Wever,"`D103368 `__ `D103413 `__",Review, -[format.string.std],"Standard format specifiers - boolean type",`D103379 `__,Mark de Wever,"`D103368 `__ `D103413 `__",Review, -[format.string.std],"Standard format specifiers - integral types",,Mark de Wever,`D103368 `__,Review, -[format.string.std],"Standard format specifiers - floating-point types",,Mark de Wever,,,, -[format.string.std],"Standard format specifiers - pointer types",,Mark de Wever,,,, -[format.functions],"Format functions - format(string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - format(wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - format(const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - format(const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - vformat(string_view fmt, format_args args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - vformat(wstring_view fmt, wformat_args args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - vformat(const locale& loc, string_view fmt, format_args args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - vformat(const locale& loc, wstring_view fmt, wformat_args args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - format_to(Out out, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - vformat_to(Out out, string_view fmt, format_args_t, char> args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - vformat_to(Out out, wstring_view fmt, format_args_t, char> args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - vformat_to(Out out, const locale& loc, string_view fmt, format_args_t, char> args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - vformat_to(Out out, const locale& loc, wstring_view fmt,format_args_t, wchar_t> args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - format_to_n(Out out, iter_difference_t n, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - format_to_n(Out out, iter_difference_t n, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - formatted_size(string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - formatted_size(wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - formatted_size(const locale& loc, string_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - formatted_size(const locale& loc, wstring_view fmt, const Args&... args);",,Mark de Wever,`D96664 `__,Review, -[format.functions],"Format functions - Implement locale support",,Mark de Wever,,In progress,, -[format.functions],"Format functions - Improve performance format_to_n",,Mark de Wever,,,, -[format.functions],"Format functions - Improve performance formatted size",,Mark de Wever,,,, +Section,Description,Dependencies,Assignee,Status,First released version +`P1361 `__ `P2372 `__,"Formatting chrono" +`[time.syn] `_,"Formatter ``chrono::duration``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::sys_time``",,Mark de Wever,|In Progress|, +`[time.syn] `_,"Formatter ``chrono::utc_time``",A ```` implementation,Not assigned,,, +`[time.syn] `_,"Formatter ``chrono::tai_time``",A ```` implementation,Not assigned,,, +`[time.syn] `_,"Formatter ``chrono::gps_time``",A ```` implementation,Not assigned,,, +`[time.syn] `_,"Formatter ``chrono::file_time``",,Not assigned,,, +`[time.syn] `_,"Formatter ``chrono::local_time``",,Not assigned,,, +`[time.syn] `_,"Formatter ``chrono::local-time-format-t``",A ```` implementation,Not assigned,,, +`[time.syn] `_,"Formatter ``chrono::day``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::month``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::year``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::weekday``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::weekday_indexed``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::weekday_last``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::month_day``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::month_day_last``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::month_weekday``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::month_weekday_last``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::year_month``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::year_month_day``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::year_month_day_last``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::year_month_weekday``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::year_month_weekday_last``",,Mark de Wever,|Complete|, Clang 16 +`[time.syn] `_,"Formatter ``chrono::hh_mm_ss>``",,Mark de Wever,|In Progress|, +`[time.syn] `_,"Formatter ``chrono::sys_info``",A ```` implementation,Mark de Wever,, +`[time.syn] `_,"Formatter ``chrono::local_info``",A ```` implementation,Mark de Wever,, +`[time.syn] `_,"Formatter ``chrono::zoned_time``",A ```` implementation,Mark de Wever,, +`P2286R8 `__,"Formatting ranges" +`[format.syn] `_,"Concept ``formattable``",,Mark de Wever,|Complete|, Clang 16 +`[format.string.std] `_,"std-format-spec ``type`` debug",,Mark de Wever,|Complete|,Clang 16 +`[format.range] `_,"Formatting for ranges: sequences",,Mark de Wever,|Complete|,Clang 16 +`[format.range.fmtmap] `_,"Formatting for ranges: map",,Mark de Wever,|Complete|,Clang 16 +`[format.range.fmtset] `_,"Formatting for ranges: set",,Mark de Wever,|Complete|,Clang 16 +`[format.range] `_,"Formatting for ranges: container adaptors",,Mark de Wever,|Complete|,Clang 16 +`[format.range] `_,"Formatting for ranges: ``pair`` and ``tuple``",,Mark de Wever,|Complete|,Clang 16 +`[format.range] `_,"Formatting for ranges: ``vector``",,Mark de Wever,|Complete|,Clang 16 +"`P2585R0 `__","Improving default container formatting" +`[format.range.fmtstr] `_,"Formatting for ranges: strings",,Mark de Wever,|In Progress|, diff --git a/gnu/llvm/libcxx/docs/Status/Ranges.rst b/gnu/llvm/libcxx/docs/Status/Ranges.rst index 66b2ba375e0..af4300bb7ee 100644 --- a/gnu/llvm/libcxx/docs/Status/Ranges.rst +++ b/gnu/llvm/libcxx/docs/Status/Ranges.rst @@ -1,4 +1,4 @@ -.. ranges-status: +a. ranges-status: ================================ libc++ Ranges Status @@ -13,39 +13,36 @@ libc++ Ranges Status Overview ================================ -This document contains the status of the C++20 Ranges library in libc++. It is used to -track both the status of the sub-projects of the ranges library and who is assigned to -these sub-projects. This is imperative to effective implementation so that work is not +This document contains the status of the Ranges library in libc++. It is used to track +both the status of the sub-projects of the ranges library and who is assigned to these +sub-projects. This is imperative to effective implementation so that work is not duplicated and implementors are not blocked by each other. If you are interested in contributing to the libc++ Ranges library, please send a message to the #libcxx channel in the LLVM discord. Please *do not* start working on any of the -assigned items below. +*assigned* items below. -Sub-Projects in the One Ranges Proposal +Major features ======================================= .. csv-table:: - :file: RangesPaper.csv + :file: RangesMajorFeatures.csv :header-rows: 1 :widths: auto +Views +======================================= -Misc. Items and TODOs -==================================== - -(Note: files with required updates will contain the TODO at the beginning of the list item -so they can be easily found via global search.) - - * TODO(XX_SPACESHIP_CONCEPTS): when spaceship support is added to various STL types, we need to update some concept tests. - -Paper and Issue Status -==================================== +.. csv-table:: + :file: RangesViews.csv + :header-rows: 1 + :widths: auto -(Note: stolen from MSVC `here `_.) +Algorithms +======================================= .. csv-table:: - :file: RangesIssues.csv + :file: RangesAlgorithms.csv :header-rows: 1 - :widths: auto \ No newline at end of file + :widths: auto diff --git a/gnu/llvm/libcxx/docs/Status/RangesAlgorithms.csv b/gnu/llvm/libcxx/docs/Status/RangesAlgorithms.csv new file mode 100644 index 00000000000..6d63988ac65 --- /dev/null +++ b/gnu/llvm/libcxx/docs/Status/RangesAlgorithms.csv @@ -0,0 +1,12 @@ +Standard,Algorithm,Assignee,CL,Status +C++20,all C++20 algorithms,N/A,N/A,✅ +C++23,`find_last `_,Unassigned,No patch yet,Not started +C++23,`find_last_if `_,Unassigned,No patch yet,Not started +C++23,`find_last_if_not `_,Unassigned,No patch yet,Not started +C++23,`starts_with `_,Unassigned,No patch yet,Not started +C++23,`ends_with `_,Unassigned,No patch yet,Not started +C++23,`shift_left `_,Unassigned,No patch yet,Not started +C++23,`shift_right `_,Unassigned,No patch yet,Not started +C++23,`iota (algorithm) `_,Unassigned,No patch yet,Not started +C++23,`fold `_,Unassigned,No patch yet,Not started +C++23,`contains `_,Unassigned,No patch yet,Not started diff --git a/gnu/llvm/libcxx/docs/Status/RangesMajorFeatures.csv b/gnu/llvm/libcxx/docs/Status/RangesMajorFeatures.csv new file mode 100644 index 00000000000..d569f144e4e --- /dev/null +++ b/gnu/llvm/libcxx/docs/Status/RangesMajorFeatures.csv @@ -0,0 +1,4 @@ +Standard,Name,Assignee,CL,Status +C++23,`ranges::to `_,Unassigned,No patch yet,Not started +C++23,`Pipe support for user-defined range adaptors `_,Unassigned,No patch yet,Not started +C++23,`Formatting Ranges `_,Mark de Wever,Various,Complete diff --git a/gnu/llvm/libcxx/docs/Status/RangesViews.csv b/gnu/llvm/libcxx/docs/Status/RangesViews.csv new file mode 100644 index 00000000000..c3c318401b5 --- /dev/null +++ b/gnu/llvm/libcxx/docs/Status/RangesViews.csv @@ -0,0 +1,37 @@ +Standard,View,Assignee,CL,Status +C++20,`empty `_,Zoe Carver,`D103208 `_,✅ +C++20,`single `_,Zoe Carver,`D106840 `_,✅ +C++20,`iota (view) `_,Zoe Carver,`D107396 `_,✅ +C++20,`all `_,Zoe Carver,`D102028 `_,✅ +C++20,`ref_view `_,Zoe Carver,`D102020 `_,✅ +C++20,`owning_view `_,Arthur O'Dwyer,`D116894 `_,✅ +C++20,`filter `_,Louis Dionne,`D109086 `_,✅ +C++20,`transform `_,Zoe Carver,`D103056 `_,✅ +C++20,`take `_,Zoe Carver,`D106507 `_,✅ +C++20,`take_while `_,Hui Xie,`D134952 `_,✅ +C++20,`drop `_,Zoe Carver,`D102037 `_,✅ +C++20,`drop_while `_,Hui Xie,`D135460 `_,✅ +C++20,`join `_,Zoe Carver,`D107671 `_,✅ +C++20,`split `_,Hui Xie,`D142063 `_,✅ +C++20,`lazy_split `_,Zoe Carver and Konstantin Varlamov,`D107500 `_,✅ +C++20,`counted `_,Zoe Carver,`D106923 `_,✅ +C++20,`common `_,Zoe Carver,`D105753 `_,✅ +C++20,`reverse `_,Zoe Carver,`D107096 `_,✅ +C++20,`elements / keys / values `_,Hui Xie,`D136268 `_,✅ +C++20,`istream `_,Hui Xie,`D133317 `_,✅ +,,,, +,,,, +,,,, +C++23,`repeat `_,Unassigned,No patch yet,Not started +C++23,`cartesian_product `_,Unassigned,No patch yet,Not started +C++23,`zip `_,Hui Xie,`D122806 `_,✅ +C++23,`zip_transform `_,Hui Xie,No patch yet,Not started +C++23,`adjacent `_,Hui Xie,No patch yet,Not started +C++23,`adjacent_transform `_,Hui Xie,No patch yet,Not started +C++23,`join_with `_,Unassigned,No patch yet,Not started +C++23,`slide `_,Unassigned,No patch yet,Not started +C++23,`chunk `_,Unassigned,No patch yet,Not started +C++23,`chunk_by `_,Unassigned,No patch yet,Not started +C++23,`as_const `_,Unassigned,No patch yet,Not started +C++23,`as_rvalue `_,Nikolas Klauser,`D137637 `_,Complete +C++23,`stride `_,Unassigned,No patch yet,Not started diff --git a/gnu/llvm/libcxx/docs/Status/Spaceship.rst b/gnu/llvm/libcxx/docs/Status/Spaceship.rst new file mode 100644 index 00000000000..d596c1128db --- /dev/null +++ b/gnu/llvm/libcxx/docs/Status/Spaceship.rst @@ -0,0 +1,53 @@ +.. spaceship-status: + +============================================== +libc++ Spaceship Operator Status (operator<=>) +============================================== + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + + +Overview +================================ + +This document contains the status of the C++20 spaceship operator support +in libc++. It is used to track both the status of the sub-projects of the effort +and who is assigned to these sub-projects. This is imperative to effective +implementation so that work is not duplicated and implementors are not blocked +by each other. + +If you are interested in contributing to this effort, please send a message +to the #libcxx channel in the LLVM discord. Please *do not* start working on any +of the assigned items below. + + +Sub-Projects in the Implementation Effort +========================================= + +.. csv-table:: + :file: SpaceshipProjects.csv + :header-rows: 1 + :widths: auto + +.. note:: + + .. [#note-strongorder] ``std::strong_order(long double, long double)`` is not yet implemented. + + +Misc. Items and TODOs +==================================== + +(Note: files with required updates will contain the TODO at the beginning of the +list item so they can be easily found via global search.) + + +Paper and Issue Status +==================================== + +.. csv-table:: + :file: SpaceshipPapers.csv + :header-rows: 1 + :widths: auto diff --git a/gnu/llvm/libcxx/docs/Status/SpaceshipPapers.csv b/gnu/llvm/libcxx/docs/Status/SpaceshipPapers.csv new file mode 100644 index 00000000000..aab99286385 --- /dev/null +++ b/gnu/llvm/libcxx/docs/Status/SpaceshipPapers.csv @@ -0,0 +1,9 @@ +"Number","Name","Status","First released version" +`P1614R2 `_,The Mothership has Landed,|In Progress|, +`P2404R0 `_,"Relaxing equality_comparable_with's, totally_ordered_with's, and three_way_comparable_with's common reference requirements to support move-only types",, +`LWG3330 `_,Include from most library headers,"|Complete|","13.0" +`LWG3347 `_,"std::pair now requires T and U to be less-than-comparable",|Nothing To Do|, +`LWG3350 `_,Simplify return type of lexicographical_compare_three_way,|Nothing To Do|, +`LWG3360 `_,three_way_comparable_with is inconsistent with similar concepts,|Nothing To Do|, +`LWG3380 `_,common_type and comparison categories,|Nothing To Do|, +`LWG3395 `_,Definition for three-way comparison needs to be updated,|Nothing To Do|, diff --git a/gnu/llvm/libcxx/docs/Status/SpaceshipProjects.csv b/gnu/llvm/libcxx/docs/Status/SpaceshipProjects.csv new file mode 100644 index 00000000000..f732ec72211 --- /dev/null +++ b/gnu/llvm/libcxx/docs/Status/SpaceshipProjects.csv @@ -0,0 +1,81 @@ +Section,Description,Dependencies,Assignee,Complete +| `[cmp.concept] `_,"| `three_way_comparable `_ +| `three_way_comparable_with `_",None,Ruslan Arutyunyan,|Complete| +| `[cmp.result] `_,| `compare_three_way_result `_,None,Arthur O'Dwyer,|Complete| +| `[expos.only.func] `_,"| `synth-three-way `_ +| `synth-three-way-result `_",[cmp.concept],Kent Ross,|Complete| +| `[comparisons.three.way] `_,| `compare_three_way `_,[cmp.concept],Arthur O'Dwyer,|Complete| +| `[cmp.alg] `_,"| `strong_order `_ +| `weak_order `_ +| `partial_order `_ +| `strong_order_fallback `_ +| `weak_order_fallback `_ +| `partial_order_fallback `_",None,Arthur O'Dwyer,|Complete| [#note-strongorder]_ +| `[alg.three.way] `_,| `lexicographical_compare_three_way `_,[comparisons.three.way],Adrian Vogelsgesang,|In Progress| +| `[type.info] `_,| `typeinfo `_,None,Adrian Vogelsgesang,|Complete| +| `[coroutine.handle.compare] `_,| `coroutine_handle `_,[comparisons.three.way],Chuanqi Xu,|Complete| +| `[pairs.spec] `_,| `pair `_,[expos.only.func],Kent Ross,|Complete| +| `[syserr.errcat.nonvirtuals] `_,| `error_category `_,[comparisons.three.way],Adrian Vogelsgesang,|Complete| +| `[syserr.compare] `_,"| `error_code `_ +| `error_condition `_",None,Adrian Vogelsgesang,|Complete| +| `[tuple.rel] `_,| `tuple `_,[expos.only.func],Kent Ross,|Complete| +"| `[optional.relops] `_ +| `[optional.nullops] `_ +| `[optional.comp.with.t] `_","| optional +| nullopt",None,Kent Ross,|In Progress| +"| `[variant.relops] `_ +| `[variant.monostate.relops] `_","| `monostate `_ +| `variant `_",None,Kent Ross,|Complete| +| `[unique.ptr.special] `_,| `unique_ptr `_,[comparisons.three.way],Adrian Vogelsgesang,|Complete| +| `[util.smartptr.shared.cmp] `_,| `shared_ptr `_,[comparisons.three.way],Adrian Vogelsgesang,|Complete| +| `[type.index.members] `_,| `type_index `_,None,Adrian Vogelsgesang,|Complete| +| `[charconv.syn] `_,| `to_chars_result `_,None,Mark de Wever,|Complete| +| `[charconv.syn] `_,| `from_chars_result `_,None,Mark de Wever,|Complete| +| `[stacktrace.entry.cmp] `_,| stacktrace_entry,None,Unassigned,|Not Started| +| `[stacktrace.basic.cmp] `_,| basic_stacktrace,[alg.three.way],Unassigned,|Not Started| +| `[string.cmp] `_,| `basic_string `_,None,Mark de Wever,|Complete| +| `[string.view.comparison] `_,| `basic_string_view `_,None,Mark de Wever,|Complete| +| `[array.syn] `_ (`general `_),| `array `_,[expos.only.func],Adrian Vogelsgesang,|In Progress| +| `[deque.syn] `_ (`general `_),| deque,[expos.only.func],Unassigned,|Not Started| +| `[forward.list.syn] `_ (`general `_),| forward_list,[expos.only.func],Unassigned,|Not Started| +| `[list.syn] `_ (`general `_),| list,[expos.only.func],Unassigned,|Not Started| +| `[vector.syn] `_ (`general `_),| `vector `_,[expos.only.func],Adrian Vogelsgesang,|In Progress| +| `[associative.map.syn] `_ (`general `_),"| map +| multimap",[expos.only.func],Unassigned,|Not Started| +| `[associative.set.syn] `_ (`general `_),"| multiset +| set",[expos.only.func],Unassigned,|Not Started| +| `[queue.ops] `_,| queue,None,Unassigned,|Not Started| +| `[stack.ops] `_,| stack,None,Unassigned,|Not Started| +| `[reverse.iter.cmp] `_,| `reverse_iterator `_,None,Mikhail Maltsev,|Complete| +| `[move.iter.op.comp] `_,| move_iterator,None,Unassigned,|Not Started| +| `[counted.iter.cmp] `_,| counted_iterator,None,Unassigned,|Not Started| +| `[range.iota.iterator] `_,| `ranges::iota_view::iterator `_,[concepts.cmp],Arthur O'Dwyer,|Complete| +| `[range.transform.iterator] `_,| `ranges::transform_view::iterator `_,[concepts.cmp],Arthur O'Dwyer,|Complete| +| `[range.elements.iterator] `_,| ranges::elements_view::iterator,[concepts.cmp],Hui Xie,|Complete| +| `[time.duration.comparisons] `_, "chrono::duration", None, Mark de Wever, |Not Started| +| `[time.point.comparisons] `_, "chrono::time_point", None, Mark de Wever, |Not Started| +"| `[time.cal.day.nonmembers] `_ +| `[time.cal.month.nonmembers] `_ +| `[time.cal.year.nonmembers] `_ +| `[time.cal.md.nonmembers] `_ +| `[time.cal.mdlast] `_ +| `[time.cal.ym.nonmembers] `_ +| `[time.cal.ymd.nonmembers] `_ +| `[time.cal.ymdlast.nonmembers] `_","| `chrono::day `_ +| `chrono::month `_ +| `chrono::year `_ +| `chrono::month_day `_ +| `chrono::month_day_last `_ +| `chrono::year_month `_ +| `chrono::year_month_day `_ +| `chrono::year_month_day_last `_",None,Mark de Wever,|Complete| +"| `[time.zone.nonmembers] `_ +| `[time.zone.leap.nonmembers] `_ +| `[time.zone.link.nonmembers] `_","| chrono::time_zone +| chrono::leap_second +| chrono::time_zone_link",A ```` implementation,Unassigned,|Not Started| +| `[fs.filesystem.syn] `_,| `filesystem::space_info `_,None,Adrian Vogelsgesang,|Complete| +| `[fs.path.nonmember] `_,| `filesystem::path `_,None,Adrian Vogelsgesang,|Complete| +| `[fs.dir.entry.obs] `_,| `filesystem::directory_entry `_,None,Adrian Vogelsgesang,|Complete| +| `[re.submatch.op] `_,| sub_match,None,Mark de Wever,|In Progress| +| `[thread.thread.id] `_,| `thread::id `_,None,Adrian Vogelsgesang,|Complete| diff --git a/gnu/llvm/libcxx/docs/Status/Zip.rst b/gnu/llvm/libcxx/docs/Status/Zip.rst new file mode 100644 index 00000000000..db2cdfe2969 --- /dev/null +++ b/gnu/llvm/libcxx/docs/Status/Zip.rst @@ -0,0 +1,29 @@ +.. zip-status: + +=========================== +libc++ Zip Status (P2321R2) +=========================== + +.. include:: ../Helpers/Styles.rst + +.. contents:: + :local: + +Overview +======== + +This document contains the status of the C++2b zip implementation in libc++. +It is used to track both the status of the sub-projects of the effort and who +is assigned to these sub-projects. This avoids duplicating effort. + +If you are interested in contributing to this effort, please send a message +to the #libcxx channel in the LLVM discord. Please *do not* start working +on any items below that has already been assigned to someone else. + +Sub-projects in the Implementation Effort +========================================= + +.. csv-table:: + :file: ZipProjects.csv + :header-rows: 1 + :widths: auto diff --git a/gnu/llvm/libcxx/docs/Status/ZipProjects.csv b/gnu/llvm/libcxx/docs/Status/ZipProjects.csv new file mode 100644 index 00000000000..699a382ff66 --- /dev/null +++ b/gnu/llvm/libcxx/docs/Status/ZipProjects.csv @@ -0,0 +1,27 @@ +Section,Description,Dependencies,Assignee,Complete +| `[tuple.syn] `_, "`[tuple] basic_common_reference, common_type `_", None, Nikolas Klauser, |Complete| +| `[tuple.tuple] `_, "`[tuple] constructor, assignment and swap overloads `_", None, Hui Xie, |Complete| +| `[utility.syn] `_, "[pair] basic_common_reference, common_type", None, Nikolas Klauser, |Complete| +| `[pairs.pair] `_, "`[pair] constructor, assignment and swap overloads `_", None, Hui Xie, |Complete| +"| `[memory.syn] `_ +| `[allocator.uses.construction] `_", "[pair] uses_allocator_construction_args overloads", None, Nikolas Klauser, |Complete| +| `[vector.bool] `_, "[vector::reference] add const operator= overload", None, Hui Xie, |Not Started| +| `[iterator.concept.winc] `_, "Update weakly_comparable", None, Hui Xie, |Not Started| +| `[range.zip] `_, "`zip_view `_", "| `zip_view::iterator` +| `zip_view::sentinel`", Hui Xie, |Complete| +| `[range.zip.iterator] `_, "`zip_view::iterator `_", None, Hui Xie, |Complete| +| `[range.zip.sentinel] `_, "`zip_view::sentinel `_", None, Hui Xie, |Complete| +| `[range.zip.transform.view] `_, "zip_transform_view", "| `zip_transform_view::iterator` +| `zip_transform_view::sentinel`", Hui Xie, |Not Started| +| `[range.zip.transform.iterator] `_, "zip_transform_view::iterator", None, Hui Xie, |Not Started| +| `[range.zip.transform.sentinel] `_, "zip_transform_view::sentinel", None, Hui Xie, |Not Started| +| `[range.adjacent.view] `_, "adjacent_view", "| `adjacent_view::iterator` +| `adjacent_view::sentinel`", Hui Xie, |Not Started| +| `[range.adjacent.iterator] `_, "adjacent_view::iterator", None, unassigned, |Not Started| +| `[range.adjacent.sentinel] `_, "adjacent_view::sentinel", None, unassigned, |Not Started| +| `[range.adjacent.transform.view] `_, "adjacent_transform_view", "| `adjacent_transform_view::iterator`, +| `adjacent_transform_view::sentinel`", Hui Xie, |Not Started| +| `[range.adjacent.transform.iterator] `_, "adjacent_transform_view::iterator", None, Hui Xie, |Not Started| +| `[range.adjacent.transform.sentinel] `_, "adjacent_transform_view::sentinel", None, Hui Xie, |Not Started| +| `[ranges.syn] `_, "enable_borrowed_range zip_view and adjacent_view", "| `zip_view` +| `adjacent_view`", Hui Xie, |Not Started| diff --git a/gnu/llvm/libcxx/docs/TestingLibcxx.rst b/gnu/llvm/libcxx/docs/TestingLibcxx.rst index ddb8a6d09b5..283646aef4c 100644 --- a/gnu/llvm/libcxx/docs/TestingLibcxx.rst +++ b/gnu/llvm/libcxx/docs/TestingLibcxx.rst @@ -27,7 +27,7 @@ Usage After building libc++, you can run parts of the libc++ test suite by simply running ``llvm-lit`` on a specified test or directory. If you're unsure whether the required libraries have been built, you can use the -`cxx-test-depends` target. For example: +``cxx-test-depends`` target. For example: .. code-block:: bash @@ -37,45 +37,41 @@ whether the required libraries have been built, you can use the $ /bin/llvm-lit -sv libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp # Run a single test $ /bin/llvm-lit -sv libcxx/test/std/atomics libcxx/test/std/threads # Test std::thread and std::atomic +.. note:: + If you used the Bootstrapping build instead of the default runtimes build, the + ``cxx-test-depends`` target is instead named ``runtimes-test-depends``, and + you will need to prefix ``/runtimes/runtimes--bins/`` to the + paths of all tests. + In the default configuration, the tests are built against headers that form a fake installation root of libc++. This installation root has to be updated when -changes are made to the headers, so you should re-run the `cxx-test-depends` -target before running the tests manually with `lit` when you make any sort of +changes are made to the headers, so you should re-run the ``cxx-test-depends`` +target before running the tests manually with ``lit`` when you make any sort of change, including to the headers. Sometimes you'll want to change the way LIT is running the tests. Custom options -can be specified using the `--param==` flag. The most common option -you'll want to change is the standard dialect (ie -std=c++XX). By default the +can be specified using the ``--param =`` flag. The most common option +you'll want to change is the standard dialect (ie ``-std=c++XX``). By default the test suite will select the newest C++ dialect supported by the compiler and use -that. However if you want to manually specify the option like so: +that. However, you can manually specify the option like so if you want: .. code-block:: bash $ /bin/llvm-lit -sv libcxx/test/std/containers # Run the tests with the newest -std - $ /bin/llvm-lit -sv libcxx/test/std/containers --param=std=c++03 # Run the tests in C++03 - -Occasionally you'll want to add extra compile or link flags when testing. -You can do this as follows: - -.. code-block:: bash - - $ /bin/llvm-lit -sv libcxx/test --param=compile_flags='-Wcustom-warning' - $ /bin/llvm-lit -sv libcxx/test --param=link_flags='-L/custom/library/path' + $ /bin/llvm-lit -sv libcxx/test/std/containers --param std=c++03 # Run the tests in C++03 -Some other common examples include: +Other parameters are supported by the test suite. Those are defined in ``libcxx/utils/libcxx/test/params.py``. +If you want to customize how to run the libc++ test suite beyond what is available +in ``params.py``, you most likely want to use a custom site configuration instead. -.. code-block:: bash +The libc++ test suite works by loading a site configuration that defines various +"base" parameters (via Lit substitutions). These base parameters represent things +like the compiler to use for running the tests, which default compiler and linker +flags to use, and how to run an executable. This system is meant to be easily +extended for custom needs, in particular when porting the libc++ test suite to +new platforms. - # Specify a custom compiler. - $ /bin/llvm-lit -sv libcxx/test/std --param=cxx_under_test=/opt/bin/g++ - - # Disable warnings in the test suite - $ /bin/llvm-lit -sv libcxx/test --param=enable_warnings=False - - # Use UBSAN when running the tests. - $ /bin/llvm-lit -sv libcxx/test --param=use_sanitizer=Undefined - -Using a custom site configuration +Using a Custom Site Configuration --------------------------------- By default, the libc++ test suite will use a site configuration that matches @@ -96,90 +92,13 @@ configuration easier. $ make -C cxx-test-depends $ /bin/llvm-lit -sv libcxx/test # will use your custom config file +Additional tools +---------------- -LIT Options -=========== - -:program:`lit` [*options*...] [*filenames*...] - -Command Line Options --------------------- - -To use these options you pass them on the LIT command line as ``--param NAME`` -or ``--param NAME=VALUE``. Some options have default values specified during -CMake's configuration. Passing the option on the command line will override the -default. - -.. program:: lit - -.. option:: cxx_under_test= - - Specify the compiler used to build the tests. - -.. option:: stdlib= - - **Values**: libc++, libstdc++, msvc - - Specify the C++ standard library being tested. The default is libc++ if this - option is not provided. This option is intended to allow running the libc++ - test suite against other standard library implementations. - -.. option:: std= - - **Values**: c++03, c++11, c++14, c++17, c++20, c++2b - - Change the standard version used when building the tests. - -.. option:: cxx_headers= - - Specify the c++ standard library headers that are tested. By default the - headers in the source tree are used. - -.. option:: cxx_library_root= - - Specify the directory of the libc++ library to be tested. By default the - library folder of the build directory is used. - - -.. option:: cxx_runtime_root= - - Specify the directory of the libc++ library to use at runtime. This directory - is not added to the linkers search path. This can be used to compile tests - against one version of libc++ and run them using another. The default value - for this option is `cxx_library_root`. - -.. option:: use_system_cxx_lib= - - **Default**: False - - Enable or disable testing against the installed version of libc++ library. - This impacts whether the ``use_system_cxx_lib`` Lit feature is defined or - not. The ``cxx_library_root`` and ``cxx_runtime_root`` parameters should - still be used to specify the path of the library to link to and run against, - respectively. - -.. option:: debug_level= - - **Values**: 0, 1 - - Enable the use of debug mode. Level 0 enables assertions and level 1 enables - assertions and debugging of iterator misuse. - -.. option:: use_sanitizer= - - **Values**: Memory, MemoryWithOrigins, Address, Undefined - - Run the tests using the given sanitizer. If LLVM_USE_SANITIZER was given when - building libc++ then that sanitizer will be used by default. - -.. option:: llvm_unwinder - - Enable the use of LLVM unwinder instead of libgcc. - -.. option:: builtins_library - - Path to the builtins library to use instead of libgcc. +The libc++ test suite uses a few optional tools to improve the code quality. +These tools are: +- clang-tidy (you might need additional dev packages to compile libc++-specific clang-tidy checks) Writing Tests ------------- @@ -227,12 +146,11 @@ An example build would look like: .. code-block:: bash $ cd build - $ cmake [options] - $ make cxx-benchmarks + $ ninja cxx-benchmarks This will build all of the benchmarks under ``/benchmarks`` to be built against the just-built libc++. The compiled tests are output into -``build/benchmarks``. +``build/projects/libcxx/benchmarks``. The benchmarks can also be built against the platforms native standard library using the ``-DLIBCXX_BUILD_BENCHMARKS_NATIVE_STDLIB=ON`` CMake option. This @@ -255,8 +173,7 @@ For example: .. code-block:: bash - $ cd build/benchmarks - $ make cxx-benchmarks + $ cd build/projects/libcxx/benchmarks $ ./algorithms.libcxx.out # Runs all the benchmarks $ ./algorithms.libcxx.out --benchmark_filter=BM_Sort.* # Only runs the sort benchmarks diff --git a/gnu/llvm/libcxx/docs/UsingLibcxx.rst b/gnu/llvm/libcxx/docs/UsingLibcxx.rst index 863123688e6..3b64adb5f5a 100644 --- a/gnu/llvm/libcxx/docs/UsingLibcxx.rst +++ b/gnu/llvm/libcxx/docs/UsingLibcxx.rst @@ -34,28 +34,30 @@ matches that Standard in the library. library until the standard has been ratified. -Using libc++experimental and ```` -=================================================== +Enabling experimental C++ Library features +========================================== -Libc++ provides implementations of experimental technical specifications -in a separate library, ``libc++experimental.a``. Users of ```` -headers may be required to link ``-lc++experimental``. Note that not all -vendors ship ``libc++experimental.a``, and as a result, you may not be -able to use those experimental features. - -.. code-block:: bash - - $ clang++ test.cpp -lc++experimental +Libc++ provides implementations of some experimental features. Experimental features +are either Technical Specifications (TSes) or official features that were voted to +the Standard but whose implementation is not complete or stable yet in libc++. Those +are disabled by default because they are neither API nor ABI stable. However, the +``-fexperimental-library`` compiler flag can be defined to turn those features on. .. warning:: - Experimental libraries are Experimental. - * The contents of the ```` headers and ``libc++experimental.a`` + Experimental libraries are experimental. + * The contents of the ```` headers and the associated static library will not remain compatible between versions. * No guarantees of API or ABI stability are provided. * When the standardized version of an experimental feature is implemented, the experimental feature is removed two releases after the non-experimental version has shipped. The full policy is explained :ref:`here `. +.. note:: + On compilers that do not support the ``-fexperimental-library`` flag, users can + define the ``_LIBCPP_ENABLE_EXPERIMENTAL`` macro and manually link against the + appropriate static library (usually shipped as ``libc++experimental.a``) to get + access to experimental library features. + Using libc++ when it is not the system default ============================================== @@ -120,6 +122,106 @@ provide pretty-printers itself. Those can be used as: -ex "python register_libcxx_printer_loader()" \ +.. _include-what-you-use: + +include-what-you-use (IWYU) +=========================== + +libc++ provides an IWYU `mapping file `, +which drastically improves the accuracy of the tool when using libc++. To use the mapping file with +IWYU, you should run the tool like so: + +.. code-block:: bash + + $ include-what-you-use -Xiwyu /path/to/libcxx/include/libcxx.imp file.cpp + +If you would prefer to not use that flag, then you can replace ``/path/to/include-what-you-use/share/libcxx.imp``` +file with the libc++-provided ``libcxx.imp`` file. + +.. _assertions-mode: + +Enabling the "safe libc++" mode +=============================== + +Libc++ contains a number of assertions whose goal is to catch undefined behavior in the +library, usually caused by precondition violations. Those assertions do not aim to be +exhaustive -- instead they aim to provide a good balance between safety and performance. +In particular, these assertions do not change the complexity of algorithms. However, they +might, in some cases, interfere with compiler optimizations. + +By default, these assertions are turned off. Vendors can decide to turn them on while building +the compiled library by defining ``LIBCXX_ENABLE_ASSERTIONS=ON`` at CMake configuration time. +When ``LIBCXX_ENABLE_ASSERTIONS`` is used, the compiled library will be built with assertions +enabled, **and** user code will be built with assertions enabled by default. If +``LIBCXX_ENABLE_ASSERTIONS=OFF`` at CMake configure time, the compiled library will not contain +assertions and the default when building user code will be to have assertions disabled. +As a user, you can consult your vendor to know whether assertions are enabled by default. + +Furthermore, independently of any vendor-selected default, users can always control whether +assertions are enabled in their code by defining ``_LIBCPP_ENABLE_ASSERTIONS=0|1`` before +including any libc++ header (we recommend passing ``-D_LIBCPP_ENABLE_ASSERTIONS=X`` to the +compiler). Note that if the compiled library was built by the vendor without assertions, +functions compiled inside the static or shared library won't have assertions enabled even +if the user defines ``_LIBCPP_ENABLE_ASSERTIONS=1`` (the same is true for the inverse case +where the static or shared library was compiled **with** assertions but the user tries to +disable them). However, most of the code in libc++ is in the headers, so the user-selected +value for ``_LIBCPP_ENABLE_ASSERTIONS`` (if any) will usually be respected. + +When an assertion fails, the program is aborted through a special verbose termination function. The +library provides a default function that prints an error message and calls ``std::abort()``. Note +that this function is provided by the static or shared library, so it is only available when deploying +to a platform where the compiled library is sufficiently recent. On older platforms, the program will +terminate in an unspecified unsuccessful manner, but the quality of diagnostics won't be great. +However, users can also override that mechanism at two different levels. First, the mechanism can be +overriden at compile-time by defining the ``_LIBCPP_VERBOSE_ABORT(format, args...)`` variadic macro. +When that macro is defined, it will be called with a format string as the first argument, followed by +a series of arguments to format using printf-style formatting. Compile-time customization may be +interesting to get precise control over code generation, however it is also inconvenient to use in +some cases. Indeed, compile-time customization of the verbose termination function requires that all +translation units be compiled with a consistent definition for ``_LIBCPP_VERBOSE_ABORT`` to avoid ODR +violations, which can add complexity in the build system of users. + +Otherwise, if compile-time customization is not necessary, link-time customization of the handler is also +possible, similarly to how replacing ``operator new`` works. This mechanism trades off fine-grained control +over the call site where the termination is initiated in exchange for more ergonomics. Link-time customization +is done by simply defining the following function in exactly one translation unit of your program: + +.. code-block:: cpp + + void __libcpp_verbose_abort(char const* format, ...) + +This mechanism is similar to how one can replace the default definition of ``operator new`` +and ``operator delete``. For example: + +.. code-block:: cpp + + // In HelloWorldHandler.cpp + #include // must include any libc++ header before defining the function (C compatibility headers excluded) + + void std::__libcpp_verbose_abort(char const* format, ...) { + va_list list; + va_start(list, format); + std::vfprintf(stderr, format, list); + va_end(list); + + std::abort(); + } + + // In HelloWorld.cpp + #include + + int main() { + std::vector v; + int& x = v[0]; // Your termination function will be called here if _LIBCPP_ENABLE_ASSERTIONS=1 + } + +Also note that the verbose termination function should never return. Since assertions in libc++ +catch undefined behavior, your code will proceed with undefined behavior if your function is called +and does return. + +Furthermore, exceptions should not be thrown from the function. Indeed, many functions in the +library are ``noexcept``, and any exception thrown from the termination function will result +in ``std::terminate`` being called. Libc++ Configuration Macros =========================== @@ -128,9 +230,6 @@ Libc++ provides a number of configuration macros which can be used to enable or disable extended libc++ behavior, including enabling "debug mode" or thread safety annotations. -**_LIBCPP_DEBUG**: - See :ref:`using-debug-mode` for more information. - **_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS**: This macro is used to enable -Wthread-safety annotations on libc++'s ``std::mutex`` and ``std::lock_guard``. By default, these annotations are @@ -142,11 +241,6 @@ thread safety annotations. build of libc++ which does not export any symbols, which can be useful when building statically for inclusion into another library. -**_LIBCPP_DISABLE_EXTERN_TEMPLATE**: - This macro is used to disable extern template declarations in the libc++ - headers. The intended use case is for clients who wish to use the libc++ - headers without taking a dependency on the libc++ library itself. - **_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS**: This macro disables the additional diagnostics generated by libc++ using the `diagnose_if` attribute. These additional diagnostics include checks for: @@ -176,19 +270,9 @@ thread safety annotations. replacement scenarios from working, e.g. replacing `operator new` and expecting a non-replaced `operator new[]` to call the replaced `operator new`. -**_LIBCPP_ENABLE_NODISCARD**: - Allow the library to add ``[[nodiscard]]`` attributes to entities not specified - as ``[[nodiscard]]`` by the current language dialect. This includes - backporting applications of ``[[nodiscard]]`` from newer dialects and - additional extended applications at the discretion of the library. All - additional applications of ``[[nodiscard]]`` are disabled by default. - See :ref:`Extended Applications of [[nodiscard]] ` for - more information. - **_LIBCPP_DISABLE_NODISCARD_EXT**: - This macro prevents the library from applying ``[[nodiscard]]`` to entities - purely as an extension. See :ref:`Extended Applications of [[nodiscard]] ` - for more information. + This macro disables library-extensions of ``[[nodiscard]]``. + See :ref:`Extended Applications of [[nodiscard]] ` for more information. **_LIBCPP_DISABLE_DEPRECATION_WARNINGS**: This macro disables warnings when using deprecated components. For example, @@ -220,8 +304,8 @@ C++17 Specific Configuration Macros This macro is used to re-enable `set_unexpected`, `get_unexpected`, and `unexpected`. -C++20 Specific Configuration Macros: ------------------------------------- +C++20 Specific Configuration Macros +----------------------------------- **_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17**: This macro can be used to disable diagnostics emitted from functions marked ``[[nodiscard]]`` in dialects after C++17. See :ref:`Extended Applications of [[nodiscard]] ` @@ -236,6 +320,12 @@ C++20 Specific Configuration Macros: including `pointer`, `reference`, `rebind`, `address`, `max_size`, `construct`, `destroy`, and the two-argument overload of `allocate`. +**_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION**: + This macro is used to re-enable the library-provided specializations of + `allocator` and `allocator`. + Use it in conjunction with `_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS` + to ensure that removed members of `allocator` can be accessed. + **_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS**: This macro is used to re-enable the `argument_type`, `result_type`, `first_argument_type`, and `second_argument_type` members of class @@ -272,8 +362,8 @@ Users who want help diagnosing misuses of STL functions may desire a more liberal application of ``[[nodiscard]]``. For this reason libc++ provides an extension that does just that! The -extension must be enabled by defining ``_LIBCPP_ENABLE_NODISCARD``. The extended -applications of ``[[nodiscard]]`` takes two forms: +extension is enabled by default and can be disabled by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``. +The extended applications of ``[[nodiscard]]`` takes two forms: 1. Backporting ``[[nodiscard]]`` to entities declared as such by the standard in newer dialects, but not in the present one. @@ -281,17 +371,6 @@ applications of ``[[nodiscard]]`` takes two forms: 2. Extended applications of ``[[nodiscard]]``, at the library's discretion, applied to entities never declared as such by the standard. -Users may also opt-out of additional applications ``[[nodiscard]]`` using -additional macros. - -Applications of the first form, which backport ``[[nodiscard]]`` from a newer -dialect, may be disabled using macros specific to the dialect in which it was -added. For example, ``_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17``. - -Applications of the second form, which are pure extensions, may be disabled -by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``. - - Entities declared with ``_LIBCPP_NODISCARD_EXT`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -336,11 +415,105 @@ which no dialect declares as such (See the second form described above). * ``search`` * ``unique`` * ``upper_bound`` +* ``ranges::adjacent_find`` +* ``ranges::all_of`` +* ``ranges::any_of`` +* ``ranges::binary_search`` +* ``ranges::clamp`` +* ``ranges::count_if`` +* ``ranges::count`` +* ``ranges::equal_range`` +* ``ranges::equal`` +* ``ranges::find_end`` +* ``ranges::find_first_of`` +* ``ranges::find_if_not`` +* ``ranges::find_if`` +* ``ranges::find`` +* ``ranges::get_temporary_buffer`` +* ``ranges::includes`` +* ``ranges::is_heap_until`` +* ``ranges::is_heap`` +* ``ranges::is_partitioned`` +* ``ranges::is_permutation`` +* ``ranges::is_sorted_until`` +* ``ranges::is_sorted`` +* ``ranges::lexicographical_compare`` +* ``ranges::lower_bound`` +* ``ranges::max_element`` +* ``ranges::max`` +* ``ranges::min_element`` +* ``ranges::min`` +* ``ranges::minmax_element`` +* ``ranges::minmax`` +* ``ranges::mismatch`` +* ``ranges::none_of`` +* ``ranges::remove_if`` +* ``ranges::remove`` +* ``ranges::search_n`` +* ``ranges::search`` +* ``ranges::unique`` +* ``ranges::upper_bound`` * ``lock_guard``'s constructors * ``as_const`` +* ``bit_cast`` * ``forward`` * ``move`` * ``move_if_noexcept`` * ``identity::operator()`` * ``to_integer`` * ``to_underlying`` +* ``signbit`` +* ``fpclassify`` +* ``isfinite`` +* ``isinf`` +* ``isnan`` +* ``isnormal`` +* ``isgreater`` +* ``isgreaterequal`` +* ``isless`` +* ``islessequal`` +* ``islessgreater`` +* ``isunordered`` +* ``ceil`` +* ``fabs`` +* ``floor`` +* ``cbrt`` +* ``copysign`` +* ``fmax`` +* ``fmin`` +* ``nearbyint`` +* ``rint`` +* ``round`` +* ``trunc`` + +Extended integral type support +------------------------------ + +Several platforms support types that are not specified in the Standard, such as +the 128-bit integral types ``__int128_t`` and ``__uint128_t``. As an extension, +libc++ does a best-effort attempt to support these types like other integral +types, by supporting them notably in: + +* ```` +* ```` +* ```` +* ```` +* ```` +* ```` + +Additional types supported in random distributions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The `C++ Standard `_ mentions that instantiating several random number +distributions with types other than ``short``, ``int``, ``long``, ``long long``, and their unsigned versions is +undefined. As an extension, libc++ supports instantiating ``binomial_distribution``, ``discrete_distribution``, +``geometric_distribution``, ``negative_binomial_distribution``, ``poisson_distribution``, and ``uniform_int_distribution`` +with ``int8_t``, ``__int128_t`` and their unsigned versions. + +Extensions to ```` +-------------------------- + +The exposition only type ``basic-format-string`` and its typedefs +``format-string`` and ``wformat-string`` became ``basic_format_string``, +``format_string``, and ``wformat_string`` in C++23. Libc++ makes these types +available in C++20 as an extension. diff --git a/gnu/llvm/libcxx/docs/conf.py b/gnu/llvm/libcxx/docs/conf.py index f3c904c8efc..12876d18256 100644 --- a/gnu/llvm/libcxx/docs/conf.py +++ b/gnu/llvm/libcxx/docs/conf.py @@ -48,9 +48,9 @@ copyright = u'2011-%d, LLVM Project' % date.today().year # built documents. # # The short X.Y version. -version = '13.0' +version = '16.0' # The full version, including alpha/beta/rc tags. -release = '13.0' +release = '16.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/gnu/llvm/libcxx/docs/index.rst b/gnu/llvm/libcxx/docs/index.rst index c52e42b146b..265d23cc900 100644 --- a/gnu/llvm/libcxx/docs/index.rst +++ b/gnu/llvm/libcxx/docs/index.rst @@ -43,8 +43,10 @@ Getting Started with libc++ Status/Cxx17 Status/Cxx20 Status/Cxx2b - Status/Ranges Status/Format + Status/Ranges + Status/Spaceship + Status/Zip .. toctree:: @@ -91,7 +93,7 @@ reasons, but some of the major ones are: Further, both projects are apparently abandoned: STLport 5.2.1 was released in Oct'08, and STDCXX 4.2.1 in May'08. -.. _platform_and_compiler_support: +.. _SupportedPlatforms: Platform and Compiler Support ============================= @@ -103,9 +105,10 @@ velocity, libc++ drops support for older compilers as newer ones are released. ============ =============== ========================== ===================== Compiler Versions Restrictions Support policy ============ =============== ========================== ===================== -Clang 11, 12 latest two stable releases per `LLVM's release page `_ -AppleClang 12 latest stable release per `Xcode's release page `_ -GCC 11 In C++11 or later only latest stable release per `GCC's release page `_ +Clang 14, 15, 16-git latest two stable releases per `LLVM's release page `_ and the development version +AppleClang 14 latest stable release per `Xcode's release page `_ +Open XL 17.1 (AIX) latest stable release per `Open XL's documentation page `_ +GCC 12 In C++11 or later only latest stable release per `GCC's release page `_ ============ =============== ========================== ===================== Libc++ also supports common platforms and architectures: @@ -116,7 +119,8 @@ Target platform Target architecture Notes macOS 10.9+ i386, x86_64, arm64 Building the shared library itself requires targetting macOS 10.11+ FreeBSD 10+ i386, x86_64, arm Linux i386, x86_64, arm, arm64 -Windows x86_64 +Windows i386, x86_64 Both MSVC and MinGW style environments +AIX powerpc, powerpc64 =============== ========================= ============================ Generally speaking, libc++ should work on any platform that provides a fairly complete @@ -129,8 +133,8 @@ for all the platforms and compilers that we claim to support. If a platform or c is not listed here, it is not officially supported. It may happen to work, and in practice the library is known to work on some platforms not listed here, but we don't make any guarantees. If you would like your compiler and/or platform -to be formally supported and listed here, -please work with the libc++ team to set up testing for your configuration. +to be formally supported and listed here, please work with the libc++ team to set +up testing for your configuration. C++ Dialect Support @@ -155,7 +159,7 @@ This list contains known issues with libc++ A full list of currently open libc++ bugs can be `found here`__. -.. __: https://bugs.llvm.org/buglist.cgi?component=All%20Bugs&product=libc%2B%2B&query_format=advanced&resolution=---&order=changeddate%20DESC%2Cassigned_to%20DESC%2Cbug_status%2Cpriority%2Cbug_id&list_id=74184 +.. __: https://github.com/llvm/llvm-project/labels/libc%2B%2B Design Documents @@ -172,9 +176,11 @@ Design Documents DesignDocs/ExtendedCXX03Support DesignDocs/FeatureTestMacros DesignDocs/FileTimeType + DesignDocs/HeaderRemovalPolicy DesignDocs/NoexceptPolicy DesignDocs/ThreadingSupportAPI DesignDocs/UniquePtrTrivialAbi + DesignDocs/UnspecifiedBehaviorRandomization DesignDocs/VisibilityMacros @@ -182,7 +188,7 @@ Build Bots and Test Coverage ============================ * `Buildkite CI pipeline `_ -* `LLVM Buildbot Builders `_ +* `LLVM Buildbot Builders `_ * :ref:`Adding New CI Jobs ` @@ -195,26 +201,25 @@ and `Getting started with LLVM `__. **Bug Reports** If you think you've found a bug in libc++, please report it using -the `LLVM Bugzilla`_. If you're not sure, you -can post a message to the `libcxx-dev mailing list`_ or on IRC. +the `LLVM bug tracker`_. If you're not sure, you +can ask for support on the `libcxx forum`_ or on IRC. **Patches** If you want to contribute a patch to libc++, the best place for that is `Phabricator `_. Please add `libcxx-commits` as a subscriber. -Also make sure you are subscribed to the `libcxx-commits mailing list `_. +Also make sure you are subscribed to the `libcxx-commits mailing list`_. **Discussion and Questions** -Send discussions and questions to the -`libcxx-dev mailing list `_. +Send discussions and questions to the `libcxx forum`_. Quick Links =========== * `LLVM Homepage `_ * `libc++abi Homepage `_ -* `LLVM Bugzilla `_ -* `libcxx-commits Mailing List`_ -* `libcxx-dev Mailing List`_ +* `LLVM Bug Tracker `_ +* `libcxx-commits Mailing List `_ +* `libcxx Forum `_ * `Browse libc++ Sources `_ diff --git a/gnu/llvm/libcxx/include/CMakeLists.txt b/gnu/llvm/libcxx/include/CMakeLists.txt index 5fba7607756..a12aa1de135 100644 --- a/gnu/llvm/libcxx/include/CMakeLists.txt +++ b/gnu/llvm/libcxx/include/CMakeLists.txt @@ -4,76 +4,172 @@ set(files __algorithm/any_of.h __algorithm/binary_search.h __algorithm/clamp.h - __algorithm/comp_ref_type.h __algorithm/comp.h + __algorithm/comp_ref_type.h + __algorithm/copy.h __algorithm/copy_backward.h __algorithm/copy_if.h + __algorithm/copy_move_common.h __algorithm/copy_n.h - __algorithm/copy.h - __algorithm/count_if.h __algorithm/count.h - __algorithm/equal_range.h + __algorithm/count_if.h __algorithm/equal.h - __algorithm/fill_n.h + __algorithm/equal_range.h __algorithm/fill.h + __algorithm/fill_n.h + __algorithm/find.h __algorithm/find_end.h __algorithm/find_first_of.h - __algorithm/find_if_not.h __algorithm/find_if.h - __algorithm/find.h - __algorithm/for_each_n.h + __algorithm/find_if_not.h __algorithm/for_each.h - __algorithm/generate_n.h + __algorithm/for_each_n.h __algorithm/generate.h + __algorithm/generate_n.h __algorithm/half_positive.h + __algorithm/in_found_result.h + __algorithm/in_fun_result.h + __algorithm/in_in_out_result.h + __algorithm/in_in_result.h + __algorithm/in_out_out_result.h + __algorithm/in_out_result.h __algorithm/includes.h __algorithm/inplace_merge.h - __algorithm/is_heap_until.h __algorithm/is_heap.h + __algorithm/is_heap_until.h __algorithm/is_partitioned.h __algorithm/is_permutation.h - __algorithm/is_sorted_until.h __algorithm/is_sorted.h + __algorithm/is_sorted_until.h __algorithm/iter_swap.h + __algorithm/iterator_operations.h __algorithm/lexicographical_compare.h __algorithm/lower_bound.h __algorithm/make_heap.h - __algorithm/max_element.h + __algorithm/make_projected.h __algorithm/max.h + __algorithm/max_element.h __algorithm/merge.h - __algorithm/min_element.h __algorithm/min.h - __algorithm/minmax_element.h + __algorithm/min_element.h + __algorithm/min_max_result.h __algorithm/minmax.h + __algorithm/minmax_element.h __algorithm/mismatch.h - __algorithm/move_backward.h __algorithm/move.h + __algorithm/move_backward.h __algorithm/next_permutation.h __algorithm/none_of.h __algorithm/nth_element.h - __algorithm/partial_sort_copy.h __algorithm/partial_sort.h + __algorithm/partial_sort_copy.h + __algorithm/partition.h __algorithm/partition_copy.h __algorithm/partition_point.h - __algorithm/partition.h __algorithm/pop_heap.h __algorithm/prev_permutation.h __algorithm/push_heap.h - __algorithm/remove_copy_if.h + __algorithm/ranges_adjacent_find.h + __algorithm/ranges_all_of.h + __algorithm/ranges_any_of.h + __algorithm/ranges_binary_search.h + __algorithm/ranges_clamp.h + __algorithm/ranges_copy.h + __algorithm/ranges_copy_backward.h + __algorithm/ranges_copy_if.h + __algorithm/ranges_copy_n.h + __algorithm/ranges_count.h + __algorithm/ranges_count_if.h + __algorithm/ranges_equal.h + __algorithm/ranges_equal_range.h + __algorithm/ranges_fill.h + __algorithm/ranges_fill_n.h + __algorithm/ranges_find.h + __algorithm/ranges_find_end.h + __algorithm/ranges_find_first_of.h + __algorithm/ranges_find_if.h + __algorithm/ranges_find_if_not.h + __algorithm/ranges_for_each.h + __algorithm/ranges_for_each_n.h + __algorithm/ranges_generate.h + __algorithm/ranges_generate_n.h + __algorithm/ranges_includes.h + __algorithm/ranges_inplace_merge.h + __algorithm/ranges_is_heap.h + __algorithm/ranges_is_heap_until.h + __algorithm/ranges_is_partitioned.h + __algorithm/ranges_is_permutation.h + __algorithm/ranges_is_sorted.h + __algorithm/ranges_is_sorted_until.h + __algorithm/ranges_iterator_concept.h + __algorithm/ranges_lexicographical_compare.h + __algorithm/ranges_lower_bound.h + __algorithm/ranges_make_heap.h + __algorithm/ranges_max.h + __algorithm/ranges_max_element.h + __algorithm/ranges_merge.h + __algorithm/ranges_min.h + __algorithm/ranges_min_element.h + __algorithm/ranges_minmax.h + __algorithm/ranges_minmax_element.h + __algorithm/ranges_mismatch.h + __algorithm/ranges_move.h + __algorithm/ranges_move_backward.h + __algorithm/ranges_next_permutation.h + __algorithm/ranges_none_of.h + __algorithm/ranges_nth_element.h + __algorithm/ranges_partial_sort.h + __algorithm/ranges_partial_sort_copy.h + __algorithm/ranges_partition.h + __algorithm/ranges_partition_copy.h + __algorithm/ranges_partition_point.h + __algorithm/ranges_pop_heap.h + __algorithm/ranges_prev_permutation.h + __algorithm/ranges_push_heap.h + __algorithm/ranges_remove.h + __algorithm/ranges_remove_copy.h + __algorithm/ranges_remove_copy_if.h + __algorithm/ranges_remove_if.h + __algorithm/ranges_replace.h + __algorithm/ranges_replace_copy.h + __algorithm/ranges_replace_copy_if.h + __algorithm/ranges_replace_if.h + __algorithm/ranges_reverse.h + __algorithm/ranges_reverse_copy.h + __algorithm/ranges_rotate.h + __algorithm/ranges_rotate_copy.h + __algorithm/ranges_sample.h + __algorithm/ranges_search.h + __algorithm/ranges_search_n.h + __algorithm/ranges_set_difference.h + __algorithm/ranges_set_intersection.h + __algorithm/ranges_set_symmetric_difference.h + __algorithm/ranges_set_union.h + __algorithm/ranges_shuffle.h + __algorithm/ranges_sort.h + __algorithm/ranges_sort_heap.h + __algorithm/ranges_stable_partition.h + __algorithm/ranges_stable_sort.h + __algorithm/ranges_swap_ranges.h + __algorithm/ranges_transform.h + __algorithm/ranges_unique.h + __algorithm/ranges_unique_copy.h + __algorithm/ranges_upper_bound.h + __algorithm/remove.h __algorithm/remove_copy.h + __algorithm/remove_copy_if.h __algorithm/remove_if.h - __algorithm/remove.h - __algorithm/replace_copy_if.h + __algorithm/replace.h __algorithm/replace_copy.h + __algorithm/replace_copy_if.h __algorithm/replace_if.h - __algorithm/replace.h - __algorithm/reverse_copy.h __algorithm/reverse.h - __algorithm/rotate_copy.h + __algorithm/reverse_copy.h __algorithm/rotate.h + __algorithm/rotate_copy.h __algorithm/sample.h - __algorithm/search_n.h __algorithm/search.h + __algorithm/search_n.h __algorithm/set_difference.h __algorithm/set_intersection.h __algorithm/set_symmetric_difference.h @@ -82,34 +178,167 @@ set(files __algorithm/shift_right.h __algorithm/shuffle.h __algorithm/sift_down.h - __algorithm/sort_heap.h __algorithm/sort.h + __algorithm/sort_heap.h __algorithm/stable_partition.h __algorithm/stable_sort.h __algorithm/swap_ranges.h __algorithm/transform.h - __algorithm/unique_copy.h + __algorithm/uniform_random_bit_generator_adaptor.h __algorithm/unique.h + __algorithm/unique_copy.h __algorithm/unwrap_iter.h + __algorithm/unwrap_range.h __algorithm/upper_bound.h + __assert __availability + __bit/bit_cast.h + __bit/bit_ceil.h + __bit/bit_floor.h + __bit/bit_log2.h + __bit/bit_width.h + __bit/blsr.h + __bit/byteswap.h + __bit/countl.h + __bit/countr.h + __bit/endian.h + __bit/has_single_bit.h + __bit/popcount.h + __bit/rotate.h __bit_reference - __bits __bsd_locale_defaults.h __bsd_locale_fallbacks.h + __charconv/chars_format.h + __charconv/from_chars_result.h + __charconv/tables.h + __charconv/to_chars_base_10.h + __charconv/to_chars_result.h + __chrono/calendar.h + __chrono/convert_to_timespec.h + __chrono/convert_to_tm.h + __chrono/day.h + __chrono/duration.h + __chrono/file_clock.h + __chrono/formatter.h + __chrono/hh_mm_ss.h + __chrono/high_resolution_clock.h + __chrono/literals.h + __chrono/month.h + __chrono/month_weekday.h + __chrono/monthday.h + __chrono/ostream.h + __chrono/parser_std_format_spec.h + __chrono/statically_widen.h + __chrono/steady_clock.h + __chrono/system_clock.h + __chrono/time_point.h + __chrono/weekday.h + __chrono/year.h + __chrono/year_month.h + __chrono/year_month_day.h + __chrono/year_month_weekday.h + __compare/common_comparison_category.h + __compare/compare_partial_order_fallback.h + __compare/compare_strong_order_fallback.h + __compare/compare_three_way.h + __compare/compare_three_way_result.h + __compare/compare_weak_order_fallback.h + __compare/is_eq.h + __compare/ordering.h + __compare/partial_order.h + __compare/strong_order.h + __compare/synth_three_way.h + __compare/three_way_comparable.h + __compare/weak_order.h + __concepts/arithmetic.h + __concepts/assignable.h + __concepts/boolean_testable.h + __concepts/class_or_enum.h + __concepts/common_reference_with.h + __concepts/common_with.h + __concepts/constructible.h + __concepts/convertible_to.h + __concepts/copyable.h + __concepts/derived_from.h + __concepts/destructible.h + __concepts/different_from.h + __concepts/equality_comparable.h + __concepts/invocable.h + __concepts/movable.h + __concepts/predicate.h + __concepts/regular.h + __concepts/relation.h + __concepts/same_as.h + __concepts/semiregular.h + __concepts/swappable.h + __concepts/totally_ordered.h __config + __coroutine/coroutine_handle.h + __coroutine/coroutine_traits.h + __coroutine/noop_coroutine_handle.h + __coroutine/trivial_awaitables.h __debug + __debug_utils/randomize_range.h __errc + __expected/bad_expected_access.h + __expected/expected.h + __expected/unexpect.h + __expected/unexpected.h + __filesystem/copy_options.h + __filesystem/directory_entry.h + __filesystem/directory_iterator.h + __filesystem/directory_options.h + __filesystem/file_status.h + __filesystem/file_time_type.h + __filesystem/file_type.h + __filesystem/filesystem_error.h + __filesystem/operations.h + __filesystem/path.h + __filesystem/path_iterator.h + __filesystem/perm_options.h + __filesystem/perms.h + __filesystem/recursive_directory_iterator.h + __filesystem/space_info.h + __filesystem/u8path.h + __format/buffer.h + __format/concepts.h + __format/container_adaptor.h + __format/enable_insertable.h + __format/escaped_output_table.h + __format/extended_grapheme_cluster_table.h + __format/format_arg.h + __format/format_arg_store.h + __format/format_args.h + __format/format_context.h __format/format_error.h + __format/format_functions.h + __format/format_fwd.h __format/format_parse_context.h - __function_like.h - __functional_base + __format/format_string.h + __format/format_to_n_result.h + __format/formatter.h + __format/formatter_bool.h + __format/formatter_char.h + __format/formatter_floating_point.h + __format/formatter_integer.h + __format/formatter_integral.h + __format/formatter_output.h + __format/formatter_pointer.h + __format/formatter_string.h + __format/formatter_tuple.h + __format/parser_std_format_spec.h + __format/range_default_formatter.h + __format/range_formatter.h + __format/unicode.h __functional/binary_function.h __functional/binary_negate.h - __functional/bind_front.h __functional/bind.h + __functional/bind_back.h + __functional/bind_front.h __functional/binder1st.h __functional/binder2nd.h + __functional/boyer_moore_searcher.h + __functional/compose.h __functional/default_searcher.h __functional/function.h __functional/hash.h @@ -129,10 +358,22 @@ set(files __functional/unary_negate.h __functional/unwrap_ref.h __functional/weak_result_type.h + __fwd/array.h + __fwd/get.h + __fwd/hash.h + __fwd/memory_resource.h + __fwd/pair.h + __fwd/span.h + __fwd/string.h + __fwd/string_view.h + __fwd/subrange.h + __fwd/tuple.h __hash_table + __ios/fpos.h __iterator/access.h __iterator/advance.h __iterator/back_insert_iterator.h + __iterator/bounded_iter.h __iterator/common_iterator.h __iterator/concepts.h __iterator/counted_iterator.h @@ -143,107 +384,344 @@ set(files __iterator/erase_if_container.h __iterator/front_insert_iterator.h __iterator/incrementable_traits.h + __iterator/indirectly_comparable.h __iterator/insert_iterator.h __iterator/istream_iterator.h __iterator/istreambuf_iterator.h __iterator/iter_move.h __iterator/iter_swap.h - __iterator/iterator_traits.h __iterator/iterator.h + __iterator/iterator_traits.h + __iterator/iterator_with_data.h + __iterator/mergeable.h __iterator/move_iterator.h + __iterator/move_sentinel.h __iterator/next.h __iterator/ostream_iterator.h __iterator/ostreambuf_iterator.h + __iterator/permutable.h __iterator/prev.h __iterator/projected.h __iterator/readable_traits.h __iterator/reverse_access.h __iterator/reverse_iterator.h + __iterator/segmented_iterator.h __iterator/size.h + __iterator/sortable.h + __iterator/unreachable_sentinel.h __iterator/wrap_iter.h - __libcpp_version __locale + __mbstate_t.h __memory/addressof.h + __memory/align.h + __memory/allocate_at_least.h __memory/allocation_guard.h + __memory/allocator.h __memory/allocator_arg_t.h + __memory/allocator_destructor.h __memory/allocator_traits.h - __memory/allocator.h + __memory/assume_aligned.h __memory/auto_ptr.h + __memory/builtin_new_allocator.h __memory/compressed_pair.h + __memory/concepts.h __memory/construct_at.h - __memory/pointer_safety.h + __memory/destruct_n.h __memory/pointer_traits.h + __memory/ranges_construct_at.h + __memory/ranges_uninitialized_algorithms.h __memory/raw_storage_iterator.h __memory/shared_ptr.h + __memory/swap_allocator.h + __memory/temp_value.h __memory/temporary_buffer.h __memory/uninitialized_algorithms.h __memory/unique_ptr.h __memory/uses_allocator.h + __memory/uses_allocator_construction.h + __memory/voidify.h + __memory_resource/memory_resource.h + __memory_resource/monotonic_buffer_resource.h + __memory_resource/polymorphic_allocator.h + __memory_resource/pool_options.h + __memory_resource/synchronized_pool_resource.h + __memory_resource/unsynchronized_pool_resource.h __mutex_base __node_handle - __nullptr + __numeric/accumulate.h + __numeric/adjacent_difference.h + __numeric/exclusive_scan.h + __numeric/gcd_lcm.h + __numeric/inclusive_scan.h + __numeric/inner_product.h + __numeric/iota.h + __numeric/midpoint.h + __numeric/partial_sum.h + __numeric/reduce.h + __numeric/transform_exclusive_scan.h + __numeric/transform_inclusive_scan.h + __numeric/transform_reduce.h + __random/bernoulli_distribution.h + __random/binomial_distribution.h + __random/cauchy_distribution.h + __random/chi_squared_distribution.h + __random/clamp_to_integral.h + __random/default_random_engine.h + __random/discard_block_engine.h + __random/discrete_distribution.h + __random/exponential_distribution.h + __random/extreme_value_distribution.h + __random/fisher_f_distribution.h + __random/gamma_distribution.h + __random/generate_canonical.h + __random/geometric_distribution.h + __random/independent_bits_engine.h + __random/is_seed_sequence.h + __random/is_valid.h + __random/knuth_b.h + __random/linear_congruential_engine.h + __random/log2.h + __random/lognormal_distribution.h + __random/mersenne_twister_engine.h + __random/negative_binomial_distribution.h + __random/normal_distribution.h + __random/piecewise_constant_distribution.h + __random/piecewise_linear_distribution.h + __random/poisson_distribution.h + __random/random_device.h + __random/ranlux.h + __random/seed_seq.h + __random/shuffle_order_engine.h + __random/student_t_distribution.h + __random/subtract_with_carry_engine.h __random/uniform_int_distribution.h + __random/uniform_random_bit_generator.h + __random/uniform_real_distribution.h + __random/weibull_distribution.h __ranges/access.h __ranges/all.h + __ranges/as_rvalue_view.h __ranges/common_view.h __ranges/concepts.h __ranges/copyable_box.h + __ranges/counted.h __ranges/dangling.h __ranges/data.h __ranges/drop_view.h - __ranges/empty_view.h + __ranges/drop_while_view.h + __ranges/elements_view.h __ranges/empty.h + __ranges/empty_view.h __ranges/enable_borrowed_range.h __ranges/enable_view.h + __ranges/filter_view.h + __ranges/iota_view.h + __ranges/istream_view.h + __ranges/join_view.h + __ranges/lazy_split_view.h __ranges/non_propagating_cache.h + __ranges/owning_view.h + __ranges/range_adaptor.h + __ranges/rbegin.h __ranges/ref_view.h + __ranges/rend.h + __ranges/reverse_view.h + __ranges/single_view.h __ranges/size.h + __ranges/split_view.h __ranges/subrange.h + __ranges/take_view.h + __ranges/take_while_view.h __ranges/transform_view.h __ranges/view_interface.h + __ranges/views.h + __ranges/zip_view.h __split_buffer __std_stream - __string + __string/char_traits.h + __string/extern_template_lists.h __support/android/locale_bionic.h __support/fuchsia/xlocale.h __support/ibm/gettod_zos.h - __support/ibm/limits.h - __support/ibm/locale_mgmt_aix.h __support/ibm/locale_mgmt_zos.h __support/ibm/nanosleep.h - __support/ibm/support.h __support/ibm/xlocale.h __support/musl/xlocale.h __support/newlib/xlocale.h - __support/nuttx/xlocale.h __support/openbsd/xlocale.h __support/solaris/floatingpoint.h __support/solaris/wchar.h __support/solaris/xlocale.h - __support/win32/limits_msvc_win32.h __support/win32/locale_win32.h __support/xlocale/__nop_locale_mgmt.h __support/xlocale/__posix_l_fallback.h __support/xlocale/__strtonum_fallback.h + __thread/poll_with_backoff.h + __thread/timed_backoff_policy.h __threading_support __tree - __tuple + __tuple_dir/apply_cv.h + __tuple_dir/make_tuple_types.h + __tuple_dir/pair_like.h + __tuple_dir/sfinae_helpers.h + __tuple_dir/tuple_element.h + __tuple_dir/tuple_indices.h + __tuple_dir/tuple_like.h + __tuple_dir/tuple_like_ext.h + __tuple_dir/tuple_size.h + __tuple_dir/tuple_types.h + __type_traits/add_const.h + __type_traits/add_cv.h + __type_traits/add_lvalue_reference.h + __type_traits/add_pointer.h + __type_traits/add_rvalue_reference.h + __type_traits/add_volatile.h + __type_traits/aligned_storage.h + __type_traits/aligned_union.h + __type_traits/alignment_of.h + __type_traits/apply_cv.h + __type_traits/can_extract_key.h + __type_traits/common_reference.h + __type_traits/common_type.h + __type_traits/conditional.h + __type_traits/conjunction.h + __type_traits/copy_cv.h + __type_traits/copy_cvref.h + __type_traits/decay.h + __type_traits/dependent_type.h + __type_traits/disjunction.h + __type_traits/enable_if.h + __type_traits/extent.h + __type_traits/has_unique_object_representation.h + __type_traits/has_virtual_destructor.h + __type_traits/integral_constant.h + __type_traits/is_abstract.h + __type_traits/is_aggregate.h + __type_traits/is_allocator.h + __type_traits/is_always_bitcastable.h + __type_traits/is_arithmetic.h + __type_traits/is_array.h + __type_traits/is_assignable.h + __type_traits/is_base_of.h + __type_traits/is_bounded_array.h + __type_traits/is_callable.h + __type_traits/is_char_like_type.h + __type_traits/is_class.h + __type_traits/is_compound.h + __type_traits/is_const.h + __type_traits/is_constant_evaluated.h + __type_traits/is_constructible.h + __type_traits/is_convertible.h + __type_traits/is_copy_assignable.h + __type_traits/is_copy_constructible.h + __type_traits/is_core_convertible.h + __type_traits/is_default_constructible.h + __type_traits/is_destructible.h + __type_traits/is_empty.h + __type_traits/is_enum.h + __type_traits/is_final.h + __type_traits/is_floating_point.h + __type_traits/is_function.h + __type_traits/is_fundamental.h + __type_traits/is_implicitly_default_constructible.h + __type_traits/is_integral.h + __type_traits/is_literal_type.h + __type_traits/is_member_function_pointer.h + __type_traits/is_member_object_pointer.h + __type_traits/is_member_pointer.h + __type_traits/is_move_assignable.h + __type_traits/is_move_constructible.h + __type_traits/is_nothrow_assignable.h + __type_traits/is_nothrow_constructible.h + __type_traits/is_nothrow_convertible.h + __type_traits/is_nothrow_copy_assignable.h + __type_traits/is_nothrow_copy_constructible.h + __type_traits/is_nothrow_default_constructible.h + __type_traits/is_nothrow_destructible.h + __type_traits/is_nothrow_move_assignable.h + __type_traits/is_nothrow_move_constructible.h + __type_traits/is_null_pointer.h + __type_traits/is_object.h + __type_traits/is_pod.h + __type_traits/is_pointer.h + __type_traits/is_polymorphic.h + __type_traits/is_primary_template.h + __type_traits/is_reference.h + __type_traits/is_reference_wrapper.h + __type_traits/is_referenceable.h + __type_traits/is_same.h + __type_traits/is_scalar.h + __type_traits/is_scoped_enum.h + __type_traits/is_signed.h + __type_traits/is_signed_integer.h + __type_traits/is_specialization.h + __type_traits/is_standard_layout.h + __type_traits/is_swappable.h + __type_traits/is_trivial.h + __type_traits/is_trivially_assignable.h + __type_traits/is_trivially_constructible.h + __type_traits/is_trivially_copy_assignable.h + __type_traits/is_trivially_copy_constructible.h + __type_traits/is_trivially_copyable.h + __type_traits/is_trivially_default_constructible.h + __type_traits/is_trivially_destructible.h + __type_traits/is_trivially_move_assignable.h + __type_traits/is_trivially_move_constructible.h + __type_traits/is_unbounded_array.h + __type_traits/is_union.h + __type_traits/is_unsigned.h + __type_traits/is_unsigned_integer.h + __type_traits/is_valid_expansion.h + __type_traits/is_void.h + __type_traits/is_volatile.h + __type_traits/lazy.h + __type_traits/make_32_64_or_128_bit.h + __type_traits/make_const_lvalue_ref.h + __type_traits/make_signed.h + __type_traits/make_unsigned.h + __type_traits/maybe_const.h + __type_traits/nat.h + __type_traits/negation.h + __type_traits/noexcept_move_assign_container.h + __type_traits/promote.h + __type_traits/rank.h + __type_traits/remove_all_extents.h + __type_traits/remove_const.h + __type_traits/remove_const_ref.h + __type_traits/remove_cv.h + __type_traits/remove_cvref.h + __type_traits/remove_extent.h + __type_traits/remove_pointer.h + __type_traits/remove_reference.h + __type_traits/remove_volatile.h + __type_traits/result_of.h + __type_traits/strip_signature.h + __type_traits/type_identity.h + __type_traits/type_list.h + __type_traits/underlying_type.h + __type_traits/void_t.h __undef_macros - __utility/__decay_copy.h __utility/as_const.h + __utility/auto_cast.h __utility/cmp.h + __utility/convert_to_integral.h __utility/declval.h + __utility/exception_guard.h __utility/exchange.h __utility/forward.h + __utility/forward_like.h __utility/in_place.h __utility/integer_sequence.h __utility/move.h __utility/pair.h __utility/piecewise_construct.h + __utility/priority_tag.h __utility/rel_ops.h __utility/swap.h __utility/to_underlying.h + __utility/unreachable.h __variant/monostate.h + __verbose_abort algorithm any array @@ -270,6 +748,7 @@ set(files complex.h concepts condition_variable + coroutine csetjmp csignal cstdarg @@ -282,18 +761,19 @@ set(files ctgmath ctime ctype.h + cuchar cwchar cwctype deque errno.h exception execution + expected experimental/__config experimental/__memory experimental/algorithm experimental/coroutine experimental/deque - experimental/filesystem experimental/forward_list experimental/functional experimental/iterator @@ -330,6 +810,7 @@ set(files istream iterator latch + libcxx.imp limits limits.h list @@ -338,7 +819,7 @@ set(files map math.h memory - module.modulemap + memory_resource mutex new numbers @@ -348,7 +829,6 @@ set(files queue random ranges - ranges ratio regex scoped_allocator @@ -356,9 +836,11 @@ set(files set setjmp.h shared_mutex + source_location span sstream stack + stdatomic.h stdbool.h stddef.h stdexcept @@ -367,8 +849,8 @@ set(files stdlib.h streambuf string - string_view string.h + string_view strstream system_error tgmath.h @@ -377,6 +859,7 @@ set(files type_traits typeindex typeinfo + uchar.h unordered_map unordered_set utility @@ -388,9 +871,17 @@ set(files wctype.h ) +foreach(feature LIBCXX_ENABLE_FILESYSTEM LIBCXX_ENABLE_LOCALIZATION LIBCXX_ENABLE_FSTREAM LIBCXX_ENABLE_THREADS LIBCXX_ENABLE_WIDE_CHARACTERS) + if (NOT ${${feature}}) + set(requires_${feature} "requires LIBCXX_CONFIGURED_WITHOUT_SUPPORT_FOR_THIS_HEADER") + endif() +endforeach() + configure_file("__config_site.in" "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site" @ONLY) +configure_file("module.modulemap.in" "${LIBCXX_GENERATED_INCLUDE_DIR}/module.modulemap" @ONLY) -set(_all_includes "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site") +set(_all_includes "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site" + "${LIBCXX_GENERATED_INCLUDE_DIR}/module.modulemap") foreach(f ${files}) set(src "${CMAKE_CURRENT_SOURCE_DIR}/${f}") set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${f}") @@ -404,29 +895,30 @@ endforeach() add_custom_target(generate-cxx-headers ALL DEPENDS ${_all_includes}) add_library(cxx-headers INTERFACE) -add_dependencies(cxx-headers generate-cxx-headers ${LIBCXX_CXX_ABI_HEADER_TARGET}) -# TODO: Use target_include_directories once we figure out why that breaks the runtimes build -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") - target_compile_options(cxx-headers INTERFACE /I${LIBCXX_GENERATED_INCLUDE_DIR} - INTERFACE /I${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}) -else() - target_compile_options(cxx-headers INTERFACE -I${LIBCXX_GENERATED_INCLUDE_DIR} - INTERFACE -I${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}) -endif() +target_link_libraries(cxx-headers INTERFACE libcxx-abi-headers) +add_dependencies(cxx-headers generate-cxx-headers) +target_include_directories(cxx-headers INTERFACE ${LIBCXX_GENERATED_INCLUDE_DIR} + ${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}) if (LIBCXX_INSTALL_HEADERS) foreach(file ${files}) get_filename_component(dir ${file} DIRECTORY) install(FILES ${file} - DESTINATION ${LIBCXX_INSTALL_INCLUDE_DIR}/${dir} + DESTINATION "${LIBCXX_INSTALL_INCLUDE_DIR}/${dir}" COMPONENT cxx-headers PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) endforeach() - # Install the generated __config_site. - install(FILES ${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site - DESTINATION ${LIBCXX_INSTALL_INCLUDE_TARGET_DIR} + # Install the generated __config_site file to the per-target include dir. + install(FILES "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site" + DESTINATION "${LIBCXX_INSTALL_INCLUDE_TARGET_DIR}" + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + COMPONENT cxx-headers) + + # Install the generated modulemap file to the generic include dir. + install(FILES "${LIBCXX_GENERATED_INCLUDE_DIR}/module.modulemap" + DESTINATION "${LIBCXX_INSTALL_INCLUDE_DIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT cxx-headers) diff --git a/gnu/llvm/libcxx/include/__algorithm/adjacent_find.h b/gnu/llvm/libcxx/include/__algorithm/adjacent_find.h index 0a2aa055c10..30df4a976f3 100644 --- a/gnu/llvm/libcxx/include/__algorithm/adjacent_find.h +++ b/gnu/llvm/libcxx/include/__algorithm/adjacent_find.h @@ -10,42 +10,44 @@ #ifndef _LIBCPP___ALGORITHM_ADJACENT_FIND_H #define _LIBCPP___ALGORITHM_ADJACENT_FIND_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter +__adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { + if (__first == __last) + return __first; + _Iter __i = __first; + while (++__i != __last) { + if (__pred(*__first, *__i)) + return __first; + __first = __i; + } + return __i; +} + template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { - if (__first != __last) { - _ForwardIterator __i = __first; - while (++__i != __last) { - if (__pred(*__first, *__i)) - return __first; - __first = __i; - } - } - return __last; + return std::__adjacent_find(std::move(__first), std::move(__last), __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { - typedef typename iterator_traits<_ForwardIterator>::value_type __v; - return _VSTD::adjacent_find(__first, __last, __equal_to<__v>()); + return std::adjacent_find(std::move(__first), std::move(__last), __equal_to()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H diff --git a/gnu/llvm/libcxx/include/__algorithm/all_of.h b/gnu/llvm/libcxx/include/__algorithm/all_of.h index 7d6ed508596..284c34ffcda 100644 --- a/gnu/llvm/libcxx/include/__algorithm/all_of.h +++ b/gnu/llvm/libcxx/include/__algorithm/all_of.h @@ -13,16 +13,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) @@ -32,6 +29,4 @@ all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_ALL_OF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/any_of.h b/gnu/llvm/libcxx/include/__algorithm/any_of.h index d5a6c094a67..fe0882816b9 100644 --- a/gnu/llvm/libcxx/include/__algorithm/any_of.h +++ b/gnu/llvm/libcxx/include/__algorithm/any_of.h @@ -13,16 +13,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) @@ -32,6 +29,4 @@ any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_ANY_OF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/binary_search.h b/gnu/llvm/libcxx/include/__algorithm/binary_search.h index 766f5da1629..8f958c2c1ad 100644 --- a/gnu/llvm/libcxx/include/__algorithm/binary_search.h +++ b/gnu/llvm/libcxx/include/__algorithm/binary_search.h @@ -9,53 +9,38 @@ #ifndef _LIBCPP___ALGORITHM_BINARY_SEARCH_H #define _LIBCPP___ALGORITHM_BINARY_SEARCH_H -#include <__config> #include <__algorithm/comp.h> -#include <__algorithm/lower_bound.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/lower_bound.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -bool -__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) -{ - __first = _VSTD::__lower_bound<_Compare>(__first, __last, __value_, __comp); - return __first != __last && !__comp(__value_, *__first); -} - template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__binary_search<_Comp_ref>(__first, __last, __value_, __comp); + __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp); + return __first != __last && !__comp(__value, *__first); } template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - return _VSTD::binary_search(__first, __last, __value_, - __less::value_type, _Tp>()); + return std::binary_search(__first, __last, __value, + __less::value_type, _Tp>()); } - _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_BINARY_SEARCH_H diff --git a/gnu/llvm/libcxx/include/__algorithm/clamp.h b/gnu/llvm/libcxx/include/__algorithm/clamp.h index f8eba03cf89..30ddbdce64a 100644 --- a/gnu/llvm/libcxx/include/__algorithm/clamp.h +++ b/gnu/llvm/libcxx/include/__algorithm/clamp.h @@ -9,24 +9,20 @@ #ifndef _LIBCPP___ALGORITHM_CLAMP_H #define _LIBCPP___ALGORITHM_CLAMP_H -#include <__config> -#include <__debug> #include <__algorithm/comp.h> +#include <__assert> +#include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 -// clamp template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +_LIBCPP_INLINE_VISIBILITY constexpr const _Tp& clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) { @@ -37,7 +33,7 @@ clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +_LIBCPP_INLINE_VISIBILITY constexpr const _Tp& clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) { @@ -47,6 +43,4 @@ clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_CLAMP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/comp.h b/gnu/llvm/libcxx/include/__algorithm/comp.h index 2039cf7b395..af8eb7b5d76 100644 --- a/gnu/llvm/libcxx/include/__algorithm/comp.h +++ b/gnu/llvm/libcxx/include/__algorithm/comp.h @@ -12,86 +12,55 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -// I'd like to replace these with _VSTD::equal_to, but can't because: -// * That only works with C++14 and later, and -// * We haven't included here. -template -struct __equal_to -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;} -}; - -template -struct __equal_to<_T1, _T1> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} -}; - -template -struct __equal_to -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} -}; - -template -struct __equal_to<_T1, const _T1> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} +struct __equal_to { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T2& __y) const { + return __x == __y; + } }; template struct __less { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} }; template struct __less<_T1, _T1> { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} }; template struct __less { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} }; template struct __less<_T1, const _T1> { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} }; _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_COMP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/comp_ref_type.h b/gnu/llvm/libcxx/include/__algorithm/comp_ref_type.h index b3bca82c095..f2338e14468 100644 --- a/gnu/llvm/libcxx/include/__algorithm/comp_ref_type.h +++ b/gnu/llvm/libcxx/include/__algorithm/comp_ref_type.h @@ -10,28 +10,24 @@ #define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H #include <__config> -#include +#include <__debug> +#include <__utility/declval.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#ifdef _LIBCPP_DEBUG - template struct __debug_less { _Compare &__comp_; - _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_CONSTEXPR_SINCE_CXX14 __debug_less(_Compare& __c) : __comp_(__c) {} template - _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __x, const _Up& __y) { bool __r = __comp_(__x, __y); @@ -41,7 +37,7 @@ struct __debug_less } template - _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(_Tp& __x, _Up& __y) { bool __r = __comp_(__x, __y); @@ -51,37 +47,33 @@ struct __debug_less } template - _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_INLINE_VISIBILITY - decltype((void)declval<_Compare&>()( - declval<_LHS &>(), declval<_RHS &>())) + decltype((void)std::declval<_Compare&>()( + std::declval<_LHS &>(), std::declval<_RHS &>())) __do_compare_assert(int, _LHS & __l, _RHS & __r) { - _LIBCPP_ASSERT(!__comp_(__l, __r), + _LIBCPP_DEBUG_ASSERT(!__comp_(__l, __r), "Comparator does not induce a strict weak ordering"); + (void)__l; + (void)__r; } template - _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_INLINE_VISIBILITY void __do_compare_assert(long, _LHS &, _RHS &) {} }; -#endif // _LIBCPP_DEBUG - +// Pass the comparator by lvalue reference. Or in debug mode, using a +// debugging wrapper that stores a reference. +#ifdef _LIBCPP_ENABLE_DEBUG_MODE template -struct __comp_ref_type { - // Pass the comparator by lvalue reference. Or in debug mode, using a - // debugging wrapper that stores a reference. -#ifndef _LIBCPP_DEBUG - typedef typename add_lvalue_reference<_Comp>::type type; +using __comp_ref_type = __debug_less<_Comp>; #else - typedef __debug_less<_Comp> type; +template +using __comp_ref_type = _Comp&; #endif -}; - _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_COMP_REF_TYPE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/copy.h b/gnu/llvm/libcxx/include/__algorithm/copy.h index 9db7434c043..193a6df3165 100644 --- a/gnu/llvm/libcxx/include/__algorithm/copy.h +++ b/gnu/llvm/libcxx/include/__algorithm/copy.h @@ -9,14 +9,17 @@ #ifndef _LIBCPP___ALGORITHM_COPY_H #define _LIBCPP___ALGORITHM_COPY_H +#include <__algorithm/copy_move_common.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> #include <__config> -#include <__algorithm/unwrap_iter.h> -#include <__iterator/iterator_traits.h> -#include -#include +#include <__iterator/segmented_iterator.h> +#include <__type_traits/common_type.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -24,55 +27,96 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -// copy +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter); -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - for (; __first != __last; ++__first, (void) ++__result) - *__result = *__first; - return __result; -} +template +struct __copy_loop { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { + while (__first != __last) { + *__result = *__first; + ++__first; + ++__result; + } -template -inline _LIBCPP_INLINE_VISIBILITY -_OutputIterator -__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - return _VSTD::__copy_constexpr(__first, __last, __result); -} + return std::make_pair(std::move(__first), std::move(__result)); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) const { + using _Traits = __segmented_iterator_traits<_InIter>; + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + if (__sfirst == __slast) { + auto __iters = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); + return std::make_pair(__last, std::move(__iters.second)); + } + + __result = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second; + ++__sfirst; + while (__sfirst != __slast) { + __result = + std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second; + ++__sfirst; + } + __result = + std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second; + return std::make_pair(__last, std::move(__result)); + } -template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_same::type, _Up>::value && - is_trivially_copy_assignable<_Up>::value, - _Up* ->::type -__copy(_Tp* __first, _Tp* __last, _Up* __result) -{ - const size_t __n = static_cast(__last - __first); - if (__n > 0) - _VSTD::memmove(__result, __first, __n * sizeof(_Up)); - return __result + __n; + template ::value && + !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) { + using _Traits = __segmented_iterator_traits<_OutIter>; + using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; + + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__result)); + + auto __local_first = _Traits::__local(__result); + auto __segment_iterator = _Traits::__segment(__result); + while (true) { + auto __local_last = _Traits::__end(__segment_iterator); + auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first); + auto __iters = std::__copy<_AlgPolicy>(__first, __first + __size, __local_first); + __first = std::move(__iters.first); + + if (__first == __last) + return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second))); + + __local_first = _Traits::__begin(++__segment_iterator); + } + } +}; + +struct __copy_trivial { + // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> + operator()(_In* __first, _In* __last, _Out* __result) const { + return std::__copy_trivial_impl(__first, __last, __result); + } +}; + +template +pair<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +__copy(_InIter __first, _Sent __last, _OutIter __result) { + return std::__dispatch_copy_or_move<_AlgPolicy, __copy_loop<_AlgPolicy>, __copy_trivial>( + std::move(__first), std::move(__last), std::move(__result)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - if (__libcpp_is_constant_evaluated()) { - return _VSTD::__copy_constexpr(__first, __last, __result); - } else { - return _VSTD::__rewrap_iter(__result, - _VSTD::__copy(_VSTD::__unwrap_iter(__first), - _VSTD::__unwrap_iter(__last), - _VSTD::__unwrap_iter(__result))); - } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { + return std::__copy<_ClassicAlgPolicy>(__first, __last, __result).second; } _LIBCPP_END_NAMESPACE_STD diff --git a/gnu/llvm/libcxx/include/__algorithm/copy_backward.h b/gnu/llvm/libcxx/include/__algorithm/copy_backward.h index 03a9c5f2d00..bb2a4328781 100644 --- a/gnu/llvm/libcxx/include/__algorithm/copy_backward.h +++ b/gnu/llvm/libcxx/include/__algorithm/copy_backward.h @@ -9,14 +9,18 @@ #ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H #define _LIBCPP___ALGORITHM_COPY_BACKWARD_H +#include <__algorithm/copy_move_common.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> #include <__config> -#include <__algorithm/unwrap_iter.h> -#include <__iterator/iterator_traits.h> -#include -#include +#include <__iterator/segmented_iterator.h> +#include <__type_traits/common_type.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -24,57 +28,112 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) -{ - while (__first != __last) - *--__result = *--__last; - return __result; -} +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter> +__copy_backward(_InIter __first, _Sent __last, _OutIter __result); -template -inline _LIBCPP_INLINE_VISIBILITY -_OutputIterator -__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) -{ - return _VSTD::__copy_backward_constexpr(__first, __last, __result); -} +template +struct __copy_backward_loop { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { + auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + auto __original_last_iter = __last_iter; -template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_same::type, _Up>::value && - is_trivially_copy_assignable<_Up>::value, - _Up* ->::type -__copy_backward(_Tp* __first, _Tp* __last, _Up* __result) -{ - const size_t __n = static_cast(__last - __first); - if (__n > 0) - { - __result -= __n; - _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + while (__first != __last_iter) { + *--__result = *--__last_iter; + } + + return std::make_pair(std::move(__original_last_iter), std::move(__result)); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) const { + using _Traits = __segmented_iterator_traits<_InIter>; + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + if (__sfirst == __slast) { + auto __iters = + std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); + return std::make_pair(__last, __iters.second); + } + + __result = + std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result)) + .second; + --__slast; + while (__sfirst != __slast) { + __result = + std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result)) + .second; + --__slast; } - return __result; + __result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result)) + .second; + return std::make_pair(__last, std::move(__result)); + } + + template ::value && + !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) { + using _Traits = __segmented_iterator_traits<_OutIter>; + auto __orig_last = __last; + auto __segment_iterator = _Traits::__segment(__result); + + // When the range contains no elements, __result might not be a valid iterator + if (__first == __last) + return std::make_pair(__first, __result); + + auto __local_last = _Traits::__local(__result); + while (true) { + using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; + + auto __local_first = _Traits::__begin(__segment_iterator); + auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first); + auto __iter = std::__copy_backward<_AlgPolicy>(__last - __size, __last, __local_last).second; + __last -= __size; + + if (__first == __last) + return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter))); + --__segment_iterator; + __local_last = _Traits::__end(__segment_iterator); + } + } +}; + +struct __copy_backward_trivial { + // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> + operator()(_In* __first, _In* __last, _Out* __result) const { + return std::__copy_backward_trivial_impl(__first, __last, __result); + } +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2> +__copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) { + return std::__dispatch_copy_or_move<_AlgPolicy, __copy_backward_loop<_AlgPolicy>, __copy_backward_trivial>( + std::move(__first), std::move(__last), std::move(__result)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2 copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { - if (__libcpp_is_constant_evaluated()) { - return _VSTD::__copy_backward_constexpr(__first, __last, __result); - } else { - return _VSTD::__rewrap_iter(__result, - _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first), - _VSTD::__unwrap_iter(__last), - _VSTD::__unwrap_iter(__result))); - } + static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && + std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); + + return std::__copy_backward<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), std::move(__result)).second; } _LIBCPP_END_NAMESPACE_STD diff --git a/gnu/llvm/libcxx/include/__algorithm/copy_if.h b/gnu/llvm/libcxx/include/__algorithm/copy_if.h index 153304c7a76..a5938b8719d 100644 --- a/gnu/llvm/libcxx/include/__algorithm/copy_if.h +++ b/gnu/llvm/libcxx/include/__algorithm/copy_if.h @@ -10,22 +10,15 @@ #define _LIBCPP___ALGORITHM_COPY_IF_H #include <__config> -#include <__algorithm/unwrap_iter.h> -#include <__iterator/iterator_traits.h> -#include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) @@ -43,6 +36,4 @@ copy_if(_InputIterator __first, _InputIterator __last, _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_COPY_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/copy_move_common.h b/gnu/llvm/libcxx/include/__algorithm/copy_move_common.h new file mode 100644 index 00000000000..b88c14911b9 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/copy_move_common.h @@ -0,0 +1,163 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_COPY_MOVE_COMMON_H +#define _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/unwrap_iter.h> +#include <__algorithm/unwrap_range.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_always_bitcastable.h> +#include <__type_traits/is_constant_evaluated.h> +#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_trivially_assignable.h> +#include <__type_traits/is_trivially_copyable.h> +#include <__type_traits/is_volatile.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Type traits. + +template +struct __can_lower_copy_assignment_to_memmove { + static const bool value = + // If the types are always bitcastable, it's valid to do a bitwise copy between them. + __is_always_bitcastable<_From, _To>::value && + // Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays). + is_trivially_assignable<_To&, const _From&>::value && + // `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case. + !is_volatile<_From>::value && + !is_volatile<_To>::value; +}; + +template +struct __can_lower_move_assignment_to_memmove { + static const bool value = + __is_always_bitcastable<_From, _To>::value && + is_trivially_assignable<_To&, _From&&>::value && + !is_volatile<_From>::value && + !is_volatile<_To>::value; +}; + +// `memmove` algorithms implementation. + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> +__copy_trivial_impl(_In* __first, _In* __last, _Out* __result) { + const size_t __n = static_cast(__last - __first); + ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); + + return std::make_pair(__last, __result + __n); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> +__copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) { + const size_t __n = static_cast(__last - __first); + __result -= __n; + + ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); + + return std::make_pair(__last, __result); +} + +// Iterator unwrapping and dispatching to the correct overload. + +template +struct __overload : _F1, _F2 { + using _F1::operator(); + using _F2::operator(); +}; + +template +struct __can_rewrap : false_type {}; + +template +struct __can_rewrap<_InIter, + _Sent, + _OutIter, + // Note that sentinels are always copy-constructible. + __enable_if_t< is_copy_constructible<_InIter>::value && + is_copy_constructible<_OutIter>::value > > : true_type {}; + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> +__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) { + auto __range = std::__unwrap_range(__first, std::move(__last)); + auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first)); + return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)), + std::__rewrap_iter(std::move(__out_first), std::move(__result.second))); +} + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> +__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) { + return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first)); +} + +template +struct __can_copy_without_conversion : false_type {}; + +template +struct __can_copy_without_conversion< + _IterOps, + _InValue, + _OutIter, + __enable_if_t >::value> > : true_type {}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> +__dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) { +#ifdef _LIBCPP_COMPILER_GCC + // GCC doesn't support `__builtin_memmove` during constant evaluation. + if (__libcpp_is_constant_evaluated()) { + return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); + } +#else + // In Clang, `__builtin_memmove` only supports fully trivially copyable types (just having trivial copy assignment is + // insufficient). Also, conversions are not supported. + if (__libcpp_is_constant_evaluated()) { + using _InValue = typename _IterOps<_AlgPolicy>::template __value_type<_InIter>; + if (!is_trivially_copyable<_InValue>::value || + !__can_copy_without_conversion<_IterOps<_AlgPolicy>, _InValue, _OutIter>::value) { + return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); + } + } +#endif // _LIBCPP_COMPILER_GCC + + using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>; + return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H diff --git a/gnu/llvm/libcxx/include/__algorithm/copy_n.h b/gnu/llvm/libcxx/include/__algorithm/copy_n.h index bbfeb8686fb..b08bbdfb9b7 100644 --- a/gnu/llvm/libcxx/include/__algorithm/copy_n.h +++ b/gnu/llvm/libcxx/include/__algorithm/copy_n.h @@ -9,24 +9,20 @@ #ifndef _LIBCPP___ALGORITHM_COPY_N_H #define _LIBCPP___ALGORITHM_COPY_N_H -#include <__config> #include <__algorithm/copy.h> -#include <__algorithm/unwrap_iter.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include +#include <__utility/convert_to_integral.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if < __is_cpp17_input_iterator<_InputIterator>::value && @@ -52,7 +48,7 @@ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if < __is_cpp17_random_access_iterator<_InputIterator>::value, @@ -60,13 +56,12 @@ typename enable_if >::type copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { + typedef typename iterator_traits<_InputIterator>::difference_type difference_type; typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; _IntegralSize __n = __orig_n; - return _VSTD::copy(__first, __first + __n, __result); + return _VSTD::copy(__first, __first + difference_type(__n), __result); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_COPY_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/count.h b/gnu/llvm/libcxx/include/__algorithm/count.h index 7f2d1954cd6..6c8c7fda35d 100644 --- a/gnu/llvm/libcxx/include/__algorithm/count.h +++ b/gnu/llvm/libcxx/include/__algorithm/count.h @@ -14,27 +14,22 @@ #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename iterator_traits<_InputIterator>::difference_type - count(_InputIterator __first, _InputIterator __last, const _Tp& __value_) { + count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { typename iterator_traits<_InputIterator>::difference_type __r(0); for (; __first != __last; ++__first) - if (*__first == __value_) + if (*__first == __value) ++__r; return __r; } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_COUNT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/count_if.h b/gnu/llvm/libcxx/include/__algorithm/count_if.h index a5efffb9260..b96521fe0a8 100644 --- a/gnu/llvm/libcxx/include/__algorithm/count_if.h +++ b/gnu/llvm/libcxx/include/__algorithm/count_if.h @@ -14,16 +14,13 @@ #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename iterator_traits<_InputIterator>::difference_type count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { typename iterator_traits<_InputIterator>::difference_type __r(0); @@ -35,6 +32,4 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_C _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_COUNT_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/equal.h b/gnu/llvm/libcxx/include/__algorithm/equal.h index bc675598196..cf37f46aaf6 100644 --- a/gnu/llvm/libcxx/include/__algorithm/equal.h +++ b/gnu/llvm/libcxx/include/__algorithm/equal.h @@ -10,22 +10,19 @@ #ifndef _LIBCPP___ALGORITHM_EQUAL_H #define _LIBCPP___ALGORITHM_EQUAL_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> +#include <__iterator/distance.h> #include <__iterator/iterator_traits.h> -#include // FIXME: replace with <__iterator/distance.h> when it lands #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { for (; __first1 != __last1; ++__first1, (void)++__first2) if (!__pred(*__first1, *__first2)) @@ -34,16 +31,14 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { - typedef typename iterator_traits<_InputIterator1>::value_type __v1; - typedef typename iterator_traits<_InputIterator2>::value_type __v2; - return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>()); + return std::equal(__first1, __last1, __first2, __equal_to()); } #if _LIBCPP_STD_VER > 11 template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) { for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) @@ -53,38 +48,39 @@ __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fir } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) return false; return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2, - typename add_lvalue_reference<_BinaryPredicate>::type>(__first1, __last1, __first2, __pred); + _BinaryPredicate&>(__first1, __last1, __first2, __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred) { - return _VSTD::__equal::type>( + return _VSTD::__equal<_BinaryPredicate&>( __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(), typename iterator_traits<_InputIterator2>::iterator_category()); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { - typedef typename iterator_traits<_InputIterator1>::value_type __v1; - typedef typename iterator_traits<_InputIterator2>::value_type __v2; - return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(), - typename iterator_traits<_InputIterator1>::iterator_category(), - typename iterator_traits<_InputIterator2>::iterator_category()); + return std::__equal( + __first1, + __last1, + __first2, + __last2, + __equal_to(), + typename iterator_traits<_InputIterator1>::iterator_category(), + typename iterator_traits<_InputIterator2>::iterator_category()); } #endif _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_EQUAL_H diff --git a/gnu/llvm/libcxx/include/__algorithm/equal_range.h b/gnu/llvm/libcxx/include/__algorithm/equal_range.h index 9694dae9500..2075b03412e 100644 --- a/gnu/llvm/libcxx/include/__algorithm/equal_range.h +++ b/gnu/llvm/libcxx/include/__algorithm/equal_range.h @@ -9,79 +9,79 @@ #ifndef _LIBCPP___ALGORITHM_EQUAL_RANGE_H #define _LIBCPP___ALGORITHM_EQUAL_RANGE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/half_positive.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/lower_bound.h> #include <__algorithm/upper_bound.h> -#include +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__type_traits/is_callable.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> -__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) -{ - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - difference_type __len = _VSTD::distance(__first, __last); - while (__len != 0) - { - difference_type __l2 = _VSTD::__half_positive(__len); - _ForwardIterator __m = __first; - _VSTD::advance(__m, __l2); - if (__comp(*__m, __value_)) - { - __first = ++__m; - __len -= __l2 + 1; - } - else if (__comp(__value_, *__m)) - { - __last = __m; - __len = __l2; - } - else - { - _ForwardIterator __mp1 = __m; - return pair<_ForwardIterator, _ForwardIterator> - ( - _VSTD::__lower_bound<_Compare>(__first, __m, __value_, __comp), - _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value_, __comp) - ); - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter> +__equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp, _Proj&& __proj) { + auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); + _Iter __end = _IterOps<_AlgPolicy>::next(__first, __last); + while (__len != 0) { + auto __half_len = std::__half_positive(__len); + _Iter __mid = _IterOps<_AlgPolicy>::next(__first, __half_len); + if (std::__invoke(__comp, std::__invoke(__proj, *__mid), __value)) { + __first = ++__mid; + __len -= __half_len + 1; + } else if (std::__invoke(__comp, __value, std::__invoke(__proj, *__mid))) { + __end = __mid; + __len = __half_len; + } else { + _Iter __mp1 = __mid; + return pair<_Iter, _Iter>( + std::__lower_bound_impl<_AlgPolicy>(__first, __mid, __value, __comp, __proj), + std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj)); } - return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + return pair<_Iter, _Iter>(__first, __first); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -pair<_ForwardIterator, _ForwardIterator> -equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__equal_range<_Comp_ref>(__first, __last, __value_, __comp); +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, + "The comparator has to be callable"); + static_assert(is_copy_constructible<_ForwardIterator>::value, + "Iterator has to be copy constructible"); + return std::__equal_range<_ClassicAlgPolicy>( + std::move(__first), + std::move(__last), + __value, + static_cast<__comp_ref_type<_Compare> >(__comp), + std::__identity()); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -pair<_ForwardIterator, _ForwardIterator> -equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) -{ - return _VSTD::equal_range(__first, __last, __value_, - __less::value_type, _Tp>()); +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::equal_range( + std::move(__first), + std::move(__last), + __value, + __less::value_type, _Tp>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_EQUAL_RANGE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/fill.h b/gnu/llvm/libcxx/include/__algorithm/fill.h index 4fefe86536d..76cf4a1477a 100644 --- a/gnu/llvm/libcxx/include/__algorithm/fill.h +++ b/gnu/llvm/libcxx/include/__algorithm/fill.h @@ -9,47 +9,44 @@ #ifndef _LIBCPP___ALGORITHM_FILL_H #define _LIBCPP___ALGORITHM_FILL_H -#include <__config> #include <__algorithm/fill_n.h> +#include <__config> #include <__iterator/iterator_traits.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +// fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. + template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void -__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag) +__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) { for (; __first != __last; ++__first) - *__first = __value_; + *__first = __value; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void -__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag) +__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) { - _VSTD::fill_n(__first, __last - __first, __value_); + _VSTD::fill_n(__first, __last - __first, __value); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void -fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category()); + _VSTD::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_FILL_H diff --git a/gnu/llvm/libcxx/include/__algorithm/fill_n.h b/gnu/llvm/libcxx/include/__algorithm/fill_n.h index 34a245edb51..fe58c8d6417 100644 --- a/gnu/llvm/libcxx/include/__algorithm/fill_n.h +++ b/gnu/llvm/libcxx/include/__algorithm/fill_n.h @@ -11,37 +11,35 @@ #include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/convert_to_integral.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. + template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator -__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) +__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { for (; __n > 0; ++__first, (void) --__n) - *__first = __value_; + *__first = __value; return __first; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator -fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) +fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { - return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value_); + return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_FILL_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/find.h b/gnu/llvm/libcxx/include/__algorithm/find.h index bc593dc5425..e51dc9bb160 100644 --- a/gnu/llvm/libcxx/include/__algorithm/find.h +++ b/gnu/llvm/libcxx/include/__algorithm/find.h @@ -13,25 +13,20 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator -find(_InputIterator __first, _InputIterator __last, const _Tp& __value_) { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { for (; __first != __last; ++__first) - if (*__first == __value_) + if (*__first == __value) break; return __first; } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_FIND_H diff --git a/gnu/llvm/libcxx/include/__algorithm/find_end.h b/gnu/llvm/libcxx/include/__algorithm/find_end.h index f4277f003aa..e2fee6b3c45 100644 --- a/gnu/llvm/libcxx/include/__algorithm/find_end.h +++ b/gnu/llvm/libcxx/include/__algorithm/find_end.h @@ -10,49 +10,70 @@ #ifndef _LIBCPP___ALGORITHM_FIND_END_OF_H #define _LIBCPP___ALGORITHM_FIND_END_OF_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/search.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/advance.h> #include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/reverse_iterator.h> +#include <__utility/pair.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred, forward_iterator_tag, - forward_iterator_tag) { +template < + class _AlgPolicy, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Pred, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + forward_iterator_tag, + forward_iterator_tag) { // modeled after search algorithm - _ForwardIterator1 __r = __last1; // __last1 is the "default" answer + _Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer + _Iter1 __match_last = __match_first; if (__first2 == __last2) - return __r; + return pair<_Iter1, _Iter1>(__match_last, __match_last); while (true) { while (true) { - if (__first1 == __last1) // if source exhausted return last correct answer - return __r; // (or __last1 if never found) - if (__pred(*__first1, *__first2)) + if (__first1 == __last1) // if source exhausted return last correct answer (or __last1 if never found) + return pair<_Iter1, _Iter1>(__match_first, __match_last); + if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) break; ++__first1; } // *__first1 matches *__first2, now match elements after here - _ForwardIterator1 __m1 = __first1; - _ForwardIterator2 __m2 = __first2; + _Iter1 __m1 = __first1; + _Iter2 __m2 = __first2; while (true) { if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one - __r = __first1; + __match_first = __first1; + __match_last = ++__m1; ++__first1; break; } if (++__m1 == __last1) // Source exhausted, return last answer - return __r; - if (!__pred(*__m1, *__m2)) // mismatch, restart with a new __first + return pair<_Iter1, _Iter1>(__match_first, __match_last); + // mismatch, restart with a new __first + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) { ++__first1; break; @@ -61,33 +82,52 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __f } } -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end( - _BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2, - _BidirectionalIterator2 __last2, _BinaryPredicate __pred, bidirectional_iterator_tag, bidirectional_iterator_tag) { +template < + class _IterOps, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end( + _Iter1 __first1, + _Sent1 __sent1, + _Iter2 __first2, + _Sent2 __sent2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + bidirectional_iterator_tag, + bidirectional_iterator_tag) { + auto __last1 = _IterOps::next(__first1, __sent1); + auto __last2 = _IterOps::next(__first2, __sent2); // modeled after search algorithm (in reverse) if (__first2 == __last2) return __last1; // Everything matches an empty sequence - _BidirectionalIterator1 __l1 = __last1; - _BidirectionalIterator2 __l2 = __last2; + _Iter1 __l1 = __last1; + _Iter2 __l2 = __last2; --__l2; while (true) { // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks while (true) { if (__first1 == __l1) // return __last1 if no element matches *__first2 return __last1; - if (__pred(*--__l1, *__l2)) + if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2))) break; } // *__l1 matches *__l2, now match elements before here - _BidirectionalIterator1 __m1 = __l1; - _BidirectionalIterator2 __m2 = __l2; + _Iter1 __m1 = __l1; + _Iter2 __m2 = __l2; while (true) { if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern) return __m1; if (__m1 == __first1) // Otherwise if source exhaused, pattern not found return __last1; - if (!__pred(*--__m1, *--__m2)) // if there is a mismatch, restart with a new __l1 + + // if there is a mismatch, restart with a new __l1 + if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) { break; } // else there is a match, check next elements @@ -95,35 +135,53 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end( } } -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end( - _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { +template < + class _AlgPolicy, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end( + _Iter1 __first1, + _Sent1 __sent1, + _Iter2 __first2, + _Sent2 __sent2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + random_access_iterator_tag, + random_access_iterator_tag) { + typedef typename iterator_traits<_Iter1>::difference_type _D1; + auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1); + auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2); // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern - typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2; + auto __len2 = __last2 - __first2; if (__len2 == 0) return __last1; - typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1; + auto __len1 = __last1 - __first1; if (__len1 < __len2) return __last1; - const _RandomAccessIterator1 __s = __first1 + (__len2 - 1); // End of pattern match can't go before here - _RandomAccessIterator1 __l1 = __last1; - _RandomAccessIterator2 __l2 = __last2; + const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here + _Iter1 __l1 = __last1; + _Iter2 __l2 = __last2; --__l2; while (true) { while (true) { if (__s == __l1) return __last1; - if (__pred(*--__l1, *__l2)) + if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2))) break; } - _RandomAccessIterator1 __m1 = __l1; - _RandomAccessIterator2 __m2 = __l2; + _Iter1 __m1 = __l1; + _Iter2 __m2 = __l2; while (true) { if (__m2 == __first2) return __m1; // no need to check range on __m1 because __s guarantees we have enough source - if (!__pred(*--__m1, *--__m2)) { + if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(*--__m2))) { break; } } @@ -131,24 +189,39 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end( } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 -find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred) { - return _VSTD::__find_end::type>( - __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(), - typename iterator_traits<_ForwardIterator2>::iterator_category()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +_ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate& __pred) { + auto __proj = __identity(); + return std::__find_end_impl<_ClassicAlgPolicy>( + __first1, + __last1, + __first2, + __last2, + __pred, + __proj, + __proj, + typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()) + .first; +} + +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) { + return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 -find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; - typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; - return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + return std::find_end(__first1, __last1, __first2, __last2, __equal_to()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_FIND_END_OF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/find_first_of.h b/gnu/llvm/libcxx/include/__algorithm/find_first_of.h index d956c8dda2f..12f0109a616 100644 --- a/gnu/llvm/libcxx/include/__algorithm/find_first_of.h +++ b/gnu/llvm/libcxx/include/__algorithm/find_first_of.h @@ -10,24 +10,23 @@ #ifndef _LIBCPP___ALGORITHM_FIND_FIRST_OF_H #define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1, +_LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred) { + _ForwardIterator2 __last2, + _BinaryPredicate&& __pred) { for (; __first1 != __last1; ++__first1) for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) if (__pred(*__first1, *__j)) @@ -36,22 +35,18 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1 __find_first_of_ce(_ForwardItera } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 find_first_of( +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; - typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; - return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); + return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_FIND_FIRST_OF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/find_if.h b/gnu/llvm/libcxx/include/__algorithm/find_if.h index 456cc5b0a34..f4ef3ac31cf 100644 --- a/gnu/llvm/libcxx/include/__algorithm/find_if.h +++ b/gnu/llvm/libcxx/include/__algorithm/find_if.h @@ -13,16 +13,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) @@ -32,6 +29,4 @@ find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_FIND_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/find_if_not.h b/gnu/llvm/libcxx/include/__algorithm/find_if_not.h index d7d25160cc7..96c159cf5ed 100644 --- a/gnu/llvm/libcxx/include/__algorithm/find_if_not.h +++ b/gnu/llvm/libcxx/include/__algorithm/find_if_not.h @@ -13,16 +13,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) @@ -32,6 +29,4 @@ find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_FIND_IF_NOT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/for_each.h b/gnu/llvm/libcxx/include/__algorithm/for_each.h index e71a36a1de4..6564f31cd0e 100644 --- a/gnu/llvm/libcxx/include/__algorithm/for_each.h +++ b/gnu/llvm/libcxx/include/__algorithm/for_each.h @@ -13,16 +13,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Function for_each(_InputIterator __first, +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function for_each(_InputIterator __first, _InputIterator __last, _Function __f) { for (; __first != __last; ++__first) @@ -32,6 +29,4 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Function for_eac _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_FOR_EACH_H diff --git a/gnu/llvm/libcxx/include/__algorithm/for_each_n.h b/gnu/llvm/libcxx/include/__algorithm/for_each_n.h index 77f6c862145..38d204a1181 100644 --- a/gnu/llvm/libcxx/include/__algorithm/for_each_n.h +++ b/gnu/llvm/libcxx/include/__algorithm/for_each_n.h @@ -11,21 +11,19 @@ #define _LIBCPP___ALGORITHM_FOR_EACH_N_H #include <__config> +#include <__utility/convert_to_integral.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator for_each_n(_InputIterator __first, +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; @@ -42,6 +40,4 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator fo _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/generate.h b/gnu/llvm/libcxx/include/__algorithm/generate.h index d3e1133e2bc..48e21b51e6c 100644 --- a/gnu/llvm/libcxx/include/__algorithm/generate.h +++ b/gnu/llvm/libcxx/include/__algorithm/generate.h @@ -12,16 +12,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { @@ -31,6 +28,4 @@ generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_GENERATE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/generate_n.h b/gnu/llvm/libcxx/include/__algorithm/generate_n.h index c3125985861..45259989bf0 100644 --- a/gnu/llvm/libcxx/include/__algorithm/generate_n.h +++ b/gnu/llvm/libcxx/include/__algorithm/generate_n.h @@ -10,19 +10,17 @@ #define _LIBCPP___ALGORITHM_GENERATE_N_H #include <__config> +#include <__utility/convert_to_integral.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) { @@ -35,6 +33,4 @@ generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_GENERATE_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/half_positive.h b/gnu/llvm/libcxx/include/__algorithm/half_positive.h index b03efc495b1..74aede2b566 100644 --- a/gnu/llvm/libcxx/include/__algorithm/half_positive.h +++ b/gnu/llvm/libcxx/include/__algorithm/half_positive.h @@ -13,12 +13,9 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD // Perform division by two quickly for positive integers (llvm.org/PR39129) @@ -32,7 +29,7 @@ typename enable_if >::type __half_positive(_Integral __value) { - return static_cast<_Integral>(static_cast::type>(__value) / 2); + return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2); } template @@ -49,6 +46,4 @@ __half_positive(_Tp __value) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_HALF_POSITIVE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/in_found_result.h b/gnu/llvm/libcxx/include/__algorithm/in_found_result.h new file mode 100644 index 00000000000..3134d6e0df2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/in_found_result.h @@ -0,0 +1,49 @@ +// -*- 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___ALGORITHM_IN_FOUND_RESULT_H +#define _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +template +struct in_found_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; + bool found; + + template + requires convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const & { + return {in, found}; + } + + template + requires convertible_to<_InIter1, _InIter2> + _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() && { + return {std::move(in), found}; + } +}; +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/in_fun_result.h b/gnu/llvm/libcxx/include/__algorithm/in_fun_result.h new file mode 100644 index 00000000000..3cbb9e12d3b --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/in_fun_result.h @@ -0,0 +1,49 @@ +// -*- 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___ALGORITHM_IN_FUN_RESULT_H +#define _LIBCPP___ALGORITHM_IN_FUN_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { +template +struct in_fun_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; + _LIBCPP_NO_UNIQUE_ADDRESS _Func1 fun; + + template + requires convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const & { + return {in, fun}; + } + + template + requires convertible_to<_InIter1, _InIter2> && convertible_to<_Func1, _Func2> + _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() && { + return {std::move(in), std::move(fun)}; + } +}; +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_FUN_RESULT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/in_in_out_result.h b/gnu/llvm/libcxx/include/__algorithm/in_in_out_result.h new file mode 100644 index 00000000000..3e747be44d6 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/in_in_out_result.h @@ -0,0 +1,56 @@ +// -*- 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___ALGORITHM_IN_IN_OUT_RESULT_H +#define _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +struct in_in_out_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1; + _LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2; + _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; + + template + requires convertible_to + && convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& { + return {in1, in2, out}; + } + + template + requires convertible_to<_InIter1, _InIter3> + && convertible_to<_InIter2, _InIter4> && convertible_to<_OutIter1, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && { + return {std::move(in1), std::move(in2), std::move(out)}; + } +}; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/in_in_result.h b/gnu/llvm/libcxx/include/__algorithm/in_in_result.h new file mode 100644 index 00000000000..2098c188cc9 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/in_in_result.h @@ -0,0 +1,53 @@ +// -*- 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___ALGORITHM_IN_IN_RESULT_H +#define _LIBCPP___ALGORITHM_IN_IN_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +struct in_in_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1; + _LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2; + + template + requires convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_InIter3, _InIter4>() const & { + return {in1, in2}; + } + + template + requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_in_result<_InIter3, _InIter4>() && { + return {std::move(in1), std::move(in2)}; + } +}; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/in_out_out_result.h b/gnu/llvm/libcxx/include/__algorithm/in_out_out_result.h new file mode 100644 index 00000000000..4046eee57df --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/in_out_out_result.h @@ -0,0 +1,54 @@ +// -*- 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___ALGORITHM_IN_OUT_OUT_RESULT_H +#define _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { +template +struct in_out_out_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; + _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out1; + _LIBCPP_NO_UNIQUE_ADDRESS _OutIter2 out2; + + template + requires convertible_to + && convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& { + return {in, out1, out2}; + } + + template + requires convertible_to<_InIter1, _InIter2> + && convertible_to<_OutIter1, _OutIter3> && convertible_to<_OutIter2, _OutIter4> + _LIBCPP_HIDE_FROM_ABI constexpr + operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && { + return {std::move(in), std::move(out1), std::move(out2)}; + } +}; +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/in_out_result.h b/gnu/llvm/libcxx/include/__algorithm/in_out_result.h new file mode 100644 index 00000000000..7f5a0271b4c --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/in_out_result.h @@ -0,0 +1,53 @@ +// -*- 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___ALGORITHM_IN_OUT_RESULT_H +#define _LIBCPP___ALGORITHM_IN_OUT_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +struct in_out_result { + _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; + _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; + + template + requires convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InIter2, _OutIter2>() const & { + return {in, out}; + } + + template + requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter2> + _LIBCPP_HIDE_FROM_ABI + constexpr operator in_out_result<_InIter2, _OutIter2>() && { + return {std::move(in), std::move(out)}; + } +}; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/includes.h b/gnu/llvm/libcxx/include/__algorithm/includes.h index ff298a51118..cc39f275bf4 100644 --- a/gnu/llvm/libcxx/include/__algorithm/includes.h +++ b/gnu/llvm/libcxx/include/__algorithm/includes.h @@ -9,59 +9,67 @@ #ifndef _LIBCPP___ALGORITHM_INCLUDES_H #define _LIBCPP___ALGORITHM_INCLUDES_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> #include <__iterator/iterator_traits.h> +#include <__type_traits/is_callable.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 bool -__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, - _Compare __comp) -{ - for (; __first2 != __last2; ++__first1) - { - if (__first1 == __last1 || __comp(*__first2, *__first1)) - return false; - if (!__comp(*__first1, *__first2)) - ++__first2; - } - return true; +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Comp&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) { + for (; __first2 != __last2; ++__first1) { + if (__first1 == __last1 || std::__invoke( + __comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1))) + return false; + if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) + ++__first2; + } + return true; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -bool -includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, - _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _Compare __comp) { + static_assert(__is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, + "Comparator has to be callable"); + + return std::__includes( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + static_cast<__comp_ref_type<_Compare> >(__comp), + __identity(), + __identity()); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -bool -includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) -{ - return _VSTD::includes(__first1, __last1, __first2, __last2, - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { + return std::includes( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_INCLUDES_H diff --git a/gnu/llvm/libcxx/include/__algorithm/inplace_merge.h b/gnu/llvm/libcxx/include/__algorithm/inplace_merge.h index c74633a74cf..5bbefc94bdf 100644 --- a/gnu/llvm/libcxx/include/__algorithm/inplace_merge.h +++ b/gnu/llvm/libcxx/include/__algorithm/inplace_merge.h @@ -9,20 +9,28 @@ #ifndef _LIBCPP___ALGORITHM_INPLACE_MERGE_H #define _LIBCPP___ALGORITHM_INPLACE_MERGE_H -#include <__config> -#include <__algorithm/comp_ref_type.h> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/lower_bound.h> #include <__algorithm/min.h> #include <__algorithm/move.h> #include <__algorithm/rotate.h> #include <__algorithm/upper_bound.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/advance.h> +#include <__iterator/distance.h> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> -#include +#include <__iterator/reverse_iterator.h> +#include <__memory/destruct_n.h> +#include <__memory/temporary_buffer.h> +#include <__memory/unique_ptr.h> +#include <__utility/pair.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -50,72 +58,81 @@ public: bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} }; -template -void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, - _OutputIterator __result, _Compare __comp) +template +_LIBCPP_HIDE_FROM_ABI +void __half_inplace_merge(_InputIterator1 __first1, _Sent1 __last1, + _InputIterator2 __first2, _Sent2 __last2, + _OutputIterator __result, _Compare&& __comp) { for (; __first1 != __last1; ++__result) { if (__first2 == __last2) { - _VSTD::move(__first1, __last1, __result); + std::__move<_AlgPolicy>(__first1, __last1, __result); return; } if (__comp(*__first2, *__first1)) { - *__result = _VSTD::move(*__first2); + *__result = _IterOps<_AlgPolicy>::__iter_move(__first2); ++__first2; } else { - *__result = _VSTD::move(*__first1); + *__result = _IterOps<_AlgPolicy>::__iter_move(__first1); ++__first1; } } // __first2 through __last2 are already in the right spot. } -template -void -__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, - _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, - typename iterator_traits<_BidirectionalIterator>::difference_type __len2, - typename iterator_traits<_BidirectionalIterator>::value_type* __buff) -{ - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; +template +_LIBCPP_HIDE_FROM_ABI +void __buffered_inplace_merge( + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare&& __comp, + typename iterator_traits<_BidirectionalIterator>::difference_type __len1, + typename iterator_traits<_BidirectionalIterator>::difference_type __len2, + typename iterator_traits<_BidirectionalIterator>::value_type* __buff) { + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; __destruct_n __d(0); unique_ptr __h2(__buff, __d); if (__len1 <= __len2) { value_type* __p = __buff; for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr(), (void) ++__i, (void) ++__p) - ::new ((void*)__p) value_type(_VSTD::move(*__i)); - _VSTD::__half_inplace_merge<_Compare>(__buff, __p, __middle, __last, __first, __comp); + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); + std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp); } else { value_type* __p = __buff; for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr(), (void) ++__i, (void) ++__p) - ::new ((void*)__p) value_type(_VSTD::move(*__i)); - typedef reverse_iterator<_BidirectionalIterator> _RBi; - typedef reverse_iterator _Rv; + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); + typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi; + typedef __unconstrained_reverse_iterator _Rv; typedef __invert<_Compare> _Inverted; - _VSTD::__half_inplace_merge<_Inverted>(_Rv(__p), _Rv(__buff), + std::__half_inplace_merge<_AlgPolicy>(_Rv(__p), _Rv(__buff), _RBi(__middle), _RBi(__first), _RBi(__last), _Inverted(__comp)); } } -template -void -__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, - _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1, - typename iterator_traits<_BidirectionalIterator>::difference_type __len2, - typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size) -{ +template +void __inplace_merge( + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare&& __comp, + typename iterator_traits<_BidirectionalIterator>::difference_type __len1, + typename iterator_traits<_BidirectionalIterator>::difference_type __len2, + typename iterator_traits<_BidirectionalIterator>::value_type* __buff, + ptrdiff_t __buff_size) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; while (true) { @@ -123,7 +140,7 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, if (__len2 == 0) return; if (__len1 <= __buff_size || __len2 <= __buff_size) - return _VSTD::__buffered_inplace_merge<_Compare> + return std::__buffered_inplace_merge<_AlgPolicy> (__first, __middle, __last, __comp, __len1, __len2, __buff); // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 for (; true; ++__first, (void) --__len1) @@ -150,36 +167,36 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, { // __len >= 1, __len2 >= 2 __len21 = __len2 / 2; __m2 = __middle; - _VSTD::advance(__m2, __len21); - __m1 = _VSTD::__upper_bound<_Compare>(__first, __middle, *__m2, __comp); - __len11 = _VSTD::distance(__first, __m1); + _Ops::advance(__m2, __len21); + __m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity()); + __len11 = _Ops::distance(__first, __m1); } else { if (__len1 == 1) { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 // It is known *__first > *__middle - swap(*__first, *__middle); + _Ops::iter_swap(__first, __middle); return; } // __len1 >= 2, __len2 >= 1 __len11 = __len1 / 2; __m1 = __first; - _VSTD::advance(__m1, __len11); - __m2 = _VSTD::__lower_bound<_Compare>(__middle, __last, *__m1, __comp); - __len21 = _VSTD::distance(__middle, __m2); + _Ops::advance(__m1, __len11); + __m2 = std::lower_bound(__middle, __last, *__m1, __comp); + __len21 = _Ops::distance(__middle, __m2); } difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) difference_type __len22 = __len2 - __len21; // distance(__m2, __last) // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) // swap middle two partitions - __middle = _VSTD::rotate(__m1, __middle, __m2); + __middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first; // __len12 and __len21 now have swapped meanings // merge smaller range with recursive call and larger with tail recursion elimination if (__len11 + __len21 < __len12 + __len22) { - _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); -// _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); + std::__inplace_merge<_AlgPolicy>( + __first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); __first = __middle; __middle = __m2; __len1 = __len12; @@ -187,8 +204,8 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, } else { - _VSTD::__inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); -// _VSTD::__inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); + std::__inplace_merge<_AlgPolicy>( + __middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); __last = __middle; __middle = __m1; __len1 = __len11; @@ -197,30 +214,39 @@ __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, } } -template -inline _LIBCPP_INLINE_VISIBILITY +template +_LIBCPP_HIDE_FROM_ABI void -inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, - _Compare __comp) +__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, + _Compare&& __comp) { typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; - difference_type __len1 = _VSTD::distance(__first, __middle); - difference_type __len2 = _VSTD::distance(__middle, __last); + difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); + difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); difference_type __buf_size = _VSTD::min(__len1, __len2); +// TODO: Remove the use of std::get_temporary_buffer +_LIBCPP_SUPPRESS_DEPRECATED_PUSH pair __buf = _VSTD::get_temporary_buffer(__buf_size); +_LIBCPP_SUPPRESS_DEPRECATED_POP unique_ptr __h(__buf.first); - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2, - __buf.first, __buf.second); + return std::__inplace_merge<_AlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second); +} + +template +inline _LIBCPP_HIDE_FROM_ABI void inplace_merge( + _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) { + std::__inplace_merge<_ClassicAlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)); } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI void inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) { - _VSTD::inplace_merge(__first, __middle, __last, + std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less::value_type>()); } diff --git a/gnu/llvm/libcxx/include/__algorithm/is_heap.h b/gnu/llvm/libcxx/include/__algorithm/is_heap.h index bc3682d471a..2dcb4a28e8d 100644 --- a/gnu/llvm/libcxx/include/__algorithm/is_heap.h +++ b/gnu/llvm/libcxx/include/__algorithm/is_heap.h @@ -9,32 +9,30 @@ #ifndef _LIBCPP___ALGORITHM_IS_HEAP_H #define _LIBCPP___ALGORITHM_IS_HEAP_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> #include <__algorithm/is_heap_until.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - return _VSTD::is_heap_until(__first, __last, __comp) == __last; + return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last; } template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { @@ -43,6 +41,4 @@ is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_IS_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/is_heap_until.h b/gnu/llvm/libcxx/include/__algorithm/is_heap_until.h index 8c52edb7d49..6ed4cb29c42 100644 --- a/gnu/llvm/libcxx/include/__algorithm/is_heap_until.h +++ b/gnu/llvm/libcxx/include/__algorithm/is_heap_until.h @@ -9,22 +9,20 @@ #ifndef _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H #define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator -is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; difference_type __len = __last - __first; @@ -49,17 +47,20 @@ is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp return __last; } +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +{ + return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); +} + template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_RandomAccessIterator +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) { - return _VSTD::is_heap_until(__first, __last, __less::value_type>()); + return _VSTD::__is_heap_until(__first, __last, __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H diff --git a/gnu/llvm/libcxx/include/__algorithm/is_partitioned.h b/gnu/llvm/libcxx/include/__algorithm/is_partitioned.h index 43de6650cbd..ab59d3cce58 100644 --- a/gnu/llvm/libcxx/include/__algorithm/is_partitioned.h +++ b/gnu/llvm/libcxx/include/__algorithm/is_partitioned.h @@ -12,16 +12,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) @@ -38,6 +35,4 @@ is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_IS_PARTITIONED_H diff --git a/gnu/llvm/libcxx/include/__algorithm/is_permutation.h b/gnu/llvm/libcxx/include/__algorithm/is_permutation.h index 0545eb76370..005445652e9 100644 --- a/gnu/llvm/libcxx/include/__algorithm/is_permutation.h +++ b/gnu/llvm/libcxx/include/__algorithm/is_permutation.h @@ -11,158 +11,228 @@ #define _LIBCPP___ALGORITHM_IS_PERMUTATION_H #include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> #include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__iterator/next.h> -#include // FIXME: replace with <__iterator/distance.h> when it lands +#include <__utility/move.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 bool -is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _BinaryPredicate __pred) { - // shorten sequences as much as possible by lopping of any equal prefix - for (; __first1 != __last1; ++__first1, (void)++__first2) - if (!__pred(*__first1, *__first2)) - break; - if (__first1 == __last1) - return true; +template +struct _ConstTimeDistance : false_type {}; - // __first1 != __last1 && *__first1 != *__first2 - typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; - _D1 __l1 = _VSTD::distance(__first1, __last1); - if (__l1 == _D1(1)) - return false; - _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1); - // For each element in [f1, l1) see if there are the same number of - // equal elements in [f2, l2) - for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) { +#if _LIBCPP_STD_VER > 17 + +template +struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t< + sized_sentinel_for<_Sent1, _Iter1> && + sized_sentinel_for<_Sent2, _Iter2> +>> : true_type {}; + +#else + +template +struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t< + is_same::iterator_category, random_access_iterator_tag>::value && + is_same::iterator_category, random_access_iterator_tag>::value +> > : true_type {}; + +#endif // _LIBCPP_STD_VER > 17 + +// Internal functions + +// For each element in [f1, l1) see if there are the same number of equal elements in [f2, l2) +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { + using _D1 = __iter_diff_t<_Iter1>; + + for (auto __i = __first1; __i != __last1; ++__i) { // Have we already counted the number of *__i in [f1, l1)? - _ForwardIterator1 __match = __first1; - for (; __match != __i; ++__match) - if (__pred(*__match, *__i)) + auto __match = __first1; + for (; __match != __i; ++__match) { + if (std::__invoke(__pred, std::__invoke(__proj1, *__match), std::__invoke(__proj1, *__i))) break; + } + if (__match == __i) { // Count number of *__i in [f2, l2) _D1 __c2 = 0; - for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) - if (__pred(*__i, *__j)) + for (auto __j = __first2; __j != __last2; ++__j) { + if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj2, *__j))) ++__c2; + } if (__c2 == 0) return false; + // Count number of *__i in [__i, l1) (we can start with 1) _D1 __c1 = 1; - for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) - if (__pred(*__i, *__j)) + for (auto __j = _IterOps<_AlgPolicy>::next(__i); __j != __last1; ++__j) { + if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj1, *__j))) ++__c1; + } if (__c1 != __c2) return false; } } + return true; } -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool -is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { - typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; - typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; - return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>()); +// 2+1 iterators, predicate. Not used by range algorithms. +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, + _BinaryPredicate&& __pred) { + // Shorten sequences as much as possible by lopping of any equal prefix. + for (; __first1 != __last1; ++__first1, (void)++__first2) { + if (!__pred(*__first1, *__first2)) + break; + } + + if (__first1 == __last1) + return true; + + // __first1 != __last1 && *__first1 != *__first2 + using _D1 = __iter_diff_t<_ForwardIterator1>; + _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); + if (__l1 == _D1(1)) + return false; + auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __l1); + + return std::__is_permutation_impl<_AlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __identity(), __identity()); } -#if _LIBCPP_STD_VER > 11 -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 bool -__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) { - // shorten sequences as much as possible by lopping of any equal prefix - for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) - if (!__pred(*__first1, *__first2)) +// 2+2 iterators, predicate, non-constant time `distance`. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, + /*_ConstTimeDistance=*/false_type) { + // Shorten sequences as much as possible by lopping of any equal prefix. + while (__first1 != __last1 && __first2 != __last2) { + if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) break; + ++__first1; + ++__first2; + } + if (__first1 == __last1) return __first2 == __last2; - else if (__first2 == __last2) + if (__first2 == __last2) // Second range is shorter return false; - typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; - _D1 __l1 = _VSTD::distance(__first1, __last1); + using _D1 = __iter_diff_t<_Iter1>; + _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); - typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2; - _D2 __l2 = _VSTD::distance(__first2, __last2); + using _D2 = __iter_diff_t<_Iter2>; + _D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2); if (__l1 != __l2) return false; - // For each element in [f1, l1) see if there are the same number of - // equal elements in [f2, l2) - for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) { - // Have we already counted the number of *__i in [f1, l1)? - _ForwardIterator1 __match = __first1; - for (; __match != __i; ++__match) - if (__pred(*__match, *__i)) - break; - if (__match == __i) { - // Count number of *__i in [f2, l2) - _D1 __c2 = 0; - for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) - if (__pred(*__i, *__j)) - ++__c2; - if (__c2 == 0) - return false; - // Count number of *__i in [__i, l1) (we can start with 1) - _D1 __c1 = 1; - for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j) - if (__pred(*__i, *__j)) - ++__c1; - if (__c1 != __c2) - return false; - } - } - return true; + return std::__is_permutation_impl<_AlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2); } -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1, - _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, - _BinaryPredicate __pred, random_access_iterator_tag, - random_access_iterator_tag) { - if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) +// 2+2 iterators, predicate, specialization for constant-time `distance` call. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, + /*_ConstTimeDistance=*/true_type) { + if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) return false; - return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2, - typename add_lvalue_reference<_BinaryPredicate>::type>(__first1, __last1, __first2, - __pred); + return std::__is_permutation<_AlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2, + /*_ConstTimeDistance=*/false_type()); +} + +// 2+2 iterators, predicate +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { + return std::__is_permutation<_AlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2, + _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2>()); } +// Public interface + +// 2+1 iterators, predicate template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred) { - return _VSTD::__is_permutation::type>( - __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_ForwardIterator1>::iterator_category(), - typename iterator_traits<_ForwardIterator2>::iterator_category()); + _BinaryPredicate __pred) { + static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, + "The predicate has to be callable"); + + return std::__is_permutation<_ClassicAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), __pred); } +// 2+1 iterators +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + return std::is_permutation(__first1, __last1, __first2, __equal_to()); +} + +#if _LIBCPP_STD_VER > 11 + +// 2+2 iterators template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( + _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + return std::__is_permutation<_ClassicAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __equal_to(), + __identity(), + __identity()); +} + +// 2+2 iterators, predicate +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2) { - typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; - typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; - return _VSTD::__is_permutation(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(), - typename iterator_traits<_ForwardIterator1>::iterator_category(), - typename iterator_traits<_ForwardIterator2>::iterator_category()); + _ForwardIterator2 __last2, _BinaryPredicate __pred) { + static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, + "The predicate has to be callable"); + + return std::__is_permutation<_ClassicAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __identity(), __identity()); } -#endif -_LIBCPP_END_NAMESPACE_STD +#endif // _LIBCPP_STD_VER > 11 -_LIBCPP_POP_MACROS +_LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/is_sorted.h b/gnu/llvm/libcxx/include/__algorithm/is_sorted.h index 30d8da0499e..bf44f45764d 100644 --- a/gnu/llvm/libcxx/include/__algorithm/is_sorted.h +++ b/gnu/llvm/libcxx/include/__algorithm/is_sorted.h @@ -10,31 +10,29 @@ #define _LIBCPP___ALGORITHM_IS_SORTED_H #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> #include <__algorithm/is_sorted_until.h> #include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - return _VSTD::is_sorted_until(__first, __last, __comp) == __last; + return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last; } template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_sorted(_ForwardIterator __first, _ForwardIterator __last) { @@ -43,6 +41,4 @@ is_sorted(_ForwardIterator __first, _ForwardIterator __last) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_IS_SORTED_H diff --git a/gnu/llvm/libcxx/include/__algorithm/is_sorted_until.h b/gnu/llvm/libcxx/include/__algorithm/is_sorted_until.h index a914b5a566b..b6683000a06 100644 --- a/gnu/llvm/libcxx/include/__algorithm/is_sorted_until.h +++ b/gnu/llvm/libcxx/include/__algorithm/is_sorted_until.h @@ -9,22 +9,20 @@ #ifndef _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H #define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { if (__first != __last) { @@ -39,10 +37,15 @@ is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __co return __last; } +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp); +} + template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) { return _VSTD::is_sorted_until(__first, __last, __less::value_type>()); @@ -50,6 +53,4 @@ is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H diff --git a/gnu/llvm/libcxx/include/__algorithm/iter_swap.h b/gnu/llvm/libcxx/include/__algorithm/iter_swap.h index b63bce62cc0..44422b5de0f 100644 --- a/gnu/llvm/libcxx/include/__algorithm/iter_swap.h +++ b/gnu/llvm/libcxx/include/__algorithm/iter_swap.h @@ -14,24 +14,19 @@ #include <__utility/swap.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void iter_swap(_ForwardIterator1 __a, +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) - _NOEXCEPT_(_NOEXCEPT_(swap(*declval<_ForwardIterator1>(), *declval<_ForwardIterator2>()))) { + _NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) { swap(*__a, *__b); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_ITER_SWAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/iterator_operations.h b/gnu/llvm/libcxx/include/__algorithm/iterator_operations.h new file mode 100644 index 00000000000..bd3e6f1d38f --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/iterator_operations.h @@ -0,0 +1,175 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_ITERATOR_OPERATIONS_H +#define _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H + +#include <__algorithm/iter_swap.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__config> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/prev.h> +#include <__iterator/readable_traits.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/is_same.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template struct _IterOps; + +#if _LIBCPP_STD_VER > 17 +struct _RangeAlgPolicy {}; + +template <> +struct _IterOps<_RangeAlgPolicy> { + + template + using __value_type = iter_value_t<_Iter>; + + template + using __iterator_category = ranges::__iterator_concept<_Iter>; + + template + using __difference_type = iter_difference_t<_Iter>; + + static constexpr auto advance = ranges::advance; + static constexpr auto distance = ranges::distance; + static constexpr auto __iter_move = ranges::iter_move; + static constexpr auto iter_swap = ranges::iter_swap; + static constexpr auto next = ranges::next; + static constexpr auto prev = ranges::prev; + static constexpr auto __advance_to = ranges::advance; +}; + +#endif + +struct _ClassicAlgPolicy {}; + +template <> +struct _IterOps<_ClassicAlgPolicy> { + + template + using __value_type = typename iterator_traits<_Iter>::value_type; + + template + using __iterator_category = typename iterator_traits<_Iter>::iterator_category; + + template + using __difference_type = typename iterator_traits<_Iter>::difference_type; + + // advance + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + static void advance(_Iter& __iter, _Distance __count) { + std::advance(__iter, __count); + } + + // distance + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + static typename iterator_traits<_Iter>::difference_type distance(_Iter __first, _Iter __last) { + return std::distance(__first, __last); + } + + template + using __deref_t = decltype(*std::declval<_Iter&>()); + + template + using __move_t = decltype(std::move(*std::declval<_Iter&>())); + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + static void __validate_iter_reference() { + static_assert(is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value, + "It looks like your iterator's `iterator_traits::reference` does not match the return type of " + "dereferencing the iterator, i.e., calling `*it`. This is undefined behavior according to [input.iterators] " + "and can lead to dangling reference issues at runtime, so we are flagging this."); + } + + // iter_move + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static + // If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it. Note + // that the C++03 mode doesn't support `decltype(auto)` as the return type. + __enable_if_t< + is_reference<__deref_t<_Iter> >::value, + __move_t<_Iter> > + __iter_move(_Iter&& __i) { + __validate_iter_reference<_Iter>(); + + return std::move(*std::forward<_Iter>(__i)); + } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static + // If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a + // value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to that + // temporary. Note that the C++03 mode doesn't support `auto` as the return type. + __enable_if_t< + !is_reference<__deref_t<_Iter> >::value, + __deref_t<_Iter> > + __iter_move(_Iter&& __i) { + __validate_iter_reference<_Iter>(); + + return *std::forward<_Iter>(__i); + } + + // iter_swap + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + static void iter_swap(_Iter1&& __a, _Iter2&& __b) { + std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b)); + } + + // next + template + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 + _Iterator next(_Iterator, _Iterator __last) { + return __last; + } + + template + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 + __remove_cvref_t<_Iter> next(_Iter&& __it, + typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { + return std::next(std::forward<_Iter>(__it), __n); + } + + // prev + template + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 + __remove_cvref_t<_Iter> prev(_Iter&& __iter, + typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { + return std::prev(std::forward<_Iter>(__iter), __n); + } + + template + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 + void __advance_to(_Iter& __first, _Iter __last) { + __first = __last; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H diff --git a/gnu/llvm/libcxx/include/__algorithm/lexicographical_compare.h b/gnu/llvm/libcxx/include/__algorithm/lexicographical_compare.h index 6e4a90bdc03..0a13c5dd31c 100644 --- a/gnu/llvm/libcxx/include/__algorithm/lexicographical_compare.h +++ b/gnu/llvm/libcxx/include/__algorithm/lexicographical_compare.h @@ -9,22 +9,19 @@ #ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H #define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { @@ -40,18 +37,17 @@ __lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); + return _VSTD::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp); } template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) @@ -63,6 +59,4 @@ lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/lower_bound.h b/gnu/llvm/libcxx/include/__algorithm/lower_bound.h index 1448c896332..2648982ea50 100644 --- a/gnu/llvm/libcxx/include/__algorithm/lower_bound.h +++ b/gnu/llvm/libcxx/include/__algorithm/lower_bound.h @@ -9,64 +9,60 @@ #ifndef _LIBCPP___ALGORITHM_LOWER_BOUND_H #define _LIBCPP___ALGORITHM_LOWER_BOUND_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/half_positive.h> -#include +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_callable.h> +#include <__type_traits/remove_reference.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) -{ - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - difference_type __len = _VSTD::distance(__first, __last); - while (__len != 0) - { - difference_type __l2 = _VSTD::__half_positive(__len); - _ForwardIterator __m = __first; - _VSTD::advance(__m, __l2); - if (__comp(*__m, __value_)) - { - __first = ++__m; - __len -= __l2 + 1; - } - else - __len = __l2; +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { + auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); + + while (__len != 0) { + auto __l2 = std::__half_positive(__len); + _Iter __m = __first; + _IterOps<_AlgPolicy>::advance(__m, __l2); + if (std::__invoke(__comp, std::__invoke(__proj, *__m), __value)) { + __first = ++__m; + __len -= __l2 + 1; + } else { + __len = __l2; } - return __first; + } + return __first; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator -lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) -{ - typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; - return _VSTD::__lower_bound<_Comp_ref>(__first, __last, __value_, __comp); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, + "The comparator has to be callable"); + auto __proj = std::__identity(); + return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator -lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) -{ - return _VSTD::lower_bound(__first, __last, __value_, - __less::value_type, _Tp>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::lower_bound(__first, __last, __value, + __less::value_type, _Tp>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_LOWER_BOUND_H diff --git a/gnu/llvm/libcxx/include/__algorithm/make_heap.h b/gnu/llvm/libcxx/include/__algorithm/make_heap.h index eca4013cbd1..d66cfe2e5fc 100644 --- a/gnu/llvm/libcxx/include/__algorithm/make_heap.h +++ b/gnu/llvm/libcxx/include/__algorithm/make_heap.h @@ -9,56 +9,48 @@ #ifndef _LIBCPP___ALGORITHM_MAKE_HEAP_H #define _LIBCPP___ALGORITHM_MAKE_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/sift_down.h> +#include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 void -__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - difference_type __n = __last - __first; - if (__n > 1) - { - // start from the first parent, there is no need to consider children - for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) - { - _VSTD::__sift_down<_Compare>(__first, __last, __comp, __n, __first + __start); - } +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { + __comp_ref_type<_Compare> __comp_ref = __comp; + + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + difference_type __n = __last - __first; + if (__n > 1) { + // start from the first parent, there is no need to consider children + for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) { + std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start); } + } } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - _VSTD::__make_heap<_Comp_ref>(__first, __last, __comp); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - _VSTD::make_heap(__first, __last, __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::make_heap(std::move(__first), std::move(__last), + __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/make_projected.h b/gnu/llvm/libcxx/include/__algorithm/make_projected.h new file mode 100644 index 00000000000..87d4d59042c --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/make_projected.h @@ -0,0 +1,126 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_MAKE_PROJECTED_H +#define _LIBCPP___ALGORITHM_MAKE_PROJECTED_H + +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__type_traits/decay.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_member_pointer.h> +#include <__type_traits/is_same.h> +#include <__utility/declval.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _ProjectedPred { + _Pred& __pred; // Can be a unary or a binary predicate. + _Proj& __proj; + + _LIBCPP_CONSTEXPR _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg) : __pred(__pred_arg), __proj(__proj_arg) {} + + template + typename __invoke_of<_Pred&, + decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>())) + >::type + _LIBCPP_CONSTEXPR operator()(_Tp&& __v) const { + return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v))); + } + + template + typename __invoke_of<_Pred&, + decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())), + decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>())) + >::type + _LIBCPP_CONSTEXPR operator()(_T1&& __lhs, _T2&& __rhs) const { + return std::__invoke(__pred, + std::__invoke(__proj, std::forward<_T1>(__lhs)), + std::__invoke(__proj, std::forward<_T2>(__rhs))); + } + +}; + +template +struct __can_use_pristine_comp : false_type {}; + +template +struct __can_use_pristine_comp<_Pred, _Proj, __enable_if_t< + !is_member_pointer::type>::value && ( +#if _LIBCPP_STD_VER > 17 + is_same::type, identity>::value || +#endif + is_same::type, __identity>::value + ) +> > : true_type {}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static +__enable_if_t< + !__can_use_pristine_comp<_Pred, _Proj>::value, + _ProjectedPred<_Pred, _Proj> +> +__make_projected(_Pred& __pred, _Proj& __proj) { + return _ProjectedPred<_Pred, _Proj>(__pred, __proj); +} + +// Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable +// optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in +// the call stack when the comparator is invoked, even in an unoptimized build. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static +__enable_if_t< + __can_use_pristine_comp<_Pred, _Proj>::value, + _Pred& +> +__make_projected(_Pred& __pred, _Proj&) { + return __pred; +} + +_LIBCPP_END_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr static +decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) { + if constexpr (same_as, identity> && same_as, identity> && + !is_member_pointer_v>) { + // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable + // optimizations that rely on the type of the comparator. + return __comp; + + } else { + return [&](auto&& __lhs, auto&& __rhs) { + return std::invoke(__comp, + std::invoke(__proj1, std::forward(__lhs)), + std::invoke(__proj2, std::forward(__rhs))); + }; + } +} + +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H diff --git a/gnu/llvm/libcxx/include/__algorithm/max.h b/gnu/llvm/libcxx/include/__algorithm/max.h index 2fa97cad87f..a08a3fc59bd 100644 --- a/gnu/llvm/libcxx/include/__algorithm/max.h +++ b/gnu/llvm/libcxx/include/__algorithm/max.h @@ -9,13 +9,14 @@ #ifndef _LIBCPP___ALGORITHM_MAX_H #define _LIBCPP___ALGORITHM_MAX_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> #include <__algorithm/max_element.h> +#include <__config> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -25,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) { @@ -34,7 +35,7 @@ max(const _Tp& __a, const _Tp& __b, _Compare __comp) template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& max(const _Tp& __a, const _Tp& __b) { @@ -45,16 +46,16 @@ max(const _Tp& __a, const _Tp& __b) template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t, _Compare __comp) { - return *_VSTD::max_element(__t.begin(), __t.end(), __comp); + return *_VSTD::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t) { diff --git a/gnu/llvm/libcxx/include/__algorithm/max_element.h b/gnu/llvm/libcxx/include/__algorithm/max_element.h index b93b67eacf5..6ac310619bf 100644 --- a/gnu/llvm/libcxx/include/__algorithm/max_element.h +++ b/gnu/llvm/libcxx/include/__algorithm/max_element.h @@ -9,24 +9,20 @@ #ifndef _LIBCPP___ALGORITHM_MAX_ELEMENT_H #define _LIBCPP___ALGORITHM_MAX_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -_ForwardIterator -max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, "std::max_element requires a ForwardIterator"); @@ -40,11 +36,16 @@ max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) return __first; } +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) +{ + return _VSTD::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp); +} + template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -_ForwardIterator +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last) { return _VSTD::max_element(__first, __last, @@ -53,6 +54,4 @@ max_element(_ForwardIterator __first, _ForwardIterator __last) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_MAX_ELEMENT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/merge.h b/gnu/llvm/libcxx/include/__algorithm/merge.h index ea53ad68f7f..e54e430bcb6 100644 --- a/gnu/llvm/libcxx/include/__algorithm/merge.h +++ b/gnu/llvm/libcxx/include/__algorithm/merge.h @@ -9,23 +9,20 @@ #ifndef _LIBCPP___ALGORITHM_MERGE_H #define _LIBCPP___ALGORITHM_MERGE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__config> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_CONSTEXPR_AFTER_CXX17 +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator __merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) @@ -49,17 +46,16 @@ __merge(_InputIterator1 __first1, _InputIterator1 __last1, } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); + return _VSTD::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) @@ -71,6 +67,4 @@ merge(_InputIterator1 __first1, _InputIterator1 __last1, _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_MERGE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/min.h b/gnu/llvm/libcxx/include/__algorithm/min.h index 9fea7f70a2b..2882485ad76 100644 --- a/gnu/llvm/libcxx/include/__algorithm/min.h +++ b/gnu/llvm/libcxx/include/__algorithm/min.h @@ -9,13 +9,14 @@ #ifndef _LIBCPP___ALGORITHM_MIN_H #define _LIBCPP___ALGORITHM_MIN_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> #include <__algorithm/min_element.h> +#include <__config> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -25,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) { @@ -34,7 +35,7 @@ min(const _Tp& __a, const _Tp& __b, _Compare __comp) template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& min(const _Tp& __a, const _Tp& __b) { @@ -45,16 +46,16 @@ min(const _Tp& __a, const _Tp& __b) template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t, _Compare __comp) { - return *_VSTD::min_element(__t.begin(), __t.end(), __comp); + return *_VSTD::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t) { diff --git a/gnu/llvm/libcxx/include/__algorithm/min_element.h b/gnu/llvm/libcxx/include/__algorithm/min_element.h index 6bff140e5d9..c0706fe9e44 100644 --- a/gnu/llvm/libcxx/include/__algorithm/min_element.h +++ b/gnu/llvm/libcxx/include/__algorithm/min_element.h @@ -9,41 +9,56 @@ #ifndef _LIBCPP___ALGORITHM_MIN_ELEMENT_H #define _LIBCPP___ALGORITHM_MIN_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/comp_ref_type.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> #include <__iterator/iterator_traits.h> +#include <__type_traits/is_callable.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) { + if (__first == __last) + return __first; + + _Iter __i = __first; + while (++__i != __last) + if (std::__invoke(__comp, std::__invoke(__proj, *__i), std::__invoke(__proj, *__first))) + __first = __i; + + return __first; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) { + auto __proj = __identity(); + return std::__min_element<_Comp>(std::move(__first), std::move(__last), __comp, __proj); +} + template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -_ForwardIterator +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, - "std::min_element requires a ForwardIterator"); - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - if (__comp(*__i, *__first)) - __first = __i; - } - return __first; + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, + "std::min_element requires a ForwardIterator"); + static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, + "The comparator has to be callable"); + + return std::__min_element<__comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -_ForwardIterator +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last) { return _VSTD::min_element(__first, __last, @@ -52,6 +67,4 @@ min_element(_ForwardIterator __first, _ForwardIterator __last) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/min_max_result.h b/gnu/llvm/libcxx/include/__algorithm/min_max_result.h new file mode 100644 index 00000000000..4be39992b42 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/min_max_result.h @@ -0,0 +1,56 @@ +// -*- 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___ALGORITHM_MIN_MAX_RESULT_H +#define _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +struct min_max_result { + _LIBCPP_NO_UNIQUE_ADDRESS _T1 min; + _LIBCPP_NO_UNIQUE_ADDRESS _T1 max; + + template + requires convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const & { + return {min, max}; + } + + template + requires convertible_to<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() && { + return {std::move(min), std::move(max)}; + } +}; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/minmax.h b/gnu/llvm/libcxx/include/__algorithm/minmax.h index 63753f2fecd..6ef0a777083 100644 --- a/gnu/llvm/libcxx/include/__algorithm/minmax.h +++ b/gnu/llvm/libcxx/include/__algorithm/minmax.h @@ -9,24 +9,23 @@ #ifndef _LIBCPP___ALGORITHM_MINMAX_H #define _LIBCPP___ALGORITHM_MINMAX_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/minmax_element.h> +#include <__config> +#include <__functional/identity.h> +#include <__type_traits/is_callable.h> +#include <__utility/pair.h> #include -#include - #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 pair minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) { @@ -36,66 +35,35 @@ minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 pair minmax(const _Tp& __a, const _Tp& __b) { - return _VSTD::minmax(__a, __b, __less<_Tp>()); + return std::minmax(__a, __b, __less<_Tp>()); } #ifndef _LIBCPP_CXX03_LANG template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -pair<_Tp, _Tp> -minmax(initializer_list<_Tp> __t, _Compare __comp) -{ - typedef typename initializer_list<_Tp>::const_iterator _Iter; - _Iter __first = __t.begin(); - _Iter __last = __t.end(); - pair<_Tp, _Tp> __result(*__first, *__first); - - ++__first; - if (__t.size() % 2 == 0) - { - if (__comp(*__first, __result.first)) - __result.first = *__first; - else - __result.second = *__first; - ++__first; - } - - while (__first != __last) - { - _Tp __prev = *__first++; - if (__comp(*__first, __prev)) { - if ( __comp(*__first, __result.first)) __result.first = *__first; - if (!__comp(__prev, __result.second)) __result.second = __prev; - } - else { - if ( __comp(__prev, __result.first)) __result.first = __prev; - if (!__comp(*__first, __result.second)) __result.second = *__first; - } - - __first++; - } - return __result; +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) { + static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); + __identity __proj; + auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj); + return pair<_Tp, _Tp>(*__ret.first, *__ret.second); } template _LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t) { - return _VSTD::minmax(__t, __less<_Tp>()); + return std::minmax(__t, __less<_Tp>()); } #endif // _LIBCPP_CXX03_LANG _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_MINMAX_H diff --git a/gnu/llvm/libcxx/include/__algorithm/minmax_element.h b/gnu/llvm/libcxx/include/__algorithm/minmax_element.h index 1eba006de9a..caa963e112e 100644 --- a/gnu/llvm/libcxx/include/__algorithm/minmax_element.h +++ b/gnu/llvm/libcxx/include/__algorithm/minmax_element.h @@ -9,82 +9,93 @@ #ifndef _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H #define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> +#include <__functional/identity.h> #include <__iterator/iterator_traits.h> -#include +#include <__utility/pair.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +template +class _MinmaxElementLessFunc { + _Comp& __comp_; + _Proj& __proj_; + +public: + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR + _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj) : __comp_(__comp), __proj_(__proj) {} + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool operator()(_Iter& __it1, _Iter& __it2) { + return std::__invoke(__comp_, std::__invoke(__proj_, *__it1), std::__invoke(__proj_, *__it2)); + } +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj); + + pair<_Iter, _Iter> __result(__first, __first); + if (__first == __last || ++__first == __last) + return __result; + + if (__less(__first, __result.first)) + __result.first = __first; + else + __result.second = __first; + + while (++__first != __last) { + _Iter __i = __first; + if (++__first == __last) { + if (__less(__i, __result.first)) + __result.first = __i; + else if (!__less(__i, __result.second)) + __result.second = __i; + return __result; + } + + if (__less(__first, __i)) { + if (__less(__first, __result.first)) + __result.first = __first; + if (!__less(__i, __result.second)) + __result.second = __i; + } else { + if (__less(__i, __result.first)) + __result.first = __i; + if (!__less(__first, __result.second)) + __result.second = __first; + } + } + + return __result; +} + template -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> -minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ +minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, - "std::minmax_element requires a ForwardIterator"); - pair<_ForwardIterator, _ForwardIterator> __result(__first, __first); - if (__first != __last) - { - if (++__first != __last) - { - if (__comp(*__first, *__result.first)) - __result.first = __first; - else - __result.second = __first; - while (++__first != __last) - { - _ForwardIterator __i = __first; - if (++__first == __last) - { - if (__comp(*__i, *__result.first)) - __result.first = __i; - else if (!__comp(*__i, *__result.second)) - __result.second = __i; - break; - } - else - { - if (__comp(*__first, *__i)) - { - if (__comp(*__first, *__result.first)) - __result.first = __first; - if (!__comp(*__i, *__result.second)) - __result.second = __i; - } - else - { - if (__comp(*__i, *__result.first)) - __result.first = __i; - if (!__comp(*__first, *__result.second)) - __result.second = __first; - } - } - } - } - } - return __result; + "std::minmax_element requires a ForwardIterator"); + static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, + "The comparator has to be callable"); + auto __proj = __identity(); + return std::__minmax_element_impl(__first, __last, __comp, __proj); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -pair<_ForwardIterator, _ForwardIterator> -minmax_element(_ForwardIterator __first, _ForwardIterator __last) -{ - return _VSTD::minmax_element(__first, __last, - __less::value_type>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) { + return std::minmax_element(__first, __last, __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/mismatch.h b/gnu/llvm/libcxx/include/__algorithm/mismatch.h index fdd2bc8c09c..600e2cdd3da 100644 --- a/gnu/llvm/libcxx/include/__algorithm/mismatch.h +++ b/gnu/llvm/libcxx/include/__algorithm/mismatch.h @@ -10,23 +10,20 @@ #ifndef _LIBCPP___ALGORITHM_MISMATCH_H #define _LIBCPP___ALGORITHM_MISMATCH_H -#include <__config> #include <__algorithm/comp.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> + _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { for (; __first1 != __last1; ++__first1, (void)++__first2) if (!__pred(*__first1, *__first2)) @@ -36,17 +33,15 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY template _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> + _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { - typedef typename iterator_traits<_InputIterator1>::value_type __v1; - typedef typename iterator_traits<_InputIterator2>::value_type __v2; - return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>()); + return std::mismatch(__first1, __last1, __first2, __equal_to()); } #if _LIBCPP_STD_VER > 11 template _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> + _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred) { for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) @@ -57,16 +52,12 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY template _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> + _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { - typedef typename iterator_traits<_InputIterator1>::value_type __v1; - typedef typename iterator_traits<_InputIterator2>::value_type __v2; - return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); + return std::mismatch(__first1, __last1, __first2, __last2, __equal_to()); } #endif _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_MISMATCH_H diff --git a/gnu/llvm/libcxx/include/__algorithm/move.h b/gnu/llvm/libcxx/include/__algorithm/move.h index f5fc74854f0..ac95bda7b61 100644 --- a/gnu/llvm/libcxx/include/__algorithm/move.h +++ b/gnu/llvm/libcxx/include/__algorithm/move.h @@ -9,15 +9,18 @@ #ifndef _LIBCPP___ALGORITHM_MOVE_H #define _LIBCPP___ALGORITHM_MOVE_H +#include <__algorithm/copy_move_common.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> #include <__config> -#include <__algorithm/unwrap_iter.h> +#include <__iterator/segmented_iterator.h> +#include <__type_traits/common_type.h> +#include <__type_traits/is_copy_constructible.h> #include <__utility/move.h> -#include -#include -#include +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -25,55 +28,99 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -// move +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> +__move(_InIter __first, _Sent __last, _OutIter __result); -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -_OutputIterator -__move_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - for (; __first != __last; ++__first, (void) ++__result) - *__result = _VSTD::move(*__first); - return __result; -} +template +struct __move_loop { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { + while (__first != __last) { + *__result = _IterOps<_AlgPolicy>::__iter_move(__first); + ++__first; + ++__result; + } + return std::make_pair(std::move(__first), std::move(__result)); + } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -_OutputIterator -__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - return _VSTD::__move_constexpr(__first, __last, __result); -} + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) const { + using _Traits = __segmented_iterator_traits<_InIter>; + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + if (__sfirst == __slast) { + auto __iters = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); + return std::make_pair(__last, std::move(__iters.second)); + } + + __result = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second; + ++__sfirst; + while (__sfirst != __slast) { + __result = + std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second; + ++__sfirst; + } + __result = + std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second; + return std::make_pair(__last, std::move(__result)); + } + + template ::value && + !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) { + using _Traits = __segmented_iterator_traits<_OutIter>; + using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -typename enable_if -< - is_same::type, _Up>::value && - is_trivially_move_assignable<_Up>::value, - _Up* ->::type -__move(_Tp* __first, _Tp* __last, _Up* __result) -{ - const size_t __n = static_cast(__last - __first); - if (__n > 0) - _VSTD::memmove(__result, __first, __n * sizeof(_Up)); - return __result + __n; + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__result)); + + auto __local_first = _Traits::__local(__result); + auto __segment_iterator = _Traits::__segment(__result); + while (true) { + auto __local_last = _Traits::__end(__segment_iterator); + auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first); + auto __iters = std::__move<_AlgPolicy>(__first, __first + __size, __local_first); + __first = std::move(__iters.first); + + if (__first == __last) + return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second))); + + __local_first = _Traits::__begin(++__segment_iterator); + } + } +}; + +struct __move_trivial { + // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> + operator()(_In* __first, _In* __last, _Out* __result) const { + return std::__copy_trivial_impl(__first, __last, __result); + } +}; + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> +__move(_InIter __first, _Sent __last, _OutIter __result) { + return std::__dispatch_copy_or_move<_AlgPolicy, __move_loop<_AlgPolicy>, __move_trivial>( + std::move(__first), std::move(__last), std::move(__result)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - if (__libcpp_is_constant_evaluated()) { - return _VSTD::__move_constexpr(__first, __last, __result); - } else { - return _VSTD::__rewrap_iter(__result, - _VSTD::__move(_VSTD::__unwrap_iter(__first), - _VSTD::__unwrap_iter(__last), - _VSTD::__unwrap_iter(__result))); - } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { + static_assert(is_copy_constructible<_InputIterator>::value, "Iterators has to be copy constructible."); + static_assert(is_copy_constructible<_OutputIterator>::value, "The output iterator has to be copy constructible."); + + return std::__move<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second; } _LIBCPP_END_NAMESPACE_STD diff --git a/gnu/llvm/libcxx/include/__algorithm/move_backward.h b/gnu/llvm/libcxx/include/__algorithm/move_backward.h index 1c93b981973..d4f013be680 100644 --- a/gnu/llvm/libcxx/include/__algorithm/move_backward.h +++ b/gnu/llvm/libcxx/include/__algorithm/move_backward.h @@ -9,14 +9,18 @@ #ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H #define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H +#include <__algorithm/copy_move_common.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> #include <__config> -#include <__algorithm/unwrap_iter.h> -#include -#include -#include +#include <__iterator/segmented_iterator.h> +#include <__type_traits/common_type.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -24,57 +28,108 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -_OutputIterator -__move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - while (__first != __last) - *--__result = _VSTD::move(*--__last); - return __result; -} +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2> +__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result); -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -_OutputIterator -__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - return _VSTD::__move_backward_constexpr(__first, __last, __result); -} +template +struct __move_backward_loop { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { + auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + auto __original_last_iter = __last_iter; + + while (__first != __last_iter) { + *--__result = _IterOps<_AlgPolicy>::__iter_move(--__last_iter); + } + + return std::make_pair(std::move(__original_last_iter), std::move(__result)); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) const { + using _Traits = __segmented_iterator_traits<_InIter>; + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + if (__sfirst == __slast) { + auto __iters = + std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); + return std::make_pair(__last, __iters.second); + } + + __result = + std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result)) + .second; + --__slast; + while (__sfirst != __slast) { + __result = + std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result)) + .second; + --__slast; + } + __result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result)) + .second; + return std::make_pair(__last, std::move(__result)); + } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -typename enable_if -< - is_same::type, _Up>::value && - is_trivially_move_assignable<_Up>::value, - _Up* ->::type -__move_backward(_Tp* __first, _Tp* __last, _Up* __result) -{ - const size_t __n = static_cast(__last - __first); - if (__n > 0) - { - __result -= __n; - _VSTD::memmove(__result, __first, __n * sizeof(_Up)); + template ::value && + !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> + operator()(_InIter __first, _InIter __last, _OutIter __result) { + using _Traits = __segmented_iterator_traits<_OutIter>; + using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; + + // When the range contains no elements, __result might not be a valid iterator + if (__first == __last) + return std::make_pair(__first, __result); + + auto __orig_last = __last; + + auto __local_last = _Traits::__local(__result); + auto __segment_iterator = _Traits::__segment(__result); + while (true) { + auto __local_first = _Traits::__begin(__segment_iterator); + auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first); + auto __iter = std::__move_backward<_AlgPolicy>(__last - __size, __last, __local_last).second; + __last -= __size; + + if (__first == __last) + return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter))); + + __local_last = _Traits::__end(--__segment_iterator); } - return __result; + } +}; + +struct __move_backward_trivial { + // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> + operator()(_In* __first, _In* __last, _Out* __result) const { + return std::__copy_backward_trivial_impl(__first, __last, __result); + } +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2> +__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) { + static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && + std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); + + return std::__dispatch_copy_or_move<_AlgPolicy, __move_backward_loop<_AlgPolicy>, __move_backward_trivial>( + std::move(__first), std::move(__last), std::move(__result)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_BidirectionalIterator2 -move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, - _BidirectionalIterator2 __result) -{ - if (__libcpp_is_constant_evaluated()) { - return _VSTD::__move_backward_constexpr(__first, __last, __result); - } else { - return _VSTD::__rewrap_iter(__result, - _VSTD::__move_backward(_VSTD::__unwrap_iter(__first), - _VSTD::__unwrap_iter(__last), - _VSTD::__unwrap_iter(__result))); - } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2 +move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { + return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second; } _LIBCPP_END_NAMESPACE_STD diff --git a/gnu/llvm/libcxx/include/__algorithm/next_permutation.h b/gnu/llvm/libcxx/include/__algorithm/next_permutation.h index a337e5efa09..73e8b99ab90 100644 --- a/gnu/llvm/libcxx/include/__algorithm/next_permutation.h +++ b/gnu/llvm/libcxx/include/__algorithm/next_permutation.h @@ -9,60 +9,63 @@ #ifndef _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H #define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/reverse.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 bool -__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool> +__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) { - _BidirectionalIterator __i = __last; + using _Result = pair<_BidirectionalIterator, bool>; + + _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + _BidirectionalIterator __i = __last_iter; if (__first == __last || __first == --__i) - return false; + return _Result(std::move(__last_iter), false); + while (true) { _BidirectionalIterator __ip1 = __i; if (__comp(*--__i, *__ip1)) { - _BidirectionalIterator __j = __last; + _BidirectionalIterator __j = __last_iter; while (!__comp(*__i, *--__j)) ; - swap(*__i, *__j); - _VSTD::reverse(__ip1, __last); - return true; + _IterOps<_AlgPolicy>::iter_swap(__i, __j); + std::__reverse<_AlgPolicy>(__ip1, __last_iter); + return _Result(std::move(__last_iter), true); } if (__i == __first) { - _VSTD::reverse(__first, __last); - return false; + std::__reverse<_AlgPolicy>(__first, __last_iter); + return _Result(std::move(__last_iter), false); } } } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__next_permutation<_Comp_ref>(__first, __last, __comp); + return std::__next_permutation<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { @@ -72,6 +75,4 @@ next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/none_of.h b/gnu/llvm/libcxx/include/__algorithm/none_of.h index 285691520c4..19357eb2367 100644 --- a/gnu/llvm/libcxx/include/__algorithm/none_of.h +++ b/gnu/llvm/libcxx/include/__algorithm/none_of.h @@ -13,16 +13,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) @@ -32,6 +29,4 @@ none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_NONE_OF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/nth_element.h b/gnu/llvm/libcxx/include/__algorithm/nth_element.h index 67a03cfc37b..9fdfb2cae64 100644 --- a/gnu/llvm/libcxx/include/__algorithm/nth_element.h +++ b/gnu/llvm/libcxx/include/__algorithm/nth_element.h @@ -9,24 +9,24 @@ #ifndef _LIBCPP___ALGORITHM_NTH_ELEMENT_H #define _LIBCPP___ALGORITHM_NTH_ELEMENT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/sort.h> +#include <__config> +#include <__debug> +#include <__debug_utils/randomize_range.h> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_CONSTEXPR_AFTER_CXX11 bool +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j, _RandomAccessIterator __m, _Compare __comp) { @@ -41,10 +41,12 @@ __nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j, } } -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 void +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + // _Compare is known to be a reference type typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; const difference_type __limit = 7; @@ -60,24 +62,24 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando return; case 2: if (__comp(*--__last, *__first)) - swap(*__first, *__last); + _Ops::iter_swap(__first, __last); return; case 3: { _RandomAccessIterator __m = __first; - _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp); + std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp); return; } } if (__len <= __limit) { - _VSTD::__selection_sort<_Compare>(__first, __last, __comp); + std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp); return; } // __len > __limit >= 3 _RandomAccessIterator __m = __first + __len/2; _RandomAccessIterator __lm1 = __last; - unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp); + unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp); // *__m is median // partition [__first, __m) < *__m and *__m <= [__m, __last) // (this inhibits tossing elements equivalent to __m around unnecessarily) @@ -90,7 +92,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando { // *__first == *__m, *__first doesn't go in first part if (_VSTD::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) { - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; } else { // *__first == *__m, *__m <= all other elements @@ -102,7 +104,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando if (__i == __j) { return; // [__first, __last) all equivalent elements } else if (__comp(*__first, *__i)) { - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; ++__i; break; @@ -121,7 +123,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando ; if (__i >= __j) break; - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; ++__i; } @@ -152,7 +154,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando ; if (__i >= __j) break; - swap(*__i, *__j); + _Ops::iter_swap(__i, __j); ++__n_swaps; // It is known that __m != __j // If __m just moved, follow it @@ -164,7 +166,7 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando // [__first, __i) < *__m and *__m <= [__i, __last) if (__i != __m && __comp(*__m, *__i)) { - swap(*__i, *__m); + _Ops::iter_swap(__i, __m); ++__n_swaps; } // [__first, __i) < *__i and *__i <= [__i+1, __last) @@ -220,25 +222,37 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando } } +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, + _Compare& __comp) { + if (__nth == __last) + return; + + std::__debug_randomize_range<_AlgPolicy>(__first, __last); + + std::__nth_element<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __nth, __last, __comp); + + std::__debug_randomize_range<_AlgPolicy>(__first, __nth); + if (__nth != __last) { + std::__debug_randomize_range<_AlgPolicy>(++__nth, __last); + } +} + template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - _VSTD::__nth_element<_Comp_ref>(__first, __nth, __last, __comp); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, + _Compare __comp) { + std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) -{ - _VSTD::nth_element(__first, __nth, __last, __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { + std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_NTH_ELEMENT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/partial_sort.h b/gnu/llvm/libcxx/include/__algorithm/partial_sort.h index 4f9872c4922..e0812affe6b 100644 --- a/gnu/llvm/libcxx/include/__algorithm/partial_sort.h +++ b/gnu/llvm/libcxx/include/__algorithm/partial_sort.h @@ -9,63 +9,88 @@ #ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H #define _LIBCPP___ALGORITHM_PARTIAL_SORT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/make_heap.h> #include <__algorithm/sift_down.h> #include <__algorithm/sort_heap.h> +#include <__config> +#include <__debug> +#include <__debug_utils/randomize_range.h> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> +#include <__utility/move.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 void -__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - _Compare __comp) -{ - _VSTD::__make_heap<_Compare>(__first, __middle, __comp); - typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; - for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) - { - if (__comp(*__i, *__first)) - { - swap(*__i, *__first); - _VSTD::__sift_down<_Compare>(__first, __middle, __comp, __len, __first); - } - } - _VSTD::__sort_heap<_Compare>(__first, __middle, __comp); +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_RandomAccessIterator __partial_sort_impl( + _RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) { + if (__first == __middle) { + return _IterOps<_AlgPolicy>::next(__middle, __last); + } + + std::__make_heap<_AlgPolicy>(__first, __middle, __comp); + + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; + _RandomAccessIterator __i = __middle; + for (; __i != __last; ++__i) + { + if (__comp(*__i, *__first)) + { + _IterOps<_AlgPolicy>::iter_swap(__i, __first); + std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first); + } + } + std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp); + + return __i; +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, + _Compare& __comp) { + if (__first == __middle) + return _IterOps<_AlgPolicy>::next(__middle, __last); + + std::__debug_randomize_range<_AlgPolicy>(__first, __last); + + auto __last_iter = + std::__partial_sort_impl<_AlgPolicy>(__first, __middle, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); + + std::__debug_randomize_range<_AlgPolicy>(__middle, __last); + + return __last_iter; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - _VSTD::__partial_sort<_Comp_ref>(__first, __middle, __last, __comp); + static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); + static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + + (void)std::__partial_sort<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last), __comp); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { _VSTD::partial_sort(__first, __middle, __last, - __less::value_type>()); + __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/partial_sort_copy.h b/gnu/llvm/libcxx/include/__algorithm/partial_sort_copy.h index 31a12615fa5..1aba07105dc 100644 --- a/gnu/llvm/libcxx/include/__algorithm/partial_sort_copy.h +++ b/gnu/llvm/libcxx/include/__algorithm/partial_sort_copy.h @@ -9,59 +9,72 @@ #ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H #define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/make_heap.h> +#include <__algorithm/make_projected.h> #include <__algorithm/sift_down.h> #include <__algorithm/sort_heap.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> #include <__iterator/iterator_traits.h> -#include // swap +#include <__type_traits/is_callable.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator -__partial_sort_copy(_InputIterator __first, _InputIterator __last, - _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> +__partial_sort_copy(_InputIterator __first, _Sentinel1 __last, + _RandomAccessIterator __result_first, _Sentinel2 __result_last, + _Compare&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) { _RandomAccessIterator __r = __result_first; + auto&& __projected_comp = std::__make_projected(__comp, __proj2); + if (__r != __result_last) { for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) *__r = *__first; - _VSTD::__make_heap<_Compare>(__result_first, __r, __comp); + std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp); typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; for (; __first != __last; ++__first) - if (__comp(*__first, *__result_first)) - { + if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) { *__result_first = *__first; - _VSTD::__sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first); + std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first); } - _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp); + std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp); } - return __r; + + return pair<_InputIterator, _RandomAccessIterator>( + _IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) { - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp); + static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, + "Comparator has to be callable"); + + auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(__first, __last, __result_first, __result_last, + static_cast<__comp_ref_type<_Compare> >(__comp), __identity(), __identity()); + return __result.second; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) @@ -72,6 +85,4 @@ partial_sort_copy(_InputIterator __first, _InputIterator __last, _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/partition.h b/gnu/llvm/libcxx/include/__algorithm/partition.h index c859eaca28a..0e094bf8dd9 100644 --- a/gnu/llvm/libcxx/include/__algorithm/partition.h +++ b/gnu/llvm/libcxx/include/__algorithm/partition.h @@ -9,55 +9,58 @@ #ifndef _LIBCPP___ALGORITHM_PARTITION_H #define _LIBCPP___ALGORITHM_PARTITION_H +#include <__algorithm/iterator_operations.h> #include <__config> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> -#include // pair +#include <__utility/move.h> +#include <__utility/pair.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) { while (true) { if (__first == __last) - return __first; + return std::make_pair(std::move(__first), std::move(__first)); if (!__pred(*__first)) break; ++__first; } - for (_ForwardIterator __p = __first; ++__p != __last;) + + _ForwardIterator __p = __first; + while (++__p != __last) { if (__pred(*__p)) { - swap(*__first, *__p); + _IterOps<_AlgPolicy>::iter_swap(__first, __p); ++__first; } } - return __first; + return std::make_pair(std::move(__first), std::move(__p)); } -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator -__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator> +__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, bidirectional_iterator_tag) { + _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel); + _BidirectionalIterator __last = __original_last; + while (true) { while (true) { if (__first == __last) - return __first; + return std::make_pair(std::move(__first), std::move(__original_last)); if (!__pred(*__first)) break; ++__first; @@ -65,24 +68,31 @@ __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Pred do { if (__first == --__last) - return __first; + return std::make_pair(std::move(__first), std::move(__original_last)); } while (!__pred(*__last)); - swap(*__first, *__last); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); ++__first; } } +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +pair<_ForwardIterator, _ForwardIterator> __partition( + _ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) { + return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>( + std::move(__first), std::move(__last), __pred, __iter_category); +} + template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - return _VSTD::__partition::type> - (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); + using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; + auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory()); + return __result.first; } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_PARTITION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/partition_copy.h b/gnu/llvm/libcxx/include/__algorithm/partition_copy.h index 445eacdfbe9..ff8826a9371 100644 --- a/gnu/llvm/libcxx/include/__algorithm/partition_copy.h +++ b/gnu/llvm/libcxx/include/__algorithm/partition_copy.h @@ -11,20 +11,17 @@ #include <__config> #include <__iterator/iterator_traits.h> -#include // pair +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_OutputIterator1, _OutputIterator2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> partition_copy(_InputIterator __first, _InputIterator __last, _OutputIterator1 __out_true, _OutputIterator2 __out_false, _Predicate __pred) @@ -47,6 +44,4 @@ partition_copy(_InputIterator __first, _InputIterator __last, _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_PARTITION_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/partition_point.h b/gnu/llvm/libcxx/include/__algorithm/partition_point.h index 12ddacf9d75..6ede71a264c 100644 --- a/gnu/llvm/libcxx/include/__algorithm/partition_point.h +++ b/gnu/llvm/libcxx/include/__algorithm/partition_point.h @@ -9,21 +9,20 @@ #ifndef _LIBCPP___ALGORITHM_PARTITION_POINT_H #define _LIBCPP___ALGORITHM_PARTITION_POINT_H -#include <__config> #include <__algorithm/half_positive.h> -#include +#include <__config> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; @@ -46,6 +45,4 @@ partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __ _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_PARTITION_POINT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/pop_heap.h b/gnu/llvm/libcxx/include/__algorithm/pop_heap.h index 7ebbef25e0b..94d32a42391 100644 --- a/gnu/llvm/libcxx/include/__algorithm/pop_heap.h +++ b/gnu/llvm/libcxx/include/__algorithm/pop_heap.h @@ -9,54 +9,65 @@ #ifndef _LIBCPP___ALGORITHM_POP_HEAP_H #define _LIBCPP___ALGORITHM_POP_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/push_heap.h> #include <__algorithm/sift_down.h> +#include <__assert> +#include <__config> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> +#include <__utility/move.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len) -{ - if (__len > 1) - { - swap(*__first, *--__last); - _VSTD::__sift_down<_Compare>(__first, __last, __comp, __len - 1, __first); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { + _LIBCPP_ASSERT(__len > 0, "The heap given to pop_heap must be non-empty"); + + __comp_ref_type<_Compare> __comp_ref = __comp; + + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + if (__len > 1) { + value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first + _RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len); + --__last; + + if (__hole == __last) { + *__hole = std::move(__top); + } else { + *__hole = _IterOps<_AlgPolicy>::__iter_move(__last); + ++__hole; + *__last = std::move(__top); + std::__sift_up<_AlgPolicy>(__first, __hole, __comp_ref, __hole - __first); } + } } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - _VSTD::__pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); + static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first; + std::__pop_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp, __len); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - _VSTD::pop_heap(__first, __last, __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::pop_heap(std::move(__first), std::move(__last), + __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_POP_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/prev_permutation.h b/gnu/llvm/libcxx/include/__algorithm/prev_permutation.h index d6daa73ada0..0b86ab74ee0 100644 --- a/gnu/llvm/libcxx/include/__algorithm/prev_permutation.h +++ b/gnu/llvm/libcxx/include/__algorithm/prev_permutation.h @@ -9,60 +9,64 @@ #ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H #define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/reverse.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 bool -__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +pair<_BidirectionalIterator, bool> +__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) { - _BidirectionalIterator __i = __last; + using _Result = pair<_BidirectionalIterator, bool>; + + _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + _BidirectionalIterator __i = __last_iter; if (__first == __last || __first == --__i) - return false; + return _Result(std::move(__last_iter), false); + while (true) { _BidirectionalIterator __ip1 = __i; if (__comp(*__ip1, *--__i)) { - _BidirectionalIterator __j = __last; + _BidirectionalIterator __j = __last_iter; while (!__comp(*--__j, *__i)) ; - swap(*__i, *__j); - _VSTD::reverse(__ip1, __last); - return true; + _IterOps<_AlgPolicy>::iter_swap(__i, __j); + std::__reverse<_AlgPolicy>(__ip1, __last_iter); + return _Result(std::move(__last_iter), true); } if (__i == __first) { - _VSTD::reverse(__first, __last); - return false; + std::__reverse<_AlgPolicy>(__first, __last_iter); + return _Result(std::move(__last_iter), false); } } } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__prev_permutation<_Comp_ref>(__first, __last, __comp); + return std::__prev_permutation<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { @@ -72,6 +76,4 @@ prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/push_heap.h b/gnu/llvm/libcxx/include/__algorithm/push_heap.h index 82a7c123d83..90684957744 100644 --- a/gnu/llvm/libcxx/include/__algorithm/push_heap.h +++ b/gnu/llvm/libcxx/include/__algorithm/push_heap.h @@ -9,67 +9,69 @@ #ifndef _LIBCPP___ALGORITHM_PUSH_HEAP_H #define _LIBCPP___ALGORITHM_PUSH_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/move.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 void -__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len) -{ - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - if (__len > 1) - { - __len = (__len - 2) / 2; - _RandomAccessIterator __ptr = __first + __len; - if (__comp(*__ptr, *--__last)) - { - value_type __t(_VSTD::move(*__last)); - do - { - *__last = _VSTD::move(*__ptr); - __last = __ptr; - if (__len == 0) - break; - __len = (__len - 1) / 2; - __ptr = __first + __len; - } while (__comp(*__ptr, __t)); - *__last = _VSTD::move(__t); - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + + if (__len > 1) { + __len = (__len - 2) / 2; + _RandomAccessIterator __ptr = __first + __len; + + if (__comp(*__ptr, *--__last)) { + value_type __t(_IterOps<_AlgPolicy>::__iter_move(__last)); + do { + *__last = _IterOps<_AlgPolicy>::__iter_move(__ptr); + __last = __ptr; + if (__len == 0) + break; + __len = (__len - 1) / 2; + __ptr = __first + __len; + } while (__comp(*__ptr, __t)); + + *__last = std::move(__t); } + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first; + std::__sift_up<_AlgPolicy, __comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp, __len); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - _VSTD::__sift_up<_Comp_ref>(__first, __last, __comp, __last - __first); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); + static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + + std::__push_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - _VSTD::push_heap(__first, __last, __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::push_heap(std::move(__first), std::move(__last), + __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_adjacent_find.h b/gnu/llvm/libcxx/include/__algorithm/ranges_adjacent_find.h new file mode 100644 index 00000000000..d338d13e6ee --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_adjacent_find.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_ADJACENT_FIND_H +#define _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __adjacent_find { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + if (__first == __last) + return __first; + + auto __i = __first; + while (++__i != __last) { + if (std::invoke(__pred, std::invoke(__proj, *__first), std::invoke(__proj, *__i))) + return __first; + __first = __i; + } + return __i; + } + + template _Sent, + class _Proj = identity, + indirect_binary_predicate, projected<_Iter, _Proj>> _Pred = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>, + projected, _Proj>> _Pred = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const { + return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __adjacent_find + +inline namespace __cpo { + inline constexpr auto adjacent_find = __adjacent_find::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_all_of.h b/gnu/llvm/libcxx/include/__algorithm/ranges_all_of.h new file mode 100644 index 00000000000..e45c4e58437 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_all_of.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_ALL_OF_H +#define _LIBCPP___ALGORITHM_RANGES_ALL_OF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __all_of { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (!std::invoke(__pred, std::invoke(__proj, *__first))) + return false; + } + return true; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __all_of + +inline namespace __cpo { + inline constexpr auto all_of = __all_of::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_any_of.h b/gnu/llvm/libcxx/include/__algorithm/ranges_any_of.h new file mode 100644 index 00000000000..e7d1e723a70 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_any_of.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_ANY_OF_H +#define _LIBCPP___ALGORITHM_RANGES_ANY_OF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __any_of { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + return true; + } + return false; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __any_of + +inline namespace __cpo { + inline constexpr auto any_of = __any_of::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_binary_search.h b/gnu/llvm/libcxx/include/__algorithm/ranges_binary_search.h new file mode 100644 index 00000000000..d72d4e05740 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_binary_search.h @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_BINARY_SEARCH_H +#define _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/lower_bound.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __binary_search { +struct __fn { + template _Sent, class _Type, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); + return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); + auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); + return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); + } +}; +} // namespace __binary_search + +inline namespace __cpo { + inline constexpr auto binary_search = __binary_search::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_clamp.h b/gnu/llvm/libcxx/include/__algorithm/ranges_clamp.h new file mode 100644 index 00000000000..09a97fc790e --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_clamp.h @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_CLAMP_H +#define _LIBCPP___ALGORITHM_RANGES_CLAMP_H + +#include <__assert> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __clamp { +struct __fn { + + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + const _Type& operator()(const _Type& __value, + const _Type& __low, + const _Type& __high, + _Comp __comp = {}, + _Proj __proj = {}) const { + _LIBCPP_ASSERT(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))), + "Bad bounds passed to std::ranges::clamp"); + + if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, __low))) + return __low; + else if (std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __value))) + return __high; + else + return __value; + } + +}; +} // namespace __clamp + +inline namespace __cpo { + inline constexpr auto clamp = __clamp::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_copy.h b/gnu/llvm/libcxx/include/__algorithm/ranges_copy.h new file mode 100644 index 00000000000..bb02c84efbd --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_copy.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_H + +#include <__algorithm/copy.h> +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using copy_result = in_out_result<_InIter, _OutIter>; + +namespace __copy { +struct __fn { + + template _Sent, weakly_incrementable _OutIter> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + auto __ret = std::__copy<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_result, _OutIter> operator()(_Range&& __r, _OutIter __result) const { + auto __ret = std::__copy<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; +} // namespace __copy + +inline namespace __cpo { + inline constexpr auto copy = __copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_copy_backward.h b/gnu/llvm/libcxx/include/__algorithm/ranges_copy_backward.h new file mode 100644 index 00000000000..f41af66f39f --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_copy_backward.h @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_COPY_BACKWARD_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H + +#include <__algorithm/copy_backward.h> +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using copy_backward_result = in_out_result<_Ip, _Op>; + +namespace __copy_backward { +struct __fn { + + template _Sent1, bidirectional_iterator _InIter2> + requires indirectly_copyable<_InIter1, _InIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_backward_result<_InIter1, _InIter2> operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const { + auto __ret = std::__copy_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template + requires indirectly_copyable, _Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_backward_result, _Iter> operator()(_Range&& __r, _Iter __result) const { + auto __ret = std::__copy_backward<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; +} // namespace __copy_backward + +inline namespace __cpo { + inline constexpr auto copy_backward = __copy_backward::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_copy_if.h b/gnu/llvm/libcxx/include/__algorithm/ranges_copy_if.h new file mode 100644 index 00000000000..dba41c3b3ab --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_copy_if.h @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_COPY_IF_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_IF_H + +#include <__algorithm/in_out_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using copy_if_result = in_out_result<_Ip, _Op>; + +namespace __copy_if { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI static constexpr + copy_if_result <_InIter, _OutIter> + __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) { + *__result = *__first; + ++__result; + } + } + return {std::move(__first), std::move(__result)}; + } + + template _Sent, weakly_incrementable _OutIter, class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_copyable<_Iter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_if_result<_Iter, _OutIter> + operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); + } + + template , _Proj>> _Pred> + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_if_result, _OutIter> + operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj); + } +}; +} // namespace __copy_if + +inline namespace __cpo { + inline constexpr auto copy_if = __copy_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_copy_n.h b/gnu/llvm/libcxx/include/__algorithm/ranges_copy_n.h new file mode 100644 index 00000000000..04bb80b3ba1 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_copy_n.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 _LIBCPP___ALGORITHM_RANGES_COPY_N_H +#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H + +#include <__algorithm/copy.h> +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/ranges_copy.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/unreachable_sentinel.h> +#include <__iterator/wrap_iter.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +using copy_n_result = in_out_result<_Ip, _Op>; + +namespace __copy_n { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { + while (__n != 0) { + *__result = *__first; + ++__first; + ++__result; + --__n; + } + return {std::move(__first), std::move(__result)}; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { + auto __ret = std::__copy<_RangeAlgPolicy>(__first, __first + __n, __result); + return {__ret.first, __ret.second}; + } + + template + requires indirectly_copyable<_Ip, _Op> + _LIBCPP_HIDE_FROM_ABI constexpr + copy_n_result<_Ip, _Op> operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const { + return __go(std::move(__first), __n, std::move(__result)); + } +}; +} // namespace __copy_n + +inline namespace __cpo { + inline constexpr auto copy_n = __copy_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_RANGES_COPY_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_count.h b/gnu/llvm/libcxx/include/__algorithm/ranges_count.h new file mode 100644 index 00000000000..527dd062008 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_count.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_COUNT_H +#define _LIBCPP___ALGORITHM_RANGES_COUNT_H + +#include <__algorithm/ranges_count_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __count { +struct __fn { + template _Sent, class _Type, class _Proj = identity> + requires indirect_binary_predicate, const _Type*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __e) { return __e == __value; }; + return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template + requires indirect_binary_predicate, _Proj>, const _Type*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __e) { return __e == __value; }; + return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); + } +}; +} // namespace __count + +inline namespace __cpo { + inline constexpr auto count = __count::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_count_if.h b/gnu/llvm/libcxx/include/__algorithm/ranges_count_if.h new file mode 100644 index 00000000000..931618b7b54 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_count_if.h @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_COUNT_IF_H +#define _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +template +_LIBCPP_HIDE_FROM_ABI constexpr +iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last, + _Pred& __pred, _Proj& __proj) { + iter_difference_t<_Iter> __counter(0); + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + ++__counter; + } + return __counter; +} + +namespace __count_if { +struct __fn { + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Predicate> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const { + return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Predicate> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const { + return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); + } +}; +} // namespace __count_if + +inline namespace __cpo { + inline constexpr auto count_if = __count_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_equal.h b/gnu/llvm/libcxx/include/__algorithm/ranges_equal.h new file mode 100644 index 00000000000..3c417f09de9 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_equal.h @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_EQUAL_H +#define _LIBCPP___ALGORITHM_RANGES_EQUAL_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/indirectly_comparable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __equal { +struct __fn { +private: + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __equal_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { + while (__first1 != __last1 && __first2 != __last2) { + if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) + return false; + ++__first1; + ++__first2; + } + return __first1 == __last1 && __first2 == __last2; + } + +public: + + template _Sent1, + input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) { + if (__last1 - __first1 != __last2 - __first2) + return false; + } + return __equal_impl(std::move(__first1), std::move(__last1), + std::move(__first2), std::move(__last2), + __pred, + __proj1, + __proj2); + } + + template + requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range1&& __range1, + _Range2&& __range2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + if constexpr (sized_range<_Range1> && sized_range<_Range2>) { + if (ranges::distance(__range1) != ranges::distance(__range2)) + return false; + } + return __equal_impl(ranges::begin(__range1), ranges::end(__range1), + ranges::begin(__range2), ranges::end(__range2), + __pred, + __proj1, + __proj2); + return false; + } +}; +} // namespace __equal + +inline namespace __cpo { + inline constexpr auto equal = __equal::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_equal_range.h b/gnu/llvm/libcxx/include/__algorithm/ranges_equal_range.h new file mode 100644 index 00000000000..94dc058e7bc --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_equal_range.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_EQUAL_RANGE_H +#define _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H + +#include <__algorithm/equal_range.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__ranges/subrange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __equal_range { + +struct __fn { + template < + forward_iterator _Iter, + sentinel_for<_Iter> _Sent, + class _Tp, + class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__equal_range<_RangeAlgPolicy>( + std::move(__first), std::move(__last), __value, __comp, __proj); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template < + forward_range _Range, + class _Tp, + class _Proj = identity, + indirect_strict_weak_order, _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__equal_range<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), __value, __comp, __proj); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; + +} // namespace __equal_range + +inline namespace __cpo { + inline constexpr auto equal_range = __equal_range::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_fill.h b/gnu/llvm/libcxx/include/__algorithm/ranges_fill.h new file mode 100644 index 00000000000..6ebc2bd67d6 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_fill.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_FILL_H +#define _LIBCPP___ALGORITHM_RANGES_FILL_H + +#include <__algorithm/ranges_fill_n.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __fill { +struct __fn { + template _Iter, sentinel_for<_Iter> _Sent> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const { + if constexpr(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) { + return ranges::fill_n(__first, __last - __first, __value); + } else { + for (; __first != __last; ++__first) + *__first = __value; + return __first; + } + } + + template _Range> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const { + return (*this)(ranges::begin(__range), ranges::end(__range), __value); + } +}; +} // namespace __fill + +inline namespace __cpo { + inline constexpr auto fill = __fill::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FILL_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_fill_n.h b/gnu/llvm/libcxx/include/__algorithm/ranges_fill_n.h new file mode 100644 index 00000000000..a2660e8b592 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_fill_n.h @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_FILL_N_H +#define _LIBCPP___ALGORITHM_RANGES_FILL_N_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __fill_n { +struct __fn { + template _Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const { + for (; __n != 0; --__n) { + *__first = __value; + ++__first; + } + return __first; + } +}; +} // namespace __fill_n + +inline namespace __cpo { + inline constexpr auto fill_n = __fill_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FILL_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_find_end.h b/gnu/llvm/libcxx/include/__algorithm/ranges_find_end.h new file mode 100644 index 00000000000..ea36f4d4e6e --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_find_end.h @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_FIND_END_H +#define _LIBCPP___ALGORITHM_RANGES_FIND_END_H + +#include <__algorithm/find_end.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __find_end { +struct __fn { + template _Sent1, + forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__find_end_impl<_RangeAlgPolicy>( + __first1, + __last1, + __first2, + __last2, + __pred, + __proj1, + __proj2, + __iterator_concept<_Iter1>(), + __iterator_concept<_Iter2>()); + return {__ret.first, __ret.second}; + } + + template + requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range1> operator()(_Range1&& __range1, + _Range2&& __range2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__find_end_impl<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __pred, + __proj1, + __proj2, + __iterator_concept>(), + __iterator_concept>()); + return {__ret.first, __ret.second}; + } +}; +} // namespace __find_end + +inline namespace __cpo { + inline constexpr auto find_end = __find_end::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_find_first_of.h b/gnu/llvm/libcxx/include/__algorithm/ranges_find_first_of.h new file mode 100644 index 00000000000..9d66e7511c0 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_find_first_of.h @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_FIND_FIRST_OF_H +#define _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __find_first_of { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter1 __find_first_of_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { + for (; __first1 != __last1; ++__first1) { + for (auto __j = __first2; __j != __last2; ++__j) { + if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j))) + return __first1; + } + } + return __first1; + } + + template _Sent1, + forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter1 operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __find_first_of_impl(std::move(__first1), std::move(__last1), + std::move(__first2), std::move(__last2), + __pred, + __proj1, + __proj2); + } + + template + requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range1> operator()(_Range1&& __range1, + _Range2&& __range2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __find_first_of_impl(ranges::begin(__range1), ranges::end(__range1), + ranges::begin(__range2), ranges::end(__range2), + __pred, + __proj1, + __proj2); + } + +}; +} // namespace __find_first_of + +inline namespace __cpo { + inline constexpr auto find_first_of = __find_first_of::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_for_each.h b/gnu/llvm/libcxx/include/__algorithm/ranges_for_each.h new file mode 100644 index 00000000000..0c70c05981a --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_for_each.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_FOR_EACH_H +#define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H + +#include <__algorithm/in_fun_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using for_each_result = in_fun_result<_Iter, _Func>; + +namespace __for_each { +struct __fn { +private: + template + _LIBCPP_HIDE_FROM_ABI constexpr static + for_each_result<_Iter, _Func> __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) { + for (; __first != __last; ++__first) + std::invoke(__func, std::invoke(__proj, *__first)); + return {std::move(__first), std::move(__func)}; + } + +public: + template _Sent, + class _Proj = identity, + indirectly_unary_invocable> _Func> + _LIBCPP_HIDE_FROM_ABI constexpr + for_each_result<_Iter, _Func> operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const { + return __for_each_impl(std::move(__first), std::move(__last), __func, __proj); + } + + template , _Proj>> _Func> + _LIBCPP_HIDE_FROM_ABI constexpr + for_each_result, _Func> operator()(_Range&& __range, + _Func __func, + _Proj __proj = {}) const { + return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj); + } + +}; +} // namespace __for_each + +inline namespace __cpo { + inline constexpr auto for_each = __for_each::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_for_each_n.h b/gnu/llvm/libcxx/include/__algorithm/ranges_for_each_n.h new file mode 100644 index 00000000000..261816aba43 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_for_each_n.h @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_FOR_EACH_N_H +#define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H + +#include <__algorithm/in_fun_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using for_each_n_result = in_fun_result<_Iter, _Func>; + +namespace __for_each_n { +struct __fn { + + template > _Func> + _LIBCPP_HIDE_FROM_ABI constexpr + for_each_n_result<_Iter, _Func> operator()(_Iter __first, + iter_difference_t<_Iter> __count, + _Func __func, + _Proj __proj = {}) const { + while (__count-- > 0) { + std::invoke(__func, std::invoke(__proj, *__first)); + ++__first; + } + return {std::move(__first), std::move(__func)}; + } + +}; +} // namespace __for_each_n + +inline namespace __cpo { + inline constexpr auto for_each_n = __for_each_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_generate.h b/gnu/llvm/libcxx/include/__algorithm/ranges_generate.h new file mode 100644 index 00000000000..ae486ae6539 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_generate.h @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_GENERATE_H +#define _LIBCPP___ALGORITHM_RANGES_GENERATE_H + +#include <__concepts/constructible.h> +#include <__concepts/invocable.h> +#include <__config> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __generate { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr + static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) { + for (; __first != __last; ++__first) { + *__first = __gen(); + } + + return __first; + } + + template _Sent, copy_constructible _Func> + requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> + _LIBCPP_HIDE_FROM_ABI constexpr + _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const { + return __generate_fn_impl(std::move(__first), std::move(__last), __gen); + } + + template + requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const { + return __generate_fn_impl(ranges::begin(__range), ranges::end(__range), __gen); + } + +}; + +} // namespace __generate + +inline namespace __cpo { + inline constexpr auto generate = __generate::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_generate_n.h b/gnu/llvm/libcxx/include/__algorithm/ranges_generate_n.h new file mode 100644 index 00000000000..e625e3a9742 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_generate_n.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H +#define _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H + +#include <__concepts/constructible.h> +#include <__concepts/invocable.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __generate_n { + +struct __fn { + + template + requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> + _LIBCPP_HIDE_FROM_ABI constexpr + _OutIter operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const { + for (; __n > 0; --__n) { + *__first = __gen(); + ++__first; + } + + return __first; + } + +}; + +} // namespace __generate_n + +inline namespace __cpo { + inline constexpr auto generate_n = __generate_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_includes.h b/gnu/llvm/libcxx/include/__algorithm/ranges_includes.h new file mode 100644 index 00000000000..8438117cfa8 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_includes.h @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_INCLUDES_H +#define _LIBCPP___ALGORITHM_RANGES_INCLUDES_H + +#include <__algorithm/includes.h> +#include <__algorithm/make_projected.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __includes { + +struct __fn { + template < + input_iterator _Iter1, + sentinel_for<_Iter1> _Sent1, + input_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return std::__includes( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__comp), + std::move(__proj1), + std::move(__proj2)); + } + + template < + input_range _Range1, + input_range _Range2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_strict_weak_order, _Proj1>, projected, _Proj2>> + _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return std::__includes( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + std::move(__comp), + std::move(__proj1), + std::move(__proj2)); + } +}; + +} // namespace __includes + +inline namespace __cpo { + inline constexpr auto includes = __includes::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_INCLUDES_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_inplace_merge.h b/gnu/llvm/libcxx/include/__algorithm/ranges_inplace_merge.h new file mode 100644 index 00000000000..88171a65c8e --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_inplace_merge.h @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_INPLACE_MERGE_H +#define _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H + +#include <__algorithm/inplace_merge.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __inplace_merge { + + struct __fn { + template + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) { + auto __last_iter = ranges::next(__middle, __last); + std::__inplace_merge<_RangeAlgPolicy>( + std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj)); + return __last_iter; + } + + template < + bidirectional_iterator _Iter, + sentinel_for<_Iter> _Sent, + class _Comp = ranges::less, + class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI _Iter + operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __inplace_merge_impl( + std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj)); + } + + template + requires sortable< + iterator_t<_Range>, + _Comp, + _Proj> _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> + operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { + return __inplace_merge_impl( + ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj)); + } + }; + +} // namespace __inplace_merge + +inline namespace __cpo { + inline constexpr auto inplace_merge = __inplace_merge::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_is_heap.h b/gnu/llvm/libcxx/include/__algorithm/ranges_is_heap.h new file mode 100644 index 00000000000..a16c075b076 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_is_heap.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H + +#include <__algorithm/is_heap_until.h> +#include <__algorithm/make_projected.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_heap { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr + static bool __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + auto&& __projected_comp = std::__make_projected(__comp, __proj); + + auto __result = std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); + return __result == __last; + } + + template _Sent, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); + } +}; + +} // namespace __is_heap + +inline namespace __cpo { + inline constexpr auto is_heap = __is_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_is_heap_until.h b/gnu/llvm/libcxx/include/__algorithm/ranges_is_heap_until.h new file mode 100644 index 00000000000..8c8dac5bc90 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_is_heap_until.h @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_IS_HEAP_UNTIL_H +#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H + +#include <__algorithm/is_heap_until.h> +#include <__algorithm/make_projected.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_heap_until { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr + static _Iter __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + auto&& __projected_comp = std::__make_projected(__comp, __proj); + + return std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); + } + + template _Sent, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); + } + +}; + +} // namespace __is_heap_until + +inline namespace __cpo { + inline constexpr auto is_heap_until = __is_heap_until::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_is_partitioned.h b/gnu/llvm/libcxx/include/__algorithm/ranges_is_partitioned.h new file mode 100644 index 00000000000..b903953d616 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_is_partitioned.h @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_IS_PARTITIONED_H +#define _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_partitioned { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __is_parititioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (!std::invoke(__pred, std::invoke(__proj, *__first))) + break; + } + + if (__first == __last) + return true; + ++__first; + + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + return false; + } + + return true; + } + + template _Sent, + class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __is_parititioned_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __is_parititioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __is_partitioned + +inline namespace __cpo { + inline constexpr auto is_partitioned = __is_partitioned::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_is_permutation.h b/gnu/llvm/libcxx/include/__algorithm/ranges_is_permutation.h new file mode 100644 index 00000000000..b617500ea0d --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_is_permutation.h @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_IS_PERMUTATION_H +#define _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H + +#include <__algorithm/is_permutation.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_permutation { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __is_permutation_func_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + return std::__is_permutation<_RangeAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2); + } + + template _Sent1, + forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_equivalence_relation, + projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __is_permutation_func_impl( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), + __pred, __proj1, __proj2); + } + + template , _Proj1>, projected, _Proj2>> _Pred = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range1&& __range1, _Range2&& __range2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + if constexpr (sized_range<_Range1> && sized_range<_Range2>) { + if (ranges::distance(__range1) != ranges::distance(__range2)) + return false; + } + + return __is_permutation_func_impl( + ranges::begin(__range1), ranges::end(__range1), ranges::begin(__range2), ranges::end(__range2), + __pred, __proj1, __proj2); + } +}; +} // namespace __is_permutation + +inline namespace __cpo { + inline constexpr auto is_permutation = __is_permutation::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_is_sorted.h b/gnu/llvm/libcxx/include/__algorithm/ranges_is_sorted.h new file mode 100644 index 00000000000..ce3032ff226 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_is_sorted.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// 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__ALGORITHM_RANGES_IS_SORTED_H +#define _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H + +#include <__algorithm/ranges_is_sorted_until.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __is_sorted { +struct __fn { + template _Sent, + class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__is_sorted_until_impl(std::move(__first), __last, __comp, __proj) == __last; + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __last = ranges::end(__range); + return ranges::__is_sorted_until_impl(ranges::begin(__range), __last, __comp, __proj) == __last; + } +}; +} // namespace __is_sorted + +inline namespace __cpo { + inline constexpr auto is_sorted = __is_sorted::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_is_sorted_until.h b/gnu/llvm/libcxx/include/__algorithm/ranges_is_sorted_until.h new file mode 100644 index 00000000000..17fc42e97fd --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_is_sorted_until.h @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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__ALGORITHM_RANGES_IS_SORTED_UNTIL_H +#define _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr +_Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + if (__first == __last) + return __first; + auto __i = __first; + while (++__i != __last) { + if (std::invoke(__comp, std::invoke(__proj, *__i), std::invoke(__proj, *__first))) + return __i; + __first = __i; + } + return __i; +} + +namespace __is_sorted_until { +struct __fn { + template _Sent, + class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__is_sorted_until_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__is_sorted_until_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); + } +}; +} // namespace __is_sorted_until + +inline namespace __cpo { + inline constexpr auto is_sorted_until = __is_sorted_until::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_iterator_concept.h b/gnu/llvm/libcxx/include/__algorithm/ranges_iterator_concept.h new file mode 100644 index 00000000000..3ac6b317031 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_iterator_concept.h @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_ITERATOR_CONCEPT_H +#define _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/remove_cvref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +consteval auto __get_iterator_concept() { + using _Iter = __remove_cvref_t<_IterMaybeQualified>; + + if constexpr (contiguous_iterator<_Iter>) + return contiguous_iterator_tag(); + else if constexpr (random_access_iterator<_Iter>) + return random_access_iterator_tag(); + else if constexpr (bidirectional_iterator<_Iter>) + return bidirectional_iterator_tag(); + else if constexpr (forward_iterator<_Iter>) + return forward_iterator_tag(); + else if constexpr (input_iterator<_Iter>) + return input_iterator_tag(); +} + +template +using __iterator_concept = decltype(__get_iterator_concept<_Iter>()); + +} // namespace ranges +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_lexicographical_compare.h b/gnu/llvm/libcxx/include/__algorithm/ranges_lexicographical_compare.h new file mode 100644 index 00000000000..2972e327169 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_lexicographical_compare.h @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H +#define _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __lexicographical_compare { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __lexicographical_compare_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Comp& __comp, + _Proj1& __proj1, + _Proj2& __proj2) { + while (__first2 != __last2) { + if (__first1 == __last1 + || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) + return true; + if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) + return false; + ++__first1; + ++__first2; + } + return false; + } + + template _Sent1, + input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __lexicographical_compare_impl(std::move(__first1), std::move(__last1), + std::move(__first2), std::move(__last2), + __comp, + __proj1, + __proj2); + } + + template , _Proj1>, + projected, _Proj2>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __lexicographical_compare_impl(ranges::begin(__range1), ranges::end(__range1), + ranges::begin(__range2), ranges::end(__range2), + __comp, + __proj1, + __proj2); + } + +}; +} // namespace __lexicographical_compare + +inline namespace __cpo { + inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_lower_bound.h b/gnu/llvm/libcxx/include/__algorithm/ranges_lower_bound.h new file mode 100644 index 00000000000..78cbb6d4fb2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_lower_bound.h @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_LOWER_BOUND_H +#define _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/lower_bound.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +namespace __lower_bound { +struct __fn { + template _Sent, class _Type, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, + const _Type& __value, + _Comp __comp = {}, + _Proj __proj = {}) const { + return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); + } +}; +} // namespace __lower_bound + +inline namespace __cpo { + inline constexpr auto lower_bound = __lower_bound::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_make_heap.h b/gnu/llvm/libcxx/include/__algorithm/ranges_make_heap.h new file mode 100644 index 00000000000..f25c7ab5888 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_make_heap.h @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MAKE_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_heap.h> +#include <__algorithm/make_projected.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __make_heap { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__make_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __make_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __make_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __make_heap + +inline namespace __cpo { + inline constexpr auto make_heap = __make_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_max.h b/gnu/llvm/libcxx/include/__algorithm/ranges_max.h new file mode 100644 index 00000000000..55aef997698 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_max.h @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MAX_H +#define _LIBCPP___ALGORITHM_RANGES_MAX_H + +#include <__algorithm/ranges_min_element.h> +#include <__assert> +#include <__concepts/copyable.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __max { +struct __fn { + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { + return std::invoke(__comp, std::invoke(__proj, __a), std::invoke(__proj, __b)) ? __b : __a; + } + + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element"); + + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj); + } + + template , _Proj>> _Comp = ranges::less> + requires indirectly_copyable_storable, range_value_t<_Rp>*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); + + _LIBCPP_ASSERT(__first != __last, "range must contain at least one element"); + + if constexpr (forward_range<_Rp>) { + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + return *ranges::__min_element_impl(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj); + } else { + range_value_t<_Rp> __result = *__first; + while (++__first != __last) { + if (std::invoke(__comp, std::invoke(__proj, __result), std::invoke(__proj, *__first))) + __result = *__first; + } + return __result; + } + } +}; +} // namespace __max + +inline namespace __cpo { + inline constexpr auto max = __max::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 17 && + +#endif // _LIBCPP___ALGORITHM_RANGES_MAX_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_max_element.h b/gnu/llvm/libcxx/include/__algorithm/ranges_max_element.h new file mode 100644 index 00000000000..490f32075a4 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_max_element.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MAX_ELEMENT_H +#define _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H + +#include <__algorithm/ranges_min_element.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __max_element { +struct __fn { + template _Sp, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj); + } +}; +} // namespace __max_element + +inline namespace __cpo { + inline constexpr auto max_element = __max_element::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_merge.h b/gnu/llvm/libcxx/include/__algorithm/ranges_merge.h new file mode 100644 index 00000000000..b36a05abc41 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_merge.h @@ -0,0 +1,142 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MERGE_H +#define _LIBCPP___ALGORITHM_RANGES_MERGE_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/ranges_copy.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/mergeable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using merge_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; + +namespace __merge { + +template < + class _InIter1, + class _Sent1, + class _InIter2, + class _Sent2, + class _OutIter, + class _Comp, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>, __remove_cvref_t<_InIter2>, __remove_cvref_t<_OutIter>> +__merge_impl( + _InIter1&& __first1, + _Sent1&& __last1, + _InIter2&& __first2, + _Sent2&& __last2, + _OutIter&& __result, + _Comp&& __comp, + _Proj1&& __proj1, + _Proj2&& __proj2) { + for (; __first1 != __last1 && __first2 != __last2; ++__result) { + if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) { + *__result = *__first2; + ++__first2; + } else { + *__result = *__first1; + ++__first1; + } + } + auto __ret1 = ranges::copy(std::move(__first1), std::move(__last1), std::move(__result)); + auto __ret2 = ranges::copy(std::move(__first2), std::move(__last2), std::move(__ret1.out)); + return {std::move(__ret1.in), std::move(__ret2.in), std::move(__ret2.out)}; +} + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr merge_result<_InIter1, _InIter2, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __merge::__merge_impl(__first1, __last1, __first2, __last2, __result, __comp, __proj1, __proj2); + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable< + iterator_t<_Range1>, + iterator_t<_Range2>, + _OutIter, + _Comp, + _Proj1, + _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr merge_result, borrowed_iterator_t<_Range2>, _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __merge::__merge_impl( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __result, + __comp, + __proj1, + __proj2); + } +}; + +} // namespace __merge + +inline namespace __cpo { + inline constexpr auto merge = __merge::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MERGE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_min.h b/gnu/llvm/libcxx/include/__algorithm/ranges_min.h new file mode 100644 index 00000000000..0e31f57fb8d --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_min.h @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MIN_H +#define _LIBCPP___ALGORITHM_RANGES_MIN_H + +#include <__algorithm/ranges_min_element.h> +#include <__assert> +#include <__concepts/copyable.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __min { +struct __fn { + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { + return std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)) ? __b : __a; + } + + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element"); + return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + requires indirectly_copyable_storable, range_value_t<_Rp>*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); + + _LIBCPP_ASSERT(__first != __last, "range must contain at least one element"); + + if constexpr (forward_range<_Rp>) { + return *ranges::__min_element_impl(__first, __last, __comp, __proj); + } else { + range_value_t<_Rp> __result = *__first; + while (++__first != __last) { + if (std::invoke(__comp, std::invoke(__proj, *__first), std::invoke(__proj, __result))) + __result = *__first; + } + return __result; + } + } +}; +} // namespace __min + +inline namespace __cpo { + inline constexpr auto min = __min::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 17 && + +#endif // _LIBCPP___ALGORITHM_RANGES_MIN_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_min_element.h b/gnu/llvm/libcxx/include/__algorithm/ranges_min_element.h new file mode 100644 index 00000000000..1751874d03b --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_min_element.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H +#define _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +// TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`. +template +_LIBCPP_HIDE_FROM_ABI static constexpr +_Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { + if (__first == __last) + return __first; + + _Ip __i = __first; + while (++__i != __last) + if (std::invoke(__comp, std::invoke(__proj, *__i), std::invoke(__proj, *__first))) + __first = __i; + return __first; +} + +namespace __min_element { +struct __fn { + template _Sp, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__min_element_impl(__first, __last, __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; +} // namespace __min_element + +inline namespace __cpo { + inline constexpr auto min_element = __min_element::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_minmax.h b/gnu/llvm/libcxx/include/__algorithm/ranges_minmax.h new file mode 100644 index 00000000000..f82e00551e4 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_minmax.h @@ -0,0 +1,134 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MINMAX_H +#define _LIBCPP___ALGORITHM_RANGES_MINMAX_H + +#include <__algorithm/min_max_result.h> +#include <__algorithm/minmax_element.h> +#include <__assert> +#include <__concepts/copyable.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +template +using minmax_result = min_max_result<_T1>; + +namespace __minmax { +struct __fn { + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result + operator()(const _Type& __a, const _Type& __b, _Comp __comp = {}, _Proj __proj = {}) const { + if (std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a))) + return {__b, __a}; + return {__a, __b}; + } + + template > _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list has to contain at least one element"); + auto __iters = std::__minmax_element_impl(__il.begin(), __il.end(), __comp, __proj); + return ranges::minmax_result<_Type> { *__iters.first, *__iters.second }; + } + + template , _Proj>> _Comp = ranges::less> + requires indirectly_copyable_storable, range_value_t<_Range>*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_result> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); + using _ValueT = range_value_t<_Range>; + + _LIBCPP_ASSERT(__first != __last, "range has to contain at least one element"); + + if constexpr (forward_range<_Range>) { + auto __result = std::__minmax_element_impl(__first, __last, __comp, __proj); + return {*__result.first, *__result.second}; + } else { + // input_iterators can't be copied, so the implementation for input_iterators has to store + // the values instead of a pointer to the correct values + auto __less = [&](auto&& __a, auto&& __b) -> bool { + return std::invoke(__comp, std::invoke(__proj, std::forward(__a)), + std::invoke(__proj, std::forward(__b))); + }; + + ranges::minmax_result<_ValueT> __result = {*__first, __result.min}; + if (__first == __last || ++__first == __last) + return __result; + + if (__less(*__first, __result.min)) + __result.min = *__first; + else + __result.max = *__first; + + while (++__first != __last) { + _ValueT __i = *__first; + if (++__first == __last) { + if (__less(__i, __result.min)) + __result.min = __i; + else if (!__less(__i, __result.max)) + __result.max = __i; + return __result; + } + + if (__less(*__first, __i)) { + if (__less(*__first, __result.min)) + __result.min = *__first; + if (!__less(__i, __result.max)) + __result.max = std::move(__i); + } else { + if (__less(__i, __result.min)) + __result.min = std::move(__i); + if (!__less(*__first, __result.max)) + __result.max = *__first; + } + } + return __result; + } + } +}; +} // namespace __minmax + +inline namespace __cpo { + inline constexpr auto minmax = __minmax::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_minmax_element.h b/gnu/llvm/libcxx/include/__algorithm/ranges_minmax_element.h new file mode 100644 index 00000000000..6699f9626e1 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_minmax_element.h @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MINMAX_ELEMENT_H +#define _LIBCPP___ALGORITHM_RANGES_MINMAX_ELEMENT_H + +#include <__algorithm/min_max_result.h> +#include <__algorithm/minmax_element.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using minmax_element_result = min_max_result<_T1>; + +namespace __minmax_element { +struct __fn { + template _Sp, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj); + return {__ret.first, __ret.second}; + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + ranges::minmax_element_result> + operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + return {__ret.first, __ret.second}; + } +}; +} // namespace __minmax_element + +inline namespace __cpo { + inline constexpr auto minmax_element = __minmax_element::__fn{}; +} // namespace __cpo + +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_mismatch.h b/gnu/llvm/libcxx/include/__algorithm/ranges_mismatch.h new file mode 100644 index 00000000000..4fd05179283 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_mismatch.h @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MISMATCH_H +#define _LIBCPP___ALGORITHM_RANGES_MISMATCH_H + +#include <__algorithm/in_in_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace ranges { + +template +using mismatch_result = in_in_result<_I1, _I2>; + +namespace __mismatch { +struct __fn { + template + static _LIBCPP_HIDE_FROM_ABI constexpr + mismatch_result<_I1, _I2> + __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, + _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + while (__first1 != __last1 && __first2 != __last2) { + if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) + break; + ++__first1; + ++__first2; + } + return {std::move(__first1), std::move(__first2)}; + } + + template _S1, + input_iterator _I2, sentinel_for<_I2> _S2, + class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity> + requires indirectly_comparable<_I1, _I2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + mismatch_result<_I1, _I2> operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __go(std::move(__first1), __last1, std::move(__first2), __last2, __pred, __proj1, __proj2); + } + + template + requires indirectly_comparable, iterator_t<_R2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + mismatch_result, borrowed_iterator_t<_R2>> + operator()(_R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __go(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), + __pred, __proj1, __proj2); + } +}; +} // namespace __mismatch + +inline namespace __cpo { + constexpr inline auto mismatch = __mismatch::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_RANGES_MISMATCH_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_move.h b/gnu/llvm/libcxx/include/__algorithm/ranges_move.h new file mode 100644 index 00000000000..46a0970f834 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_move.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MOVE_H +#define _LIBCPP___ALGORITHM_RANGES_MOVE_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/move.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using move_result = in_out_result<_InIter, _OutIter>; + +namespace __move { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) { + auto __ret = std::__move<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template _Sent, weakly_incrementable _OutIter> + requires indirectly_movable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + return __move_impl(std::move(__first), std::move(__last), std::move(__result)); + } + + template + requires indirectly_movable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_result, _OutIter> operator()(_Range&& __range, _OutIter __result) const { + return __move_impl(ranges::begin(__range), ranges::end(__range), std::move(__result)); + } + +}; +} // namespace __move + +inline namespace __cpo { + inline constexpr auto move = __move::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_move_backward.h b/gnu/llvm/libcxx/include/__algorithm/ranges_move_backward.h new file mode 100644 index 00000000000..d4e8eb1a500 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_move_backward.h @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_MOVE_BACKWARD_H +#define _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/move_backward.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_move.h> +#include <__iterator/next.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using move_backward_result = in_out_result<_InIter, _OutIter>; + +namespace __move_backward { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + move_backward_result<_InIter, _OutIter> __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) { + auto __ret = std::__move_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template _Sent, bidirectional_iterator _OutIter> + requires indirectly_movable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_backward_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + return __move_backward_impl(std::move(__first), std::move(__last), std::move(__result)); + } + + template + requires indirectly_movable, _Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_backward_result, _Iter> operator()(_Range&& __range, _Iter __result) const { + return __move_backward_impl(ranges::begin(__range), ranges::end(__range), std::move(__result)); + } + +}; +} // namespace __move_backward + +inline namespace __cpo { + inline constexpr auto move_backward = __move_backward::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_next_permutation.h b/gnu/llvm/libcxx/include/__algorithm/ranges_next_permutation.h new file mode 100644 index 00000000000..6c8e8e1529f --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_next_permutation.h @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_NEXT_PERMUTATION_H +#define _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H + +#include <__algorithm/in_found_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/next_permutation.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using next_permutation_result = in_found_result<_InIter>; + +namespace __next_permutation { + +struct __fn { + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr next_permutation_result<_Iter> + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__next_permutation<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr next_permutation_result> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__next_permutation<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } +}; + +} // namespace __next_permutation + +inline namespace __cpo { +constexpr inline auto next_permutation = __next_permutation::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_none_of.h b/gnu/llvm/libcxx/include/__algorithm/ranges_none_of.h new file mode 100644 index 00000000000..b39e570fd33 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_none_of.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_NONE_OF_H +#define _LIBCPP___ALGORITHM_RANGES_NONE_OF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __none_of { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + bool __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + return false; + } + return true; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + return __none_of_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __none_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __none_of + +inline namespace __cpo { + inline constexpr auto none_of = __none_of::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_NONE_OF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_nth_element.h b/gnu/llvm/libcxx/include/__algorithm/ranges_nth_element.h new file mode 100644 index 00000000000..d9ec4f13825 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_nth_element.h @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_NTH_ELEMENT_H +#define _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/nth_element.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __nth_element { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__nth_element_impl<_RangeAlgPolicy>(std::move(__first), std::move(__nth), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __nth_element_fn_impl(std::move(__first), std::move(__nth), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, + _Proj __proj = {}) const { + return __nth_element_fn_impl(ranges::begin(__r), std::move(__nth), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __nth_element + +inline namespace __cpo { + inline constexpr auto nth_element = __nth_element::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_partial_sort.h b/gnu/llvm/libcxx/include/__algorithm/ranges_partial_sort.h new file mode 100644 index 00000000000..3ea0a7fb44b --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_partial_sort.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_PARTIAL_SORT_H +#define _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/partial_sort.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __partial_sort { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto&& __projected_comp = std::__make_projected(__comp, __proj); + return std::__partial_sort<_RangeAlgPolicy>(std::move(__first), std::move(__middle), __last, __projected_comp); + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __partial_sort_fn_impl(std::move(__first), std::move(__middle), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, + _Proj __proj = {}) const { + return __partial_sort_fn_impl(ranges::begin(__r), std::move(__middle), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __partial_sort + +inline namespace __cpo { + inline constexpr auto partial_sort = __partial_sort::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_partial_sort_copy.h b/gnu/llvm/libcxx/include/__algorithm/ranges_partial_sort_copy.h new file mode 100644 index 00000000000..212db555a8d --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_partial_sort_copy.h @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/partial_sort_copy.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using partial_sort_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __partial_sort_copy { + +struct __fn { + + template _Sent1, + random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity> + requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> && + indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> + _LIBCPP_HIDE_FROM_ABI constexpr + partial_sort_copy_result<_Iter1, _Iter2> + operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last, + _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + auto __result = std::__partial_sort_copy<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::move(__result_first), std::move(__result_last), + __comp, __proj1, __proj2 + ); + return {std::move(__result.first), std::move(__result.second)}; + } + + template + requires indirectly_copyable, iterator_t<_Range2>> && + sortable, _Comp, _Proj2> && + indirect_strict_weak_order<_Comp, projected, _Proj1>, + projected, _Proj2>> + _LIBCPP_HIDE_FROM_ABI constexpr + partial_sort_copy_result, borrowed_iterator_t<_Range2>> + operator()(_Range1&& __range, _Range2&& __result_range, _Comp __comp = {}, + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + auto __result = std::__partial_sort_copy<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), ranges::begin(__result_range), ranges::end(__result_range), + __comp, __proj1, __proj2 + ); + return {std::move(__result.first), std::move(__result.second)}; + } + +}; + +} // namespace __partial_sort_copy + +inline namespace __cpo { + inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_partition.h b/gnu/llvm/libcxx/include/__algorithm/ranges_partition.h new file mode 100644 index 00000000000..8b3aae5c250 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_partition.h @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_PARTITION_H +#define _LIBCPP___ALGORITHM_RANGES_PARTITION_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/partition.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __partition { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI static constexpr + subrange<__remove_cvref_t<_Iter>> __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { + auto&& __projected_pred = std::__make_projected(__pred, __proj); + auto __result = std::__partition<_RangeAlgPolicy>( + std::move(__first), std::move(__last), __projected_pred, __iterator_concept<_Iter>()); + + return {std::move(__result.first), std::move(__result.second)}; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __partition_fn_impl(__first, __last, __pred, __proj); + } + + template , _Proj>> _Pred> + requires permutable> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } + +}; + +} // namespace __partition + +inline namespace __cpo { + inline constexpr auto partition = __partition::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_partition_copy.h b/gnu/llvm/libcxx/include/__algorithm/ranges_partition_copy.h new file mode 100644 index 00000000000..e7a9a347df5 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_partition_copy.h @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_PARTITION_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H + +#include <__algorithm/in_out_out_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>; + +namespace __partition_copy { + +struct __fn { + + // TODO(ranges): delegate to the classic algorithm. + template + _LIBCPP_HIDE_FROM_ABI constexpr + static partition_copy_result< + __remove_cvref_t<_InIter>, __remove_cvref_t<_OutIter1>, __remove_cvref_t<_OutIter2> + > __partition_copy_fn_impl( _InIter&& __first, _Sent&& __last, _OutIter1&& __out_true, _OutIter2&& __out_false, + _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) { + *__out_true = *__first; + ++__out_true; + + } else { + *__out_false = *__first; + ++__out_false; + } + } + + return {std::move(__first), std::move(__out_true), std::move(__out_false)}; + } + + template _Sent, + weakly_incrementable _OutIter1, weakly_incrementable _OutIter2, + class _Proj = identity, indirect_unary_predicate> _Pred> + requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + partition_copy_result<_InIter, _OutIter1, _OutIter2> + operator()(_InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, + _Pred __pred, _Proj __proj = {}) const { + return __partition_copy_fn_impl( + std::move(__first), std::move(__last), std::move(__out_true), std::move(__out_false), __pred, __proj); + } + + template , _Proj>> _Pred> + requires indirectly_copyable, _OutIter1> && indirectly_copyable, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr + partition_copy_result, _OutIter1, _OutIter2> + operator()(_Range&& __range, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) const { + return __partition_copy_fn_impl( + ranges::begin(__range), ranges::end(__range), std::move(__out_true), std::move(__out_false), __pred, __proj); + } + +}; + +} // namespace __partition_copy + +inline namespace __cpo { + inline constexpr auto partition_copy = __partition_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_partition_point.h b/gnu/llvm/libcxx/include/__algorithm/ranges_partition_point.h new file mode 100644 index 00000000000..2bd118d4def --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_partition_point.h @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_PARTITION_POINT_H +#define _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H + +#include <__algorithm/half_positive.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __partition_point { + +struct __fn { + + // TODO(ranges): delegate to the classic algorithm. + template + _LIBCPP_HIDE_FROM_ABI constexpr + static _Iter __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) { + auto __len = ranges::distance(__first, __last); + + while (__len != 0) { + auto __half_len = std::__half_positive(__len); + auto __mid = ranges::next(__first, __half_len); + + if (std::invoke(__pred, std::invoke(__proj, *__mid))) { + __first = ++__mid; + __len -= __half_len + 1; + + } else { + __len = __half_len; + } + } + + return __first; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __partition_point_fn_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __partition_point_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } + +}; + +} // namespace __partition_point + +inline namespace __cpo { + inline constexpr auto partition_point = __partition_point::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_pop_heap.h b/gnu/llvm/libcxx/include/__algorithm/ranges_pop_heap.h new file mode 100644 index 00000000000..65beec88644 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_pop_heap.h @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_POP_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/pop_heap.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __pop_heap { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + auto __len = __last_iter - __first; + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__pop_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp, __len); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __pop_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __pop_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __pop_heap + +inline namespace __cpo { + inline constexpr auto pop_heap = __pop_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_prev_permutation.h b/gnu/llvm/libcxx/include/__algorithm/ranges_prev_permutation.h new file mode 100644 index 00000000000..6866d90cf48 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_prev_permutation.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 _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H +#define _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H + +#include <__algorithm/in_found_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/prev_permutation.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using prev_permutation_result = in_found_result<_InIter>; + +namespace __prev_permutation { + +struct __fn { + + template _Sent, + class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<_Iter> + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__prev_permutation<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __result = std::__prev_permutation<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); + return {std::move(__result.first), std::move(__result.second)}; + } + +}; + +} // namespace __prev_permutation + +inline namespace __cpo { +constexpr inline auto prev_permutation = __prev_permutation::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_push_heap.h b/gnu/llvm/libcxx/include/__algorithm/ranges_push_heap.h new file mode 100644 index 00000000000..a1f43474176 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_push_heap.h @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_PUSH_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/push_heap.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __push_heap { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__push_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __push_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __push_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __push_heap + +inline namespace __cpo { + inline constexpr auto push_heap = __push_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_remove.h b/gnu/llvm/libcxx/include/__algorithm/ranges_remove.h new file mode 100644 index 00000000000..dd5c5fb4536 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_remove.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_H +#define _LIBCPP___ALGORITHM_RANGES_REMOVE_H +#include <__config> + +#include <__algorithm/ranges_remove_if.h> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __remove { +struct __fn { + + template _Sent, class _Type, class _Proj = identity> + requires indirect_binary_predicate, const _Type*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __other) { return __value == __other; }; + return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template + requires permutable> + && indirect_binary_predicate, _Proj>, const _Type*> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __other) { return __value == __other; }; + return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __remove + +inline namespace __cpo { + inline constexpr auto remove = __remove::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_remove_copy.h b/gnu/llvm/libcxx/include/__algorithm/ranges_remove_copy.h new file mode 100644 index 00000000000..21022286675 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_remove_copy.h @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_REMOVE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/ranges_remove_copy_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using remove_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __remove_copy { + + struct __fn { + template _Sent, + weakly_incrementable _OutIter, + class _Type, + class _Proj = identity> + requires indirectly_copyable<_InIter, _OutIter> && + indirect_binary_predicate, const _Type*> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __val) { return __value == __val; }; + return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); + } + + template + requires indirectly_copyable, _OutIter> && + indirect_binary_predicate, _Proj>, const _Type*> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __val) { return __value == __val; }; + return ranges::__remove_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); + } + }; + +} // namespace __remove_copy + +inline namespace __cpo { + inline constexpr auto remove_copy = __remove_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_remove_copy_if.h b/gnu/llvm/libcxx/include/__algorithm/ranges_remove_copy_if.h new file mode 100644 index 00000000000..4fc67454b92 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_remove_copy_if.h @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_REMOVE_COPY_IF_H +#define _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/remove_copy_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using remove_copy_if_result = in_out_result<_InIter, _OutIter>; + +template +_LIBCPP_HIDE_FROM_ABI constexpr in_out_result<_InIter, _OutIter> +__remove_copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (!std::invoke(__pred, std::invoke(__proj, *__first))) { + *__result = *__first; + ++__result; + } + } + return {std::move(__first), std::move(__result)}; +} + +namespace __remove_copy_if { + + struct __fn { + template _Sent, + weakly_incrementable _OutIter, + class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); + } + + template , _Proj>> _Pred> + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); + } + }; + +} // namespace __remove_copy_if + +inline namespace __cpo { + inline constexpr auto remove_copy_if = __remove_copy_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_remove_if.h b/gnu/llvm/libcxx/include/__algorithm/ranges_remove_if.h new file mode 100644 index 00000000000..1f17467fc43 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_remove_if.h @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_REMOVE_IF_H +#define _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H +#include <__config> + +#include <__algorithm/ranges_find_if.h> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iter_move.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr +subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + auto __new_end = ranges::__find_if_impl(__first, __last, __pred, __proj); + if (__new_end == __last) + return {__new_end, __new_end}; + + _Iter __i = __new_end; + while (++__i != __last) { + if (!std::invoke(__pred, std::invoke(__proj, *__i))) { + *__new_end = ranges::iter_move(__i); + ++__new_end; + } + } + return {__new_end, __i}; +} + +namespace __remove_if { +struct __fn { + + template _Sent, + class _Proj = identity, + indirect_unary_predicate> _Pred> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>> _Pred> + requires permutable> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } + +}; +} // namespace __remove_if + +inline namespace __cpo { + inline constexpr auto remove_if = __remove_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_replace.h b/gnu/llvm/libcxx/include/__algorithm/ranges_replace.h new file mode 100644 index 00000000000..8b12beacb71 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_replace.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_H +#define _LIBCPP___ALGORITHM_RANGES_REPLACE_H + +#include <__algorithm/ranges_replace_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __replace { +struct __fn { + + template _Sent, + class _Type1, + class _Type2, + class _Proj = identity> + requires indirectly_writable<_Iter, const _Type2&> + && indirect_binary_predicate, const _Type1*> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, + const _Type1& __old_value, + const _Type2& __new_value, + _Proj __proj = {}) const { + auto __pred = [&](const auto& __val) { return __val == __old_value; }; + return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj); + } + + template + requires indirectly_writable, const _Type2&> + && indirect_binary_predicate, _Proj>, const _Type1*> + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __range, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __val) { return __val == __old_value; }; + return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj); + } + +}; +} // namespace __replace + +inline namespace __cpo { + inline constexpr auto replace = __replace::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_replace_copy.h b/gnu/llvm/libcxx/include/__algorithm/ranges_replace_copy.h new file mode 100644 index 00000000000..f87a236fbd0 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_replace_copy.h @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_REPLACE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/ranges_replace_copy_if.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using replace_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __replace_copy { + + struct __fn { + template _Sent, + class _OldType, + class _NewType, + output_iterator _OutIter, + class _Proj = identity> + requires indirectly_copyable<_InIter, _OutIter> && + indirect_binary_predicate, const _OldType*> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter> + operator()(_InIter __first, + _Sent __last, + _OutIter __result, + const _OldType& __old_value, + const _NewType& __new_value, + _Proj __proj = {}) const { + auto __pred = [&](const auto& __value) { return __value == __old_value; }; + return ranges::__replace_copy_if_impl( + std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); + } + + template _OutIter, + class _Proj = identity> + requires indirectly_copyable, _OutIter> && + indirect_binary_predicate, _Proj>, const _OldType*> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result, _OutIter> + operator()(_Range&& __range, + _OutIter __result, + const _OldType& __old_value, + const _NewType& __new_value, + _Proj __proj = {}) const { + auto __pred = [&](const auto& __value) { return __value == __old_value; }; + return ranges::__replace_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); + } + }; + +} // namespace __replace_copy + +inline namespace __cpo { + inline constexpr auto replace_copy = __replace_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_replace_copy_if.h b/gnu/llvm/libcxx/include/__algorithm/ranges_replace_copy_if.h new file mode 100644 index 00000000000..b8741ec7be5 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_replace_copy_if.h @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_REPLACE_COPY_IF_H +#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H + +#include <__algorithm/in_out_result.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using replace_copy_if_result = in_out_result<_InIter, _OutIter>; + +template +_LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> __replace_copy_if_impl( + _InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, const _Type& __new_value, _Proj& __proj) { + while (__first != __last) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + *__result = __new_value; + else + *__result = *__first; + + ++__first; + ++__result; + } + + return {std::move(__first), std::move(__result)}; +} + +namespace __replace_copy_if { + + struct __fn { + template _Sent, + class _Type, + output_iterator _OutIter, + class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()( + _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) + const { + return ranges::__replace_copy_if_impl( + std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); + } + + template _OutIter, + class _Proj = identity, + indirect_unary_predicate, _Proj>> _Pred> + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { + return ranges::__replace_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); + } + }; + +} // namespace __replace_copy_if + +inline namespace __cpo { + inline constexpr auto replace_copy_if = __replace_copy_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_replace_if.h b/gnu/llvm/libcxx/include/__algorithm/ranges_replace_if.h new file mode 100644 index 00000000000..65be3c7d76d --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_replace_if.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 _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H +#define _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr +_Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) { + for (; __first != __last; ++__first) { + if (std::invoke(__pred, std::invoke(__proj, *__first))) + *__first = __new_value; + } + return __first; +} + +namespace __replace_if { +struct __fn { + + template _Sent, + class _Type, + class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_writable<_Iter, const _Type&> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { + return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj); + } + + template , _Proj>> _Pred> + requires indirectly_writable, const _Type&> + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __range, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { + return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj); + } + +}; +} // namespace __replace_if + +inline namespace __cpo { + inline constexpr auto replace_if = __replace_if::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_reverse.h b/gnu/llvm/libcxx/include/__algorithm/ranges_reverse.h new file mode 100644 index 00000000000..e2a5d9a8250 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_reverse.h @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_REVERSE_H +#define _LIBCPP___ALGORITHM_RANGES_REVERSE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_swap.h> +#include <__iterator/next.h> +#include <__iterator/permutable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __reverse { +struct __fn { + + template _Sent> + requires permutable<_Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last) const { + if constexpr (random_access_iterator<_Iter>) { + if (__first == __last) + return __first; + + auto __end = ranges::next(__first, __last); + auto __ret = __end; + + while (__first < --__end) { + ranges::iter_swap(__first, __end); + ++__first; + } + return __ret; + } else { + auto __end = ranges::next(__first, __last); + auto __ret = __end; + + while (__first != __end) { + if (__first == --__end) + break; + + ranges::iter_swap(__first, __end); + ++__first; + } + return __ret; + } + } + + template + requires permutable> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range) const { + return (*this)(ranges::begin(__range), ranges::end(__range)); + } + +}; +} // namespace __reverse + +inline namespace __cpo { + inline constexpr auto reverse = __reverse::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_reverse_copy.h b/gnu/llvm/libcxx/include/__algorithm/ranges_reverse_copy.h new file mode 100644 index 00000000000..a84b1ad7805 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_reverse_copy.h @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_REVERSE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/ranges_copy.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/next.h> +#include <__iterator/reverse_iterator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using reverse_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __reverse_copy { +struct __fn { + + template _Sent, weakly_incrementable _OutIter> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + reverse_copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + return (*this)(subrange(std::move(__first), std::move(__last)), std::move(__result)); + } + + template + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + reverse_copy_result, _OutIter> operator()(_Range&& __range, _OutIter __result) const { + auto __ret = ranges::copy(std::__reverse_range(__range), std::move(__result)); + return {ranges::next(ranges::begin(__range), ranges::end(__range)), std::move(__ret.out)}; + } + +}; +} // namespace __reverse_copy + +inline namespace __cpo { + inline constexpr auto reverse_copy = __reverse_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_rotate.h b/gnu/llvm/libcxx/include/__algorithm/ranges_rotate.h new file mode 100644 index 00000000000..91ed4027df2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_rotate.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_ROTATE_H +#define _LIBCPP___ALGORITHM_RANGES_ROTATE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__algorithm/rotate.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/permutable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __rotate { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr + static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) { + auto __ret = std::__rotate<_RangeAlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template _Sent> + _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const { + return __rotate_fn_impl(std::move(__first), std::move(__middle), std::move(__last)); + } + + template + requires permutable> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, iterator_t<_Range> __middle) const { + return __rotate_fn_impl(ranges::begin(__range), std::move(__middle), ranges::end(__range)); + } + +}; + +} // namespace __rotate + +inline namespace __cpo { + inline constexpr auto rotate = __rotate::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_rotate_copy.h b/gnu/llvm/libcxx/include/__algorithm/ranges_rotate_copy.h new file mode 100644 index 00000000000..52f403c16a8 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_rotate_copy.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_ROTATE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/ranges_copy.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/reverse_iterator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using rotate_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __rotate_copy { +struct __fn { + + template _Sent, weakly_incrementable _OutIter> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + rotate_copy_result<_InIter, _OutIter> + operator()(_InIter __first, _InIter __middle, _Sent __last, _OutIter __result) const { + auto __res1 = ranges::copy(__middle, __last, std::move(__result)); + auto __res2 = ranges::copy(__first, __middle, std::move(__res1.out)); + return {std::move(__res1.in), std::move(__res2.out)}; + } + + template + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr + rotate_copy_result, _OutIter> + operator()(_Range&& __range, iterator_t<_Range> __middle, _OutIter __result) const { + return (*this)(ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__result)); + } + +}; +} // namespace __rotate_copy + +inline namespace __cpo { + inline constexpr auto rotate_copy = __rotate_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_sample.h b/gnu/llvm/libcxx/include/__algorithm/ranges_sample.h new file mode 100644 index 00000000000..a37cb64fa2b --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_sample.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_SAMPLE_H +#define _LIBCPP___ALGORITHM_RANGES_SAMPLE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/sample.h> +#include <__algorithm/uniform_random_bit_generator_adaptor.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__random/uniform_random_bit_generator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __sample { + +struct __fn { + + template _Sent, weakly_incrementable _OutIter, class _Gen> + requires (forward_iterator<_Iter> || random_access_iterator<_OutIter>) && + indirectly_copyable<_Iter, _OutIter> && + uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI + _OutIter operator()(_Iter __first, _Sent __last, + _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const { + _ClassicGenAdaptor<_Gen> __adapted_gen(__gen); + return std::__sample<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::move(__out_first), __n, __adapted_gen); + } + + template + requires (forward_range<_Range> || random_access_iterator<_OutIter>) && + indirectly_copyable, _OutIter> && + uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI + _OutIter operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const { + return (*this)(ranges::begin(__range), ranges::end(__range), + std::move(__out_first), __n, std::forward<_Gen>(__gen)); + } + +}; + +} // namespace __sample + +inline namespace __cpo { + inline constexpr auto sample = __sample::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SAMPLE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_search.h b/gnu/llvm/libcxx/include/__algorithm/ranges_search.h new file mode 100644 index 00000000000..388d5afa499 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_search.h @@ -0,0 +1,135 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SEARCH_H +#define _LIBCPP___ALGORITHM_RANGES_SEARCH_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/search.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/indirectly_comparable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/size.h> +#include <__ranges/subrange.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __search { +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { + if constexpr (sized_sentinel_for<_Sent2, _Iter2>) { + auto __size2 = ranges::distance(__first2, __last2); + if (__size2 == 0) + return {__first1, __first1}; + + if constexpr (sized_sentinel_for<_Sent1, _Iter1>) { + auto __size1 = ranges::distance(__first1, __last1); + if (__size1 < __size2) { + ranges::advance(__first1, __last1); + return {__first1, __first1}; + } + + if constexpr (random_access_iterator<_Iter1> && random_access_iterator<_Iter2>) { + auto __ret = std::__search_random_access_impl<_RangeAlgPolicy>( + __first1, __last1, __first2, __last2, __pred, __proj1, __proj2, __size1, __size2); + return {__ret.first, __ret.second}; + } + } + } + + auto __ret = + std::__search_forward_impl<_RangeAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); + return {__ret.first, __ret.second}; + } + + template _Sent1, + forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __ranges_search_impl(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); + } + + template + requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range1> operator()(_Range1&& __range1, + _Range2&& __range2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __first1 = ranges::begin(__range1); + if constexpr (sized_range<_Range2>) { + auto __size2 = ranges::size(__range2); + if (__size2 == 0) + return {__first1, __first1}; + if constexpr (sized_range<_Range1>) { + auto __size1 = ranges::size(__range1); + if (__size1 < __size2) { + ranges::advance(__first1, ranges::end(__range1)); + return {__first1, __first1}; + } + } + } + + return __ranges_search_impl( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __pred, + __proj1, + __proj2); + } + +}; +} // namespace __search + +inline namespace __cpo { + inline constexpr auto search = __search::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_search_n.h b/gnu/llvm/libcxx/include/__algorithm/ranges_search_n.h new file mode 100644 index 00000000000..56ec8f33d43 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_search_n.h @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SEARCH_N_H +#define _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/search_n.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/size.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __search_n { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_n_impl( + _Iter1 __first, _Sent1 __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) { + if (__count == 0) + return {__first, __first}; + + if constexpr (sized_sentinel_for<_Sent1, _Iter1>) { + auto __size = ranges::distance(__first, __last); + if (__size < __count) { + ranges::advance(__first, __last); + return {__first, __first}; + } + + if constexpr (random_access_iterator<_Iter1>) { + auto __ret = std::__search_n_random_access_impl<_RangeAlgPolicy>( + __first, __last, __count, __value, __pred, __proj, __size); + return {std::move(__ret.first), std::move(__ret.second)}; + } + } + + auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last, + __count, + __value, + __pred, + __proj); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template _Sent, + class _Type, + class _Pred = ranges::equal_to, + class _Proj = identity> + requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + subrange<_Iter> operator()(_Iter __first, _Sent __last, + iter_difference_t<_Iter> __count, + const _Type& __value, + _Pred __pred = {}, + _Proj __proj = _Proj{}) const { + return __ranges_search_n_impl(__first, __last, __count, __value, __pred, __proj); + } + + template + requires indirectly_comparable, const _Type*, _Pred, _Proj> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_subrange_t<_Range> operator()(_Range&& __range, + range_difference_t<_Range> __count, + const _Type& __value, + _Pred __pred = {}, + _Proj __proj = {}) const { + auto __first = ranges::begin(__range); + if (__count <= 0) + return {__first, __first}; + if constexpr (sized_range<_Range>) { + auto __size1 = ranges::size(__range); + if (__size1 < static_cast>(__count)) { + ranges::advance(__first, ranges::end(__range)); + return {__first, __first}; + } + } + + return __ranges_search_n_impl(ranges::begin(__range), ranges::end(__range), __count, __value, __pred, __proj); + } +}; +} // namespace __search_n + +inline namespace __cpo { + inline constexpr auto search_n = __search_n::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_set_difference.h b/gnu/llvm/libcxx/include/__algorithm/ranges_set_difference.h new file mode 100644 index 00000000000..607dd687a5d --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_set_difference.h @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SET_DIFFERENCE_H +#define _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/set_difference.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/mergeable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__type_traits/decay.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using set_difference_result = in_out_result<_InIter, _OutIter>; + +namespace __set_difference { + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<_InIter1, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_difference<_RangeAlgPolicy>( + __first1, __last1, __first2, __last2, __result, ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result, _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_difference<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __result, + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; + +} // namespace __set_difference + +inline namespace __cpo { + inline constexpr auto set_difference = __set_difference::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_set_intersection.h b/gnu/llvm/libcxx/include/__algorithm/ranges_set_intersection.h new file mode 100644 index 00000000000..aa9fd24ced0 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_set_intersection.h @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SET_INTERSECTION_H +#define _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/set_intersection.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/mergeable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using set_intersection_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; + +namespace __set_intersection { + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<_InIter1, _InIter2, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_intersection<_RangeAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable< + iterator_t<_Range1>, + iterator_t<_Range2>, + _OutIter, + _Comp, + _Proj1, + _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result, + borrowed_iterator_t<_Range2>, + _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_intersection<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } +}; + +} // namespace __set_intersection + +inline namespace __cpo { + inline constexpr auto set_intersection = __set_intersection::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_set_symmetric_difference.h b/gnu/llvm/libcxx/include/__algorithm/ranges_set_symmetric_difference.h new file mode 100644 index 00000000000..bc4a9065503 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_set_symmetric_difference.h @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H +#define _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/set_symmetric_difference.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/mergeable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using set_symmetric_difference_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; + +namespace __set_symmetric_difference { + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<_InIter1, _InIter2, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable< + iterator_t<_Range1>, + iterator_t<_Range2>, + _OutIter, + _Comp, + _Proj1, + _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result, + borrowed_iterator_t<_Range2>, + _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } +}; + +} // namespace __set_symmetric_difference + +inline namespace __cpo { + inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_set_union.h b/gnu/llvm/libcxx/include/__algorithm/ranges_set_union.h new file mode 100644 index 00000000000..f8cd45ca0e3 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_set_union.h @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SET_UNION_H +#define _LIBCPP___ALGORITHM_RANGES_SET_UNION_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/set_union.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/mergeable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using set_union_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; + +namespace __set_union { + +struct __fn { + template < + input_iterator _InIter1, + sentinel_for<_InIter1> _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<_InIter1, _InIter2, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_union<_RangeAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } + + template < + input_range _Range1, + input_range _Range2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> + requires mergeable< + iterator_t<_Range1>, + iterator_t<_Range2>, + _OutIter, + _Comp, + _Proj1, + _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_union_result, + borrowed_iterator_t<_Range2>, + _OutIter> + operator()( + _Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + auto __ret = std::__set_union<_RangeAlgPolicy>( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + std::move(__result), + ranges::__make_projected_comp(__comp, __proj1, __proj2)); + return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; + } +}; + +} // namespace __set_union + +inline namespace __cpo { + inline constexpr auto set_union = __set_union::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SET_UNION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_shuffle.h b/gnu/llvm/libcxx/include/__algorithm/ranges_shuffle.h new file mode 100644 index 00000000000..a2f2c0edded --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_shuffle.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SHUFFLE_H +#define _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/shuffle.h> +#include <__algorithm/uniform_random_bit_generator_adaptor.h> +#include <__config> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/permutable.h> +#include <__random/uniform_random_bit_generator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __shuffle { + +struct __fn { + + template _Sent, class _Gen> + requires permutable<_Iter> && uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI + _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const { + _ClassicGenAdaptor<_Gen> __adapted_gen(__gen); + return std::__shuffle<_RangeAlgPolicy>(std::move(__first), std::move(__last), __adapted_gen); + } + + template + requires permutable> && uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const { + return (*this)(ranges::begin(__range), ranges::end(__range), std::forward<_Gen>(__gen)); + } + +}; + +} // namespace __shuffle + +inline namespace __cpo { + inline constexpr auto shuffle = __shuffle::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_sort.h b/gnu/llvm/libcxx/include/__algorithm/ranges_sort.h new file mode 100644 index 00000000000..32391df5f6d --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_sort.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SORT_H +#define _LIBCPP___ALGORITHM_RANGES_SORT_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/sort.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __sort { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __sort + +inline namespace __cpo { + inline constexpr auto sort = __sort::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SORT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_sort_heap.h b/gnu/llvm/libcxx/include/__algorithm/ranges_sort_heap.h new file mode 100644 index 00000000000..9feb0f609b2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_sort_heap.h @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SORT_HEAP_H +#define _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/sort_heap.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __sort_heap { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__sort_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __sort_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __sort_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __sort_heap + +inline namespace __cpo { + inline constexpr auto sort_heap = __sort_heap::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_stable_partition.h b/gnu/llvm/libcxx/include/__algorithm/ranges_stable_partition.h new file mode 100644 index 00000000000..c3469f17c7d --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_stable_partition.h @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_STABLE_PARTITION_H +#define _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/ranges_iterator_concept.h> +#include <__algorithm/stable_partition.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__ranges/subrange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __stable_partition { + +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI static + subrange<__remove_cvref_t<_Iter>> __stable_partition_fn_impl( + _Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_pred = std::__make_projected(__pred, __proj); + auto __result = std::__stable_partition<_RangeAlgPolicy>( + std::move(__first), __last_iter, __projected_pred, __iterator_concept<_Iter>()); + + return {std::move(__result), std::move(__last_iter)}; + } + + template _Sent, class _Proj = identity, + indirect_unary_predicate> _Pred> + requires permutable<_Iter> + _LIBCPP_HIDE_FROM_ABI + subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __stable_partition_fn_impl(__first, __last, __pred, __proj); + } + + template , _Proj>> _Pred> + requires permutable> + _LIBCPP_HIDE_FROM_ABI + borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __stable_partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } + +}; + +} // namespace __stable_partition + +inline namespace __cpo { + inline constexpr auto stable_partition = __stable_partition::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_stable_sort.h b/gnu/llvm/libcxx/include/__algorithm/ranges_stable_sort.h new file mode 100644 index 00000000000..d3c48ddb9b8 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_stable_sort.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_STABLE_SORT_H +#define _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/stable_sort.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/projected.h> +#include <__iterator/sortable.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __stable_sort { + +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI + static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + + auto&& __projected_comp = std::__make_projected(__comp, __proj); + std::__stable_sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp); + + return __last_iter; + } + + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI + _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __stable_sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj); + } + + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return __stable_sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; + +} // namespace __stable_sort + +inline namespace __cpo { + inline constexpr auto stable_sort = __stable_sort::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_swap_ranges.h b/gnu/llvm/libcxx/include/__algorithm/ranges_swap_ranges.h new file mode 100644 index 00000000000..552fd55ff88 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_swap_ranges.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_SWAP_RANGES_H +#define _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H + +#include <__algorithm/in_in_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/swap_ranges.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_swap.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using swap_ranges_result = in_in_result<_I1, _I2>; + +namespace __swap_ranges { +struct __fn { + template _S1, + input_iterator _I2, sentinel_for<_I2> _S2> + requires indirectly_swappable<_I1, _I2> + _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<_I1, _I2> + operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2) const { + auto __ret = std::__swap_ranges<_RangeAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template + requires indirectly_swappable, iterator_t<_R2>> + _LIBCPP_HIDE_FROM_ABI constexpr + swap_ranges_result, borrowed_iterator_t<_R2>> + operator()(_R1&& __r1, _R2&& __r2) const { + return operator()(ranges::begin(__r1), ranges::end(__r1), + ranges::begin(__r2), ranges::end(__r2)); + } +}; +} // namespace __swap_ranges + +inline namespace __cpo { + inline constexpr auto swap_ranges = __swap_ranges::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_transform.h b/gnu/llvm/libcxx/include/__algorithm/ranges_transform.h new file mode 100644 index 00000000000..c0981a04a9b --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_transform.h @@ -0,0 +1,170 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_TRANSFORM_H +#define _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H + +#include <__algorithm/in_in_out_result.h> +#include <__algorithm/in_out_result.h> +#include <__concepts/constructible.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using unary_transform_result = in_out_result<_Ip, _Op>; + +template +using binary_transform_result = in_in_out_result<_I1, _I2, _O1>; + +namespace __transform { +struct __fn { +private: + template + _LIBCPP_HIDE_FROM_ABI static constexpr + unary_transform_result<_InIter, _OutIter> __unary(_InIter __first, _Sent __last, + _OutIter __result, + _Func& __operation, + _Proj& __projection) { + while (__first != __last) { + *__result = std::invoke(__operation, std::invoke(__projection, *__first)); + ++__first; + ++__result; + } + + return {std::move(__first), std::move(__result)}; + } + + template + _LIBCPP_HIDE_FROM_ABI static constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> + __binary(_InIter1 __first1, _Sent1 __last1, + _InIter2 __first2, _Sent2 __last2, + _OutIter __result, + _Func& __binary_operation, + _Proj1& __projection1, + _Proj2& __projection2) { + while (__first1 != __last1 && __first2 != __last2) { + *__result = std::invoke(__binary_operation, std::invoke(__projection1, *__first1), + std::invoke(__projection2, *__first2)); + ++__first1; + ++__first2; + ++__result; + } + return {std::move(__first1), std::move(__first2), std::move(__result)}; + } +public: + template _Sent, + weakly_incrementable _OutIter, + copy_constructible _Func, + class _Proj = identity> + requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter, _Proj>>> + _LIBCPP_HIDE_FROM_ABI constexpr + unary_transform_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, + _OutIter __result, + _Func __operation, + _Proj __proj = {}) const { + return __unary(std::move(__first), std::move(__last), std::move(__result), __operation, __proj); + } + + template + requires indirectly_writable<_OutIter, indirect_result_t<_Func, projected, _Proj>>> + _LIBCPP_HIDE_FROM_ABI constexpr + unary_transform_result, _OutIter> operator()(_Range&& __range, + _OutIter __result, + _Func __operation, + _Proj __projection = {}) const { + return __unary(ranges::begin(__range), ranges::end(__range), std::move(__result), __operation, __projection); + } + + template _Sent1, + input_iterator _InIter2, sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + copy_constructible _Func, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter1, _Proj1>, + projected<_InIter2, _Proj2>>> + _LIBCPP_HIDE_FROM_ABI constexpr + binary_transform_result<_InIter1, _InIter2, _OutIter> operator()(_InIter1 __first1, _Sent1 __last1, + _InIter2 __first2, _Sent2 __last2, + _OutIter __result, + _Func __binary_operation, + _Proj1 __projection1 = {}, + _Proj2 __projection2 = {}) const { + return __binary(std::move(__first1), std::move(__last1), + std::move(__first2), std::move(__last2), + std::move(__result), + __binary_operation, + __projection1, + __projection2); + } + + template + requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected, _Proj1>, + projected, _Proj2>>> + _LIBCPP_HIDE_FROM_ABI constexpr + binary_transform_result, borrowed_iterator_t<_Range2>, _OutIter> + operator()(_Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Func __binary_operation, + _Proj1 __projection1 = {}, + _Proj2 __projection2 = {}) const { + return __binary(ranges::begin(__range1), ranges::end(__range1), + ranges::begin(__range2), ranges::end(__range2), + std::move(__result), + __binary_operation, + __projection1, + __projection2); + } + +}; +} // namespace __transform + +inline namespace __cpo { + inline constexpr auto transform = __transform::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_unique.h b/gnu/llvm/libcxx/include/__algorithm/ranges_unique.h new file mode 100644 index 00000000000..be427ccf7fa --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_unique.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_UNIQUE_H +#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/unique.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__ranges/subrange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __unique { + + struct __fn { + template < + permutable _Iter, + sentinel_for<_Iter> _Sent, + class _Proj = identity, + indirect_equivalence_relation> _Comp = ranges::equal_to> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__unique<_RangeAlgPolicy>( + std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template < + forward_range _Range, + class _Proj = identity, + indirect_equivalence_relation, _Proj>> _Comp = ranges::equal_to> + requires permutable> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__unique<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); + return {std::move(__ret.first), std::move(__ret.second)}; + } + }; + +} // namespace __unique + +inline namespace __cpo { + inline constexpr auto unique = __unique::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_unique_copy.h b/gnu/llvm/libcxx/include/__algorithm/ranges_unique_copy.h new file mode 100644 index 00000000000..3ad47b06f5d --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_unique_copy.h @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_UNIQUE_COPY_H +#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H + +#include <__algorithm/in_out_result.h> +#include <__algorithm/iterator_operations.h> +#include <__algorithm/make_projected.h> +#include <__algorithm/unique_copy.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/projected.h> +#include <__iterator/readable_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +using unique_copy_result = in_out_result<_InIter, _OutIter>; + +namespace __unique_copy { + +template +concept __can_reread_from_output = (input_iterator<_OutIter> && same_as, iter_value_t<_OutIter>>); + +struct __fn { + template + static consteval auto __get_algo_tag() { + if constexpr (forward_iterator<_InIter>) { + return __unique_copy_tags::__reread_from_input_tag{}; + } else if constexpr (__can_reread_from_output<_InIter, _OutIter>) { + return __unique_copy_tags::__reread_from_output_tag{}; + } else if constexpr (indirectly_copyable_storable<_InIter, _OutIter>) { + return __unique_copy_tags::__read_from_tmp_value_tag{}; + } + } + + template + using __algo_tag_t = decltype(__get_algo_tag<_InIter, _OutIter>()); + + template _Sent, + weakly_incrementable _OutIter, + class _Proj = identity, + indirect_equivalence_relation> _Comp = ranges::equal_to> + requires indirectly_copyable<_InIter, _OutIter> && + (forward_iterator<_InIter> || + (input_iterator<_OutIter> && same_as, iter_value_t<_OutIter>>) || + indirectly_copyable_storable<_InIter, _OutIter>) + _LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__unique_copy<_RangeAlgPolicy>( + std::move(__first), + std::move(__last), + std::move(__result), + std::__make_projected(__comp, __proj), + __algo_tag_t<_InIter, _OutIter>()); + return {std::move(__ret.first), std::move(__ret.second)}; + } + + template , _Proj>> _Comp = ranges::equal_to> + requires indirectly_copyable, _OutIter> && + (forward_iterator> || + (input_iterator<_OutIter> && same_as, iter_value_t<_OutIter>>) || + indirectly_copyable_storable, _OutIter>) + _LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__unique_copy<_RangeAlgPolicy>( + ranges::begin(__range), + ranges::end(__range), + std::move(__result), + std::__make_projected(__comp, __proj), + __algo_tag_t, _OutIter>()); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; + +} // namespace __unique_copy + +inline namespace __cpo { +inline constexpr auto unique_copy = __unique_copy::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/ranges_upper_bound.h b/gnu/llvm/libcxx/include/__algorithm/ranges_upper_bound.h new file mode 100644 index 00000000000..a1340809048 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/ranges_upper_bound.h @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_RANGES_UPPER_BOUND_H +#define _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H + +#include <__algorithm/iterator_operations.h> +#include <__algorithm/lower_bound.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __upper_bound { +struct __fn { + template _Sent, class _Type, class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) { + return !std::invoke(__comp, __rhs, __lhs); + }; + + return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj); + } + + template , _Proj>> _Comp = ranges::less> + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __r, + const _Type& __value, + _Comp __comp = {}, + _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) { + return !std::invoke(__comp, __rhs, __lhs); + }; + + return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), + ranges::end(__r), + __value, + __comp_lhs_rhs_swapped, + __proj); + } +}; +} // namespace __upper_bound + +inline namespace __cpo { + inline constexpr auto upper_bound = __upper_bound::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H diff --git a/gnu/llvm/libcxx/include/__algorithm/remove.h b/gnu/llvm/libcxx/include/__algorithm/remove.h index 4717d7d9731..533e41b54fa 100644 --- a/gnu/llvm/libcxx/include/__algorithm/remove.h +++ b/gnu/llvm/libcxx/include/__algorithm/remove.h @@ -9,31 +9,28 @@ #ifndef _LIBCPP___ALGORITHM_REMOVE_H #define _LIBCPP___ALGORITHM_REMOVE_H -#include <__config> #include <__algorithm/find.h> #include <__algorithm/find_if.h> +#include <__config> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - __first = _VSTD::find(__first, __last, __value_); + __first = _VSTD::find(__first, __last, __value); if (__first != __last) { _ForwardIterator __i = __first; while (++__i != __last) { - if (!(*__i == __value_)) + if (!(*__i == __value)) { *__first = _VSTD::move(*__i); ++__first; @@ -45,6 +42,4 @@ remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REMOVE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/remove_copy.h b/gnu/llvm/libcxx/include/__algorithm/remove_copy.h index 5d2b6403438..ecba08a053e 100644 --- a/gnu/llvm/libcxx/include/__algorithm/remove_copy.h +++ b/gnu/llvm/libcxx/include/__algorithm/remove_copy.h @@ -12,22 +12,19 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator -remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_) +remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) { for (; __first != __last; ++__first) { - if (!(*__first == __value_)) + if (!(*__first == __value)) { *__result = *__first; ++__result; @@ -38,6 +35,4 @@ remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __res _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REMOVE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/remove_copy_if.h b/gnu/llvm/libcxx/include/__algorithm/remove_copy_if.h index 44822564a5c..2f235fd32ff 100644 --- a/gnu/llvm/libcxx/include/__algorithm/remove_copy_if.h +++ b/gnu/llvm/libcxx/include/__algorithm/remove_copy_if.h @@ -12,16 +12,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { @@ -38,6 +35,4 @@ remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __ _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/remove_if.h b/gnu/llvm/libcxx/include/__algorithm/remove_if.h index e506b4c67fb..27350728d25 100644 --- a/gnu/llvm/libcxx/include/__algorithm/remove_if.h +++ b/gnu/llvm/libcxx/include/__algorithm/remove_if.h @@ -9,26 +9,21 @@ #ifndef _LIBCPP___ALGORITHM_REMOVE_IF_H #define _LIBCPP___ALGORITHM_REMOVE_IF_H -#include <__config> #include <__algorithm/find_if.h> -#include -#include +#include <__config> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type> - (__first, __last, __pred); + __first = _VSTD::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); if (__first != __last) { _ForwardIterator __i = __first; @@ -46,6 +41,4 @@ remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REMOVE_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/replace.h b/gnu/llvm/libcxx/include/__algorithm/replace.h index b723ffeeace..ce6215066f5 100644 --- a/gnu/llvm/libcxx/include/__algorithm/replace.h +++ b/gnu/llvm/libcxx/include/__algorithm/replace.h @@ -12,16 +12,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) { @@ -32,6 +29,4 @@ replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_valu _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REPLACE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/replace_copy.h b/gnu/llvm/libcxx/include/__algorithm/replace_copy.h index 1923a57e427..bebb14cbe21 100644 --- a/gnu/llvm/libcxx/include/__algorithm/replace_copy.h +++ b/gnu/llvm/libcxx/include/__algorithm/replace_copy.h @@ -12,16 +12,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __old_value, const _Tp& __new_value) @@ -36,6 +33,4 @@ replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __re _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REPLACE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/replace_copy_if.h b/gnu/llvm/libcxx/include/__algorithm/replace_copy_if.h index 72b6f736970..e1ddb527be8 100644 --- a/gnu/llvm/libcxx/include/__algorithm/replace_copy_if.h +++ b/gnu/llvm/libcxx/include/__algorithm/replace_copy_if.h @@ -12,16 +12,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred, const _Tp& __new_value) @@ -36,6 +33,4 @@ replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator _ _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/replace_if.h b/gnu/llvm/libcxx/include/__algorithm/replace_if.h index 49101a5ce16..b3a3367d223 100644 --- a/gnu/llvm/libcxx/include/__algorithm/replace_if.h +++ b/gnu/llvm/libcxx/include/__algorithm/replace_if.h @@ -12,16 +12,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) { @@ -32,6 +29,4 @@ replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REPLACE_IF_H diff --git a/gnu/llvm/libcxx/include/__algorithm/reverse.h b/gnu/llvm/libcxx/include/__algorithm/reverse.h index e538de11472..aa76951707a 100644 --- a/gnu/llvm/libcxx/include/__algorithm/reverse.h +++ b/gnu/llvm/libcxx/include/__algorithm/reverse.h @@ -9,53 +9,57 @@ #ifndef _LIBCPP___ALGORITHM_REVERSE_H #define _LIBCPP___ALGORITHM_REVERSE_H -#include <__config> #include <__algorithm/iter_swap.h> +#include <__algorithm/iterator_operations.h> +#include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void -__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) +__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) { while (__first != __last) { if (__first == --__last) break; - _VSTD::iter_swap(__first, __last); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); ++__first; } } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void -__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) +__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { if (__first != __last) for (; __first < --__last; ++__first) - _VSTD::iter_swap(__first, __last); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void __reverse(_BidirectionalIterator __first, _Sentinel __last) { + using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_BidirectionalIterator>; + std::__reverse_impl<_AlgPolicy>(std::move(__first), std::move(__last), _IterCategory()); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) { - _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category()); + std::__reverse<_ClassicAlgPolicy>(std::move(__first), std::move(__last)); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REVERSE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/reverse_copy.h b/gnu/llvm/libcxx/include/__algorithm/reverse_copy.h index 48ce60cf881..f4a0e9713dd 100644 --- a/gnu/llvm/libcxx/include/__algorithm/reverse_copy.h +++ b/gnu/llvm/libcxx/include/__algorithm/reverse_copy.h @@ -12,16 +12,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) { @@ -32,6 +29,4 @@ reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _Out _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_REVERSE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/rotate.h b/gnu/llvm/libcxx/include/__algorithm/rotate.h index 0c9ccd7bf7b..8934ce095bb 100644 --- a/gnu/llvm/libcxx/include/__algorithm/rotate.h +++ b/gnu/llvm/libcxx/include/__algorithm/rotate.h @@ -9,56 +9,58 @@ #ifndef _LIBCPP___ALGORITHM_ROTATE_H #define _LIBCPP___ALGORITHM_ROTATE_H +#include <__algorithm/iterator_operations.h> #include <__algorithm/move.h> #include <__algorithm/move_backward.h> #include <__algorithm/swap_ranges.h> #include <__config> #include <__iterator/iterator_traits.h> -#include <__iterator/next.h> -#include <__iterator/prev.h> -#include <__utility/swap.h> -#include +#include <__utility/move.h> +#include <__utility/pair.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator __rotate_left(_ForwardIterator __first, _ForwardIterator __last) { typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - value_type __tmp = _VSTD::move(*__first); - _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first); + using _Ops = _IterOps<_AlgPolicy>; + + value_type __tmp = _Ops::__iter_move(__first); + _ForwardIterator __lm1 = std::__move<_AlgPolicy>( + _Ops::next(__first), __last, __first).second; *__lm1 = _VSTD::move(__tmp); return __lm1; } -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator __rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) { typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - _BidirectionalIterator __lm1 = _VSTD::prev(__last); - value_type __tmp = _VSTD::move(*__lm1); - _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last); + using _Ops = _IterOps<_AlgPolicy>; + + _BidirectionalIterator __lm1 = _Ops::prev(__last); + value_type __tmp = _Ops::__iter_move(__lm1); + _BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second; *__first = _VSTD::move(__tmp); return __fp1; } -template -_LIBCPP_CONSTEXPR_AFTER_CXX14 _ForwardIterator +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _ForwardIterator __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { _ForwardIterator __i = __middle; while (true) { - swap(*__first, *__i); + _IterOps<_AlgPolicy>::iter_swap(__first, __i); ++__first; if (++__i == __last) break; @@ -71,7 +73,7 @@ __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIt __i = __middle; while (true) { - swap(*__first, *__i); + _IterOps<_AlgPolicy>::iter_swap(__first, __i); ++__first; if (++__i == __last) { @@ -88,7 +90,7 @@ __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIt template inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX14 _Integral +_LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral __algo_gcd(_Integral __x, _Integral __y) { do @@ -100,31 +102,32 @@ __algo_gcd(_Integral __x, _Integral __y) return __x; } -template -_LIBCPP_CONSTEXPR_AFTER_CXX14 _RandomAccessIterator +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator __rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; const difference_type __m1 = __middle - __first; - const difference_type __m2 = __last - __middle; + const difference_type __m2 = _Ops::distance(__middle, __last); if (__m1 == __m2) { - _VSTD::swap_ranges(__first, __middle, __middle); + std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last); return __middle; } const difference_type __g = _VSTD::__algo_gcd(__m1, __m2); for (_RandomAccessIterator __p = __first + __g; __p != __first;) { - value_type __t(_VSTD::move(*--__p)); + value_type __t(_Ops::__iter_move(--__p)); _RandomAccessIterator __p1 = __p; _RandomAccessIterator __p2 = __p1 + __m1; do { - *__p1 = _VSTD::move(*__p2); + *__p1 = _Ops::__iter_move(__p2); __p1 = __p2; - const difference_type __d = __last - __p2; + const difference_type __d = _Ops::distance(__p2, __last); if (__m1 < __d) __p2 += __m1; else @@ -135,71 +138,84 @@ __rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran return __first + __m2; } -template +template inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator -__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, +_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +__rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _VSTD::forward_iterator_tag) { typedef typename iterator_traits<_ForwardIterator>::value_type value_type; if (is_trivially_move_assignable::value) { - if (_VSTD::next(__first) == __middle) - return _VSTD::__rotate_left(__first, __last); + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); } - return _VSTD::__rotate_forward(__first, __middle, __last); + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } -template +template inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX11 _BidirectionalIterator -__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, +_LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator +__rotate_impl(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, bidirectional_iterator_tag) { typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; if (is_trivially_move_assignable::value) { - if (_VSTD::next(__first) == __middle) - return _VSTD::__rotate_left(__first, __last); - if (_VSTD::next(__middle) == __last) - return _VSTD::__rotate_right(__first, __last); + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + if (_IterOps<_AlgPolicy>::next(__middle) == __last) + return std::__rotate_right<_AlgPolicy>(__first, __last); } - return _VSTD::__rotate_forward(__first, __middle, __last); + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } -template +template inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator -__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, +_LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator +__rotate_impl(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, random_access_iterator_tag) { typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; if (is_trivially_move_assignable::value) { - if (_VSTD::next(__first) == __middle) - return _VSTD::__rotate_left(__first, __last); - if (_VSTD::next(__middle) == __last) - return _VSTD::__rotate_right(__first, __last); - return _VSTD::__rotate_gcd(__first, __middle, __last); + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + if (_IterOps<_AlgPolicy>::next(__middle) == __last) + return std::__rotate_right<_AlgPolicy>(__first, __last); + return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last); } - return _VSTD::__rotate_forward(__first, __middle, __last); + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iterator, _Iterator> +__rotate(_Iterator __first, _Iterator __middle, _Sentinel __last) { + using _Ret = pair<_Iterator, _Iterator>; + _Iterator __last_iter = _IterOps<_AlgPolicy>::next(__middle, __last); + + if (__first == __middle) + return _Ret(__last_iter, __last_iter); + if (__middle == __last) + return _Ret(std::move(__first), std::move(__last_iter)); + + using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_Iterator>; + auto __result = std::__rotate_impl<_AlgPolicy>( + std::move(__first), std::move(__middle), __last_iter, _IterCategory()); + + return _Ret(std::move(__result), std::move(__last_iter)); } template inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +_LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { - if (__first == __middle) - return __last; - if (__middle == __last) - return __first; - return _VSTD::__rotate(__first, __middle, __last, - typename iterator_traits<_ForwardIterator>::iterator_category()); + return std::__rotate<_ClassicAlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last)).first; } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_ROTATE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/rotate_copy.h b/gnu/llvm/libcxx/include/__algorithm/rotate_copy.h index d5ab7d3b515..c154649ab98 100644 --- a/gnu/llvm/libcxx/include/__algorithm/rotate_copy.h +++ b/gnu/llvm/libcxx/include/__algorithm/rotate_copy.h @@ -9,22 +9,17 @@ #ifndef _LIBCPP___ALGORITHM_ROTATE_COPY_H #define _LIBCPP___ALGORITHM_ROTATE_COPY_H -#include <__config> #include <__algorithm/copy.h> -#include -#include +#include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) { @@ -33,6 +28,4 @@ rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterato _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_ROTATE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/sample.h b/gnu/llvm/libcxx/include/__algorithm/sample.h index 2aac6ffa8ce..f403ba61258 100644 --- a/gnu/llvm/libcxx/include/__algorithm/sample.h +++ b/gnu/llvm/libcxx/include/__algorithm/sample.h @@ -9,13 +9,18 @@ #ifndef _LIBCPP___ALGORITHM_SAMPLE_H #define _LIBCPP___ALGORITHM_SAMPLE_H -#include <__config> +#include <__algorithm/iterator_operations.h> #include <__algorithm/min.h> +#include <__assert> +#include <__config> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> #include <__random/uniform_int_distribution.h> -#include +#include <__utility/move.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -23,13 +28,14 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -template _LIBCPP_INLINE_VISIBILITY _SampleIterator __sample(_PopulationIterator __first, - _PopulationIterator __last, _SampleIterator __output_iter, + _PopulationSentinel __last, _SampleIterator __output_iter, _Distance __n, - _UniformRandomNumberGenerator & __g, + _UniformRandomNumberGenerator& __g, input_iterator_tag) { _Distance __k = 0; @@ -44,15 +50,16 @@ _SampleIterator __sample(_PopulationIterator __first, return __output_iter + _VSTD::min(__n, __k); } -template _LIBCPP_INLINE_VISIBILITY _SampleIterator __sample(_PopulationIterator __first, - _PopulationIterator __last, _SampleIterator __output_iter, + _PopulationSentinel __last, _SampleIterator __output_iter, _Distance __n, _UniformRandomNumberGenerator& __g, forward_iterator_tag) { - _Distance __unsampled_sz = _VSTD::distance(__first, __last); + _Distance __unsampled_sz = _IterOps<_AlgPolicy>::distance(__first, __last); for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { _Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); if (__r < __n) { @@ -63,24 +70,22 @@ _SampleIterator __sample(_PopulationIterator __first, return __output_iter; } -template _LIBCPP_INLINE_VISIBILITY _SampleIterator __sample(_PopulationIterator __first, - _PopulationIterator __last, _SampleIterator __output_iter, + _PopulationSentinel __last, _SampleIterator __output_iter, _Distance __n, _UniformRandomNumberGenerator& __g) { - typedef typename iterator_traits<_PopulationIterator>::iterator_category - _PopCategory; - typedef typename iterator_traits<_PopulationIterator>::difference_type - _Difference; - static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value || - __is_cpp17_random_access_iterator<_SampleIterator>::value, - "SampleIterator must meet the requirements of RandomAccessIterator"); - typedef typename common_type<_Distance, _Difference>::type _CommonType; _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); - return _VSTD::__sample( - __first, __last, __output_iter, _CommonType(__n), - __g, _PopCategory()); + + using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>; + using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>; + using _CommonType = typename common_type<_Distance, _Difference>::type; + + return std::__sample<_AlgPolicy>( + std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n), + __g, _PopIterCategory()); } #if _LIBCPP_STD_VER > 14 @@ -90,8 +95,14 @@ inline _LIBCPP_INLINE_VISIBILITY _SampleIterator sample(_PopulationIterator __first, _PopulationIterator __last, _SampleIterator __output_iter, _Distance __n, _UniformRandomNumberGenerator&& __g) { - return _VSTD::__sample(__first, __last, __output_iter, __n, __g); + static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value || + __is_cpp17_random_access_iterator<_SampleIterator>::value, + "SampleIterator must meet the requirements of RandomAccessIterator"); + + return std::__sample<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), std::move(__output_iter), __n, __g); } + #endif // _LIBCPP_STD_VER > 14 _LIBCPP_END_NAMESPACE_STD diff --git a/gnu/llvm/libcxx/include/__algorithm/search.h b/gnu/llvm/libcxx/include/__algorithm/search.h index 008b8ebb04a..93771be39e3 100644 --- a/gnu/llvm/libcxx/include/__algorithm/search.h +++ b/gnu/llvm/libcxx/include/__algorithm/search.h @@ -11,45 +11,59 @@ #define _LIBCPP___ALGORITHM_SEARCH_H #include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> #include <__config> +#include <__functional/identity.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> +#include <__type_traits/is_callable.h> +#include <__utility/pair.h> #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -pair<_ForwardIterator1, _ForwardIterator1> - _LIBCPP_CONSTEXPR_AFTER_CXX11 __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) { +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { if (__first2 == __last2) - return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence + return std::make_pair(__first1, __first1); // Everything matches an empty sequence while (true) { // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks while (true) { - if (__first1 == __last1) // return __last1 if no element matches *__first2 - return _VSTD::make_pair(__last1, __last1); - if (__pred(*__first1, *__first2)) + if (__first1 == __last1) { // return __last1 if no element matches *__first2 + _IterOps<_AlgPolicy>::__advance_to(__first1, __last1); + return std::make_pair(__first1, __first1); + } + if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) break; ++__first1; } // *__first1 matches *__first2, now match elements after here - _ForwardIterator1 __m1 = __first1; - _ForwardIterator2 __m2 = __first2; + _Iter1 __m1 = __first1; + _Iter2 __m2 = __first2; while (true) { if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) - return _VSTD::make_pair(__first1, __m1); - if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found - return _VSTD::make_pair(__last1, __last1); - if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 + return std::make_pair(__first1, ++__m1); + if (++__m1 == __last1) { // Otherwise if source exhaused, pattern not found + return std::make_pair(__m1, __m1); + } + + // if there is a mismatch, restart with a new __first1 + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) { ++__first1; break; @@ -58,38 +72,42 @@ pair<_ForwardIterator1, _ForwardIterator1> } } -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_RandomAccessIterator1, _RandomAccessIterator1> -__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, - random_access_iterator_tag) { - typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; - typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; - // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern - const _D2 __len2 = __last2 - __first2; - if (__len2 == 0) - return _VSTD::make_pair(__first1, __first1); - const _D1 __len1 = __last1 - __first1; - if (__len1 < __len2) - return _VSTD::make_pair(__last1, __last1); - const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + _DiffT1 __size1, + _DiffT2 __size2) { + const _Iter1 __s = __first1 + __size1 - _DiffT1(__size2 - 1); // Start of pattern match can't go beyond here while (true) { while (true) { - if (__first1 == __s) - return _VSTD::make_pair(__last1, __last1); - if (__pred(*__first1, *__first2)) + if (__first1 == __s) { + _IterOps<_AlgPolicy>::__advance_to(__first1, __last1); + return std::make_pair(__first1, __first1); + } + if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) break; ++__first1; } - _RandomAccessIterator1 __m1 = __first1; - _RandomAccessIterator2 __m2 = __first2; + _Iter1 __m1 = __first1; + _Iter2 __m2 = __first2; while (true) { if (++__m2 == __last2) - return _VSTD::make_pair(__first1, __first1 + __len2); + return std::make_pair(__first1, __first1 + _DiffT1(__size2)); ++__m1; // no need to check range on __m1 because __s guarantees we have enough source - if (!__pred(*__m1, *__m2)) { + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) { ++__first1; break; } @@ -97,27 +115,81 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _Rando } } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + __enable_if_t<__is_cpp17_random_access_iterator<_Iter1>::value + && __is_cpp17_random_access_iterator<_Iter2>::value>* = nullptr) { + + auto __size2 = __last2 - __first2; + if (__size2 == 0) + return std::make_pair(__first1, __first1); + + auto __size1 = __last1 - __first1; + if (__size1 < __size2) { + return std::make_pair(__last1, __last1); + } + + return std::__search_random_access_impl<_ClassicAlgPolicy>(__first1, __last1, + __first2, __last2, + __pred, + __proj1, + __proj2, + __size1, + __size2); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value + && __is_cpp17_forward_iterator<_Iter2>::value + && !(__is_cpp17_random_access_iterator<_Iter1>::value + && __is_cpp17_random_access_iterator<_Iter2>::value)>* = nullptr) { + return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, + __first2, __last2, + __pred, + __proj1, + __proj2); +} + template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 -search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred) { - return _VSTD::__search::type>( - __first1, __last1, __first2, __last2, __pred, - typename iterator_traits<_ForwardIterator1>::iterator_category(), - typename iterator_traits<_ForwardIterator2>::iterator_category()).first; +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) { + static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, + "BinaryPredicate has to be callable"); + auto __proj = __identity(); + return std::__search_impl(__first1, __last1, __first2, __last2, __pred, __proj, __proj).first; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 -search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; - typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; - return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + return std::search(__first1, __last1, __first2, __last2, __equal_to()); } #if _LIBCPP_STD_VER > 14 template -_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) { return __s(__f, __l).first; } @@ -126,6 +198,4 @@ search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) { _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SEARCH_H diff --git a/gnu/llvm/libcxx/include/__algorithm/search_n.h b/gnu/llvm/libcxx/include/__algorithm/search_n.h index 1584e8e613c..60a07356515 100644 --- a/gnu/llvm/libcxx/include/__algorithm/search_n.h +++ b/gnu/llvm/libcxx/include/__algorithm/search_n.h @@ -10,44 +10,58 @@ #ifndef _LIBCPP___ALGORITHM_SEARCH_N_H #define _LIBCPP___ALGORITHM_SEARCH_N_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> #include <__iterator/iterator_traits.h> -#include +#include <__ranges/concepts.h> +#include <__utility/convert_to_integral.h> +#include <__utility/pair.h> +#include // __convert_to_integral #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last, - _Size __count, const _Tp& __value_, _BinaryPredicate __pred, - forward_iterator_tag) { +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, + _SizeT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj) { if (__count <= 0) - return __first; + return std::make_pair(__first, __first); while (true) { - // Find first element in sequence that matchs __value_, with a mininum of loop checks + // Find first element in sequence that matchs __value, with a mininum of loop checks while (true) { - if (__first == __last) // return __last if no element matches __value_ - return __last; - if (__pred(*__first, __value_)) + if (__first == __last) { // return __last if no element matches __value + _IterOps<_AlgPolicy>::__advance_to(__first, __last); + return std::make_pair(__first, __first); + } + if (std::__invoke(__pred, std::__invoke(__proj, *__first), __value)) break; ++__first; } - // *__first matches __value_, now match elements after here - _ForwardIterator __m = __first; - _Size __c(0); + // *__first matches __value, now match elements after here + _Iter __m = __first; + _SizeT __c(0); while (true) { if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) - return __first; - if (++__m == __last) // Otherwise if source exhaused, pattern not found - return __last; - if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first + return std::make_pair(__first, ++__m); + if (++__m == __last) { // Otherwise if source exhaused, pattern not found + _IterOps<_AlgPolicy>::__advance_to(__first, __last); + return std::make_pair(__first, __first); + } + + // if there is a mismatch, restart with a new __first + if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) { __first = __m; ++__first; @@ -57,34 +71,44 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __fir } } -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIterator __first, - _RandomAccessIterator __last, _Size __count, - const _Tp& __value_, _BinaryPredicate __pred, - random_access_iterator_tag) { - if (__count <= 0) - return __first; - _Size __len = static_cast<_Size>(__last - __first); - if (__len < __count) - return __last; - const _RandomAccessIterator __s = __last - (__count - 1); // Start of pattern match can't go beyond here +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __last, + _SizeT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj, + _DiffT __size1) { + using difference_type = typename iterator_traits<_Iter>::difference_type; + if (__count == 0) + return std::make_pair(__first, __first); + if (__size1 < static_cast<_DiffT>(__count)) { + _IterOps<_AlgPolicy>::__advance_to(__first, __last); + return std::make_pair(__first, __first); + } + + const auto __s = __first + __size1 - difference_type(__count - 1); // Start of pattern match can't go beyond here while (true) { - // Find first element in sequence that matchs __value_, with a mininum of loop checks + // Find first element in sequence that matchs __value, with a mininum of loop checks while (true) { - if (__first >= __s) // return __last if no element matches __value_ - return __last; - if (__pred(*__first, __value_)) + if (__first >= __s) { // return __last if no element matches __value + _IterOps<_AlgPolicy>::__advance_to(__first, __last); + return std::make_pair(__first, __first); + } + if (std::__invoke(__pred, std::__invoke(__proj, *__first), __value)) break; ++__first; } // *__first matches __value_, now match elements after here - _RandomAccessIterator __m = __first; - _Size __c(0); + auto __m = __first; + _SizeT __c(0); while (true) { if (++__c == __count) // If pattern exhausted, __first is the answer (works for 1 element pattern) - return __first; - ++__m; // no need to check range on __m because __s guarantees we have enough source - if (!__pred(*__m, __value_)) // if there is a mismatch, restart with a new __first + return std::make_pair(__first, __first + _DiffT(__count)); + ++__m; // no need to check range on __m because __s guarantees we have enough source + + // if there is a mismatch, restart with a new __first + if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) { __first = __m; ++__first; @@ -94,23 +118,64 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIter } } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last, + _DiffT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj, + __enable_if_t<__is_cpp17_random_access_iterator<_Iter>::value>* = nullptr) { + return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last, + __count, + __value, + __pred, + __proj, + __last - __first); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last, + _DiffT __count, + const _Type& __value, + _Pred& __pred, + _Proj& __proj, + __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value + && !__is_cpp17_random_access_iterator<_Iter1>::value>* = nullptr) { + return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, + __count, + __value, + __pred, + __proj); +} + template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator search_n( - _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_, _BinaryPredicate __pred) { - return _VSTD::__search_n::type>( - __first, __last, _VSTD::__convert_to_integral(__count), __value_, __pred, - typename iterator_traits<_ForwardIterator>::iterator_category()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, + _Size __count, + const _Tp& __value, + _BinaryPredicate __pred) { + static_assert(__is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, + "BinaryPredicate has to be callable"); + auto __proj = __identity(); + return std::__search_n_impl(__first, __last, std::__convert_to_integral(__count), __value, __pred, __proj).first; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) { - typedef typename iterator_traits<_ForwardIterator>::value_type __v; - return _VSTD::search_n(__first, __last, _VSTD::__convert_to_integral(__count), __value_, __equal_to<__v, _Tp>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { + return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SEARCH_N_H diff --git a/gnu/llvm/libcxx/include/__algorithm/set_difference.h b/gnu/llvm/libcxx/include/__algorithm/set_difference.h index f4c985d978c..cffdc8fc4fc 100644 --- a/gnu/llvm/libcxx/include/__algorithm/set_difference.h +++ b/gnu/llvm/libcxx/include/__algorithm/set_difference.h @@ -9,69 +9,73 @@ #ifndef _LIBCPP___ALGORITHM_SET_DIFFERENCE_H #define _LIBCPP___ALGORITHM_SET_DIFFERENCE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__set_difference(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - while (__first1 != __last1) - { - if (__first2 == __last2) - return _VSTD::copy(__first1, __last1, __result); - if (__comp(*__first1, *__first2)) - { - *__result = *__first1; - ++__result; - ++__first1; - } - else - { - if (!__comp(*__first2, *__first1)) - ++__first1; - ++__first2; - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<__remove_cvref_t<_InIter1>, __remove_cvref_t<_OutIter> > +__set_difference( + _InIter1&& __first1, _Sent1&& __last1, _InIter2&& __first2, _Sent2&& __last2, _OutIter&& __result, _Comp&& __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; + } else if (__comp(*__first2, *__first1)) { + ++__first2; + } else { + ++__first1; + ++__first2; } - return __result; + } + return std::__copy<_AlgPolicy>(std::move(__first1), std::move(__last1), std::move(__result)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_difference(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_difference( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__set_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( + __first1, __last1, __first2, __last2, __result, __comp) + .second; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_difference(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) -{ - return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result, - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_difference( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::__set_difference<_ClassicAlgPolicy>( + __first1, + __last1, + __first2, + __last2, + __result, + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()).second; } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SET_DIFFERENCE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/set_intersection.h b/gnu/llvm/libcxx/include/__algorithm/set_intersection.h index 9d34b66c23e..9fa7799aee6 100644 --- a/gnu/llvm/libcxx/include/__algorithm/set_intersection.h +++ b/gnu/llvm/libcxx/include/__algorithm/set_intersection.h @@ -9,66 +9,91 @@ #ifndef _LIBCPP___ALGORITHM_SET_INTERSECTION_H #define _LIBCPP___ALGORITHM_SET_INTERSECTION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> +#include <__config> #include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - while (__first1 != __last1 && __first2 != __last2) - { - if (__comp(*__first1, *__first2)) - ++__first1; - else - { - if (!__comp(*__first2, *__first1)) - { - *__result = *__first1; - ++__result; - ++__first1; - } - ++__first2; - } +template +struct __set_intersection_result { + _InIter1 __in1_; + _InIter2 __in2_; + _OutIter __out_; + + // need a constructor as C++03 aggregate init is hard + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + __set_intersection_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter) + : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {} +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_intersection_result<_InIter1, _InIter2, _OutIter> +__set_intersection( + _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first1, *__first2)) + ++__first1; + else { + if (!__comp(*__first2, *__first1)) { + *__result = *__first1; + ++__result; + ++__first1; + } + ++__first2; } - return __result; + } + + return __set_intersection_result<_InIter1, _InIter2, _OutIter>( + _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)), + _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)), + std::move(__result)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_intersection( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__set_intersection<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __comp) + .__out_; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) -{ - return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result, - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_intersection( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::__set_intersection<_ClassicAlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()) + .__out_; } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SET_INTERSECTION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/set_symmetric_difference.h b/gnu/llvm/libcxx/include/__algorithm/set_symmetric_difference.h index 5650b836a61..bcb09587032 100644 --- a/gnu/llvm/libcxx/include/__algorithm/set_symmetric_difference.h +++ b/gnu/llvm/libcxx/include/__algorithm/set_symmetric_difference.h @@ -9,74 +9,97 @@ #ifndef _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H #define _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__algorithm/iterator_operations.h> +#include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - while (__first1 != __last1) - { - if (__first2 == __last2) - return _VSTD::copy(__first1, __last1, __result); - if (__comp(*__first1, *__first2)) - { - *__result = *__first1; - ++__result; - ++__first1; - } - else - { - if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__result; - } - else - ++__first1; - ++__first2; - } +template +struct __set_symmetric_difference_result { + _InIter1 __in1_; + _InIter2 __in2_; + _OutIter __out_; + + // need a constructor as C++03 aggregate init is hard + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + __set_symmetric_difference_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter) + : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {} +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter> +__set_symmetric_difference( + _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { + while (__first1 != __last1) { + if (__first2 == __last2) { + auto __ret1 = std::__copy<_AlgPolicy>(std::move(__first1), std::move(__last1), std::move(__result)); + return __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>( + std::move(__ret1.first), std::move(__first2), std::move((__ret1.second))); + } + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__result; + ++__first1; + } else { + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__result; + } else { + ++__first1; + } + ++__first2; } - return _VSTD::copy(__first2, __last2, __result); + } + auto __ret2 = std::__copy<_AlgPolicy>(std::move(__first2), std::move(__last2), std::move(__result)); + return __set_symmetric_difference_result<_InIter1, _InIter2, _OutIter>( + std::move(__first1), std::move(__ret2.first), std::move((__ret2.second))); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetric_difference( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__set_symmetric_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __comp) + .__out_; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) -{ - return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetric_difference( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::set_symmetric_difference( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/set_union.h b/gnu/llvm/libcxx/include/__algorithm/set_union.h index c0874e95746..4d154b81e09 100644 --- a/gnu/llvm/libcxx/include/__algorithm/set_union.h +++ b/gnu/llvm/libcxx/include/__algorithm/set_union.h @@ -9,69 +9,93 @@ #ifndef _LIBCPP___ALGORITHM_SET_UNION_H #define _LIBCPP___ALGORITHM_SET_UNION_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> +#include <__algorithm/iterator_operations.h> +#include <__config> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__set_union(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - for (; __first1 != __last1; ++__result) - { - if (__first2 == __last2) - return _VSTD::copy(__first1, __last1, __result); - if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__first2; - } - else - { - if (!__comp(*__first1, *__first2)) - ++__first2; - *__result = *__first1; - ++__first1; - } +template +struct __set_union_result { + _InIter1 __in1_; + _InIter2 __in2_; + _OutIter __out_; + + // need a constructor as C++03 aggregate init is hard + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + __set_union_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter) + : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {} +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_union_result<_InIter1, _InIter2, _OutIter> __set_union( + _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { + for (; __first1 != __last1; ++__result) { + if (__first2 == __last2) { + auto __ret1 = std::__copy<_AlgPolicy>(std::move(__first1), std::move(__last1), std::move(__result)); + return __set_union_result<_InIter1, _InIter2, _OutIter>( + std::move(__ret1.first), std::move(__first2), std::move((__ret1.second))); + } + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + } else { + if (!__comp(*__first1, *__first2)) { + ++__first2; + } + *__result = *__first1; + ++__first1; } - return _VSTD::copy(__first2, __last2, __result); + } + auto __ret2 = std::__copy<_AlgPolicy>(std::move(__first2), std::move(__last2), std::move(__result)); + return __set_union_result<_InIter1, _InIter2, _OutIter>( + std::move(__first1), std::move(__ret2.first), std::move((__ret2.second))); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_union(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__set_union<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __comp) + .__out_; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -set_union(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) -{ - return _VSTD::set_union(__first1, __last1, __first2, __last2, __result, - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::set_union( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __less::value_type, + typename iterator_traits<_InputIterator2>::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SET_UNION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/shift_left.h b/gnu/llvm/libcxx/include/__algorithm/shift_left.h index 961b89cb00b..33f06d57e23 100644 --- a/gnu/llvm/libcxx/include/__algorithm/shift_left.h +++ b/gnu/llvm/libcxx/include/__algorithm/shift_left.h @@ -9,18 +9,15 @@ #ifndef _LIBCPP___ALGORITHM_SHIFT_LEFT_H #define _LIBCPP___ALGORITHM_SHIFT_LEFT_H -#include <__config> #include <__algorithm/move.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include // swap +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 17 @@ -56,6 +53,4 @@ shift_left(_ForwardIterator __first, _ForwardIterator __last, _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/shift_right.h b/gnu/llvm/libcxx/include/__algorithm/shift_right.h index 5cb41950642..14bc761598b 100644 --- a/gnu/llvm/libcxx/include/__algorithm/shift_right.h +++ b/gnu/llvm/libcxx/include/__algorithm/shift_right.h @@ -9,20 +9,18 @@ #ifndef _LIBCPP___ALGORITHM_SHIFT_RIGHT_H #define _LIBCPP___ALGORITHM_SHIFT_RIGHT_H -#include <__config> #include <__algorithm/move.h> #include <__algorithm/move_backward.h> #include <__algorithm/swap_ranges.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include // swap +#include <__utility/swap.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 17 @@ -101,6 +99,4 @@ shift_right(_ForwardIterator __first, _ForwardIterator __last, _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SHIFT_RIGHT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/shuffle.h b/gnu/llvm/libcxx/include/__algorithm/shuffle.h index 637fca53885..f7bce68697b 100644 --- a/gnu/llvm/libcxx/include/__algorithm/shuffle.h +++ b/gnu/llvm/libcxx/include/__algorithm/shuffle.h @@ -9,15 +9,19 @@ #ifndef _LIBCPP___ALGORITHM_SHUFFLE_H #define _LIBCPP___ALGORITHM_SHUFFLE_H +#include <__algorithm/iterator_operations.h> #include <__config> +#include <__debug> #include <__iterator/iterator_traits.h> #include <__random/uniform_int_distribution.h> +#include <__utility/forward.h> +#include <__utility/move.h> #include <__utility/swap.h> #include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -25,6 +29,39 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD +class _LIBCPP_TYPE_VIS __libcpp_debug_randomizer { +public: + __libcpp_debug_randomizer() { + __state_ = __seed(); + __inc_ = __state_ + 0xda3e39cb94b95bdbULL; + __inc_ = (__inc_ << 1) | 1; + } + typedef uint_fast32_t result_type; + + static const result_type _Min = 0; + static const result_type _Max = 0xFFFFFFFF; + + _LIBCPP_HIDE_FROM_ABI result_type operator()() { + uint_fast64_t __oldstate = __state_; + __state_ = __oldstate * 6364136223846793005ULL + __inc_; + return __oldstate >> 32; + } + + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() { return _Min; } + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() { return _Max; } + +private: + uint_fast64_t __state_; + uint_fast64_t __inc_; + _LIBCPP_HIDE_FROM_ABI static uint_fast64_t __seed() { +#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED + return _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED; +#else + static char __x; + return reinterpret_cast(&__x); +#endif + } +}; #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ || defined(_LIBCPP_BUILDING_LIBRARY) @@ -57,7 +94,7 @@ public: _LIBCPP_FUNC_VIS __rs_default __rs_get(); template -_LIBCPP_DEPRECATED_IN_CXX14 void +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; @@ -78,7 +115,7 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) } template -_LIBCPP_DEPRECATED_IN_CXX14 void +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, #ifndef _LIBCPP_CXX03_LANG _RandomNumberGenerator&& __rand) @@ -100,13 +137,15 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, } #endif -template - void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, - _UniformRandomNumberGenerator&& __g) -{ +template +_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator __shuffle( + _RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef uniform_int_distribution _Dp; typedef typename _Dp::param_type _Pp; + + auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel); + auto __last = __original_last; difference_type __d = __last - __first; if (__d > 1) { @@ -115,9 +154,18 @@ template { difference_type __i = __uid(__g, _Pp(0, __d)); if (__i != difference_type(0)) - swap(*__first, *(__first + __i)); + _IterOps<_AlgPolicy>::iter_swap(__first, __first + __i); } } + + return __original_last; +} + +template +_LIBCPP_HIDE_FROM_ABI void +shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, _UniformRandomNumberGenerator&& __g) { + (void)std::__shuffle<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), std::forward<_UniformRandomNumberGenerator>(__g)); } _LIBCPP_END_NAMESPACE_STD diff --git a/gnu/llvm/libcxx/include/__algorithm/sift_down.h b/gnu/llvm/libcxx/include/__algorithm/sift_down.h index dd4b54ed8e5..e3972fb6f46 100644 --- a/gnu/llvm/libcxx/include/__algorithm/sift_down.h +++ b/gnu/llvm/libcxx/include/__algorithm/sift_down.h @@ -9,26 +9,26 @@ #ifndef _LIBCPP___ALGORITHM_SIFT_DOWN_H #define _LIBCPP___ALGORITHM_SIFT_DOWN_H +#include <__algorithm/iterator_operations.h> +#include <__assert> #include <__config> #include <__iterator/iterator_traits.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 void -__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, - _Compare __comp, +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__sift_down(_RandomAccessIterator __first, _Compare&& __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, _RandomAccessIterator __start) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; // left-child of __start is at 2 * __start + 1 @@ -41,7 +41,7 @@ __sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, __child = 2 * __child + 1; _RandomAccessIterator __child_i = __first + __child; - if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { // right-child exists and is greater than left-child ++__child_i; ++__child; @@ -49,14 +49,14 @@ __sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, // check if we are in heap-order if (__comp(*__child_i, *__start)) - // we are, __start is larger than it's largest child + // we are, __start is larger than its largest child return; - value_type __top(_VSTD::move(*__start)); + value_type __top(_Ops::__iter_move(__start)); do { // we are not in heap-order, swap the parent with its largest child - *__start = _VSTD::move(*__child_i); + *__start = _Ops::__iter_move(__child_i); __start = __child_i; if ((__len - 2) / 2 < __child) @@ -66,7 +66,7 @@ __sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, __child = 2 * __child + 1; __child_i = __first + __child; - if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { // right-child exists and is greater than left-child ++__child_i; ++__child; @@ -77,8 +77,38 @@ __sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, *__start = _VSTD::move(__top); } -_LIBCPP_END_NAMESPACE_STD +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator +__floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) +{ + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + _LIBCPP_ASSERT(__len >= 2, "shouldn't be called unless __len >= 2"); + + _RandomAccessIterator __hole = __first; + _RandomAccessIterator __child_i = __first; + difference_type __child = 0; -_LIBCPP_POP_MACROS + while (true) { + __child_i += difference_type(__child + 1); + __child = 2 * __child + 1; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // swap __hole with its largest child + *__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i); + __hole = __child_i; + + // if __hole is now a leaf, we're done + if (__child > (__len - 2) / 2) + return __hole; + } +} + +_LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H diff --git a/gnu/llvm/libcxx/include/__algorithm/sort.h b/gnu/llvm/libcxx/include/__algorithm/sort.h index 39ec21302d2..a236be0a4da 100644 --- a/gnu/llvm/libcxx/include/__algorithm/sort.h +++ b/gnu/llvm/libcxx/include/__algorithm/sort.h @@ -9,522 +9,709 @@ #ifndef _LIBCPP___ALGORITHM_SORT_H #define _LIBCPP___ALGORITHM_SORT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/min_element.h> #include <__algorithm/partial_sort.h> #include <__algorithm/unwrap_iter.h> -#include <__utility/swap.h> -#include -#include // swap +#include <__config> +#include <__debug> +#include <__debug_utils/randomize_range.h> +#include <__functional/operations.h> +#include <__functional/ranges_operations.h> +#include <__iterator/iterator_traits.h> +#include <__memory/destruct_n.h> +#include <__memory/unique_ptr.h> +#include <__type_traits/is_arithmetic.h> +#include <__type_traits/is_trivially_copy_assignable.h> +#include <__type_traits/is_trivially_copy_constructible.h> +#include <__utility/move.h> +#include +#include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +// Wraps an algorithm policy tag and a comparator in a single struct, used to pass the policy tag around without +// changing the number of template arguments (to keep the ABI stable). This is only used for the "range" policy tag. +// +// To create an object of this type, use `_WrapAlgPolicy::type` -- see the specialization below for the rationale. +template +struct _WrapAlgPolicy { + using type = _WrapAlgPolicy; + + using _AlgPolicy = _PolicyT; + using _Comp = _CompT; + _Comp& __comp; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + _WrapAlgPolicy(_Comp& __c) : __comp(__c) {} +}; + +// Specialization for the "classic" policy tag that avoids creating a struct and simply defines an alias for the +// comparator. When unwrapping, a pristine comparator is always considered to have the "classic" tag attached. Passing +// the pristine comparator where possible allows using template instantiations from the dylib. +template +struct _WrapAlgPolicy<_PolicyT, _CompT, __enable_if_t::value> > { + using type = _CompT; +}; + +// Unwraps a pristine functor (e.g. `std::less`) as if it were wrapped using `_WrapAlgPolicy`. The policy tag is always +// set to "classic". +template +struct _UnwrapAlgPolicy { + using _AlgPolicy = _ClassicAlgPolicy; + using _Comp = _CompT; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static + _Comp __get_comp(_Comp __comp) { return __comp; } +}; + +// Unwraps a `_WrapAlgPolicy` struct. +template +struct _UnwrapAlgPolicy<_WrapAlgPolicy<_Ts...> > { + using _Wrapped = _WrapAlgPolicy<_Ts...>; + using _AlgPolicy = typename _Wrapped::_AlgPolicy; + using _Comp = typename _Wrapped::_Comp; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static + _Comp __get_comp(_Wrapped& __w) { return __w.__comp; } +}; + // stable, 2-3 compares, 0-2 swaps -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 unsigned -__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c) -{ - unsigned __r = 0; - if (!__c(*__y, *__x)) // if x <= y - { - if (!__c(*__z, *__y)) // if y <= z - return __r; // x <= y && y <= z - // x <= y && y > z - swap(*__y, *__z); // x <= z && y < z - __r = 1; - if (__c(*__y, *__x)) // if x > y - { - swap(*__x, *__y); // x < y && y <= z - __r = 2; - } - return __r; // x <= y && y < z - } - if (__c(*__z, *__y)) // x > y, if y > z - { - swap(*__x, *__z); // x < y && y < z - __r = 1; - return __r; - } - swap(*__x, *__y); // x > y && y <= z - __r = 1; // x < y && x <= z - if (__c(*__z, *__y)) // if y > z +template +_LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned __sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, + _Compare __c) { + using _Ops = _IterOps<_AlgPolicy>; + + unsigned __r = 0; + if (!__c(*__y, *__x)) // if x <= y + { + if (!__c(*__z, *__y)) // if y <= z + return __r; // x <= y && y <= z + // x <= y && y > z + _Ops::iter_swap(__y, __z); // x <= z && y < z + __r = 1; + if (__c(*__y, *__x)) // if x > y { - swap(*__y, *__z); // x <= y && y < z - __r = 2; + _Ops::iter_swap(__x, __y); // x < y && y <= z + __r = 2; } + return __r; // x <= y && y < z + } + if (__c(*__z, *__y)) // x > y, if y > z + { + _Ops::iter_swap(__x, __z); // x < y && y < z + __r = 1; return __r; -} // x <= y && y <= z + } + _Ops::iter_swap(__x, __y); // x > y && y <= z + __r = 1; // x < y && x <= z + if (__c(*__z, *__y)) // if y > z + { + _Ops::iter_swap(__y, __z); // x <= y && y < z + __r = 2; + } + return __r; +} // x <= y && y <= z // stable, 3-6 compares, 0-5 swaps -template -unsigned -__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, - _ForwardIterator __x4, _Compare __c) -{ - unsigned __r = _VSTD::__sort3<_Compare>(__x1, __x2, __x3, __c); - if (__c(*__x4, *__x3)) - { - swap(*__x3, *__x4); +template +_LIBCPP_HIDE_FROM_ABI +unsigned __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, + _Compare __c) { + using _Ops = _IterOps<_AlgPolicy>; + + unsigned __r = std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); + if (__c(*__x4, *__x3)) { + _Ops::iter_swap(__x3, __x4); + ++__r; + if (__c(*__x3, *__x2)) { + _Ops::iter_swap(__x2, __x3); + ++__r; + if (__c(*__x2, *__x1)) { + _Ops::iter_swap(__x1, __x2); ++__r; - if (__c(*__x3, *__x2)) - { - swap(*__x2, *__x3); - ++__r; - if (__c(*__x2, *__x1)) - { - swap(*__x1, *__x2); - ++__r; - } - } + } } - return __r; + } + return __r; } // stable, 4-10 compares, 0-9 swaps -template -_LIBCPP_HIDDEN -unsigned -__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, - _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c) -{ - unsigned __r = _VSTD::__sort4<_Compare>(__x1, __x2, __x3, __x4, __c); - if (__c(*__x5, *__x4)) - { - swap(*__x4, *__x5); +template +_LIBCPP_HIDDEN unsigned __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, + _ForwardIterator __x4, _ForwardIterator __x5, _WrappedComp __wrapped_comp) { + using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; + using _AlgPolicy = typename _Unwrap::_AlgPolicy; + using _Ops = _IterOps<_AlgPolicy>; + + using _Compare = typename _Unwrap::_Comp; + _Compare __c = _Unwrap::__get_comp(__wrapped_comp); + + unsigned __r = std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); + if (__c(*__x5, *__x4)) { + _Ops::iter_swap(__x4, __x5); + ++__r; + if (__c(*__x4, *__x3)) { + _Ops::iter_swap(__x3, __x4); + ++__r; + if (__c(*__x3, *__x2)) { + _Ops::iter_swap(__x2, __x3); ++__r; - if (__c(*__x4, *__x3)) - { - swap(*__x3, *__x4); - ++__r; - if (__c(*__x3, *__x2)) - { - swap(*__x2, *__x3); - ++__r; - if (__c(*__x2, *__x1)) - { - swap(*__x1, *__x2); - ++__r; - } - } + if (__c(*__x2, *__x1)) { + _Ops::iter_swap(__x1, __x2); + ++__r; } + } } - return __r; + } + return __r; +} + +template +_LIBCPP_HIDE_FROM_ABI unsigned __sort5_wrap_policy( + _ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _ForwardIterator __x5, + _Compare __c) { + using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type; + _WrappedComp __wrapped_comp(__c); + return std::__sort5<_WrappedComp>( + std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __wrapped_comp); +} + +// The comparator being simple is a prerequisite for using the branchless optimization. +template +struct __is_simple_comparator : false_type {}; +template +struct __is_simple_comparator<__less<_Tp>&> : true_type {}; +template +struct __is_simple_comparator&> : true_type {}; +template +struct __is_simple_comparator&> : true_type {}; +#if _LIBCPP_STD_VER > 17 +template <> +struct __is_simple_comparator : true_type {}; +template <> +struct __is_simple_comparator : true_type {}; +#endif + +template ::value_type> +using __use_branchless_sort = + integral_constant::value && sizeof(_Tp) <= sizeof(void*) && + is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>; + +// Ensures that __c(*__x, *__y) is true by swapping *__x and *__y if necessary. +template +inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) { + // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + bool __r = __c(*__x, *__y); + value_type __tmp = __r ? *__x : *__y; + *__y = __r ? *__y : *__x; + *__x = __tmp; +} + +// Ensures that *__x, *__y and *__z are ordered according to the comparator __c, +// under the assumption that *__y and *__z are already ordered. +template +inline _LIBCPP_HIDE_FROM_ABI void __partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, + _RandomAccessIterator __z, _Compare __c) { + // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + bool __r = __c(*__z, *__x); + value_type __tmp = __r ? *__z : *__x; + *__z = __r ? *__x : *__z; + __r = __c(__tmp, *__y); + *__x = __r ? *__x : *__y; + *__y = __r ? *__y : __tmp; +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> +__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _Compare __c) { + std::__cond_swap<_Compare>(__x2, __x3, __c); + std::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, void> +__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _Compare __c) { + std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> +__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _RandomAccessIterator __x4, _Compare __c) { + std::__cond_swap<_Compare>(__x1, __x3, __c); + std::__cond_swap<_Compare>(__x2, __x4, __c); + std::__cond_swap<_Compare>(__x1, __x2, __c); + std::__cond_swap<_Compare>(__x3, __x4, __c); + std::__cond_swap<_Compare>(__x2, __x3, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, void> +__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _RandomAccessIterator __x4, _Compare __c) { + std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> +__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) { + std::__cond_swap<_Compare>(__x1, __x2, __c); + std::__cond_swap<_Compare>(__x4, __x5, __c); + std::__partially_sorted_swap<_Compare>(__x3, __x4, __x5, __c); + std::__cond_swap<_Compare>(__x2, __x5, __c); + std::__partially_sorted_swap<_Compare>(__x1, __x3, __x4, __c); + std::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c); +} + +template +inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, void> +__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, + _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) { + std::__sort5_wrap_policy<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __x5, __c); } // Assumes size > 0 -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 void -__selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) -{ - _BidirectionalIterator __lm1 = __last; - for (--__lm1; __first != __lm1; ++__first) - { - _BidirectionalIterator __i = _VSTD::min_element<_BidirectionalIterator, - typename add_lvalue_reference<_Compare>::type> - (__first, __last, __comp); - if (__i != __first) - swap(*__first, *__i); +template +_LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, + _Compare __comp) { + _BidirectionalIterator __lm1 = __last; + for (--__lm1; __first != __lm1; ++__first) { + _BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp); + if (__i != __first) + _IterOps<_AlgPolicy>::iter_swap(__first, __i); + } +} + +template +_LIBCPP_HIDE_FROM_ABI +void __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + if (__first != __last) { + _BidirectionalIterator __i = __first; + for (++__i; __i != __last; ++__i) { + _BidirectionalIterator __j = __i; + value_type __t(_Ops::__iter_move(__j)); + for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j) + *__j = _Ops::__iter_move(__k); + *__j = std::move(__t); } + } } -template -void -__insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) -{ - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - if (__first != __last) - { - _BidirectionalIterator __i = __first; - for (++__i; __i != __last; ++__i) - { - _BidirectionalIterator __j = __i; - value_type __t(_VSTD::move(*__j)); - for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j) - *__j = _VSTD::move(*__k); - *__j = _VSTD::move(__t); - } +template +_LIBCPP_HIDE_FROM_ABI +void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + _RandomAccessIterator __j = __first + difference_type(2); + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp); + for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { + if (__comp(*__i, *__j)) { + value_type __t(_Ops::__iter_move(__i)); + _RandomAccessIterator __k = __j; + __j = __i; + do { + *__j = _Ops::__iter_move(__k); + __j = __k; + } while (__j != __first && __comp(__t, *--__k)); + *__j = std::move(__t); } + __j = __i; + } } -template -void -__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - _RandomAccessIterator __j = __first+2; - _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp); - for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) - { - if (__comp(*__i, *__j)) - { - value_type __t(_VSTD::move(*__i)); - _RandomAccessIterator __k = __j; - __j = __i; - do - { - *__j = _VSTD::move(*__k); - __j = __k; - } while (__j != __first && __comp(__t, *--__k)); - *__j = _VSTD::move(__t); - } - __j = __i; +template +_LIBCPP_HIDDEN bool __insertion_sort_incomplete( + _RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) { + using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; + using _AlgPolicy = typename _Unwrap::_AlgPolicy; + using _Ops = _IterOps<_AlgPolicy>; + + using _Compare = typename _Unwrap::_Comp; + _Compare __comp = _Unwrap::__get_comp(__wrapped_comp); + + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + switch (__last - __first) { + case 0: + case 1: + return true; + case 2: + if (__comp(*--__last, *__first)) + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + return true; + case 3: + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp); + return true; + case 4: + std::__sort4_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp); + return true; + case 5: + std::__sort5_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), + --__last, __comp); + return true; + } + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + _RandomAccessIterator __j = __first + difference_type(2); + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp); + const unsigned __limit = 8; + unsigned __count = 0; + for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { + if (__comp(*__i, *__j)) { + value_type __t(_Ops::__iter_move(__i)); + _RandomAccessIterator __k = __j; + __j = __i; + do { + *__j = _Ops::__iter_move(__k); + __j = __k; + } while (__j != __first && __comp(__t, *--__k)); + *__j = std::move(__t); + if (++__count == __limit) + return ++__i == __last; } + __j = __i; + } + return true; } -template -bool -__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - switch (__last - __first) - { +template +_LIBCPP_HIDE_FROM_ABI +void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1, + typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + if (__first1 != __last1) { + __destruct_n __d(0); + unique_ptr __h(__first2, __d); + value_type* __last2 = __first2; + ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + for (++__last2; ++__first1 != __last1; ++__last2) { + value_type* __j2 = __last2; + value_type* __i2 = __j2; + if (__comp(*__first1, *--__i2)) { + ::new ((void*)__j2) value_type(std::move(*__i2)); + __d.template __incr(); + for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) + *__j2 = std::move(*__i2); + *__j2 = _Ops::__iter_move(__first1); + } else { + ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + } + } + __h.release(); + } +} + +template +void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __depth) { + using _Ops = _IterOps<_AlgPolicy>; + + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + const difference_type __limit = + is_trivially_copy_constructible::value && is_trivially_copy_assignable::value ? 30 : 6; + while (true) { + __restart: + difference_type __len = __last - __first; + switch (__len) { case 0: case 1: - return true; + return; case 2: - if (__comp(*--__last, *__first)) - swap(*__first, *__last); - return true; + if (__comp(*--__last, *__first)) + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + return; case 3: - _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); - return true; + std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp); + return; case 4: - _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); - return true; + std::__sort4_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp); + return; case 5: - _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); - return true; + std::__sort5_maybe_branchless<_AlgPolicy, _Compare>( + __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), + --__last, __comp); + return; } - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - _RandomAccessIterator __j = __first+2; - _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp); - const unsigned __limit = 8; - unsigned __count = 0; - for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) - { - if (__comp(*__i, *__j)) - { - value_type __t(_VSTD::move(*__i)); - _RandomAccessIterator __k = __j; - __j = __i; - do - { - *__j = _VSTD::move(*__k); - __j = __k; - } while (__j != __first && __comp(__t, *--__k)); - *__j = _VSTD::move(__t); - if (++__count == __limit) - return ++__i == __last; - } - __j = __i; + if (__len <= __limit) { + std::__insertion_sort_3<_AlgPolicy, _Compare>(__first, __last, __comp); + return; } - return true; -} - -template -void -__insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1, - typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) -{ - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - if (__first1 != __last1) + // __len > 5 + if (__depth == 0) { + // Fallback to heap sort as Introsort suggests. + std::__partial_sort<_AlgPolicy, _Compare>(__first, __last, __last, __comp); + return; + } + --__depth; + _RandomAccessIterator __m = __first; + _RandomAccessIterator __lm1 = __last; + --__lm1; + unsigned __n_swaps; { - __destruct_n __d(0); - unique_ptr __h(__first2, __d); - value_type* __last2 = __first2; - ::new ((void*)__last2) value_type(_VSTD::move(*__first1)); - __d.template __incr(); - for (++__last2; ++__first1 != __last1; ++__last2) - { - value_type* __j2 = __last2; - value_type* __i2 = __j2; - if (__comp(*__first1, *--__i2)) - { - ::new ((void*)__j2) value_type(_VSTD::move(*__i2)); - __d.template __incr(); - for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) - *__j2 = _VSTD::move(*__i2); - *__j2 = _VSTD::move(*__first1); - } - else - { - ::new ((void*)__j2) value_type(_VSTD::move(*__first1)); - __d.template __incr(); - } - } - __h.release(); + difference_type __delta; + if (__len >= 1000) { + __delta = __len / 2; + __m += __delta; + __delta /= 2; + __n_swaps = std::__sort5_wrap_policy<_AlgPolicy, _Compare>( + __first, __first + __delta, __m, __m + __delta, __lm1, __comp); + } else { + __delta = __len / 2; + __m += __delta; + __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, __lm1, __comp); + } } -} - -template -void -__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - const difference_type __limit = is_trivially_copy_constructible::value && - is_trivially_copy_assignable::value ? 30 : 6; - while (true) + // *__m is median + // partition [__first, __m) < *__m and *__m <= [__m, __last) + // (this inhibits tossing elements equivalent to __m around unnecessarily) + _RandomAccessIterator __i = __first; + _RandomAccessIterator __j = __lm1; + // j points beyond range to be tested, *__m is known to be <= *__lm1 + // The search going up is known to be guarded but the search coming down isn't. + // Prime the downward search with a guard. + if (!__comp(*__i, *__m)) // if *__first == *__m { - __restart: - difference_type __len = __last - __first; - switch (__len) - { - case 0: - case 1: - return; - case 2: - if (__comp(*--__last, *__first)) - swap(*__first, *__last); - return; - case 3: - _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); - return; - case 4: - _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); - return; - case 5: - _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); - return; - } - if (__len <= __limit) - { - _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp); - return; - } - // __len > 5 - _RandomAccessIterator __m = __first; - _RandomAccessIterator __lm1 = __last; - --__lm1; - unsigned __n_swaps; - { - difference_type __delta; - if (__len >= 1000) - { - __delta = __len/2; - __m += __delta; - __delta /= 2; - __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp); - } - else - { - __delta = __len/2; - __m += __delta; - __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp); - } - } - // *__m is median - // partition [__first, __m) < *__m and *__m <= [__m, __last) - // (this inhibits tossing elements equivalent to __m around unnecessarily) - _RandomAccessIterator __i = __first; - _RandomAccessIterator __j = __lm1; - // j points beyond range to be tested, *__m is known to be <= *__lm1 - // The search going up is known to be guarded but the search coming down isn't. - // Prime the downward search with a guard. - if (!__comp(*__i, *__m)) // if *__first == *__m - { - // *__first == *__m, *__first doesn't go in first part - // manually guard downward moving __j against __i - while (true) - { - if (__i == --__j) - { - // *__first == *__m, *__m <= all other elements - // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) - ++__i; // __first + 1 - __j = __last; - if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) - { - while (true) - { - if (__i == __j) - return; // [__first, __last) all equivalent elements - if (__comp(*__first, *__i)) - { - swap(*__i, *__j); - ++__n_swaps; - ++__i; - break; - } - ++__i; - } - } - // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 - if (__i == __j) - return; - while (true) - { - while (!__comp(*__first, *__i)) - ++__i; - while (__comp(*__first, *--__j)) - ; - if (__i >= __j) - break; - swap(*__i, *__j); - ++__n_swaps; - ++__i; - } - // [__first, __i) == *__first and *__first < [__i, __last) - // The first part is sorted, sort the second part - // _VSTD::__sort<_Compare>(__i, __last, __comp); - __first = __i; - goto __restart; - } - if (__comp(*__j, *__m)) - { - swap(*__i, *__j); - ++__n_swaps; - break; // found guard for downward moving __j, now use unguarded partition - } - } - } - // It is known that *__i < *__m - ++__i; - // j points beyond range to be tested, *__m is known to be <= *__lm1 - // if not yet partitioned... - if (__i < __j) - { - // known that *(__i - 1) < *__m - // known that __i <= __m - while (true) - { - // __m still guards upward moving __i - while (__comp(*__i, *__m)) - ++__i; - // It is now known that a guard exists for downward moving __j - while (!__comp(*--__j, *__m)) - ; - if (__i > __j) - break; - swap(*__i, *__j); + // *__first == *__m, *__first doesn't go in first part + // manually guard downward moving __j against __i + while (true) { + if (__i == --__j) { + // *__first == *__m, *__m <= all other elements + // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) + ++__i; // __first + 1 + __j = __last; + if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) + { + while (true) { + if (__i == __j) + return; // [__first, __last) all equivalent elements + if (__comp(*__first, *__i)) { + _Ops::iter_swap(__i, __j); ++__n_swaps; - // It is known that __m != __j - // If __m just moved, follow it - if (__m == __i) - __m = __j; ++__i; + break; + } + ++__i; } - } - // [__first, __i) < *__m and *__m <= [__i, __last) - if (__i != __m && __comp(*__m, *__i)) - { - swap(*__i, *__m); + } + // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 + if (__i == __j) + return; + while (true) { + while (!__comp(*__first, *__i)) + ++__i; + while (__comp(*__first, *--__j)) + ; + if (__i >= __j) + break; + _Ops::iter_swap(__i, __j); ++__n_swaps; + ++__i; + } + // [__first, __i) == *__first and *__first < [__i, __last) + // The first part is sorted, sort the second part + // std::__sort<_Compare>(__i, __last, __comp); + __first = __i; + goto __restart; } - // [__first, __i) < *__i and *__i <= [__i+1, __last) - // If we were given a perfect partition, see if insertion sort is quick... - if (__n_swaps == 0) - { - bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp); - if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp)) - { - if (__fs) - return; - __last = __i; - continue; - } - else - { - if (__fs) - { - __first = ++__i; - continue; - } - } - } - // sort smaller range with recursive call and larger with tail recursion elimination - if (__i - __first < __last - __i) - { - _VSTD::__sort<_Compare>(__first, __i, __comp); - // _VSTD::__sort<_Compare>(__i+1, __last, __comp); - __first = ++__i; + if (__comp(*__j, *__m)) { + _Ops::iter_swap(__i, __j); + ++__n_swaps; + break; // found guard for downward moving __j, now use unguarded partition } - else - { - _VSTD::__sort<_Compare>(__i+1, __last, __comp); - // _VSTD::__sort<_Compare>(__first, __i, __comp); - __last = __i; + } + } + // It is known that *__i < *__m + ++__i; + // j points beyond range to be tested, *__m is known to be <= *__lm1 + // if not yet partitioned... + if (__i < __j) { + // known that *(__i - 1) < *__m + // known that __i <= __m + while (true) { + // __m still guards upward moving __i + while (__comp(*__i, *__m)) + ++__i; + // It is now known that a guard exists for downward moving __j + while (!__comp(*--__j, *__m)) + ; + if (__i > __j) + break; + _Ops::iter_swap(__i, __j); + ++__n_swaps; + // It is known that __m != __j + // If __m just moved, follow it + if (__m == __i) + __m = __j; + ++__i; + } + } + // [__first, __i) < *__m and *__m <= [__i, __last) + if (__i != __m && __comp(*__m, *__i)) { + _Ops::iter_swap(__i, __m); + ++__n_swaps; + } + // [__first, __i) < *__i and *__i <= [__i+1, __last) + // If we were given a perfect partition, see if insertion sort is quick... + if (__n_swaps == 0) { + using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type; + _WrappedComp __wrapped_comp(__comp); + bool __fs = std::__insertion_sort_incomplete<_WrappedComp>(__first, __i, __wrapped_comp); + if (std::__insertion_sort_incomplete<_WrappedComp>(__i + difference_type(1), __last, __wrapped_comp)) { + if (__fs) + return; + __last = __i; + continue; + } else { + if (__fs) { + __first = ++__i; + continue; } + } } + // sort smaller range with recursive call and larger with tail recursion elimination + if (__i - __first < __last - __i) { + std::__introsort<_AlgPolicy, _Compare>(__first, __i, __comp, __depth); + __first = ++__i; + } else { + std::__introsort<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp, __depth); + __last = __i; + } + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) { + if (__n == 0) + return 0; + if (sizeof(__n) <= sizeof(unsigned)) + return sizeof(unsigned) * CHAR_BIT - 1 - __libcpp_clz(static_cast(__n)); + if (sizeof(__n) <= sizeof(unsigned long)) + return sizeof(unsigned long) * CHAR_BIT - 1 - __libcpp_clz(static_cast(__n)); + if (sizeof(__n) <= sizeof(unsigned long long)) + return sizeof(unsigned long long) * CHAR_BIT - 1 - __libcpp_clz(static_cast(__n)); + + _Number __log2 = 0; + while (__n > 1) { + __log2++; + __n >>= 1; + } + return __log2; +} + +template +_LIBCPP_HIDDEN void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __depth_limit = 2 * std::__log2i(__last - __first); + + using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; + using _AlgPolicy = typename _Unwrap::_AlgPolicy; + using _Compare = typename _Unwrap::_Comp; + _Compare __comp = _Unwrap::__get_comp(__wrapped_comp); + std::__introsort<_AlgPolicy, _Compare>(__first, __last, __comp, __depth_limit); } template -inline _LIBCPP_INLINE_VISIBILITY -void -__sort(_Tp** __first, _Tp** __last, __less<_Tp*>&) -{ - __less __comp; - _VSTD::__sort<__less&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp); +inline _LIBCPP_INLINE_VISIBILITY void __sort(_Tp** __first, _Tp** __last, __less<_Tp*>&) { + __less __comp; + std::__sort<__less&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp); } -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, char*>(char*, char*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, signed char*>(signed char*, signed char*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, short*>(short*, short*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, int*>(int*, int*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned*>(unsigned*, unsigned*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, long*>(long*, long*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, long long*>(long long*, long long*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, float*>(float*, float*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, double*>(double*, double*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less&, long double*>(long double*, long double*, __less&)) - -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, char*>(char*, char*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, signed char*>(signed char*, signed char*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, short*>(short*, short*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, int*>(int*, int*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned*>(unsigned*, unsigned*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long*>(long*, long*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long long*>(long long*, long long*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, float*>(float*, float*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, double*>(double*, double*, __less&)) -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long double*>(long double*, long double*, __less&)) - -_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less&, long double*>(long double*, long double*, long double*, long double*, long double*, __less&)) - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - if (__libcpp_is_constant_evaluated()) { - _VSTD::__partial_sort<_Comp_ref>(__first, __last, __last, _Comp_ref(__comp)); - } else { - _VSTD::__sort<_Comp_ref>(_VSTD::__unwrap_iter(__first), _VSTD::__unwrap_iter(__last), _Comp_ref(__comp)); - } +extern template _LIBCPP_FUNC_VIS void __sort<__less&, char*>(char*, char*, __less&); +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +extern template _LIBCPP_FUNC_VIS void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&); +#endif +extern template _LIBCPP_FUNC_VIS void __sort<__less&, signed char*>(signed char*, signed char*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, short*>(short*, short*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, int*>(int*, int*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned*>(unsigned*, unsigned*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, long*>(long*, long*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, long long*>(long long*, long long*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, float*>(float*, float*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, double*>(double*, double*, __less&); +extern template _LIBCPP_FUNC_VIS void __sort<__less&, long double*>(long double*, long double*, __less&); + +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, char*>(char*, char*, __less&); +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&); +#endif +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, signed char*>(signed char*, signed char*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, short*>(short*, short*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, int*>(int*, int*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned*>(unsigned*, unsigned*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long*>(long*, long*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long long*>(long long*, long long*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, float*>(float*, float*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, double*>(double*, double*, __less&); +extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less&, long double*>(long double*, long double*, __less&); + +extern template _LIBCPP_FUNC_VIS unsigned __sort5<__less&, long double*>(long double*, long double*, long double*, long double*, long double*, __less&); + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { + std::__debug_randomize_range<_AlgPolicy>(__first, __last); + + using _Comp_ref = __comp_ref_type<_Comp>; + if (__libcpp_is_constant_evaluated()) { + std::__partial_sort<_AlgPolicy>(__first, __last, __last, __comp); + + } else { + using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Comp_ref>::type; + _Comp_ref __comp_ref(__comp); + _WrappedComp __wrapped_comp(__comp_ref); + std::__sort<_WrappedComp>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __wrapped_comp); + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { + std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -sort(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - _VSTD::sort(__first, __last, __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::sort(__first, __last, __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SORT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/sort_heap.h b/gnu/llvm/libcxx/include/__algorithm/sort_heap.h index aa8ef762ab1..8249407b550 100644 --- a/gnu/llvm/libcxx/include/__algorithm/sort_heap.h +++ b/gnu/llvm/libcxx/include/__algorithm/sort_heap.h @@ -9,50 +9,47 @@ #ifndef _LIBCPP___ALGORITHM_SORT_HEAP_H #define _LIBCPP___ALGORITHM_SORT_HEAP_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/pop_heap.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include // swap +#include <__utility/move.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 void -__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) - _VSTD::__pop_heap<_Compare>(__first, __last, __comp, __n); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { + __comp_ref_type<_Compare> __comp_ref = __comp; + + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) + std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - _VSTD::__sort_heap<_Comp_ref>(__first, __last, __comp); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); + static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + + std::__sort_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -void -sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - _VSTD::sort_heap(__first, __last, __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::sort_heap(std::move(__first), std::move(__last), + __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SORT_HEAP_H diff --git a/gnu/llvm/libcxx/include/__algorithm/stable_partition.h b/gnu/llvm/libcxx/include/__algorithm/stable_partition.h index 931335f4447..a49de6dbb0e 100644 --- a/gnu/llvm/libcxx/include/__algorithm/stable_partition.h +++ b/gnu/llvm/libcxx/include/__algorithm/stable_partition.h @@ -9,26 +9,33 @@ #ifndef _LIBCPP___ALGORITHM_STABLE_PARTITION_H #define _LIBCPP___ALGORITHM_STABLE_PARTITION_H -#include <__config> +#include <__algorithm/iterator_operations.h> #include <__algorithm/rotate.h> +#include <__config> +#include <__iterator/advance.h> +#include <__iterator/distance.h> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> -#include +#include <__memory/destruct_n.h> +#include <__memory/temporary_buffer.h> +#include <__memory/unique_ptr.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_ForwardIterator -__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, +template +_LIBCPP_HIDE_FROM_ABI _ForwardIterator +__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, _Distance __len, _Pair __p, forward_iterator_tag __fit) { + using _Ops = _IterOps<_AlgPolicy>; + // *__first is known to be false // __len >= 1 if (__len == 1) @@ -38,7 +45,7 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate _ForwardIterator __m = __first; if (__pred(*++__m)) { - swap(*__first, *__m); + _Ops::iter_swap(__first, __m); return __m; } return __first; @@ -51,7 +58,7 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate // Move the falses into the temporary buffer, and the trues to the front of the line // Update __first to always point to the end of the trues value_type* __t = __p.first; - ::new ((void*)__t) value_type(_VSTD::move(*__first)); + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); __d.template __incr(); ++__t; _ForwardIterator __i = __first; @@ -59,12 +66,12 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate { if (__pred(*__i)) { - *__first = _VSTD::move(*__i); + *__first = _Ops::__iter_move(__i); ++__first; } else { - ::new ((void*)__t) value_type(_VSTD::move(*__i)); + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); __d.template __incr(); ++__t; } @@ -73,7 +80,7 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate // Move falses back into range, but don't mess up __first which points to first false __i = __first; for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) - *__i = _VSTD::move(*__t2); + *__i = _Ops::__iter_move(__t2); // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer return __first; } @@ -81,12 +88,12 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate // __len >= 3 _ForwardIterator __m = __first; _Distance __len2 = __len / 2; // __len2 >= 2 - _VSTD::advance(__m, __len2); + _Ops::advance(__m, __len2); // recurse on [__first, __m), *__first know to be false // F????????????????? // f m l - typedef typename add_lvalue_reference<_Predicate>::type _PredRef; - _ForwardIterator __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit); + _ForwardIterator __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + __first, __m, __pred, __len2, __p, __fit); // TTTFFFFF?????????? // f ff m l // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true @@ -101,18 +108,19 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate } // TTTFFFFFTTTF?????? // f ff m m1 l - __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit); + __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + __m1, __last, __pred, __len_half, __p, __fit); __second_half_done: // TTTFFFFFTTTTTFFFFF // f ff m sf l - return _VSTD::rotate(__first_false, __m, __second_false); + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; // TTTTTTTTFFFFFFFFFF // | } -template -_ForwardIterator -__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, +template +_LIBCPP_HIDE_FROM_ABI _ForwardIterator +__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) { const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment @@ -129,29 +137,34 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate // *__first is known to be false typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - difference_type __len = _VSTD::distance(__first, __last); + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); pair __p(0, 0); unique_ptr __h; if (__len >= __alloc_limit) { +// TODO: Remove the use of std::get_temporary_buffer +_LIBCPP_SUPPRESS_DEPRECATED_PUSH __p = _VSTD::get_temporary_buffer(__len); +_LIBCPP_SUPPRESS_DEPRECATED_POP __h.reset(__p.first); } - return _VSTD::__stable_partition::type> - (__first, __last, __pred, __len, __p, forward_iterator_tag()); + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag()); } -template +template _BidirectionalIterator -__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, +__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, _Distance __len, _Pair __p, bidirectional_iterator_tag __bit) { + using _Ops = _IterOps<_AlgPolicy>; + // *__first is known to be false // *__last is known to be true // __len >= 2 if (__len == 2) { - swap(*__first, *__last); + _Ops::iter_swap(__first, __last); return __last; } if (__len == 3) @@ -159,12 +172,12 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last _BidirectionalIterator __m = __first; if (__pred(*++__m)) { - swap(*__first, *__m); - swap(*__m, *__last); + _Ops::iter_swap(__first, __m); + _Ops::iter_swap(__m, __last); return __last; } - swap(*__m, *__last); - swap(*__first, *__m); + _Ops::iter_swap(__m, __last); + _Ops::iter_swap(__first, __m); return __m; } if (__len <= __p.second) @@ -175,7 +188,7 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last // Move the falses into the temporary buffer, and the trues to the front of the line // Update __first to always point to the end of the trues value_type* __t = __p.first; - ::new ((void*)__t) value_type(_VSTD::move(*__first)); + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); __d.template __incr(); ++__t; _BidirectionalIterator __i = __first; @@ -183,23 +196,23 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last { if (__pred(*__i)) { - *__first = _VSTD::move(*__i); + *__first = _Ops::__iter_move(__i); ++__first; } else { - ::new ((void*)__t) value_type(_VSTD::move(*__i)); + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); __d.template __incr(); ++__t; } } // move *__last, known to be true - *__first = _VSTD::move(*__i); + *__first = _Ops::__iter_move(__i); __i = ++__first; // All trues now at start of range, all falses in buffer // Move falses back into range, but don't mess up __first which points to first false for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) - *__i = _VSTD::move(*__t2); + *__i = _Ops::__iter_move(__t2); // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer return __first; } @@ -207,7 +220,7 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last // __len >= 4 _BidirectionalIterator __m = __first; _Distance __len2 = __len / 2; // __len2 >= 2 - _VSTD::advance(__m, __len2); + _Ops::advance(__m, __len2); // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false // F????????????????T // f m l @@ -222,8 +235,8 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last } // F???TFFF?????????T // f m1 m l - typedef typename add_lvalue_reference<_Predicate>::type _PredRef; - __first_false = _VSTD::__stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit); + __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + __first, __m1, __pred, __len_half, __p, __bit); __first_half_done: // TTTFFFFF?????????T // f ff m l @@ -240,18 +253,19 @@ __first_half_done: } // TTTFFFFFTTTF?????T // f ff m m1 l - __second_false = _VSTD::__stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit); + __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + __m1, __last, __pred, __len_half, __p, __bit); __second_half_done: // TTTFFFFFTTTTTFFFFF // f ff m sf l - return _VSTD::rotate(__first_false, __m, __second_false); + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; // TTTTTTTTFFFFFFFFFF // | } -template -_BidirectionalIterator -__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, +template +_LIBCPP_HIDE_FROM_ABI _BidirectionalIterator +__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, bidirectional_iterator_tag) { typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; @@ -277,16 +291,27 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last // *__first is known to be false // *__last is known to be true // __len >= 2 - difference_type __len = _VSTD::distance(__first, __last) + 1; + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; pair __p(0, 0); unique_ptr __h; if (__len >= __alloc_limit) { +// TODO: Remove the use of std::get_temporary_buffer +_LIBCPP_SUPPRESS_DEPRECATED_PUSH __p = _VSTD::get_temporary_buffer(__len); +_LIBCPP_SUPPRESS_DEPRECATED_POP __h.reset(__p.first); } - return _VSTD::__stable_partition::type> - (__first, __last, __pred, __len, __p, bidirectional_iterator_tag()); + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag()); +} + +template +_LIBCPP_HIDE_FROM_ABI +_ForwardIterator __stable_partition( + _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred, _IterCategory __iter_category) { + return std::__stable_partition_impl<_AlgPolicy, __remove_cvref_t<_Predicate>&>( + std::move(__first), std::move(__last), __pred, __iter_category); } template @@ -294,12 +319,11 @@ inline _LIBCPP_INLINE_VISIBILITY _ForwardIterator stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - return _VSTD::__stable_partition::type> - (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category()); + using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; + return std::__stable_partition<_ClassicAlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, _IterCategory()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_STABLE_PARTITION_H diff --git a/gnu/llvm/libcxx/include/__algorithm/stable_sort.h b/gnu/llvm/libcxx/include/__algorithm/stable_sort.h index 32b239a0d72..8e70978ab61 100644 --- a/gnu/llvm/libcxx/include/__algorithm/stable_sort.h +++ b/gnu/llvm/libcxx/include/__algorithm/stable_sort.h @@ -9,31 +9,35 @@ #ifndef _LIBCPP___ALGORITHM_STABLE_SORT_H #define _LIBCPP___ALGORITHM_STABLE_SORT_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/inplace_merge.h> +#include <__algorithm/iterator_operations.h> #include <__algorithm/sort.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include <__utility/swap.h> -#include -#include // swap +#include <__memory/destruct_n.h> +#include <__memory/temporary_buffer.h> +#include <__memory/unique_ptr.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -void +template +_LIBCPP_HIDE_FROM_ABI void __merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename iterator_traits<_InputIterator1>::value_type value_type; __destruct_n __d(0); unique_ptr __h(__result, __d); @@ -41,112 +45,116 @@ __merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, { if (__first1 == __last1) { - for (; __first2 != __last2; ++__first2, ++__result, (void)__d.template __incr()) - ::new ((void*)__result) value_type(_VSTD::move(*__first2)); + for (; __first2 != __last2; ++__first2, (void) ++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); __h.release(); return; } if (__first2 == __last2) { - for (; __first1 != __last1; ++__first1, ++__result, (void)__d.template __incr()) - ::new ((void*)__result) value_type(_VSTD::move(*__first1)); + for (; __first1 != __last1; ++__first1, (void) ++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); __h.release(); return; } if (__comp(*__first2, *__first1)) { - ::new ((void*)__result) value_type(_VSTD::move(*__first2)); + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); __d.template __incr(); ++__first2; } else { - ::new ((void*)__result) value_type(_VSTD::move(*__first1)); + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); __d.template __incr(); ++__first1; } } } -template -void +template +_LIBCPP_HIDE_FROM_ABI void __merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; + for (; __first1 != __last1; ++__result) { if (__first2 == __last2) { for (; __first1 != __last1; ++__first1, (void) ++__result) - *__result = _VSTD::move(*__first1); + *__result = _Ops::__iter_move(__first1); return; } if (__comp(*__first2, *__first1)) { - *__result = _VSTD::move(*__first2); + *__result = _Ops::__iter_move(__first2); ++__first2; } else { - *__result = _VSTD::move(*__first1); + *__result = _Ops::__iter_move(__first1); ++__first1; } } for (; __first2 != __last2; ++__first2, (void) ++__result) - *__result = _VSTD::move(*__first2); + *__result = _Ops::__iter_move(__first2); } -template +template void __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); -template +template void __stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, typename iterator_traits<_RandomAccessIterator>::value_type* __first2) { + using _Ops = _IterOps<_AlgPolicy>; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; switch (__len) { case 0: return; case 1: - ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); return; case 2: __destruct_n __d(0); unique_ptr __h2(__first2, __d); if (__comp(*--__last1, *__first1)) { - ::new ((void*)__first2) value_type(_VSTD::move(*__last1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); __d.template __incr(); ++__first2; - ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); } else { - ::new ((void*)__first2) value_type(_VSTD::move(*__first1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); __d.template __incr(); ++__first2; - ::new ((void*)__first2) value_type(_VSTD::move(*__last1)); + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); } __h2.release(); return; } if (__len <= 8) { - _VSTD::__insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp); + std::__insertion_sort_move<_AlgPolicy, _Compare>(__first1, __last1, __first2, __comp); return; } typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; _RandomAccessIterator __m = __first1 + __l2; - _VSTD::__stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2); - _VSTD::__stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); - _VSTD::__merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp); + std::__stable_sort<_AlgPolicy, _Compare>(__first1, __m, __comp, __l2, __first2, __l2); + std::__stable_sort<_AlgPolicy, _Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); + std::__merge_move_construct<_AlgPolicy, _Compare>(__first1, __m, __m, __last1, __first2, __comp); } template @@ -155,7 +163,7 @@ struct __stable_sort_switch static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; }; -template +template void __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, @@ -170,12 +178,12 @@ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp return; case 2: if (__comp(*--__last, *__first)) - swap(*__first, *__last); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); return; } if (__len <= static_cast(__stable_sort_switch::value)) { - _VSTD::__insertion_sort<_Compare>(__first, __last, __comp); + std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); return; } typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; @@ -184,11 +192,12 @@ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp { __destruct_n __d(0); unique_ptr __h2(__buff, __d); - _VSTD::__stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff); + std::__stable_sort_move<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff); __d.__set(__l2, (value_type*)nullptr); - _VSTD::__stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); + std::__stable_sort_move<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); __d.__set(__len, (value_type*)nullptr); - _VSTD::__merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); + std::__merge_move_assign<_AlgPolicy, _Compare>( + __buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); // _VSTD::__merge<_Compare>(move_iterator(__buff), // move_iterator(__buff + __l2), // move_iterator<_RandomAccessIterator>(__buff + __l2), @@ -196,40 +205,43 @@ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp // __first, __comp); return; } - _VSTD::__stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size); - _VSTD::__stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); - _VSTD::__inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); + std::__stable_sort<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff, __buff_size); + std::__stable_sort<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); + std::__inplace_merge<_AlgPolicy>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); +} + +template +inline _LIBCPP_HIDE_FROM_ABI +void __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + + difference_type __len = __last - __first; + pair __buf(0, 0); + unique_ptr __h; + if (__len > static_cast(__stable_sort_switch::value)) { +// TODO: Remove the use of std::get_temporary_buffer +_LIBCPP_SUPPRESS_DEPRECATED_PUSH + __buf = std::get_temporary_buffer(__len); +_LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__buf.first); + } + + std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second); } template -inline _LIBCPP_INLINE_VISIBILITY -void -stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - difference_type __len = __last - __first; - pair __buf(0, 0); - unique_ptr __h; - if (__len > static_cast(__stable_sort_switch::value)) - { - __buf = _VSTD::get_temporary_buffer(__len); - __h.reset(__buf.first); - } - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - _VSTD::__stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second); +inline _LIBCPP_HIDE_FROM_ABI +void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + std::__stable_sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_INLINE_VISIBILITY -void -stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - _VSTD::stable_sort(__first, __last, __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI +void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::stable_sort(__first, __last, __less::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_STABLE_SORT_H diff --git a/gnu/llvm/libcxx/include/__algorithm/swap_ranges.h b/gnu/llvm/libcxx/include/__algorithm/swap_ranges.h index 3c72dbd24c6..5ce5ed8c884 100644 --- a/gnu/llvm/libcxx/include/__algorithm/swap_ranges.h +++ b/gnu/llvm/libcxx/include/__algorithm/swap_ranges.h @@ -9,29 +9,52 @@ #ifndef _LIBCPP___ALGORITHM_SWAP_RANGES_H #define _LIBCPP___ALGORITHM_SWAP_RANGES_H +#include <__algorithm/iterator_operations.h> #include <__config> -#include <__utility/swap.h> -#include +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +// 2+2 iterators: the shorter size will be used. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +pair<_ForwardIterator1, _ForwardIterator2> +__swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _Sentinel2 __last2) { + while (__first1 != __last1 && __first2 != __last2) { + _IterOps<_AlgPolicy>::iter_swap(__first1, __first2); + ++__first1; + ++__first2; + } + + return pair<_ForwardIterator1, _ForwardIterator2>(std::move(__first1), std::move(__first2)); +} + +// 2+1 iterators: size2 >= size1. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +pair<_ForwardIterator1, _ForwardIterator2> +__swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2) { + while (__first1 != __last1) { + _IterOps<_AlgPolicy>::iter_swap(__first1, __first2); + ++__first1; + ++__first2; + } + + return pair<_ForwardIterator1, _ForwardIterator2>(std::move(__first1), std::move(__first2)); +} + template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator2 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator2 swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { - for (; __first1 != __last1; ++__first1, (void)++__first2) - swap(*__first1, *__first2); - return __first2; + return std::__swap_ranges<_ClassicAlgPolicy>( + std::move(__first1), std::move(__last1), std::move(__first2)).second; } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_SWAP_RANGES_H diff --git a/gnu/llvm/libcxx/include/__algorithm/transform.h b/gnu/llvm/libcxx/include/__algorithm/transform.h index 218f0f12eac..4722c154cff 100644 --- a/gnu/llvm/libcxx/include/__algorithm/transform.h +++ b/gnu/llvm/libcxx/include/__algorithm/transform.h @@ -12,16 +12,13 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) { @@ -31,7 +28,7 @@ transform(_InputIterator __first, _InputIterator __last, _OutputIterator __resul } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _OutputIterator __result, _BinaryOperation __binary_op) @@ -43,6 +40,4 @@ transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __f _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_TRANSFORM_H diff --git a/gnu/llvm/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h b/gnu/llvm/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h new file mode 100644 index 00000000000..1e86074b3db --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H +#define _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H + +#include <__config> +#include <__functional/invoke.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Range versions of random algorithms (e.g. `std::shuffle`) are less constrained than their classic counterparts. +// Range algorithms only require the given generator to satisfy the `std::uniform_random_bit_generator` concept. +// Classic algorithms require the given generator to meet the uniform random bit generator requirements; these +// requirements include satisfying `std::uniform_random_bit_generator` and add a requirement for the generator to +// provide a nested `result_type` typedef (see `[rand.req.urng]`). +// +// To be able to reuse classic implementations, make the given generator meet the classic requirements by wrapping +// it into an adaptor type that forwards all of its interface and adds the required typedef. +template +class _ClassicGenAdaptor { +private: + // The generator is not required to be copyable or movable, so it has to be stored as a reference. + _Gen& __gen_; + +public: + using result_type = invoke_result_t<_Gen&>; + + _LIBCPP_HIDE_FROM_ABI + static constexpr auto min() { return __remove_cvref_t<_Gen>::min(); } + _LIBCPP_HIDE_FROM_ABI + static constexpr auto max() { return __remove_cvref_t<_Gen>::max(); } + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen_(__g) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()() const { return __gen_(); } +}; + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H diff --git a/gnu/llvm/libcxx/include/__algorithm/unique.h b/gnu/llvm/libcxx/include/__algorithm/unique.h index fb6251a39a8..1717a00c8a9 100644 --- a/gnu/llvm/libcxx/include/__algorithm/unique.h +++ b/gnu/llvm/libcxx/include/__algorithm/unique.h @@ -9,55 +9,51 @@ #ifndef _LIBCPP___ALGORITHM_UNIQUE_H #define _LIBCPP___ALGORITHM_UNIQUE_H -#include <__config> -#include <__algorithm/comp.h> #include <__algorithm/adjacent_find.h> +#include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> #include <__iterator/iterator_traits.h> #include <__utility/move.h> -#include +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD // unique +template +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter> +__unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { + __first = std::__adjacent_find(__first, __last, __pred); + if (__first != __last) { + // ... a a ? ... + // f i + _Iter __i = __first; + for (++__i; ++__i != __last;) + if (!__pred(*__first, *__i)) + *++__first = _IterOps<_AlgPolicy>::__iter_move(__i); + ++__first; + return std::pair<_Iter, _Iter>(std::move(__first), std::move(__i)); + } + return std::pair<_Iter, _Iter>(__first, __first); +} + template -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) -{ - __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type> - (__first, __last, __pred); - if (__first != __last) - { - // ... a a ? ... - // f i - _ForwardIterator __i = __first; - for (++__i; ++__i != __last;) - if (!__pred(*__first, *__i)) - *++__first = _VSTD::move(*__i); - ++__first; - } - return __first; +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { + return std::__unique<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred).first; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator -unique(_ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type __v; - return _VSTD::unique(__first, __last, __equal_to<__v>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +unique(_ForwardIterator __first, _ForwardIterator __last) { + return std::unique(__first, __last, __equal_to()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_UNIQUE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/unique_copy.h b/gnu/llvm/libcxx/include/__algorithm/unique_copy.h index 974a7c4df2d..81fcd50f011 100644 --- a/gnu/llvm/libcxx/include/__algorithm/unique_copy.h +++ b/gnu/llvm/libcxx/include/__algorithm/unique_copy.h @@ -9,106 +9,114 @@ #ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H #define _LIBCPP___ALGORITHM_UNIQUE_COPY_H -#include <__config> #include <__algorithm/comp.h> +#include <__algorithm/iterator_operations.h> +#include <__config> #include <__iterator/iterator_traits.h> -#include -#include +#include <__type_traits/conditional.h> +#include <__type_traits/is_base_of.h> +#include <__type_traits/is_same.h> +#include <__utility/move.h> +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred, - input_iterator_tag, output_iterator_tag) -{ - if (__first != __last) - { - typename iterator_traits<_InputIterator>::value_type __t(*__first); +namespace __unique_copy_tags { + +struct __reread_from_input_tag {}; +struct __reread_from_output_tag {}; +struct __read_from_tmp_value_tag {}; + +} // namespace __unique_copy_tags + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _OutputIterator> +__unique_copy(_InputIterator __first, + _Sent __last, + _OutputIterator __result, + _BinaryPredicate&& __pred, + __unique_copy_tags::__read_from_tmp_value_tag) { + if (__first != __last) { + typename _IterOps<_AlgPolicy>::template __value_type<_InputIterator> __t(*__first); + *__result = __t; + ++__result; + while (++__first != __last) { + if (!__pred(__t, *__first)) { + __t = *__first; *__result = __t; ++__result; - while (++__first != __last) - { - if (!__pred(__t, *__first)) - { - __t = *__first; - *__result = __t; - ++__result; - } - } + } } - return __result; + } + return pair<_InputIterator, _OutputIterator>(std::move(__first), std::move(__result)); } -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, - forward_iterator_tag, output_iterator_tag) -{ - if (__first != __last) - { - _ForwardIterator __i = __first; - *__result = *__i; +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pair<_ForwardIterator, _OutputIterator> +__unique_copy(_ForwardIterator __first, + _Sent __last, + _OutputIterator __result, + _BinaryPredicate&& __pred, + __unique_copy_tags::__reread_from_input_tag) { + if (__first != __last) { + _ForwardIterator __i = __first; + *__result = *__i; + ++__result; + while (++__first != __last) { + if (!__pred(*__i, *__first)) { + *__result = *__first; ++__result; - while (++__first != __last) - { - if (!__pred(*__i, *__first)) - { - *__result = *__first; - ++__result; - __i = __first; - } - } + __i = __first; + } } - return __result; + } + return pair<_ForwardIterator, _OutputIterator>(std::move(__first), std::move(__result)); } -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred, - input_iterator_tag, forward_iterator_tag) -{ - if (__first != __last) - { - *__result = *__first; - while (++__first != __last) - if (!__pred(*__result, *__first)) - *++__result = *__first; - ++__result; - } - return __result; +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _InputAndOutputIterator> +__unique_copy(_InputIterator __first, + _Sent __last, + _InputAndOutputIterator __result, + _BinaryPredicate&& __pred, + __unique_copy_tags::__reread_from_output_tag) { + if (__first != __last) { + *__result = *__first; + while (++__first != __last) + if (!__pred(*__result, *__first)) + *++__result = *__first; + ++__result; + } + return pair<_InputIterator, _InputAndOutputIterator>(std::move(__first), std::move(__result)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) -{ - return _VSTD::__unique_copy::type> - (__first, __last, __result, __pred, - typename iterator_traits<_InputIterator>::iterator_category(), - typename iterator_traits<_OutputIterator>::iterator_category()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) { + using __algo_tag = __conditional_t< + is_base_of::iterator_category>::value, + __unique_copy_tags::__reread_from_input_tag, + __conditional_t< + is_base_of::iterator_category>::value && + is_same< typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_OutputIterator>::value_type>::value, + __unique_copy_tags::__reread_from_output_tag, + __unique_copy_tags::__read_from_tmp_value_tag> >; + return std::__unique_copy<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), std::move(__result), __pred, __algo_tag()) + .second; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_OutputIterator -unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) -{ - typedef typename iterator_traits<_InputIterator>::value_type __v; - return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { + return std::unique_copy(std::move(__first), std::move(__last), std::move(__result), __equal_to()); } - _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H diff --git a/gnu/llvm/libcxx/include/__algorithm/unwrap_iter.h b/gnu/llvm/libcxx/include/__algorithm/unwrap_iter.h index a45d45cdd86..0f661e10a74 100644 --- a/gnu/llvm/libcxx/include/__algorithm/unwrap_iter.h +++ b/gnu/llvm/libcxx/include/__algorithm/unwrap_iter.h @@ -10,78 +10,65 @@ #define _LIBCPP___ALGORITHM_UNWRAP_ITER_H #include <__config> -#include +#include <__iterator/iterator_traits.h> #include <__memory/pointer_traits.h> -#include +#include <__type_traits/enable_if.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/declval.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -// The job of __unwrap_iter is to lower contiguous iterators (such as -// vector::iterator) into pointers, to reduce the number of template -// instantiations and to enable pointer-based optimizations e.g. in std::copy. -// For iterators that are not contiguous, it must be a no-op. +// TODO: Change the name of __unwrap_iter_impl to something more appropriate +// The job of __unwrap_iter is to remove iterator wrappers (like reverse_iterator or __wrap_iter), +// to reduce the number of template instantiations and to enable pointer-based optimizations e.g. in std::copy. // In debug mode, we don't do this. // -// __unwrap_iter is non-constexpr for user-defined iterators whose -// `to_address` and/or `operator->` is non-constexpr. This is okay; but we -// try to avoid doing __unwrap_iter in constant-evaluated contexts anyway. -// // Some algorithms (e.g. std::copy, but not std::sort) need to convert an -// "unwrapped" result back into a contiguous iterator. Since contiguous iterators -// are random-access, we can do this portably using iterator arithmetic; this -// is the job of __rewrap_iter. +// "unwrapped" result back into the original iterator type. Doing that is the job of __rewrap_iter. +// Default case - we can't unwrap anything template ::value> struct __unwrap_iter_impl { - static _LIBCPP_CONSTEXPR _Iter - __apply(_Iter __i) _NOEXCEPT { - return __i; - } + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap(_Iter, _Iter __iter) { return __iter; } + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __unwrap(_Iter __i) _NOEXCEPT { return __i; } }; -#if _LIBCPP_DEBUG_LEVEL < 2 +#ifndef _LIBCPP_ENABLE_DEBUG_MODE +// It's a contiguous iterator, so we can use a raw pointer instead template struct __unwrap_iter_impl<_Iter, true> { - static _LIBCPP_CONSTEXPR decltype(_VSTD::__to_address(declval<_Iter>())) - __apply(_Iter __i) _NOEXCEPT { - return _VSTD::__to_address(__i); - } -}; + using _ToAddressT = decltype(std::__to_address(std::declval<_Iter>())); -#endif // _LIBCPP_DEBUG_LEVEL < 2 + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap(_Iter __orig_iter, _ToAddressT __unwrapped_iter) { + return __orig_iter + (__unwrapped_iter - std::__to_address(__orig_iter)); + } -template > -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -decltype(_Impl::__apply(declval<_Iter>())) -__unwrap_iter(_Iter __i) _NOEXCEPT -{ - return _Impl::__apply(__i); -} + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToAddressT __unwrap(_Iter __i) _NOEXCEPT { + return std::__to_address(__i); + } +}; + +#endif // !_LIBCPP_ENABLE_DEBUG_MODE -template -_OrigIter __rewrap_iter(_OrigIter, _OrigIter __result) -{ - return __result; +template, + __enable_if_t::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +decltype(_Impl::__unwrap(std::declval<_Iter>())) __unwrap_iter(_Iter __i) _NOEXCEPT { + return _Impl::__unwrap(__i); } -template -_OrigIter __rewrap_iter(_OrigIter __first, _UnwrappedIter __result) -{ - // Precondition: __result is reachable from __first - // Precondition: _OrigIter is a contiguous iterator - return __first + (__result - _VSTD::__unwrap_iter(__first)); +template > +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __orig_iter, _Iter __iter) _NOEXCEPT { + return _Impl::__rewrap(std::move(__orig_iter), std::move(__iter)); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H diff --git a/gnu/llvm/libcxx/include/__algorithm/unwrap_range.h b/gnu/llvm/libcxx/include/__algorithm/unwrap_range.h new file mode 100644 index 00000000000..2c5d23e69f1 --- /dev/null +++ b/gnu/llvm/libcxx/include/__algorithm/unwrap_range.h @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// 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___ALGORITHM_UNWRAP_RANGE_H +#define _LIBCPP___ALGORITHM_UNWRAP_RANGE_H + +#include <__algorithm/unwrap_iter.h> +#include <__concepts/constructible.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/next.h> +#include <__utility/declval.h> +#include <__utility/move.h> +#include <__utility/pair.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// __unwrap_range and __rewrap_range are used to unwrap ranges which may have different iterator and sentinel types. +// __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have +// the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter. + +#if _LIBCPP_STD_VER > 17 +template +struct __unwrap_range_impl { + _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent) + requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter> + { + auto __last = ranges::next(__first, __sent); + return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))}; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __last) { + return pair{std::move(__first), std::move(__last)}; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) + requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter> + { + return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter)); + } + + _LIBCPP_HIDE_FROM_ABI static constexpr auto __rewrap(const _Iter&, _Iter __iter) + requires (!(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>)) + { + return __iter; + } +}; + +template +struct __unwrap_range_impl<_Iter, _Iter> { + _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Iter __last) { + return pair{std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))}; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) { + return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter)); + } +}; + +template +_LIBCPP_HIDE_FROM_ABI constexpr auto __unwrap_range(_Iter __first, _Sent __last) { + return __unwrap_range_impl<_Iter, _Sent>::__unwrap(std::move(__first), std::move(__last)); +} + +template < + class _Sent, + class _Iter, + class _Unwrapped = decltype(std::__unwrap_range(std::declval<_Iter>(), std::declval<_Sent>()))> +_LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) { + return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter)); +} +#else // _LIBCPP_STD_VER > 17 +template ()))> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) { + return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))); +} + +template ()))> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) { + return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter)); +} +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_UNWRAP_RANGE_H diff --git a/gnu/llvm/libcxx/include/__algorithm/upper_bound.h b/gnu/llvm/libcxx/include/__algorithm/upper_bound.h index 7be607f8253..96552ce1f8a 100644 --- a/gnu/llvm/libcxx/include/__algorithm/upper_bound.h +++ b/gnu/llvm/libcxx/include/__algorithm/upper_bound.h @@ -9,64 +9,60 @@ #ifndef _LIBCPP___ALGORITHM_UPPER_BOUND_H #define _LIBCPP___ALGORITHM_UPPER_BOUND_H -#include <__config> #include <__algorithm/comp.h> #include <__algorithm/half_positive.h> -#include +#include <__algorithm/iterator_operations.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__iterator/advance.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_copy_constructible.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) -{ - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - difference_type __len = _VSTD::distance(__first, __last); - while (__len != 0) - { - difference_type __l2 = _VSTD::__half_positive(__len); - _ForwardIterator __m = __first; - _VSTD::advance(__m, __l2); - if (__comp(__value_, *__m)) - __len = __l2; - else - { - __first = ++__m; - __len -= __l2 + 1; - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter +__upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp, _Proj&& __proj) { + auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); + while (__len != 0) { + auto __half_len = std::__half_positive(__len); + auto __mid = _IterOps<_AlgPolicy>::next(__first, __half_len); + if (std::__invoke(__comp, __value, std::__invoke(__proj, *__mid))) + __len = __half_len; + else { + __first = ++__mid; + __len -= __half_len + 1; } - return __first; + } + return __first; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator -upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) -{ - typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; - return _VSTD::__upper_bound<_Comp_ref>(__first, __last, __value_, __comp); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + static_assert(is_copy_constructible<_ForwardIterator>::value, + "Iterator has to be copy constructible"); + return std::__upper_bound<_ClassicAlgPolicy>( + std::move(__first), std::move(__last), __value, std::move(__comp), std::__identity()); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator -upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) -{ - return _VSTD::upper_bound(__first, __last, __value_, - __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::upper_bound( + std::move(__first), + std::move(__last), + __value, + __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H diff --git a/gnu/llvm/libcxx/include/__assert b/gnu/llvm/libcxx/include/__assert new file mode 100644 index 00000000000..9c0cd1b1192 --- /dev/null +++ b/gnu/llvm/libcxx/include/__assert @@ -0,0 +1,55 @@ +// -*- 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___ASSERT +#define _LIBCPP___ASSERT + +#include <__config> +#include <__verbose_abort> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// TODO: Remove in LLVM 17. +#if defined(_LIBCPP_DEBUG) +# error "Defining _LIBCPP_DEBUG is not supported anymore. Please use _LIBCPP_ENABLE_DEBUG_MODE instead." +#endif + +// Automatically enable assertions when the debug mode is enabled. +#if defined(_LIBCPP_ENABLE_DEBUG_MODE) +# ifndef _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_ENABLE_ASSERTIONS 1 +# endif +#endif + +#ifndef _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT +#endif + +#if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1 +# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1" +#endif + +#if _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_ASSERT(expression, message) \ + (__builtin_expect(static_cast(expression), 1) ? \ + (void)0 : \ + _LIBCPP_VERBOSE_ABORT("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message)) +#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume) +# define _LIBCPP_ASSERT(expression, message) \ + (_LIBCPP_DIAGNOSTIC_PUSH \ + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \ + __builtin_assume(static_cast(expression)) \ + _LIBCPP_DIAGNOSTIC_POP) +#else +# define _LIBCPP_ASSERT(expression, message) ((void)0) +#endif + +#endif // _LIBCPP___ASSERT diff --git a/gnu/llvm/libcxx/include/__availability b/gnu/llvm/libcxx/include/__availability index 13d11950fd6..6dfca3fa8b1 100644 --- a/gnu/llvm/libcxx/include/__availability +++ b/gnu/llvm/libcxx/include/__availability @@ -13,7 +13,7 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header +# pragma GCC system_header #endif // Libc++ is shipped by various vendors. In particular, it is used as a system @@ -91,6 +91,10 @@ // other exception types. These were put in the shared library to prevent // code bloat from every user program defining the vtable for these exception // types. + // + // Note that when exceptions are disabled, the methods that normally throw + // these exceptions can be used even on older deployment targets, but those + // methods will abort instead of throwing. # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS # define _LIBCPP_AVAILABILITY_BAD_ANY_CAST @@ -99,10 +103,15 @@ # define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS // This controls the availability of the sized version of ::operator delete, - // which was added to the dylib later. + // ::operator delete[], and their align_val_t variants, which were all added + // in C++17, and hence not present in early dylibs. # define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE // This controls the availability of the std::future_error exception. + // + // Note that when exceptions are disabled, the methods that normally throw + // std::future_error can be used even on older deployment targets, but those + // methods will abort instead of throwing. # define _LIBCPP_AVAILABILITY_FUTURE_ERROR // This controls the availability of std::type_info's vtable. @@ -126,12 +135,14 @@ # define _LIBCPP_AVAILABILITY_FILESYSTEM_POP // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem - // This controls the availability of std::to_chars. -# define _LIBCPP_AVAILABILITY_TO_CHARS + // This controls the availability of floating-point std::to_chars functions. + // These overloads were added later than the integer overloads. +# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT // This controls the availability of the C++20 synchronization library, // which requires shared library support for various operations - // (see libcxx/src/atomic.cpp). + // (see libcxx/src/atomic.cpp). This includes , , + // , and notification functions on std::atomic. # define _LIBCPP_AVAILABILITY_SYNC // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier @@ -139,16 +150,21 @@ // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore // This controls the availability of the C++20 format library. - // The library is in development and not ABI stable yet. Currently - // P2216 is aiming to be retroactively accepted in C++20. This paper - // contains ABI breaking changes. + // The library is in development and not ABI stable yet. P2216 is + // retroactively accepted in C++20. This paper contains ABI breaking + // changes. # define _LIBCPP_AVAILABILITY_FORMAT // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format + // This controls whether the library claims to provide a default verbose + // termination function, and consequently whether the headers will try + // to use it when the mechanism isn't overriden at compile-time. +// # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY + #elif defined(__APPLE__) # define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(macos,strict,introduced=10.12))) \ __attribute__((availability(ios,strict,introduced=10.0))) \ __attribute__((availability(tvos,strict,introduced=10.0))) \ __attribute__((availability(watchos,strict,introduced=3.0))) @@ -160,24 +176,27 @@ # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex # endif + // Note: bad_optional_access & friends were not introduced in the matching + // macOS and iOS versions, so the version mismatch between macOS and others + // is intended. # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ - __attribute__((availability(macosx,strict,introduced=10.13))) \ - __attribute__((availability(ios,strict,introduced=11.0))) \ - __attribute__((availability(tvos,strict,introduced=11.0))) \ - __attribute__((availability(watchos,strict,introduced=4.0))) + __attribute__((availability(macos,strict,introduced=10.13))) \ + __attribute__((availability(ios,strict,introduced=12.0))) \ + __attribute__((availability(tvos,strict,introduced=12.0))) \ + __attribute__((availability(watchos,strict,introduced=5.0))) # define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \ _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \ _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(macos,strict,introduced=10.12))) \ __attribute__((availability(ios,strict,introduced=10.0))) \ __attribute__((availability(tvos,strict,introduced=10.0))) \ __attribute__((availability(watchos,strict,introduced=3.0))) # define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(macos,strict,introduced=10.12))) \ __attribute__((availability(ios,strict,introduced=10.0))) \ __attribute__((availability(tvos,strict,introduced=10.0))) \ __attribute__((availability(watchos,strict,introduced=3.0))) @@ -186,26 +205,26 @@ __attribute__((availability(ios,strict,introduced=6.0))) # define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(macos,strict,introduced=10.9))) \ __attribute__((availability(ios,strict,introduced=7.0))) # define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(macos,strict,introduced=10.9))) \ __attribute__((availability(ios,strict,introduced=7.0))) # define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(macos,strict,introduced=10.9))) \ __attribute__((availability(ios,strict,introduced=7.0))) # define _LIBCPP_AVAILABILITY_FILESYSTEM \ - __attribute__((availability(macosx,strict,introduced=10.15))) \ + __attribute__((availability(macos,strict,introduced=10.15))) \ __attribute__((availability(ios,strict,introduced=13.0))) \ __attribute__((availability(tvos,strict,introduced=13.0))) \ __attribute__((availability(watchos,strict,introduced=6.0))) # define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \ - _Pragma("clang attribute push(__attribute__((availability(macosx,strict,introduced=10.15))), apply_to=any(function,record))") \ - _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \ - _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \ _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))") # define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \ _Pragma("clang attribute pop") \ @@ -219,11 +238,11 @@ # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem # endif -# define _LIBCPP_AVAILABILITY_TO_CHARS \ - _LIBCPP_AVAILABILITY_FILESYSTEM +# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \ + __attribute__((unavailable)) # define _LIBCPP_AVAILABILITY_SYNC \ - __attribute__((availability(macosx,strict,introduced=11.0))) \ + __attribute__((availability(macos,strict,introduced=11.0))) \ __attribute__((availability(ios,strict,introduced=14.0))) \ __attribute__((availability(tvos,strict,introduced=14.0))) \ __attribute__((availability(watchos,strict,introduced=7.0))) @@ -237,13 +256,12 @@ # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore # endif - // This controls the availability of the C++20 format library. - // The library is in development and not ABI stable yet. Currently - // P2216 is aiming to be retroactively accepted in C++20. This paper - // contains ABI breaking changes. # define _LIBCPP_AVAILABILITY_FORMAT \ __attribute__((unavailable)) # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format + +# define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY + #else // ...New vendors can add availability markup here... diff --git a/gnu/llvm/libcxx/include/__bit/bit_cast.h b/gnu/llvm/libcxx/include/__bit/bit_cast.h new file mode 100644 index 00000000000..2ca4120c763 --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/bit_cast.h @@ -0,0 +1,36 @@ +// -*- 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___BIT_BIT_CAST_H +#define _LIBCPP___BIT_BIT_CAST_H + +#include <__config> +#include <__type_traits/is_trivially_copyable.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template + requires(sizeof(_ToType) == sizeof(_FromType) && + is_trivially_copyable_v<_ToType> && + is_trivially_copyable_v<_FromType>) +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { + return __builtin_bit_cast(_ToType, __from); +} + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BIT_CAST_H diff --git a/gnu/llvm/libcxx/include/__bit/bit_ceil.h b/gnu/llvm/libcxx/include/__bit/bit_ceil.h new file mode 100644 index 00000000000..a558d619427 --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/bit_ceil.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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___BIT_BIT_CEIL_H +#define _LIBCPP___BIT_BIT_CEIL_H + +#include <__assert> +#include <__bit/countl.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { + if (__t < 2) + return 1; + const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u)); + _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil"); + + if constexpr (sizeof(_Tp) >= sizeof(unsigned)) + return _Tp{1} << __n; + else { + const unsigned __extra = numeric_limits::digits - numeric_limits<_Tp>::digits; + const unsigned __retVal = 1u << (__n + __extra); + return (_Tp)(__retVal >> __extra); + } +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BIT_CEIL_H diff --git a/gnu/llvm/libcxx/include/__bit/bit_floor.h b/gnu/llvm/libcxx/include/__bit/bit_floor.h new file mode 100644 index 00000000000..b2e38092f2d --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/bit_floor.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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___BIT_BIT_FLOOR_H +#define _LIBCPP___BIT_BIT_FLOOR_H + +#include <__bit/bit_log2.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { + return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t); +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BIT_FLOOR_H diff --git a/gnu/llvm/libcxx/include/__bit/bit_log2.h b/gnu/llvm/libcxx/include/__bit/bit_log2.h new file mode 100644 index 00000000000..62936f67868 --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/bit_log2.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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___BIT_BIT_LOG2_H +#define _LIBCPP___BIT_BIT_LOG2_H + +#include <__bit/countl.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_log2(_Tp __t) noexcept { + return numeric_limits<_Tp>::digits - 1 - std::countl_zero(__t); +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BIT_LOG2_H diff --git a/gnu/llvm/libcxx/include/__bit/bit_width.h b/gnu/llvm/libcxx/include/__bit/bit_width.h new file mode 100644 index 00000000000..4381f227f5e --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/bit_width.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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___BIT_BIT_WIDTH_H +#define _LIBCPP___BIT_BIT_WIDTH_H + +#include <__bit/bit_log2.h> +#include <__concepts/arithmetic.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 20 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { + return __t == 0 ? 0 : std::__bit_log2(__t) + 1; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +#endif // _LIBCPP___BIT_BIT_WIDTH_H diff --git a/gnu/llvm/libcxx/include/__bit/blsr.h b/gnu/llvm/libcxx/include/__bit/blsr.h new file mode 100644 index 00000000000..de991e9adb3 --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/blsr.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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___BIT_BLSR_H +#define _LIBCPP___BIT_BLSR_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned __libcpp_blsr(unsigned __x) _NOEXCEPT { + return __x ^ (__x & -__x); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long __libcpp_blsr(unsigned long __x) _NOEXCEPT { + return __x ^ (__x & -__x); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long long __libcpp_blsr(unsigned long long __x) _NOEXCEPT { + return __x ^ (__x & -__x); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BLSR_H diff --git a/gnu/llvm/libcxx/include/__bit/byteswap.h b/gnu/llvm/libcxx/include/__bit/byteswap.h new file mode 100644 index 00000000000..6fa8d48bafa --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/byteswap.h @@ -0,0 +1,55 @@ +// -*- 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___BIT_BYTESWAP_H +#define _LIBCPP___BIT_BYTESWAP_H + +#include <__concepts/arithmetic.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +template +_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { + + if constexpr (sizeof(_Tp) == 1) { + return __val; + } else if constexpr (sizeof(_Tp) == 2) { + return __builtin_bswap16(__val); + } else if constexpr (sizeof(_Tp) == 4) { + return __builtin_bswap32(__val); + } else if constexpr (sizeof(_Tp) == 8) { + return __builtin_bswap64(__val); +#ifndef _LIBCPP_HAS_NO_INT128 + } else if constexpr (sizeof(_Tp) == 16) { +#if __has_builtin(__builtin_bswap128) + return __builtin_bswap128(__val); +#else + return static_cast<_Tp>(byteswap(static_cast(__val))) << 64 | + static_cast<_Tp>(byteswap(static_cast(__val >> 64))); +#endif // __has_builtin(__builtin_bswap128) +#endif // _LIBCPP_HAS_NO_INT128 + } else { + static_assert(sizeof(_Tp) == 0, "byteswap is unimplemented for integral types of this size"); + } +} + +#endif // _LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_BYTESWAP_H diff --git a/gnu/llvm/libcxx/include/__bit/countl.h b/gnu/llvm/libcxx/include/__bit/countl.h new file mode 100644 index 00000000000..86eaee0c1b3 --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/countl.h @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_COUNTL_H +#define _LIBCPP___BIT_COUNTL_H + +#include <__bit/rotate.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include <__type_traits/is_unsigned_integer.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } + +# ifndef _LIBCPP_HAS_NO_INT128 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(__uint128_t __x) _NOEXCEPT { + // The function is written in this form due to C++ constexpr limitations. + // The algorithm: + // - Test whether any bit in the high 64-bits is set + // - No bits set: + // - The high 64-bits contain 64 leading zeros, + // - Add the result of the low 64-bits. + // - Any bits set: + // - The number of leading zeros of the input is the number of leading + // zeros in the high 64-bits. + return ((__x >> 64) == 0) + ? (64 + __builtin_clzll(static_cast(__x))) + : __builtin_clzll(static_cast(__x >> 64)); +} +# endif // _LIBCPP_HAS_NO_INT128 + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +int __countl_zero(_Tp __t) _NOEXCEPT +{ + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type"); + if (__t == 0) + return numeric_limits<_Tp>::digits; + + if (sizeof(_Tp) <= sizeof(unsigned int)) + return std::__libcpp_clz(static_cast(__t)) + - (numeric_limits::digits - numeric_limits<_Tp>::digits); + else if (sizeof(_Tp) <= sizeof(unsigned long)) + return std::__libcpp_clz(static_cast(__t)) + - (numeric_limits::digits - numeric_limits<_Tp>::digits); + else if (sizeof(_Tp) <= sizeof(unsigned long long)) + return std::__libcpp_clz(static_cast(__t)) + - (numeric_limits::digits - numeric_limits<_Tp>::digits); + else + { + int __ret = 0; + int __iter = 0; + const unsigned int __ulldigits = numeric_limits::digits; + while (true) { + __t = std::__rotr(__t, __ulldigits); + if ((__iter = std::__countl_zero(static_cast(__t))) != __ulldigits) + break; + __ret += __iter; + } + return __ret + __iter; + } +} + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { + return std::__countl_zero(__t); +} + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { + return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_COUNTL_H diff --git a/gnu/llvm/libcxx/include/__bit/countr.h b/gnu/llvm/libcxx/include/__bit/countr.h new file mode 100644 index 00000000000..d3ca5b6c94f --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/countr.h @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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___BIT_COUNTR_H +#define _LIBCPP___BIT_COUNTR_H + +#include <__bit/rotate.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { + if (__t == 0) + return numeric_limits<_Tp>::digits; + + if (sizeof(_Tp) <= sizeof(unsigned int)) + return std::__libcpp_ctz(static_cast(__t)); + else if (sizeof(_Tp) <= sizeof(unsigned long)) + return std::__libcpp_ctz(static_cast(__t)); + else if (sizeof(_Tp) <= sizeof(unsigned long long)) + return std::__libcpp_ctz(static_cast(__t)); + else { + int __ret = 0; + const unsigned int __ulldigits = numeric_limits::digits; + while (static_cast(__t) == 0uLL) { + __ret += __ulldigits; + __t >>= __ulldigits; + } + return __ret + std::__libcpp_ctz(static_cast(__t)); + } +} + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { + return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_COUNTR_H diff --git a/gnu/llvm/libcxx/include/__bit/endian.h b/gnu/llvm/libcxx/include/__bit/endian.h new file mode 100644 index 00000000000..52635f2d249 --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/endian.h @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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___BIT_ENDIAN_H +#define _LIBCPP___BIT_ENDIAN_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 20 + +_LIBCPP_BEGIN_NAMESPACE_STD + +enum class endian { + little = 0xDEAD, + big = 0xFACE, +# if defined(_LIBCPP_LITTLE_ENDIAN) + native = little +# elif defined(_LIBCPP_BIG_ENDIAN) + native = big +# else + native = 0xCAFE +# endif +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +#endif // _LIBCPP___BIT_ENDIAN_H diff --git a/gnu/llvm/libcxx/include/__bit/has_single_bit.h b/gnu/llvm/libcxx/include/__bit/has_single_bit.h new file mode 100644 index 00000000000..b89f5995b32 --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/has_single_bit.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_HAS_SINGLE_BIT_H +#define _LIBCPP___BIT_HAS_SINGLE_BIT_H + +#include <__concepts/arithmetic.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 20 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { + return __t != 0 && (((__t & (__t - 1)) == 0)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_HAS_SINGLE_BIT_H diff --git a/gnu/llvm/libcxx/include/__bit/popcount.h b/gnu/llvm/libcxx/include/__bit/popcount.h new file mode 100644 index 00000000000..33b94cff712 --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/popcount.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// 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___BIT_POPCOUNT_H +#define _LIBCPP___BIT_POPCOUNT_H + +#include <__bit/rotate.h> +#include <__concepts/arithmetic.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { + if (sizeof(_Tp) <= sizeof(unsigned int)) + return std::__libcpp_popcount(static_cast(__t)); + else if (sizeof(_Tp) <= sizeof(unsigned long)) + return std::__libcpp_popcount(static_cast(__t)); + else if (sizeof(_Tp) <= sizeof(unsigned long long)) + return std::__libcpp_popcount(static_cast(__t)); + else { + int __ret = 0; + while (__t != 0) { + __ret += std::__libcpp_popcount(static_cast(__t)); + __t >>= numeric_limits::digits; + } + return __ret; + } +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___BIT_POPCOUNT_H diff --git a/gnu/llvm/libcxx/include/__bit/rotate.h b/gnu/llvm/libcxx/include/__bit/rotate.h new file mode 100644 index 00000000000..5aa7518b3c5 --- /dev/null +++ b/gnu/llvm/libcxx/include/__bit/rotate.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___BIT_ROTATE_H +#define _LIBCPP___BIT_ROTATE_H + +#include <__concepts/arithmetic.h> +#include <__config> +#include <__type_traits/is_unsigned_integer.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT +{ + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); + const unsigned int __dig = numeric_limits<_Tp>::digits; + if ((__cnt % __dig) == 0) + return __t; + return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig))); +} + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept { + const unsigned int __dig = numeric_limits<_Tp>::digits; + if ((__cnt % __dig) == 0) + return __t; + return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); +} + +template <__libcpp_unsigned_integer _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept { + return std::__rotr(__t, __cnt); +} + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___BIT_ROTATE_H diff --git a/gnu/llvm/libcxx/include/__bit_reference b/gnu/llvm/libcxx/include/__bit_reference index a02492c077d..26657491393 100644 --- a/gnu/llvm/libcxx/include/__bit_reference +++ b/gnu/llvm/libcxx/include/__bit_reference @@ -10,12 +10,20 @@ #ifndef _LIBCPP___BIT_REFERENCE #define _LIBCPP___BIT_REFERENCE +#include <__algorithm/copy_n.h> +#include <__algorithm/fill_n.h> +#include <__algorithm/min.h> +#include <__bit/countr.h> +#include <__bit/popcount.h> #include <__config> -#include <__bits> -#include +#include <__iterator/iterator_traits.h> +#include <__memory/construct_at.h> +#include <__memory/pointer_traits.h> +#include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -47,15 +55,17 @@ class __bit_reference friend class __bit_const_reference<_Cp>; friend class __bit_iterator<_Cp, false>; public: - _LIBCPP_INLINE_VISIBILITY + using __container = typename _Cp::__self; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference(const __bit_reference&) = default; - _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT {return static_cast(*__seg_ & __mask_);} - _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator ~() const _NOEXCEPT {return !static_cast(*this);} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(bool __x) _NOEXCEPT { if (__x) @@ -65,16 +75,26 @@ public: return *this; } - _LIBCPP_INLINE_VISIBILITY +#if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept { + if (__x) + *__seg_ |= __mask_; + else + *__seg_ &= ~__mask_; + return *this; + } +#endif + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT {return operator=(static_cast(__x));} - _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;} - _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT - {return __bit_iterator<_Cp, false>(__seg_, static_cast(__libcpp_ctz(__mask_)));} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT {*__seg_ ^= __mask_;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT + {return __bit_iterator<_Cp, false>(__seg_, static_cast(std::__libcpp_ctz(__mask_)));} private: - _LIBCPP_INLINE_VISIBILITY - __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT : __seg_(__s), __mask_(__m) {} }; @@ -84,7 +104,7 @@ class __bit_reference<_Cp, false> }; template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT { @@ -94,7 +114,7 @@ swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT { @@ -104,7 +124,7 @@ swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT { @@ -114,7 +134,7 @@ swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT { @@ -138,19 +158,19 @@ public: _LIBCPP_INLINE_VISIBILITY __bit_const_reference(const __bit_const_reference&) = default; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT : __seg_(__x.__seg_), __mask_(__x.__mask_) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT {return static_cast(*__seg_ & __mask_);} - _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT - {return __bit_iterator<_Cp, true>(__seg_, static_cast(__libcpp_ctz(__mask_)));} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT + {return __bit_iterator<_Cp, true>(__seg_, static_cast(std::__libcpp_ctz(__mask_)));} private: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT : __seg_(__s), __mask_(__m) {} __bit_const_reference& operator=(const __bit_const_reference&) = delete; @@ -159,12 +179,12 @@ private: // find template -__bit_iterator<_Cp, _IsConst> +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst> __find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) { typedef __bit_iterator<_Cp, _IsConst> _It; typedef typename _It::__storage_type __storage_type; - static const int __bits_per_word = _It::__bits_per_word; + const int __bits_per_word = _It::__bits_per_word; // do first partial word if (__first.__ctz_ != 0) { @@ -195,7 +215,7 @@ __find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type } template -__bit_iterator<_Cp, _IsConst> +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst> __find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) { typedef __bit_iterator<_Cp, _IsConst> _It; @@ -234,11 +254,11 @@ __find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, _IsConst> -find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) +find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value) { - if (static_cast(__value_)) + if (static_cast(__value)) return _VSTD::__find_bool_true(__first, static_cast(__last - __first)); return _VSTD::__find_bool_false(__first, static_cast(__last - __first)); } @@ -246,7 +266,7 @@ find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last // count template -typename __bit_iterator<_Cp, _IsConst>::difference_type +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __bit_iterator<_Cp, _IsConst>::difference_type __count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) { typedef __bit_iterator<_Cp, _IsConst> _It; @@ -277,7 +297,7 @@ __count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type } template -typename __bit_iterator<_Cp, _IsConst>::difference_type +_LIBCPP_HIDE_FROM_ABI typename __bit_iterator<_Cp, _IsConst>::difference_type __count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) { typedef __bit_iterator<_Cp, _IsConst> _It; @@ -310,9 +330,9 @@ __count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_typ template inline _LIBCPP_INLINE_VISIBILITY typename __bit_iterator<_Cp, _IsConst>::difference_type -count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) +count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value) { - if (static_cast(__value_)) + if (static_cast(__value)) return _VSTD::__count_bool_true(__first, static_cast(__last - __first)); return _VSTD::__count_bool_false(__first, static_cast(__last - __first)); } @@ -320,7 +340,7 @@ count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __las // fill_n template -void +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) { typedef __bit_iterator<_Cp, false> _It; @@ -338,7 +358,7 @@ __fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) } // do middle whole words __storage_type __nw = __n / __bits_per_word; - _VSTD::memset(_VSTD::__to_address(__first.__seg_), 0, __nw * sizeof(__storage_type)); + std::fill_n(std::__to_address(__first.__seg_), __nw, 0); __n -= __nw * __bits_per_word; // do last partial word if (__n > 0) @@ -350,7 +370,7 @@ __fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) } template -void +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) { typedef __bit_iterator<_Cp, false> _It; @@ -368,7 +388,8 @@ __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) } // do middle whole words __storage_type __nw = __n / __bits_per_word; - _VSTD::memset(_VSTD::__to_address(__first.__seg_), -1, __nw * sizeof(__storage_type)); + // __storage_type is always an unsigned type, so -1 sets all bits + std::fill_n(std::__to_address(__first.__seg_), __nw, static_cast<__storage_type>(-1)); __n -= __nw * __bits_per_word; // do last partial word if (__n > 0) @@ -380,13 +401,13 @@ __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void -fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_) +fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value) { if (__n > 0) { - if (__value_) + if (__value) _VSTD::__fill_n_true(__first, __n); else _VSTD::__fill_n_false(__first, __n); @@ -396,17 +417,17 @@ fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __v // fill template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void -fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_) +fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value) { - _VSTD::fill_n(__first, static_cast(__last - __first), __value_); + _VSTD::fill_n(__first, static_cast(__last - __first), __value); } // copy template -__bit_iterator<_Cp, false> +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { @@ -435,9 +456,7 @@ __copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCon // __first.__ctz_ == 0; // do middle words __storage_type __nw = __n / __bits_per_word; - _VSTD::memmove(_VSTD::__to_address(__result.__seg_), - _VSTD::__to_address(__first.__seg_), - __nw * sizeof(__storage_type)); + std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_)); __n -= __nw * __bits_per_word; __result.__seg_ += __nw; // do last word @@ -455,14 +474,14 @@ __copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCon } template -__bit_iterator<_Cp, false> +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { typedef __bit_iterator<_Cp, _IsConst> _In; typedef typename _In::difference_type difference_type; typedef typename _In::__storage_type __storage_type; - static const int __bits_per_word = _In::__bits_per_word; + const int __bits_per_word = _In::__bits_per_word; difference_type __n = __last - __first; if (__n > 0) { @@ -533,7 +552,7 @@ __copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsC } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { @@ -545,7 +564,7 @@ copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last // copy_backward template -__bit_iterator<_Cp, false> +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { @@ -576,9 +595,7 @@ __copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_C __storage_type __nw = __n / __bits_per_word; __result.__seg_ -= __nw; __last.__seg_ -= __nw; - _VSTD::memmove(_VSTD::__to_address(__result.__seg_), - _VSTD::__to_address(__last.__seg_), - __nw * sizeof(__storage_type)); + std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_)); __n -= __nw * __bits_per_word; // do last word if (__n > 0) @@ -594,7 +611,7 @@ __copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_C } template -__bit_iterator<_Cp, false> +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { @@ -680,7 +697,7 @@ __copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator< } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { @@ -712,7 +729,7 @@ move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCons // swap_ranges template -__bit_iterator<__C2, false> +_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, __bit_iterator<__C2, false> __result) { @@ -762,7 +779,7 @@ __swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, } template -__bit_iterator<__C2, false> +_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, __bit_iterator<__C2, false> __result) { @@ -887,14 +904,19 @@ struct __bit_array difference_type __size_; __storage_type __word_[_Np]; - _LIBCPP_INLINE_VISIBILITY static difference_type capacity() + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() {return static_cast(_Np * __bits_per_word);} - _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {} - _LIBCPP_INLINE_VISIBILITY iterator begin() + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) { + if (__libcpp_is_constant_evaluated()) { + for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i) + std::__construct_at(__word_ + __i, 0); + } + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() { return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); } - _LIBCPP_INLINE_VISIBILITY iterator end() + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() { return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, static_cast(__size_ % __bits_per_word)); @@ -902,7 +924,7 @@ struct __bit_array }; template -__bit_iterator<_Cp, false> +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) { typedef __bit_iterator<_Cp, false> _I1; @@ -953,14 +975,14 @@ rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, // equal template -bool +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { typedef __bit_iterator<_Cp, _IC1> _It; typedef typename _It::difference_type difference_type; typedef typename _It::__storage_type __storage_type; - static const int __bits_per_word = _It::__bits_per_word; + const int __bits_per_word = _It::__bits_per_word; difference_type __n = __last1 - __first1; if (__n > 0) { @@ -1035,14 +1057,14 @@ __equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> } template -bool +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { typedef __bit_iterator<_Cp, _IC1> _It; typedef typename _It::difference_type difference_type; typedef typename _It::__storage_type __storage_type; - static const int __bits_per_word = _It::__bits_per_word; + const int __bits_per_word = _It::__bits_per_word; difference_type __n = __last1 - __first1; if (__n > 0) { @@ -1078,7 +1100,7 @@ __equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { @@ -1095,20 +1117,24 @@ public: typedef typename _Cp::difference_type difference_type; typedef bool value_type; typedef __bit_iterator pointer; - typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference; +#ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL + typedef __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> > reference; +#else + using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >; +#endif typedef random_access_iterator_tag iterator_category; private: typedef typename _Cp::__storage_type __storage_type; - typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer, - typename _Cp::__storage_pointer>::type __storage_pointer; + typedef __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer> + __storage_pointer; static const unsigned __bits_per_word = _Cp::__bits_per_word; __storage_pointer __seg_; unsigned __ctz_; public: - _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 : __seg_(nullptr), __ctz_(0) #endif @@ -1119,7 +1145,7 @@ public: // When _IsConst=true, this is a converting constructor; // the copy and move constructors are implicitly generated // and trivial. - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} @@ -1128,17 +1154,19 @@ public: // the implicit generation of a defaulted one is deprecated. // When _IsConst=true, the assignment operators are // implicitly generated and trivial. - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) { __seg_ = __it.__seg_; __ctz_ = __it.__ctz_; return *this; } - _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT - {return reference(__seg_, __storage_type(1) << __ctz_);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT { + return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >( + __seg_, __storage_type(1) << __ctz_); + } - _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++() + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() { if (__ctz_ != __bits_per_word-1) ++__ctz_; @@ -1150,14 +1178,14 @@ public: return *this; } - _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) { __bit_iterator __tmp = *this; ++(*this); return __tmp; } - _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--() + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() { if (__ctz_ != 0) --__ctz_; @@ -1169,14 +1197,14 @@ public: return *this; } - _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) { __bit_iterator __tmp = *this; --(*this); return __tmp; } - _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) { if (__n >= 0) __seg_ += (__n + __ctz_) / __bits_per_word; @@ -1188,55 +1216,55 @@ public: return *this; } - _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) { return *this += -__n; } - _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const { __bit_iterator __t(*this); __t += __n; return __t; } - _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const { __bit_iterator __t(*this); __t -= __n; return __t; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y) {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;} - _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const {return *(*this + __n);} - _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;} - _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) {return !(__x == __y);} - _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);} - _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) {return __y < __x;} - _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) {return !(__y < __x);} - _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) {return !(__x < __y);} private: - _LIBCPP_INLINE_VISIBILITY - __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT : __seg_(__s), __ctz_(__ctz) {} friend typename _Cp::__self; @@ -1245,26 +1273,44 @@ private: friend class __bit_const_reference<_Cp>; friend class __bit_iterator<_Cp, true>; template friend struct __bit_array; - template friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); - template friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); - template friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first, + __bit_iterator<_Dp, _IC> __last, + __bit_iterator<_Dp, false> __result); template friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>, __bit_iterator<__C1, false>, __bit_iterator<__C2, false>); @@ -1274,23 +1320,34 @@ private: template friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>, __bit_iterator<__C1, false>, __bit_iterator<__C2, false>); - template friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>, - __bit_iterator<_Dp, false>, - __bit_iterator<_Dp, false>); - template friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC2>); - template friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC2>); - template friend bool equal(__bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC2>); - template friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, - typename _Dp::size_type); - template friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, - typename _Dp::size_type); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>, + __bit_iterator<_Dp, false>, + __bit_iterator<_Dp, false>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend bool equal(__bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC1>, + __bit_iterator<_Dp, _IC2>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 + friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); template friend typename __bit_iterator<_Dp, _IC>::difference_type + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); template friend typename __bit_iterator<_Dp, _IC>::difference_type __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); diff --git a/gnu/llvm/libcxx/include/__bsd_locale_defaults.h b/gnu/llvm/libcxx/include/__bsd_locale_defaults.h index 2ace2a21cb0..4d990482d4a 100644 --- a/gnu/llvm/libcxx/include/__bsd_locale_defaults.h +++ b/gnu/llvm/libcxx/include/__bsd_locale_defaults.h @@ -1,5 +1,5 @@ // -*- C++ -*- -//===---------------------- __bsd_locale_defaults.h -----------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,11 +11,11 @@ // we will define the mapping from an internal macro to the real BSD symbol. //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_BSD_LOCALE_DEFAULTS_H -#define _LIBCPP_BSD_LOCALE_DEFAULTS_H +#ifndef _LIBCPP___BSD_LOCALE_DEFAULTS_H +#define _LIBCPP___BSD_LOCALE_DEFAULTS_H #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif #define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc) @@ -33,4 +33,4 @@ #define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__) #define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__) -#endif // _LIBCPP_BSD_LOCALE_DEFAULTS_H +#endif // _LIBCPP___BSD_LOCALE_DEFAULTS_H diff --git a/gnu/llvm/libcxx/include/__bsd_locale_fallbacks.h b/gnu/llvm/libcxx/include/__bsd_locale_fallbacks.h index ed0eabf60ec..9abd7e7e5ff 100644 --- a/gnu/llvm/libcxx/include/__bsd_locale_fallbacks.h +++ b/gnu/llvm/libcxx/include/__bsd_locale_fallbacks.h @@ -1,5 +1,5 @@ // -*- C++ -*- -//===---------------------- __bsd_locale_fallbacks.h ----------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,15 +10,14 @@ // of those functions for non-BSD platforms. //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H -#define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H +#ifndef _LIBCPP___BSD_LOCALE_FALLBACKS_H +#define _LIBCPP___BSD_LOCALE_FALLBACKS_H -#include #include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -30,6 +29,7 @@ decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) return MB_CUR_MAX; } +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_btowc_l(int __c, locale_t __l) { @@ -88,6 +88,7 @@ size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __libcpp_locale_guard __current(__l); return mbrlen(__s, __n, __ps); } +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS inline _LIBCPP_INLINE_VISIBILITY lconv *__libcpp_localeconv_l(locale_t __l) @@ -96,6 +97,7 @@ lconv *__libcpp_localeconv_l(locale_t __l) return localeconv(); } +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, mbstate_t *__ps, locale_t __l) @@ -103,8 +105,9 @@ size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, __libcpp_locale_guard __current(__l); return mbsrtowcs(__dest, __src, __len, __ps); } +#endif -inline +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -114,7 +117,7 @@ int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__forma return __res; } -inline +inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -124,7 +127,7 @@ int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { return __res; } -inline +inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -136,4 +139,4 @@ int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H +#endif // _LIBCPP___BSD_LOCALE_FALLBACKS_H diff --git a/gnu/llvm/libcxx/include/__charconv/chars_format.h b/gnu/llvm/libcxx/include/__charconv/chars_format.h new file mode 100644 index 00000000000..695bd873189 --- /dev/null +++ b/gnu/llvm/libcxx/include/__charconv/chars_format.h @@ -0,0 +1,77 @@ +// -*- 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___CHARCONV_CHARS_FORMAT_H +#define _LIBCPP___CHARCONV_CHARS_FORMAT_H + +#include <__config> +#include <__utility/to_underlying.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +enum class _LIBCPP_ENUM_VIS chars_format +{ + scientific = 0x1, + fixed = 0x2, + hex = 0x4, + general = fixed | scientific +}; + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator~(chars_format __x) { + return chars_format(~_VSTD::__to_underlying(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator&(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) & + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator|(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) | + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator^(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) ^ + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& +operator&=(chars_format& __x, chars_format __y) { + __x = __x & __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& +operator|=(chars_format& __x, chars_format __y) { + __x = __x | __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& +operator^=(chars_format& __x, chars_format __y) { + __x = __x ^ __y; + return __x; +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_CHARS_FORMAT_H diff --git a/gnu/llvm/libcxx/include/__charconv/from_chars_result.h b/gnu/llvm/libcxx/include/__charconv/from_chars_result.h new file mode 100644 index 00000000000..05ffe1485ca --- /dev/null +++ b/gnu/llvm/libcxx/include/__charconv/from_chars_result.h @@ -0,0 +1,37 @@ +// -*- 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___CHARCONV_FROM_CHARS_RESULT_H +#define _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H + +#include <__config> +#include <__errc> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +struct _LIBCPP_TYPE_VIS from_chars_result +{ + const char* ptr; + errc ec; +# if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default; +# endif +}; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H diff --git a/gnu/llvm/libcxx/include/__charconv/tables.h b/gnu/llvm/libcxx/include/__charconv/tables.h new file mode 100644 index 00000000000..9b82440348b --- /dev/null +++ b/gnu/llvm/libcxx/include/__charconv/tables.h @@ -0,0 +1,154 @@ +// -*- 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___CHARCONV_TABLES +#define _LIBCPP___CHARCONV_TABLES + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +namespace __itoa { + +inline constexpr char __base_2_lut[64] = { + '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '1', '0', '0', '0', '1', '1', '0', '1', '0', '0', '0', '1', + '0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '0', '1', '0', '0', '1', '1', '0', '1', '0', + '1', '0', '1', '1', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '1', '0', '1', '1', '1', '1'}; + +inline constexpr char __base_8_lut[128] = { + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '1', '0', '1', '1', '1', '2', + '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', + '2', '6', '2', '7', '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '4', '0', + '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '5', '0', '5', '1', '5', '2', '5', '3', + '5', '4', '5', '5', '5', '6', '5', '7', '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', + '6', '7', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7'}; + +inline constexpr char __base_16_lut[512] = { + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', '0', 'a', '0', + 'b', '0', 'c', '0', 'd', '0', 'e', '0', 'f', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', + '1', '7', '1', '8', '1', '9', '1', 'a', '1', 'b', '1', 'c', '1', 'd', '1', 'e', '1', 'f', '2', '0', '2', '1', '2', + '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', '2', 'a', '2', 'b', '2', 'c', '2', 'd', + '2', 'e', '2', 'f', '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', + '9', '3', 'a', '3', 'b', '3', 'c', '3', 'd', '3', 'e', '3', 'f', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', + '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '4', 'a', '4', 'b', '4', 'c', '4', 'd', '4', 'e', '4', 'f', '5', + '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', '5', 'a', '5', 'b', + '5', 'c', '5', 'd', '5', 'e', '5', 'f', '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', + '7', '6', '8', '6', '9', '6', 'a', '6', 'b', '6', 'c', '6', 'd', '6', 'e', '6', 'f', '7', '0', '7', '1', '7', '2', + '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '7', 'a', '7', 'b', '7', 'c', '7', 'd', '7', + 'e', '7', 'f', '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', + '8', 'a', '8', 'b', '8', 'c', '8', 'd', '8', 'e', '8', 'f', '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', + '5', '9', '6', '9', '7', '9', '8', '9', '9', '9', 'a', '9', 'b', '9', 'c', '9', 'd', '9', 'e', '9', 'f', 'a', '0', + 'a', '1', 'a', '2', 'a', '3', 'a', '4', 'a', '5', 'a', '6', 'a', '7', 'a', '8', 'a', '9', 'a', 'a', 'a', 'b', 'a', + 'c', 'a', 'd', 'a', 'e', 'a', 'f', 'b', '0', 'b', '1', 'b', '2', 'b', '3', 'b', '4', 'b', '5', 'b', '6', 'b', '7', + 'b', '8', 'b', '9', 'b', 'a', 'b', 'b', 'b', 'c', 'b', 'd', 'b', 'e', 'b', 'f', 'c', '0', 'c', '1', 'c', '2', 'c', + '3', 'c', '4', 'c', '5', 'c', '6', 'c', '7', 'c', '8', 'c', '9', 'c', 'a', 'c', 'b', 'c', 'c', 'c', 'd', 'c', 'e', + 'c', 'f', 'd', '0', 'd', '1', 'd', '2', 'd', '3', 'd', '4', 'd', '5', 'd', '6', 'd', '7', 'd', '8', 'd', '9', 'd', + 'a', 'd', 'b', 'd', 'c', 'd', 'd', 'd', 'e', 'd', 'f', 'e', '0', 'e', '1', 'e', '2', 'e', '3', 'e', '4', 'e', '5', + 'e', '6', 'e', '7', 'e', '8', 'e', '9', 'e', 'a', 'e', 'b', 'e', 'c', 'e', 'd', 'e', 'e', 'e', 'f', 'f', '0', 'f', + '1', 'f', '2', 'f', '3', 'f', '4', 'f', '5', 'f', '6', 'f', '7', 'f', '8', 'f', '9', 'f', 'a', 'f', 'b', 'f', 'c', + 'f', 'd', 'f', 'e', 'f', 'f'}; + +inline constexpr uint32_t __pow10_32[10] = { + UINT32_C(0), UINT32_C(10), UINT32_C(100), UINT32_C(1000), UINT32_C(10000), + UINT32_C(100000), UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), UINT32_C(1000000000)}; + +inline constexpr uint64_t __pow10_64[20] = {UINT64_C(0), + UINT64_C(10), + UINT64_C(100), + UINT64_C(1000), + UINT64_C(10000), + UINT64_C(100000), + UINT64_C(1000000), + UINT64_C(10000000), + UINT64_C(100000000), + UINT64_C(1000000000), + UINT64_C(10000000000), + UINT64_C(100000000000), + UINT64_C(1000000000000), + UINT64_C(10000000000000), + UINT64_C(100000000000000), + UINT64_C(1000000000000000), + UINT64_C(10000000000000000), + UINT64_C(100000000000000000), + UINT64_C(1000000000000000000), + UINT64_C(10000000000000000000)}; + +# ifndef _LIBCPP_HAS_NO_INT128 +inline constexpr int __pow10_128_offset = 0; +inline constexpr __uint128_t __pow10_128[40] = { + UINT64_C(0), + UINT64_C(10), + UINT64_C(100), + UINT64_C(1000), + UINT64_C(10000), + UINT64_C(100000), + UINT64_C(1000000), + UINT64_C(10000000), + UINT64_C(100000000), + UINT64_C(1000000000), + UINT64_C(10000000000), + UINT64_C(100000000000), + UINT64_C(1000000000000), + UINT64_C(10000000000000), + UINT64_C(100000000000000), + UINT64_C(1000000000000000), + UINT64_C(10000000000000000), + UINT64_C(100000000000000000), + UINT64_C(1000000000000000000), + UINT64_C(10000000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(100000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(1000000000000000000), + __uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000000000), + (__uint128_t(UINT64_C(10000000000000000000)) * UINT64_C(10000000000000000000)) * 10}; +# endif + +inline constexpr char __digits_base_10[200] = { + // clang-format off + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', + '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', + '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', + '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', + '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', + '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', + '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', + '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', + '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', + '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'}; +// clang-format on + +} // namespace __itoa + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_TABLES diff --git a/gnu/llvm/libcxx/include/__charconv/to_chars_base_10.h b/gnu/llvm/libcxx/include/__charconv/to_chars_base_10.h new file mode 100644 index 00000000000..fc7fb76e3e9 --- /dev/null +++ b/gnu/llvm/libcxx/include/__charconv/to_chars_base_10.h @@ -0,0 +1,185 @@ +// -*- 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___CHARCONV_TO_CHARS_BASE_10_H +#define _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H + +#include <__algorithm/copy_n.h> +#include <__charconv/tables.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +namespace __itoa { + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append1(char* __first, uint32_t __value) noexcept { + *__first = '0' + static_cast(__value); + return __first + 1; +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append2(char* __first, uint32_t __value) noexcept { + return std::copy_n(&__digits_base_10[__value * 2], 2, __first); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append3(char* __first, uint32_t __value) noexcept { + return __itoa::__append2(__itoa::__append1(__first, __value / 100), __value % 100); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append4(char* __first, uint32_t __value) noexcept { + return __itoa::__append2(__itoa::__append2(__first, __value / 100), __value % 100); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append5(char* __first, uint32_t __value) noexcept { + return __itoa::__append4(__itoa::__append1(__first, __value / 10000), __value % 10000); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append6(char* __first, uint32_t __value) noexcept { + return __itoa::__append4(__itoa::__append2(__first, __value / 10000), __value % 10000); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append7(char* __first, uint32_t __value) noexcept { + return __itoa::__append6(__itoa::__append1(__first, __value / 1000000), __value % 1000000); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append8(char* __first, uint32_t __value) noexcept { + return __itoa::__append6(__itoa::__append2(__first, __value / 1000000), __value % 1000000); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __append9(char* __first, uint32_t __value) noexcept { + return __itoa::__append8(__itoa::__append1(__first, __value / 100000000), __value % 100000000); +} + +template +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __append10(char* __first, _Tp __value) noexcept { + return __itoa::__append8(__itoa::__append2(__first, static_cast(__value / 100000000)), + static_cast(__value % 100000000)); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u32(char* __first, uint32_t __value) noexcept { + if (__value < 1000000) { + if (__value < 10000) { + if (__value < 100) { + // 0 <= __value < 100 + if (__value < 10) + return __itoa::__append1(__first, __value); + return __itoa::__append2(__first, __value); + } + // 100 <= __value < 10'000 + if (__value < 1000) + return __itoa::__append3(__first, __value); + return __itoa::__append4(__first, __value); + } + + // 10'000 <= __value < 1'000'000 + if (__value < 100000) + return __itoa::__append5(__first, __value); + return __itoa::__append6(__first, __value); + } + + // __value => 1'000'000 + if (__value < 100000000) { + // 1'000'000 <= __value < 100'000'000 + if (__value < 10000000) + return __itoa::__append7(__first, __value); + return __itoa::__append8(__first, __value); + } + + // 100'000'000 <= __value < max + if (__value < 1000000000) + return __itoa::__append9(__first, __value); + return __itoa::__append10(__first, __value); +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(char* __buffer, uint64_t __value) noexcept { + if (__value <= UINT32_MAX) + return __itoa::__base_10_u32(__buffer, static_cast(__value)); + + // Numbers in the range UINT32_MAX <= val < 10'000'000'000 always contain 10 + // digits and are outputted after this if statement. + if (__value >= 10000000000) { + // This function properly deterimines the first non-zero leading digit. + __buffer = __itoa::__base_10_u32(__buffer, static_cast(__value / 10000000000)); + __value %= 10000000000; + } + return __itoa::__append10(__buffer, __value); +} + +# ifndef _LIBCPP_HAS_NO_INT128 +/// \returns 10^\a exp +/// +/// \pre \a exp [19, 39] +/// +/// \note The lookup table contains a partial set of exponents limiting the +/// range that can be used. However the range is sufficient for +/// \ref __base_10_u128. +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline __uint128_t __pow_10(int __exp) noexcept { + _LIBCPP_ASSERT(__exp >= __pow10_128_offset, "Index out of bounds"); + return __pow10_128[__exp - __pow10_128_offset]; +} + +_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(char* __buffer, __uint128_t __value) noexcept { + _LIBCPP_ASSERT( + __value > numeric_limits::max(), "The optimizations for this algorithm fail when this isn't true."); + + // Unlike the 64 to 32 bit case the 128 bit case the "upper half" can't be + // stored in the "lower half". Instead we first need to handle the top most + // digits separately. + // + // Maximum unsigned values + // 64 bit 18'446'744'073'709'551'615 (20 digits) + // 128 bit 340'282'366'920'938'463'463'374'607'431'768'211'455 (39 digits) + // step 1 ^ ([0-1] digits) + // step 2 ^^^^^^^^^^^^^^^^^^^^^^^^^ ([0-19] digits) + // step 3 ^^^^^^^^^^^^^^^^^^^^^^^^^ (19 digits) + if (__value >= __itoa::__pow_10(38)) { + // step 1 + __buffer = __itoa::__append1(__buffer, static_cast(__value / __itoa::__pow_10(38))); + __value %= __itoa::__pow_10(38); + + // step 2 always 19 digits. + // They are handled here since leading zeros need to be appended to the buffer, + __buffer = __itoa::__append9(__buffer, static_cast(__value / __itoa::__pow_10(29))); + __value %= __itoa::__pow_10(29); + __buffer = __itoa::__append10(__buffer, static_cast(__value / __itoa::__pow_10(19))); + __value %= __itoa::__pow_10(19); + } + else { + // step 2 + // This version needs to determine the position of the leading non-zero digit. + __buffer = __base_10_u64(__buffer, static_cast(__value / __itoa::__pow_10(19))); + __value %= __itoa::__pow_10(19); + } + + // Step 3 + __buffer = __itoa::__append9(__buffer, static_cast(__value / 10000000000)); + __buffer = __itoa::__append10(__buffer, static_cast(__value % 10000000000)); + + return __buffer; +} +# endif +} // namespace __itoa + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H diff --git a/gnu/llvm/libcxx/include/__charconv/to_chars_result.h b/gnu/llvm/libcxx/include/__charconv/to_chars_result.h new file mode 100644 index 00000000000..2eb4098dfc4 --- /dev/null +++ b/gnu/llvm/libcxx/include/__charconv/to_chars_result.h @@ -0,0 +1,37 @@ +// -*- 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___CHARCONV_TO_CHARS_RESULT_H +#define _LIBCPP___CHARCONV_TO_CHARS_RESULT_H + +#include <__config> +#include <__errc> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +struct _LIBCPP_TYPE_VIS to_chars_result +{ + char* ptr; + errc ec; +# if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default; +# endif +}; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHARCONV_TO_CHARS_RESULT_H diff --git a/gnu/llvm/libcxx/include/__chrono/calendar.h b/gnu/llvm/libcxx/include/__chrono/calendar.h new file mode 100644 index 00000000000..d3762a631c9 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/calendar.h @@ -0,0 +1,44 @@ +// -*- 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___CHRONO_CALENDAR_H +#define _LIBCPP___CHRONO_CALENDAR_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +struct local_t {}; +template +using local_time = time_point; +using local_seconds = local_time; +using local_days = local_time; + +struct last_spec { _LIBCPP_HIDE_FROM_ABI explicit last_spec() = default; }; +inline constexpr last_spec last{}; + + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_CALENDAR_H diff --git a/gnu/llvm/libcxx/include/__chrono/convert_to_timespec.h b/gnu/llvm/libcxx/include/__chrono/convert_to_timespec.h new file mode 100644 index 00000000000..fab07f2567d --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/convert_to_timespec.h @@ -0,0 +1,56 @@ +// -*- 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___CHRONO_CONVERT_TO_TIMESPEC_H +#define _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H + +#include <__chrono/duration.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Convert a nanoseconds duration to the given TimeSpec type, which must have +// the same properties as std::timespec. +template +_LIBCPP_HIDE_FROM_ABI inline +_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + seconds __s = duration_cast(__ns); + _TimeSpec __ts; + typedef decltype(__ts.tv_sec) __ts_sec; + const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); + + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + __ts.tv_nsec = static_cast((__ns - __s).count()); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = 999999999; // (10^9 - 1) + } + + return __ts; +} + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H diff --git a/gnu/llvm/libcxx/include/__chrono/convert_to_tm.h b/gnu/llvm/libcxx/include/__chrono/convert_to_tm.h new file mode 100644 index 00000000000..36846b3f714 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/convert_to_tm.h @@ -0,0 +1,127 @@ +// -*- 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___CHRONO_CONVERT_TO_TM_H +#define _LIBCPP___CHRONO_CONVERT_TO_TM_H + +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/hh_mm_ss.h> +#include <__chrono/month.h> +#include <__chrono/month_weekday.h> +#include <__chrono/monthday.h> +#include <__chrono/statically_widen.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__chrono/weekday.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__chrono/year_month_day.h> +#include <__chrono/year_month_weekday.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__memory/addressof.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// Conerts a chrono date and weekday to a given _Tm type. +// +// This is an implementation detail for the function +// template +// _Tm __convert_to_tm(const _ChronoT& __value) +// +// This manually converts the two values to the proper type. It is possible to +// convert from sys_days to time_t and then to _Tm. But this leads to the Y2K +// bug when time_t is a 32-bit signed integer. Chrono considers years beyond +// the year 2038 valid, so instead do the transformation manually. +template + requires(same_as<_Date, chrono::year_month_day> || same_as<_Date, chrono::year_month_day_last>) +_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _Date& __date, chrono::weekday __weekday) { + _Tm __result = {}; +# ifdef __GLIBC__ + __result.tm_zone = "UTC"; +# endif + __result.tm_year = static_cast(__date.year()) - 1900; + __result.tm_mon = static_cast(__date.month()) - 1; + __result.tm_mday = static_cast(__date.day()); + __result.tm_wday = static_cast(__weekday.c_encoding()); + __result.tm_yday = + (static_cast(__date) - + static_cast(chrono::year_month_day{__date.year(), chrono::January, chrono::day{1}})) + .count(); + + return __result; +} + +// Convert a chrono (calendar) time point, or dururation to the given _Tm type, +// which must have the same properties as std::tm. +template +_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) { + _Tm __result = {}; +# ifdef __GLIBC__ + __result.tm_zone = "UTC"; +# endif + + if constexpr (chrono::__is_duration<_ChronoT>::value) { + // [time.format]/6 + // ... However, if a flag refers to a "time of day" (e.g. %H, %I, %p, + // etc.), then a specialization of duration is interpreted as the time of + // day elapsed since midnight. + uint64_t __sec = chrono::duration_cast(__value).count(); + __sec %= 24 * 3600; + __result.tm_hour = __sec / 3600; + __sec %= 3600; + __result.tm_min = __sec / 60; + __result.tm_sec = __sec % 60; + } else if constexpr (same_as<_ChronoT, chrono::day>) + __result.tm_mday = static_cast(__value); + else if constexpr (same_as<_ChronoT, chrono::month>) + __result.tm_mon = static_cast(__value) - 1; + else if constexpr (same_as<_ChronoT, chrono::year>) + __result.tm_year = static_cast(__value) - 1900; + else if constexpr (same_as<_ChronoT, chrono::weekday>) + __result.tm_wday = __value.c_encoding(); + else if constexpr (same_as<_ChronoT, chrono::weekday_indexed> || same_as<_ChronoT, chrono::weekday_last>) + __result.tm_wday = __value.weekday().c_encoding(); + else if constexpr (same_as<_ChronoT, chrono::month_day>) { + __result.tm_mday = static_cast(__value.day()); + __result.tm_mon = static_cast(__value.month()) - 1; + } else if constexpr (same_as<_ChronoT, chrono::month_day_last>) { + __result.tm_mon = static_cast(__value.month()) - 1; + } else if constexpr (same_as<_ChronoT, chrono::month_weekday> || same_as<_ChronoT, chrono::month_weekday_last>) { + __result.tm_wday = __value.weekday_indexed().weekday().c_encoding(); + __result.tm_mon = static_cast(__value.month()) - 1; + } else if constexpr (same_as<_ChronoT, chrono::year_month>) { + __result.tm_year = static_cast(__value.year()) - 1900; + __result.tm_mon = static_cast(__value.month()) - 1; + } else if constexpr (same_as<_ChronoT, chrono::year_month_day> || same_as<_ChronoT, chrono::year_month_day_last>) { + return std::__convert_to_tm<_Tm>( + chrono::year_month_day{__value}, chrono::weekday{static_cast(__value)}); + } else if constexpr (same_as<_ChronoT, chrono::year_month_weekday> || + same_as<_ChronoT, chrono::year_month_weekday_last>) { + return std::__convert_to_tm<_Tm>(chrono::year_month_day{static_cast(__value)}, __value.weekday()); + } else + static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization"); + + return __result; +} + +#endif //if _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_CONVERT_TO_TM_H diff --git a/gnu/llvm/libcxx/include/__chrono/day.h b/gnu/llvm/libcxx/include/__chrono/day.h new file mode 100644 index 00000000000..35ecfcf9e5b --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/day.h @@ -0,0 +1,84 @@ +// -*- 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___CHRONO_DAY_H +#define _LIBCPP___CHRONO_DAY_H + +#include <__chrono/duration.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class day { +private: + unsigned char __d_; +public: + _LIBCPP_HIDE_FROM_ABI day() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept : __d_(static_cast(__val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++() noexcept { ++__d_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator--() noexcept { --__d_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI constexpr day& operator+=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr day& operator-=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __d_ >= 1 && __d_ <= 31; } + }; + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const day& __lhs, const day& __rhs) noexcept +{ return static_cast(__lhs) == static_cast(__rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const day& __lhs, const day& __rhs) noexcept { + return static_cast(__lhs) <=> static_cast(__rhs); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day operator+ (const day& __lhs, const days& __rhs) noexcept +{ return day(static_cast(__lhs) + __rhs.count()); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day operator+ (const days& __lhs, const day& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day operator- (const day& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +days operator-(const day& __lhs, const day& __rhs) noexcept +{ return days(static_cast(static_cast(__lhs)) - + static_cast(static_cast(__rhs))); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day& day::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +day& day::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_DAY_H diff --git a/gnu/llvm/libcxx/include/__chrono/duration.h b/gnu/llvm/libcxx/include/__chrono/duration.h new file mode 100644 index 00000000000..afcc38b5cfc --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/duration.h @@ -0,0 +1,622 @@ +// -*- 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___CHRONO_DURATION_H +#define _LIBCPP___CHRONO_DURATION_H + +#include <__config> +#include <__type_traits/common_type.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_floating_point.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template > class _LIBCPP_TEMPLATE_VIS duration; + +template +struct __is_duration : false_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +template +struct __is_duration > : true_type {}; + +} // namespace chrono + +template +struct _LIBCPP_TEMPLATE_VIS common_type, + chrono::duration<_Rep2, _Period2> > +{ + typedef chrono::duration::type, + typename __ratio_gcd<_Period1, _Period2>::type> type; +}; + +namespace chrono { + +// duration_cast + +template ::type, + bool = _Period::num == 1, + bool = _Period::den == 1> +struct __duration_cast; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + return _ToDuration(static_cast(__fd.count())); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); + } +}; + +template +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + _ToDuration operator()(const _FromDuration& __fd) const + { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) + / static_cast<_Ct>(_Period::den))); + } +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +duration_cast(const duration<_Rep, _Period>& __fd) +{ + return __duration_cast, _ToDuration>()(__fd); +} + +template +struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {}; + +#if _LIBCPP_STD_VER > 14 +template +inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; +#endif + +template +struct _LIBCPP_TEMPLATE_VIS duration_values +{ +public: + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} +}; + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +floor(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); + if (__t > __d) + __t = __t - _ToDuration{1}; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +ceil(const duration<_Rep, _Period>& __d) +{ + _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); + if (__t < __d) + __t = __t + _ToDuration{1}; + return __t; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + _ToDuration +>::type +round(const duration<_Rep, _Period>& __d) +{ + _ToDuration __lower = chrono::floor<_ToDuration>(__d); + _ToDuration __upper = __lower + _ToDuration{1}; + auto __lowerDiff = __d - __lower; + auto __upperDiff = __upper - __d; + if (__lowerDiff < __upperDiff) + return __lower; + if (__lowerDiff > __upperDiff) + return __upper; + return __lower.count() & 1 ? __upper : __lower; +} +#endif + +// duration + +template +class _LIBCPP_TEMPLATE_VIS duration +{ + static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); + static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); + static_assert(_Period::num > 0, "duration period must be positive"); + + template + struct __no_overflow + { + private: + static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; + static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; + static const intmax_t __n1 = _R1::num / __gcd_n1_n2; + static const intmax_t __d1 = _R1::den / __gcd_d1_d2; + static const intmax_t __n2 = _R2::num / __gcd_n1_n2; + static const intmax_t __d2 = _R2::den / __gcd_d1_d2; + static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); + + template + struct __mul // __overflow == false + { + static const intmax_t value = _Xp * _Yp; + }; + + template + struct __mul<_Xp, _Yp, true> + { + static const intmax_t value = 1; + }; + + public: + static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); + typedef ratio<__mul<__n1, __d2, !value>::value, + __mul<__n2, __d1, !value>::value> type; + }; + +public: + typedef _Rep rep; + typedef typename _Period::type period; +private: + rep __rep_; +public: + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +#ifndef _LIBCPP_CXX03_LANG + duration() = default; +#else + duration() {} +#endif + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + explicit duration(const _Rep2& __r, + typename enable_if + < + is_convertible::value && + (treat_as_floating_point::value || + !treat_as_floating_point<_Rep2>::value) + >::type* = nullptr) + : __rep_(__r) {} + + // conversions + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + duration(const duration<_Rep2, _Period2>& __d, + typename enable_if + < + __no_overflow<_Period2, period>::value && ( + treat_as_floating_point::value || + (__no_overflow<_Period2, period>::type::den == 1 && + !treat_as_floating_point<_Rep2>::value)) + >::type* = nullptr) + : __rep_(chrono::duration_cast(__d).count()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type::type operator+() const {return typename common_type::type(*this);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type::type operator-() const {return typename common_type::type(-__rep_);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++() {++__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator++(int) {return duration(__rep_++);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator--() {--__rep_; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator--(int) {return duration(__rep_--);} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator*=(const rep& __rhs) {__rep_ *= __rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator/=(const rep& __rhs) {__rep_ /= __rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const rep& __rhs) {__rep_ %= __rhs; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const duration& __rhs) {__rep_ %= __rhs.count(); return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values::zero());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values::max());} +}; + +typedef duration nanoseconds; +typedef duration microseconds; +typedef duration milliseconds; +typedef duration seconds; +typedef duration< long, ratio< 60> > minutes; +typedef duration< long, ratio<3600> > hours; +#if _LIBCPP_STD_VER > 17 +typedef duration< int, ratio_multiply, hours::period>> days; +typedef duration< int, ratio_multiply, days::period>> weeks; +typedef duration< int, ratio_multiply, days::period>> years; +typedef duration< int, ratio_divide>> months; +#endif +// Duration == + +template +struct __duration_eq +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() == _Ct(__rhs).count(); + } +}; + +template +struct __duration_eq<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() == __rhs.count();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_eq, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration != + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// Duration < + +template +struct __duration_lt +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const + { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() < _Ct(__rhs).count(); + } +}; + +template +struct __duration_lt<_LhsDuration, _LhsDuration> +{ + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const + {return __lhs.count() < __rhs.count();} +}; + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __duration_lt, duration<_Rep2, _Period2> >()(__lhs, __rhs); +} + +// Duration > + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return __rhs < __lhs; +} + +// Duration <= + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// Duration >= + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +bool +operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// Duration + + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); +} + +// Duration - + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); +} + +// Duration * + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) +{ + return __d * __s; +} + +// Duration / + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type<_Rep1, _Rep2>::type +operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type, duration<_Rep2, _Period2> >::type _Ct; + return _Ct(__lhs).count() / _Ct(__rhs).count(); +} + +// Duration % + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename enable_if +< + !__is_duration<_Rep2>::value && + is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, + duration::type, _Period> +>::type +operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +typename common_type, duration<_Rep2, _Period2> >::type +operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); +} + +} // namespace chrono + +#if _LIBCPP_STD_VER > 11 +// Suffixes for duration literals [time.duration.literals] +inline namespace literals +{ + inline namespace chrono_literals + { + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) + { + return chrono::hours(static_cast(__h)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""h(long double __h) + { + return chrono::duration>(__h); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) + { + return chrono::minutes(static_cast(__m)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""min(long double __m) + { + return chrono::duration> (__m); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) + { + return chrono::seconds(static_cast(__s)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""s(long double __s) + { + return chrono::duration (__s); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) + { + return chrono::milliseconds(static_cast(__ms)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ms(long double __ms) + { + return chrono::duration(__ms); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) + { + return chrono::microseconds(static_cast(__us)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""us(long double __us) + { + return chrono::duration (__us); + } + + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) + { + return chrono::nanoseconds(static_cast(__ns)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ns(long double __ns) + { + return chrono::duration (__ns); + } + +} // namespace chrono_literals +} // namespace literals + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} // namespace chrono + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 +# include +#endif + +#endif // _LIBCPP___CHRONO_DURATION_H diff --git a/gnu/llvm/libcxx/include/__chrono/file_clock.h b/gnu/llvm/libcxx/include/__chrono/file_clock.h new file mode 100644 index 00000000000..ef62b832959 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/file_clock.h @@ -0,0 +1,85 @@ +// -*- 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___CHRONO_FILE_CLOCK_H +#define _LIBCPP___CHRONO_FILE_CLOCK_H + +#include <__availability> +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +// [time.clock.file], type file_clock +using file_clock = _VSTD_FS::_FilesystemClock; + +template +using file_time = time_point; + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock { +#if !defined(_LIBCPP_HAS_NO_INT128) + typedef __int128_t rep; + typedef nano period; +#else + typedef long long rep; + typedef nano period; +#endif + + typedef chrono::duration duration; + typedef chrono::time_point<_FilesystemClock> time_point; + + _LIBCPP_EXPORTED_FROM_ABI + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; + + _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; + +#if _LIBCPP_STD_VER > 17 + template + _LIBCPP_HIDE_FROM_ABI + static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { + return chrono::sys_time<_Duration>(__t.time_since_epoch()); + } + + template + _LIBCPP_HIDE_FROM_ABI + static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { + return chrono::file_time<_Duration>(__t.time_since_epoch()); + } +#endif // _LIBCPP_STD_VER > 17 +}; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + +#endif // _LIBCPP___CHRONO_FILE_CLOCK_H diff --git a/gnu/llvm/libcxx/include/__chrono/formatter.h b/gnu/llvm/libcxx/include/__chrono/formatter.h new file mode 100644 index 00000000000..2015783acbb --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/formatter.h @@ -0,0 +1,716 @@ +// -*- 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___CHRONO_FORMATTER_H +#define _LIBCPP___CHRONO_FORMATTER_H + +#include <__chrono/calendar.h> +#include <__chrono/convert_to_tm.h> +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/hh_mm_ss.h> +#include <__chrono/month.h> +#include <__chrono/month_weekday.h> +#include <__chrono/monthday.h> +#include <__chrono/ostream.h> +#include <__chrono/parser_std_format_spec.h> +#include <__chrono/statically_widen.h> +#include <__chrono/time_point.h> +#include <__chrono/weekday.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__chrono/year_month_day.h> +#include <__chrono/year_month_weekday.h> +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_error.h> +#include <__format/format_functions.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__memory/addressof.h> +#include +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +namespace __formatter { + +/// Formats a time based on a tm struct. +/// +/// This formatter passes the formatting to time_put which uses strftime. When +/// the value is outside the valid range it's unspecified what strftime will +/// output. For example weekday 8 can print 1 when the day is processed modulo +/// 7 since that handles the Sunday for 0-based weekday. It can also print 8 if +/// 7 is handled as a special case. +/// +/// The Standard doesn't specify what to do in this case so the result depends +/// on the result of the underlying code. +/// +/// \pre When the (abbreviated) weekday or month name are used, the caller +/// validates whether the value is valid. So the caller handles that +/// requirement of Table 97: Meaning of conversion specifiers +/// [tab:time.format.spec]. +/// +/// When no chrono-specs are provided it uses the stream formatter. + +// For tiny ratios it's not possible to convert a duration to a hh_mm_ss. This +// fails compile-time due to the limited precision of the ratio (64-bit is too +// small). Therefore a duration uses its own conversion. +template + requires(chrono::__is_duration<_Tp>::value) +_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) { + __sstr << std::use_facet>(__sstr.getloc()).decimal_point(); + + auto __fraction = __value - chrono::duration_cast(__value); + if constexpr (chrono::treat_as_floating_point_v) + // When the floating-point value has digits itself they are ignored based + // on the wording in [tab:time.format.spec] + // If the precision of the input cannot be exactly represented with + // seconds, then the format is a decimal floating-point number with a + // fixed format and a precision matching that of the precision of the + // input (or to a microseconds precision if the conversion to + // floating-point decimal seconds cannot be made within 18 fractional + // digits). + // + // This matches the behaviour of MSVC STL, fmtlib interprets this + // differently and uses 3 decimals. + // https://godbolt.org/z/6dsbnW8ba + std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, + _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"), + __fraction.count(), + chrono::hh_mm_ss<_Tp>::fractional_width); + else + std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, + _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"), + __fraction.count(), + chrono::hh_mm_ss<_Tp>::fractional_width); +} + +template +consteval bool __use_fraction() { + if constexpr (chrono::__is_duration<_Tp>::value) + return chrono::hh_mm_ss<_Tp>::fractional_width; + else + return false; +} + +template +_LIBCPP_HIDE_FROM_ABI void __format_year(int __year, basic_stringstream<_CharT>& __sstr) { + if (__year < 0) { + __sstr << _CharT('-'); + __year = -__year; + } + + // TODO FMT Write an issue + // If the result has less than four digits it is zero-padded with 0 to two digits. + // is less -> has less + // left-padded -> zero-padded, otherwise the proper value would be 000-0. + + // Note according to the wording it should be left padded, which is odd. + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:04}"), __year); +} + +template +_LIBCPP_HIDE_FROM_ABI void __format_century(int __year, basic_stringstream<_CharT>& __sstr) { + // TODO FMT Write an issue + // [tab:time.format.spec] + // %C The year divided by 100 using floored division. If the result is a + // single decimal digit, it is prefixed with 0. + + bool __negative = __year < 0; + int __century = (__year - (99 * __negative)) / 100; // floored division + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), __century); +} + +template +_LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( + const _Tp& __value, basic_stringstream<_CharT>& __sstr, basic_string_view<_CharT> __chrono_specs) { + tm __t = std::__convert_to_tm(__value); + const auto& __facet = std::use_facet>(__sstr.getloc()); + for (auto __it = __chrono_specs.begin(); __it != __chrono_specs.end(); ++__it) { + if (*__it == _CharT('%')) { + auto __s = __it; + ++__it; + // We only handle the types that can't be directly handled by time_put. + // (as an optimization n, t, and % are also handled directly.) + switch (*__it) { + case _CharT('n'): + __sstr << _CharT('\n'); + break; + case _CharT('t'): + __sstr << _CharT('\t'); + break; + case _CharT('%'): + __sstr << *__it; + break; + + case _CharT('C'): { + // strftime's output is only defined in the range [00, 99]. + int __year = __t.tm_year + 1900; + if (__year < 1000 || __year > 9999) + __formatter::__format_century(__year, __sstr); + else + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + } break; + + case _CharT('j'): + if constexpr (chrono::__is_duration<_Tp>::value) + // Converting a duration where the period has a small ratio to days + // may fail to compile. This due to loss of precision in the + // conversion. In order to avoid that issue convert to seconds as + // an intemediate step. + __sstr << chrono::duration_cast(chrono::duration_cast(__value)).count(); + else + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + break; + + case _CharT('q'): + if constexpr (chrono::__is_duration<_Tp>::value) { + __sstr << chrono::__units_suffix<_CharT, typename _Tp::period>(); + break; + } + __builtin_unreachable(); + + case _CharT('Q'): + // TODO FMT Determine the proper ideas + // - Should it honour the precision? + // - Shoult it honour the locale setting for the separators? + // The wording for Q doesn't use the word locale and the effect of + // precision is unspecified. + // + // MSVC STL ignores precision but uses separator + // FMT honours precision and has a bug for separator + // https://godbolt.org/z/78b7sMxns + if constexpr (chrono::__is_duration<_Tp>::value) { + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{}"), __value.count()); + break; + } + __builtin_unreachable(); + + case _CharT('S'): + case _CharT('T'): + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + if constexpr (__use_fraction<_Tp>()) + __formatter::__format_sub_seconds(__value, __sstr); + break; + + // Unlike time_put and strftime the formatting library requires %Y + // + // [tab:time.format.spec] + // The year as a decimal number. If the result is less than four digits + // it is left-padded with 0 to four digits. + // + // This means years in the range (-1000, 1000) need manual formatting. + // It's unclear whether %EY needs the same treatment. For example the + // Japanese EY contains the era name and year. This is zero-padded to 2 + // digits in time_put (note that older glibc versions didn't do + // padding.) However most eras won't reach 100 years, let alone 1000. + // So padding to 4 digits seems unwanted for Japanese. + // + // The same applies to %Ex since that too depends on the era. + // + // %x the locale's date representation is currently doesn't handle the + // zero-padding too. + // + // The 4 digits can be implemented better at a later time. On POSIX + // systems the required information can be extracted by nl_langinfo + // https://man7.org/linux/man-pages/man3/nl_langinfo.3.html + // + // Note since year < -1000 is expected to be rare it uses the more + // expensive year routine. + // + // TODO FMT evaluate the comment above. + +# if defined(__GLIBC__) || defined(_AIX) + case _CharT('y'): + // Glibc fails for negative values, AIX for positive values too. + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), (std::abs(__t.tm_year + 1900)) % 100); + break; +# endif // defined(__GLIBC__) || defined(_AIX) + + case _CharT('Y'): { + int __year = __t.tm_year + 1900; + if (__year < 1000) + __formatter::__format_year(__year, __sstr); + else + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + } break; + + case _CharT('F'): { + int __year = __t.tm_year + 1900; + if (__year < 1000) { + __formatter::__format_year(__year, __sstr); + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday); + } else + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + } break; + + case _CharT('O'): + if constexpr (__use_fraction<_Tp>()) { + // Handle OS using the normal representation for the non-fractional + // part. There seems to be no locale information regarding how the + // fractional part should be formatted. + if (*(__it + 1) == 'S') { + ++__it; + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + __formatter::__format_sub_seconds(__value, __sstr); + break; + } + } + [[fallthrough]]; + case _CharT('E'): + ++__it; + [[fallthrough]]; + default: + __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); + break; + } + } else { + __sstr << *__it; + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) { + if constexpr (same_as<_Tp, chrono::day>) + return true; + else if constexpr (same_as<_Tp, chrono::month>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_indexed>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month_day>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day_last>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday>) + return __value.weekday().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) + return __value.weekday().ok(); + else + static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) { + if constexpr (same_as<_Tp, chrono::day>) + return true; + else if constexpr (same_as<_Tp, chrono::month>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::weekday_indexed>) + return __value.weekday().ok(); + else if constexpr (same_as<_Tp, chrono::weekday_last>) + return __value.weekday().ok(); + else if constexpr (same_as<_Tp, chrono::month_day>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday>) + return __value.weekday_indexed().ok(); + else if constexpr (same_as<_Tp, chrono::month_weekday_last>) + return __value.weekday_indexed().ok(); + else if constexpr (same_as<_Tp, chrono::year_month>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month_day>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day_last>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday>) + return __value.weekday().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) + return __value.weekday().ok(); + else + static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) { + if constexpr (same_as<_Tp, chrono::day>) + return true; + else if constexpr (same_as<_Tp, chrono::month>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_indexed>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::month_weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month>) + return true; + else if constexpr (same_as<_Tp, chrono::year_month_day>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day_last>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) + return __value.ok(); + else + static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) { + if constexpr (same_as<_Tp, chrono::day>) + return true; + else if constexpr (same_as<_Tp, chrono::month>) + return __value.ok(); + else if constexpr (same_as<_Tp, chrono::year>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_indexed>) + return true; + else if constexpr (same_as<_Tp, chrono::weekday_last>) + return true; + else if constexpr (same_as<_Tp, chrono::month_day>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::month_day_last>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::month_weekday>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::month_weekday_last>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_day_last>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday>) + return __value.month().ok(); + else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) + return __value.month().ok(); + else + static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_chrono(const _Tp& __value, + auto& __ctx, + __format_spec::__parsed_specifications<_CharT> __specs, + basic_string_view<_CharT> __chrono_specs) -> decltype(__ctx.out()) { + basic_stringstream<_CharT> __sstr; + // [time.format]/2 + // 2.1 - the "C" locale if the L option is not present in chrono-format-spec, otherwise + // 2.2 - the locale passed to the formatting function if any, otherwise + // 2.3 - the global locale. + // Note that the __ctx's locale() call does 2.2 and 2.3. + if (__specs.__chrono_.__locale_specific_form_) + __sstr.imbue(__ctx.locale()); + else + __sstr.imbue(locale::classic()); + + if (__chrono_specs.empty()) + __sstr << __value; + else { + if constexpr (chrono::__is_duration<_Tp>::value) { + if (__value < __value.zero()) + __sstr << _CharT('-'); + __formatter::__format_chrono_using_chrono_specs(chrono::abs(__value), __sstr, __chrono_specs); + // TODO FMT When keeping the precision it will truncate the string. + // Note that the behaviour what the precision does isn't specified. + __specs.__precision_ = -1; + } else { + // Test __weekday_name_ before __weekday_ to give a better error. + if (__specs.__chrono_.__weekday_name_ && !__formatter::__weekday_name_ok(__value)) + std::__throw_format_error("formatting a weekday name needs a valid weekday"); + + if (__specs.__chrono_.__weekday_ && !__formatter::__weekday_ok(__value)) + std::__throw_format_error("formatting a weekday needs a valid weekday"); + + if (__specs.__chrono_.__day_of_year_ && !__formatter::__date_ok(__value)) + std::__throw_format_error("formatting a day of year needs a valid date"); + + if (__specs.__chrono_.__week_of_year_ && !__formatter::__date_ok(__value)) + std::__throw_format_error("formatting a week of year needs a valid date"); + + if (__specs.__chrono_.__month_name_ && !__formatter::__month_name_ok(__value)) + std::__throw_format_error("formatting a month name from an invalid month number"); + + __formatter::__format_chrono_using_chrono_specs(__value, __sstr, __chrono_specs); + } + } + + // TODO FMT Use the stringstream's view after P0408R7 has been implemented. + basic_string<_CharT> __str = __sstr.str(); + return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); +} + +} // namespace __formatter + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_chrono { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse( + basic_format_parse_context<_CharT>& __parse_ctx, __format_spec::__fields __fields, __format_spec::__flags __flags) + -> decltype(__parse_ctx.begin()) { + return __parser_.__parse(__parse_ctx, __fields, __flags); + } + + template + _LIBCPP_HIDE_FROM_ABI auto format(const _Tp& __value, auto& __ctx) const -> decltype(__ctx.out()) const { + return __formatter::__format_chrono( + __value, __ctx, __parser_.__parser_.__get_parsed_chrono_specifications(__ctx), __parser_.__chrono_specs_); + } + + __format_spec::__parser_chrono<_CharT> __parser_; +}; + +template +struct formatter, _CharT> : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + // [time.format]/1 + // Giving a precision specification in the chrono-format-spec is valid only + // for std::chrono::duration types where the representation type Rep is a + // floating-point type. For all other Rep types, an exception of type + // format_error is thrown if the chrono-format-spec contains a precision + // specification. + // + // Note this doesn't refer to chrono::treat_as_floating_point_v<_Rep>. + if constexpr (std::floating_point<_Rep>) + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono_fractional, __format_spec::__flags::__duration); + else + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__duration); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__day); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); + } +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); + } +}; + +#endif // if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_FORMATTER_H diff --git a/gnu/llvm/libcxx/include/__chrono/hh_mm_ss.h b/gnu/llvm/libcxx/include/__chrono/hh_mm_ss.h new file mode 100644 index 00000000000..fd61cbe8f84 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/hh_mm_ss.h @@ -0,0 +1,112 @@ +// -*- 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___CHRONO_HH_MM_SS_H +#define _LIBCPP___CHRONO_HH_MM_SS_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template +class hh_mm_ss +{ +private: + static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); + using __CommonType = common_type_t<_Duration, chrono::seconds>; + + _LIBCPP_HIDE_FROM_ABI static constexpr uint64_t __pow10(unsigned __exp) + { + uint64_t __ret = 1; + for (unsigned __i = 0; __i < __exp; ++__i) + __ret *= 10U; + return __ret; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) + { + if (__n >= 2 && __d != 0 && __w < 19) + return 1 + __width(__n, __d % __n * 10, __w+1); + return 0; + } + +public: + _LIBCPP_HIDE_FROM_ABI static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? + __width(__CommonType::period::den) : 6u; + using precision = duration>; + + _LIBCPP_HIDE_FROM_ABI constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} + + _LIBCPP_HIDE_FROM_ABI constexpr explicit hh_mm_ss(_Duration __d) noexcept : + __is_neg_(__d < _Duration(0)), + __h_(chrono::duration_cast (chrono::abs(__d))), + __m_(chrono::duration_cast(chrono::abs(__d) - hours())), + __s_(chrono::duration_cast(chrono::abs(__d) - hours() - minutes())), + __f_(chrono::duration_cast (chrono::abs(__d) - hours() - minutes() - seconds())) + {} + + _LIBCPP_HIDE_FROM_ABI constexpr bool is_negative() const noexcept { return __is_neg_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours hours() const noexcept { return __h_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes minutes() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds seconds() const noexcept { return __s_; } + _LIBCPP_HIDE_FROM_ABI constexpr precision subseconds() const noexcept { return __f_; } + + _LIBCPP_HIDE_FROM_ABI constexpr precision to_duration() const noexcept + { + auto __dur = __h_ + __m_ + __s_ + __f_; + return __is_neg_ ? -__dur : __dur; + } + + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator precision() const noexcept { return to_duration(); } + +private: + bool __is_neg_; + chrono::hours __h_; + chrono::minutes __m_; + chrono::seconds __s_; + precision __f_; +}; + +_LIBCPP_HIDE_FROM_ABI constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } +_LIBCPP_HIDE_FROM_ABI constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } + +_LIBCPP_HIDE_FROM_ABI constexpr hours make12(const hours& __h) noexcept +{ + if (__h == hours( 0)) return hours(12); + else if (__h <= hours(12)) return __h; + else return __h - hours(12); +} + +_LIBCPP_HIDE_FROM_ABI constexpr hours make24(const hours& __h, bool __is_pm) noexcept +{ + if (__is_pm) + return __h == hours(12) ? __h : __h + hours(12); + else + return __h == hours(12) ? hours(0) : __h; +} +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_HH_MM_SS_H diff --git a/gnu/llvm/libcxx/include/__chrono/high_resolution_clock.h b/gnu/llvm/libcxx/include/__chrono/high_resolution_clock.h new file mode 100644 index 00000000000..778ff44f3d0 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/high_resolution_clock.h @@ -0,0 +1,36 @@ +// -*- 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___CHRONO_HIGH_RESOLUTION_CLOCK_H +#define _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H + +#include <__chrono/steady_clock.h> +#include <__chrono/system_clock.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +typedef steady_clock high_resolution_clock; +#else +typedef system_clock high_resolution_clock; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H diff --git a/gnu/llvm/libcxx/include/__chrono/literals.h b/gnu/llvm/libcxx/include/__chrono/literals.h new file mode 100644 index 00000000000..50529bd44ad --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/literals.h @@ -0,0 +1,49 @@ +// -*- 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___CHRONO_LITERALS_H +#define _LIBCPP___CHRONO_LITERALS_H + +#include <__chrono/day.h> +#include <__chrono/year.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +inline namespace literals +{ + inline namespace chrono_literals + { + _LIBCPP_HIDE_FROM_ABI constexpr chrono::day operator ""d(unsigned long long __d) noexcept + { + return chrono::day(static_cast(__d)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr chrono::year operator ""y(unsigned long long __y) noexcept + { + return chrono::year(static_cast(__y)); + } +} // namespace chrono_literals +} // namespace literals + +namespace chrono { // hoist the literals into namespace std::chrono + using namespace literals::chrono_literals; +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_LITERALS_H diff --git a/gnu/llvm/libcxx/include/__chrono/month.h b/gnu/llvm/libcxx/include/__chrono/month.h new file mode 100644 index 00000000000..e929f248842 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/month.h @@ -0,0 +1,103 @@ +// -*- 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___CHRONO_MONTH_H +#define _LIBCPP___CHRONO_MONTH_H + +#include <__chrono/duration.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class month { +private: + unsigned char __m_; +public: + _LIBCPP_HIDE_FROM_ABI month() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept : __m_(static_cast(__val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { ++__m_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { --__m_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI constexpr month& operator+=(const months& __m1) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr month& operator-=(const months& __m1) noexcept; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_ >= 1 && __m_ <= 12; } +}; + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month& __lhs, const month& __rhs) noexcept +{ return static_cast(__lhs) == static_cast(__rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const month& __lhs, const month& __rhs) noexcept { + return static_cast(__lhs) <=> static_cast(__rhs); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month operator+ (const month& __lhs, const months& __rhs) noexcept +{ + auto const __mu = static_cast(static_cast(__lhs)) + (__rhs.count() - 1); + auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; + return month{static_cast(__mu - __yr * 12 + 1)}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month operator+ (const months& __lhs, const month& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month operator- (const month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +months operator-(const month& __lhs, const month& __rhs) noexcept +{ + auto const __dm = static_cast(__lhs) - static_cast(__rhs); + return months(__dm <= 11 ? __dm : __dm + 12); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month& month::operator+=(const months& __dm) noexcept +{ *this = *this + __dm; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month& month::operator-=(const months& __dm) noexcept +{ *this = *this - __dm; return *this; } + +inline constexpr month January{1}; +inline constexpr month February{2}; +inline constexpr month March{3}; +inline constexpr month April{4}; +inline constexpr month May{5}; +inline constexpr month June{6}; +inline constexpr month July{7}; +inline constexpr month August{8}; +inline constexpr month September{9}; +inline constexpr month October{10}; +inline constexpr month November{11}; +inline constexpr month December{12}; + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_MONTH_H diff --git a/gnu/llvm/libcxx/include/__chrono/month_weekday.h b/gnu/llvm/libcxx/include/__chrono/month_weekday.h new file mode 100644 index 00000000000..01cdf76d84b --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/month_weekday.h @@ -0,0 +1,106 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CHRONO_MONTH_WEEKDAY_H +#define _LIBCPP___CHRONO_MONTH_WEEKDAY_H + +#include <__chrono/month.h> +#include <__chrono/weekday.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class month_weekday { +private: + chrono::month __m_; + chrono::weekday_indexed __wdi_; +public: + _LIBCPP_HIDE_FROM_ABI constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept + : __m_{__mval}, __wdi_{__wdival} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdi_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{__lhs, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{month(__lhs), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept +{ return month_weekday{__rhs, __lhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept +{ return month_weekday{month(__rhs), __lhs}; } + + +class month_weekday_last { + chrono::month __m_; + chrono::weekday_last __wdl_; + public: + _LIBCPP_HIDE_FROM_ABI constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept + : __m_{__mval}, __wdl_{__wdlval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdl_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{__lhs, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{month(__lhs), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept +{ return month_weekday_last{__rhs, __lhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept +{ return month_weekday_last{month(__rhs), __lhs}; } +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_MONTH_WEEKDAY_H diff --git a/gnu/llvm/libcxx/include/__chrono/monthday.h b/gnu/llvm/libcxx/include/__chrono/monthday.h new file mode 100644 index 00000000000..c0ee3e4a94f --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/monthday.h @@ -0,0 +1,129 @@ +// -*- 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___CHRONO_MONTHDAY_H +#define _LIBCPP___CHRONO_MONTHDAY_H + +#include <__chrono/calendar.h> +#include <__chrono/day.h> +#include <__chrono/month.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class month_day { +private: + chrono::month __m_; + chrono::day __d_; +public: + _LIBCPP_HIDE_FROM_ABI month_day() = default; + _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept + : __m_{__mval}, __d_{__dval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool month_day::ok() const noexcept +{ + if (!__m_.ok()) return false; + const unsigned __dval = static_cast(__d_); + if (__dval < 1 || __dval > 31) return false; + if (__dval <= 29) return true; +// Now we've got either 30 or 31 + const unsigned __mval = static_cast(__m_); + if (__mval == 2) return false; + if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) + return __dval == 30; + return true; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const month_day& __lhs, const month_day& __rhs) noexcept { + if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) + return __c; + return __lhs.day() <=> __rhs.day(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day operator/(const month& __lhs, const day& __rhs) noexcept +{ return month_day{__lhs, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI constexpr +month_day operator/(const day& __lhs, const month& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day operator/(const month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr +month_day operator/(int __lhs, const day& __rhs) noexcept +{ return month(__lhs) / __rhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +month_day operator/(const day& __lhs, int __rhs) noexcept +{ return month(__rhs) / __lhs; } + +class month_day_last { +private: + chrono::month __m_; +public: + _LIBCPP_HIDE_FROM_ABI explicit constexpr month_day_last(const chrono::month& __val) noexcept + : __m_{__val} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month(); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering +operator<=>(const month_day_last& __lhs, const month_day_last& __rhs) noexcept { + return __lhs.month() <=> __rhs.month(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day_last operator/(const month& __lhs, last_spec) noexcept +{ return month_day_last{__lhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day_last operator/(last_spec, const month& __rhs) noexcept +{ return month_day_last{__rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day_last operator/(int __lhs, last_spec) noexcept +{ return month_day_last{month(__lhs)}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +month_day_last operator/(last_spec, int __rhs) noexcept +{ return month_day_last{month(__rhs)}; } + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_MONTHDAY_H diff --git a/gnu/llvm/libcxx/include/__chrono/ostream.h b/gnu/llvm/libcxx/include/__chrono/ostream.h new file mode 100644 index 00000000000..30a04bd2658 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/ostream.h @@ -0,0 +1,238 @@ +// -*- 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___CHRONO_OSTREAM_H +#define _LIBCPP___CHRONO_OSTREAM_H + +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/month.h> +#include <__chrono/month_weekday.h> +#include <__chrono/monthday.h> +#include <__chrono/statically_widen.h> +#include <__chrono/weekday.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__chrono/year_month_day.h> +#include <__chrono/year_month_weekday.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/format_functions.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +namespace chrono { + +// Depending on the type the return is a const _CharT* or a basic_string<_CharT> +template +_LIBCPP_HIDE_FROM_ABI auto __units_suffix() { + // TODO FMT LWG issue the suffixes are always char and not STATICALLY-WIDEN'ed. + if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "as"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "fs"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ps"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ns"); + else if constexpr (same_as) +# ifndef _LIBCPP_HAS_NO_UNICODE + return _LIBCPP_STATICALLY_WIDEN(_CharT, "\u00b5s"); +# else + return _LIBCPP_STATICALLY_WIDEN(_CharT, "us"); +# endif + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ms"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "cs"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ds"); + else if constexpr (same_as>) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "s"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "das"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "hs"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ks"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ms"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Gs"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ts"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ps"); + else if constexpr (same_as) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "Es"); + else if constexpr (same_as>) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "min"); + else if constexpr (same_as>) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "h"); + else if constexpr (same_as>) + return _LIBCPP_STATICALLY_WIDEN(_CharT, "d"); + else if constexpr (_Period::den == 1) + return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}]s"), _Period::num); + else + return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}/{}]s"), _Period::num, _Period::den); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) { + basic_ostringstream<_CharT, _Traits> __s; + __s.flags(__os.flags()); + __s.imbue(__os.getloc()); + __s.precision(__os.precision()); + __s << __d.count() << chrono::__units_suffix<_CharT, _Period>(); + return __os << __s.str(); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) { + return __os + << (__d.ok() + ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d) + // Note this error differs from the wording of the Standard. The + // Standard wording doesn't work well on AIX or Windows. There + // the formatted day seems to be either modulo 100 or completely + // omitted. Judging by the wording this is valid. + // TODO FMT Write a paper of file an LWG issue. + : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"), static_cast(__d))); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) { + return __os << (__m.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%b}"), __m) + : std::format(__os.getloc(), + _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid month"), + static_cast(__m))); // TODO FMT Standard mandated locale isn't used. +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) { + return __os << (__y.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y}"), __y) + : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), __y)); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) { + return __os << (__wd.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%a}"), __wd) + : std::format(__os.getloc(), // TODO FMT Standard mandated locale isn't used. + _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid weekday"), + static_cast(__wd.c_encoding()))); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) { + auto __i = __wdi.index(); + return __os << (__i >= 1 && __i <= 5 + ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{}]"), __wdi.weekday(), __i) + : std::format(__os.getloc(), + _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{} is not a valid index]"), + __wdi.weekday(), + __i)); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) { + return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) { + // TODO FMT The Standard allows 30th of February to be printed. + // It would be nice to show an error message instead. + return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{}"), __md.month(), __md.day()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) { + return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) { + return __os << std::format( + __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) { + return __os << std::format( + __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) { + return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) { + return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd) + : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd)); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) { + return __os << std::format( + __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) { + return __os << std::format( + __os.getloc(), + _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"), + __ymwd.year(), + __ymwd.month(), + __ymwd.weekday_indexed()); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) { + return __os << std::format( + __os.getloc(), + _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"), + __ymwdl.year(), + __ymwdl.month(), + __ymwdl.weekday_last()); +} + +} // namespace chrono + +#endif //if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_OSTREAM_H diff --git a/gnu/llvm/libcxx/include/__chrono/parser_std_format_spec.h b/gnu/llvm/libcxx/include/__chrono/parser_std_format_spec.h new file mode 100644 index 00000000000..dbcfe6da608 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/parser_std_format_spec.h @@ -0,0 +1,410 @@ +// -*- 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___CHRONO_PARSER_STD_FORMAT_SPEC_H +#define _LIBCPP___CHRONO_PARSER_STD_FORMAT_SPEC_H + +#include <__config> +#include <__format/concepts.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/formatter_string.h> +#include <__format/parser_std_format_spec.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +namespace __format_spec { + +// By not placing this constant in the formatter class it's not duplicated for char and wchar_t +inline constexpr __fields __fields_chrono_fractional{ + .__precision_ = true, .__locale_specific_form_ = true, .__type_ = false}; +inline constexpr __fields __fields_chrono{.__locale_specific_form_ = true, .__type_ = false}; + +/// Flags available or required in a chrono type. +/// +/// The caller of the chrono formatter lists the types it has available and the +/// validation tests whether the requested type spec (e.g. %M) is available in +/// the formatter. +/// When the type in the chrono-format-spec isn't present in the data a +/// \ref format_error is thrown. +enum class __flags { + __second = 0x1, + __minute = 0x2, + __hour = 0x4, + __time = __hour | __minute | __second, + + __day = 0x8, + __month = 0x10, + __year = 0x20, + + __weekday = 0x40, + + __month_day = __day | __month, + __month_weekday = __weekday | __month, + __year_month = __month | __year, + __date = __day | __month | __year | __weekday, + + __date_time = __date | __time, + + __duration = 0x80 | __time, + + __time_zone = 0x100, + + __clock = __date_time | __time_zone +}; + +_LIBCPP_HIDE_FROM_ABI constexpr __flags operator&(__flags __lhs, __flags __rhs) { + return static_cast<__flags>(static_cast(__lhs) & static_cast(__rhs)); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_second(__flags __flags) { + if ((__flags & __flags::__second) != __flags::__second) + std::__throw_format_error("The supplied date time doesn't contain a second"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_minute(__flags __flags) { + if ((__flags & __flags::__minute) != __flags::__minute) + std::__throw_format_error("The supplied date time doesn't contain a minute"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_hour(__flags __flags) { + if ((__flags & __flags::__hour) != __flags::__hour) + std::__throw_format_error("The supplied date time doesn't contain an hour"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_time(__flags __flags) { + if ((__flags & __flags::__time) != __flags::__time) + std::__throw_format_error("The supplied date time doesn't contain a time"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_day(__flags __flags) { + if ((__flags & __flags::__day) != __flags::__day) + std::__throw_format_error("The supplied date time doesn't contain a day"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_month(__flags __flags) { + if ((__flags & __flags::__month) != __flags::__month) + std::__throw_format_error("The supplied date time doesn't contain a month"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_year(__flags __flags) { + if ((__flags & __flags::__year) != __flags::__year) + std::__throw_format_error("The supplied date time doesn't contain a year"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_date(__flags __flags) { + if ((__flags & __flags::__date) != __flags::__date) + std::__throw_format_error("The supplied date time doesn't contain a date"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_date_or_duration(__flags __flags) { + if (((__flags & __flags::__date) != __flags::__date) && ((__flags & __flags::__duration) != __flags::__duration)) + std::__throw_format_error("The supplied date time doesn't contain a date or duration"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_date_time(__flags __flags) { + if ((__flags & __flags::__date_time) != __flags::__date_time) + std::__throw_format_error("The supplied date time doesn't contain a date and time"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_weekday(__flags __flags) { + if ((__flags & __flags::__weekday) != __flags::__weekday) + std::__throw_format_error("The supplied date time doesn't contain a weekday"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_duration(__flags __flags) { + if ((__flags & __flags::__duration) != __flags::__duration) + std::__throw_format_error("The supplied date time doesn't contain a duration"); +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __validate_time_zone(__flags __flags) { + if ((__flags & __flags::__time_zone) != __flags::__time_zone) + std::__throw_format_error("The supplied date time doesn't contain a time zone"); +} + +template +class _LIBCPP_TEMPLATE_VIS __parser_chrono { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields, __flags __flags) + -> decltype(__parse_ctx.begin()) { + const _CharT* __begin = __parser_.__parse(__parse_ctx, __fields); + const _CharT* __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + const _CharT* __last = __parse_chrono_specs(__begin, __end, __flags); + __chrono_specs_ = basic_string_view<_CharT>{__begin, __last}; + + return __last; + } + + __parser<_CharT> __parser_; + basic_string_view<_CharT> __chrono_specs_; + +private: + _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* + __parse_chrono_specs(const _CharT* __begin, const _CharT* __end, __flags __flags) { + _LIBCPP_ASSERT(__begin != __end, + "When called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); + + if (*__begin != _CharT('%') && *__begin != _CharT('}')) + std::__throw_format_error("Expected '%' or '}' in the chrono format-string"); + + do { + switch (*__begin) { + case _CharT('{'): + std::__throw_format_error("The chrono-specs contains a '{'"); + + case _CharT('}'): + return __begin; + + case _CharT('%'): + __parse_conversion_spec(__begin, __end, __flags); + [[fallthrough]]; + + default: + // All other literals + ++__begin; + } + + } while (__begin != __end && *__begin != _CharT('}')); + + return __begin; + } + + /// \pre *__begin == '%' + /// \post __begin points at the end parsed conversion-spec + _LIBCPP_HIDE_FROM_ABI constexpr void + __parse_conversion_spec(const _CharT*& __begin, const _CharT* __end, __flags __flags) { + ++__begin; + if (__begin == __end) + std::__throw_format_error("End of input while parsing the modifier chrono conversion-spec"); + + switch (*__begin) { + case _CharT('n'): + case _CharT('t'): + case _CharT('%'): + break; + + case _CharT('S'): + __format_spec::__validate_second(__flags); + break; + + case _CharT('M'): + __format_spec::__validate_minute(__flags); + break; + + case _CharT('p'): // TODO FMT does the formater require an hour or a time? + case _CharT('H'): + case _CharT('I'): + __validate_hour(__flags); + break; + + case _CharT('r'): + case _CharT('R'): + case _CharT('T'): + case _CharT('X'): + __format_spec::__validate_time(__flags); + break; + + case _CharT('d'): + case _CharT('e'): + __format_spec::__validate_day(__flags); + break; + + case _CharT('b'): + case _CharT('h'): + case _CharT('B'): + __parser_.__month_name_ = true; + [[fallthrough]]; + case _CharT('m'): + __format_spec::__validate_month(__flags); + break; + + case _CharT('y'): + case _CharT('C'): + case _CharT('Y'): + __format_spec::__validate_year(__flags); + break; + + case _CharT('j'): + __parser_.__day_of_year_ = true; + __format_spec::__validate_date_or_duration(__flags); + break; + + case _CharT('g'): + case _CharT('G'): + case _CharT('U'): + case _CharT('V'): + case _CharT('W'): + __parser_.__week_of_year_ = true; + [[fallthrough]]; + case _CharT('x'): + case _CharT('D'): + case _CharT('F'): + __format_spec::__validate_date(__flags); + break; + + case _CharT('c'): + __format_spec::__validate_date_time(__flags); + break; + + case _CharT('a'): + case _CharT('A'): + __parser_.__weekday_name_ = true; + [[fallthrough]]; + case _CharT('u'): + case _CharT('w'): + __parser_.__weekday_ = true; + __validate_weekday(__flags); + __format_spec::__validate_weekday(__flags); + break; + + case _CharT('q'): + case _CharT('Q'): + __format_spec::__validate_duration(__flags); + break; + + case _CharT('E'): + __parse_modifier_E(__begin, __end, __flags); + break; + + case _CharT('O'): + __parse_modifier_O(__begin, __end, __flags); + break; + + case _CharT('z'): + case _CharT('Z'): + // Currently there's no time zone information. However some clocks have a + // hard-coded "time zone", for these clocks the information can be used. + // TODO FMT implement time zones. + __format_spec::__validate_time_zone(__flags); + break; + + default: // unknown type; + std::__throw_format_error("The date time type specifier is invalid"); + } + } + + /// \pre *__begin == 'E' + /// \post __begin is incremented by one. + _LIBCPP_HIDE_FROM_ABI constexpr void + __parse_modifier_E(const _CharT*& __begin, const _CharT* __end, __flags __flags) { + ++__begin; + if (__begin == __end) + std::__throw_format_error("End of input while parsing the modifier E"); + + switch (*__begin) { + case _CharT('X'): + __format_spec::__validate_time(__flags); + break; + + case _CharT('y'): + case _CharT('C'): + case _CharT('Y'): + __format_spec::__validate_year(__flags); + break; + + case _CharT('x'): + __format_spec::__validate_date(__flags); + break; + + case _CharT('c'): + __format_spec::__validate_date_time(__flags); + break; + + case _CharT('z'): + // Currently there's no time zone information. However some clocks have a + // hard-coded "time zone", for these clocks the information can be used. + // TODO FMT implement time zones. + __format_spec::__validate_time_zone(__flags); + break; + + default: + std::__throw_format_error("The date time type specifier for modifier E is invalid"); + } + } + + /// \pre *__begin == 'O' + /// \post __begin is incremented by one. + _LIBCPP_HIDE_FROM_ABI constexpr void + __parse_modifier_O(const _CharT*& __begin, const _CharT* __end, __flags __flags) { + ++__begin; + if (__begin == __end) + std::__throw_format_error("End of input while parsing the modifier O"); + + switch (*__begin) { + case _CharT('S'): + __format_spec::__validate_second(__flags); + break; + + case _CharT('M'): + __format_spec::__validate_minute(__flags); + break; + + case _CharT('I'): + case _CharT('H'): + __format_spec::__validate_hour(__flags); + break; + + case _CharT('d'): + case _CharT('e'): + __format_spec::__validate_day(__flags); + break; + + case _CharT('m'): + __format_spec::__validate_month(__flags); + break; + + case _CharT('y'): + __format_spec::__validate_year(__flags); + break; + + case _CharT('U'): + case _CharT('V'): + case _CharT('W'): + __parser_.__week_of_year_ = true; + __format_spec::__validate_date(__flags); + break; + + case _CharT('u'): + case _CharT('w'): + __parser_.__weekday_ = true; + __format_spec::__validate_weekday(__flags); + break; + + case _CharT('z'): + // Currently there's no time zone information. However some clocks have a + // hard-coded "time zone", for these clocks the information can be used. + // TODO FMT implement time zones. + __format_spec::__validate_time_zone(__flags); + break; + + default: + std::__throw_format_error("The date time type specifier for modifier O is invalid"); + } + } +}; + +} // namespace __format_spec + +#endif //_LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_PARSER_STD_FORMAT_SPEC_H diff --git a/gnu/llvm/libcxx/include/__chrono/statically_widen.h b/gnu/llvm/libcxx/include/__chrono/statically_widen.h new file mode 100644 index 00000000000..360b6c2c7d5 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/statically_widen.h @@ -0,0 +1,52 @@ +// -*- 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___CHRONO_STATICALLY_WIDEN_H +#define _LIBCPP___CHRONO_STATICALLY_WIDEN_H + +// Implements the STATICALLY-WIDEN exposition-only function. ([time.general]/2) + +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <__fmt_char_type _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __str, const wchar_t* __wstr) { + if constexpr (same_as<_CharT, char>) + return __str; + else + return __wstr; +} +# define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str, L##__str) +# else // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +// Without this indirection the unit test test/libcxx/modules_include.sh.cpp +// fails for the CI build "No wide characters". This seems like a bug. +// TODO FMT investigate why this is needed. +template <__fmt_char_type _CharT> +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __str) { + return __str; +} +# define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str) +# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_STATICALLY_WIDEN_H diff --git a/gnu/llvm/libcxx/include/__chrono/steady_clock.h b/gnu/llvm/libcxx/include/__chrono/steady_clock.h new file mode 100644 index 00000000000..ba83351738d --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/steady_clock.h @@ -0,0 +1,44 @@ +// -*- 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___CHRONO_STEADY_CLOCK_H +#define _LIBCPP___CHRONO_STEADY_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK +class _LIBCPP_TYPE_VIS steady_clock +{ +public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true; + + static time_point now() _NOEXCEPT; +}; +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_STEADY_CLOCK_H diff --git a/gnu/llvm/libcxx/include/__chrono/system_clock.h b/gnu/llvm/libcxx/include/__chrono/system_clock.h new file mode 100644 index 00000000000..331db468013 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/system_clock.h @@ -0,0 +1,54 @@ +// -*- 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___CHRONO_SYSTEM_CLOCK_H +#define _LIBCPP___CHRONO_SYSTEM_CLOCK_H + +#include <__chrono/duration.h> +#include <__chrono/time_point.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class _LIBCPP_TYPE_VIS system_clock +{ +public: + typedef microseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; + + static time_point now() _NOEXCEPT; + static time_t to_time_t (const time_point& __t) _NOEXCEPT; + static time_point from_time_t(time_t __t) _NOEXCEPT; +}; + +#if _LIBCPP_STD_VER > 17 + +template +using sys_time = time_point; +using sys_seconds = sys_time; +using sys_days = sys_time; + +#endif + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CHRONO_SYSTEM_CLOCK_H diff --git a/gnu/llvm/libcxx/include/__chrono/time_point.h b/gnu/llvm/libcxx/include/__chrono/time_point.h new file mode 100644 index 00000000000..8a8fa2176d6 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/time_point.h @@ -0,0 +1,251 @@ +// -*- 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___CHRONO_TIME_POINT_H +#define _LIBCPP___CHRONO_TIME_POINT_H + +#include <__chrono/duration.h> +#include <__config> +#include <__type_traits/common_type.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_convertible.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +template +class _LIBCPP_TEMPLATE_VIS time_point +{ + static_assert(__is_duration<_Duration>::value, + "Second template parameter of time_point must be a std::chrono::duration"); +public: + typedef _Clock clock; + typedef _Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; +private: + duration __d_; + +public: + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point() : __d_(duration::zero()) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit time_point(const duration& __d) : __d_(__d) {} + + // conversions + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 + time_point(const time_point& __t, + typename enable_if + < + is_convertible<_Duration2, duration>::value + >::type* = nullptr) + : __d_(__t.time_since_epoch()) {} + + // observer + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const {return __d_;} + + // arithmetic + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} + + // special values + + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} +}; + +} // namespace chrono + +template +struct _LIBCPP_TEMPLATE_VIS common_type, + chrono::time_point<_Clock, _Duration2> > +{ + typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; +}; + +namespace chrono { + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +time_point<_Clock, _ToDuration> +time_point_cast(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); +} + +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +floor(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +ceil(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + __is_duration<_ToDuration>::value, + time_point<_Clock, _ToDuration> +>::type +round(const time_point<_Clock, _Duration>& __t) +{ + return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())}; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + numeric_limits<_Rep>::is_signed, + duration<_Rep, _Period> +>::type +abs(duration<_Rep, _Period> __d) +{ + return __d >= __d.zero() ? +__d : -__d; +} +#endif // _LIBCPP_STD_VER > 14 + +// time_point == + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() == __rhs.time_since_epoch(); +} + +// time_point != + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs == __rhs); +} + +// time_point < + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() < __rhs.time_since_epoch(); +} + +// time_point > + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs < __lhs; +} + +// time_point <= + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__rhs < __lhs); +} + +// time_point >= + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +bool +operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return !(__lhs < __rhs); +} + +// time_point operator+(time_point x, duration y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; + return _Tr (__lhs.time_since_epoch() + __rhs); +} + +// time_point operator+(duration x, time_point y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +time_point<_Clock, typename common_type, _Duration2>::type> +operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __rhs + __lhs; +} + +// time_point operator-(time_point x, duration y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) +{ + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; + return _Ret(__lhs.time_since_epoch() -__rhs); +} + +// duration operator-(time_point x, time_point y); + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename common_type<_Duration1, _Duration2>::type +operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) +{ + return __lhs.time_since_epoch() - __rhs.time_since_epoch(); +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_TIME_POINT_H diff --git a/gnu/llvm/libcxx/include/__chrono/weekday.h b/gnu/llvm/libcxx/include/__chrono/weekday.h new file mode 100644 index 00000000000..e0bc8a4cae2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/weekday.h @@ -0,0 +1,185 @@ +// -*- 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___CHRONO_WEEKDAY_H +#define _LIBCPP___CHRONO_WEEKDAY_H + +#include <__chrono/calendar.h> +#include <__chrono/duration.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class weekday_indexed; +class weekday_last; + +class weekday { +private: + unsigned char __wd_; + _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept; +public: + _LIBCPP_HIDE_FROM_ABI weekday() = default; + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept : __wd_(static_cast(__val == 7 ? 0 : __val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept + : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(const local_days& __locd) noexcept + : __wd_(__weekday_from_days(__locd.time_since_epoch().count())) {} + + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator++() noexcept { __wd_ = (__wd_ == 6 ? 0 : __wd_ + 1); return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator--() noexcept { __wd_ = (__wd_ == 0 ? 6 : __wd_ - 1); return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator+=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator-=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned c_encoding() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned iso_encoding() const noexcept { return __wd_ == 0u ? 7 : __wd_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_ <= 6; } + _LIBCPP_HIDE_FROM_ABI constexpr weekday_indexed operator[](unsigned __index) const noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday_last operator[](last_spec) const noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days +_LIBCPP_HIDE_FROM_ABI inline constexpr +unsigned char weekday::__weekday_from_days(int __days) noexcept +{ + return static_cast( + static_cast(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) + ); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept +{ return __lhs.c_encoding() == __rhs.c_encoding(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept +{ return __lhs.c_encoding() < __rhs.c_encoding(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept +{ return __rhs < __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__rhs < __lhs);} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs < __rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr +weekday operator+(const weekday& __lhs, const days& __rhs) noexcept +{ + auto const __mu = static_cast(__lhs.c_encoding()) + __rhs.count(); + auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; + return weekday{static_cast(__mu - __yr * 7)}; +} + +_LIBCPP_HIDE_FROM_ABI constexpr +weekday operator+(const days& __lhs, const weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +weekday operator-(const weekday& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +days operator-(const weekday& __lhs, const weekday& __rhs) noexcept +{ + const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); + const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; + return days{__wdu - __wk * 7}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +weekday& weekday::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +weekday& weekday::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + +class weekday_indexed { +private: + chrono::weekday __wd_; + unsigned char __idx_; +public: + _LIBCPP_HIDE_FROM_ABI weekday_indexed() = default; + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept + : __wd_{__wdval}, __idx_(__idxval) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __idx_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_.ok() && __idx_ >= 1 && __idx_ <= 5; } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +class weekday_last { +private: + chrono::weekday __wd_; +public: + _LIBCPP_HIDE_FROM_ABI explicit constexpr weekday_last(const chrono::weekday& __val) noexcept + : __wd_{__val} {} + _LIBCPP_HIDE_FROM_ABI constexpr chrono::weekday weekday() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept { return __wd_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } + + +inline constexpr weekday Sunday{0}; +inline constexpr weekday Monday{1}; +inline constexpr weekday Tuesday{2}; +inline constexpr weekday Wednesday{3}; +inline constexpr weekday Thursday{4}; +inline constexpr weekday Friday{5}; +inline constexpr weekday Saturday{6}; + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_WEEKDAY_H diff --git a/gnu/llvm/libcxx/include/__chrono/year.h b/gnu/llvm/libcxx/include/__chrono/year.h new file mode 100644 index 00000000000..79ee8a02b8f --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/year.h @@ -0,0 +1,102 @@ +// -*- 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___CHRONO_YEAR_H +#define _LIBCPP___CHRONO_YEAR_H + +#include <__chrono/duration.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class year { +private: + short __y_; +public: + _LIBCPP_HIDE_FROM_ABI year() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y_(static_cast(__val)) {} + + _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++() noexcept { ++__y_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator--() noexcept { --__y_; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; } + _LIBCPP_HIDE_FROM_ABI constexpr year& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year& operator-=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator+() const noexcept { return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator-() const noexcept { return year{-__y_}; } + + _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_leap() const noexcept { return __y_ % 4 == 0 && (__y_ % 100 != 0 || __y_ % 400 == 0); } + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator int() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + _LIBCPP_HIDE_FROM_ABI static inline constexpr year min() noexcept { return year{-32767}; } + _LIBCPP_HIDE_FROM_ABI static inline constexpr year max() noexcept { return year{ 32767}; } +}; + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year& __lhs, const year& __rhs) noexcept +{ return static_cast(__lhs) == static_cast(__rhs); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const year& __lhs, const year& __rhs) noexcept { + return static_cast(__lhs) <=> static_cast(__rhs); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year operator+ (const year& __lhs, const years& __rhs) noexcept +{ return year(static_cast(__lhs) + __rhs.count()); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year operator+ (const years& __lhs, const year& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year operator- (const year& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +years operator-(const year& __lhs, const year& __rhs) noexcept +{ return years{static_cast(__lhs) - static_cast(__rhs)}; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year& year::operator+=(const years& __dy) noexcept +{ *this = *this + __dy; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year& year::operator-=(const years& __dy) noexcept +{ *this = *this - __dy; return *this; } + +_LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept { + static_assert(static_cast(std::numeric_limits::max()) == static_cast(max())); + return static_cast(min()) <= __y_; +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___CHRONO_YEAR_H diff --git a/gnu/llvm/libcxx/include/__chrono/year_month.h b/gnu/llvm/libcxx/include/__chrono/year_month.h new file mode 100644 index 00000000000..9f1e65c8c83 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/year_month.h @@ -0,0 +1,101 @@ +// -*- 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___CHRONO_YEAR_MONTH_H +#define _LIBCPP___CHRONO_YEAR_MONTH_H + +#include <__chrono/duration.h> +#include <__chrono/month.h> +#include <__chrono/year.h> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class year_month { + chrono::year __y_; + chrono::month __m_; +public: + _LIBCPP_HIDE_FROM_ABI year_month() = default; + _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept + : __y_{__yval}, __m_{__mval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m_ += __dm; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m_ -= __dm; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y_ += __dy; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y_ -= __dy; return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const year_month& __lhs, const year_month& __rhs) noexcept { + if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) + return __c; + return __lhs.month() <=> __rhs.month(); +} + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator+(const year_month& __lhs, const months& __rhs) noexcept +{ + int __dmi = static_cast(static_cast(__lhs.month())) - 1 + __rhs.count(); + const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; + __dmi = __dmi - __dy * 12 + 1; + return (__lhs.year() + years(__dy)) / month(static_cast(__dmi)); +} + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator+(const months& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator+(const year_month& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month(); } + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator+(const years& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +months operator-(const year_month& __lhs, const year_month& __rhs) noexcept +{ return (__lhs.year() - __rhs.year()) + months(static_cast(__lhs.month()) - static_cast(__rhs.month())); } + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator-(const year_month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI constexpr +year_month operator-(const year_month& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_YEAR_MONTH_H diff --git a/gnu/llvm/libcxx/include/__chrono/year_month_day.h b/gnu/llvm/libcxx/include/__chrono/year_month_day.h new file mode 100644 index 00000000000..b74901470c6 --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/year_month_day.h @@ -0,0 +1,307 @@ +// -*- 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___CHRONO_YEAR_MONTH_DAY_H +#define _LIBCPP___CHRONO_YEAR_MONTH_DAY_H + +#include <__chrono/calendar.h> +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/month.h> +#include <__chrono/monthday.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class year_month_day_last; + +class year_month_day { +private: + chrono::year __y_; + chrono::month __m_; + chrono::day __d_; +public: + _LIBCPP_HIDE_FROM_ABI year_month_day() = default; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day( + const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept + : __y_{__yval}, __m_{__mval}, __d_{__dval} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(const sys_days& __sysd) noexcept + : year_month_day(__from_days(__sysd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_day(const local_days& __locd) noexcept + : year_month_day(__from_days(__locd.time_since_epoch())) {} + + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const years& __dy) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + + _LIBCPP_HIDE_FROM_ABI static constexpr year_month_day __from_days(days __d) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#civil_from_days +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day year_month_day::__from_days(days __d) noexcept +{ + static_assert(numeric_limits::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20 , ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] + const int __yr = static_cast(__yoe) + __era * 400; + const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] + const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] + const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] + const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] + return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; +} + +// https://howardhinnant.github.io/date_algorithms.html#days_from_civil +_LIBCPP_HIDE_FROM_ABI inline constexpr +days year_month_day::__to_days() const noexcept +{ + static_assert(numeric_limits::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20 , ""); + + const int __yr = static_cast(__y_) - (__m_ <= February); + const unsigned __mth = static_cast(__m_); + const unsigned __dy = static_cast(__d_); + + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast(__yr - __era * 400); // [0, 399] + const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] + const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] + return days{__era * 146097 + static_cast(__doe) - 719468}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering +operator<=>(const year_month_day& __lhs, const year_month_day& __rhs) noexcept { + if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) + return __c; + if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) + return __c; + return __lhs.day() <=> __rhs.day(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept +{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const year_month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept +{ return __lhs / __rhs.month() / __rhs.day(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(int __lhs, const month_day& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator/(const month_day& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept +{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class year_month_day_last { +private: + chrono::year __y_; + chrono::month_day_last __mdl_; +public: + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept + : __y_{__yval}, __mdl_{__mdlval} {} + + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const months& __m) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const months& __m) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const years& __y) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const years& __y) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __mdl_.month(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::day day() const noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __mdl_.ok(); } +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +chrono::day year_month_day_last::day() const noexcept +{ + constexpr chrono::day __d[] = + { + chrono::day(31), chrono::day(28), chrono::day(31), + chrono::day(30), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(30), chrono::day(31) + }; + return (month() != February || !__y_.is_leap()) && month().ok() ? + __d[static_cast(month()) - 1] : chrono::day{29}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ + if (__lhs.year() < __rhs.year()) return true; + if (__lhs.year() > __rhs.year()) return false; + return __lhs.month_day_last() < __rhs.month_day_last(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs < __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__rhs < __lhs);} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs < __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept +{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{__lhs, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{year{__lhs}, __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator/(const month_day_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept +{ return year{__rhs} / __lhs; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / last; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept + : __y_{__ymdl.year()}, __m_{__ymdl.month()}, __d_{__ymdl.day()} {} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool year_month_day::ok() const noexcept +{ + if (!__y_.ok() || !__m_.ok()) return false; + return chrono::day{1} <= __d_ && __d_ <= (__y_ / __m_ / last).day(); +} + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_YEAR_MONTH_DAY_H diff --git a/gnu/llvm/libcxx/include/__chrono/year_month_weekday.h b/gnu/llvm/libcxx/include/__chrono/year_month_weekday.h new file mode 100644 index 00000000000..6604deaf12c --- /dev/null +++ b/gnu/llvm/libcxx/include/__chrono/year_month_weekday.h @@ -0,0 +1,255 @@ +// -*- 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___CHRONO_YEAR_MONTH_WEEKDAY_H +#define _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H + +#include <__chrono/calendar.h> +#include <__chrono/day.h> +#include <__chrono/duration.h> +#include <__chrono/month.h> +#include <__chrono/month_weekday.h> +#include <__chrono/system_clock.h> +#include <__chrono/time_point.h> +#include <__chrono/weekday.h> +#include <__chrono/year.h> +#include <__chrono/year_month.h> +#include <__chrono/year_month_day.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace chrono +{ + +class year_month_weekday { + chrono::year __y_; + chrono::month __m_; + chrono::weekday_indexed __wdi_; +public: + _LIBCPP_HIDE_FROM_ABI year_month_weekday() = default; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_indexed& __wdival) noexcept + : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept + : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept + : year_month_weekday(__from_days(__locd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi_.weekday(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi_.index(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } + + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept + { + if (!__y_.ok() || !__m_.ok() || !__wdi_.ok()) return false; + if (__wdi_.index() <= 4) return true; + auto __nth_weekday_day = + __wdi_.weekday() - + chrono::weekday{static_cast(__y_ / __m_ / 1)} + + days{(__wdi_.index() - 1) * 7 + 1}; + return static_cast(__nth_weekday_day.count()) <= + static_cast((__y_ / __m_ / last).day()); + } + + _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday year_month_weekday::__from_days(days __d) noexcept +{ + const sys_days __sysd{__d}; + const chrono::weekday __wd = chrono::weekday(__sysd); + const year_month_day __ymd = year_month_day(__sysd); + return year_month_weekday{__ymd.year(), __ymd.month(), + __wd[(static_cast(__ymd.day())-1)/7+1]}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +days year_month_weekday::__to_days() const noexcept +{ + const sys_days __sysd = sys_days(__y_/__m_/1); + return (__sysd + (__wdi_.weekday() - chrono::weekday(__sysd) + days{(__wdi_.index()-1)*7})) + .time_since_epoch(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept +{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept +{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class year_month_weekday_last { +private: + chrono::year __y_; + chrono::month __m_; + chrono::weekday_last __wdl_; +public: + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_last& __wdlval) noexcept + : __y_{__yval}, __m_{__mval}, __wdl_{__wdlval} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; + + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl_.weekday(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok() && __wdl_.ok(); } + + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; + +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr +days year_month_weekday_last::__to_days() const noexcept +{ + const sys_days __last = sys_days{__y_/__m_/last}; + return (__last - (chrono::weekday{__last} - __wdl_.weekday())).time_since_epoch(); + +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +_LIBCPP_HIDE_FROM_ABI inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +} // namespace chrono + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H diff --git a/gnu/llvm/libcxx/include/__compare/common_comparison_category.h b/gnu/llvm/libcxx/include/__compare/common_comparison_category.h new file mode 100644 index 00000000000..06c4b28491e --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/common_comparison_category.h @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_COMMON_COMPARISON_CATEGORY_H +#define _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H + +#include <__compare/ordering.h> +#include <__config> +#include <__type_traits/is_same.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __comp_detail { + +enum _ClassifyCompCategory : unsigned { + _None, + _PartialOrd, + _WeakOrd, + _StrongOrd, + _CCC_Size +}; + +template +_LIBCPP_HIDE_FROM_ABI +constexpr _ClassifyCompCategory __type_to_enum() noexcept { + if (is_same_v<_Tp, partial_ordering>) + return _PartialOrd; + if (is_same_v<_Tp, weak_ordering>) + return _WeakOrd; + if (is_same_v<_Tp, strong_ordering>) + return _StrongOrd; + return _None; +} + +template +_LIBCPP_HIDE_FROM_ABI +constexpr _ClassifyCompCategory +__compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { + int __seen[_CCC_Size] = {}; + for (auto __type : __types) + ++__seen[__type]; + if (__seen[_None]) + return _None; + if (__seen[_PartialOrd]) + return _PartialOrd; + if (__seen[_WeakOrd]) + return _WeakOrd; + return _StrongOrd; +} + +template +_LIBCPP_HIDE_FROM_ABI +constexpr auto __get_comp_type() { + using _CCC = _ClassifyCompCategory; + constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...}; + constexpr _CCC _Cat = __comp_detail::__compute_comp_type(__type_kinds); + if constexpr (_Cat == _None) + return void(); + else if constexpr (_Cat == _PartialOrd) + return partial_ordering::equivalent; + else if constexpr (_Cat == _WeakOrd) + return weak_ordering::equivalent; + else if constexpr (_Cat == _StrongOrd) + return strong_ordering::equivalent; + else + static_assert(_False, "unhandled case"); +} +} // namespace __comp_detail + +// [cmp.common], common comparison category type +template +struct _LIBCPP_TEMPLATE_VIS common_comparison_category { + using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); +}; + +template +using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H diff --git a/gnu/llvm/libcxx/include/__compare/compare_partial_order_fallback.h b/gnu/llvm/libcxx/include/__compare/compare_partial_order_fallback.h new file mode 100644 index 00000000000..06f03fe7ade --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/compare_partial_order_fallback.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK +#define _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK + +#include <__compare/ordering.h> +#include <__compare/partial_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__type_traits/is_same.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __compare_partial_order_fallback { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(_VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + -> decltype( _VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) + { return _VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : + partial_ordering::unordered)) + -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : + partial_ordering::unordered) + { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : + _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : + partial_ordering::unordered; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } + }; +} // namespace __compare_partial_order_fallback + +inline namespace __cpo { + inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK diff --git a/gnu/llvm/libcxx/include/__compare/compare_strong_order_fallback.h b/gnu/llvm/libcxx/include/__compare/compare_strong_order_fallback.h new file mode 100644 index 00000000000..869386817a1 --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/compare_strong_order_fallback.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_COMPARE_STRONG_ORDER_FALLBACK +#define _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK + +#include <__compare/ordering.h> +#include <__compare/strong_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__type_traits/is_same.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __compare_strong_order_fallback { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + -> decltype( _VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) + { return _VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : + strong_ordering::greater)) + -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : + strong_ordering::greater) + { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : + strong_ordering::greater; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } + }; +} // namespace __compare_strong_order_fallback + +inline namespace __cpo { + inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK diff --git a/gnu/llvm/libcxx/include/__compare/compare_three_way.h b/gnu/llvm/libcxx/include/__compare/compare_three_way.h new file mode 100644 index 00000000000..fdbba04a78e --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/compare_three_way.h @@ -0,0 +1,41 @@ +// -*- 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___COMPARE_COMPARE_THREE_WAY_H +#define _LIBCPP___COMPARE_COMPARE_THREE_WAY_H + +#include <__compare/three_way_comparable.h> +#include <__config> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +struct _LIBCPP_TEMPLATE_VIS compare_three_way +{ + template + requires three_way_comparable_with<_T1, _T2> + constexpr _LIBCPP_HIDE_FROM_ABI + auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(_VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u))) + { return _VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u); } + + using is_transparent = void; +}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_THREE_WAY_H diff --git a/gnu/llvm/libcxx/include/__compare/compare_three_way_result.h b/gnu/llvm/libcxx/include/__compare/compare_three_way_result.h new file mode 100644 index 00000000000..8885d7effad --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/compare_three_way_result.h @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_COMPARE_THREE_WAY_RESULT_H +#define _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H + +#include <__config> +#include <__type_traits/make_const_lvalue_ref.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result { }; + +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result<_Tp, _Up, decltype( + std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>(), void() +)> { + using type = decltype(std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>()); +}; + +template +struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_result<_Tp, _Up, void> { }; + +template +using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H diff --git a/gnu/llvm/libcxx/include/__compare/compare_weak_order_fallback.h b/gnu/llvm/libcxx/include/__compare/compare_weak_order_fallback.h new file mode 100644 index 00000000000..f434dcb4a31 --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/compare_weak_order_fallback.h @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_COMPARE_WEAK_ORDER_FALLBACK +#define _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK + +#include <__compare/ordering.h> +#include <__compare/weak_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__type_traits/is_same.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __compare_weak_order_fallback { + struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + -> decltype( _VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) + { return _VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : + weak_ordering::greater)) + -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : + weak_ordering::greater) + { + return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : + _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : + weak_ordering::greater; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } + }; +} // namespace __compare_weak_order_fallback + +inline namespace __cpo { + inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK diff --git a/gnu/llvm/libcxx/include/__compare/is_eq.h b/gnu/llvm/libcxx/include/__compare/is_eq.h new file mode 100644 index 00000000000..49648924e81 --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/is_eq.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_IS_EQ_H +#define _LIBCPP___COMPARE_IS_EQ_H + +#include <__compare/ordering.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; } + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_IS_EQ_H diff --git a/gnu/llvm/libcxx/include/__compare/ordering.h b/gnu/llvm/libcxx/include/__compare/ordering.h new file mode 100644 index 00000000000..ff148abf234 --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/ordering.h @@ -0,0 +1,326 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_ORDERING_H +#define _LIBCPP___COMPARE_ORDERING_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_same.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// exposition only +enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { + __less = -1, + __equiv = 0, + __greater = 1 +}; + +enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { + __unordered = -127 +}; + +class partial_ordering; +class weak_ordering; +class strong_ordering; + +template +inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...); + +struct _CmpUnspecifiedParam { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL + _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} + + template>> + _CmpUnspecifiedParam(_Tp) = delete; +}; + +class partial_ordering { + using _ValueT = signed char; + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr partial_ordering(_OrdResult __v) noexcept + : __value_(_ValueT(__v)) {} + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr partial_ordering(_NCmpResult __v) noexcept + : __value_(_ValueT(__v)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr bool __is_ordered() const noexcept { + return __value_ != _ValueT(_NCmpResult::__unordered); + } +public: + // valid values + static const partial_ordering less; + static const partial_ordering equivalent; + static const partial_ordering greater; + static const partial_ordering unordered; + + // comparisons + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ < 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ <= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ > 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__is_ordered() && __v.__value_ >= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 < __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 <= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 > __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v.__is_ordered() && 0 >= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); + } +private: + _ValueT __value_; +}; + +inline constexpr partial_ordering partial_ordering::less(_OrdResult::__less); +inline constexpr partial_ordering partial_ordering::equivalent(_OrdResult::__equiv); +inline constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater); +inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered); + +class weak_ordering { + using _ValueT = signed char; + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + +public: + static const weak_ordering less; + static const weak_ordering equivalent; + static const weak_ordering greater; + + _LIBCPP_HIDE_FROM_ABI + constexpr operator partial_ordering() const noexcept { + return __value_ == 0 ? partial_ordering::equivalent + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + } + + // comparisons + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ < 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ <= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ > 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ >= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 < __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 <= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 > __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return 0 >= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); + } + +private: + _ValueT __value_; +}; + +inline constexpr weak_ordering weak_ordering::less(_OrdResult::__less); +inline constexpr weak_ordering weak_ordering::equivalent(_OrdResult::__equiv); +inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); + +class strong_ordering { + using _ValueT = signed char; + + _LIBCPP_HIDE_FROM_ABI + explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + +public: + static const strong_ordering less; + static const strong_ordering equal; + static const strong_ordering equivalent; + static const strong_ordering greater; + + // conversions + _LIBCPP_HIDE_FROM_ABI + constexpr operator partial_ordering() const noexcept { + return __value_ == 0 ? partial_ordering::equivalent + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr operator weak_ordering() const noexcept { + return __value_ == 0 ? weak_ordering::equivalent + : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); + } + + // comparisons + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ == 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ < 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ <= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ > 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v.__value_ >= 0; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 < __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 <= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 > __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return 0 >= __v.__value_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + return __v; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); + } + +private: + _ValueT __value_; +}; + +inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less); +inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv); +inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv); +inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); + +/// [cmp.categories.pre]/1 +/// The types partial_ordering, weak_ordering, and strong_ordering are +/// collectively termed the comparison category types. +template +concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_ORDERING_H diff --git a/gnu/llvm/libcxx/include/__compare/partial_order.h b/gnu/llvm/libcxx/include/__compare/partial_order.h new file mode 100644 index 00000000000..aee07ebb428 --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/partial_order.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COMPARE_PARTIAL_ORDER +#define _LIBCPP___COMPARE_PARTIAL_ORDER + +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__compare/weak_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__type_traits/is_same.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __partial_order { + struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) partial_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) + noexcept(noexcept(partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + // NOLINTEND(libcpp-robust-against-adl) + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } + }; +} // namespace __partial_order + +inline namespace __cpo { + inline constexpr auto partial_order = __partial_order::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_PARTIAL_ORDER diff --git a/gnu/llvm/libcxx/include/__compare/strong_order.h b/gnu/llvm/libcxx/include/__compare/strong_order.h new file mode 100644 index 00000000000..05856c20939 --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/strong_order.h @@ -0,0 +1,139 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_STRONG_ORDER +#define _LIBCPP___COMPARE_STRONG_ORDER + +#include <__bit/bit_cast.h> +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__config> +#include <__type_traits/conditional.h> +#include <__type_traits/decay.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include +#include +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __strong_order { + struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) strong_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) + noexcept(noexcept(strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + // NOLINTEND(libcpp-robust-against-adl) + + template> + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept + { + if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) { + int32_t __rx = _VSTD::bit_cast(__t); + int32_t __ry = _VSTD::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) { + int64_t __rx = _VSTD::bit_cast(__t); + int64_t __ry = _VSTD::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if (__t < __u) { + return strong_ordering::less; + } else if (__t > __u) { + return strong_ordering::greater; + } else if (__t == __u) { + if constexpr (numeric_limits<_Dp>::radix == 2) { + return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); + } else { + // This is bullet 3 of the IEEE754 algorithm, relevant + // only for decimal floating-point; + // see https://stackoverflow.com/questions/69068075/ + if (__t == 0 || _VSTD::isinf(__t)) { + return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); + } else { + int __texp, __uexp; + (void)_VSTD::frexp(__t, &__texp); + (void)_VSTD::frexp(__u, &__uexp); + return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp); + } + } + } else { + // They're unordered, so one of them must be a NAN. + // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN. + bool __t_is_nan = _VSTD::isnan(__t); + bool __u_is_nan = _VSTD::isnan(__u); + bool __t_is_negative = _VSTD::signbit(__t); + bool __u_is_negative = _VSTD::signbit(__u); + using _IntType = conditional_t< + sizeof(__t) == sizeof(int32_t), int32_t, conditional_t< + sizeof(__t) == sizeof(int64_t), int64_t, void> + >; + if constexpr (is_same_v<_IntType, void>) { + static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type"); + } else if (__t_is_nan && __u_is_nan) { + // Order by sign bit, then by "payload bits" (we'll just use bit_cast). + if (__t_is_negative != __u_is_negative) { + return (__u_is_negative <=> __t_is_negative); + } else { + return _VSTD::bit_cast<_IntType>(__t) <=> _VSTD::bit_cast<_IntType>(__u); + } + } else if (__t_is_nan) { + return __t_is_negative ? strong_ordering::less : strong_ordering::greater; + } else { + return __u_is_negative ? strong_ordering::greater : strong_ordering::less; + } + } + } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } + }; +} // namespace __strong_order + +inline namespace __cpo { + inline constexpr auto strong_order = __strong_order::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___COMPARE_STRONG_ORDER diff --git a/gnu/llvm/libcxx/include/__compare/synth_three_way.h b/gnu/llvm/libcxx/include/__compare/synth_three_way.h new file mode 100644 index 00000000000..7d338987e0d --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/synth_three_way.h @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_SYNTH_THREE_WAY_H +#define _LIBCPP___COMPARE_SYNTH_THREE_WAY_H + +#include <__compare/ordering.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/boolean_testable.h> +#include <__config> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [expos.only.func] + +_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way = + [](const _Tp& __t, const _Up& __u) + requires requires { + { __t < __u } -> __boolean_testable; + { __u < __t } -> __boolean_testable; + } + { + if constexpr (three_way_comparable_with<_Tp, _Up>) { + return __t <=> __u; + } else { + if (__t < __u) return weak_ordering::less; + if (__u < __t) return weak_ordering::greater; + return weak_ordering::equivalent; + } + }; + +template +using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>())); + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_SYNTH_THREE_WAY_H diff --git a/gnu/llvm/libcxx/include/__compare/three_way_comparable.h b/gnu/llvm/libcxx/include/__compare/three_way_comparable.h new file mode 100644 index 00000000000..6c98916d858 --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/three_way_comparable.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_THREE_WAY_COMPARABLE_H +#define _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H + +#include <__compare/common_comparison_category.h> +#include <__compare/ordering.h> +#include <__concepts/common_reference_with.h> +#include <__concepts/equality_comparable.h> +#include <__concepts/same_as.h> +#include <__concepts/totally_ordered.h> +#include <__config> +#include <__type_traits/common_reference.h> +#include <__type_traits/make_const_lvalue_ref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept __compares_as = + same_as, _Cat>; + +template +concept three_way_comparable = + __weakly_equality_comparable_with<_Tp, _Tp> && + __partially_ordered_with<_Tp, _Tp> && + requires(__make_const_lvalue_ref<_Tp> __a, __make_const_lvalue_ref<_Tp> __b) { + { __a <=> __b } -> __compares_as<_Cat>; + }; + +template +concept three_way_comparable_with = + three_way_comparable<_Tp, _Cat> && + three_way_comparable<_Up, _Cat> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && + three_way_comparable, __make_const_lvalue_ref<_Up>>, _Cat> && + __weakly_equality_comparable_with<_Tp, _Up> && + __partially_ordered_with<_Tp, _Up> && + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t <=> __u } -> __compares_as<_Cat>; + { __u <=> __t } -> __compares_as<_Cat>; + }; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H diff --git a/gnu/llvm/libcxx/include/__compare/weak_order.h b/gnu/llvm/libcxx/include/__compare/weak_order.h new file mode 100644 index 00000000000..abb24e3665b --- /dev/null +++ b/gnu/llvm/libcxx/include/__compare/weak_order.h @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// 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___COMPARE_WEAK_ORDER +#define _LIBCPP___COMPARE_WEAK_ORDER + +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> +#include <__compare/strong_order.h> +#include <__config> +#include <__type_traits/decay.h> +#include <__utility/forward.h> +#include <__utility/priority_tag.h> +#include + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [cmp.alg] +namespace __weak_order { + struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) weak_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<3>) + noexcept(noexcept(weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + // NOLINTEND(libcpp-robust-against-adl) + + template> + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering + __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept + { + partial_ordering __po = (__t <=> __u); + if (__po == partial_ordering::less) { + return weak_ordering::less; + } else if (__po == partial_ordering::equivalent) { + return weak_ordering::equivalent; + } else if (__po == partial_ordering::greater) { + return weak_ordering::greater; + } else { + // Otherwise, at least one of them is a NaN. + bool __t_is_nan = _VSTD::isnan(__t); + bool __u_is_nan = _VSTD::isnan(__u); + bool __t_is_negative = _VSTD::signbit(__t); + bool __u_is_negative = _VSTD::signbit(__u); + if (__t_is_nan && __u_is_nan) { + return (__u_is_negative <=> __t_is_negative); + } else if (__t_is_nan) { + return __t_is_negative ? weak_ordering::less : weak_ordering::greater; + } else { + return __u_is_negative ? weak_ordering::greater : weak_ordering::less; + } + } + } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) + noexcept(noexcept(weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) + noexcept(noexcept(weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) + -> decltype( weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { return weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()))) + -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>())) + { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()); } + }; +} // namespace __weak_order + +inline namespace __cpo { + inline constexpr auto weak_order = __weak_order::__fn{}; +} // namespace __cpo + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___COMPARE_WEAK_ORDER diff --git a/gnu/llvm/libcxx/include/__concepts/arithmetic.h b/gnu/llvm/libcxx/include/__concepts/arithmetic.h new file mode 100644 index 00000000000..215b52aa021 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/arithmetic.h @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_ARITHMETIC_H +#define _LIBCPP___CONCEPTS_ARITHMETIC_H + +#include <__config> +#include <__type_traits/is_floating_point.h> +#include <__type_traits/is_integral.h> +#include <__type_traits/is_signed.h> +#include <__type_traits/is_signed_integer.h> +#include <__type_traits/is_unsigned_integer.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concepts.arithmetic], arithmetic concepts + +template +concept integral = is_integral_v<_Tp>; + +template +concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; + +template +concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; + +template +concept floating_point = is_floating_point_v<_Tp>; + +// Concept helpers for the internal type traits for the fundamental types. + +template +concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value; +template +concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_ARITHMETIC_H diff --git a/gnu/llvm/libcxx/include/__concepts/assignable.h b/gnu/llvm/libcxx/include/__concepts/assignable.h new file mode 100644 index 00000000000..91edd400adf --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/assignable.h @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_ASSIGNABLE_H +#define _LIBCPP___CONCEPTS_ASSIGNABLE_H + +#include <__concepts/common_reference_with.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__type_traits/is_reference.h> +#include <__type_traits/make_const_lvalue_ref.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.assignable] + +template +concept assignable_from = + is_lvalue_reference_v<_Lhs> && + common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && + requires (_Lhs __lhs, _Rhs&& __rhs) { + { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; + }; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_ASSIGNABLE_H diff --git a/gnu/llvm/libcxx/include/__concepts/boolean_testable.h b/gnu/llvm/libcxx/include/__concepts/boolean_testable.h new file mode 100644 index 00000000000..a96bde71174 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/boolean_testable.h @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_BOOLEAN_TESTABLE_H +#define _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H + +#include <__concepts/convertible_to.h> +#include <__config> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concepts.booleantestable] + +template +concept __boolean_testable_impl = convertible_to<_Tp, bool>; + +template +concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) { + { !_VSTD::forward<_Tp>(__t) } -> __boolean_testable_impl; +}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H diff --git a/gnu/llvm/libcxx/include/__concepts/class_or_enum.h b/gnu/llvm/libcxx/include/__concepts/class_or_enum.h new file mode 100644 index 00000000000..c4d2f98952c --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/class_or_enum.h @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_CLASS_OR_ENUM_H +#define _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H + +#include <__config> +#include <__type_traits/is_class.h> +#include <__type_traits/is_enum.h> +#include <__type_traits/is_union.h> +#include <__type_traits/remove_cvref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// Whether a type is a class type or enumeration type according to the Core wording. + +template +concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; + +// Work around Clang bug https://llvm.org/PR52970 +// TODO: remove this workaround once libc++ no longer has to support Clang 13 (it was fixed in Clang 14). +template +concept __workaround_52970 = is_class_v<__remove_cvref_t<_Tp>> || is_union_v<__remove_cvref_t<_Tp>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H diff --git a/gnu/llvm/libcxx/include/__concepts/common_reference_with.h b/gnu/llvm/libcxx/include/__concepts/common_reference_with.h new file mode 100644 index 00000000000..cc92762d310 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/common_reference_with.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H +#define _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H + +#include <__concepts/convertible_to.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__type_traits/common_reference.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.commonref] + +template +concept common_reference_with = + same_as, common_reference_t<_Up, _Tp>> && + convertible_to<_Tp, common_reference_t<_Tp, _Up>> && + convertible_to<_Up, common_reference_t<_Tp, _Up>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H diff --git a/gnu/llvm/libcxx/include/__concepts/common_with.h b/gnu/llvm/libcxx/include/__concepts/common_with.h new file mode 100644 index 00000000000..569a0ee3b76 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/common_with.h @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_COMMON_WITH_H +#define _LIBCPP___CONCEPTS_COMMON_WITH_H + +#include <__concepts/common_reference_with.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__type_traits/add_lvalue_reference.h> +#include <__type_traits/common_reference.h> +#include <__type_traits/common_type.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.common] + +template +concept common_with = + same_as, common_type_t<_Up, _Tp>> && + requires { + static_cast>(std::declval<_Tp>()); + static_cast>(std::declval<_Up>()); + } && + common_reference_with< + add_lvalue_reference_t, + add_lvalue_reference_t> && + common_reference_with< + add_lvalue_reference_t>, + common_reference_t< + add_lvalue_reference_t, + add_lvalue_reference_t>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COMMON_WITH_H diff --git a/gnu/llvm/libcxx/include/__concepts/constructible.h b/gnu/llvm/libcxx/include/__concepts/constructible.h new file mode 100644 index 00000000000..1d78eb5fd15 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/constructible.h @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_CONSTRUCTIBLE_H +#define _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H + +#include <__concepts/convertible_to.h> +#include <__concepts/destructible.h> +#include <__config> +#include <__type_traits/is_constructible.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.constructible] +template +concept constructible_from = + destructible<_Tp> && is_constructible_v<_Tp, _Args...>; + +// [concept.default.init] + +template +concept __default_initializable = requires { ::new _Tp; }; + +template +concept default_initializable = constructible_from<_Tp> && + requires { _Tp{}; } && __default_initializable<_Tp>; + +// [concept.moveconstructible] +template +concept move_constructible = + constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; + +// [concept.copyconstructible] +template +concept copy_constructible = + move_constructible<_Tp> && + constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && + constructible_from<_Tp, const _Tp&> && convertible_to && + constructible_from<_Tp, const _Tp> && convertible_to; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H diff --git a/gnu/llvm/libcxx/include/__concepts/convertible_to.h b/gnu/llvm/libcxx/include/__concepts/convertible_to.h new file mode 100644 index 00000000000..2c1d2674100 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/convertible_to.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H +#define _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H + +#include <__config> +#include <__type_traits/is_convertible.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.convertible] + +template +concept convertible_to = + is_convertible_v<_From, _To> && + requires { + static_cast<_To>(std::declval<_From>()); + }; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H diff --git a/gnu/llvm/libcxx/include/__concepts/copyable.h b/gnu/llvm/libcxx/include/__concepts/copyable.h new file mode 100644 index 00000000000..c5d8a80b9da --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/copyable.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_COPYABLE_H +#define _LIBCPP___CONCEPTS_COPYABLE_H + +#include <__concepts/assignable.h> +#include <__concepts/constructible.h> +#include <__concepts/movable.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concepts.object] + +template +concept copyable = + copy_constructible<_Tp> && + movable<_Tp> && + assignable_from<_Tp&, _Tp&> && + assignable_from<_Tp&, const _Tp&> && + assignable_from<_Tp&, const _Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COPYABLE_H diff --git a/gnu/llvm/libcxx/include/__concepts/derived_from.h b/gnu/llvm/libcxx/include/__concepts/derived_from.h new file mode 100644 index 00000000000..0d3462df6a6 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/derived_from.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_DERIVED_FROM_H +#define _LIBCPP___CONCEPTS_DERIVED_FROM_H + +#include <__config> +#include <__type_traits/is_base_of.h> +#include <__type_traits/is_convertible.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.derived] + +template +concept derived_from = + is_base_of_v<_Bp, _Dp> && + is_convertible_v; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_DERIVED_FROM_H diff --git a/gnu/llvm/libcxx/include/__concepts/destructible.h b/gnu/llvm/libcxx/include/__concepts/destructible.h new file mode 100644 index 00000000000..ad3819d5dcf --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/destructible.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_DESTRUCTIBLE_H +#define _LIBCPP___CONCEPTS_DESTRUCTIBLE_H + +#include <__config> +#include <__type_traits/is_nothrow_destructible.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.destructible] + +template +concept destructible = is_nothrow_destructible_v<_Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_DESTRUCTIBLE_H diff --git a/gnu/llvm/libcxx/include/__concepts/different_from.h b/gnu/llvm/libcxx/include/__concepts/different_from.h new file mode 100644 index 00000000000..15fd8f05510 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/different_from.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_DIFFERENT_FROM_H +#define _LIBCPP___CONCEPTS_DIFFERENT_FROM_H + +#include <__concepts/same_as.h> +#include <__config> +#include <__type_traits/remove_cvref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept __different_from = !same_as, remove_cvref_t<_Up>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_DIFFERENT_FROM_H diff --git a/gnu/llvm/libcxx/include/__concepts/equality_comparable.h b/gnu/llvm/libcxx/include/__concepts/equality_comparable.h new file mode 100644 index 00000000000..b865141705f --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/equality_comparable.h @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_EQUALITY_COMPARABLE_H +#define _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/common_reference_with.h> +#include <__config> +#include <__type_traits/common_reference.h> +#include <__type_traits/make_const_lvalue_ref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.equalitycomparable] + +template +concept __weakly_equality_comparable_with = + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t == __u } -> __boolean_testable; + { __t != __u } -> __boolean_testable; + { __u == __t } -> __boolean_testable; + { __u != __t } -> __boolean_testable; + }; + +template +concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>; + +template +concept equality_comparable_with = + equality_comparable<_Tp> && equality_comparable<_Up> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && + equality_comparable< + common_reference_t< + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && + __weakly_equality_comparable_with<_Tp, _Up>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H diff --git a/gnu/llvm/libcxx/include/__concepts/invocable.h b/gnu/llvm/libcxx/include/__concepts/invocable.h new file mode 100644 index 00000000000..ec39b7b817c --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/invocable.h @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_INVOCABLE_H +#define _LIBCPP___CONCEPTS_INVOCABLE_H + +#include <__config> +#include <__functional/invoke.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.invocable] + +template +concept invocable = requires(_Fn&& __fn, _Args&&... __args) { + _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving +}; + +// [concept.regular.invocable] + +template +concept regular_invocable = invocable<_Fn, _Args...>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_INVOCABLE_H diff --git a/gnu/llvm/libcxx/include/__concepts/movable.h b/gnu/llvm/libcxx/include/__concepts/movable.h new file mode 100644 index 00000000000..749b78ad10b --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/movable.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_MOVABLE_H +#define _LIBCPP___CONCEPTS_MOVABLE_H + +#include <__concepts/assignable.h> +#include <__concepts/constructible.h> +#include <__concepts/swappable.h> +#include <__config> +#include <__type_traits/is_object.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concepts.object] + +template +concept movable = + is_object_v<_Tp> && + move_constructible<_Tp> && + assignable_from<_Tp&, _Tp> && + swappable<_Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_MOVABLE_H diff --git a/gnu/llvm/libcxx/include/__concepts/predicate.h b/gnu/llvm/libcxx/include/__concepts/predicate.h new file mode 100644 index 00000000000..7ae97832642 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/predicate.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_PREDICATE_H +#define _LIBCPP___CONCEPTS_PREDICATE_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/invocable.h> +#include <__config> +#include <__functional/invoke.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.predicate] + +template +concept predicate = + regular_invocable<_Fn, _Args...> && __boolean_testable>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_PREDICATE_H diff --git a/gnu/llvm/libcxx/include/__concepts/regular.h b/gnu/llvm/libcxx/include/__concepts/regular.h new file mode 100644 index 00000000000..d15728d298b --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/regular.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_REGULAR_H +#define _LIBCPP___CONCEPTS_REGULAR_H + +#include <__concepts/equality_comparable.h> +#include <__concepts/semiregular.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.object] + +template +concept regular = semiregular<_Tp> && equality_comparable<_Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_REGULAR_H diff --git a/gnu/llvm/libcxx/include/__concepts/relation.h b/gnu/llvm/libcxx/include/__concepts/relation.h new file mode 100644 index 00000000000..7d5141cac74 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/relation.h @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_RELATION_H +#define _LIBCPP___CONCEPTS_RELATION_H + +#include <__concepts/predicate.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.relation] + +template +concept relation = + predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && + predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; + +// [concept.equiv] + +template +concept equivalence_relation = relation<_Rp, _Tp, _Up>; + +// [concept.strictweakorder] + +template +concept strict_weak_order = relation<_Rp, _Tp, _Up>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_RELATION_H diff --git a/gnu/llvm/libcxx/include/__concepts/same_as.h b/gnu/llvm/libcxx/include/__concepts/same_as.h new file mode 100644 index 00000000000..554ebc3b074 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/same_as.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_SAME_AS_H +#define _LIBCPP___CONCEPTS_SAME_AS_H + +#include <__config> +#include <__type_traits/is_same.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.same] + +template +concept __same_as_impl = _IsSame<_Tp, _Up>::value; + +template +concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_SAME_AS_H diff --git a/gnu/llvm/libcxx/include/__concepts/semiregular.h b/gnu/llvm/libcxx/include/__concepts/semiregular.h new file mode 100644 index 00000000000..d15bb3ba42b --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/semiregular.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_SEMIREGULAR_H +#define _LIBCPP___CONCEPTS_SEMIREGULAR_H + +#include <__concepts/constructible.h> +#include <__concepts/copyable.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.object] + +template +concept semiregular = copyable<_Tp> && default_initializable<_Tp>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_SEMIREGULAR_H diff --git a/gnu/llvm/libcxx/include/__concepts/swappable.h b/gnu/llvm/libcxx/include/__concepts/swappable.h new file mode 100644 index 00000000000..d91a7a1dc3c --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/swappable.h @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_SWAPPABLE_H +#define _LIBCPP___CONCEPTS_SWAPPABLE_H + +#include <__concepts/assignable.h> +#include <__concepts/class_or_enum.h> +#include <__concepts/common_reference_with.h> +#include <__concepts/constructible.h> +#include <__config> +#include <__type_traits/extent.h> +#include <__type_traits/is_nothrow_move_assignable.h> +#include <__type_traits/is_nothrow_move_constructible.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/exchange.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.swappable] + +namespace ranges { +namespace __swap { + + template + void swap(_Tp&, _Tp&) = delete; + + template + concept __unqualified_swappable_with = + (__class_or_enum> || __class_or_enum>) && + requires(_Tp&& __t, _Up&& __u) { + swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + }; + + struct __fn; + + template + concept __swappable_arrays = + !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> && + extent_v<_Tp> == extent_v<_Up> && + requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) { + __swap(__t[0], __u[0]); + }; + + template + concept __exchangeable = + !__unqualified_swappable_with<_Tp&, _Tp&> && + move_constructible<_Tp> && + assignable_from<_Tp&, _Tp>; + + struct __fn { + // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... + // *The name `swap` is used here unqualified. + template + requires __unqualified_swappable_with<_Tp, _Up> + constexpr void operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) + { + swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + } + + // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... + template + requires __swappable_arrays<_Tp, _Up, _Size> + constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const + noexcept(noexcept((*this)(*__t, *__u))) + { + // TODO(cjdb): replace with `ranges::swap_ranges`. + for (size_t __i = 0; __i < _Size; ++__i) { + (*this)(__t[__i], __u[__i]); + } + } + + // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... + template<__exchangeable _Tp> + constexpr void operator()(_Tp& __x, _Tp& __y) const + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) + { + __y = _VSTD::exchange(__x, _VSTD::move(__y)); + } + }; +} // namespace __swap + +inline namespace __cpo { + inline constexpr auto swap = __swap::__fn{}; +} // namespace __cpo +} // namespace ranges + +template +concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); }; + +template +concept swappable_with = + common_reference_with<_Tp, _Up> && + requires(_Tp&& __t, _Up&& __u) { + ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t)); + ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u)); + ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t)); + }; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_SWAPPABLE_H diff --git a/gnu/llvm/libcxx/include/__concepts/totally_ordered.h b/gnu/llvm/libcxx/include/__concepts/totally_ordered.h new file mode 100644 index 00000000000..f12d26b1082 --- /dev/null +++ b/gnu/llvm/libcxx/include/__concepts/totally_ordered.h @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// 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___CONCEPTS_TOTALLY_ORDERED_H +#define _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/equality_comparable.h> +#include <__config> +#include <__type_traits/common_reference.h> +#include <__type_traits/make_const_lvalue_ref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// [concept.totallyordered] + +template +concept __partially_ordered_with = + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t < __u } -> __boolean_testable; + { __t > __u } -> __boolean_testable; + { __t <= __u } -> __boolean_testable; + { __t >= __u } -> __boolean_testable; + { __u < __t } -> __boolean_testable; + { __u > __t } -> __boolean_testable; + { __u <= __t } -> __boolean_testable; + { __u >= __t } -> __boolean_testable; + }; + +template +concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>; + +template +concept totally_ordered_with = + totally_ordered<_Tp> && totally_ordered<_Up> && + equality_comparable_with<_Tp, _Up> && + totally_ordered< + common_reference_t< + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && + __partially_ordered_with<_Tp, _Up>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H diff --git a/gnu/llvm/libcxx/include/__config_site.in b/gnu/llvm/libcxx/include/__config_site.in index e202d923f31..2ff67254c34 100644 --- a/gnu/llvm/libcxx/include/__config_site.in +++ b/gnu/llvm/libcxx/include/__config_site.in @@ -6,20 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_CONFIG_SITE -#define _LIBCPP_CONFIG_SITE +#ifndef _LIBCPP___CONFIG_SITE +#define _LIBCPP___CONFIG_SITE #cmakedefine _LIBCPP_ABI_VERSION @_LIBCPP_ABI_VERSION@ -#cmakedefine _LIBCPP_ABI_UNSTABLE +#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@ #cmakedefine _LIBCPP_ABI_FORCE_ITANIUM #cmakedefine _LIBCPP_ABI_FORCE_MICROSOFT -#cmakedefine _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT -#cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE -#cmakedefine _LIBCPP_HAS_NO_STDIN -#cmakedefine _LIBCPP_HAS_NO_STDOUT #cmakedefine _LIBCPP_HAS_NO_THREADS #cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK -#cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS #cmakedefine _LIBCPP_HAS_MUSL_LIBC #cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD #cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL @@ -29,14 +24,26 @@ #cmakedefine _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS #cmakedefine _LIBCPP_NO_VCRUNTIME #cmakedefine _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION @_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION@ -#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@ #cmakedefine _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY #cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS #cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE #cmakedefine _LIBCPP_HAS_NO_LOCALIZATION -#cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_FORMAT -#cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_RANGES +#cmakedefine _LIBCPP_HAS_NO_FSTREAM +#cmakedefine _LIBCPP_HAS_NO_WIDE_CHARACTERS +#cmakedefine01 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT +#cmakedefine _LIBCPP_ENABLE_DEBUG_MODE + +// __USE_MINGW_ANSI_STDIO gets redefined on MinGW +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmacro-redefined" +#endif @_LIBCPP_ABI_DEFINES@ +@_LIBCPP_EXTRA_SITE_DEFINES@ + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif -#endif // _LIBCPP_CONFIG_SITE +#endif // _LIBCPP___CONFIG_SITE diff --git a/gnu/llvm/libcxx/include/__coroutine/coroutine_handle.h b/gnu/llvm/libcxx/include/__coroutine/coroutine_handle.h new file mode 100644 index 00000000000..0a6cc1cab69 --- /dev/null +++ b/gnu/llvm/libcxx/include/__coroutine/coroutine_handle.h @@ -0,0 +1,203 @@ +//===----------------------------------------------------------------------===// +// +// 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___COROUTINE_COROUTINE_HANDLE_H +#define _LIBCPP___COROUTINE_COROUTINE_HANDLE_H + +#include <__assert> +#include <__config> +#include <__functional/hash.h> +#include <__memory/addressof.h> +#include <__type_traits/remove_cv.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [coroutine.handle] +template +struct _LIBCPP_TEMPLATE_VIS coroutine_handle; + +template <> +struct _LIBCPP_TEMPLATE_VIS coroutine_handle { +public: + // [coroutine.handle.con], construct/reset + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle() noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle(nullptr_t) noexcept {} + + _LIBCPP_HIDE_FROM_ABI + coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } + + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI + constexpr void* address() const noexcept { return __handle_; } + + _LIBCPP_HIDE_FROM_ABI + static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } + + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const noexcept { + return __handle_ != nullptr; + } + + _LIBCPP_HIDE_FROM_ABI + bool done() const { + _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } + + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI + void operator()() const { resume(); } + + _LIBCPP_HIDE_FROM_ABI + void resume() const { + _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } + + _LIBCPP_HIDE_FROM_ABI + void destroy() const { + _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } + +private: + bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } + + void* __handle_ = nullptr; +}; + +// [coroutine.handle.compare] +inline _LIBCPP_HIDE_FROM_ABI +constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return __x.address() == __y.address(); +} +inline _LIBCPP_HIDE_FROM_ABI +constexpr strong_ordering operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return compare_three_way()(__x.address(), __y.address()); +} + +template +struct _LIBCPP_TEMPLATE_VIS coroutine_handle { +public: + // [coroutine.handle.con], construct/reset + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle() noexcept = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr coroutine_handle(nullptr_t) noexcept {} + + _LIBCPP_HIDE_FROM_ABI + static coroutine_handle from_promise(_Promise& __promise) { + using _RawPromise = __remove_cv_t<_Promise>; + coroutine_handle __tmp; + __tmp.__handle_ = + __builtin_coro_promise(_VSTD::addressof(const_cast<_RawPromise&>(__promise)), alignof(_Promise), true); + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } + + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI + constexpr void* address() const noexcept { return __handle_; } + + _LIBCPP_HIDE_FROM_ABI + static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } + + // [coroutine.handle.conv], conversion + _LIBCPP_HIDE_FROM_ABI + constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } + + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const noexcept { + return __handle_ != nullptr; + } + + _LIBCPP_HIDE_FROM_ABI + bool done() const { + _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } + + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI + void operator()() const { resume(); } + + _LIBCPP_HIDE_FROM_ABI + void resume() const { + _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } + + _LIBCPP_HIDE_FROM_ABI + void destroy() const { + _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } + + // [coroutine.handle.promise], promise access + _LIBCPP_HIDE_FROM_ABI + _Promise& promise() const { + return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false)); + } + +private: + bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } + void* __handle_ = nullptr; +}; + +// [coroutine.handle.hash] +template +struct hash> { + _LIBCPP_HIDE_FROM_ABI + size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { return hash()(__v.address()); } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___COROUTINE_COROUTINE_HANDLE_H diff --git a/gnu/llvm/libcxx/include/__coroutine/coroutine_traits.h b/gnu/llvm/libcxx/include/__coroutine/coroutine_traits.h new file mode 100644 index 00000000000..d513075098c --- /dev/null +++ b/gnu/llvm/libcxx/include/__coroutine/coroutine_traits.h @@ -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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___COROUTINE_COROUTINE_TRAITS_H +#define _LIBCPP___COROUTINE_COROUTINE_TRAITS_H + +#include <__config> +#include <__type_traits/void_t.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [coroutine.traits] +// [coroutine.traits.primary] +// The header defined the primary template coroutine_traits such that +// if ArgTypes is a parameter pack of types and if the qualified-id R::promise_type +// is valid and denotes a type ([temp.deduct]), then coroutine_traits +// has the following publicly accessible memebr: +// +// using promise_type = typename R::promise_type; +// +// Otherwise, coroutine_traits has no members. +template +struct __coroutine_traits_sfinae {}; + +template +struct __coroutine_traits_sfinae< + _Tp, __void_t > +{ + using promise_type = typename _Tp::promise_type; +}; + +template +struct coroutine_traits + : public __coroutine_traits_sfinae<_Ret> +{ +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___COROUTINE_COROUTINE_TRAITS_H diff --git a/gnu/llvm/libcxx/include/__coroutine/noop_coroutine_handle.h b/gnu/llvm/libcxx/include/__coroutine/noop_coroutine_handle.h new file mode 100644 index 00000000000..299304794cc --- /dev/null +++ b/gnu/llvm/libcxx/include/__coroutine/noop_coroutine_handle.h @@ -0,0 +1,112 @@ +//===----------------------------------------------------------------------===// +// +// 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___COROUTINE_NOOP_COROUTINE_HANDLE_H +#define _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H + +#include <__config> +#include <__coroutine/coroutine_handle.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) + +// [coroutine.noop] +// [coroutine.promise.noop] +struct noop_coroutine_promise {}; + +// [coroutine.handle.noop] +template <> +struct _LIBCPP_TEMPLATE_VIS coroutine_handle { +public: + // [coroutine.handle.noop.conv], conversion + _LIBCPP_HIDE_FROM_ABI + constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } + + // [coroutine.handle.noop.observers], observers + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI + constexpr bool done() const noexcept { return false; } + + // [coroutine.handle.noop.resumption], resumption + _LIBCPP_HIDE_FROM_ABI + constexpr void operator()() const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void resume() const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void destroy() const noexcept {} + + // [coroutine.handle.noop.promise], promise access + _LIBCPP_HIDE_FROM_ABI + noop_coroutine_promise& promise() const noexcept { + return *static_cast( + __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false)); + } + + // [coroutine.handle.noop.address], address + _LIBCPP_HIDE_FROM_ABI + constexpr void* address() const noexcept { return __handle_; } + +private: + _LIBCPP_HIDE_FROM_ABI + friend coroutine_handle noop_coroutine() noexcept; + +#if __has_builtin(__builtin_coro_noop) + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { + this->__handle_ = __builtin_coro_noop(); + } + + void* __handle_ = nullptr; + +#elif defined(_LIBCPP_COMPILER_GCC) + // GCC doesn't implement __builtin_coro_noop(). + // Construct the coroutine frame manually instead. + struct __noop_coroutine_frame_ty_ { + static void __dummy_resume_destroy_func() { } + + void (*__resume_)() = __dummy_resume_destroy_func; + void (*__destroy_)() = __dummy_resume_destroy_func; + struct noop_coroutine_promise __promise_; + }; + + static __noop_coroutine_frame_ty_ __noop_coroutine_frame_; + + void* __handle_ = &__noop_coroutine_frame_; + + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default; + +#endif // __has_builtin(__builtin_coro_noop) +}; + +using noop_coroutine_handle = coroutine_handle; + +#if defined(_LIBCPP_COMPILER_GCC) +inline noop_coroutine_handle::__noop_coroutine_frame_ty_ + noop_coroutine_handle::__noop_coroutine_frame_{}; +#endif + +// [coroutine.noop.coroutine] +inline _LIBCPP_HIDE_FROM_ABI +noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } + +#endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 + +#endif // _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H diff --git a/gnu/llvm/libcxx/include/__coroutine/trivial_awaitables.h b/gnu/llvm/libcxx/include/__coroutine/trivial_awaitables.h new file mode 100644 index 00000000000..bbbae7a47f2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__coroutine/trivial_awaitables.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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___COROUTINE_TRIVIAL_AWAITABLES_H +#define __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H + +#include <__config> +#include <__coroutine/coroutine_handle.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [coroutine.trivial.awaitables] +struct suspend_never { + _LIBCPP_HIDE_FROM_ABI + constexpr bool await_ready() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI + constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void await_resume() const noexcept {} +}; + +struct suspend_always { + _LIBCPP_HIDE_FROM_ABI + constexpr bool await_ready() const noexcept { return false; } + _LIBCPP_HIDE_FROM_ABI + constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI + constexpr void await_resume() const noexcept {} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // __LIBCPP_STD_VER > 17 + +#endif // __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H diff --git a/gnu/llvm/libcxx/include/__debug b/gnu/llvm/libcxx/include/__debug index 771e4316320..140cc9142a8 100644 --- a/gnu/llvm/libcxx/include/__debug +++ b/gnu/llvm/libcxx/include/__debug @@ -1,5 +1,5 @@ // -*- C++ -*- -//===--------------------------- __debug ----------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,79 +7,36 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_DEBUG_H -#define _LIBCPP_DEBUG_H +#ifndef _LIBCPP___DEBUG +#define _LIBCPP___DEBUG +#include <__assert> #include <__config> -#include +#include <__type_traits/is_constant_evaluated.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -#if defined(_LIBCPP_HAS_NO_NULLPTR) -# include +#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY) +# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY #endif -#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) -# include -# include -# include +#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING) +# define _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING #endif -#if _LIBCPP_DEBUG_LEVEL == 0 -# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) -# define _LIBCPP_ASSERT_IMPL(x, m) ((void)0) -#elif _LIBCPP_DEBUG_LEVEL == 1 -# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) -# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) -#elif _LIBCPP_DEBUG_LEVEL == 2 -# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m) -# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) +#ifdef _LIBCPP_ENABLE_DEBUG_MODE +# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m) #else -# error _LIBCPP_DEBUG_LEVEL must be one of 0, 1, 2 +# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) #endif -#if !defined(_LIBCPP_ASSERT) -# define _LIBCPP_ASSERT(x, m) _LIBCPP_ASSERT_IMPL(x, m) -#endif +#if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) _LIBCPP_BEGIN_NAMESPACE_STD -struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - __libcpp_debug_info() - : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m) - : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {} - - _LIBCPP_FUNC_VIS string what() const; - - const char* __file_; - int __line_; - const char* __pred_; - const char* __msg_; -}; - -/// __libcpp_debug_function_type - The type of the assertion failure handler. -typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&); - -/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT -/// fails. -extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function; - -/// __libcpp_abort_debug_function - A debug handler that aborts when called. -_LIBCPP_NORETURN _LIBCPP_FUNC_VIS -void __libcpp_abort_debug_function(__libcpp_debug_info const&); - -/// __libcpp_set_debug_function - Set the debug handler to the specified -/// function. -_LIBCPP_FUNC_VIS -bool __libcpp_set_debug_function(__libcpp_debug_function_type __func); - -#if _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY) - struct _LIBCPP_TYPE_VIS __c_node; struct _LIBCPP_TYPE_VIS __i_node @@ -88,15 +45,9 @@ struct _LIBCPP_TYPE_VIS __i_node __i_node* __next_; __c_node* __c_; -#ifndef _LIBCPP_CXX03_LANG __i_node(const __i_node&) = delete; __i_node& operator=(const __i_node&) = delete; -#else -private: - __i_node(const __i_node&); - __i_node& operator=(const __i_node&); -public: -#endif + _LIBCPP_INLINE_VISIBILITY __i_node(void* __i, __i_node* __next, __c_node* __c) : __i_(__i), __next_(__next), __c_(__c) {} @@ -111,17 +62,11 @@ struct _LIBCPP_TYPE_VIS __c_node __i_node** end_; __i_node** cap_; -#ifndef _LIBCPP_CXX03_LANG __c_node(const __c_node&) = delete; __c_node& operator=(const __c_node&) = delete; -#else -private: - __c_node(const __c_node&); - __c_node& operator=(const __c_node&); -public: -#endif + _LIBCPP_INLINE_VISIBILITY - __c_node(void* __c, __c_node* __next) + explicit __c_node(void* __c, __c_node* __next) : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} virtual ~__c_node(); @@ -138,13 +83,13 @@ template struct _C_node : public __c_node { - _C_node(void* __c, __c_node* __n) + explicit _C_node(void* __c, __c_node* __n) : __c_node(__c, __n) {} - virtual bool __dereferenceable(const void*) const; - virtual bool __decrementable(const void*) const; - virtual bool __addable(const void*, ptrdiff_t) const; - virtual bool __subscriptable(const void*, ptrdiff_t) const; + bool __dereferenceable(const void*) const override; + bool __decrementable(const void*) const override; + bool __addable(const void*, ptrdiff_t) const override; + bool __subscriptable(const void*, ptrdiff_t) const override; }; template @@ -196,17 +141,11 @@ class _LIBCPP_TYPE_VIS __libcpp_db __i_node** __iend_; size_t __isz_; - __libcpp_db(); + explicit __libcpp_db(); public: -#ifndef _LIBCPP_CXX03_LANG __libcpp_db(const __libcpp_db&) = delete; __libcpp_db& operator=(const __libcpp_db&) = delete; -#else -private: - __libcpp_db(const __libcpp_db&); - __libcpp_db& operator=(const __libcpp_db&); -public: -#endif + ~__libcpp_db(); class __db_c_iterator; @@ -265,9 +204,63 @@ private: _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); _LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); +_LIBCPP_END_NAMESPACE_STD + +#endif // defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_c(_Tp* __c) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_c(__c); +#else + (void)(__c); +#endif +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_i(_Tp* __i) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->__insert_i(__i); +#else + (void)(__i); +#endif +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_erase_c(_Tp* __c) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->__erase_c(__c); +#else + (void)(__c); +#endif +} -#endif // _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY) +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_swap(_Tp* __lhs, _Tp* __rhs) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->swap(__lhs, __rhs); +#else + (void)(__lhs); + (void)(__rhs); +#endif +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_invalidate_all(_Tp* __c) { +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + if (!__libcpp_is_constant_evaluated()) + __get_db()->__invalidate_all(__c); +#else + (void)(__c); +#endif +} _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP_DEBUG_H +#endif // _LIBCPP___DEBUG diff --git a/gnu/llvm/libcxx/include/__debug_utils/randomize_range.h b/gnu/llvm/libcxx/include/__debug_utils/randomize_range.h new file mode 100644 index 00000000000..dce61923bc9 --- /dev/null +++ b/gnu/llvm/libcxx/include/__debug_utils/randomize_range.h @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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___LIBCXX_DEBUG_RANDOMIZE_RANGE_H +#define _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H + +#include <__config> + +#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY +# include <__algorithm/shuffle.h> +# include <__type_traits/is_constant_evaluated.h> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 +void __debug_randomize_range(_Iterator __first, _Sentinel __last) { +#ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY +# ifdef _LIBCPP_CXX03_LANG +# error Support for unspecified stability is only for C++11 and higher +# endif + + if (!__libcpp_is_constant_evaluated()) + std::__shuffle<_AlgPolicy>(__first, __last, __libcpp_debug_randomizer()); +#else + (void)__first; + (void)__last; +#endif +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H diff --git a/gnu/llvm/libcxx/include/__errc b/gnu/llvm/libcxx/include/__errc index 81da2e1970c..17bbe0e2afc 100644 --- a/gnu/llvm/libcxx/include/__errc +++ b/gnu/llvm/libcxx/include/__errc @@ -1,5 +1,5 @@ // -*- C++ -*- -//===---------------------------- __errc ----------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -104,7 +104,7 @@ enum class errc #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/gnu/llvm/libcxx/include/__expected/bad_expected_access.h b/gnu/llvm/libcxx/include/__expected/bad_expected_access.h new file mode 100644 index 00000000000..361eab4b601 --- /dev/null +++ b/gnu/llvm/libcxx/include/__expected/bad_expected_access.h @@ -0,0 +1,64 @@ +// -*- 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___EXPECTED_BAD_EXPECTED_ACCESS_H +#define _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H + +#include <__config> +#include <__utility/move.h> + +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class bad_expected_access; + +template <> +class bad_expected_access : public exception { +protected: + _LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&) = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&) = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&) = default; + ~bad_expected_access() override = default; + +public: + // The way this has been designed (by using a class template below) means that we'll already + // have a profusion of these vtables in TUs, and the dynamic linker will already have a bunch + // of work to do. So it is not worth hiding the specialization in the dylib, given that + // it adds deployment target restrictions. + const char* what() const noexcept override { return "bad access to std::expected"; } +}; + +template +class bad_expected_access : public bad_expected_access { +public: + _LIBCPP_HIDE_FROM_ABI explicit bad_expected_access(_Err __e) : __unex_(std::move(__e)) {} + + _LIBCPP_HIDE_FROM_ABI _Err& error() & noexcept { return __unex_; } + _LIBCPP_HIDE_FROM_ABI const _Err& error() const& noexcept { return __unex_; } + _LIBCPP_HIDE_FROM_ABI _Err&& error() && noexcept { return std::move(__unex_); } + _LIBCPP_HIDE_FROM_ABI const _Err&& error() const&& noexcept { return std::move(__unex_); } + +private: + _Err __unex_; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +#endif // _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H diff --git a/gnu/llvm/libcxx/include/__expected/expected.h b/gnu/llvm/libcxx/include/__expected/expected.h new file mode 100644 index 00000000000..ca3e8a59922 --- /dev/null +++ b/gnu/llvm/libcxx/include/__expected/expected.h @@ -0,0 +1,974 @@ +// -*- 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___EXPECTED_EXPECTED_H +#define _LIBCPP___EXPECTED_EXPECTED_H + +#include <__assert> +#include <__config> +#include <__expected/bad_expected_access.h> +#include <__expected/unexpect.h> +#include <__expected/unexpected.h> +#include <__memory/addressof.h> +#include <__memory/construct_at.h> +#include <__type_traits/conjunction.h> +#include <__type_traits/disjunction.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_copy_assignable.h> +#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_default_constructible.h> +#include <__type_traits/is_function.h> +#include <__type_traits/is_move_assignable.h> +#include <__type_traits/is_move_constructible.h> +#include <__type_traits/is_nothrow_constructible.h> +#include <__type_traits/is_nothrow_copy_assignable.h> +#include <__type_traits/is_nothrow_copy_constructible.h> +#include <__type_traits/is_nothrow_default_constructible.h> +#include <__type_traits/is_nothrow_move_assignable.h> +#include <__type_traits/is_nothrow_move_constructible.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_swappable.h> +#include <__type_traits/is_trivially_copy_constructible.h> +#include <__type_traits/is_trivially_destructible.h> +#include <__type_traits/is_trivially_move_constructible.h> +#include <__type_traits/is_void.h> +#include <__type_traits/lazy.h> +#include <__type_traits/negation.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/exception_guard.h> +#include <__utility/forward.h> +#include <__utility/in_place.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include // for std::abort +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace __expected { + +template +_LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) { +# ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_expected_access<_Err>(std::forward<_Arg>(__arg)); +# else + (void)__arg; + std::abort(); +# endif +} + +} // namespace __expected + +template +class expected { + static_assert( + !is_reference_v<_Tp> && + !is_function_v<_Tp> && + !is_same_v, in_place_t> && + !is_same_v, unexpect_t> && + !__is_std_unexpected>::value && + __valid_std_unexpected<_Err>::value + , + "[expected.object.general] A program that instantiates the definition of template expected for a " + "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a " + "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the " + "definition of the template expected with a type for the E parameter that is not a valid " + "template argument for unexpected is ill-formed."); + + template + friend class expected; + +public: + using value_type = _Tp; + using error_type = _Err; + using unexpected_type = unexpected<_Err>; + + template + using rebind = expected<_Up, error_type>; + + // [expected.object.ctor], constructors + _LIBCPP_HIDE_FROM_ABI constexpr expected() + noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened + requires is_default_constructible_v<_Tp> + : __has_val_(true) { + std::construct_at(std::addressof(__union_.__val_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) + requires(is_copy_constructible_v<_Tp> && + is_copy_constructible_v<_Err> && + is_trivially_copy_constructible_v<_Tp> && + is_trivially_copy_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) + noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && + !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)) + : __has_val_(__other.__has_val_) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_); + } else { + std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_); + } + } + + + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) + requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> + && is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && + !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)) + : __has_val_(__other.__has_val_) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_)); + } else { + std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_)); + } + } + +private: + template + using __can_convert = + _And< is_constructible<_Tp, _UfQual>, + is_constructible<_Err, _OtherErrQual>, + _Not&>>, + _Not>>, + _Not&>>, + _Not>>, + _Not&, _Tp>>, + _Not&&, _Tp>>, + _Not&, _Tp>>, + _Not&&, _Tp>>, + _Not, expected<_Up, _OtherErr>&>>, + _Not, expected<_Up, _OtherErr>>>, + _Not, const expected<_Up, _OtherErr>&>>, + _Not, const expected<_Up, _OtherErr>>> >; + + +public: + template + requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v || + !is_convertible_v) + expected(const expected<_Up, _OtherErr>& __other) + noexcept(is_nothrow_constructible_v<_Tp, const _Up&> && + is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __has_val_(__other.__has_val_) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_); + } else { + std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_); + } + } + + template + requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>) + expected(expected<_Up, _OtherErr>&& __other) + noexcept(is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __has_val_(__other.__has_val_) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_)); + } else { + std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_)); + } + } + + template + requires(!is_same_v, in_place_t> && !is_same_v> && + !__is_std_unexpected>::value && is_constructible_v<_Tp, _Up>) + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>) + expected(_Up&& __u) + noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened + : __has_val_(true) { + std::construct_at(std::addressof(__union_.__val_), std::forward<_Up>(__u)); + } + + + template + requires is_constructible_v<_Err, const _OtherErr&> + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) + expected(const unexpected<_OtherErr>& __unex) + noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), __unex.error()); + } + + template + requires is_constructible_v<_Err, _OtherErr> + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) + expected(unexpected<_OtherErr>&& __unex) + noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error())); + } + + template + requires is_constructible_v<_Tp, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Tp, _Args...>) // strengthened + : __has_val_(true) { + std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...); + } + + template + requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... > + _LIBCPP_HIDE_FROM_ABI constexpr explicit + expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened + : __has_val_(true) { + std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...); + } + + template + requires is_constructible_v<_Err, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...); + } + + template + requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > + _LIBCPP_HIDE_FROM_ABI constexpr explicit + expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); + } + + // [expected.object.dtor], destructor + + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() + requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() + requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) + { + if (__has_val_) { + std::destroy_at(std::addressof(__union_.__val_)); + } else { + std::destroy_at(std::addressof(__union_.__unex_)); + } + } + +private: + template + _LIBCPP_HIDE_FROM_ABI static constexpr void __reinit_expected(_T1& __newval, _T2& __oldval, _Args&&... __args) { + if constexpr (is_nothrow_constructible_v<_T1, _Args...>) { + std::destroy_at(std::addressof(__oldval)); + std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...); + } else if constexpr (is_nothrow_move_constructible_v<_T1>) { + _T1 __tmp(std::forward<_Args>(__args)...); + std::destroy_at(std::addressof(__oldval)); + std::construct_at(std::addressof(__newval), std::move(__tmp)); + } else { + static_assert( + is_nothrow_move_constructible_v<_T2>, + "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can " + "be reverted to the previous state in case an exception is thrown during the assignment."); + _T2 __tmp(std::move(__oldval)); + std::destroy_at(std::addressof(__oldval)); + auto __trans = + std::__make_exception_guard([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); }); + std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...); + __trans.__complete(); + } + } + +public: + // [expected.object.assign], assignment + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) + noexcept(is_nothrow_copy_assignable_v<_Tp> && + is_nothrow_copy_constructible_v<_Tp> && + is_nothrow_copy_assignable_v<_Err> && + is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_assignable_v<_Tp> && + is_copy_constructible_v<_Tp> && + is_copy_assignable_v<_Err> && + is_copy_constructible_v<_Err> && + (is_nothrow_move_constructible_v<_Tp> || + is_nothrow_move_constructible_v<_Err>)) + { + if (__has_val_ && __rhs.__has_val_) { + __union_.__val_ = __rhs.__union_.__val_; + } else if (__has_val_) { + __reinit_expected(__union_.__unex_, __union_.__val_, __rhs.__union_.__unex_); + } else if (__rhs.__has_val_) { + __reinit_expected(__union_.__val_, __union_.__unex_, __rhs.__union_.__val_); + } else { + __union_.__unex_ = __rhs.__union_.__unex_; + } + // note: only reached if no exception+rollback was done inside __reinit_expected + __has_val_ = __rhs.__has_val_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) + noexcept(is_nothrow_move_assignable_v<_Tp> && + is_nothrow_move_constructible_v<_Tp> && + is_nothrow_move_assignable_v<_Err> && + is_nothrow_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Tp> && + is_move_assignable_v<_Tp> && + is_move_constructible_v<_Err> && + is_move_assignable_v<_Err> && + (is_nothrow_move_constructible_v<_Tp> || + is_nothrow_move_constructible_v<_Err>)) + { + if (__has_val_ && __rhs.__has_val_) { + __union_.__val_ = std::move(__rhs.__union_.__val_); + } else if (__has_val_) { + __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__rhs.__union_.__unex_)); + } else if (__rhs.__has_val_) { + __reinit_expected(__union_.__val_, __union_.__unex_, std::move(__rhs.__union_.__val_)); + } else { + __union_.__unex_ = std::move(__rhs.__union_.__unex_); + } + // note: only reached if no exception+rollback was done inside __reinit_expected + __has_val_ = __rhs.__has_val_; + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v) + requires(!is_same_v> && + !__is_std_unexpected>::value && + is_constructible_v<_Tp, _Up> && + is_assignable_v<_Tp&, _Up> && + (is_nothrow_constructible_v<_Tp, _Up> || + is_nothrow_move_constructible_v<_Tp> || + is_nothrow_move_constructible_v<_Err>)) + { + if (__has_val_) { + __union_.__val_ = std::forward<_Up>(__v); + } else { + __reinit_expected(__union_.__val_, __union_.__unex_, std::forward<_Up>(__v)); + __has_val_ = true; + } + return *this; + } + +private: + template + static constexpr bool __can_assign_from_unexpected = + _And< is_constructible<_Err, _OtherErrQual>, + is_assignable<_Err&, _OtherErrQual>, + _Lazy<_Or, + is_nothrow_constructible<_Err, _OtherErrQual>, + is_nothrow_move_constructible<_Tp>, + is_nothrow_move_constructible<_Err>> >::value; + +public: + template + requires(__can_assign_from_unexpected) + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { + if (__has_val_) { + __reinit_expected(__union_.__unex_, __union_.__val_, __un.error()); + __has_val_ = false; + } else { + __union_.__unex_ = __un.error(); + } + return *this; + } + + template + requires(__can_assign_from_unexpected<_OtherErr>) + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { + if (__has_val_) { + __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__un.error())); + __has_val_ = false; + } else { + __union_.__unex_ = std::move(__un.error()); + } + return *this; + } + + template + requires is_nothrow_constructible_v<_Tp, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept { + if (__has_val_) { + std::destroy_at(std::addressof(__union_.__val_)); + } else { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } + return *std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...); + } + + template + requires is_nothrow_constructible_v< _Tp, initializer_list<_Up>&, _Args... > + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept { + if (__has_val_) { + std::destroy_at(std::addressof(__union_.__val_)); + } else { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } + return *std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...); + } + + +public: + // [expected.object.swap], swap + _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) + noexcept(is_nothrow_move_constructible_v<_Tp> && + is_nothrow_swappable_v<_Tp> && + is_nothrow_move_constructible_v<_Err> && + is_nothrow_swappable_v<_Err>) + requires(is_swappable_v<_Tp> && + is_swappable_v<_Err> && + is_move_constructible_v<_Tp> && + is_move_constructible_v<_Err> && + (is_nothrow_move_constructible_v<_Tp> || + is_nothrow_move_constructible_v<_Err>)) + { + auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { + if constexpr (is_nothrow_move_constructible_v<_Err>) { + _Err __tmp(std::move(__with_err.__union_.__unex_)); + std::destroy_at(std::addressof(__with_err.__union_.__unex_)); + auto __trans = std::__make_exception_guard([&] { + std::construct_at(std::addressof(__with_err.__union_.__unex_), std::move(__tmp)); + }); + std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__with_val.__union_.__val_)); + __trans.__complete(); + std::destroy_at(std::addressof(__with_val.__union_.__val_)); + std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__tmp)); + } else { + static_assert(is_nothrow_move_constructible_v<_Tp>, + "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so " + "that it can be reverted to the previous state in case an exception is thrown during swap."); + _Tp __tmp(std::move(__with_val.__union_.__val_)); + std::destroy_at(std::addressof(__with_val.__union_.__val_)); + auto __trans = std::__make_exception_guard([&] { + std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp)); + }); + std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_)); + __trans.__complete(); + std::destroy_at(std::addressof(__with_err.__union_.__unex_)); + std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__tmp)); + } + __with_val.__has_val_ = false; + __with_err.__has_val_ = true; + }; + + if (__has_val_) { + if (__rhs.__has_val_) { + using std::swap; + swap(__union_.__val_, __rhs.__union_.__val_); + } else { + __swap_val_unex_impl(*this, __rhs); + } + } else { + if (__rhs.__has_val_) { + __swap_val_unex_impl(__rhs, *this); + } else { + using std::swap; + swap(__union_.__unex_, __rhs.__union_.__unex_); + } + } + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) + noexcept(noexcept(__x.swap(__y))) + requires requires { __x.swap(__y); } + { + __x.swap(__y); + } + + // [expected.object.obs], observers + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); + return std::addressof(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); + return std::addressof(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + return __union_.__val_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + return __union_.__val_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + return std::move(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + return std::move(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); + } + return __union_.__val_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); + } + return __union_.__val_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + } + return std::move(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + } + return std::move(__union_.__val_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return __union_.__unex_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return __union_.__unex_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return std::move(__union_.__unex_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return std::move(__union_.__unex_); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& { + static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible"); + static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type"); + return __has_val_ ? __union_.__val_ : static_cast<_Tp>(std::forward<_Up>(__v)); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && { + static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible"); + static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type"); + return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v)); + } + + // [expected.object.eq], equality operators + template + requires(!is_void_v<_T2>) + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) { + if (__x.__has_val_ != __y.__has_val_) { + return false; + } else { + if (__x.__has_val_) { + return __x.__union_.__val_ == __y.__union_.__val_; + } else { + return __x.__union_.__unex_ == __y.__union_.__unex_; + } + } + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) { + return __x.__has_val_ && static_cast(__x.__union_.__val_ == __v); + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) { + return !__x.__has_val_ && static_cast(__x.__union_.__unex_ == __e.error()); + } + +private: + struct __empty_t {}; + // use named union because [[no_unique_address]] cannot be applied to an unnamed union + _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { + _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} + + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() + requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) + = default; + + // the expected's destructor handles this + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() + requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) + {} + + _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; + _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; + _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; + } __union_; + + bool __has_val_; +}; + +template + requires is_void_v<_Tp> +class expected<_Tp, _Err> { + static_assert(__valid_std_unexpected<_Err>::value, + "[expected.void.general] A program that instantiates expected with a E that is not a " + "valid argument for unexpected is ill-formed"); + + template + friend class expected; + + template + using __can_convert = + _And< is_void<_Up>, + is_constructible<_Err, _OtherErrQual>, + _Not, expected<_Up, _OtherErr>&>>, + _Not, expected<_Up, _OtherErr>>>, + _Not, const expected<_Up, _OtherErr>&>>, + _Not, const expected<_Up, _OtherErr>>>>; + +public: + using value_type = _Tp; + using error_type = _Err; + using unexpected_type = unexpected<_Err>; + + template + using rebind = expected<_Up, error_type>; + + // [expected.void.ctor], constructors + _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __has_val_(true) {} + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) + requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) + noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>) + : __has_val_(__rhs.__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); + } + } + + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) + requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) + noexcept(is_nothrow_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>) + : __has_val_(__rhs.__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); + } + } + + template + requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) + expected(const expected<_Up, _OtherErr>& __rhs) + noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __has_val_(__rhs.__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); + } + } + + template + requires __can_convert<_Up, _OtherErr, _OtherErr>::value + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) + expected(expected<_Up, _OtherErr>&& __rhs) + noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __has_val_(__rhs.__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); + } + } + + template + requires is_constructible_v<_Err, const _OtherErr&> + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) + expected(const unexpected<_OtherErr>& __unex) + noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), __unex.error()); + } + + template + requires is_constructible_v<_Err, _OtherErr> + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) + expected(unexpected<_OtherErr>&& __unex) + noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error())); + } + + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {} + + template + requires is_constructible_v<_Err, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...); + } + + template + requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) + noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + : __has_val_(false) { + std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); + } + + // [expected.void.dtor], destructor + + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() + requires is_trivially_destructible_v<_Err> + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() + requires(!is_trivially_destructible_v<_Err>) + { + if (!__has_val_) { + std::destroy_at(std::addressof(__union_.__unex_)); + } + } + + // [expected.void.assign], assignment + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) + noexcept(is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>) + { + if (__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); + __has_val_ = false; + } + } else { + if (__rhs.__has_val_) { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } else { + __union_.__unex_ = __rhs.__union_.__unex_; + } + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) + noexcept(is_nothrow_move_assignable_v<_Err> && + is_nothrow_move_constructible_v<_Err>) + requires(is_move_assignable_v<_Err> && + is_move_constructible_v<_Err>) + { + if (__has_val_) { + if (!__rhs.__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); + __has_val_ = false; + } + } else { + if (__rhs.__has_val_) { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } else { + __union_.__unex_ = std::move(__rhs.__union_.__unex_); + } + } + return *this; + } + + template + requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>) + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), __un.error()); + __has_val_ = false; + } else { + __union_.__unex_ = __un.error(); + } + return *this; + } + + template + requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>) + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { + if (__has_val_) { + std::construct_at(std::addressof(__union_.__unex_), std::move(__un.error())); + __has_val_ = false; + } else { + __union_.__unex_ = std::move(__un.error()); + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept { + if (!__has_val_) { + std::destroy_at(std::addressof(__union_.__unex_)); + __has_val_ = true; + } + } + + // [expected.void.swap], swap + _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) + noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) + requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>) + { + auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { + std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_)); + std::destroy_at(std::addressof(__with_err.__union_.__unex_)); + __with_val.__has_val_ = false; + __with_err.__has_val_ = true; + }; + + if (__has_val_) { + if (!__rhs.__has_val_) { + __swap_val_unex_impl(*this, __rhs); + } + } else { + if (__rhs.__has_val_) { + __swap_val_unex_impl(__rhs, *this); + } else { + using std::swap; + swap(__union_.__unex_, __rhs.__union_.__unex_); + } + } + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) + noexcept(noexcept(__x.swap(__y))) + requires requires { __x.swap(__y); } + { + __x.swap(__y); + } + + // [expected.void.obs], observers + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept { + _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + } + + _LIBCPP_HIDE_FROM_ABI constexpr void value() const& { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); + } + } + + _LIBCPP_HIDE_FROM_ABI constexpr void value() && { + if (!__has_val_) { + __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + } + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return __union_.__unex_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return __union_.__unex_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return std::move(__union_.__unex_); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { + _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); + return std::move(__union_.__unex_); + } + + // [expected.void.eq], equality operators + template + requires is_void_v<_T2> + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) { + if (__x.__has_val_ != __y.__has_val_) { + return false; + } else { + return __x.__has_val_ || static_cast(__x.__union_.__unex_ == __y.__union_.__unex_); + } + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) { + return !__x.__has_val_ && static_cast(__x.__union_.__unex_ == __y.error()); + } + +private: + struct __empty_t {}; + // use named union because [[no_unique_address]] cannot be applied to an unnamed union + _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { + _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} + + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() + requires(is_trivially_destructible_v<_Err>) + = default; + + // the expected's destructor handles this + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() + requires(!is_trivially_destructible_v<_Err>) + {} + + _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; + _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; + } __union_; + + bool __has_val_; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +#endif // _LIBCPP___EXPECTED_EXPECTED_H diff --git a/gnu/llvm/libcxx/include/__expected/unexpect.h b/gnu/llvm/libcxx/include/__expected/unexpect.h new file mode 100644 index 00000000000..20bafc1107c --- /dev/null +++ b/gnu/llvm/libcxx/include/__expected/unexpect.h @@ -0,0 +1,32 @@ +// -*- 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___EXPECTED_UNEXPECT_H +#define _LIBCPP___EXPECTED_UNEXPECT_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct unexpect_t { + _LIBCPP_HIDE_FROM_ABI explicit unexpect_t() = default; +}; + +inline constexpr unexpect_t unexpect{}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +#endif // _LIBCPP___EXPECTED_UNEXPECT_H diff --git a/gnu/llvm/libcxx/include/__expected/unexpected.h b/gnu/llvm/libcxx/include/__expected/unexpected.h new file mode 100644 index 00000000000..075963a84de --- /dev/null +++ b/gnu/llvm/libcxx/include/__expected/unexpected.h @@ -0,0 +1,122 @@ +// -*- 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___EXPECTED_UNEXPECTED_H +#define _LIBCPP___EXPECTED_UNEXPECTED_H + +#include <__config> +#include <__type_traits/conjunction.h> +#include <__type_traits/is_array.h> +#include <__type_traits/is_const.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_nothrow_constructible.h> +#include <__type_traits/is_object.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_swappable.h> +#include <__type_traits/is_volatile.h> +#include <__type_traits/negation.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/forward.h> +#include <__utility/in_place.h> +#include <__utility/move.h> +#include <__utility/swap.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class unexpected; + +template +struct __is_std_unexpected : false_type {}; + +template +struct __is_std_unexpected> : true_type {}; + +template +using __valid_std_unexpected = _BoolConstant< // + is_object_v<_Tp> && // + !is_array_v<_Tp> && // + !__is_std_unexpected<_Tp>::value && // + !is_const_v<_Tp> && // + !is_volatile_v<_Tp> // + >; + +template +class unexpected { + static_assert(__valid_std_unexpected<_Err>::value, + "[expected.un.general] states a program that instantiates std::unexpected for a non-object type, an " + "array type, a specialization of unexpected, or a cv-qualified type is ill-formed."); + +public: + _LIBCPP_HIDE_FROM_ABI constexpr unexpected(const unexpected&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr unexpected(unexpected&&) = default; + + template + requires(!is_same_v, unexpected> && // + !is_same_v, in_place_t> && // + is_constructible_v<_Err, _Error>) + _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(_Error&& __error) // + noexcept(is_nothrow_constructible_v<_Err, _Error>) // strengthened + : __unex_(std::forward<_Error>(__error)) {} + + template + requires is_constructible_v<_Err, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(in_place_t, _Args&&... __args) // + noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened + : __unex_(std::forward<_Args>(__args)...) {} + + template + requires is_constructible_v<_Err, initializer_list<_Up>&, _Args...> + _LIBCPP_HIDE_FROM_ABI constexpr explicit unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) // + noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + : __unex_(__il, std::forward<_Args>(__args)...) {} + + _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(const unexpected&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(unexpected&&) = default; + + _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { return __unex_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { return __unex_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { return std::move(__unex_); } + _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { return std::move(__unex_); } + + _LIBCPP_HIDE_FROM_ABI constexpr void swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Err>) { + static_assert(is_swappable_v<_Err>, "unexpected::swap requires is_swappable_v to be true"); + using std::swap; + swap(__unex_, __other.__unex_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y))) + requires is_swappable_v<_Err> + { + __x.swap(__y); + } + + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const unexpected& __x, const unexpected<_Err2>& __y) { + return __x.__unex_ == __y.__unex_; + } + +private: + _Err __unex_; +}; + +template +unexpected(_Err) -> unexpected<_Err>; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +#endif // _LIBCPP___EXPECTED_UNEXPECTED_H diff --git a/gnu/llvm/libcxx/include/__filesystem/copy_options.h b/gnu/llvm/libcxx/include/__filesystem/copy_options.h new file mode 100644 index 00000000000..96c7535812e --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/copy_options.h @@ -0,0 +1,84 @@ +// -*- 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___FILESYSTEM_COPY_OPTIONS_H +#define _LIBCPP___FILESYSTEM_COPY_OPTIONS_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +enum class _LIBCPP_ENUM_VIS copy_options : unsigned short { + none = 0, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256, + __in_recursive_copy = 512, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) & + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) | + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) ^ + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator~(copy_options __lhs) { + return static_cast(~static_cast(__lhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator&=(copy_options& __lhs, copy_options __rhs) { + return __lhs = __lhs & __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator|=(copy_options& __lhs, copy_options __rhs) { + return __lhs = __lhs | __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) { + return __lhs = __lhs ^ __rhs; +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_COPY_OPTIONS_H diff --git a/gnu/llvm/libcxx/include/__filesystem/directory_entry.h b/gnu/llvm/libcxx/include/__filesystem/directory_entry.h new file mode 100644 index 00000000000..b17eaaab4c5 --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/directory_entry.h @@ -0,0 +1,527 @@ +// -*- 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___FILESYSTEM_DIRECTORY_ENTRY_H +#define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H + +#include <__availability> +#include <__chrono/time_point.h> +#include <__config> +#include <__errc> +#include <__filesystem/file_status.h> +#include <__filesystem/file_time_type.h> +#include <__filesystem/file_type.h> +#include <__filesystem/filesystem_error.h> +#include <__filesystem/operations.h> +#include <__filesystem/path.h> +#include <__filesystem/perms.h> +#include <__utility/unreachable.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + + +class directory_entry { + typedef _VSTD_FS::path _Path; + +public: + // constructors and destructors + directory_entry() noexcept = default; + directory_entry(directory_entry const&) = default; + directory_entry(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + explicit directory_entry(_Path const& __p) : __p_(__p) { + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { + __refresh(&__ec); + } + + ~directory_entry() {} + + directory_entry& operator=(directory_entry const&) = default; + directory_entry& operator=(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p) { + __p_ = __p; + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p, error_code& __ec) { + __p_ = __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p) { + __p_.replace_filename(__p); + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p, error_code& __ec) { + __p_ = __p_.parent_path() / __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void refresh() { __refresh(); } + + _LIBCPP_INLINE_VISIBILITY + void refresh(error_code& __ec) noexcept { __refresh(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + _Path const& path() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + operator const _Path&() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool exists(error_code& __ec) const noexcept { + return _VSTD_FS::exists(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file() const { return __get_ft() == file_type::block; } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::block; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file() const { return __get_ft() == file_type::character; } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::character; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory() const { return __get_ft() == file_type::directory; } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::directory; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo() const { return __get_ft() == file_type::fifo; } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::fifo; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool is_other(error_code& __ec) const noexcept { + return _VSTD_FS::is_other(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file() const { return __get_ft() == file_type::regular; } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::regular; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket() const { return __get_ft() == file_type::socket; } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::socket; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink(error_code& __ec) const noexcept { + return __get_sym_ft(&__ec) == file_type::symlink; + } + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size() const { return __get_size(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size(error_code& __ec) const noexcept { + return __get_size(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count() const { return __get_nlink(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count(error_code& __ec) const noexcept { + return __get_nlink(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time() const { return __get_write_time(); } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time(error_code& __ec) const noexcept { + return __get_write_time(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status status() const { return __get_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status status(error_code& __ec) const noexcept { + return __get_status(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status() const { return __get_symlink_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status(error_code& __ec) const noexcept { + return __get_symlink_status(&__ec); + } + + + _LIBCPP_INLINE_VISIBILITY + bool operator==(directory_entry const& __rhs) const noexcept { + return __p_ == __rhs.__p_; + } + +#if _LIBCPP_STD_VER <= 17 + _LIBCPP_INLINE_VISIBILITY + bool operator!=(directory_entry const& __rhs) const noexcept { + return __p_ != __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<(directory_entry const& __rhs) const noexcept { + return __p_ < __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<=(directory_entry const& __rhs) const noexcept { + return __p_ <= __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>(directory_entry const& __rhs) const noexcept { + return __p_ > __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>=(directory_entry const& __rhs) const noexcept { + return __p_ >= __rhs.__p_; + } + +#else // _LIBCPP_STD_VER <= 17 + + _LIBCPP_HIDE_FROM_ABI + strong_ordering operator<=>(const directory_entry& __rhs) const noexcept { + return __p_ <=> __rhs.__p_; + } + +#endif // _LIBCPP_STD_VER <= 17 + + template + _LIBCPP_INLINE_VISIBILITY + friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { + return __os << __d.path(); + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + friend class _LIBCPP_HIDDEN __dir_stream; + + enum _CacheType : unsigned char { + _Empty, + _IterSymlink, + _IterNonSymlink, + _RefreshSymlink, + _RefreshSymlinkUnresolved, + _RefreshNonSymlink + }; + + struct __cached_data { + uintmax_t __size_; + uintmax_t __nlink_; + file_time_type __write_time_; + perms __sym_perms_; + perms __non_sym_perms_; + file_type __type_; + _CacheType __cache_type_; + + _LIBCPP_INLINE_VISIBILITY + __cached_data() noexcept { __reset(); } + + _LIBCPP_INLINE_VISIBILITY + void __reset() { + __cache_type_ = _Empty; + __type_ = file_type::none; + __sym_perms_ = __non_sym_perms_ = perms::unknown; + __size_ = __nlink_ = uintmax_t(-1); + __write_time_ = file_time_type::min(); + } + }; + + _LIBCPP_INLINE_VISIBILITY + static __cached_data __create_iter_result(file_type __ft) { + __cached_data __data; + __data.__type_ = __ft; + __data.__cache_type_ = [&]() { + switch (__ft) { + case file_type::none: + return _Empty; + case file_type::symlink: + return _IterSymlink; + default: + return _IterNonSymlink; + } + }(); + return __data; + } + + _LIBCPP_INLINE_VISIBILITY + void __assign_iter_entry(_Path&& __p, __cached_data __dt) { + __p_ = _VSTD::move(__p); + __data_ = __dt; + } + + _LIBCPP_FUNC_VIS + error_code __do_refresh() noexcept; + + _LIBCPP_INLINE_VISIBILITY + static bool __is_dne_error(error_code const& __ec) { + if (!__ec) + return true; + switch (static_cast(__ec.value())) { + case errc::no_such_file_or_directory: + case errc::not_a_directory: + return true; + default: + return false; + } + } + + _LIBCPP_INLINE_VISIBILITY + void __handle_error(const char* __msg, error_code* __dest_ec, + error_code const& __ec, bool __allow_dne = false) const { + if (__dest_ec) { + *__dest_ec = __ec; + return; + } + if (__ec && (!__allow_dne || !__is_dne_error(__ec))) + __throw_filesystem_error(__msg, __p_, __ec); + } + + _LIBCPP_INLINE_VISIBILITY + void __refresh(error_code* __ec = nullptr) { + __handle_error("in directory_entry::refresh", __ec, __do_refresh(), + /*allow_dne*/ true); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_sym_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + return __symlink_status(__p_, __ec).type(); + case _IterSymlink: + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + if (__ec) + __ec->clear(); + return file_type::symlink; + case _IterNonSymlink: + case _RefreshNonSymlink: + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec).type(); + case _IterNonSymlink: + case _RefreshNonSymlink: + case _RefreshSymlink: { + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec); + case _RefreshNonSymlink: + case _RefreshSymlink: + return file_status(__get_ft(__ec), __data_.__non_sym_perms_); + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_symlink_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + return __symlink_status(__p_, __ec); + case _RefreshNonSymlink: + return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_); + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + return file_status(__get_sym_ft(__ec), __data_.__sym_perms_); + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_size(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__file_size(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::file_size", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) { + errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory + : errc::not_supported; + __handle_error("in directory_entry::file_size", __ec, + make_error_code(__err_kind)); + } + return __data_.__size_; + } + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_nlink(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__hard_link_count(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + (void)__get_ft(&__m_ec); + __handle_error("in directory_entry::hard_link_count", __ec, __m_ec); + return __data_.__nlink_; + } + } + __libcpp_unreachable(); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type __get_write_time(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__last_write_time(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::last_write_time", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && + __data_.__write_time_ == file_time_type::min()) + __handle_error("in directory_entry::last_write_time", __ec, + make_error_code(errc::value_too_large)); + return __data_.__write_time_; + } + } + __libcpp_unreachable(); + } + +private: + _Path __p_; + __cached_data __data_; +}; + +class __dir_element_proxy { +public: + inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() { + return _VSTD::move(__elem_); + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} + __dir_element_proxy(__dir_element_proxy&& __o) + : __elem_(_VSTD::move(__o.__elem_)) {} + directory_entry __elem_; +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H diff --git a/gnu/llvm/libcxx/include/__filesystem/directory_iterator.h b/gnu/llvm/libcxx/include/__filesystem/directory_iterator.h new file mode 100644 index 00000000000..5ff2f01ac7b --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/directory_iterator.h @@ -0,0 +1,165 @@ +// -*- 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___FILESYSTEM_DIRECTORY_ITERATOR_H +#define _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H + +#include <__assert> +#include <__availability> +#include <__config> +#include <__filesystem/directory_entry.h> +#include <__filesystem/directory_options.h> +#include <__filesystem/path.h> +#include <__iterator/iterator_traits.h> +#include <__memory/shared_ptr.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class _LIBCPP_HIDDEN __dir_stream; +class directory_iterator { +public: + typedef directory_entry value_type; + typedef ptrdiff_t difference_type; + typedef value_type const* pointer; + typedef value_type const& reference; + typedef input_iterator_tag iterator_category; + +public: + //ctor & dtor + _LIBCPP_HIDE_FROM_ABI + directory_iterator() noexcept {} + + _LIBCPP_HIDE_FROM_ABI + explicit directory_iterator(const path& __p) + : directory_iterator(__p, nullptr) {} + + _LIBCPP_HIDE_FROM_ABI + directory_iterator(const path& __p, directory_options __opts) + : directory_iterator(__p, nullptr, __opts) {} + + _LIBCPP_HIDE_FROM_ABI + directory_iterator(const path& __p, error_code& __ec) + : directory_iterator(__p, &__ec) {} + + _LIBCPP_HIDE_FROM_ABI + directory_iterator(const path& __p, directory_options __opts, + error_code& __ec) + : directory_iterator(__p, &__ec, __opts) {} + + _LIBCPP_HIDE_FROM_ABI directory_iterator(const directory_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI directory_iterator(directory_iterator&&) = default; + _LIBCPP_HIDE_FROM_ABI directory_iterator& operator=(const directory_iterator&) = default; + + _LIBCPP_HIDE_FROM_ABI + directory_iterator& operator=(directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI ~directory_iterator() = default; + + _LIBCPP_HIDE_FROM_ABI + const directory_entry& operator*() const { + _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); + return __dereference(); + } + + _LIBCPP_HIDE_FROM_ABI + const directory_entry* operator->() const { return &**this; } + + _LIBCPP_HIDE_FROM_ABI + directory_iterator& operator++() { return __increment(); } + + _LIBCPP_HIDE_FROM_ABI + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + _LIBCPP_HIDE_FROM_ABI + directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } + +private: + inline _LIBCPP_HIDE_FROM_ABI friend bool + operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept; + + // construct the dir_stream + _LIBCPP_FUNC_VIS + directory_iterator(const path&, error_code*, + directory_options = directory_options::none); + + _LIBCPP_FUNC_VIS + directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + +private: + shared_ptr<__dir_stream> __imp_; +}; + +inline _LIBCPP_HIDE_FROM_ABI bool +operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +inline _LIBCPP_HIDE_FROM_ABI bool +operator!=(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept { + return !(__lhs == __rhs); +} + +// enable directory_iterator range-based for statements +inline _LIBCPP_HIDE_FROM_ABI directory_iterator +begin(directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_HIDE_FROM_ABI directory_iterator +end(directory_iterator) noexcept { + return directory_iterator(); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#if _LIBCPP_STD_VER > 17 + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true; + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true; + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__filesystem/directory_options.h b/gnu/llvm/libcxx/include/__filesystem/directory_options.h new file mode 100644 index 00000000000..c5c031a567c --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/directory_options.h @@ -0,0 +1,82 @@ +// -*- 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___FILESYSTEM_DIRECTORY_OPTIONS_H +#define _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +enum class _LIBCPP_ENUM_VIS directory_options : unsigned char { + none = 0, + follow_directory_symlink = 1, + skip_permission_denied = 2 +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator&(directory_options __lhs, + directory_options __rhs) { + return static_cast(static_cast(__lhs) & + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator|(directory_options __lhs, + directory_options __rhs) { + return static_cast(static_cast(__lhs) | + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator^(directory_options __lhs, + directory_options __rhs) { + return static_cast(static_cast(__lhs) ^ + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator~(directory_options __lhs) { + return static_cast(~static_cast(__lhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator&=(directory_options& __lhs, + directory_options __rhs) { + return __lhs = __lhs & __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator|=(directory_options& __lhs, + directory_options __rhs) { + return __lhs = __lhs | __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator^=(directory_options& __lhs, + directory_options __rhs) { + return __lhs = __lhs ^ __rhs; +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H diff --git a/gnu/llvm/libcxx/include/__filesystem/file_status.h b/gnu/llvm/libcxx/include/__filesystem/file_status.h new file mode 100644 index 00000000000..ac3f6cbed9d --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/file_status.h @@ -0,0 +1,72 @@ +// -*- 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___FILESYSTEM_FILE_STATUS_H +#define _LIBCPP___FILESYSTEM_FILE_STATUS_H + +#include <__availability> +#include <__config> +#include <__filesystem/file_type.h> +#include <__filesystem/perms.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class _LIBCPP_TYPE_VIS file_status { +public: + // constructors + _LIBCPP_INLINE_VISIBILITY + file_status() noexcept : file_status(file_type::none) {} + _LIBCPP_INLINE_VISIBILITY + explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept + : __ft_(__ft), + __prms_(__prms) {} + + file_status(const file_status&) noexcept = default; + file_status(file_status&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + ~file_status() {} + + file_status& operator=(const file_status&) noexcept = default; + file_status& operator=(file_status&&) noexcept = default; + + // observers + _LIBCPP_INLINE_VISIBILITY + file_type type() const noexcept { return __ft_; } + + _LIBCPP_INLINE_VISIBILITY + perms permissions() const noexcept { return __prms_; } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void type(file_type __ft) noexcept { __ft_ = __ft; } + + _LIBCPP_INLINE_VISIBILITY + void permissions(perms __p) noexcept { __prms_ = __p; } + +private: + file_type __ft_; + perms __prms_; +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILE_STATUS_H diff --git a/gnu/llvm/libcxx/include/__filesystem/file_time_type.h b/gnu/llvm/libcxx/include/__filesystem/file_time_type.h new file mode 100644 index 00000000000..7c4932e603b --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/file_time_type.h @@ -0,0 +1,32 @@ +// -*- 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___FILESYSTEM_FILE_TIME_TYPE_H +#define _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H + +#include <__availability> +#include <__chrono/file_clock.h> +#include <__chrono/time_point.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +typedef chrono::time_point<_FilesystemClock> file_time_type; + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H diff --git a/gnu/llvm/libcxx/include/__filesystem/file_type.h b/gnu/llvm/libcxx/include/__filesystem/file_type.h new file mode 100644 index 00000000000..c756a05c848 --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/file_type.h @@ -0,0 +1,43 @@ +// -*- 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___FILESYSTEM_FILE_TYPE_H +#define _LIBCPP___FILESYSTEM_FILE_TYPE_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +// On Windows, the library never identifies files as block, character, fifo +// or socket. +enum class _LIBCPP_ENUM_VIS file_type : signed char { + none = 0, + not_found = -1, + regular = 1, + directory = 2, + symlink = 3, + block = 4, + character = 5, + fifo = 6, + socket = 7, + unknown = 8 +}; + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILE_TYPE_H diff --git a/gnu/llvm/libcxx/include/__filesystem/filesystem_error.h b/gnu/llvm/libcxx/include/__filesystem/filesystem_error.h new file mode 100644 index 00000000000..effe6998338 --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/filesystem_error.h @@ -0,0 +1,104 @@ +// -*- 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___FILESYSTEM_FILESYSTEM_ERROR_H +#define _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H + +#include <__availability> +#include <__config> +#include <__filesystem/path.h> +#include <__memory/shared_ptr.h> +#include <__utility/forward.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error { +public: + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(path(), path())) { + __create_what(0); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, path())) { + __create_what(1); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, const path& __p2, + error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, __p2)) { + __create_what(2); + } + + _LIBCPP_INLINE_VISIBILITY + const path& path1() const noexcept { return __storage_->__p1_; } + + _LIBCPP_INLINE_VISIBILITY + const path& path2() const noexcept { return __storage_->__p2_; } + + filesystem_error(const filesystem_error&) = default; + ~filesystem_error() override; // key function + + _LIBCPP_HIDE_FROM_ABI_VIRTUAL + const char* what() const noexcept override { + return __storage_->__what_.c_str(); + } + + void __create_what(int __num_paths); + +private: + struct _LIBCPP_HIDDEN _Storage { + _LIBCPP_INLINE_VISIBILITY + _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} + + path __p1_; + path __p2_; + string __what_; + }; + shared_ptr<_Storage> __storage_; +}; + +// TODO(ldionne): We need to pop the pragma and push it again after +// filesystem_error to work around PR41078. +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_NO_EXCEPTIONS +void __throw_filesystem_error(_Args&&... __args) { + throw filesystem_error(_VSTD::forward<_Args>(__args)...); +} +#else +void __throw_filesystem_error(_Args&&...) { + _VSTD::abort(); +} +#endif +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H diff --git a/gnu/llvm/libcxx/include/__filesystem/operations.h b/gnu/llvm/libcxx/include/__filesystem/operations.h new file mode 100644 index 00000000000..f48d301d090 --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/operations.h @@ -0,0 +1,201 @@ +// -*- 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___FILESYSTEM_OPERATIONS_H +#define _LIBCPP___FILESYSTEM_OPERATIONS_H + +#include <__availability> +#include <__chrono/time_point.h> +#include <__config> +#include <__filesystem/copy_options.h> +#include <__filesystem/file_status.h> +#include <__filesystem/file_time_type.h> +#include <__filesystem/file_type.h> +#include <__filesystem/path.h> +#include <__filesystem/perm_options.h> +#include <__filesystem/perms.h> +#include <__filesystem/space_info.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +_LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directories(const path&, error_code* = nullptr); +_LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path&, error_code* = nullptr); +_LIBCPP_FUNC_VIS bool __create_directory(const path&, const path& __attributes, error_code* = nullptr); +_LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __current_path(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __equivalent(const path&, const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS path __read_symlink(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS bool __remove(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __rename(const path& __from, const path& __to, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS void __resize_file(const path&, uintmax_t __size, error_code* = nullptr); +_LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr); + +inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); } +inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); } +inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to) { return __copy_file(__from, __to, copy_options::none); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, error_code& __ec) { return __copy_file(__from, __to, copy_options::none, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt) { return __copy_file(__from, __to, __opt); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { return __copy_file(__from, __to, __opt, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to) { __copy_symlink(__from, __to); } +inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { __copy_symlink(__from, __to, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to) { __copy(__from, __to, copy_options::none); } +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, error_code& __ec) { __copy(__from, __to, copy_options::none, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt) { __copy(__from, __to, __opt); } +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { __copy(__from, __to, __opt, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p) { return __create_directories(__p); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p, error_code& __ec) { return __create_directories(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link) { __create_directory_symlink(__target, __link); } +inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { __create_directory_symlink(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p) { return __create_directory(__p); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, error_code& __ec) noexcept { return __create_directory(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs) { return __create_directory(__p, __attrs); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { return __create_directory(__p, __attrs, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link) { __create_hard_link(__target, __link); } +inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { __create_hard_link(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link) { __create_symlink(__target, __link); } +inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { return __create_symlink(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI path current_path() { return __current_path(); } +inline _LIBCPP_HIDE_FROM_ABI path current_path(error_code& __ec) { return __current_path(&__ec); } +inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p) { __current_path(__p); } +inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p, error_code& __ec) noexcept { __current_path(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); } +inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { return __equivalent(__p1, __p2, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; } +inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; } +inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p) { return exists(__status(__p)); } + +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, error_code& __ec) noexcept { + auto __s = __status(__p, &__ec); + if (status_known(__s)) + __ec.clear(); + return exists(__s); +} + +inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p) { return __file_size(__p); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept { return __file_size(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { return __hard_link_count(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; } +inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p) { return is_block_file(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept { return is_block_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept { return __s.type() == file_type::character; } +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p) { return is_character_file(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& __ec) noexcept { return is_character_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; } +inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); } +_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& __p, error_code* __ec = nullptr); +inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); } +inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; } +inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p) { return is_fifo(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p, error_code& __ec) noexcept { return is_fifo(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; } +inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p) { return is_regular_file(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p, error_code& __ec) noexcept { return is_regular_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; } +inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p) { return is_symlink(__symlink_status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p, error_code& __ec) noexcept { return is_symlink(__symlink_status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_other(file_status __s) noexcept { return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); } +inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p) { return is_other(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p, error_code& __ec) noexcept { return is_other(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; } +inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p) { return is_socket(__status(__p)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p, error_code& __ec) noexcept { return is_socket(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) { return __last_write_time(__p); } +inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); } +inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); } +_LIBCPP_FUNC_VIS void __permissions(const path&, perms, perm_options, error_code* = nullptr); +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); } +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); } + +inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __base, error_code& __ec) { + path __tmp = __weakly_canonical(__p, &__ec); + if (__ec) + return {}; + path __tmp_base = __weakly_canonical(__base, &__ec); + if (__ec) + return {}; + return __tmp.lexically_proximate(__tmp_base); +} + +inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, error_code& __ec) { return proximate(__p, current_path(), __ec); } +inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); } +inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p) { return __read_symlink(__p); } +inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p, error_code& __ec) { return __read_symlink(__p, &__ec); } + +inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __base, error_code& __ec) { + path __tmp = __weakly_canonical(__p, &__ec); + if (__ec) + return path(); + path __tmpbase = __weakly_canonical(__base, &__ec); + if (__ec) + return path(); + return __tmp.lexically_relative(__tmpbase); +} + +inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, error_code& __ec) { return relative(__p, current_path(), __ec); } +inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p) { return __remove_all(__p); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p, error_code& __ec) { return __remove_all(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p) { return __remove(__p); } +inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p, error_code& __ec) noexcept { return __remove(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to) { return __rename(__from, __to); } +inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); } +inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); } +_LIBCPP_FUNC_VIS space_info __space(const path&, error_code* __ec = nullptr); +inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); } +inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); } +inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p, error_code& __ec) noexcept { return __status(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p) { return __symlink_status(__p); } +inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p, error_code& __ec) noexcept { return __symlink_status(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path() { return __temp_directory_path(); } +inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) { return __temp_directory_path(&__ec); } +inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); } +inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); } + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_OPERATIONS_H diff --git a/gnu/llvm/libcxx/include/__filesystem/path.h b/gnu/llvm/libcxx/include/__filesystem/path.h new file mode 100644 index 00000000000..4e6912fcf3e --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/path.h @@ -0,0 +1,1091 @@ +// -*- 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___FILESYSTEM_PATH_H +#define _LIBCPP___FILESYSTEM_PATH_H + +#include <__algorithm/replace.h> +#include <__algorithm/replace_copy.h> +#include <__availability> +#include <__config> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/iterator_traits.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# include // for quoted +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +struct __can_convert_char { + static const bool value = false; +}; +template +struct __can_convert_char : public __can_convert_char<_Tp> {}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char; +}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = wchar_t; +}; +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char8_t; +}; +#endif +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char16_t; +}; +template <> +struct __can_convert_char { + static const bool value = true; + using __char_type = char32_t; +}; + +template +_LIBCPP_HIDE_FROM_ABI +typename enable_if<__can_convert_char<_ECharT>::value, bool>::type +__is_separator(_ECharT __e) { +#if defined(_LIBCPP_WIN32API) + return __e == _ECharT('/') || __e == _ECharT('\\'); +#else + return __e == _ECharT('/'); +#endif +} + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +typedef u8string __u8_string; +#else +typedef string __u8_string; +#endif + +struct _NullSentinel {}; + +template +using _Void = void; + +template +struct __is_pathable_string : public false_type {}; + +template +struct __is_pathable_string< + basic_string<_ECharT, _Traits, _Alloc>, + _Void::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string<_ECharT, _Traits, _Alloc>; + using _Base = __can_convert_char<_ECharT>; + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template +struct __is_pathable_string< + basic_string_view<_ECharT, _Traits>, + _Void::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string_view<_ECharT, _Traits>; + using _Base = __can_convert_char<_ECharT>; + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template ::type, + class _UnqualPtrType = + __remove_const_t<__remove_pointer_t<_DS> >, + bool _IsCharPtr = is_pointer<_DS>::value&& + __can_convert_char<_UnqualPtrType>::value> +struct __is_pathable_char_array : false_type {}; + +template +struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> + : __can_convert_char<__remove_const_t<_ECharT> > { + using _Base = __can_convert_char<__remove_const_t<_ECharT> >; + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT const* __range_end(const _ECharT* __b) { + using _Iter = const _ECharT*; + const _ECharT __sentinel = _ECharT{}; + _Iter __e = __b; + for (; *__e != __sentinel; ++__e) + ; + return __e; + } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } +}; + +template ::value, + class = void> +struct __is_pathable_iter : false_type {}; + +template +struct __is_pathable_iter< + _Iter, true, + _Void::value_type>::__char_type> > + : __can_convert_char::value_type> { + using _ECharT = typename iterator_traits<_Iter>::value_type; + using _Base = __can_convert_char<_ECharT>; + + _LIBCPP_HIDE_FROM_ABI + static _Iter __range_begin(_Iter __b) { return __b; } + + _LIBCPP_HIDE_FROM_ABI + static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; } + + _LIBCPP_HIDE_FROM_ABI + static _ECharT __first_or_null(_Iter __b) { return *__b; } +}; + +template ::value, + bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, + bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> +struct __is_pathable : false_type { + static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); +}; + +template +struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; + +template +struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> { +}; + +template +struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; + +#if defined(_LIBCPP_WIN32API) +typedef wstring __path_string; +typedef wchar_t __path_value; +#else +typedef string __path_string; +typedef char __path_value; +#endif + +#if defined(_LIBCPP_WIN32API) +_LIBCPP_FUNC_VIS +size_t __wide_to_char(const wstring&, char*, size_t); +_LIBCPP_FUNC_VIS +size_t __char_to_wide(const string&, wchar_t*, size_t); +#endif + +template +struct _PathCVT; + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +template +struct _PathCVT { + static_assert(__can_convert_char<_ECharT>::value, + "Char type not convertible"); + + typedef __narrow_to_utf8 _Narrower; +#if defined(_LIBCPP_WIN32API) + typedef __widen_from_utf8 _Widener; +#endif + + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _ECharT const* __b, + _ECharT const* __e) { +#if defined(_LIBCPP_WIN32API) + string __utf8; + _Narrower()(back_inserter(__utf8), __b, __e); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); +#else + _Narrower()(back_inserter(__dest), __b, __e); +#endif + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + if (__b == __e) + return; + basic_string<_ECharT> __tmp(__b, __e); +#if defined(_LIBCPP_WIN32API) + string __utf8; + _Narrower()(back_inserter(__utf8), __tmp.data(), + __tmp.data() + __tmp.length()); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); +#else + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); +#endif + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + const _ECharT __sentinel = _ECharT{}; + if (*__b == __sentinel) + return; + basic_string<_ECharT> __tmp; + for (; *__b != __sentinel; ++__b) + __tmp.push_back(*__b); +#if defined(_LIBCPP_WIN32API) + string __utf8; + _Narrower()(back_inserter(__utf8), __tmp.data(), + __tmp.data() + __tmp.length()); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); +#else + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); +#endif + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_source(__path_string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; +#endif // !_LIBCPP_HAS_NO_LOCALIZATION + +template <> +struct _PathCVT<__path_value> { + + template + _LIBCPP_HIDE_FROM_ABI + static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + for (; __b != __e; ++__b) + __dest.push_back(*__b); + } + + template + _LIBCPP_HIDE_FROM_ABI + static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + __dest.append(__b, __e); + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + const char __sentinel = char{}; + for (; *__b != __sentinel; ++__b) + __dest.push_back(*__b); + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_source(__path_string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +#if defined(_LIBCPP_WIN32API) +template <> +struct _PathCVT { + + _LIBCPP_HIDE_FROM_ABI + static void + __append_string(__path_string& __dest, const basic_string &__str) { + size_t __size = __char_to_wide(__str, nullptr, 0); + size_t __pos = __dest.size(); + __dest.resize(__pos + __size); + __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size); + } + + template + _LIBCPP_HIDE_FROM_ABI + static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + basic_string __tmp(__b, __e); + __append_string(__dest, __tmp); + } + + template + _LIBCPP_HIDE_FROM_ABI + static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type + __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + basic_string __tmp(__b, __e); + __append_string(__dest, __tmp); + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + const char __sentinel = char{}; + basic_string __tmp; + for (; *__b != __sentinel; ++__b) + __tmp.push_back(*__b); + __append_string(__dest, __tmp); + } + + template + _LIBCPP_HIDE_FROM_ABI + static void __append_source(__path_string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +template +struct _PathExport { + typedef __narrow_to_utf8 _Narrower; + typedef __widen_from_utf8 _Widener; + + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + string __utf8; + _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size()); + _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); + } +}; + +template <> +struct _PathExport { + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + size_t __size = __wide_to_char(__src, nullptr, 0); + size_t __pos = __dest.size(); + __dest.resize(__size); + __wide_to_char(__src, const_cast(__dest.data()) + __pos, __size); + } +}; + +template <> +struct _PathExport { + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + __dest.append(__src.begin(), __src.end()); + } +}; + +template <> +struct _PathExport { + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + __dest.append(__src.begin(), __src.end()); + } +}; + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <> +struct _PathExport { + typedef __narrow_to_utf8 _Narrower; + + template + _LIBCPP_HIDE_FROM_ABI + static void __append(_Str& __dest, const __path_string& __src) { + _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size()); + } +}; +#endif /* !_LIBCPP_HAS_NO_CHAR8_T */ +#endif /* _LIBCPP_WIN32API */ + +class _LIBCPP_TYPE_VIS path { + template + using _EnableIfPathable = + typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; + + template + using _SourceChar = typename __is_pathable<_Tp>::__char_type; + + template + using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; + +public: +#if defined(_LIBCPP_WIN32API) + typedef wchar_t value_type; + static constexpr value_type preferred_separator = L'\\'; +#else + typedef char value_type; + static constexpr value_type preferred_separator = '/'; +#endif + typedef basic_string string_type; + typedef basic_string_view __string_view; + + enum _LIBCPP_ENUM_VIS format : unsigned char { + auto_format, + native_format, + generic_format + }; + + // constructors and destructor + _LIBCPP_HIDE_FROM_ABI path() noexcept {} + _LIBCPP_HIDE_FROM_ABI path(const path& __p) : __pn_(__p.__pn_) {} + _LIBCPP_HIDE_FROM_ABI path(path&& __p) noexcept + : __pn_(_VSTD::move(__p.__pn_)) {} + + _LIBCPP_HIDE_FROM_ABI + path(string_type&& __s, format = format::auto_format) noexcept + : __pn_(_VSTD::move(__s)) {} + + template > + _LIBCPP_HIDE_FROM_ABI + path(const _Source& __src, format = format::auto_format) { + _SourceCVT<_Source>::__append_source(__pn_, __src); + } + + template + _LIBCPP_HIDE_FROM_ABI + path(_InputIt __first, _InputIt __last, format = format::auto_format) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + } + +/* +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + // TODO Implement locale conversions. + template > + path(const _Source& __src, const locale& __loc, format = format::auto_format); + template + path(_InputIt __first, _InputIt _last, const locale& __loc, + format = format::auto_format); +#endif +*/ + + _LIBCPP_HIDE_FROM_ABI + ~path() = default; + + // assignments + _LIBCPP_HIDE_FROM_ABI + path& operator=(const path& __p) { + __pn_ = __p.__pn_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator=(path&& __p) noexcept { + __pn_ = _VSTD::move(__p.__pn_); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator=(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& assign(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> + operator=(const _Source& __src) { + return this->assign(__src); + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> assign(const _Source& __src) { + __pn_.clear(); + _SourceCVT<_Source>::__append_source(__pn_, __src); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + path& assign(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + __pn_.clear(); + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + +public: + // appends +#if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI + path& operator/=(const path& __p) { + auto __p_root_name = __p.__root_name(); + auto __p_root_name_size = __p_root_name.size(); + if (__p.is_absolute() || + (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { + __pn_ = __p.__pn_; + return *this; + } + if (__p.has_root_directory()) { + path __root_name_str = root_name(); + __pn_ = __root_name_str.native(); + __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); + return *this; + } + if (has_filename() || (!has_root_directory() && is_absolute())) + __pn_ += preferred_separator; + __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); + return *this; + } + template + _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> + operator/=(const _Source& __src) { + return operator/=(path(__src)); + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> append(const _Source& __src) { + return operator/=(path(__src)); + } + + template + _LIBCPP_HIDE_FROM_ABI + path& append(_InputIt __first, _InputIt __last) { + return operator/=(path(__first, __last)); + } +#else + _LIBCPP_HIDE_FROM_ABI + path& operator/=(const path& __p) { + if (__p.is_absolute()) { + __pn_ = __p.__pn_; + return *this; + } + if (has_filename()) + __pn_ += preferred_separator; + __pn_ += __p.native(); + return *this; + } + + // FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src + // is known at compile time to be "/' since the user almost certainly intended + // to append a separator instead of overwriting the path with "/" + template + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> + operator/=(const _Source& __src) { + return this->append(__src); + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> append(const _Source& __src) { + using _Traits = __is_pathable<_Source>; + using _CVT = _PathCVT<_SourceChar<_Source> >; + bool __source_is_absolute = _VSTD_FS::__is_separator(_Traits::__first_or_null(__src)); + if (__source_is_absolute) + __pn_.clear(); + else if (has_filename()) + __pn_ += preferred_separator; + _CVT::__append_source(__pn_, __src); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + path& append(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); + using _CVT = _PathCVT<_ItVal>; + if (__first != __last && _VSTD_FS::__is_separator(*__first)) + __pn_.clear(); + else if (has_filename()) + __pn_ += preferred_separator; + _CVT::__append_range(__pn_, __first, __last); + return *this; + } +#endif + + // concatenation + _LIBCPP_HIDE_FROM_ABI + path& operator+=(const path& __x) { + __pn_ += __x.__pn_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator+=(const string_type& __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator+=(__string_view __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator+=(const value_type* __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& operator+=(value_type __x) { + __pn_ += __x; + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + typename enable_if<__can_convert_char<_ECharT>::value, path&>::type + operator+=(_ECharT __x) { + _PathCVT<_ECharT>::__append_source(__pn_, + basic_string_view<_ECharT>(&__x, 1)); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> operator+=(const _Source& __x) { + return this->concat(__x); + } + + template + _LIBCPP_HIDE_FROM_ABI + _EnableIfPathable<_Source> concat(const _Source& __x) { + _SourceCVT<_Source>::__append_source(__pn_, __x); + return *this; + } + + template + _LIBCPP_HIDE_FROM_ABI + path& concat(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + + // modifiers + _LIBCPP_HIDE_FROM_ABI + void clear() noexcept { __pn_.clear(); } + + _LIBCPP_HIDE_FROM_ABI + path& make_preferred() { +#if defined(_LIBCPP_WIN32API) + _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\'); +#endif + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& remove_filename() { + auto __fname = __filename(); + if (!__fname.empty()) + __pn_.erase(__fname.data() - __pn_.data()); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + path& replace_filename(const path& __replacement) { + remove_filename(); + return (*this /= __replacement); + } + + path& replace_extension(const path& __replacement = path()); + + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) == 0; + } +# if _LIBCPP_STD_VER <= 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) != 0; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator<(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) < 0; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator<=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) <= 0; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator>(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) > 0; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator>=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) >= 0; + } +# else // _LIBCPP_STD_VER <= 17 + friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const path& __lhs, const path& __rhs) noexcept { + return __lhs.__compare(__rhs.__pn_) <=> 0; + } +# endif // _LIBCPP_STD_VER <= 17 + + friend _LIBCPP_HIDE_FROM_ABI path operator/(const path& __lhs, const path& __rhs) { + path __result(__lhs); + __result /= __rhs; + return __result; + } + + _LIBCPP_HIDE_FROM_ABI + void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } + + // private helper to allow reserving memory in the path + _LIBCPP_HIDE_FROM_ABI + void __reserve(size_t __s) { __pn_.reserve(__s); } + + // native format observers + _LIBCPP_HIDE_FROM_ABI + const string_type& native() const noexcept { return __pn_; } + + _LIBCPP_HIDE_FROM_ABI + const value_type* c_str() const noexcept { return __pn_.c_str(); } + + _LIBCPP_HIDE_FROM_ABI operator string_type() const { return __pn_; } + +#if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const { return __pn_; } + + _LIBCPP_HIDE_FROM_ABI + _VSTD::wstring generic_wstring() const { + _VSTD::wstring __s; + __s.resize(__pn_.size()); + _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); + return __s; + } + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , + class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _PathExport<_ECharT>::__append(__s, __pn_); + return __s; + } + + _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const { + return string(); + } + _LIBCPP_HIDE_FROM_ABI __u8_string u8string() const { + using _CVT = __narrow_to_utf8; + __u8_string __s; + __s.reserve(__pn_.size()); + _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + + _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const { + return string(); + } + _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const { + return string(); + } + + // generic format observers + template , + class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI + basic_string<_ECharT, _Traits, _Allocator> + generic_string(const _Allocator& __a = _Allocator()) const { + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s = string<_ECharT, _Traits, _Allocator>(__a); + // Note: This (and generic_u8string below) is slightly suboptimal as + // it iterates twice over the string; once to convert it to the right + // character type, and once to replace path delimiters. + _VSTD::replace(__s.begin(), __s.end(), + static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); + return __s; + } + + _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return generic_string(); } + _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return generic_string(); } + _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return generic_string(); } + _LIBCPP_HIDE_FROM_ABI + __u8_string generic_u8string() const { + __u8_string __s = u8string(); + _VSTD::replace(__s.begin(), __s.end(), '\\', '/'); + return __s; + } +#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +#else /* _LIBCPP_WIN32API */ + + _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const { return __pn_; } +#ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_HIDE_FROM_ABI _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } +#else + _LIBCPP_HIDE_FROM_ABI _VSTD::string u8string() const { return __pn_; } +#endif + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , + class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _CVT = __widen_from_utf8; + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _CVT()(std::back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const { + return string(); + } +#endif + _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const { + return string(); + } + _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const { + return string(); + } +#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ + + // generic format observers + _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return __pn_; } +#ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_HIDE_FROM_ABI _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } +#else + _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_u8string() const { return __pn_; } +#endif + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , + class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI + basic_string<_ECharT, _Traits, _Allocator> + generic_string(const _Allocator& __a = _Allocator()) const { + return string<_ECharT, _Traits, _Allocator>(__a); + } + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_HIDE_FROM_ABI _VSTD::wstring generic_wstring() const { return string(); } +#endif + _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return string(); } + _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return string(); } +#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +#endif /* !_LIBCPP_WIN32API */ + +private: + int __compare(__string_view) const; + __string_view __root_name() const; + __string_view __root_directory() const; + __string_view __root_path_raw() const; + __string_view __relative_path() const; + __string_view __parent_path() const; + __string_view __filename() const; + __string_view __stem() const; + __string_view __extension() const; + +public: + // compare + _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { + return __compare(__p.__pn_); + } + _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { + return __compare(__s); + } + _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { + return __compare(__s); + } + _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { + return __compare(__s); + } + + // decomposition + _LIBCPP_HIDE_FROM_ABI path root_name() const { + return string_type(__root_name()); + } + _LIBCPP_HIDE_FROM_ABI path root_directory() const { + return string_type(__root_directory()); + } + _LIBCPP_HIDE_FROM_ABI path root_path() const { +#if defined(_LIBCPP_WIN32API) + return string_type(__root_path_raw()); +#else + return root_name().append(string_type(__root_directory())); +#endif + } + _LIBCPP_HIDE_FROM_ABI path relative_path() const { + return string_type(__relative_path()); + } + _LIBCPP_HIDE_FROM_ABI path parent_path() const { + return string_type(__parent_path()); + } + _LIBCPP_HIDE_FROM_ABI path filename() const { + return string_type(__filename()); + } + _LIBCPP_HIDE_FROM_ABI path stem() const { return string_type(__stem()); } + _LIBCPP_HIDE_FROM_ABI path extension() const { + return string_type(__extension()); + } + + // query + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool + empty() const noexcept { + return __pn_.empty(); + } + + _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { + return !__root_name().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { + return !__root_directory().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { + return !__root_path_raw().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { + return !__relative_path().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { + return !__parent_path().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_filename() const { + return !__filename().empty(); + } + _LIBCPP_HIDE_FROM_ABI bool has_stem() const { return !__stem().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_extension() const { + return !__extension().empty(); + } + + _LIBCPP_HIDE_FROM_ABI bool is_absolute() const { +#if defined(_LIBCPP_WIN32API) + __string_view __root_name_str = __root_name(); + __string_view __root_dir = __root_directory(); + if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { + // A drive letter with no root directory is relative, e.g. x:example. + return !__root_dir.empty(); + } + // If no root name, it's relative, e.g. \example is relative to the current drive + if (__root_name_str.empty()) + return false; + if (__root_name_str.size() < 3) + return false; + // A server root name, like \\server, is always absolute + if (__root_name_str[0] != '/' && __root_name_str[0] != '\\') + return false; + if (__root_name_str[1] != '/' && __root_name_str[1] != '\\') + return false; + // Seems to be a server root name + return true; +#else + return has_root_directory(); +#endif + } + _LIBCPP_HIDE_FROM_ABI bool is_relative() const { return !is_absolute(); } + + // relative paths + path lexically_normal() const; + path lexically_relative(const path& __base) const; + + _LIBCPP_HIDE_FROM_ABI path lexically_proximate(const path& __base) const { + path __result = this->lexically_relative(__base); + if (__result.native().empty()) + return *this; + return __result; + } + + // iterators + class _LIBCPP_TYPE_VIS iterator; + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + +#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template + _LIBCPP_HIDE_FROM_ABI friend + typename enable_if::value && + is_same<_Traits, char_traits >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << _VSTD::__quoted(__p.native()); + return __os; + } + + template + _LIBCPP_HIDE_FROM_ABI friend + typename enable_if::value || + !is_same<_Traits, char_traits >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << _VSTD::__quoted(__p.string<_CharT, _Traits>()); + return __os; + } + + template + _LIBCPP_HIDE_FROM_ABI friend basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { + basic_string<_CharT, _Traits> __tmp; + __is >> _VSTD::__quoted(__tmp); + __p = __tmp; + return __is; + } +#endif // !_LIBCPP_HAS_NO_LOCALIZATION + +private: + inline _LIBCPP_HIDE_FROM_ABI path& + __assign_view(__string_view const& __s) noexcept { + __pn_ = string_type(__s); + return *this; + } + string_type __pn_; +}; + +inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { + __lhs.swap(__rhs); +} + +_LIBCPP_FUNC_VIS +size_t hash_value(const path& __p) noexcept; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PATH_H diff --git a/gnu/llvm/libcxx/include/__filesystem/path_iterator.h b/gnu/llvm/libcxx/include/__filesystem/path_iterator.h new file mode 100644 index 00000000000..6f2baf8f7a2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/path_iterator.h @@ -0,0 +1,134 @@ +// -*- 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___FILESYSTEM_PATH_ITERATOR_H +#define _LIBCPP___FILESYSTEM_PATH_ITERATOR_H + +#include <__assert> +#include <__availability> +#include <__config> +#include <__filesystem/path.h> +#include <__iterator/iterator_traits.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class _LIBCPP_TYPE_VIS path::iterator { +public: + enum _ParserState : unsigned char { + _Singular, + _BeforeBegin, + _InRootName, + _InRootDir, + _InFilenames, + _InTrailingSep, + _AtEnd + }; + +public: + typedef input_iterator_tag iterator_category; + typedef bidirectional_iterator_tag iterator_concept; + + typedef path value_type; + typedef ptrdiff_t difference_type; + typedef const path* pointer; + typedef path reference; + +public: + _LIBCPP_INLINE_VISIBILITY + iterator() + : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), + __state_(_Singular) {} + + iterator(const iterator&) = default; + ~iterator() = default; + + iterator& operator=(const iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { return __stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { return &__stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator++() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to increment a singular iterator"); + _LIBCPP_ASSERT(__state_ != _AtEnd, + "attempting to increment the end iterator"); + return __increment(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator++(int) { + iterator __it(*this); + this->operator++(); + return __it; + } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator--() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to decrement a singular iterator"); + _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), + "attempting to decrement the begin iterator"); + return __decrement(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator--(int) { + iterator __it(*this); + this->operator--(); + return __it; + } + +private: + friend class path; + + inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&, + const iterator&); + + iterator& __increment(); + iterator& __decrement(); + + path __stashed_elem_; + const path* __path_ptr_; + path::__string_view __entry_; + _ParserState __state_; +}; + +inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, + const path::iterator& __rhs) { + return __lhs.__path_ptr_ == __rhs.__path_ptr_ && + __lhs.__entry_.data() == __rhs.__entry_.data(); +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs, + const path::iterator& __rhs) { + return !(__lhs == __rhs); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PATH_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__filesystem/perm_options.h b/gnu/llvm/libcxx/include/__filesystem/perm_options.h new file mode 100644 index 00000000000..4aba302edfb --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/perm_options.h @@ -0,0 +1,77 @@ +// -*- 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___FILESYSTEM_PERM_OPTIONS_H +#define _LIBCPP___FILESYSTEM_PERM_OPTIONS_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +enum class _LIBCPP_ENUM_VIS perm_options : unsigned char { + replace = 1, + add = 2, + remove = 4, + nofollow = 8 +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator&(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) & + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator|(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) | + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator^(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) ^ + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perm_options operator~(perm_options __lhs) { + return static_cast(~static_cast(__lhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator&=(perm_options& __lhs, perm_options __rhs) { + return __lhs = __lhs & __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator|=(perm_options& __lhs, perm_options __rhs) { + return __lhs = __lhs | __rhs; +} + +_LIBCPP_INLINE_VISIBILITY +inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) { + return __lhs = __lhs ^ __rhs; +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PERM_OPTIONS_H diff --git a/gnu/llvm/libcxx/include/__filesystem/perms.h b/gnu/llvm/libcxx/include/__filesystem/perms.h new file mode 100644 index 00000000000..df4590057ee --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/perms.h @@ -0,0 +1,95 @@ +// -*- 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___FILESYSTEM_PERMS_H +#define _LIBCPP___FILESYSTEM_PERMS_H + +#include <__availability> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +// On Windows, these permission bits map to one single readonly flag per +// file, and the executable bit is always returned as set. When setting +// permissions, as long as the write bit is set for either owner, group or +// others, the readonly flag is cleared. +enum class _LIBCPP_ENUM_VIS perms : unsigned { + none = 0, + + owner_read = 0400, + owner_write = 0200, + owner_exec = 0100, + owner_all = 0700, + + group_read = 040, + group_write = 020, + group_exec = 010, + group_all = 070, + + others_read = 04, + others_write = 02, + others_exec = 01, + others_all = 07, + + all = 0777, + + set_uid = 04000, + set_gid = 02000, + sticky_bit = 01000, + mask = 07777, + unknown = 0xFFFF, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator&(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) & + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator|(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) | + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator^(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) ^ + static_cast(__rhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator~(perms __lhs) { + return static_cast(~static_cast(__lhs)); +} + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator&=(perms& __lhs, perms __rhs) { return __lhs = __lhs & __rhs; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __rhs; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; } + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_PERMS_H diff --git a/gnu/llvm/libcxx/include/__filesystem/recursive_directory_iterator.h b/gnu/llvm/libcxx/include/__filesystem/recursive_directory_iterator.h new file mode 100644 index 00000000000..b20d201f583 --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/recursive_directory_iterator.h @@ -0,0 +1,185 @@ +// -*- 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___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H +#define _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H + +#include <__availability> +#include <__config> +#include <__filesystem/directory_entry.h> +#include <__filesystem/directory_options.h> +#include <__filesystem/path.h> +#include <__iterator/iterator_traits.h> +#include <__memory/shared_ptr.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +class recursive_directory_iterator { +public: + using value_type = directory_entry; + using difference_type = ptrdiff_t; + using pointer = directory_entry const*; + using reference = directory_entry const&; + using iterator_category = input_iterator_tag; + +public: + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator() noexcept : __rec_(false) {} + + _LIBCPP_INLINE_VISIBILITY + explicit recursive_directory_iterator( + const path& __p, directory_options __xoptions = directory_options::none) + : recursive_directory_iterator(__p, __xoptions, nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, directory_options __xoptions, + error_code& __ec) + : recursive_directory_iterator(__p, __xoptions, &__ec) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, error_code& __ec) + : recursive_directory_iterator(__p, directory_options::none, &__ec) {} + + recursive_directory_iterator(const recursive_directory_iterator&) = default; + recursive_directory_iterator(recursive_directory_iterator&&) = default; + + recursive_directory_iterator& + operator=(const recursive_directory_iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& + operator=(recursive_directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + __rec_ = __o.__rec_; + } + return *this; + } + + ~recursive_directory_iterator() = default; + + _LIBCPP_INLINE_VISIBILITY + const directory_entry& operator*() const { return __dereference(); } + + _LIBCPP_INLINE_VISIBILITY + const directory_entry* operator->() const { return &__dereference(); } + + recursive_directory_iterator& operator++() { return __increment(); } + + _LIBCPP_INLINE_VISIBILITY + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& increment(error_code& __ec) { + return __increment(&__ec); + } + + _LIBCPP_FUNC_VIS directory_options options() const; + _LIBCPP_FUNC_VIS int depth() const; + + _LIBCPP_INLINE_VISIBILITY + void pop() { __pop(); } + + _LIBCPP_INLINE_VISIBILITY + void pop(error_code& __ec) { __pop(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + bool recursion_pending() const { return __rec_; } + + _LIBCPP_INLINE_VISIBILITY + void disable_recursion_pending() { __rec_ = false; } + +private: + _LIBCPP_FUNC_VIS + recursive_directory_iterator(const path& __p, directory_options __opt, + error_code* __ec); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + + _LIBCPP_FUNC_VIS + bool __try_recursion(error_code* __ec); + + _LIBCPP_FUNC_VIS + void __advance(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + recursive_directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + void __pop(error_code* __ec = nullptr); + + inline _LIBCPP_INLINE_VISIBILITY friend bool + operator==(const recursive_directory_iterator&, + const recursive_directory_iterator&) noexcept; + + struct _LIBCPP_HIDDEN __shared_imp; + shared_ptr<__shared_imp> __imp_; + bool __rec_; +}; // class recursive_directory_iterator + +inline _LIBCPP_INLINE_VISIBILITY bool +operator==(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +_LIBCPP_INLINE_VISIBILITY +inline bool operator!=(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return !(__lhs == __rhs); +} +// enable recursive_directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +begin(recursive_directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +end(recursive_directory_iterator) noexcept { + return recursive_directory_iterator(); +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#if _LIBCPP_STD_VER > 17 + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true; + +template <> +_LIBCPP_AVAILABILITY_FILESYSTEM +inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true; + +#endif // _LIBCPP_STD_VER > 17 + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__filesystem/space_info.h b/gnu/llvm/libcxx/include/__filesystem/space_info.h new file mode 100644 index 00000000000..d0747e35ebf --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/space_info.h @@ -0,0 +1,43 @@ +// -*- 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___FILESYSTEM_SPACE_INFO_H +#define _LIBCPP___FILESYSTEM_SPACE_INFO_H + +#include <__availability> +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +struct _LIBCPP_TYPE_VIS space_info { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; + +# if _LIBCPP_STD_VER > 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const space_info&, const space_info&) = default; +# endif +}; + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_SPACE_INFO_H diff --git a/gnu/llvm/libcxx/include/__filesystem/u8path.h b/gnu/llvm/libcxx/include/__filesystem/u8path.h new file mode 100644 index 00000000000..d35faa14bb8 --- /dev/null +++ b/gnu/llvm/libcxx/include/__filesystem/u8path.h @@ -0,0 +1,108 @@ +// -*- 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___FILESYSTEM_U8PATH_H +#define _LIBCPP___FILESYSTEM_U8PATH_H + +#include <__algorithm/unwrap_iter.h> +#include <__availability> +#include <__config> +#include <__filesystem/path.h> +#include +#include + +// Only required on Windows for __widen_from_utf8, and included conservatively +// because it requires support for localization. +#if defined(_LIBCPP_WIN32API) +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_CXX03_LANG + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T + typename enable_if<__is_pathable<_InputIt>::value, path>::type + u8path(_InputIt __f, _InputIt __l) { + static_assert( +#ifndef _LIBCPP_HAS_NO_CHAR8_T + is_same::__char_type, char8_t>::value || +#endif + is_same::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" + " or 'char8_t'"); +#if defined(_LIBCPP_WIN32API) + string __tmp(__f, __l); + using _CVT = __widen_from_utf8; + _VSTD::wstring __w; + __w.reserve(__tmp.size()); + _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); + return path(__w); +#else + return path(__f, __l); +#endif /* !_LIBCPP_WIN32API */ +} + +#if defined(_LIBCPP_WIN32API) +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T + typename enable_if<__is_pathable<_InputIt>::value, path>::type + u8path(_InputIt __f, _NullSentinel) { + static_assert( +#ifndef _LIBCPP_HAS_NO_CHAR8_T + is_same::__char_type, char8_t>::value || +#endif + is_same::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" + " or 'char8_t'"); + string __tmp; + const char __sentinel = char{}; + for (; *__f != __sentinel; ++__f) + __tmp.push_back(*__f); + using _CVT = __widen_from_utf8; + _VSTD::wstring __w; + __w.reserve(__tmp.size()); + _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); + return path(__w); +} +#endif /* _LIBCPP_WIN32API */ + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T + typename enable_if<__is_pathable<_Source>::value, path>::type + u8path(const _Source& __s) { + static_assert( +#ifndef _LIBCPP_HAS_NO_CHAR8_T + is_same::__char_type, char8_t>::value || +#endif + is_same::__char_type, char>::value, + "u8path(Source const&) requires Source have a character type of type " + "'char' or 'char8_t'"); +#if defined(_LIBCPP_WIN32API) + using _Traits = __is_pathable<_Source>; + return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s))); +#else + return path(__s); +#endif +} + +_LIBCPP_AVAILABILITY_FILESYSTEM_POP + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // _LIBCPP_CXX03_LANG + +#endif // _LIBCPP___FILESYSTEM_U8PATH_H diff --git a/gnu/llvm/libcxx/include/__format/buffer.h b/gnu/llvm/libcxx/include/__format/buffer.h new file mode 100644 index 00000000000..ddfe76728e9 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/buffer.h @@ -0,0 +1,573 @@ +// -*- 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___FORMAT_BUFFER_H +#define _LIBCPP___FORMAT_BUFFER_H + +#include <__algorithm/copy_n.h> +#include <__algorithm/fill_n.h> +#include <__algorithm/max.h> +#include <__algorithm/min.h> +#include <__algorithm/ranges_copy_n.h> +#include <__algorithm/transform.h> +#include <__algorithm/unwrap_iter.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/enable_insertable.h> +#include <__format/format_to_n_result.h> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/wrap_iter.h> +#include <__utility/move.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { + +/// A "buffer" that handles writing to the proper iterator. +/// +/// This helper is used together with the @ref back_insert_iterator to offer +/// type-erasure for the formatting functions. This reduces the number to +/// template instantiations. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __output_buffer { +public: + using value_type = _CharT; + + template + _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(_CharT* __ptr, size_t __capacity, _Tp* __obj) + : __ptr_(__ptr), + __capacity_(__capacity), + __flush_([](_CharT* __p, size_t __n, void* __o) { static_cast<_Tp*>(__o)->__flush(__p, __n); }), + __obj_(__obj) {} + + _LIBCPP_HIDE_FROM_ABI void __reset(_CharT* __ptr, size_t __capacity) { + __ptr_ = __ptr; + __capacity_ = __capacity; + } + + _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return std::back_insert_iterator{*this}; } + + // Used in std::back_insert_iterator. + _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { + __ptr_[__size_++] = __c; + + // Profiling showed flushing after adding is more efficient than flushing + // when entering the function. + if (__size_ == __capacity_) + __flush(); + } + + /// Copies the input __str to the buffer. + /// + /// Since some of the input is generated by std::to_chars, there needs to be a + /// conversion when _CharT is wchar_t. + template <__fmt_char_type _InCharT> + _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) { + // When the underlying iterator is a simple iterator the __capacity_ is + // infinite. For a string or container back_inserter it isn't. This means + // adding a large string the the buffer can cause some overhead. In that + // case a better approach could be: + // - flush the buffer + // - container.append(__str.begin(), __str.end()); + // The same holds true for the fill. + // For transform it might be slightly harder, however the use case for + // transform is slightly less common; it converts hexadecimal values to + // upper case. For integral these strings are short. + // TODO FMT Look at the improvements above. + size_t __n = __str.size(); + + __flush_on_overflow(__n); + if (__n <= __capacity_) { + _VSTD::copy_n(__str.data(), __n, _VSTD::addressof(__ptr_[__size_])); + __size_ += __n; + return; + } + + // The output doesn't fit in the internal buffer. + // Copy the data in "__capacity_" sized chunks. + _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); + const _InCharT* __first = __str.data(); + do { + size_t __chunk = _VSTD::min(__n, __capacity_); + _VSTD::copy_n(__first, __chunk, _VSTD::addressof(__ptr_[__size_])); + __size_ = __chunk; + __first += __chunk; + __n -= __chunk; + __flush(); + } while (__n); + } + + /// A std::transform wrapper. + /// + /// Like @ref __copy it may need to do type conversion. + template <__fmt_char_type _InCharT, class _UnaryOperation> + _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { + _LIBCPP_ASSERT(__first <= __last, "not a valid range"); + + size_t __n = static_cast(__last - __first); + __flush_on_overflow(__n); + if (__n <= __capacity_) { + _VSTD::transform(__first, __last, _VSTD::addressof(__ptr_[__size_]), _VSTD::move(__operation)); + __size_ += __n; + return; + } + + // The output doesn't fit in the internal buffer. + // Transform the data in "__capacity_" sized chunks. + _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); + do { + size_t __chunk = _VSTD::min(__n, __capacity_); + _VSTD::transform(__first, __first + __chunk, _VSTD::addressof(__ptr_[__size_]), __operation); + __size_ = __chunk; + __first += __chunk; + __n -= __chunk; + __flush(); + } while (__n); + } + + /// A \c fill_n wrapper. + _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { + __flush_on_overflow(__n); + if (__n <= __capacity_) { + _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __n, __value); + __size_ += __n; + return; + } + + // The output doesn't fit in the internal buffer. + // Fill the buffer in "__capacity_" sized chunks. + _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); + do { + size_t __chunk = _VSTD::min(__n, __capacity_); + _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __chunk, __value); + __size_ = __chunk; + __n -= __chunk; + __flush(); + } while (__n); + } + + _LIBCPP_HIDE_FROM_ABI void __flush() { + __flush_(__ptr_, __size_, __obj_); + __size_ = 0; + } + +private: + _CharT* __ptr_; + size_t __capacity_; + size_t __size_{0}; + void (*__flush_)(_CharT*, size_t, void*); + void* __obj_; + + /// Flushes the buffer when the output operation would overflow the buffer. + /// + /// A simple approach for the overflow detection would be something along the + /// lines: + /// \code + /// // The internal buffer is large enough. + /// if (__n <= __capacity_) { + /// // Flush when we really would overflow. + /// if (__size_ + __n >= __capacity_) + /// __flush(); + /// ... + /// } + /// \endcode + /// + /// This approach works for all cases but one: + /// A __format_to_n_buffer_base where \ref __enable_direct_output is true. + /// In that case the \ref __capacity_ of the buffer changes during the first + /// \ref __flush. During that operation the output buffer switches from its + /// __writer_ to its __storage_. The \ref __capacity_ of the former depends + /// on the value of n, of the latter is a fixed size. For example: + /// - a format_to_n call with a 10'000 char buffer, + /// - the buffer is filled with 9'500 chars, + /// - adding 1'000 elements would overflow the buffer so the buffer gets + /// changed and the \ref __capacity_ decreases from 10'000 to + /// __buffer_size (256 at the time of writing). + /// + /// This means that the \ref __flush for this class may need to copy a part of + /// the internal buffer to the proper output. In this example there will be + /// 500 characters that need this copy operation. + /// + /// Note it would be more efficient to write 500 chars directly and then swap + /// the buffers. This would make the code more complex and \ref format_to_n is + /// not the most common use case. Therefore the optimization isn't done. + _LIBCPP_HIDE_FROM_ABI void __flush_on_overflow(size_t __n) { + if (__size_ + __n >= __capacity_) + __flush(); + } +}; + +/// A storage using an internal buffer. +/// +/// This storage is used when writing a single element to the output iterator +/// is expensive. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __internal_storage { +public: + _LIBCPP_HIDE_FROM_ABI _CharT* __begin() { return __buffer_; } + + static constexpr size_t __buffer_size = 256 / sizeof(_CharT); + +private: + _CharT __buffer_[__buffer_size]; +}; + +/// A storage writing directly to the storage. +/// +/// This requires the storage to be a contiguous buffer of \a _CharT. +/// Since the output is directly written to the underlying storage this class +/// is just an empty class. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __direct_storage {}; + +template +concept __enable_direct_output = __fmt_char_type<_CharT> && + (same_as<_OutIt, _CharT*> +#ifndef _LIBCPP_ENABLE_DEBUG_MODE + || same_as<_OutIt, __wrap_iter<_CharT*>> +#endif + ); + +/// Write policy for directly writing to the underlying output. +template +class _LIBCPP_TEMPLATE_VIS __writer_direct { +public: + _LIBCPP_HIDE_FROM_ABI explicit __writer_direct(_OutIt __out_it) + : __out_it_(__out_it) {} + + _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() { return __out_it_; } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT*, size_t __n) { + // _OutIt can be a __wrap_iter. Therefore the original iterator + // is adjusted. + __out_it_ += __n; + } + +private: + _OutIt __out_it_; +}; + +/// Write policy for copying the buffer to the output. +template +class _LIBCPP_TEMPLATE_VIS __writer_iterator { +public: + _LIBCPP_HIDE_FROM_ABI explicit __writer_iterator(_OutIt __out_it) + : __out_it_{_VSTD::move(__out_it)} {} + + _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { return std::move(__out_it_); } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { + __out_it_ = std::ranges::copy_n(__ptr, __n, std::move(__out_it_)).out; + } + +private: + _OutIt __out_it_; +}; + +/// Concept to see whether a \a _Container is insertable. +/// +/// The concept is used to validate whether multiple calls to a +/// \ref back_insert_iterator can be replace by a call to \c _Container::insert. +/// +/// \note a \a _Container needs to opt-in to the concept by specializing +/// \ref __enable_insertable. +template +concept __insertable = + __enable_insertable<_Container> && __fmt_char_type && + requires(_Container& __t, add_pointer_t __first, + add_pointer_t __last) { __t.insert(__t.end(), __first, __last); }; + +/// Extract the container type of a \ref back_insert_iterator. +template +struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container { + using type = void; +}; + +template <__insertable _Container> +struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container> { + using type = _Container; +}; + +/// Write policy for inserting the buffer in a container. +template +class _LIBCPP_TEMPLATE_VIS __writer_container { +public: + using _CharT = typename _Container::value_type; + + _LIBCPP_HIDE_FROM_ABI explicit __writer_container(back_insert_iterator<_Container> __out_it) + : __container_{__out_it.__get_container()} {} + + _LIBCPP_HIDE_FROM_ABI auto __out_it() { return std::back_inserter(*__container_); } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { + __container_->insert(__container_->end(), __ptr, __ptr + __n); + } + +private: + _Container* __container_; +}; + +/// Selects the type of the writer used for the output iterator. +template +class _LIBCPP_TEMPLATE_VIS __writer_selector { + using _Container = typename __back_insert_iterator_container<_OutIt>::type; + +public: + using type = conditional_t, __writer_container<_Container>, + conditional_t<__enable_direct_output<_OutIt, _CharT>, __writer_direct<_OutIt, _CharT>, + __writer_iterator<_OutIt, _CharT>>>; +}; + +/// The generic formatting buffer. +template +requires(output_iterator<_OutIt, const _CharT&>) class _LIBCPP_TEMPLATE_VIS + __format_buffer { + using _Storage = + conditional_t<__enable_direct_output<_OutIt, _CharT>, + __direct_storage<_CharT>, __internal_storage<_CharT>>; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) + requires(same_as<_Storage, __internal_storage<_CharT>>) + : __output_(__storage_.__begin(), __storage_.__buffer_size, this), __writer_(_VSTD::move(__out_it)) {} + + _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) requires( + same_as<_Storage, __direct_storage<_CharT>>) + : __output_(_VSTD::__unwrap_iter(__out_it), size_t(-1), this), + __writer_(_VSTD::move(__out_it)) {} + + _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return __output_.__make_output_iterator(); } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { __writer_.__flush(__ptr, __n); } + + _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { + __output_.__flush(); + return _VSTD::move(__writer_).__out_it(); + } + +private: + _LIBCPP_NO_UNIQUE_ADDRESS _Storage __storage_; + __output_buffer<_CharT> __output_; + typename __writer_selector<_OutIt, _CharT>::type __writer_; +}; + +/// A buffer that counts the number of insertions. +/// +/// Since \ref formatted_size only needs to know the size, the output itself is +/// discarded. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __formatted_size_buffer { +public: + _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return __output_.__make_output_iterator(); } + + _LIBCPP_HIDE_FROM_ABI void __flush(const _CharT*, size_t __n) { __size_ += __n; } + + _LIBCPP_HIDE_FROM_ABI size_t __result() && { + __output_.__flush(); + return __size_; + } + +private: + __internal_storage<_CharT> __storage_; + __output_buffer<_CharT> __output_{__storage_.__begin(), __storage_.__buffer_size, this}; + size_t __size_{0}; +}; + +/// The base of a buffer that counts and limits the number of insertions. +template + requires(output_iterator<_OutIt, const _CharT&>) +struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base { + using _Size = iter_difference_t<_OutIt>; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size) + : __writer_(_VSTD::move(__out_it)), __max_size_(_VSTD::max(_Size(0), __max_size)) {} + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { + if (_Size(__size_) <= __max_size_) + __writer_.__flush(__ptr, _VSTD::min(_Size(__n), __max_size_ - __size_)); + __size_ += __n; + } + +protected: + __internal_storage<_CharT> __storage_; + __output_buffer<_CharT> __output_{__storage_.__begin(), __storage_.__buffer_size, this}; + typename __writer_selector<_OutIt, _CharT>::type __writer_; + + _Size __max_size_; + _Size __size_{0}; +}; + +/// The base of a buffer that counts and limits the number of insertions. +/// +/// This version is used when \c __enable_direct_output<_OutIt, _CharT> == true. +/// +/// This class limits the size available to the direct writer so it will not +/// exceed the maximum number of code units. +template + requires(output_iterator<_OutIt, const _CharT&>) +class _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base<_OutIt, _CharT, true> { + using _Size = iter_difference_t<_OutIt>; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size) + : __output_(_VSTD::__unwrap_iter(__out_it), __max_size, this), + __writer_(_VSTD::move(__out_it)), + __max_size_(__max_size) { + if (__max_size <= 0) [[unlikely]] + __output_.__reset(__storage_.__begin(), __storage_.__buffer_size); + } + + _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { + // A __flush to the direct writer happens in the following occasions: + // - The format function has written the maximum number of allowed code + // units. At this point it's no longer valid to write to this writer. So + // switch to the internal storage. This internal storage doesn't need to + // be written anywhere so the __flush for that storage writes no output. + // - Like above, but the next "mass write" operation would overflow the + // buffer. In that case the buffer is pre-emptively switched. The still + // valid code units will be written separately. + // - The format_to_n function is finished. In this case there's no need to + // switch the buffer, but for simplicity the buffers are still switched. + // When the __max_size <= 0 the constructor already switched the buffers. + if (__size_ == 0 && __ptr != __storage_.__begin()) { + __writer_.__flush(__ptr, __n); + __output_.__reset(__storage_.__begin(), __storage_.__buffer_size); + } else if (__size_ < __max_size_) { + // Copies a part of the internal buffer to the output up to n characters. + // See __output_buffer<_CharT>::__flush_on_overflow for more information. + _Size __s = _VSTD::min(_Size(__n), __max_size_ - __size_); + std::copy_n(__ptr, __s, __writer_.__out_it()); + __writer_.__flush(__ptr, __s); + } + + __size_ += __n; + } + +protected: + __internal_storage<_CharT> __storage_; + __output_buffer<_CharT> __output_; + __writer_direct<_OutIt, _CharT> __writer_; + + _Size __max_size_; + _Size __size_{0}; +}; + +/// The buffer that counts and limits the number of insertions. +template + requires(output_iterator<_OutIt, const _CharT&>) +struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer final + : public __format_to_n_buffer_base< _OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>> { + using _Base = __format_to_n_buffer_base<_OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>>; + using _Size = iter_difference_t<_OutIt>; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer(_OutIt __out_it, _Size __max_size) + : _Base(_VSTD::move(__out_it), __max_size) {} + _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return this->__output_.__make_output_iterator(); } + + _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __result() && { + this->__output_.__flush(); + return {_VSTD::move(this->__writer_).__out_it(), this->__size_}; + } +}; + +// A dynamically growing buffer intended to be used for retargeting a context. +// +// P2286 Formatting ranges adds range formatting support. It allows the user to +// specify the minimum width for the entire formatted range. The width of the +// range is not known until the range is formatted. Formatting is done to an +// output_iterator so there's no guarantee it would be possible to add the fill +// to the front of the output. Instead the range is formatted to a temporary +// buffer and that buffer is formatted as a string. +// +// There is an issue with that approach, the format context used in +// std::formatter::format contains the output iterator used as part of its +// type. So using this output iterator means there needs to be a new format +// context and the format arguments need to be retargeted to the new context. +// This retargeting is done by a basic_format_context specialized for the +// __iterator of this container. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __retarget_buffer { +public: + using value_type = _CharT; + + struct __iterator { + using difference_type = ptrdiff_t; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer) + : __buffer_(std::addressof(__buffer)) {} + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(const _CharT& __c) { + __buffer_->push_back(__c); + return *this; + } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(_CharT&& __c) { + __buffer_->push_back(__c); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) { return *this; } + __retarget_buffer* __buffer_; + }; + + _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { __buffer_.reserve(__size_hint); } + + _LIBCPP_HIDE_FROM_ABI __iterator __make_output_iterator() { return __iterator{*this}; } + + _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { __buffer_.push_back(__c); } + + template <__fmt_char_type _InCharT> + _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) { + __buffer_.insert(__buffer_.end(), __str.begin(), __str.end()); + } + + template <__fmt_char_type _InCharT, class _UnaryOperation> + _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { + _LIBCPP_ASSERT(__first <= __last, "not a valid range"); + std::transform(__first, __last, std::back_inserter(__buffer_), std::move(__operation)); + } + + _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { __buffer_.insert(__buffer_.end(), __n, __value); } + + _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__buffer_.data(), __buffer_.size()}; } + +private: + // Use vector instead of string to avoid adding zeros after every append + // operation. The buffer is exposed as a string_view and not as a c-string. + vector<_CharT> __buffer_; +}; + +} // namespace __format + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_BUFFER_H diff --git a/gnu/llvm/libcxx/include/__format/concepts.h b/gnu/llvm/libcxx/include/__format/concepts.h new file mode 100644 index 00000000000..ba8d8e31622 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/concepts.h @@ -0,0 +1,77 @@ +// -*- 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___FORMAT_CONCEPTS_H +#define _LIBCPP___FORMAT_CONCEPTS_H + +#include <__concepts/same_as.h> +#include <__concepts/semiregular.h> +#include <__config> +#include <__format/format_fwd.h> +#include <__format/format_parse_context.h> +#include <__type_traits/is_specialization.h> +#include <__utility/pair.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +/// The character type specializations of \ref formatter. +template +concept __fmt_char_type = + same_as<_CharT, char> +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + || same_as<_CharT, wchar_t> +# endif + ; + +// The output iterator isn't specified. A formatter should accept any +// output_iterator. This iterator is a minimal iterator to test the concept. +// (Note testing for (w)format_context would be a valid choice, but requires +// selecting the proper one depending on the type of _CharT.) +template +using __fmt_iter_for = _CharT*; + +template +concept __formattable = + (semiregular, _CharT>>) && + requires(formatter, _CharT> __f, + const formatter, _CharT> __cf, + _Tp __t, + basic_format_context<__fmt_iter_for<_CharT>, _CharT> __fc, + basic_format_parse_context<_CharT> __pc) { + { __f.parse(__pc) } -> same_as::iterator>; + { __cf.format(__t, __fc) } -> same_as<__fmt_iter_for<_CharT>>; + }; + +# if _LIBCPP_STD_VER > 20 +template +concept formattable = __formattable<_Tp, _CharT>; + +// [tuple.like] defines a tuple-like exposition only concept. This concept is +// not related to that. Therefore it uses a different name for the concept. +// +// TODO FMT Add a test to validate we fail when using that concept after P2165 +// has been implemented. +template +concept __fmt_pair_like = + __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2); + +# endif //_LIBCPP_STD_VER > 20 +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_CONCEPTS_H diff --git a/gnu/llvm/libcxx/include/__format/container_adaptor.h b/gnu/llvm/libcxx/include/__format/container_adaptor.h new file mode 100644 index 00000000000..62b698186ea --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/container_adaptor.h @@ -0,0 +1,70 @@ +// -*- 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___FORMAT_CONTAINER_ADAPTOR_H +#define _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__availability> +#include <__config> +#include <__format/concepts.h> +#include <__format/formatter.h> +#include <__format/range_default_formatter.h> +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +// [container.adaptors.format] only specifies the library should provide the +// formatter specializations, not which header should provide them. +// Since includes a lot of headers, add these headers here instead of +// adding more dependencies like, locale, optinal, string, tuple, etc. to the +// adaptor headers. To use the format functions users already include . + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_container_adaptor { +private: + using __maybe_const_adaptor = __fmt_maybe_const<_Adaptor, _CharT>; + formatter __underlying_; + +public: + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return __underlying_.parse(__ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + format(__maybe_const_adaptor& __adaptor, _FormatContext& __ctx) const { + return __underlying_.format(__adaptor.__get_container(), __ctx); + } +}; + +template _Container> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_container_adaptor, _CharT> {}; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_container_adaptor, _CharT> {}; + +template _Container> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_container_adaptor, _CharT> {}; + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H diff --git a/gnu/llvm/libcxx/include/__format/enable_insertable.h b/gnu/llvm/libcxx/include/__format/enable_insertable.h new file mode 100644 index 00000000000..71b4252930d --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/enable_insertable.h @@ -0,0 +1,35 @@ +// -*- 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___FORMAT_ENABLE_INSERTABLE_H +#define _LIBCPP___FORMAT_ENABLE_INSERTABLE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { + +/// Opt-in to enable \ref __insertable for a \a _Container. +template +inline constexpr bool __enable_insertable = false; + +} // namespace __format + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_ENABLE_INSERTABLE_H diff --git a/gnu/llvm/libcxx/include/__format/escaped_output_table.h b/gnu/llvm/libcxx/include/__format/escaped_output_table.h new file mode 100644 index 00000000000..bd2994bdc66 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/escaped_output_table.h @@ -0,0 +1,1038 @@ +// -*- 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 +// +//===----------------------------------------------------------------------===// + +// WARNING, this entire header is generated by +// utils/generate_escaped_output_table.py +// DO NOT MODIFY! + +// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +// +// See Terms of Use +// for definitions of Unicode Inc.'s Data Files and Software. +// +// NOTICE TO USER: Carefully read the following legal agreement. +// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +// TERMS AND CONDITIONS OF THIS AGREEMENT. +// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +// THE DATA FILES OR SOFTWARE. +// +// COPYRIGHT AND PERMISSION NOTICE +// +// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved. +// Distributed under the Terms of Use in https://www.unicode.org/copyright.html. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of the Unicode data files and any associated documentation +// (the "Data Files") or Unicode software and any associated documentation +// (the "Software") to deal in the Data Files or Software +// without restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, and/or sell copies of +// the Data Files or Software, and to permit persons to whom the Data Files +// or Software are furnished to do so, provided that either +// (a) this copyright and permission notice appear with all copies +// of the Data Files or Software, or +// (b) this copyright and permission notice appear in associated +// Documentation. +// +// THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT OF THIRD PARTY RIGHTS. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THE DATA FILES OR SOFTWARE. +// +// Except as contained in this notice, the name of a copyright holder +// shall not be used in advertising or otherwise to promote the sale, +// use or other dealings in these Data Files or Software without prior +// written authorization of the copyright holder. + +#ifndef _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H +#define _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H + +#include <__algorithm/ranges_upper_bound.h> +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +namespace __escaped_output_table { + +/// The entries of the characters to escape in format's debug string. +/// +/// Contains the entries for [format.string.escaped]/2.2.1.2.1 +/// CE is a Unicode encoding and C corresponds to either a UCS scalar value +/// whose Unicode property General_Category has a value in the groups +/// Separator (Z) or Other (C) or to a UCS scalar value which has the Unicode +/// property Grapheme_Extend=Yes, as described by table 12 of UAX #44 +/// +/// Separator (Z) consists of General_Category +/// - Space_Separator, +/// - Line_Separator, +/// - Paragraph_Separator. +/// +/// Other (C) consists of General_Category +/// - Control, +/// - Format, +/// - Surrogate, +/// - Private_Use, +/// - Unassigned. +/// +/// The data is generated from +/// - https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt +/// - https://www.unicode.org/Public/UCD/latest/ucd/extracted/DerivedGeneralCategory.txt +/// +/// The table is similar to the table +/// __extended_grapheme_custer_property_boundary::__entries +/// which explains the details of these classes. The only difference is this +/// table lacks a property, thus having more bits available for the size. +/// +/// The data has 2 values: +/// - bits [0, 10] The size of the range, allowing 2048 elements. +/// - bits [11, 31] The lower bound code point of the range. The upper bound of +/// the range is lower bound + size. +inline constexpr uint32_t __entries[893] = { + 0x00000020, + 0x0003f821, + 0x00056800, + 0x0018006f, + 0x001bc001, + 0x001c0003, + 0x001c5800, + 0x001c6800, + 0x001d1000, + 0x00241806, + 0x00298000, + 0x002ab801, + 0x002c5801, + 0x002c802d, + 0x002df800, + 0x002e0801, + 0x002e2001, + 0x002e3808, + 0x002f5803, + 0x002fa810, + 0x0030800a, + 0x0030e000, + 0x00325814, + 0x00338000, + 0x0036b007, + 0x0036f805, + 0x00373801, + 0x00375003, + 0x00387001, + 0x00388800, + 0x0039801c, + 0x003d300a, + 0x003d900d, + 0x003f5808, + 0x003fd802, + 0x0040b003, + 0x0040d808, + 0x00412802, + 0x00414806, + 0x0041f800, + 0x0042c804, + 0x0042f800, + 0x00435804, + 0x00447810, + 0x00465038, + 0x0049d000, + 0x0049e000, + 0x004a0807, + 0x004a6800, + 0x004a8806, + 0x004b1001, + 0x004c0800, + 0x004c2000, + 0x004c6801, + 0x004c8801, + 0x004d4800, + 0x004d8800, + 0x004d9802, + 0x004dd002, + 0x004df000, + 0x004e0805, + 0x004e4801, + 0x004e6800, + 0x004e780c, + 0x004ef000, + 0x004f1003, + 0x004ff004, + 0x00502000, + 0x00505803, + 0x00508801, + 0x00514800, + 0x00518800, + 0x0051a000, + 0x0051b800, + 0x0051d003, + 0x00520817, + 0x0052e800, + 0x0052f806, + 0x00538001, + 0x0053a800, + 0x0053b80b, + 0x00542000, + 0x00547000, + 0x00549000, + 0x00554800, + 0x00558800, + 0x0055a000, + 0x0055d002, + 0x00560807, + 0x00565000, + 0x00566802, + 0x0056880e, + 0x00571003, + 0x00579006, + 0x0057d007, + 0x00582000, + 0x00586801, + 0x00588801, + 0x00594800, + 0x00598800, + 0x0059a000, + 0x0059d002, + 0x0059f001, + 0x005a0805, + 0x005a4801, + 0x005a680e, + 0x005af000, + 0x005b1003, + 0x005bc00a, + 0x005c2000, + 0x005c5802, + 0x005c8800, + 0x005cb002, + 0x005cd800, + 0x005ce800, + 0x005d0002, + 0x005d2802, + 0x005d5802, + 0x005dd004, + 0x005e0000, + 0x005e1802, + 0x005e4800, + 0x005e6802, + 0x005e8814, + 0x005fd805, + 0x00602000, + 0x00606800, + 0x00608800, + 0x00614800, + 0x0061d002, + 0x0061f002, + 0x00622812, + 0x0062d801, + 0x0062f001, + 0x00631003, + 0x00638006, + 0x00640800, + 0x00646800, + 0x00648800, + 0x00654800, + 0x0065a000, + 0x0065d002, + 0x0065f800, + 0x00661000, + 0x00662801, + 0x00664800, + 0x00666010, + 0x0066f800, + 0x00671003, + 0x00678000, + 0x0067a00d, + 0x00686800, + 0x00688800, + 0x0069d801, + 0x0069f000, + 0x006a0804, + 0x006a4800, + 0x006a6800, + 0x006a8003, + 0x006ab800, + 0x006b1003, + 0x006c0001, + 0x006c2000, + 0x006cb802, + 0x006d9000, + 0x006de000, + 0x006df001, + 0x006e3808, + 0x006e9005, + 0x006ef806, + 0x006f8001, + 0x006fa80b, + 0x00718800, + 0x0071a00a, + 0x00723807, + 0x0072e024, + 0x00741800, + 0x00742800, + 0x00745800, + 0x00752000, + 0x00753000, + 0x00758800, + 0x0075a008, + 0x0075f001, + 0x00762800, + 0x00763808, + 0x0076d001, + 0x0077001f, + 0x0078c001, + 0x0079a800, + 0x0079b800, + 0x0079c800, + 0x007a4000, + 0x007b6811, + 0x007c0004, + 0x007c3001, + 0x007c6830, + 0x007e3000, + 0x007e6800, + 0x007ed824, + 0x00816803, + 0x00819005, + 0x0081c801, + 0x0081e801, + 0x0082c001, + 0x0082f002, + 0x00838803, + 0x00841000, + 0x00842801, + 0x00846800, + 0x0084e800, + 0x00863000, + 0x00864004, + 0x00867001, + 0x00924800, + 0x00927001, + 0x0092b800, + 0x0092c800, + 0x0092f001, + 0x00944800, + 0x00947001, + 0x00958800, + 0x0095b001, + 0x0095f800, + 0x00960800, + 0x00963001, + 0x0096b800, + 0x00988800, + 0x0098b001, + 0x009ad804, + 0x009be802, + 0x009cd005, + 0x009fb001, + 0x009ff001, + 0x00b40000, + 0x00b4e802, + 0x00b7c806, + 0x00b89002, + 0x00b8b008, + 0x00b99001, + 0x00b9b808, + 0x00ba900d, + 0x00bb6800, + 0x00bb880e, + 0x00bda001, + 0x00bdb806, + 0x00be3000, + 0x00be480a, + 0x00bee802, + 0x00bf5005, + 0x00bfd005, + 0x00c05804, + 0x00c0d005, + 0x00c3c806, + 0x00c42801, + 0x00c54800, + 0x00c55804, + 0x00c7b009, + 0x00c8f803, + 0x00c93801, + 0x00c96003, + 0x00c99000, + 0x00c9c806, + 0x00ca0802, + 0x00cb7001, + 0x00cba80a, + 0x00cd6003, + 0x00ce5005, + 0x00ced802, + 0x00d0b801, + 0x00d0d802, + 0x00d2b000, + 0x00d2c008, + 0x00d31000, + 0x00d32807, + 0x00d3980c, + 0x00d45005, + 0x00d4d005, + 0x00d57055, + 0x00d9a006, + 0x00d9e000, + 0x00da1000, + 0x00da6802, + 0x00db5808, + 0x00dbf802, + 0x00dd1003, + 0x00dd4001, + 0x00dd5802, + 0x00df3000, + 0x00df4001, + 0x00df6800, + 0x00df7802, + 0x00dfa007, + 0x00e16007, + 0x00e1b004, + 0x00e25002, + 0x00e44806, + 0x00e5d801, + 0x00e6400a, + 0x00e6a00c, + 0x00e71006, + 0x00e76800, + 0x00e7a000, + 0x00e7c001, + 0x00e7d804, + 0x00ee003f, + 0x00f8b001, + 0x00f8f001, + 0x00fa3001, + 0x00fa7001, + 0x00fac000, + 0x00fad000, + 0x00fae000, + 0x00faf000, + 0x00fbf001, + 0x00fda800, + 0x00fe2800, + 0x00fea001, + 0x00fee000, + 0x00ff8001, + 0x00ffa800, + 0x00fff810, + 0x01014007, + 0x0102f810, + 0x01039001, + 0x01047800, + 0x0104e802, + 0x0106083e, + 0x010c6003, + 0x01213818, + 0x01225814, + 0x015ba001, + 0x015cb000, + 0x01677802, + 0x0167a004, + 0x01693000, + 0x01694004, + 0x01697001, + 0x016b4006, + 0x016b880e, + 0x016cb808, + 0x016d3800, + 0x016d7800, + 0x016db800, + 0x016df800, + 0x016e3800, + 0x016e7800, + 0x016eb800, + 0x016ef820, + 0x0172f021, + 0x0174d000, + 0x0177a00b, + 0x017eb019, + 0x017fe004, + 0x01815005, + 0x01820000, + 0x0184b803, + 0x01880004, + 0x01898000, + 0x018c7800, + 0x018f200b, + 0x0190f800, + 0x05246802, + 0x05263808, + 0x05316013, + 0x05337803, + 0x0533a009, + 0x0534f001, + 0x05378001, + 0x0537c007, + 0x053e5804, + 0x053e9000, + 0x053ea000, + 0x053ed017, + 0x05401000, + 0x05403000, + 0x05405800, + 0x05412801, + 0x05416003, + 0x0541d005, + 0x0543c007, + 0x05462009, + 0x0546d017, + 0x0547f800, + 0x05493007, + 0x054a380a, + 0x054aa00a, + 0x054be805, + 0x054d9800, + 0x054db003, + 0x054de001, + 0x054e7000, + 0x054ed003, + 0x054f2800, + 0x054ff800, + 0x05514805, + 0x05518801, + 0x0551a80a, + 0x05521800, + 0x05526000, + 0x05527001, + 0x0552d001, + 0x0553e000, + 0x05558000, + 0x05559002, + 0x0555b801, + 0x0555f001, + 0x05560800, + 0x05561817, + 0x05576001, + 0x0557b00a, + 0x05583801, + 0x05587801, + 0x0558b808, + 0x05593800, + 0x05597800, + 0x055b6003, + 0x055f2800, + 0x055f4000, + 0x055f6802, + 0x055fd005, + 0x06bd200b, + 0x06be3803, + 0x06bfe7ff, + 0x06ffe7ff, + 0x073fe7ff, + 0x077fe7ff, + 0x07bfe103, + 0x07d37001, + 0x07d6d025, + 0x07d8380b, + 0x07d8c004, + 0x07d8f000, + 0x07d9b800, + 0x07d9e800, + 0x07d9f800, + 0x07da1000, + 0x07da2800, + 0x07de180f, + 0x07ec8001, + 0x07ee4006, + 0x07ee801f, + 0x07f0000f, + 0x07f0d015, + 0x07f29800, + 0x07f33800, + 0x07f36003, + 0x07f3a800, + 0x07f7e803, + 0x07fcf001, + 0x07fdf802, + 0x07fe4001, + 0x07fe8001, + 0x07fec001, + 0x07fee802, + 0x07ff3800, + 0x07ff780c, + 0x07fff001, + 0x08006000, + 0x08013800, + 0x0801d800, + 0x0801f000, + 0x08027001, + 0x0802f021, + 0x0807d804, + 0x08081803, + 0x0809a002, + 0x080c7800, + 0x080ce802, + 0x080d082e, + 0x080fe882, + 0x0814e802, + 0x0816880f, + 0x0817e003, + 0x08192008, + 0x081a5804, + 0x081bb009, + 0x081cf000, + 0x081e2003, + 0x081eb029, + 0x0824f001, + 0x08255005, + 0x0826a003, + 0x0827e003, + 0x08294007, + 0x082b200a, + 0x082bd800, + 0x082c5800, + 0x082c9800, + 0x082cb000, + 0x082d1000, + 0x082d9000, + 0x082dd000, + 0x082de842, + 0x0839b808, + 0x083ab009, + 0x083b4017, + 0x083c3000, + 0x083d8800, + 0x083dd844, + 0x08403001, + 0x08404800, + 0x0841b000, + 0x0841c802, + 0x0841e801, + 0x0842b000, + 0x0844f807, + 0x0845802f, + 0x08479800, + 0x0847b004, + 0x0848e002, + 0x0849d004, + 0x084a003f, + 0x084dc003, + 0x084e8001, + 0x0850080e, + 0x0850a000, + 0x0850c000, + 0x0851b009, + 0x08524806, + 0x0852c806, + 0x0855001f, + 0x08572805, + 0x0857b808, + 0x0859b002, + 0x085ab001, + 0x085b9804, + 0x085c9006, + 0x085ce80b, + 0x085d804f, + 0x08624836, + 0x0865980c, + 0x08679806, + 0x0869200b, + 0x0869d125, + 0x0873f800, + 0x08755002, + 0x08757001, + 0x0875904d, + 0x08794007, + 0x087a300a, + 0x087ad015, + 0x087c1003, + 0x087c5025, + 0x087e6013, + 0x087fb808, + 0x08800800, + 0x0881c00e, + 0x08827003, + 0x08838000, + 0x08839801, + 0x0883b00b, + 0x08859803, + 0x0885c801, + 0x0885e800, + 0x0886100d, + 0x08874806, + 0x0887d008, + 0x08893804, + 0x08896808, + 0x088a4007, + 0x088b9800, + 0x088bb80a, + 0x088db008, + 0x088e4803, + 0x088e7800, + 0x088f0000, + 0x088fa80a, + 0x08909000, + 0x08917802, + 0x0891a000, + 0x0891b001, + 0x0891f000, + 0x0892083e, + 0x08943800, + 0x08944800, + 0x08947000, + 0x0894f000, + 0x08955005, + 0x0896f800, + 0x0897180c, + 0x0897d007, + 0x08982000, + 0x08986801, + 0x08988801, + 0x08994800, + 0x08998800, + 0x0899a000, + 0x0899d002, + 0x0899f000, + 0x089a0000, + 0x089a2801, + 0x089a4801, + 0x089a7001, + 0x089a880b, + 0x089b209b, + 0x08a1c007, + 0x08a21002, + 0x08a23000, + 0x08a2e000, + 0x08a2f000, + 0x08a3101d, + 0x08a58000, + 0x08a59805, + 0x08a5d000, + 0x08a5e800, + 0x08a5f801, + 0x08a61001, + 0x08a64007, + 0x08a6d0a5, + 0x08ad7800, + 0x08ad9005, + 0x08ade001, + 0x08adf801, + 0x08aee023, + 0x08b19807, + 0x08b1e800, + 0x08b1f801, + 0x08b2280a, + 0x08b2d005, + 0x08b36812, + 0x08b55800, + 0x08b56800, + 0x08b58005, + 0x08b5b800, + 0x08b5d005, + 0x08b65035, + 0x08b8d804, + 0x08b91003, + 0x08b93808, + 0x08ba38b8, + 0x08c17808, + 0x08c1c801, + 0x08c1e063, + 0x08c7980b, + 0x08c83801, + 0x08c85001, + 0x08c8a000, + 0x08c8b800, + 0x08c98000, + 0x08c9b000, + 0x08c9c803, + 0x08c9f000, + 0x08ca1800, + 0x08ca3808, + 0x08cad045, + 0x08cd4001, + 0x08cea007, + 0x08cf0000, + 0x08cf281a, + 0x08d00809, + 0x08d19805, + 0x08d1d803, + 0x08d23808, + 0x08d28805, + 0x08d2c802, + 0x08d4500c, + 0x08d4c001, + 0x08d5180c, + 0x08d7c806, + 0x08d850f5, + 0x08e04800, + 0x08e1800d, + 0x08e1f800, + 0x08e23009, + 0x08e36802, + 0x08e48018, + 0x08e55006, + 0x08e59001, + 0x08e5a84a, + 0x08e83800, + 0x08e85000, + 0x08e98814, + 0x08ea3808, + 0x08ead005, + 0x08eb3000, + 0x08eb4800, + 0x08ec7803, + 0x08eca800, + 0x08ecb800, + 0x08ecc806, + 0x08ed5135, + 0x08f79801, + 0x08f7c808, + 0x08f88800, + 0x08f9b007, + 0x08fa0000, + 0x08fa1000, + 0x08fad055, + 0x08fd880e, + 0x08ff900c, + 0x091cd065, + 0x09237800, + 0x0923a80a, + 0x092a27ff, + 0x096a224b, + 0x097f980c, + 0x09a18010, + 0x09a23fff, + 0x09e23fb8, + 0x0a323fff, + 0x0a723fff, + 0x0ab23fff, + 0x0af23fff, + 0x0b3239b8, + 0x0b51c806, + 0x0b52f800, + 0x0b535003, + 0x0b55f800, + 0x0b565005, + 0x0b577006, + 0x0b57b009, + 0x0b598006, + 0x0b5a3009, + 0x0b5ad000, + 0x0b5b1000, + 0x0b5bc004, + 0x0b5c82af, + 0x0b74d864, + 0x0b7a5804, + 0x0b7c400a, + 0x0b7d003f, + 0x0b7f200b, + 0x0b7f900d, + 0x0c3fc007, + 0x0c66b029, + 0x0c684fff, + 0x0ca84fff, + 0x0ce84fff, + 0x0d284fff, + 0x0d684ae6, + 0x0d7fa000, + 0x0d7fe000, + 0x0d7ff800, + 0x0d89180e, + 0x0d89981c, + 0x0d8a9801, + 0x0d8ab00d, + 0x0d8b4007, + 0x0d97e7ff, + 0x0dd7e103, + 0x0de35804, + 0x0de3e802, + 0x0de44806, + 0x0de4d001, + 0x0de4e801, + 0x0de507ff, + 0x0e2507ff, + 0x0e6502af, + 0x0e7e203b, + 0x0e87b009, + 0x0e893801, + 0x0e8b2800, + 0x0e8b3802, + 0x0e8b7014, + 0x0e8c2806, + 0x0e8d5003, + 0x0e8f5814, + 0x0e921002, + 0x0e923079, + 0x0e96a00b, + 0x0e97a00b, + 0x0e9ab808, + 0x0e9bc886, + 0x0ea2a800, + 0x0ea4e800, + 0x0ea50001, + 0x0ea51801, + 0x0ea53801, + 0x0ea56800, + 0x0ea5d000, + 0x0ea5e000, + 0x0ea62000, + 0x0ea83000, + 0x0ea85801, + 0x0ea8a800, + 0x0ea8e800, + 0x0ea9d000, + 0x0ea9f800, + 0x0eaa2800, + 0x0eaa3802, + 0x0eaa8800, + 0x0eb53001, + 0x0ebe6001, + 0x0ed00036, + 0x0ed1d831, + 0x0ed3a800, + 0x0ed42000, + 0x0ed46473, + 0x0ef8f805, + 0x0ef95904, + 0x0f037091, + 0x0f096809, + 0x0f09f001, + 0x0f0a5003, + 0x0f0a813f, + 0x0f157011, + 0x0f176003, + 0x0f17d004, + 0x0f1801cf, + 0x0f276003, + 0x0f27d2e5, + 0x0f3f3800, + 0x0f3f6000, + 0x0f3f7800, + 0x0f3ff800, + 0x0f462801, + 0x0f46802f, + 0x0f4a2006, + 0x0f4a6003, + 0x0f4ad003, + 0x0f4b0310, + 0x0f65a84b, + 0x0f69f0c1, + 0x0f702000, + 0x0f710000, + 0x0f711800, + 0x0f712801, + 0x0f714000, + 0x0f719800, + 0x0f71c000, + 0x0f71d000, + 0x0f71e005, + 0x0f721803, + 0x0f724000, + 0x0f725000, + 0x0f726000, + 0x0f728000, + 0x0f729800, + 0x0f72a801, + 0x0f72c000, + 0x0f72d000, + 0x0f72e000, + 0x0f72f000, + 0x0f730000, + 0x0f731800, + 0x0f732801, + 0x0f735800, + 0x0f739800, + 0x0f73c000, + 0x0f73e800, + 0x0f73f800, + 0x0f745000, + 0x0f74e004, + 0x0f752000, + 0x0f755000, + 0x0f75e033, + 0x0f77910d, + 0x0f816003, + 0x0f84a00b, + 0x0f857801, + 0x0f860000, + 0x0f868000, + 0x0f87b009, + 0x0f8d7037, + 0x0f90180c, + 0x0f91e003, + 0x0f924806, + 0x0f92900d, + 0x0f933099, + 0x0fb6c003, + 0x0fb76802, + 0x0fb7e802, + 0x0fbbb803, + 0x0fbed005, + 0x0fbf6003, + 0x0fbf880e, + 0x0fc06003, + 0x0fc24007, + 0x0fc2d005, + 0x0fc44007, + 0x0fc57001, + 0x0fc5904d, + 0x0fd2a00b, + 0x0fd37001, + 0x0fd3e802, + 0x0fd44806, + 0x0fd5f000, + 0x0fd63007, + 0x0fd6e003, + 0x0fd74806, + 0x0fd7c806, + 0x0fdc9800, + 0x0fde5824, + 0x0fdfd405, + 0x1537001f, + 0x15b9d005, + 0x15c0f001, + 0x1675100d, + 0x175f0fff, + 0x179f0c1e, + 0x17d0f5e1, + 0x189a5804}; + +/// At the end of the valid Unicode code points space a lot of code points are +/// either reserved or a noncharacter. Adding all these entries to the +/// lookup table would add 446 entries to the table (in Unicode 14). +/// Instead the only the start of the region is stored, every code point in +/// this region needs to be escaped. +inline constexpr uint32_t __unallocated_region_lower_bound = 0x000323b0; + +/// Returns whether the code unit needs to be escaped. +/// +/// \pre The code point is a valid Unicode code point. +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __needs_escape(const char32_t __code_point) noexcept { + // Since __unallocated_region_lower_bound contains the unshifted range do the + // comparison without shifting. + if (__code_point >= __unallocated_region_lower_bound) + return true; + + ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 11) | 0x7ffu) - __entries; + if (__i == 0) + return false; + + --__i; + uint32_t __upper_bound = (__entries[__i] >> 11) + (__entries[__i] & 0x7ffu); + return __code_point <= __upper_bound; +} + +} // namespace __escaped_output_table + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H diff --git a/gnu/llvm/libcxx/include/__format/extended_grapheme_cluster_table.h b/gnu/llvm/libcxx/include/__format/extended_grapheme_cluster_table.h new file mode 100644 index 00000000000..1ffcfeb5496 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/extended_grapheme_cluster_table.h @@ -0,0 +1,1661 @@ +// -*- 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 +// +//===----------------------------------------------------------------------===// + +// WARNING, this entire header is generated by +// utils/generate_extended_grapheme_cluster_table.py +// DO NOT MODIFY! + +// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +// +// See Terms of Use +// for definitions of Unicode Inc.'s Data Files and Software. +// +// NOTICE TO USER: Carefully read the following legal agreement. +// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +// TERMS AND CONDITIONS OF THIS AGREEMENT. +// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +// THE DATA FILES OR SOFTWARE. +// +// COPYRIGHT AND PERMISSION NOTICE +// +// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved. +// Distributed under the Terms of Use in https://www.unicode.org/copyright.html. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of the Unicode data files and any associated documentation +// (the "Data Files") or Unicode software and any associated documentation +// (the "Software") to deal in the Data Files or Software +// without restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, and/or sell copies of +// the Data Files or Software, and to permit persons to whom the Data Files +// or Software are furnished to do so, provided that either +// (a) this copyright and permission notice appear with all copies +// of the Data Files or Software, or +// (b) this copyright and permission notice appear in associated +// Documentation. +// +// THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT OF THIRD PARTY RIGHTS. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THE DATA FILES OR SOFTWARE. +// +// Except as contained in this notice, the name of a copyright holder +// shall not be used in advertising or otherwise to promote the sale, +// use or other dealings in these Data Files or Software without prior +// written authorization of the copyright holder. + +#ifndef _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H +#define _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H + +#include <__algorithm/ranges_upper_bound.h> +#include <__config> +#include <__iterator/access.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __extended_grapheme_custer_property_boundary { + +enum class __property : uint8_t { + // Values generated from the data files. + __CR, + __Control, + __Extend, + __Extended_Pictographic, + __L, + __LF, + __LV, + __LVT, + __Prepend, + __Regional_Indicator, + __SpacingMark, + __T, + __V, + __ZWJ, + + // The properies below aren't stored in the "database". + + // Text position properties. + __sot, + __eot, + + // The code unit has none of above properties. + __none +}; + +/// The entries of the extended grapheme cluster bondary property table. +/// +/// The data is generated from +/// - https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakProperty.txt +/// - https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt +/// +/// The data has 3 values +/// - bits [0, 3] The property. One of the values generated from the datafiles +/// of \ref __property +/// - bits [4, 10] The size of the range. +/// - bits [11, 31] The lower bound code point of the range. The upper bound of +/// the range is lower bound + size. +/// +/// The 7 bits for the size allow a maximum range of 128 elements. Some ranges +/// in the Unicode tables are larger. They are stored in multiple consecutive +/// ranges in the data table. An alternative would be to store the sizes in a +/// separate 16-bit value. The original MSVC STL code had such an approach, but +/// this approach uses less space for the data and is about 4% faster in the +/// following benchmark. +/// libcxx/benchmarks/std_format_spec_string_unicode.bench.cpp +inline constexpr uint32_t __entries[1496] = { + 0x00000091, + 0x00005005, + 0x00005811, + 0x00006800, + 0x00007111, + 0x0003fa01, + 0x00054803, + 0x00056801, + 0x00057003, + 0x001806f2, + 0x00241862, + 0x002c8ac2, + 0x002df802, + 0x002e0812, + 0x002e2012, + 0x002e3802, + 0x00300058, + 0x003080a2, + 0x0030e001, + 0x00325942, + 0x00338002, + 0x0036b062, + 0x0036e808, + 0x0036f852, + 0x00373812, + 0x00375032, + 0x00387808, + 0x00388802, + 0x003981a2, + 0x003d30a2, + 0x003f5882, + 0x003fe802, + 0x0040b032, + 0x0040d882, + 0x00412822, + 0x00414842, + 0x0042c822, + 0x00448018, + 0x0044c072, + 0x00465172, + 0x00471008, + 0x004719f2, + 0x0048180a, + 0x0049d002, + 0x0049d80a, + 0x0049e002, + 0x0049f02a, + 0x004a0872, + 0x004a483a, + 0x004a6802, + 0x004a701a, + 0x004a8862, + 0x004b1012, + 0x004c0802, + 0x004c101a, + 0x004de002, + 0x004df002, + 0x004df81a, + 0x004e0832, + 0x004e381a, + 0x004e581a, + 0x004e6802, + 0x004eb802, + 0x004f1012, + 0x004ff002, + 0x00500812, + 0x0050180a, + 0x0051e002, + 0x0051f02a, + 0x00520812, + 0x00523812, + 0x00525822, + 0x00528802, + 0x00538012, + 0x0053a802, + 0x00540812, + 0x0054180a, + 0x0055e002, + 0x0055f02a, + 0x00560842, + 0x00563812, + 0x0056480a, + 0x0056581a, + 0x00566802, + 0x00571012, + 0x0057d052, + 0x00580802, + 0x0058101a, + 0x0059e002, + 0x0059f012, + 0x005a000a, + 0x005a0832, + 0x005a381a, + 0x005a581a, + 0x005a6802, + 0x005aa822, + 0x005b1012, + 0x005c1002, + 0x005df002, + 0x005df80a, + 0x005e0002, + 0x005e081a, + 0x005e302a, + 0x005e502a, + 0x005e6802, + 0x005eb802, + 0x00600002, + 0x0060082a, + 0x00602002, + 0x0061e002, + 0x0061f022, + 0x0062083a, + 0x00623022, + 0x00625032, + 0x0062a812, + 0x00631012, + 0x00640802, + 0x0064101a, + 0x0065e002, + 0x0065f00a, + 0x0065f802, + 0x0066001a, + 0x00661002, + 0x0066181a, + 0x00663002, + 0x0066381a, + 0x0066501a, + 0x00666012, + 0x0066a812, + 0x00671012, + 0x0067980a, + 0x00680012, + 0x0068101a, + 0x0069d812, + 0x0069f002, + 0x0069f81a, + 0x006a0832, + 0x006a302a, + 0x006a502a, + 0x006a6802, + 0x006a7008, + 0x006ab802, + 0x006b1012, + 0x006c0802, + 0x006c101a, + 0x006e5002, + 0x006e7802, + 0x006e801a, + 0x006e9022, + 0x006eb002, + 0x006ec06a, + 0x006ef802, + 0x006f901a, + 0x00718802, + 0x0071980a, + 0x0071a062, + 0x00723872, + 0x00758802, + 0x0075980a, + 0x0075a082, + 0x00764062, + 0x0078c012, + 0x0079a802, + 0x0079b802, + 0x0079c802, + 0x0079f01a, + 0x007b88d2, + 0x007bf80a, + 0x007c0042, + 0x007c3012, + 0x007c68a2, + 0x007cca32, + 0x007e3002, + 0x00816832, + 0x0081880a, + 0x00819052, + 0x0081c812, + 0x0081d81a, + 0x0081e812, + 0x0082b01a, + 0x0082c012, + 0x0082f022, + 0x00838832, + 0x00841002, + 0x0084200a, + 0x00842812, + 0x00846802, + 0x0084e802, + 0x008805f4, + 0x008b047c, + 0x008d457b, + 0x009ae822, + 0x00b89022, + 0x00b8a80a, + 0x00b99012, + 0x00b9a00a, + 0x00ba9012, + 0x00bb9012, + 0x00bda012, + 0x00bdb00a, + 0x00bdb862, + 0x00bdf07a, + 0x00be3002, + 0x00be381a, + 0x00be48a2, + 0x00bee802, + 0x00c05822, + 0x00c07001, + 0x00c07802, + 0x00c42812, + 0x00c54802, + 0x00c90022, + 0x00c9183a, + 0x00c93812, + 0x00c9482a, + 0x00c9801a, + 0x00c99002, + 0x00c9985a, + 0x00c9c822, + 0x00d0b812, + 0x00d0c81a, + 0x00d0d802, + 0x00d2a80a, + 0x00d2b002, + 0x00d2b80a, + 0x00d2c062, + 0x00d30002, + 0x00d31002, + 0x00d32872, + 0x00d3685a, + 0x00d39892, + 0x00d3f802, + 0x00d581e2, + 0x00d80032, + 0x00d8200a, + 0x00d9a062, + 0x00d9d80a, + 0x00d9e002, + 0x00d9e84a, + 0x00da1002, + 0x00da181a, + 0x00db5882, + 0x00dc0012, + 0x00dc100a, + 0x00dd080a, + 0x00dd1032, + 0x00dd301a, + 0x00dd4012, + 0x00dd500a, + 0x00dd5822, + 0x00df3002, + 0x00df380a, + 0x00df4012, + 0x00df502a, + 0x00df6802, + 0x00df700a, + 0x00df7822, + 0x00df901a, + 0x00e1207a, + 0x00e16072, + 0x00e1a01a, + 0x00e1b012, + 0x00e68022, + 0x00e6a0c2, + 0x00e7080a, + 0x00e71062, + 0x00e76802, + 0x00e7a002, + 0x00e7b80a, + 0x00e7c012, + 0x00ee03f2, + 0x01005801, + 0x01006002, + 0x0100680d, + 0x01007011, + 0x01014061, + 0x0101e003, + 0x01024803, + 0x010300f1, + 0x01068202, + 0x01091003, + 0x0109c803, + 0x010ca053, + 0x010d4813, + 0x0118d013, + 0x01194003, + 0x011c4003, + 0x011e7803, + 0x011f48a3, + 0x011fc023, + 0x01261003, + 0x012d5013, + 0x012db003, + 0x012e0003, + 0x012fd833, + 0x01300053, + 0x013038b3, + 0x0130a713, + 0x01348753, + 0x013840a3, + 0x0138a003, + 0x0138b003, + 0x0138e803, + 0x01390803, + 0x01394003, + 0x01399813, + 0x013a2003, + 0x013a3803, + 0x013a6003, + 0x013a7003, + 0x013a9823, + 0x013ab803, + 0x013b1843, + 0x013ca823, + 0x013d0803, + 0x013d8003, + 0x013df803, + 0x0149a013, + 0x01582823, + 0x0158d813, + 0x015a8003, + 0x015aa803, + 0x01677822, + 0x016bf802, + 0x016f01f2, + 0x01815052, + 0x01818003, + 0x0181e803, + 0x0184c812, + 0x0194b803, + 0x0194c803, + 0x05337832, + 0x0533a092, + 0x0534f012, + 0x05378012, + 0x05401002, + 0x05403002, + 0x05405802, + 0x0541181a, + 0x05412812, + 0x0541380a, + 0x05416002, + 0x0544001a, + 0x0545a0fa, + 0x05462012, + 0x05470112, + 0x0547f802, + 0x05493072, + 0x054a38a2, + 0x054a901a, + 0x054b01c4, + 0x054c0022, + 0x054c180a, + 0x054d9802, + 0x054da01a, + 0x054db032, + 0x054dd01a, + 0x054de012, + 0x054df02a, + 0x054f2802, + 0x05514852, + 0x0551781a, + 0x05518812, + 0x0551981a, + 0x0551a812, + 0x05521802, + 0x05526002, + 0x0552680a, + 0x0553e002, + 0x05558002, + 0x05559022, + 0x0555b812, + 0x0555f012, + 0x05560802, + 0x0557580a, + 0x05576012, + 0x0557701a, + 0x0557a80a, + 0x0557b002, + 0x055f181a, + 0x055f2802, + 0x055f301a, + 0x055f4002, + 0x055f481a, + 0x055f600a, + 0x055f6802, + 0x05600006, + 0x056009a7, + 0x0560e006, + 0x0560e9a7, + 0x0561c006, + 0x0561c9a7, + 0x0562a006, + 0x0562a9a7, + 0x05638006, + 0x056389a7, + 0x05646006, + 0x056469a7, + 0x05654006, + 0x056549a7, + 0x05662006, + 0x056629a7, + 0x05670006, + 0x056709a7, + 0x0567e006, + 0x0567e9a7, + 0x0568c006, + 0x0568c9a7, + 0x0569a006, + 0x0569a9a7, + 0x056a8006, + 0x056a89a7, + 0x056b6006, + 0x056b69a7, + 0x056c4006, + 0x056c49a7, + 0x056d2006, + 0x056d29a7, + 0x056e0006, + 0x056e09a7, + 0x056ee006, + 0x056ee9a7, + 0x056fc006, + 0x056fc9a7, + 0x0570a006, + 0x0570a9a7, + 0x05718006, + 0x057189a7, + 0x05726006, + 0x057269a7, + 0x05734006, + 0x057349a7, + 0x05742006, + 0x057429a7, + 0x05750006, + 0x057509a7, + 0x0575e006, + 0x0575e9a7, + 0x0576c006, + 0x0576c9a7, + 0x0577a006, + 0x0577a9a7, + 0x05788006, + 0x057889a7, + 0x05796006, + 0x057969a7, + 0x057a4006, + 0x057a49a7, + 0x057b2006, + 0x057b29a7, + 0x057c0006, + 0x057c09a7, + 0x057ce006, + 0x057ce9a7, + 0x057dc006, + 0x057dc9a7, + 0x057ea006, + 0x057ea9a7, + 0x057f8006, + 0x057f89a7, + 0x05806006, + 0x058069a7, + 0x05814006, + 0x058149a7, + 0x05822006, + 0x058229a7, + 0x05830006, + 0x058309a7, + 0x0583e006, + 0x0583e9a7, + 0x0584c006, + 0x0584c9a7, + 0x0585a006, + 0x0585a9a7, + 0x05868006, + 0x058689a7, + 0x05876006, + 0x058769a7, + 0x05884006, + 0x058849a7, + 0x05892006, + 0x058929a7, + 0x058a0006, + 0x058a09a7, + 0x058ae006, + 0x058ae9a7, + 0x058bc006, + 0x058bc9a7, + 0x058ca006, + 0x058ca9a7, + 0x058d8006, + 0x058d89a7, + 0x058e6006, + 0x058e69a7, + 0x058f4006, + 0x058f49a7, + 0x05902006, + 0x059029a7, + 0x05910006, + 0x059109a7, + 0x0591e006, + 0x0591e9a7, + 0x0592c006, + 0x0592c9a7, + 0x0593a006, + 0x0593a9a7, + 0x05948006, + 0x059489a7, + 0x05956006, + 0x059569a7, + 0x05964006, + 0x059649a7, + 0x05972006, + 0x059729a7, + 0x05980006, + 0x059809a7, + 0x0598e006, + 0x0598e9a7, + 0x0599c006, + 0x0599c9a7, + 0x059aa006, + 0x059aa9a7, + 0x059b8006, + 0x059b89a7, + 0x059c6006, + 0x059c69a7, + 0x059d4006, + 0x059d49a7, + 0x059e2006, + 0x059e29a7, + 0x059f0006, + 0x059f09a7, + 0x059fe006, + 0x059fe9a7, + 0x05a0c006, + 0x05a0c9a7, + 0x05a1a006, + 0x05a1a9a7, + 0x05a28006, + 0x05a289a7, + 0x05a36006, + 0x05a369a7, + 0x05a44006, + 0x05a449a7, + 0x05a52006, + 0x05a529a7, + 0x05a60006, + 0x05a609a7, + 0x05a6e006, + 0x05a6e9a7, + 0x05a7c006, + 0x05a7c9a7, + 0x05a8a006, + 0x05a8a9a7, + 0x05a98006, + 0x05a989a7, + 0x05aa6006, + 0x05aa69a7, + 0x05ab4006, + 0x05ab49a7, + 0x05ac2006, + 0x05ac29a7, + 0x05ad0006, + 0x05ad09a7, + 0x05ade006, + 0x05ade9a7, + 0x05aec006, + 0x05aec9a7, + 0x05afa006, + 0x05afa9a7, + 0x05b08006, + 0x05b089a7, + 0x05b16006, + 0x05b169a7, + 0x05b24006, + 0x05b249a7, + 0x05b32006, + 0x05b329a7, + 0x05b40006, + 0x05b409a7, + 0x05b4e006, + 0x05b4e9a7, + 0x05b5c006, + 0x05b5c9a7, + 0x05b6a006, + 0x05b6a9a7, + 0x05b78006, + 0x05b789a7, + 0x05b86006, + 0x05b869a7, + 0x05b94006, + 0x05b949a7, + 0x05ba2006, + 0x05ba29a7, + 0x05bb0006, + 0x05bb09a7, + 0x05bbe006, + 0x05bbe9a7, + 0x05bcc006, + 0x05bcc9a7, + 0x05bda006, + 0x05bda9a7, + 0x05be8006, + 0x05be89a7, + 0x05bf6006, + 0x05bf69a7, + 0x05c04006, + 0x05c049a7, + 0x05c12006, + 0x05c129a7, + 0x05c20006, + 0x05c209a7, + 0x05c2e006, + 0x05c2e9a7, + 0x05c3c006, + 0x05c3c9a7, + 0x05c4a006, + 0x05c4a9a7, + 0x05c58006, + 0x05c589a7, + 0x05c66006, + 0x05c669a7, + 0x05c74006, + 0x05c749a7, + 0x05c82006, + 0x05c829a7, + 0x05c90006, + 0x05c909a7, + 0x05c9e006, + 0x05c9e9a7, + 0x05cac006, + 0x05cac9a7, + 0x05cba006, + 0x05cba9a7, + 0x05cc8006, + 0x05cc89a7, + 0x05cd6006, + 0x05cd69a7, + 0x05ce4006, + 0x05ce49a7, + 0x05cf2006, + 0x05cf29a7, + 0x05d00006, + 0x05d009a7, + 0x05d0e006, + 0x05d0e9a7, + 0x05d1c006, + 0x05d1c9a7, + 0x05d2a006, + 0x05d2a9a7, + 0x05d38006, + 0x05d389a7, + 0x05d46006, + 0x05d469a7, + 0x05d54006, + 0x05d549a7, + 0x05d62006, + 0x05d629a7, + 0x05d70006, + 0x05d709a7, + 0x05d7e006, + 0x05d7e9a7, + 0x05d8c006, + 0x05d8c9a7, + 0x05d9a006, + 0x05d9a9a7, + 0x05da8006, + 0x05da89a7, + 0x05db6006, + 0x05db69a7, + 0x05dc4006, + 0x05dc49a7, + 0x05dd2006, + 0x05dd29a7, + 0x05de0006, + 0x05de09a7, + 0x05dee006, + 0x05dee9a7, + 0x05dfc006, + 0x05dfc9a7, + 0x05e0a006, + 0x05e0a9a7, + 0x05e18006, + 0x05e189a7, + 0x05e26006, + 0x05e269a7, + 0x05e34006, + 0x05e349a7, + 0x05e42006, + 0x05e429a7, + 0x05e50006, + 0x05e509a7, + 0x05e5e006, + 0x05e5e9a7, + 0x05e6c006, + 0x05e6c9a7, + 0x05e7a006, + 0x05e7a9a7, + 0x05e88006, + 0x05e889a7, + 0x05e96006, + 0x05e969a7, + 0x05ea4006, + 0x05ea49a7, + 0x05eb2006, + 0x05eb29a7, + 0x05ec0006, + 0x05ec09a7, + 0x05ece006, + 0x05ece9a7, + 0x05edc006, + 0x05edc9a7, + 0x05eea006, + 0x05eea9a7, + 0x05ef8006, + 0x05ef89a7, + 0x05f06006, + 0x05f069a7, + 0x05f14006, + 0x05f149a7, + 0x05f22006, + 0x05f229a7, + 0x05f30006, + 0x05f309a7, + 0x05f3e006, + 0x05f3e9a7, + 0x05f4c006, + 0x05f4c9a7, + 0x05f5a006, + 0x05f5a9a7, + 0x05f68006, + 0x05f689a7, + 0x05f76006, + 0x05f769a7, + 0x05f84006, + 0x05f849a7, + 0x05f92006, + 0x05f929a7, + 0x05fa0006, + 0x05fa09a7, + 0x05fae006, + 0x05fae9a7, + 0x05fbc006, + 0x05fbc9a7, + 0x05fca006, + 0x05fca9a7, + 0x05fd8006, + 0x05fd89a7, + 0x05fe6006, + 0x05fe69a7, + 0x05ff4006, + 0x05ff49a7, + 0x06002006, + 0x060029a7, + 0x06010006, + 0x060109a7, + 0x0601e006, + 0x0601e9a7, + 0x0602c006, + 0x0602c9a7, + 0x0603a006, + 0x0603a9a7, + 0x06048006, + 0x060489a7, + 0x06056006, + 0x060569a7, + 0x06064006, + 0x060649a7, + 0x06072006, + 0x060729a7, + 0x06080006, + 0x060809a7, + 0x0608e006, + 0x0608e9a7, + 0x0609c006, + 0x0609c9a7, + 0x060aa006, + 0x060aa9a7, + 0x060b8006, + 0x060b89a7, + 0x060c6006, + 0x060c69a7, + 0x060d4006, + 0x060d49a7, + 0x060e2006, + 0x060e29a7, + 0x060f0006, + 0x060f09a7, + 0x060fe006, + 0x060fe9a7, + 0x0610c006, + 0x0610c9a7, + 0x0611a006, + 0x0611a9a7, + 0x06128006, + 0x061289a7, + 0x06136006, + 0x061369a7, + 0x06144006, + 0x061449a7, + 0x06152006, + 0x061529a7, + 0x06160006, + 0x061609a7, + 0x0616e006, + 0x0616e9a7, + 0x0617c006, + 0x0617c9a7, + 0x0618a006, + 0x0618a9a7, + 0x06198006, + 0x061989a7, + 0x061a6006, + 0x061a69a7, + 0x061b4006, + 0x061b49a7, + 0x061c2006, + 0x061c29a7, + 0x061d0006, + 0x061d09a7, + 0x061de006, + 0x061de9a7, + 0x061ec006, + 0x061ec9a7, + 0x061fa006, + 0x061fa9a7, + 0x06208006, + 0x062089a7, + 0x06216006, + 0x062169a7, + 0x06224006, + 0x062249a7, + 0x06232006, + 0x062329a7, + 0x06240006, + 0x062409a7, + 0x0624e006, + 0x0624e9a7, + 0x0625c006, + 0x0625c9a7, + 0x0626a006, + 0x0626a9a7, + 0x06278006, + 0x062789a7, + 0x06286006, + 0x062869a7, + 0x06294006, + 0x062949a7, + 0x062a2006, + 0x062a29a7, + 0x062b0006, + 0x062b09a7, + 0x062be006, + 0x062be9a7, + 0x062cc006, + 0x062cc9a7, + 0x062da006, + 0x062da9a7, + 0x062e8006, + 0x062e89a7, + 0x062f6006, + 0x062f69a7, + 0x06304006, + 0x063049a7, + 0x06312006, + 0x063129a7, + 0x06320006, + 0x063209a7, + 0x0632e006, + 0x0632e9a7, + 0x0633c006, + 0x0633c9a7, + 0x0634a006, + 0x0634a9a7, + 0x06358006, + 0x063589a7, + 0x06366006, + 0x063669a7, + 0x06374006, + 0x063749a7, + 0x06382006, + 0x063829a7, + 0x06390006, + 0x063909a7, + 0x0639e006, + 0x0639e9a7, + 0x063ac006, + 0x063ac9a7, + 0x063ba006, + 0x063ba9a7, + 0x063c8006, + 0x063c89a7, + 0x063d6006, + 0x063d69a7, + 0x063e4006, + 0x063e49a7, + 0x063f2006, + 0x063f29a7, + 0x06400006, + 0x064009a7, + 0x0640e006, + 0x0640e9a7, + 0x0641c006, + 0x0641c9a7, + 0x0642a006, + 0x0642a9a7, + 0x06438006, + 0x064389a7, + 0x06446006, + 0x064469a7, + 0x06454006, + 0x064549a7, + 0x06462006, + 0x064629a7, + 0x06470006, + 0x064709a7, + 0x0647e006, + 0x0647e9a7, + 0x0648c006, + 0x0648c9a7, + 0x0649a006, + 0x0649a9a7, + 0x064a8006, + 0x064a89a7, + 0x064b6006, + 0x064b69a7, + 0x064c4006, + 0x064c49a7, + 0x064d2006, + 0x064d29a7, + 0x064e0006, + 0x064e09a7, + 0x064ee006, + 0x064ee9a7, + 0x064fc006, + 0x064fc9a7, + 0x0650a006, + 0x0650a9a7, + 0x06518006, + 0x065189a7, + 0x06526006, + 0x065269a7, + 0x06534006, + 0x065349a7, + 0x06542006, + 0x065429a7, + 0x06550006, + 0x065509a7, + 0x0655e006, + 0x0655e9a7, + 0x0656c006, + 0x0656c9a7, + 0x0657a006, + 0x0657a9a7, + 0x06588006, + 0x065889a7, + 0x06596006, + 0x065969a7, + 0x065a4006, + 0x065a49a7, + 0x065b2006, + 0x065b29a7, + 0x065c0006, + 0x065c09a7, + 0x065ce006, + 0x065ce9a7, + 0x065dc006, + 0x065dc9a7, + 0x065ea006, + 0x065ea9a7, + 0x065f8006, + 0x065f89a7, + 0x06606006, + 0x066069a7, + 0x06614006, + 0x066149a7, + 0x06622006, + 0x066229a7, + 0x06630006, + 0x066309a7, + 0x0663e006, + 0x0663e9a7, + 0x0664c006, + 0x0664c9a7, + 0x0665a006, + 0x0665a9a7, + 0x06668006, + 0x066689a7, + 0x06676006, + 0x066769a7, + 0x06684006, + 0x066849a7, + 0x06692006, + 0x066929a7, + 0x066a0006, + 0x066a09a7, + 0x066ae006, + 0x066ae9a7, + 0x066bc006, + 0x066bc9a7, + 0x066ca006, + 0x066ca9a7, + 0x066d8006, + 0x066d89a7, + 0x066e6006, + 0x066e69a7, + 0x066f4006, + 0x066f49a7, + 0x06702006, + 0x067029a7, + 0x06710006, + 0x067109a7, + 0x0671e006, + 0x0671e9a7, + 0x0672c006, + 0x0672c9a7, + 0x0673a006, + 0x0673a9a7, + 0x06748006, + 0x067489a7, + 0x06756006, + 0x067569a7, + 0x06764006, + 0x067649a7, + 0x06772006, + 0x067729a7, + 0x06780006, + 0x067809a7, + 0x0678e006, + 0x0678e9a7, + 0x0679c006, + 0x0679c9a7, + 0x067aa006, + 0x067aa9a7, + 0x067b8006, + 0x067b89a7, + 0x067c6006, + 0x067c69a7, + 0x067d4006, + 0x067d49a7, + 0x067e2006, + 0x067e29a7, + 0x067f0006, + 0x067f09a7, + 0x067fe006, + 0x067fe9a7, + 0x0680c006, + 0x0680c9a7, + 0x0681a006, + 0x0681a9a7, + 0x06828006, + 0x068289a7, + 0x06836006, + 0x068369a7, + 0x06844006, + 0x068449a7, + 0x06852006, + 0x068529a7, + 0x06860006, + 0x068609a7, + 0x0686e006, + 0x0686e9a7, + 0x0687c006, + 0x0687c9a7, + 0x0688a006, + 0x0688a9a7, + 0x06898006, + 0x068989a7, + 0x068a6006, + 0x068a69a7, + 0x068b4006, + 0x068b49a7, + 0x068c2006, + 0x068c29a7, + 0x068d0006, + 0x068d09a7, + 0x068de006, + 0x068de9a7, + 0x068ec006, + 0x068ec9a7, + 0x068fa006, + 0x068fa9a7, + 0x06908006, + 0x069089a7, + 0x06916006, + 0x069169a7, + 0x06924006, + 0x069249a7, + 0x06932006, + 0x069329a7, + 0x06940006, + 0x069409a7, + 0x0694e006, + 0x0694e9a7, + 0x0695c006, + 0x0695c9a7, + 0x0696a006, + 0x0696a9a7, + 0x06978006, + 0x069789a7, + 0x06986006, + 0x069869a7, + 0x06994006, + 0x069949a7, + 0x069a2006, + 0x069a29a7, + 0x069b0006, + 0x069b09a7, + 0x069be006, + 0x069be9a7, + 0x069cc006, + 0x069cc9a7, + 0x069da006, + 0x069da9a7, + 0x069e8006, + 0x069e89a7, + 0x069f6006, + 0x069f69a7, + 0x06a04006, + 0x06a049a7, + 0x06a12006, + 0x06a129a7, + 0x06a20006, + 0x06a209a7, + 0x06a2e006, + 0x06a2e9a7, + 0x06a3c006, + 0x06a3c9a7, + 0x06a4a006, + 0x06a4a9a7, + 0x06a58006, + 0x06a589a7, + 0x06a66006, + 0x06a669a7, + 0x06a74006, + 0x06a749a7, + 0x06a82006, + 0x06a829a7, + 0x06a90006, + 0x06a909a7, + 0x06a9e006, + 0x06a9e9a7, + 0x06aac006, + 0x06aac9a7, + 0x06aba006, + 0x06aba9a7, + 0x06ac8006, + 0x06ac89a7, + 0x06ad6006, + 0x06ad69a7, + 0x06ae4006, + 0x06ae49a7, + 0x06af2006, + 0x06af29a7, + 0x06b00006, + 0x06b009a7, + 0x06b0e006, + 0x06b0e9a7, + 0x06b1c006, + 0x06b1c9a7, + 0x06b2a006, + 0x06b2a9a7, + 0x06b38006, + 0x06b389a7, + 0x06b46006, + 0x06b469a7, + 0x06b54006, + 0x06b549a7, + 0x06b62006, + 0x06b629a7, + 0x06b70006, + 0x06b709a7, + 0x06b7e006, + 0x06b7e9a7, + 0x06b8c006, + 0x06b8c9a7, + 0x06b9a006, + 0x06b9a9a7, + 0x06ba8006, + 0x06ba89a7, + 0x06bb6006, + 0x06bb69a7, + 0x06bc4006, + 0x06bc49a7, + 0x06bd816c, + 0x06be5b0b, + 0x07d8f002, + 0x07f000f2, + 0x07f100f2, + 0x07f7f801, + 0x07fcf012, + 0x07ff80b1, + 0x080fe802, + 0x08170002, + 0x081bb042, + 0x08500822, + 0x08502812, + 0x08506032, + 0x0851c022, + 0x0851f802, + 0x08572812, + 0x08692032, + 0x08755812, + 0x0877e822, + 0x087a30a2, + 0x087c1032, + 0x0880000a, + 0x08800802, + 0x0880100a, + 0x0881c0e2, + 0x08838002, + 0x08839812, + 0x0883f822, + 0x0884100a, + 0x0885802a, + 0x08859832, + 0x0885b81a, + 0x0885c812, + 0x0885e808, + 0x08861002, + 0x08866808, + 0x08880022, + 0x08893842, + 0x0889600a, + 0x08896872, + 0x088a281a, + 0x088b9802, + 0x088c0012, + 0x088c100a, + 0x088d982a, + 0x088db082, + 0x088df81a, + 0x088e1018, + 0x088e4832, + 0x088e700a, + 0x088e7802, + 0x0891602a, + 0x08917822, + 0x0891901a, + 0x0891a002, + 0x0891a80a, + 0x0891b012, + 0x0891f002, + 0x08920802, + 0x0896f802, + 0x0897002a, + 0x08971872, + 0x08980012, + 0x0898101a, + 0x0899d812, + 0x0899f002, + 0x0899f80a, + 0x089a0002, + 0x089a083a, + 0x089a381a, + 0x089a582a, + 0x089ab802, + 0x089b101a, + 0x089b3062, + 0x089b8042, + 0x08a1a82a, + 0x08a1c072, + 0x08a2001a, + 0x08a21022, + 0x08a2280a, + 0x08a23002, + 0x08a2f002, + 0x08a58002, + 0x08a5881a, + 0x08a59852, + 0x08a5c80a, + 0x08a5d002, + 0x08a5d81a, + 0x08a5e802, + 0x08a5f00a, + 0x08a5f812, + 0x08a6080a, + 0x08a61012, + 0x08ad7802, + 0x08ad801a, + 0x08ad9032, + 0x08adc03a, + 0x08ade012, + 0x08adf00a, + 0x08adf812, + 0x08aee012, + 0x08b1802a, + 0x08b19872, + 0x08b1d81a, + 0x08b1e802, + 0x08b1f00a, + 0x08b1f812, + 0x08b55802, + 0x08b5600a, + 0x08b56802, + 0x08b5701a, + 0x08b58052, + 0x08b5b00a, + 0x08b5b802, + 0x08b8e822, + 0x08b91032, + 0x08b9300a, + 0x08b93842, + 0x08c1602a, + 0x08c17882, + 0x08c1c00a, + 0x08c1c812, + 0x08c98002, + 0x08c9884a, + 0x08c9b81a, + 0x08c9d812, + 0x08c9e80a, + 0x08c9f002, + 0x08c9f808, + 0x08ca000a, + 0x08ca0808, + 0x08ca100a, + 0x08ca1802, + 0x08ce882a, + 0x08cea032, + 0x08ced012, + 0x08cee03a, + 0x08cf0002, + 0x08cf200a, + 0x08d00892, + 0x08d19852, + 0x08d1c80a, + 0x08d1d008, + 0x08d1d832, + 0x08d23802, + 0x08d28852, + 0x08d2b81a, + 0x08d2c822, + 0x08d42058, + 0x08d450c2, + 0x08d4b80a, + 0x08d4c012, + 0x08e1780a, + 0x08e18062, + 0x08e1c052, + 0x08e1f00a, + 0x08e1f802, + 0x08e49152, + 0x08e5480a, + 0x08e55062, + 0x08e5880a, + 0x08e59012, + 0x08e5a00a, + 0x08e5a812, + 0x08e98852, + 0x08e9d002, + 0x08e9e012, + 0x08e9f862, + 0x08ea3008, + 0x08ea3802, + 0x08ec504a, + 0x08ec8012, + 0x08ec981a, + 0x08eca802, + 0x08ecb00a, + 0x08ecb802, + 0x08f79812, + 0x08f7a81a, + 0x08f80012, + 0x08f81008, + 0x08f8180a, + 0x08f9a01a, + 0x08f9b042, + 0x08f9f01a, + 0x08fa0002, + 0x08fa080a, + 0x08fa1002, + 0x09a180f1, + 0x09a20002, + 0x09a238e2, + 0x0b578042, + 0x0b598062, + 0x0b7a7802, + 0x0b7a8b6a, + 0x0b7c7832, + 0x0b7f2002, + 0x0b7f801a, + 0x0de4e812, + 0x0de50031, + 0x0e7802d2, + 0x0e798162, + 0x0e8b2802, + 0x0e8b300a, + 0x0e8b3822, + 0x0e8b680a, + 0x0e8b7042, + 0x0e8b9871, + 0x0e8bd872, + 0x0e8c2862, + 0x0e8d5032, + 0x0e921022, + 0x0ed00362, + 0x0ed1db12, + 0x0ed3a802, + 0x0ed42002, + 0x0ed4d842, + 0x0ed508e2, + 0x0f000062, + 0x0f004102, + 0x0f00d862, + 0x0f011812, + 0x0f013042, + 0x0f047802, + 0x0f098062, + 0x0f157002, + 0x0f176032, + 0x0f276032, + 0x0f468062, + 0x0f4a2062, + 0x0f8007f3, + 0x0f8407f3, + 0x0f886823, + 0x0f897803, + 0x0f8b6053, + 0x0f8bf013, + 0x0f8c7003, + 0x0f8c8893, + 0x0f8d6b83, + 0x0f8f3199, + 0x0f9008e3, + 0x0f90d003, + 0x0f917803, + 0x0f919083, + 0x0f91e033, + 0x0f924ff3, + 0x0f964ff3, + 0x0f9a4ff3, + 0x0f9e4b13, + 0x0f9fd842, + 0x0fa007f3, + 0x0fa407f3, + 0x0fa803d3, + 0x0faa37f3, + 0x0fae37f3, + 0x0fb23093, + 0x0fb407f3, + 0x0fbba0b3, + 0x0fbeaaa3, + 0x0fc06033, + 0x0fc24073, + 0x0fc2d053, + 0x0fc44073, + 0x0fc57513, + 0x0fc862e3, + 0x0fc9e093, + 0x0fca3ff3, + 0x0fce3ff3, + 0x0fd23ff3, + 0x0fd63b83, + 0x0fe007f3, + 0x0fe407f3, + 0x0fe807f3, + 0x0fec07f3, + 0x0ff007f3, + 0x0ff407f3, + 0x0ff807f3, + 0x0ffc07d3, + 0x700001f1, + 0x700105f2, + 0x700407f1, + 0x700807f2, + 0x700c06f2, + 0x700f87f1, + 0x701387f1, + 0x701787f1, + 0x701b87f1, + 0x701f87f1, + 0x702387f1, + 0x702787f1, + 0x702b87f1, + 0x702f87f1, + 0x703387f1, + 0x703787f1, + 0x703b87f1, + 0x703f87f1, + 0x704387f1, + 0x704787f1, + 0x704b87f1, + 0x704f87f1, + 0x705387f1, + 0x705787f1, + 0x705b87f1, + 0x705f87f1, + 0x706387f1, + 0x706787f1, + 0x706b87f1, + 0x706f87f1, + 0x707387f1, + 0x707787f1, + 0x707b87f1, + 0x707f80f1}; + +/// Returns the extended grapheme cluster bondary property of a code point. +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __property __get_property(const char32_t __code_point) noexcept { + // The algorithm searches for the upper bound of the range and, when found, + // steps back one entry. This algorithm is used since the code point can be + // anywhere in the range. After a lower bound is found the next step is to + // compare whether the code unit is indeed in the range. + // + // Since the entry contains a code unit, size, and property the code point + // being sought needs to be adjusted. Just shifting the code point to the + // proper position doesn't work; suppose an entry has property 0, size 1, + // and lower bound 3. This results in the entry 0x1810. + // When searching for code point 3 it will search for 0x1800, find 0x1810 + // and moves to the previous entry. Thus the lower bound value will never + // be found. + // The simple solution is to set the bits belonging to the property and + // size. Then the upper bound for code point 3 will return the entry after + // 0x1810. After moving to the previous entry the algorithm arrives at the + // correct entry. + ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 11) | 0x7ffu) - __entries; + if (__i == 0) + return __property::__none; + + --__i; + uint32_t __upper_bound = (__entries[__i] >> 11) + ((__entries[__i] >> 4) & 0x7f); + if (__code_point <= __upper_bound) + return static_cast<__property>(__entries[__i] & 0xf); + + return __property::__none; +} + +} // namespace __extended_grapheme_custer_property_boundary + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H diff --git a/gnu/llvm/libcxx/include/__format/format_arg.h b/gnu/llvm/libcxx/include/__format/format_arg.h new file mode 100644 index 00000000000..771a03ff2fa --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/format_arg.h @@ -0,0 +1,302 @@ +// -*- 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___FORMAT_FORMAT_ARG_H +#define _LIBCPP___FORMAT_FORMAT_ARG_H + +#include <__assert> +#include <__concepts/arithmetic.h> +#include <__config> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/format_parse_context.h> +#include <__functional/invoke.h> +#include <__memory/addressof.h> +#include <__utility/forward.h> +#include <__utility/unreachable.h> +#include <__variant/monostate.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { +/// The type stored in @ref basic_format_arg. +/// +/// @note The 128-bit types are unconditionally in the list to avoid the values +/// of the enums to depend on the availability of 128-bit integers. +/// +/// @note The value is stored as a 5-bit value in the __packed_arg_t_bits. This +/// limits the maximum number of elements to 32. +/// When modifying update the test +/// test/libcxx/utilities/format/format.arguments/format.arg/arg_t.compile.pass.cpp +/// It could be packed in 4-bits but that means a new type directly becomes an +/// ABI break. The packed type is 64-bit so this reduces the maximum number of +/// packed elements from 16 to 12. +/// +/// @note Some members of this enum are an extension. These extensions need +/// special behaviour in visit_format_arg. There they need to be wrapped in a +/// handle to satisfy the user observable behaviour. The internal function +/// __visit_format_arg doesn't do this wrapping. So in the format functions +/// this function is used to avoid unneeded overhead. +enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t { + __none, + __boolean, + __char_type, + __int, + __long_long, + __i128, // extension + __unsigned, + __unsigned_long_long, + __u128, // extension + __float, + __double, + __long_double, + __const_char_type_ptr, + __string_view, + __ptr, + __handle +}; + +inline constexpr unsigned __packed_arg_t_bits = 5; +inline constexpr uint8_t __packed_arg_t_mask = 0x1f; + +inline constexpr unsigned __packed_types_storage_bits = 64; +inline constexpr unsigned __packed_types_max = __packed_types_storage_bits / __packed_arg_t_bits; + +_LIBCPP_HIDE_FROM_ABI +constexpr bool __use_packed_format_arg_store(size_t __size) { return __size <= __packed_types_max; } + +_LIBCPP_HIDE_FROM_ABI +constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { + _LIBCPP_ASSERT(__id <= __packed_types_max, ""); + + if (__id > 0) + __types >>= __id * __packed_arg_t_bits; + + return static_cast<__format::__arg_t>(__types & __packed_arg_t_mask); +} + +} // namespace __format + +// This function is not user obervable, so it can directly use the non-standard +// types of the "variant". See __arg_t for more details. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto) +__visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { + switch (__arg.__type_) { + case __format::__arg_t::__none: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__monostate_); + case __format::__arg_t::__boolean: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__boolean_); + case __format::__arg_t::__char_type: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__char_type_); + case __format::__arg_t::__int: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__int_); + case __format::__arg_t::__long_long: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_long_); + case __format::__arg_t::__i128: +# ifndef _LIBCPP_HAS_NO_INT128 + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__i128_); +# else + __libcpp_unreachable(); +# endif + case __format::__arg_t::__unsigned: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_); + case __format::__arg_t::__unsigned_long_long: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_); + case __format::__arg_t::__u128: +# ifndef _LIBCPP_HAS_NO_INT128 + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__u128_); +# else + __libcpp_unreachable(); +# endif + case __format::__arg_t::__float: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__float_); + case __format::__arg_t::__double: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__double_); + case __format::__arg_t::__long_double: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_double_); + case __format::__arg_t::__const_char_type_ptr: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__const_char_type_ptr_); + case __format::__arg_t::__string_view: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__string_view_); + case __format::__arg_t::__ptr: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__ptr_); + case __format::__arg_t::__handle: + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), + typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_}); + } + + __libcpp_unreachable(); +} + +/// Contains the values used in basic_format_arg. +/// +/// This is a separate type so it's possible to store the values and types in +/// separate arrays. +template +class __basic_format_arg_value { + using _CharT = typename _Context::char_type; + +public: + /// Contains the implementation for basic_format_arg::handle. + struct __handle { + template + _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp&& __v) noexcept + : __ptr_(_VSTD::addressof(__v)), + __format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) { + using _Dp = remove_cvref_t<_Tp>; + using _Formatter = typename _Context::template formatter_type<_Dp>; + constexpr bool __const_formattable = + requires { _Formatter().format(std::declval(), std::declval<_Context&>()); }; + using _Qp = conditional_t<__const_formattable, const _Dp, _Dp>; + + static_assert(__const_formattable || !is_const_v>, "Mandated by [format.arg]/18"); + + _Formatter __f; + __parse_ctx.advance_to(__f.parse(__parse_ctx)); + __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast(__ptr)), __ctx)); + }) {} + + const void* __ptr_; + void (*__format_)(basic_format_parse_context<_CharT>&, _Context&, const void*); + }; + + union { + monostate __monostate_; + bool __boolean_; + _CharT __char_type_; + int __int_; + unsigned __unsigned_; + long long __long_long_; + unsigned long long __unsigned_long_long_; +# ifndef _LIBCPP_HAS_NO_INT128 + __int128_t __i128_; + __uint128_t __u128_; +# endif + float __float_; + double __double_; + long double __long_double_; + const _CharT* __const_char_type_ptr_; + basic_string_view<_CharT> __string_view_; + const void* __ptr_; + __handle __handle_; + }; + + // These constructors contain the exact storage type used. If adjustments are + // required, these will be done in __create_format_arg. + + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value() noexcept : __monostate_() {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(bool __value) noexcept : __boolean_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(_CharT __value) noexcept : __char_type_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(int __value) noexcept : __int_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned __value) noexcept : __unsigned_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long long __value) noexcept : __long_long_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned long long __value) noexcept + : __unsigned_long_long_(__value) {} +# ifndef _LIBCPP_HAS_NO_INT128 + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__int128_t __value) noexcept : __i128_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__uint128_t __value) noexcept : __u128_(__value) {} +# endif + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(float __value) noexcept : __float_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(double __value) noexcept : __double_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long double __value) noexcept : __long_double_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const _CharT* __value) noexcept : __const_char_type_ptr_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept + : __string_view_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept + // TODO FMT Investigate why it doesn't work without the forward. + : __handle_(std::forward<__handle>(__value)) {} +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg { +public: + class _LIBCPP_TEMPLATE_VIS handle; + + _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept + : __type_{__format::__arg_t::__none} {} + + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { + return __type_ != __format::__arg_t::__none; + } + +private: + using char_type = typename _Context::char_type; + + // TODO FMT Implement constrain [format.arg]/4 + // Constraints: The template specialization + // typename Context::template formatter_type + // meets the Formatter requirements ([formatter.requirements]). The extent + // to which an implementation determines that the specialization meets the + // Formatter requirements is unspecified, except that as a minimum the + // expression + // typename Context::template formatter_type() + // .format(declval(), declval()) + // shall be well-formed when treated as an unevaluated operand. + +public: + __basic_format_arg_value<_Context> __value_; + __format::__arg_t __type_; + + _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(__format::__arg_t __type, + __basic_format_arg_value<_Context> __value) noexcept + : __value_(__value), __type_(__type) {} +}; + +template +class _LIBCPP_TEMPLATE_VIS basic_format_arg<_Context>::handle { +public: + _LIBCPP_HIDE_FROM_ABI + void format(basic_format_parse_context& __parse_ctx, _Context& __ctx) const { + __handle_.__format_(__parse_ctx, __ctx, __handle_.__ptr_); + } + + _LIBCPP_HIDE_FROM_ABI explicit handle(typename __basic_format_arg_value<_Context>::__handle& __handle) noexcept + : __handle_(__handle) {} + +private: + typename __basic_format_arg_value<_Context>::__handle& __handle_; +}; + +// This function is user facing, so it must wrap the non-standard types of +// the "variant" in a handle to stay conforming. See __arg_t for more details. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto) +visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { + switch (__arg.__type_) { +# ifndef _LIBCPP_HAS_NO_INT128 + case __format::__arg_t::__i128: { + typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_}; + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + } + + case __format::__arg_t::__u128: { + typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_}; + return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + } +# endif + default: + return _VSTD::__visit_format_arg(_VSTD::forward<_Visitor>(__vis), __arg); + } +} + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_ARG_H diff --git a/gnu/llvm/libcxx/include/__format/format_arg_store.h b/gnu/llvm/libcxx/include/__format/format_arg_store.h new file mode 100644 index 00000000000..6f4f4c3617a --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/format_arg_store.h @@ -0,0 +1,254 @@ +// -*- 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___FORMAT_FORMAT_ARG_STORE_H +#define _LIBCPP___FORMAT_FORMAT_ARG_STORE_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_arg.h> +#include <__utility/forward.h> +#include +#include +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { + +/// \returns The @c __arg_t based on the type of the formatting argument. +/// +/// \pre \c __formattable<_Tp, typename _Context::char_type> +template +consteval __arg_t __determine_arg_t(); + +// Boolean +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__boolean; +} + +// Char +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__char_type; +} +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template + requires(same_as && same_as<_CharT, char>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__char_type; +} +# endif + +// Signed integers +template +consteval __arg_t __determine_arg_t() { + if constexpr (sizeof(_Tp) <= sizeof(int)) + return __arg_t::__int; + else if constexpr (sizeof(_Tp) <= sizeof(long long)) + return __arg_t::__long_long; +# ifndef _LIBCPP_HAS_NO_INT128 + else if constexpr (sizeof(_Tp) == sizeof(__int128_t)) + return __arg_t::__i128; +# endif + else + static_assert(sizeof(_Tp) == 0, "an unsupported signed integer was used"); +} + +// Unsigned integers +template +consteval __arg_t __determine_arg_t() { + if constexpr (sizeof(_Tp) <= sizeof(unsigned)) + return __arg_t::__unsigned; + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long)) + return __arg_t::__unsigned_long_long; +# ifndef _LIBCPP_HAS_NO_INT128 + else if constexpr (sizeof(_Tp) == sizeof(__uint128_t)) + return __arg_t::__u128; +# endif + else + static_assert(sizeof(_Tp) == 0, "an unsupported unsigned integer was used"); +} + +// Floating-point +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__float; +} +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__double; +} +template _Tp> +consteval __arg_t __determine_arg_t() { + return __arg_t::__long_double; +} + +// Char pointer +template + requires(same_as || same_as) +consteval __arg_t __determine_arg_t() { + return __arg_t::__const_char_type_ptr; +} + +// Char array +template + requires(is_array_v<_Tp> && same_as<_Tp, typename _Context::char_type[extent_v<_Tp>]>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__string_view; +} + +// String view +template + requires(same_as && + same_as<_Tp, basic_string_view>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__string_view; +} + +// String +template + requires( + same_as && + same_as<_Tp, basic_string>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__string_view; +} + +// Pointers +template + requires(same_as<_Ptr, void*> || same_as<_Ptr, const void*> || same_as<_Ptr, nullptr_t>) +consteval __arg_t __determine_arg_t() { + return __arg_t::__ptr; +} + +// Handle +// +// Note this version can't be constrained avoiding ambiguous overloads. +// That means it can be instantiated by disabled formatters. To solve this, a +// constrained version for not formattable formatters is added. That overload +// is marked as deleted to fail creating a storage type for disabled formatters. +template +consteval __arg_t __determine_arg_t() { + return __arg_t::__handle; +} + +template + requires(!__formattable<_Tp, typename _Context::char_type>) +consteval __arg_t __determine_arg_t() = delete; + +template +_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __value) noexcept { + constexpr __arg_t __arg = __determine_arg_t<_Context, remove_cvref_t<_Tp>>(); + static_assert(__arg != __arg_t::__none); + + // Not all types can be used to directly initialize the + // __basic_format_arg_value. First handle all types needing adjustment, the + // final else requires no adjustment. + if constexpr (__arg == __arg_t::__char_type) + // On some platforms initializing a wchar_t from a char is a narrowing + // conversion. + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__int) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__long_long) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__unsigned) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__unsigned_long_long) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__string_view) + // Using std::size on a character array will add the NUL-terminator to the size. + if constexpr (is_array_v>) + return basic_format_arg<_Context>{ + __arg, basic_string_view{__value, extent_v> - 1}}; + else + // When the _Traits or _Allocator are different an implicit conversion will + // fail. + return basic_format_arg<_Context>{ + __arg, basic_string_view{__value.data(), __value.size()}}; + else if constexpr (__arg == __arg_t::__ptr) + return basic_format_arg<_Context>{__arg, static_cast(__value)}; + else if constexpr (__arg == __arg_t::__handle) + return basic_format_arg<_Context>{ + __arg, typename __basic_format_arg_value<_Context>::__handle{_VSTD::forward<_Tp>(__value)}}; + else + return basic_format_arg<_Context>{__arg, __value}; +} + +template +_LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_format_arg_value<_Context>* __values, + _Args&&... __args) noexcept { + int __shift = 0; + ( + [&] { + basic_format_arg<_Context> __arg = __format::__create_format_arg<_Context>(__args); + if (__shift != 0) + __types |= static_cast(__arg.__type_) << __shift; + else + // Assigns the initial value. + __types = static_cast(__arg.__type_); + __shift += __packed_arg_t_bits; + *__values++ = __arg.__value_; + }(), + ...); +} + +template +_LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* __data, _Args&&... __args) noexcept { + ([&] { *__data++ = __format::__create_format_arg<_Context>(__args); }(), ...); +} + +template +struct __packed_format_arg_store { + __basic_format_arg_value<_Context> __values_[N]; + uint64_t __types_; +}; + +template +struct __unpacked_format_arg_store { + basic_format_arg<_Context> __args_[N]; +}; + +} // namespace __format + +template +struct _LIBCPP_TEMPLATE_VIS __format_arg_store { + _LIBCPP_HIDE_FROM_ABI + __format_arg_store(_Args&... __args) noexcept { + if constexpr (sizeof...(_Args) != 0) { + if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args))) + __format::__create_packed_storage(__storage.__types_, __storage.__values_, __args...); + else + __format::__store_basic_format_arg<_Context>(__storage.__args_, __args...); + } + } + + using _Storage = conditional_t<__format::__use_packed_format_arg_store(sizeof...(_Args)), + __format::__packed_format_arg_store<_Context, sizeof...(_Args)>, + __format::__unpacked_format_arg_store<_Context, sizeof...(_Args)>>; + + _Storage __storage; +}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_ARG_STORE_H diff --git a/gnu/llvm/libcxx/include/__format/format_args.h b/gnu/llvm/libcxx/include/__format/format_args.h new file mode 100644 index 00000000000..8b8fbde92fe --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/format_args.h @@ -0,0 +1,80 @@ +// -*- 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___FORMAT_FORMAT_ARGS_H +#define _LIBCPP___FORMAT_FORMAT_ARGS_H + +#include <__availability> +#include <__config> +#include <__format/format_arg.h> +#include <__format/format_arg_store.h> +#include <__format/format_fwd.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_args { +public: + _LIBCPP_HIDE_FROM_ABI basic_format_args() noexcept = default; + + template + _LIBCPP_HIDE_FROM_ABI basic_format_args(const __format_arg_store<_Context, _Args...>& __store) noexcept + : __size_(sizeof...(_Args)) { + if constexpr (sizeof...(_Args) != 0) { + if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args))) { + __values_ = __store.__storage.__values_; + __types_ = __store.__storage.__types_; + } else + __args_ = __store.__storage.__args_; + } + } + + _LIBCPP_HIDE_FROM_ABI + basic_format_arg<_Context> get(size_t __id) const noexcept { + if (__id >= __size_) + return basic_format_arg<_Context>{}; + + if (__format::__use_packed_format_arg_store(__size_)) + return basic_format_arg<_Context>{__format::__get_packed_type(__types_, __id), __values_[__id]}; + + return __args_[__id]; + } + + _LIBCPP_HIDE_FROM_ABI size_t __size() const noexcept { return __size_; } + +private: + size_t __size_{0}; + // [format.args]/5 + // [Note 1: Implementations are encouraged to optimize the representation of + // basic_format_args for small number of formatting arguments by storing + // indices of type alternatives separately from values and packing the + // former. - end note] + union { + struct { + const __basic_format_arg_value<_Context>* __values_; + uint64_t __types_; + }; + const basic_format_arg<_Context>* __args_; + }; +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_args); + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_ARGS_H diff --git a/gnu/llvm/libcxx/include/__format/format_context.h b/gnu/llvm/libcxx/include/__format/format_context.h new file mode 100644 index 00000000000..85e00eb222c --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/format_context.h @@ -0,0 +1,223 @@ +// -*- 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___FORMAT_FORMAT_CONTEXT_H +#define _LIBCPP___FORMAT_FORMAT_CONTEXT_H + +#include <__availability> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/buffer.h> +#include <__format/format_arg.h> +#include <__format/format_arg_store.h> +#include <__format/format_args.h> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/concepts.h> +#include <__memory/addressof.h> +#include <__utility/move.h> +#include <__variant/monostate.h> +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +#include +#include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +requires output_iterator<_OutIt, const _CharT&> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context; + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +/** + * Helper to create a basic_format_context. + * + * This is needed since the constructor is private. + */ +template +_LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> +__format_context_create( + _OutIt __out_it, + basic_format_args> __args, + optional<_VSTD::locale>&& __loc = nullopt) { + return _VSTD::basic_format_context(_VSTD::move(__out_it), __args, _VSTD::move(__loc)); +} +#else +template +_LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> +__format_context_create( + _OutIt __out_it, + basic_format_args> __args) { + return _VSTD::basic_format_context(_VSTD::move(__out_it), __args); +} +#endif + +using format_context = + basic_format_context>, + char>; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_context = basic_format_context< + back_insert_iterator<__format::__output_buffer>, wchar_t>; +#endif + +template +requires output_iterator<_OutIt, const _CharT&> +class + // clang-format off + _LIBCPP_TEMPLATE_VIS + _LIBCPP_AVAILABILITY_FORMAT + _LIBCPP_PREFERRED_NAME(format_context) + _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context)) + // clang-format on + basic_format_context { +public: + using iterator = _OutIt; + using char_type = _CharT; + template + using formatter_type = formatter<_Tp, _CharT>; + + _LIBCPP_HIDE_FROM_ABI basic_format_arg + arg(size_t __id) const noexcept { + return __args_.get(__id); + } +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { + if (!__loc_) + __loc_ = _VSTD::locale{}; + return *__loc_; + } +#endif + _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); } + _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); } + +private: + iterator __out_it_; + basic_format_args __args_; +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + + // The Standard doesn't specify how the locale is stored. + // [format.context]/6 + // std::locale locale(); + // Returns: The locale passed to the formatting function if the latter + // takes one, and std::locale() otherwise. + // This is done by storing the locale of the constructor in this optional. If + // locale() is called and the optional has no value the value will be created. + // This allows the implementation to lazily create the locale. + // TODO FMT Validate whether lazy creation is the best solution. + optional<_VSTD::locale> __loc_; + + template + friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> + __format_context_create(__OutIt, basic_format_args>, + optional<_VSTD::locale>&&); + + // Note: the Standard doesn't specify the required constructors. + _LIBCPP_HIDE_FROM_ABI + explicit basic_format_context(_OutIt __out_it, + basic_format_args __args, + optional<_VSTD::locale>&& __loc) + : __out_it_(_VSTD::move(__out_it)), __args_(__args), + __loc_(_VSTD::move(__loc)) {} +#else + template + friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> + __format_context_create(__OutIt, basic_format_args>); + + _LIBCPP_HIDE_FROM_ABI + explicit basic_format_context(_OutIt __out_it, + basic_format_args __args) + : __out_it_(_VSTD::move(__out_it)), __args_(__args) {} +#endif +}; + +// A specialization for __retarget_buffer +// +// See __retarget_buffer for the motivation for this specialization. +// +// This context holds a reference to the instance of the basic_format_context +// that is retargeted. It converts a formatting argument when it is requested +// during formatting. It is expected that the usage of the arguments is rare so +// the lookups are not expected to be used often. An alternative would be to +// convert all elements during construction. +// +// The elements of the retargets context are only used when an underlying +// formatter uses a locale specific formatting or an formatting argument is +// part for the format spec. For example +// format("{:256:{}}", input, 8); +// Here the width of an element in input is determined dynamically. +// Note when the top-level element has no width the retargeting is not needed. +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + basic_format_context::__iterator, _CharT> { +public: + using iterator = typename __format::__retarget_buffer<_CharT>::__iterator; + using char_type = _CharT; + template + using formatter_type = formatter<_Tp, _CharT>; + + template + _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(iterator __out_it, _Context& __ctx) + : __out_it_(std::move(__out_it)), +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + __loc_([](void* __c) { return static_cast<_Context*>(__c)->locale(); }), +# endif + __ctx_(std::addressof(__ctx)), + __arg_([](void* __c, size_t __id) { + return std::visit_format_arg( + [&](auto __arg) -> basic_format_arg { + if constexpr (same_as) + return {}; + else if constexpr (same_as::handle>) + // At the moment it's not possible for formatting to use a re-targeted handle. + // TODO FMT add this when support is needed. + std::__throw_format_error("Re-targeting handle not supported"); + else + return basic_format_arg{ + __format::__determine_arg_t(), + __basic_format_arg_value(__arg)}; + }, + static_cast<_Context*>(__c)->arg(__id)); + }) { + } + + _LIBCPP_HIDE_FROM_ABI basic_format_arg arg(size_t __id) const noexcept { + return __arg_(__ctx_, __id); + } +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { return __loc_(__ctx_); } +# endif + _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); } + _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); } + +private: + iterator __out_it_; + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + std::locale (*__loc_)(void* __ctx); +# endif + + void* __ctx_; + basic_format_arg (*__arg_)(void* __ctx, size_t __id); +}; + +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context); +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_CONTEXT_H diff --git a/gnu/llvm/libcxx/include/__format/format_error.h b/gnu/llvm/libcxx/include/__format/format_error.h index f983d0ce4ac..002d1a40a22 100644 --- a/gnu/llvm/libcxx/include/__format/format_error.h +++ b/gnu/llvm/libcxx/include/__format/format_error.h @@ -11,19 +11,13 @@ #define _LIBCPP___FORMAT_FORMAT_ERROR_H #include <__config> -#include - -#ifdef _LIBCPP_NO_EXCEPTIONS #include -#endif +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 17 @@ -34,7 +28,14 @@ public: : runtime_error(__s) {} _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s) : runtime_error(__s) {} - virtual ~format_error() noexcept; + // TODO FMT Remove when format is no longer experimental. + // Avoids linker errors when building the Clang-cl Windows DLL which doesn't + // support the experimental library. +# ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR + ~format_error() noexcept override; +# else + ~format_error() noexcept override {} +# endif }; _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void @@ -51,6 +52,4 @@ __throw_format_error(const char* __s) { _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___FORMAT_FORMAT_ERROR_H diff --git a/gnu/llvm/libcxx/include/__format/format_functions.h b/gnu/llvm/libcxx/include/__format/format_functions.h new file mode 100644 index 00000000000..0f0001272d4 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/format_functions.h @@ -0,0 +1,663 @@ +// -*- 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___FORMAT_FORMAT_FUNCTIONS +#define _LIBCPP___FORMAT_FORMAT_FUNCTIONS + +// TODO FMT This is added to fix Apple back-deployment. +#include +#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +#include <__algorithm/clamp.h> +#include <__availability> +#include <__concepts/convertible_to.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__debug> +#include <__format/buffer.h> +#include <__format/format_arg.h> +#include <__format/format_arg_store.h> +#include <__format/format_args.h> +#include <__format/format_context.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/format_string.h> +#include <__format/format_to_n_result.h> +#include <__format/formatter.h> +#include <__format/formatter_bool.h> +#include <__format/formatter_char.h> +#include <__format/formatter_floating_point.h> +#include <__format/formatter_integer.h> +#include <__format/formatter_pointer.h> +#include <__format/formatter_string.h> +#include <__format/parser_std_format_spec.h> +#include <__iterator/back_insert_iterator.h> +#include <__iterator/incrementable_traits.h> +#include <__variant/monostate.h> +#include +#include +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +#include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// TODO FMT Evaluate which templates should be external templates. This +// improves the efficiency of the header. However since the header is still +// under heavy development and not all classes are stable it makes no sense +// to do this optimization now. + +using format_args = basic_format_args; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_args = basic_format_args; +#endif + +template +_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) { + return _VSTD::__format_arg_store<_Context, _Args...>(__args...); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_HIDE_FROM_ABI __format_arg_store make_wformat_args(_Args&&... __args) { + return _VSTD::__format_arg_store(__args...); +} +#endif + +namespace __format { + +/// Helper class parse and handle argument. +/// +/// When parsing a handle which is not enabled the code is ill-formed. +/// This helper uses the parser of the appropriate formatter for the stored type. +template +class _LIBCPP_TEMPLATE_VIS __compile_time_handle { +public: + _LIBCPP_HIDE_FROM_ABI + constexpr void __parse(basic_format_parse_context<_CharT>& __parse_ctx) const { __parse_(__parse_ctx); } + + template + _LIBCPP_HIDE_FROM_ABI constexpr void __enable() { + __parse_ = [](basic_format_parse_context<_CharT>& __parse_ctx) { + formatter<_Tp, _CharT> __f; + __parse_ctx.advance_to(__f.parse(__parse_ctx)); + }; + } + + // Before calling __parse the proper handler needs to be set with __enable. + // The default handler isn't a core constant expression. + _LIBCPP_HIDE_FROM_ABI constexpr __compile_time_handle() + : __parse_([](basic_format_parse_context<_CharT>&) { std::__throw_format_error("Not a handle"); }) {} + +private: + void (*__parse_)(basic_format_parse_context<_CharT>&); +}; + +// Dummy format_context only providing the parts used during constant +// validation of the basic_format_string. +template +struct _LIBCPP_TEMPLATE_VIS __compile_time_basic_format_context { +public: + using char_type = _CharT; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __compile_time_basic_format_context( + const __arg_t* __args, const __compile_time_handle<_CharT>* __handles, size_t __size) + : __args_(__args), __handles_(__handles), __size_(__size) {} + + // During the compile-time validation nothing needs to be written. + // Therefore all operations of this iterator are a NOP. + struct iterator { + _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator=(_CharT) { return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr iterator operator++(int) { return *this; } + }; + + _LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const { + if (__id >= __size_) + std::__throw_format_error("Argument index out of bounds"); + return __args_[__id]; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const { + if (__id >= __size_) + std::__throw_format_error("Argument index out of bounds"); + return __handles_[__id]; + } + + _LIBCPP_HIDE_FROM_ABI constexpr iterator out() { return {}; } + _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(iterator) {} + +private: + const __arg_t* __args_; + const __compile_time_handle<_CharT>* __handles_; + size_t __size_; +}; + +_LIBCPP_HIDE_FROM_ABI +constexpr void __compile_time_validate_integral(__arg_t __type) { + switch (__type) { + case __arg_t::__int: + case __arg_t::__long_long: + case __arg_t::__i128: + case __arg_t::__unsigned: + case __arg_t::__unsigned_long_long: + case __arg_t::__u128: + return; + + default: + std::__throw_format_error("Argument isn't an integral type"); + } +} + +// _HasPrecision does the formatter have a precision? +template +_LIBCPP_HIDE_FROM_ABI constexpr void +__compile_time_validate_argument(basic_format_parse_context<_CharT>& __parse_ctx, + __compile_time_basic_format_context<_CharT>& __ctx) { + formatter<_Tp, _CharT> __formatter; + __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); + // [format.string.std]/7 + // ... If the corresponding formatting argument is not of integral type, or + // its value is negative for precision or non-positive for width, an + // exception of type format_error is thrown. + // + // Validate whether the arguments are integrals. + if (__formatter.__parser_.__width_as_arg_) + __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__width_)); + + if constexpr (_HasPrecision) + if (__formatter.__parser_.__precision_as_arg_) + __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__precision_)); +} + +// This function is not user facing, so it can directly use the non-standard types of the "variant". +template +_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_format_parse_context<_CharT>& __parse_ctx, + __compile_time_basic_format_context<_CharT>& __ctx, + __arg_t __type) { + switch (__type) { + case __arg_t::__none: + std::__throw_format_error("Invalid argument"); + case __arg_t::__boolean: + return __format::__compile_time_validate_argument<_CharT, bool>(__parse_ctx, __ctx); + case __arg_t::__char_type: + return __format::__compile_time_validate_argument<_CharT, _CharT>(__parse_ctx, __ctx); + case __arg_t::__int: + return __format::__compile_time_validate_argument<_CharT, int>(__parse_ctx, __ctx); + case __arg_t::__long_long: + return __format::__compile_time_validate_argument<_CharT, long long>(__parse_ctx, __ctx); + case __arg_t::__i128: +# ifndef _LIBCPP_HAS_NO_INT128 + return __format::__compile_time_validate_argument<_CharT, __int128_t>(__parse_ctx, __ctx); +# else + std::__throw_format_error("Invalid argument"); +# endif + return; + case __arg_t::__unsigned: + return __format::__compile_time_validate_argument<_CharT, unsigned>(__parse_ctx, __ctx); + case __arg_t::__unsigned_long_long: + return __format::__compile_time_validate_argument<_CharT, unsigned long long>(__parse_ctx, __ctx); + case __arg_t::__u128: +# ifndef _LIBCPP_HAS_NO_INT128 + return __format::__compile_time_validate_argument<_CharT, __uint128_t>(__parse_ctx, __ctx); +# else + std::__throw_format_error("Invalid argument"); +# endif + return; + case __arg_t::__float: + return __format::__compile_time_validate_argument<_CharT, float, true>(__parse_ctx, __ctx); + case __arg_t::__double: + return __format::__compile_time_validate_argument<_CharT, double, true>(__parse_ctx, __ctx); + case __arg_t::__long_double: + return __format::__compile_time_validate_argument<_CharT, long double, true>(__parse_ctx, __ctx); + case __arg_t::__const_char_type_ptr: + return __format::__compile_time_validate_argument<_CharT, const _CharT*, true>(__parse_ctx, __ctx); + case __arg_t::__string_view: + return __format::__compile_time_validate_argument<_CharT, basic_string_view<_CharT>, true>(__parse_ctx, __ctx); + case __arg_t::__ptr: + return __format::__compile_time_validate_argument<_CharT, const void*>(__parse_ctx, __ctx); + case __arg_t::__handle: + std::__throw_format_error("Handle should use __compile_time_validate_handle_argument"); + } + std::__throw_format_error("Invalid argument"); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr const _CharT* +__handle_replacement_field(const _CharT* __begin, const _CharT* __end, + _ParseCtx& __parse_ctx, _Ctx& __ctx) { + __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); + + bool __parse = *__r.__ptr == _CharT(':'); + switch (*__r.__ptr) { + case _CharT(':'): + // The arg-id has a format-specifier, advance the input to the format-spec. + __parse_ctx.advance_to(__r.__ptr + 1); + break; + case _CharT('}'): + // The arg-id has no format-specifier. + __parse_ctx.advance_to(__r.__ptr); + break; + default: + std::__throw_format_error("The replacement field arg-id should terminate at a ':' or '}'"); + } + + if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) { + __arg_t __type = __ctx.arg(__r.__value); + if (__type == __arg_t::__none) + std::__throw_format_error("Argument index out of bounds"); + else if (__type == __arg_t::__handle) + __ctx.__handle(__r.__value).__parse(__parse_ctx); + else if (__parse) + __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type); + } else + _VSTD::__visit_format_arg( + [&](auto __arg) { + if constexpr (same_as) + std::__throw_format_error("Argument index out of bounds"); + else if constexpr (same_as::handle>) + __arg.format(__parse_ctx, __ctx); + else { + formatter __formatter; + if (__parse) + __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); + __ctx.advance_to(__formatter.format(__arg, __ctx)); + } + }, + __ctx.arg(__r.__value)); + + __begin = __parse_ctx.begin(); + if (__begin == __end || *__begin != _CharT('}')) + std::__throw_format_error("The replacement field misses a terminating '}'"); + + return ++__begin; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator +__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { + using _CharT = typename _ParseCtx::char_type; + static_assert(same_as); + + const _CharT* __begin = __parse_ctx.begin(); + const _CharT* __end = __parse_ctx.end(); + typename _Ctx::iterator __out_it = __ctx.out(); + while (__begin != __end) { + switch (*__begin) { + case _CharT('{'): + ++__begin; + if (__begin == __end) + std::__throw_format_error("The format string terminates at a '{'"); + + if (*__begin != _CharT('{')) [[likely]] { + __ctx.advance_to(_VSTD::move(__out_it)); + __begin = + __format::__handle_replacement_field(__begin, __end, __parse_ctx, __ctx); + __out_it = __ctx.out(); + + // The output is written and __begin points to the next character. So + // start the next iteration. + continue; + } + // The string is an escape character. + break; + + case _CharT('}'): + ++__begin; + if (__begin == __end || *__begin != _CharT('}')) + std::__throw_format_error("The format string contains an invalid escape sequence"); + + break; + } + + // Copy the character to the output verbatim. + *__out_it++ = *__begin++; + } + return __out_it; +} + +} // namespace __format + +template +struct _LIBCPP_TEMPLATE_VIS basic_format_string { + template + requires convertible_to> + consteval basic_format_string(const _Tp& __str) : __str_{__str} { + __format::__vformat_to(basic_format_parse_context<_CharT>{__str_, sizeof...(_Args)}, + _Context{__types_.data(), __handles_.data(), sizeof...(_Args)}); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT constexpr basic_string_view<_CharT> get() const noexcept { + return __str_; + } + +private: + basic_string_view<_CharT> __str_; + + using _Context = __format::__compile_time_basic_format_context<_CharT>; + + static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{ + __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...}; + + // TODO FMT remove this work-around when the AIX ICE has been resolved. +# if defined(_AIX) && defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1400 + template + static constexpr __format::__compile_time_handle<_CharT> __get_handle() { + __format::__compile_time_handle<_CharT> __handle; + if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle) + __handle.template __enable<_Tp>(); + + return __handle; + } + + static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{ + __get_handle<_Args>()...}; +# else + static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{[] { + using _Tp = remove_cvref_t<_Args>; + __format::__compile_time_handle<_CharT> __handle; + if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle) + __handle.template __enable<_Tp>(); + + return __handle; + }()...}; +# endif +}; + +template +using format_string = basic_format_string...>; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +using wformat_string = basic_format_string...>; +#endif + +template +requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt + __vformat_to( + _OutIt __out_it, basic_string_view<_CharT> __fmt, + basic_format_args> __args) { + if constexpr (same_as<_OutIt, _FormatOutIt>) + return _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); + else { + __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; + _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); + return _VSTD::move(__buffer).__out_it(); + } +} + +// The function is _LIBCPP_ALWAYS_INLINE since the compiler is bad at inlining +// https://reviews.llvm.org/D110499#inline-1180704 +// TODO FMT Evaluate whether we want to file a Clang bug report regarding this. +template _OutIt> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); +} +#endif + +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(), + _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(), + _VSTD::make_wformat_args(__args...)); +} +#endif + +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +vformat(string_view __fmt, format_args __args) { + string __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + return __res; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +vformat(wstring_view __fmt, wformat_args __args) { + wstring __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + return __res; +} +#endif + +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(format_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::vformat(__fmt.get(), _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +format(wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat(__fmt.get(), _VSTD::make_wformat_args(__args...)); +} +#endif + +template +_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, + basic_string_view<_CharT> __fmt, + basic_format_args<_Context> __args) { + __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; + _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); + return _VSTD::move(__buffer).__result(); +} + +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_wformat_args(__args...)); +} +#endif + +template +_LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, auto __args) { + __format::__formatted_size_buffer<_CharT> __buffer; + _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); + return _VSTD::move(__buffer).__result(); +} + +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)}); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)}); +} +#endif + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + +template +requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt + __vformat_to( + _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, + basic_format_args> __args) { + if constexpr (same_as<_OutIt, _FormatOutIt>) + return _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args, _VSTD::move(__loc))); + else { + __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; + _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); + return _VSTD::move(__buffer).__out_it(); + } +} + +template _OutIt> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( + _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + __args); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( + _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + __args); +} +#endif + +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(), + _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(), + _VSTD::make_wformat_args(__args...)); +} +#endif + +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +vformat(locale __loc, string_view __fmt, format_args __args) { + string __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, + __args); + return __res; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +vformat(locale __loc, wstring_view __fmt, wformat_args __args) { + wstring __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, + __args); + return __res; +} +#endif + +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc, + format_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(), + _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(), + _VSTD::make_wformat_args(__args...)); +} +#endif + +template +_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, + locale __loc, basic_string_view<_CharT> __fmt, + basic_format_args<_Context> __args) { + __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; + _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); + return _VSTD::move(__buffer).__result(); +} + +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(), + _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template _OutIt, class... _Args> +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt, + _Args&&... __args) { + return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(), + _VSTD::make_wformat_args(__args...)); +} +#endif + +template +_LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_CharT> __fmt, auto __args) { + __format::__formatted_size_buffer<_CharT> __buffer; + _VSTD::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); + return _VSTD::move(__buffer).__result(); +} + +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)}); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { + return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)}); +} +#endif + +#endif // _LIBCPP_HAS_NO_LOCALIZATION + + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +#endif // _LIBCPP___FORMAT_FORMAT_FUNCTIONS diff --git a/gnu/llvm/libcxx/include/__format/format_fwd.h b/gnu/llvm/libcxx/include/__format/format_fwd.h new file mode 100644 index 00000000000..f7c72e21211 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/format_fwd.h @@ -0,0 +1,39 @@ +// -*- 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___FORMAT_FORMAT_FWD_H +#define _LIBCPP___FORMAT_FORMAT_FWD_H + +#include <__availability> +#include <__config> +#include <__iterator/concepts.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg; + +template + requires output_iterator<_OutIt, const _CharT&> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_FWD_H diff --git a/gnu/llvm/libcxx/include/__format/format_parse_context.h b/gnu/llvm/libcxx/include/__format/format_parse_context.h index db39c1b5483..30e3a7dfdaf 100644 --- a/gnu/llvm/libcxx/include/__format/format_parse_context.h +++ b/gnu/llvm/libcxx/include/__format/format_parse_context.h @@ -15,23 +15,13 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 17 -// TODO FMT Remove this once we require compilers with proper C++20 support. -// If the compiler has no concepts support, the format header will be disabled. -// Without concepts support enable_if needs to be used and that too much effort -// to support compilers with partial C++20 support. -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && \ - !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) - template class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context { public: @@ -64,8 +54,7 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() { if (__indexing_ == __manual) - __throw_format_error("Using automatic argument numbering in manual " - "argument numbering mode"); + std::__throw_format_error("Using automatic argument numbering in manual argument numbering mode"); if (__indexing_ == __unknown) __indexing_ = __automatic; @@ -73,8 +62,7 @@ public: } _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) { if (__indexing_ == __automatic) - __throw_format_error("Using manual argument numbering in automatic " - "argument numbering mode"); + std::__throw_format_error("Using manual argument numbering in automatic argument numbering mode"); if (__indexing_ == __unknown) __indexing_ = __manual; @@ -87,7 +75,7 @@ public: // Note: the Throws clause [format.parse.ctx]/10 doesn't specify the // behavior when id >= num_args_. if (is_constant_evaluated() && __id >= __num_args_) - __throw_format_error("Argument index outside the valid range"); + std::__throw_format_error("Argument index outside the valid range"); } private: @@ -98,16 +86,15 @@ private: size_t __next_arg_id_; size_t __num_args_; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_parse_context); using format_parse_context = basic_format_parse_context; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS using wformat_parse_context = basic_format_parse_context; - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) +#endif #endif //_LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H diff --git a/gnu/llvm/libcxx/include/__format/format_string.h b/gnu/llvm/libcxx/include/__format/format_string.h new file mode 100644 index 00000000000..d9caf866a17 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/format_string.h @@ -0,0 +1,163 @@ +// -*- 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___FORMAT_FORMAT_STRING_H +#define _LIBCPP___FORMAT_FORMAT_STRING_H + +#include <__assert> +#include <__config> +#include <__format/format_error.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format { + +template +struct _LIBCPP_TEMPLATE_VIS __parse_number_result { + const _CharT* __ptr; + uint32_t __value; +}; + +template +__parse_number_result(const _CharT*, uint32_t) -> __parse_number_result<_CharT>; + +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_number(const _CharT* __begin, const _CharT* __end); + +/** + * The maximum value of a numeric argument. + * + * This is used for: + * * arg-id + * * width as value or arg-id. + * * precision as value or arg-id. + * + * The value is compatible with the maximum formatting width and precision + * using the `%*` syntax on a 32-bit system. + */ +inline constexpr uint32_t __number_max = INT32_MAX; + +namespace __detail { +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_zero(const _CharT* __begin, const _CharT*, auto& __parse_ctx) { + __parse_ctx.check_arg_id(0); + return {++__begin, 0}; // can never be larger than the maximum. +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_automatic(const _CharT* __begin, const _CharT*, auto& __parse_ctx) { + size_t __value = __parse_ctx.next_arg_id(); + _LIBCPP_ASSERT(__value <= __number_max, + "Compilers don't support this number of arguments"); + + return {__begin, uint32_t(__value)}; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + __parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end); + __parse_ctx.check_arg_id(__r.__value); + return __r; +} + +} // namespace __detail + +/** + * Parses a number. + * + * The number is used for the 31-bit values @em width and @em precision. This + * allows a maximum value of 2147483647. + */ +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_number(const _CharT* __begin, const _CharT* __end_input) { + static_assert(__format::__number_max == INT32_MAX, + "The algorithm is implemented based on this value."); + /* + * Limit the input to 9 digits, otherwise we need two checks during every + * iteration: + * - Are we at the end of the input? + * - Does the value exceed width of an uint32_t? (Switching to uint64_t would + * have the same issue, but with a higher maximum.) + */ + const _CharT* __end = __end_input - __begin > 9 ? __begin + 9 : __end_input; + uint32_t __value = *__begin - _CharT('0'); + while (++__begin != __end) { + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + return {__begin, __value}; + + __value = __value * 10 + *__begin - _CharT('0'); + } + + if (__begin != __end_input && *__begin >= _CharT('0') && + *__begin <= _CharT('9')) { + + /* + * There are more than 9 digits, do additional validations: + * - Does the 10th digit exceed the maximum allowed value? + * - Are there more than 10 digits? + * (More than 10 digits always overflows the maximum.) + */ + uint64_t __v = uint64_t(__value) * 10 + *__begin++ - _CharT('0'); + if (__v > __number_max || + (__begin != __end_input && *__begin >= _CharT('0') && + *__begin <= _CharT('9'))) + std::__throw_format_error("The numeric value of the format-spec is too large"); + + __value = __v; + } + + return {__begin, __value}; +} + +/** + * Multiplexer for all parse functions. + * + * The parser will return a pointer beyond the last consumed character. This + * should be the closing '}' of the arg-id. + */ +template +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> +__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + switch (*__begin) { + case _CharT('0'): + return __detail::__parse_zero(__begin, __end, __parse_ctx); + + case _CharT(':'): + // This case is conditionally valid. It's allowed in an arg-id in the + // replacement-field, but not in the std-format-spec. The caller can + // provide a better diagnostic, so accept it here unconditionally. + case _CharT('}'): + return __detail::__parse_automatic(__begin, __end, __parse_ctx); + } + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + std::__throw_format_error("The arg-id of the format-spec starts with an invalid character"); + + return __detail::__parse_manual(__begin, __end, __parse_ctx); +} + +} // namespace __format + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_STRING_H diff --git a/gnu/llvm/libcxx/include/__format/format_to_n_result.h b/gnu/llvm/libcxx/include/__format/format_to_n_result.h new file mode 100644 index 00000000000..f1ed9a0982a --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/format_to_n_result.h @@ -0,0 +1,35 @@ +// -*- 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___FORMAT_FORMAT_TO_N_RESULT_H +#define _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H + +#include <__config> +#include <__iterator/incrementable_traits.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +struct _LIBCPP_TEMPLATE_VIS format_to_n_result { + _OutIt out; + iter_difference_t<_OutIt> size; +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(format_to_n_result); + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H diff --git a/gnu/llvm/libcxx/include/__format/formatter.h b/gnu/llvm/libcxx/include/__format/formatter.h new file mode 100644 index 00000000000..900a09af4e9 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter.h @@ -0,0 +1,54 @@ +// -*- 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___FORMAT_FORMATTER_H +#define _LIBCPP___FORMAT_FORMATTER_H + +#include <__availability> +#include <__config> +#include <__format/format_fwd.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +/// The default formatter template. +/// +/// [format.formatter.spec]/5 +/// If F is a disabled specialization of formatter, these values are false: +/// - is_default_constructible_v, +/// - is_copy_constructible_v, +/// - is_move_constructible_v, +/// - is_copy_assignable, and +/// - is_move_assignable. +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +# if _LIBCPP_STD_VER > 20 + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) { + if constexpr (requires { __formatter.set_debug_format(); }) + __formatter.set_debug_format(); +} + +# endif // _LIBCPP_STD_VER > 20 +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_H diff --git a/gnu/llvm/libcxx/include/__format/formatter_bool.h b/gnu/llvm/libcxx/include/__format/formatter_bool.h new file mode 100644 index 00000000000..0d005a1bee2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter_bool.h @@ -0,0 +1,78 @@ +// -*- 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___FORMAT_FORMATTER_BOOL_H +#define _LIBCPP___FORMAT_FORMATTER_BOOL_H + +#include <__algorithm/copy.h> +#include <__availability> +#include <__config> +#include <__debug> +#include <__format/concepts.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/parser_std_format_spec.h> +#include <__utility/unreachable.h> +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral); + __format_spec::__process_parsed_bool(__parser_); + return __result; + } + + _LIBCPP_HIDE_FROM_ABI auto format(bool __value, auto& __ctx) const -> decltype(__ctx.out()) { + switch (__parser_.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__string: + return __formatter::__format_bool(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx)); + + case __format_spec::__type::__binary_lower_case: + case __format_spec::__type::__binary_upper_case: + case __format_spec::__type::__octal: + case __format_spec::__type::__decimal: + case __format_spec::__type::__hexadecimal_lower_case: + case __format_spec::__type::__hexadecimal_upper_case: + // Promotes bool to an integral type. This reduces the number of + // instantiations of __format_integer reducing code size. + return __formatter::__format_integer( + static_cast(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx)); + + default: + _LIBCPP_ASSERT(false, "The parse function should have validated the type"); + __libcpp_unreachable(); + } + } + + __format_spec::__parser<_CharT> __parser_; +}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_BOOL_H diff --git a/gnu/llvm/libcxx/include/__format/formatter_char.h b/gnu/llvm/libcxx/include/__format/formatter_char.h new file mode 100644 index 00000000000..8a92e7445b4 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter_char.h @@ -0,0 +1,93 @@ +// -*- 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___FORMAT_FORMATTER_CHAR_H +#define _LIBCPP___FORMAT_FORMATTER_CHAR_H + +#include <__availability> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__type_traits/conditional.h> +#include <__type_traits/is_signed.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_char { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral); + __format_spec::__process_parsed_char(__parser_); + return __result; + } + + _LIBCPP_HIDE_FROM_ABI auto format(_CharT __value, auto& __ctx) const -> decltype(__ctx.out()) { + if (__parser_.__type_ == __format_spec::__type::__default || __parser_.__type_ == __format_spec::__type::__char) + return __formatter::__format_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); + +# if _LIBCPP_STD_VER > 20 + if (__parser_.__type_ == __format_spec::__type::__debug) + return __formatter::__format_escaped_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); +# endif + + if constexpr (sizeof(_CharT) <= sizeof(int)) + // Promotes _CharT to an integral type. This reduces the number of + // instantiations of __format_integer reducing code size. + return __formatter::__format_integer( + static_cast, int, unsigned>>(__value), + __ctx, + __parser_.__get_parsed_std_specifications(__ctx)); + else + return __formatter::__format_integer(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx)); + } + + _LIBCPP_HIDE_FROM_ABI auto format(char __value, auto& __ctx) const -> decltype(__ctx.out()) + requires(same_as<_CharT, wchar_t>) + { + return format(static_cast(__value), __ctx); + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; } +# endif + + __format_spec::__parser<_CharT> __parser_; +}; + +template <> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_char {}; + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_char {}; + +template <> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_char { +}; + +# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_CHAR_H diff --git a/gnu/llvm/libcxx/include/__format/formatter_floating_point.h b/gnu/llvm/libcxx/include/__format/formatter_floating_point.h new file mode 100644 index 00000000000..ca065723e19 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter_floating_point.h @@ -0,0 +1,756 @@ +// -*- 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___FORMAT_FORMATTER_FLOATING_POINT_H +#define _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H + +#include <__algorithm/copy_n.h> +#include <__algorithm/find.h> +#include <__algorithm/max.h> +#include <__algorithm/min.h> +#include <__algorithm/rotate.h> +#include <__algorithm/transform.h> +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__memory/allocator.h> +#include <__utility/move.h> +#include <__utility/unreachable.h> +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __formatter { + +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt, int __precision) { + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt, __precision); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +// https://en.cppreference.com/w/cpp/language/types#cite_note-1 +// float min subnormal: +/-0x1p-149 max: +/- 3.402,823,4 10^38 +// double min subnormal: +/-0x1p-1074 max +/- 1.797,693,134,862,315,7 10^308 +// long double (x86) min subnormal: +/-0x1p-16446 max: +/- 1.189,731,495,357,231,765,021 10^4932 +// +// The maximum number of digits required for the integral part is based on the +// maximum's value power of 10. Every power of 10 requires one additional +// decimal digit. +// The maximum number of digits required for the fractional part is based on +// the minimal subnormal hexadecimal output's power of 10. Every division of a +// fraction's binary 1 by 2, requires one additional decimal digit. +// +// The maximum size of a formatted value depends on the selected output format. +// Ignoring the fact the format string can request a precision larger than the +// values maximum required, these values are: +// +// sign 1 code unit +// __max_integral +// radix point 1 code unit +// __max_fractional +// exponent character 1 code unit +// sign 1 code unit +// __max_fractional_value +// ----------------------------------- +// total 4 code units extra required. +// +// TODO FMT Optimize the storage to avoid storing digits that are known to be zero. +// https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/ + +// TODO FMT Add long double specialization when to_chars has proper long double support. +template +struct __traits; + +template +_LIBCPP_HIDE_FROM_ABI constexpr size_t __float_buffer_size(int __precision) { + using _Traits = __traits<_Fp>; + return 4 + _Traits::__max_integral + __precision + _Traits::__max_fractional_value; +} + +template <> +struct __traits { + static constexpr int __max_integral = 38; + static constexpr int __max_fractional = 149; + static constexpr int __max_fractional_value = 3; + static constexpr size_t __stack_buffer_size = 256; + + static constexpr int __hex_precision_digits = 3; +}; + +template <> +struct __traits { + static constexpr int __max_integral = 308; + static constexpr int __max_fractional = 1074; + static constexpr int __max_fractional_value = 4; + static constexpr size_t __stack_buffer_size = 1024; + + static constexpr int __hex_precision_digits = 4; +}; + +/// Helper class to store the conversion buffer. +/// +/// Depending on the maxium size required for a value, the buffer is allocated +/// on the stack or the heap. +template +class _LIBCPP_TEMPLATE_VIS __float_buffer { + using _Traits = __traits<_Fp>; + +public: + // TODO FMT Improve this constructor to do a better estimate. + // When using a scientific formatting with a precision of 6 a stack buffer + // will always suffice. At the moment that isn't important since floats and + // doubles use a stack buffer, unless the precision used in the format string + // is large. + // When supporting long doubles the __max_integral part becomes 4932 which + // may be too much for some platforms. For these cases a better estimate is + // required. + explicit _LIBCPP_HIDE_FROM_ABI __float_buffer(int __precision) + : __precision_(__precision != -1 ? __precision : _Traits::__max_fractional) { + + // When the precision is larger than _Traits::__max_fractional the digits in + // the range (_Traits::__max_fractional, precision] will contain the value + // zero. There's no need to request to_chars to write these zeros: + // - When the value is large a temporary heap buffer needs to be allocated. + // - When to_chars writes the values they need to be "copied" to the output: + // - char: std::fill on the output iterator is faster than std::copy. + // - wchar_t: same argument as char, but additional std::copy won't work. + // The input is always a char buffer, so every char in the buffer needs + // to be converted from a char to a wchar_t. + if (__precision_ > _Traits::__max_fractional) { + __num_trailing_zeros_ = __precision_ - _Traits::__max_fractional; + __precision_ = _Traits::__max_fractional; + } + + __size_ = __formatter::__float_buffer_size<_Fp>(__precision_); + if (__size_ > _Traits::__stack_buffer_size) + // The allocated buffer's contents don't need initialization. + __begin_ = allocator{}.allocate(__size_); + else + __begin_ = __buffer_; + } + + _LIBCPP_HIDE_FROM_ABI ~__float_buffer() { + if (__size_ > _Traits::__stack_buffer_size) + allocator{}.deallocate(__begin_, __size_); + } + _LIBCPP_HIDE_FROM_ABI __float_buffer(const __float_buffer&) = delete; + _LIBCPP_HIDE_FROM_ABI __float_buffer& operator=(const __float_buffer&) = delete; + + _LIBCPP_HIDE_FROM_ABI char* begin() const { return __begin_; } + _LIBCPP_HIDE_FROM_ABI char* end() const { return __begin_ + __size_; } + + _LIBCPP_HIDE_FROM_ABI int __precision() const { return __precision_; } + _LIBCPP_HIDE_FROM_ABI int __num_trailing_zeros() const { return __num_trailing_zeros_; } + _LIBCPP_HIDE_FROM_ABI void __remove_trailing_zeros() { __num_trailing_zeros_ = 0; } + _LIBCPP_HIDE_FROM_ABI void __add_trailing_zeros(int __zeros) { __num_trailing_zeros_ += __zeros; } + +private: + int __precision_; + int __num_trailing_zeros_{0}; + size_t __size_; + char* __begin_; + char __buffer_[_Traits::__stack_buffer_size]; +}; + +struct __float_result { + /// Points at the beginning of the integral part in the buffer. + /// + /// When there's no sign character this points at the start of the buffer. + char* __integral; + + /// Points at the radix point, when not present it's the same as \ref __last. + char* __radix_point; + + /// Points at the exponent character, when not present it's the same as \ref __last. + char* __exponent; + + /// Points beyond the last written element in the buffer. + char* __last; +}; + +/// Finds the position of the exponent character 'e' at the end of the buffer. +/// +/// Assuming there is an exponent the input will terminate with +/// eSdd and eSdddd (S = sign, d = digit) +/// +/// \returns a pointer to the exponent or __last when not found. +constexpr inline _LIBCPP_HIDE_FROM_ABI char* __find_exponent(char* __first, char* __last) { + ptrdiff_t __size = __last - __first; + if (__size >= 4) { + __first = __last - _VSTD::min(__size, ptrdiff_t(6)); + for (; __first != __last - 3; ++__first) { + if (*__first == 'e') + return __first; + } + } + return __last; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffer<_Fp>& __buffer, _Tp __value, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value); + + __result.__exponent = __formatter::__find_exponent(__result.__integral, __result.__last); + + // Constrains: + // - There's at least one decimal digit before the radix point. + // - The radix point, when present, is placed before the exponent. + __result.__radix_point = _VSTD::find(__result.__integral + 1, __result.__exponent, '.'); + + // When the radix point isn't found its position is the exponent instead of + // __result.__last. + if (__result.__radix_point == __result.__exponent) + __result.__radix_point = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + if (__precision == -1) + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex); + else + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::hex, __precision); + + // H = one or more hex-digits + // S = sign + // D = one or more decimal-digits + // When the fractional part is zero and no precision the output is 0p+0 + // else the output is 0.HpSD + // So testing the second position can differentiate between these two cases. + char* __first = __integral + 1; + if (*__first == '.') { + __result.__radix_point = __first; + // One digit is the minimum + // 0.hpSd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456 + // + // Four digits is the maximum + // 0.hpSdddd + // ^-- last + // ^---- integral = end of search + // ^-------- start of search + // 0123456789 + static_assert(__traits<_Fp>::__hex_precision_digits <= 4, "Guard against possible underflow."); + + char* __last = __result.__last - 2; + __first = __last - __traits<_Fp>::__hex_precision_digits; + __result.__exponent = _VSTD::find(__first, __last, 'p'); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'p'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __formatter::__format_buffer_hexadecimal_lower_case(__buffer, __value, __precision, __integral); + _VSTD::transform(__result.__integral, __result.__exponent, __result.__integral, __hex_to_upper); + *__result.__exponent = 'P'; + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = + __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision); + + char* __first = __integral + 1; + _LIBCPP_ASSERT(__first != __result.__last, "No exponent present"); + if (*__first == '.') { + __result.__radix_point = __first; + __result.__exponent = __formatter::__find_exponent(__first + 1, __result.__last); + } else { + __result.__radix_point = __result.__last; + __result.__exponent = __first; + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const __float_buffer<_Fp>& __buffer, + _Tp __value, int __precision, + char* __integral) { + __float_result __result = + __formatter::__format_buffer_scientific_lower_case(__buffer, __value, __precision, __integral); + *__result.__exponent = 'E'; + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result; + __result.__integral = __integral; + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::fixed, __precision); + + // When there's no precision there's no radix point. + // Else the radix point is placed at __precision + 1 from the end. + // By converting __precision to a bool the subtraction can be done + // unconditionally. + __result.__radix_point = __result.__last - (__precision + bool(__precision)); + __result.__exponent = __result.__last; + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last), + "Post-condition failure."); + // clang-format on + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + + __buffer.__remove_trailing_zeros(); + + __float_result __result; + __result.__integral = __integral; + __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::general, __precision); + + char* __first = __integral + 1; + if (__first == __result.__last) { + __result.__radix_point = __result.__last; + __result.__exponent = __result.__last; + } else { + __result.__exponent = __formatter::__find_exponent(__first, __result.__last); + if (__result.__exponent != __result.__last) + // In scientific mode if there's a radix point it will always be after + // the first digit. (This is the position __first points at). + __result.__radix_point = *__first == '.' ? __first : __result.__last; + else { + // In fixed mode the algorithm truncates trailing spaces and possibly the + // radix point. There's no good guess for the position of the radix point + // therefore scan the output after the first digit. + __result.__radix_point = _VSTD::find(__first, __result.__last, '.'); + } + } + + // clang-format off + _LIBCPP_ASSERT((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); + // clang-format on + + return __result; +} + +template +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value, + int __precision, char* __integral) { + __float_result __result = __formatter::__format_buffer_general_lower_case(__buffer, __value, __precision, __integral); + if (__result.__exponent != __result.__last) + *__result.__exponent = 'E'; + return __result; +} + +/// Fills the buffer with the data based on the requested formatting. +/// +/// This function, when needed, turns the characters to upper case and +/// determines the "interesting" locations which are returned to the caller. +/// +/// This means the caller never has to convert the contents of the buffer to +/// upper case or search for radix points and the location of the exponent. +/// This gives a bit of overhead. The original code didn't do that, but due +/// to the number of possible additional work needed to turn this number to +/// the proper output the code was littered with tests for upper cases and +/// searches for radix points and exponents. +/// - When a precision larger than the type's precision is selected +/// additional zero characters need to be written before the exponent. +/// - alternate form needs to add a radix point when not present. +/// - localization needs to do grouping in the integral part. +template +// TODO FMT _Fp should just be _Tp when to_chars has proper long double support. +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer( + __float_buffer<_Fp>& __buffer, + _Tp __value, + bool __negative, + bool __has_precision, + __format_spec::__sign __sign, + __format_spec::__type __type) { + char* __first = __formatter::__insert_sign(__buffer.begin(), __negative, __sign); + switch (__type) { + case __format_spec::__type::__default: + if (__has_precision) + return __formatter::__format_buffer_general_lower_case(__buffer, __value, __buffer.__precision(), __first); + else + return __formatter::__format_buffer_default(__buffer, __value, __first); + + case __format_spec::__type::__hexfloat_lower_case: + return __formatter::__format_buffer_hexadecimal_lower_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case __format_spec::__type::__hexfloat_upper_case: + return __formatter::__format_buffer_hexadecimal_upper_case( + __buffer, __value, __has_precision ? __buffer.__precision() : -1, __first); + + case __format_spec::__type::__scientific_lower_case: + return __formatter::__format_buffer_scientific_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case __format_spec::__type::__scientific_upper_case: + return __formatter::__format_buffer_scientific_upper_case(__buffer, __value, __buffer.__precision(), __first); + + case __format_spec::__type::__fixed_lower_case: + case __format_spec::__type::__fixed_upper_case: + return __formatter::__format_buffer_fixed(__buffer, __value, __buffer.__precision(), __first); + + case __format_spec::__type::__general_lower_case: + return __formatter::__format_buffer_general_lower_case(__buffer, __value, __buffer.__precision(), __first); + + case __format_spec::__type::__general_upper_case: + return __formatter::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first); + + default: + _LIBCPP_ASSERT(false, "The parser should have validated the type"); + __libcpp_unreachable(); + } +} + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION +template +_LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( + _OutIt __out_it, + const __float_buffer<_Fp>& __buffer, + const __float_result& __result, + _VSTD::locale __loc, + __format_spec::__parsed_specifications<_CharT> __specs) { + const auto& __np = std::use_facet>(__loc); + string __grouping = __np.grouping(); + char* __first = __result.__integral; + // When no radix point or exponent are present __last will be __result.__last. + char* __last = _VSTD::min(__result.__radix_point, __result.__exponent); + + ptrdiff_t __digits = __last - __first; + if (!__grouping.empty()) { + if (__digits <= __grouping[0]) + __grouping.clear(); + else + __grouping = __formatter::__determine_grouping(__digits, __grouping); + } + + ptrdiff_t __size = + __result.__last - __buffer.begin() + // Formatted string + __buffer.__num_trailing_zeros() + // Not yet rendered zeros + __grouping.size() - // Grouping contains one + !__grouping.empty(); // additional character + + __formatter::__padding_size_result __padding = {0, 0}; + bool __zero_padding = __specs.__alignment_ == __format_spec::__alignment::__zero_padding; + if (__size < __specs.__width_) { + if (__zero_padding) { + __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__fill_ = _CharT('0'); + } + + __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); + } + + // sign and (zero padding or alignment) + if (__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + if (!__zero_padding && __first != __buffer.begin()) + *__out_it++ = *__buffer.begin(); + + // integral part + if (__grouping.empty()) { + __out_it = __formatter::__copy(__first, __digits, _VSTD::move(__out_it)); + } else { + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; + _CharT __sep = __np.thousands_sep(); + // The output is divided in small groups of numbers to write: + // - A group before the first separator. + // - A separator and a group, repeated for the number of separators. + // - A group after the last separator. + // This loop achieves that process by testing the termination condition + // midway in the loop. + while (true) { + __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it)); + __first += *__r; + + if (__r == __e) + break; + + ++__r; + *__out_it++ = __sep; + } + } + + // fractional part + if (__result.__radix_point != __result.__last) { + *__out_it++ = __np.decimal_point(); + __out_it = __formatter::__copy(__result.__radix_point + 1, __result.__exponent, _VSTD::move(__out_it)); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __buffer.__num_trailing_zeros(), _CharT('0')); + } + + // exponent + if (__result.__exponent != __result.__last) + __out_it = __formatter::__copy(__result.__exponent, __result.__last, _VSTD::move(__out_it)); + + // alignment + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} +# endif // _LIBCPP_HAS_NO_LOCALIZATION + +template +_LIBCPP_HIDE_FROM_ABI _OutIt __format_floating_point_non_finite( + _OutIt __out_it, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative, bool __isnan) { + char __buffer[4]; + char* __last = __formatter::__insert_sign(__buffer, __negative, __specs.__std_.__sign_); + + // to_chars can return inf, infinity, nan, and nan(n-char-sequence). + // The format library requires inf and nan. + // All in one expression to avoid dangling references. + bool __upper_case = + __specs.__std_.__type_ == __format_spec::__type::__hexfloat_upper_case || + __specs.__std_.__type_ == __format_spec::__type::__scientific_upper_case || + __specs.__std_.__type_ == __format_spec::__type::__fixed_upper_case || + __specs.__std_.__type_ == __format_spec::__type::__general_upper_case; + __last = _VSTD::copy_n(&("infnanINFNAN"[6 * __upper_case + 3 * __isnan]), 3, __last); + + // [format.string.std]/13 + // A zero (0) character preceding the width field pads the field with + // leading zeros (following any indication of sign or base) to the field + // width, except when applied to an infinity or NaN. + if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) + __specs.__alignment_ = __format_spec::__alignment::__right; + + return __formatter::__write(__buffer, __last, _VSTD::move(__out_it), __specs); +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) + -> decltype(__ctx.out()) { + bool __negative = _VSTD::signbit(__value); + + if (!_VSTD::isfinite(__value)) [[unlikely]] + return __formatter::__format_floating_point_non_finite(__ctx.out(), __specs, __negative, _VSTD::isnan(__value)); + + // Depending on the std-format-spec string the sign and the value + // might not be outputted together: + // - zero-padding may insert additional '0' characters. + // Therefore the value is processed as a non negative value. + // The function @ref __insert_sign will insert a '-' when the value was + // negative. + + if (__negative) + __value = -__value; + + // TODO FMT _Fp should just be _Tp when to_chars has proper long double support. + using _Fp = conditional_t, double, _Tp>; + // Force the type of the precision to avoid -1 to become an unsigned value. + __float_buffer<_Fp> __buffer(__specs.__precision_); + __float_result __result = __formatter::__format_buffer( + __buffer, __value, __negative, (__specs.__has_precision()), __specs.__std_.__sign_, __specs.__std_.__type_); + + if (__specs.__std_.__alternate_form_) { + if (__result.__radix_point == __result.__last) { + *__result.__last++ = '.'; + + // When there is an exponent the point needs to be moved before the + // exponent. When there's no exponent the rotate does nothing. Since + // rotate tests whether the operation is a nop, call it unconditionally. + _VSTD::rotate(__result.__exponent, __result.__last - 1, __result.__last); + __result.__radix_point = __result.__exponent; + + // The radix point is always placed before the exponent. + // - No exponent needs to point to the new last. + // - An exponent needs to move one position to the right. + // So it's safe to increment the value unconditionally. + ++__result.__exponent; + } + + // [format.string.std]/6 + // In addition, for g and G conversions, trailing zeros are not removed + // from the result. + // + // If the type option for a floating-point type is none it may use the + // general formatting, but it's not a g or G conversion. So in that case + // the formatting should not append trailing zeros. + bool __is_general = __specs.__std_.__type_ == __format_spec::__type::__general_lower_case || + __specs.__std_.__type_ == __format_spec::__type::__general_upper_case; + + if (__is_general) { + // https://en.cppreference.com/w/c/io/fprintf + // Let P equal the precision if nonzero, 6 if the precision is not + // specified, or 1 if the precision is 0. Then, if a conversion with + // style E would have an exponent of X: + int __p = _VSTD::max(1, (__specs.__has_precision() ? __specs.__precision_ : 6)); + if (__result.__exponent == __result.__last) + // if P > X >= -4, the conversion is with style f or F and precision P - 1 - X. + // By including the radix point it calculates P - (1 + X) + __p -= __result.__radix_point - __result.__integral; + else + // otherwise, the conversion is with style e or E and precision P - 1. + --__p; + + ptrdiff_t __precision = (__result.__exponent - __result.__radix_point) - 1; + if (__precision < __p) + __buffer.__add_trailing_zeros(__p - __precision); + } + } + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + if (__specs.__std_.__locale_specific_form_) + return __formatter::__format_locale_specific_form(__ctx.out(), __buffer, __result, __ctx.locale(), __specs); +# endif + + ptrdiff_t __size = __result.__last - __buffer.begin(); + int __num_trailing_zeros = __buffer.__num_trailing_zeros(); + if (__size + __num_trailing_zeros >= __specs.__width_) { + if (__num_trailing_zeros && __result.__exponent != __result.__last) + // Insert trailing zeros before exponent character. + return __formatter::__copy( + __result.__exponent, + __result.__last, + __formatter::__fill(__formatter::__copy(__buffer.begin(), __result.__exponent, __ctx.out()), + __num_trailing_zeros, + _CharT('0'))); + + return __formatter::__fill( + __formatter::__copy(__buffer.begin(), __result.__last, __ctx.out()), __num_trailing_zeros, _CharT('0')); + } + + auto __out_it = __ctx.out(); + char* __first = __buffer.begin(); + if (__specs.__alignment_ == __format_spec::__alignment ::__zero_padding) { + // When there is a sign output it before the padding. Note the __size + // doesn't need any adjustment, regardless whether the sign is written + // here or in __formatter::__write. + if (__first != __result.__integral) + *__out_it++ = *__first++; + // After the sign is written, zero padding is the same a right alignment + // with '0'. + __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__fill_ = _CharT('0'); + } + + if (__num_trailing_zeros) + return __formatter::__write_using_trailing_zeros( + __first, __result.__last, _VSTD::move(__out_it), __specs, __size, __result.__exponent, __num_trailing_zeros); + + return __formatter::__write(__first, __result.__last, _VSTD::move(__out_it), __specs, __size); +} + +} // namespace __formatter + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS __formatter_floating_point { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_floating_point); + __format_spec::__process_parsed_floating_point(__parser_); + return __result; + } + + template + _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) { + return __formatter::__format_floating_point(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx)); + } + + __format_spec::__parser<_CharT> __parser_; +}; + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_floating_point<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_floating_point<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_floating_point<_CharT> {}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H diff --git a/gnu/llvm/libcxx/include/__format/formatter_integer.h b/gnu/llvm/libcxx/include/__format/formatter_integer.h new file mode 100644 index 00000000000..b4be9f9a07c --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter_integer.h @@ -0,0 +1,107 @@ +// -*- 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___FORMAT_FORMATTER_INTEGER_H +#define _LIBCPP___FORMAT_FORMATTER_INTEGER_H + +#include <__availability> +#include <__concepts/arithmetic.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__type_traits/make_32_64_or_128_bit.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + + _LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + + template <__fmt_char_type _CharT> + struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_integer { + +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral); + __format_spec::__process_parsed_integer(__parser_); + return __result; + } + + template + _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) { + __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); + + if (__specs.__std_.__type_ == __format_spec::__type::__char) + return __formatter::__format_char(__value, __ctx.out(), __specs); + + using _Type = __make_32_64_or_128_bit_t<_Tp>; + static_assert(!is_same<_Type, void>::value, "unsupported integral type used in __formatter_integer::__format"); + + // Reduce the number of instantiation of the integer formatter + return __formatter::__format_integer(static_cast<_Type>(__value), __ctx, __specs); + } + + __format_spec::__parser<_CharT> __parser_; +}; + +// Signed integral types. +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_integer<_CharT> { +}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +# ifndef _LIBCPP_HAS_NO_INT128 +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT> + : public __formatter_integer<_CharT> {}; +# endif + +// Unsigned integral types. +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_integer<_CharT> {}; +# ifndef _LIBCPP_HAS_NO_INT128 +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT> + : public __formatter_integer<_CharT> {}; +# endif + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_INTEGER_H diff --git a/gnu/llvm/libcxx/include/__format/formatter_integral.h b/gnu/llvm/libcxx/include/__format/formatter_integral.h new file mode 100644 index 00000000000..fe3a06311be --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter_integral.h @@ -0,0 +1,363 @@ +// -*- 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___FORMAT_FORMATTER_INTEGRAL_H +#define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H + +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_error.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__utility/unreachable.h> +#include +#include +#include +#include + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __formatter { + +// +// Generic +// + +_LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, __format_spec::__sign __sign) { + if (__negative) + *__buf++ = '-'; + else + switch (__sign) { + case __format_spec::__sign::__default: + case __format_spec::__sign::__minus: + // No sign added. + break; + case __format_spec::__sign::__plus: + *__buf++ = '+'; + break; + case __format_spec::__sign::__space: + *__buf++ = ' '; + break; + } + + return __buf; +} + +/** + * Determines the required grouping based on the size of the input. + * + * The grouping's last element will be repeated. For simplicity this repeating + * is unwrapped based on the length of the input. (When the input is short some + * groups are not processed.) + * + * @returns The size of the groups to write. This means the number of + * separator characters written is size() - 1. + * + * @note Since zero-sized groups cause issues they are silently ignored. + * + * @note The grouping field of the locale is always a @c std::string, + * regardless whether the @c std::numpunct's type is @c char or @c wchar_t. + */ +_LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const string& __grouping) { + _LIBCPP_ASSERT(!__grouping.empty() && __size > __grouping[0], + "The slow grouping formatting is used while there will be no " + "separators written"); + string __r; + auto __end = __grouping.end() - 1; + auto __ptr = __grouping.begin(); + + while (true) { + __size -= *__ptr; + if (__size > 0) + __r.push_back(*__ptr); + else { + // __size <= 0 so the value pushed will be <= *__ptr. + __r.push_back(*__ptr + __size); + return __r; + } + + // Proceed to the next group. + if (__ptr != __end) { + do { + ++__ptr; + // Skip grouping with a width of 0. + } while (*__ptr == 0 && __ptr != __end); + } + } + + __libcpp_unreachable(); +} + +// +// Char +// + +template <__fmt_char_type _CharT> +_LIBCPP_HIDE_FROM_ABI auto __format_char( + integral auto __value, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + using _Tp = decltype(__value); + if constexpr (!same_as<_CharT, _Tp>) { + // cmp_less and cmp_greater can't be used for character types. + if constexpr (signed_integral<_CharT> == signed_integral<_Tp>) { + if (__value < numeric_limits<_CharT>::min() || __value > numeric_limits<_CharT>::max()) + std::__throw_format_error("Integral value outside the range of the char type"); + } else if constexpr (signed_integral<_CharT>) { + // _CharT is signed _Tp is unsigned + if (__value > static_cast>(numeric_limits<_CharT>::max())) + std::__throw_format_error("Integral value outside the range of the char type"); + } else { + // _CharT is unsigned _Tp is signed + if (__value < 0 || static_cast>(__value) > numeric_limits<_CharT>::max()) + std::__throw_format_error("Integral value outside the range of the char type"); + } + } + + const auto __c = static_cast<_CharT>(__value); + return __formatter::__write(_VSTD::addressof(__c), _VSTD::addressof(__c) + 1, _VSTD::move(__out_it), __specs); +} + +// +// Integer +// + +/** Wrapper around @ref to_chars, returning the output pointer. */ +template +_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, int __base) { + // TODO FMT Evaluate code overhead due to not calling the internal function + // directly. (Should be zero overhead.) + to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __base); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + return __r.ptr; +} + +/** + * Helper to determine the buffer size to output a integer in Base @em x. + * + * There are several overloads for the supported bases. The function uses the + * base as template argument so it can be used in a constant expression. + */ +template +consteval size_t __buffer_size() noexcept + requires(_Base == 2) +{ + return numeric_limits<_Tp>::digits // The number of binary digits. + + 2 // Reserve space for the '0[Bb]' prefix. + + 1; // Reserve space for the sign. +} + +template +consteval size_t __buffer_size() noexcept + requires(_Base == 8) +{ + return numeric_limits<_Tp>::digits // The number of binary digits. + / 3 // Adjust to octal. + + 1 // Turn floor to ceil. + + 1 // Reserve space for the '0' prefix. + + 1; // Reserve space for the sign. +} + +template +consteval size_t __buffer_size() noexcept + requires(_Base == 10) +{ + return numeric_limits<_Tp>::digits10 // The floored value. + + 1 // Turn floor to ceil. + + 1; // Reserve space for the sign. +} + +template +consteval size_t __buffer_size() noexcept + requires(_Base == 16) +{ + return numeric_limits<_Tp>::digits // The number of binary digits. + / 4 // Adjust to hexadecimal. + + 2 // Reserve space for the '0[Xx]' prefix. + + 1; // Reserve space for the sign. +} + +template +_LIBCPP_HIDE_FROM_ABI auto __format_integer( + _Tp __value, + auto& __ctx, + __format_spec::__parsed_specifications<_CharT> __specs, + bool __negative, + char* __begin, + char* __end, + const char* __prefix, + int __base) -> decltype(__ctx.out()) { + char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_); + if (__specs.__std_.__alternate_form_ && __prefix) + while (*__prefix) + *__first++ = *__prefix++; + + char* __last = __formatter::__to_buffer(__first, __end, __value, __base); + +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + if (__specs.__std_.__locale_specific_form_) { + const auto& __np = std::use_facet>(__ctx.locale()); + string __grouping = __np.grouping(); + ptrdiff_t __size = __last - __first; + // Writing the grouped form has more overhead than the normal output + // routines. If there will be no separators written the locale-specific + // form is identical to the normal routine. Test whether to grouped form + // is required. + if (!__grouping.empty() && __size > __grouping[0]) + return __formatter::__write_using_decimal_separators( + __ctx.out(), + __begin, + __first, + __last, + __formatter::__determine_grouping(__size, __grouping), + __np.thousands_sep(), + __specs); + } +# endif + auto __out_it = __ctx.out(); + if (__specs.__alignment_ != __format_spec::__alignment::__zero_padding) + __first = __begin; + else { + // __buf contains [sign][prefix]data + // ^ location of __first + // The zero padding is done like: + // - Write [sign][prefix] + // - Write data right aligned with '0' as fill character. + __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); + __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__fill_ = _CharT('0'); + int32_t __size = __first - __begin; + + __specs.__width_ -= _VSTD::min(__size, __specs.__width_); + } + + if (__specs.__std_.__type_ != __format_spec::__type::__hexadecimal_upper_case) [[likely]] + return __formatter::__write(__first, __last, __ctx.out(), __specs); + + return __formatter::__write_transformed(__first, __last, __ctx.out(), __specs, __formatter::__hex_to_upper); +} + +template +_LIBCPP_HIDE_FROM_ABI auto __format_integer( + _Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative = false) + -> decltype(__ctx.out()) { + switch (__specs.__std_.__type_) { + case __format_spec::__type::__binary_lower_case: { + array()> __array; + return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0b", 2); + } + case __format_spec::__type::__binary_upper_case: { + array()> __array; + return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0B", 2); + } + case __format_spec::__type::__octal: { + // Octal is special; if __value == 0 there's no prefix. + array()> __array; + return __formatter::__format_integer( + __value, __ctx, __specs, __negative, __array.begin(), __array.end(), __value != 0 ? "0" : nullptr, 8); + } + case __format_spec::__type::__default: + case __format_spec::__type::__decimal: { + array()> __array; + return __formatter::__format_integer( + __value, __ctx, __specs, __negative, __array.begin(), __array.end(), nullptr, 10); + } + case __format_spec::__type::__hexadecimal_lower_case: { + array()> __array; + return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0x", 16); + } + case __format_spec::__type::__hexadecimal_upper_case: { + array()> __array; + return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0X", 16); + } + default: + _LIBCPP_ASSERT(false, "The parse function should have validated the type"); + __libcpp_unreachable(); + } +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_integer(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) + -> decltype(__ctx.out()) { + // Depending on the std-format-spec string the sign and the value + // might not be outputted together: + // - alternate form may insert a prefix string. + // - zero-padding may insert additional '0' characters. + // Therefore the value is processed as a positive unsigned value. + // The function @ref __insert_sign will a '-' when the value was negative. + auto __r = std::__to_unsigned_like(__value); + bool __negative = __value < 0; + if (__negative) + __r = std::__complement(__r); + + return __formatter::__format_integer(__r, __ctx, __specs, __negative); +} + +// +// Formatter arithmetic (bool) +// + +template +struct _LIBCPP_TEMPLATE_VIS __bool_strings; + +template <> +struct _LIBCPP_TEMPLATE_VIS __bool_strings { + static constexpr string_view __true{"true"}; + static constexpr string_view __false{"false"}; +}; + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <> +struct _LIBCPP_TEMPLATE_VIS __bool_strings { + static constexpr wstring_view __true{L"true"}; + static constexpr wstring_view __false{L"false"}; +}; +# endif + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) + -> decltype(__ctx.out()) { +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + if (__specs.__std_.__locale_specific_form_) { + const auto& __np = std::use_facet>(__ctx.locale()); + basic_string<_CharT> __str = __value ? __np.truename() : __np.falsename(); + return __formatter::__write_string_no_precision(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); + } +# endif + basic_string_view<_CharT> __str = + __value ? __formatter::__bool_strings<_CharT>::__true : __formatter::__bool_strings<_CharT>::__false; + return __formatter::__write(__str.begin(), __str.end(), __ctx.out(), __specs); +} + +} // namespace __formatter + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H diff --git a/gnu/llvm/libcxx/include/__format/formatter_output.h b/gnu/llvm/libcxx/include/__format/formatter_output.h new file mode 100644 index 00000000000..467692559ce --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter_output.h @@ -0,0 +1,570 @@ +// -*- 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___FORMAT_FORMATTER_OUTPUT_H +#define _LIBCPP___FORMAT_FORMATTER_OUTPUT_H + +#include <__algorithm/ranges_copy.h> +#include <__algorithm/ranges_fill_n.h> +#include <__algorithm/ranges_transform.h> +#include <__chrono/statically_widen.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/buffer.h> +#include <__format/concepts.h> +#include <__format/escaped_output_table.h> +#include <__format/formatter.h> +#include <__format/parser_std_format_spec.h> +#include <__format/unicode.h> +#include <__iterator/back_insert_iterator.h> +#include <__type_traits/make_unsigned.h> +#include <__utility/move.h> +#include <__utility/unreachable.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __formatter { + +_LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char __c) { + switch (__c) { + case 'a': + return 'A'; + case 'b': + return 'B'; + case 'c': + return 'C'; + case 'd': + return 'D'; + case 'e': + return 'E'; + case 'f': + return 'F'; + } + return __c; +} + +struct _LIBCPP_TYPE_VIS __padding_size_result { + size_t __before_; + size_t __after_; +}; + +_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result +__padding_size(size_t __size, size_t __width, __format_spec::__alignment __align) { + _LIBCPP_ASSERT(__width > __size, "don't call this function when no padding is required"); + _LIBCPP_ASSERT( + __align != __format_spec::__alignment::__zero_padding, "the caller should have handled the zero-padding"); + + size_t __fill = __width - __size; + switch (__align) { + case __format_spec::__alignment::__zero_padding: + __libcpp_unreachable(); + + case __format_spec::__alignment::__left: + return {0, __fill}; + + case __format_spec::__alignment::__center: { + // The extra padding is divided per [format.string.std]/3 + // __before = floor(__fill, 2); + // __after = ceil(__fill, 2); + size_t __before = __fill / 2; + size_t __after = __fill - __before; + return {__before, __after}; + } + case __format_spec::__alignment::__default: + case __format_spec::__alignment::__right: + return {__fill, 0}; + } + __libcpp_unreachable(); +} + +/// Copy wrapper. +/// +/// This uses a "mass output function" of __format::__output_buffer when possible. +template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> +_LIBCPP_HIDE_FROM_ABI auto __copy(basic_string_view<_CharT> __str, output_iterator auto __out_it) + -> decltype(__out_it) { + if constexpr (_VSTD::same_as>>) { + __out_it.__get_container()->__copy(__str); + return __out_it; + } else if constexpr (_VSTD::same_as::__iterator>) { + __out_it.__buffer_->__copy(__str); + return __out_it; + } else { + return std::ranges::copy(__str, _VSTD::move(__out_it)).out; + } +} + +template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> +_LIBCPP_HIDE_FROM_ABI auto +__copy(const _CharT* __first, const _CharT* __last, output_iterator auto __out_it) + -> decltype(__out_it) { + return __formatter::__copy(basic_string_view{__first, __last}, _VSTD::move(__out_it)); +} + +template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> +_LIBCPP_HIDE_FROM_ABI auto __copy(const _CharT* __first, size_t __n, output_iterator auto __out_it) + -> decltype(__out_it) { + return __formatter::__copy(basic_string_view{__first, __n}, _VSTD::move(__out_it)); +} + +/// Transform wrapper. +/// +/// This uses a "mass output function" of __format::__output_buffer when possible. +template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT, class _UnaryOperation> +_LIBCPP_HIDE_FROM_ABI auto +__transform(const _CharT* __first, + const _CharT* __last, + output_iterator auto __out_it, + _UnaryOperation __operation) -> decltype(__out_it) { + if constexpr (_VSTD::same_as>>) { + __out_it.__get_container()->__transform(__first, __last, _VSTD::move(__operation)); + return __out_it; + } else if constexpr (_VSTD::same_as::__iterator>) { + __out_it.__buffer_->__transform(__first, __last, _VSTD::move(__operation)); + return __out_it; + } else { + return std::ranges::transform(__first, __last, _VSTD::move(__out_it), __operation).out; + } +} + +/// Fill wrapper. +/// +/// This uses a "mass output function" of __format::__output_buffer when possible. +template <__fmt_char_type _CharT, output_iterator _OutIt> +_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value) { + if constexpr (_VSTD::same_as>>) { + __out_it.__get_container()->__fill(__n, __value); + return __out_it; + } else if constexpr (_VSTD::same_as::__iterator>) { + __out_it.__buffer_->__fill(__n, __value); + return __out_it; + } else { + return std::ranges::fill_n(_VSTD::move(__out_it), __n, __value); + } +} + +template +_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first, + const char* __last, string&& __grouping, _CharT __sep, + __format_spec::__parsed_specifications<_CharT> __specs) { + int __size = (__first - __begin) + // [sign][prefix] + (__last - __first) + // data + (__grouping.size() - 1); // number of separator characters + + __padding_size_result __padding = {0, 0}; + if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) { + // Write [sign][prefix]. + __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); + + if (__specs.__width_ > __size) { + // Write zero padding. + __padding.__before_ = __specs.__width_ - __size; + __out_it = __formatter::__fill(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0')); + } + } else { + if (__specs.__width_ > __size) { + // Determine padding and write padding. + __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); + + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + } + // Write [sign][prefix]. + __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); + } + + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; + _LIBCPP_ASSERT(__r != __e, "The slow grouping formatting is used while " + "there will be no separators written."); + // The output is divided in small groups of numbers to write: + // - A group before the first separator. + // - A separator and a group, repeated for the number of separators. + // - A group after the last separator. + // This loop achieves that process by testing the termination condition + // midway in the loop. + // + // TODO FMT This loop evaluates the loop invariant `__parser.__type != + // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test + // happens in the __write call.) Benchmark whether making two loops and + // hoisting the invariant is worth the effort. + while (true) { + if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) { + __last = __first + *__r; + __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper); + __first = __last; + } else { + __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it)); + __first += *__r; + } + + if (__r == __e) + break; + + ++__r; + *__out_it++ = __sep; + } + + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} + +/// Writes the input to the output with the required padding. +/// +/// Since the output column width is specified the function can be used for +/// ASCII and Unicode output. +/// +/// \pre \a __size <= \a __width. Using this function when this pre-condition +/// doesn't hold incurs an unwanted overhead. +/// +/// \param __str The string to write. +/// \param __out_it The output iterator to write to. +/// \param __specs The parsed formatting specifications. +/// \param __size The (estimated) output column width. When the elements +/// to be written are ASCII the following condition holds +/// \a __size == \a __last - \a __first. +/// +/// \returns An iterator pointing beyond the last element written. +/// +/// \note The type of the elements in range [\a __first, \a __last) can differ +/// from the type of \a __specs. Integer output uses \c std::to_chars for its +/// conversion, which means the [\a __first, \a __last) always contains elements +/// of the type \c char. +template +_LIBCPP_HIDE_FROM_ABI auto +__write(basic_string_view<_CharT> __str, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + ptrdiff_t __size) -> decltype(__out_it) { + if (__size >= __specs.__width_) + return __formatter::__copy(__str, _VSTD::move(__out_it)); + + __padding_size_result __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__std_.__alignment_); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__copy(__str, _VSTD::move(__out_it)); + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__write(const _CharT* __first, + const _CharT* __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + ptrdiff_t __size) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + return __formatter::__write(basic_string_view{__first, __last}, _VSTD::move(__out_it), __specs, __size); +} + +/// \overload +/// +/// Calls the function above where \a __size = \a __last - \a __first. +template +_LIBCPP_HIDE_FROM_ABI auto +__write(const _CharT* __first, + const _CharT* __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + return __formatter::__write(__first, __last, _VSTD::move(__out_it), __specs, __last - __first); +} + +template +_LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _CharT* __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + _UnaryOperation __op) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + + ptrdiff_t __size = __last - __first; + if (__size >= __specs.__width_) + return __formatter::__transform(__first, __last, _VSTD::move(__out_it), __op); + + __padding_size_result __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __op); + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} + +/// Writes additional zero's for the precision before the exponent. +/// This is used when the precision requested in the format string is larger +/// than the maximum precision of the floating-point type. These precision +/// digits are always 0. +/// +/// \param __exponent The location of the exponent character. +/// \param __num_trailing_zeros The number of 0's to write before the exponent +/// character. +template +_LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros( + const _CharT* __first, + const _CharT* __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + size_t __size, + const _CharT* __exponent, + size_t __num_trailing_zeros) -> decltype(__out_it) { + _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); + _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used"); + + __padding_size_result __padding = + __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it)); + __out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0')); + __out_it = __formatter::__copy(__exponent, __last, _VSTD::move(__out_it)); + return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); +} + +/// Writes a string using format's width estimation algorithm. +/// +/// \pre !__specs.__has_precision() +/// +/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the +/// input is ASCII. +template +_LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision( + basic_string_view<_CharT> __str, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + _LIBCPP_ASSERT(!__specs.__has_precision(), "use __write_string"); + + // No padding -> copy the string + if (!__specs.__has_width()) + return __formatter::__copy(__str, _VSTD::move(__out_it)); + + // Note when the estimated width is larger than size there's no padding. So + // there's no reason to get the real size when the estimate is larger than or + // equal to the minimum field width. + size_t __size = + __format_spec::__estimate_column_width(__str, __specs.__width_, __format_spec::__column_width_rounding::__up) + .__width_; + return __formatter::__write(__str, _VSTD::move(__out_it), __specs, __size); +} + +template +_LIBCPP_HIDE_FROM_ABI int __truncate(basic_string_view<_CharT>& __str, int __precision) { + __format_spec::__column_width_result<_CharT> __result = + __format_spec::__estimate_column_width(__str, __precision, __format_spec::__column_width_rounding::__down); + __str = basic_string_view<_CharT>{__str.begin(), __result.__last_}; + return __result.__width_; +} + +/// Writes a string using format's width estimation algorithm. +/// +/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the +/// input is ASCII. +template +_LIBCPP_HIDE_FROM_ABI auto __write_string( + basic_string_view<_CharT> __str, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + if (!__specs.__has_precision()) + return __formatter::__write_string_no_precision(__str, _VSTD::move(__out_it), __specs); + + int __size = __formatter::__truncate(__str, __specs.__precision_); + + return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size); +} + +# if _LIBCPP_STD_VER > 20 + +struct __nul_terminator {}; + +template +_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) { + return *__cstr == _CharT('\0'); +} + +template +_LIBCPP_HIDE_FROM_ABI void +__write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) { + back_insert_iterator __out_it{__str}; + std::ranges::copy(__prefix, __nul_terminator{}, __out_it); + + char __buffer[8]; + to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16); + _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it); + + __str += _CharT('}'); +} + +// [format.string.escaped]/2.2.1.2 +// ... +// then the sequence \u{hex-digit-sequence} is appended to E, where +// hex-digit-sequence is the shortest hexadecimal representation of C using +// lower-case hexadecimal digits. +template +_LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) { + __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{")); +} + +// [format.string.escaped]/2.2.3 +// Otherwise (X is a sequence of ill-formed code units), each code unit U is +// appended to E in order as the sequence \x{hex-digit-sequence}, where +// hex-digit-sequence is the shortest hexadecimal representation of U using +// lower-case hexadecimal digits. +template +_LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) { + __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{")); +} + +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) { +# ifdef _LIBCPP_HAS_NO_UNICODE + // For ASCII assume everything above 127 is printable. + if (__value > 127) + return false; +# endif + + if (!__escaped_output_table::__needs_escape(__value)) + return false; + + __formatter::__write_well_formed_escaped_code_unit(__str, __value); + return true; +} + +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) { + return static_cast>(__value); +} + +enum class _LIBCPP_ENUM_VIS __escape_quotation_mark { __apostrophe, __double_quote }; + +// [format.string.escaped]/2 +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool +__is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value, __escape_quotation_mark __mark) { + // 2.2.1.1 - Mapped character in [tab:format.escape.sequences] + switch (__value) { + case _CharT('\t'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t"); + return true; + case _CharT('\n'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n"); + return true; + case _CharT('\r'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r"); + return true; + case _CharT('\''): + if (__mark == __escape_quotation_mark::__apostrophe) + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')"); + else + __str += __value; + return true; + case _CharT('"'): + if (__mark == __escape_quotation_mark::__double_quote) + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")"); + else + __str += __value; + return true; + case _CharT('\\'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)"); + return true; + + // 2.2.1.2 - Space + case _CharT(' '): + __str += __value; + return true; + } + + // 2.2.2 + // Otherwise, if X is a shift sequence, the effect on E and further + // decoding of S is unspecified. + // For now shift sequences are ignored and treated as Unicode. Other parts + // of the format library do the same. It's unknown how ostream treats them. + // TODO FMT determine what to do with shift sequences. + + // 2.2.1.2.1 and 2.2.1.2.2 - Escape + return __formatter::__is_escaped_sequence_written(__str, __formatter::__to_char32(__value)); +} + +template +_LIBCPP_HIDE_FROM_ABI void +__escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) { + __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()}; + + while (!__view.__at_end()) { + const _CharT* __first = __view.__position(); + typename __unicode::__consume_p2286_result __result = __view.__consume_p2286(); + if (__result.__ill_formed_size == 0) { + if (!__formatter::__is_escaped_sequence_written(__str, __result.__value, __mark)) + // 2.2.1.3 - Add the character + ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str)); + + } else { + // 2.2.3 sequence of ill-formed code units + // The number of code-units in __result.__value depends on the character type being used. + if constexpr (sizeof(_CharT) == 1) { + _LIBCPP_ASSERT(__result.__ill_formed_size == 1 || __result.__ill_formed_size == 4, + "illegal number of invalid code units."); + if (__result.__ill_formed_size == 1) // ill-formed, one code unit + __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xff); + else { // out of valid range, four code units + // The code point was properly encoded, decode the value. + __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value >> 18 | 0xf0); + __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 12 & 0x3f) | 0x80); + __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 6 & 0x3f) | 0x80); + __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value & 0x3f) | 0x80); + } + } else if constexpr (sizeof(_CharT) == 2) { + _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-16 at most one invalid code unit"); + __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xffff); + } else { + static_assert(sizeof(_CharT) == 4, "unsupported character width"); + _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-32 one code unit is one code point"); + __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value); + } + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_escaped_char(_CharT __value, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + basic_string<_CharT> __str; + __str += _CharT('\''); + __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe); + __str += _CharT('\''); + return __formatter::__write(__str.data(), __str.data() + __str.size(), _VSTD::move(__out_it), __specs, __str.size()); +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_escaped_string(basic_string_view<_CharT> __values, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + basic_string<_CharT> __str; + __str += _CharT('"'); + __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote); + __str += _CharT('"'); + return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs); +} + +# endif // _LIBCPP_STD_VER > 20 + +} // namespace __formatter + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_OUTPUT_H diff --git a/gnu/llvm/libcxx/include/__format/formatter_pointer.h b/gnu/llvm/libcxx/include/__format/formatter_pointer.h new file mode 100644 index 00000000000..31b49e17ab4 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter_pointer.h @@ -0,0 +1,73 @@ +// -*- 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___FORMAT_FORMATTER_POINTER_H +#define _LIBCPP___FORMAT_FORMATTER_POINTER_H + +#include <__availability> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_integral.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS __formatter_pointer { +public: + constexpr __formatter_pointer() { __parser_.__alignment_ = __format_spec::__alignment::__right; } + + _LIBCPP_HIDE_FROM_ABI constexpr auto + parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_pointer); + __format_spec::__process_display_type_pointer(__parser_.__type_); + return __result; + } + + _LIBCPP_HIDE_FROM_ABI auto format(const void* __ptr, auto& __ctx) const -> decltype(__ctx.out()) { + __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); + __specs.__std_.__alternate_form_ = true; + __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case; + return __formatter::__format_integer(reinterpret_cast(__ptr), __ctx, __specs); + } + + __format_spec::__parser<_CharT> __parser_; +}; + +// [format.formatter.spec]/2.4 +// For each charT, the pointer type specializations template<> +// - struct formatter; +// - template<> struct formatter; +// - template<> struct formatter; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_pointer<_CharT> {}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter : public __formatter_pointer<_CharT> { +}; +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_pointer<_CharT> {}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_POINTER_H diff --git a/gnu/llvm/libcxx/include/__format/formatter_string.h b/gnu/llvm/libcxx/include/__format/formatter_string.h new file mode 100644 index 00000000000..606fb792499 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter_string.h @@ -0,0 +1,159 @@ +// -*- 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___FORMAT_FORMATTER_STRING_H +#define _LIBCPP___FORMAT_FORMATTER_STRING_H + +#include <__availability> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__utility/move.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS __formatter_string { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) + -> decltype(__parse_ctx.begin()) { + auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_string); + __format_spec::__process_display_type_string(__parser_.__type_); + return __result; + } + + _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT> __str, auto& __ctx) const -> decltype(__ctx.out()) { +# if _LIBCPP_STD_VER > 20 + if (__parser_.__type_ == __format_spec::__type::__debug) + return __formatter::__format_escaped_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); +# endif + + return __formatter::__write_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; } +# endif + + __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left}; +}; + +// Formatter const char*. +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(const _CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) { + _LIBCPP_ASSERT(__str, "The basic_format_arg constructor should have " + "prevented an invalid pointer."); + + __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx); +# if _LIBCPP_STD_VER > 20 + if (_Base::__parser_.__type_ == __format_spec::__type::__debug) + return __formatter::__format_escaped_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); +# endif + + // When using a center or right alignment and the width option the length + // of __str must be known to add the padding upfront. This case is handled + // by the base class by converting the argument to a basic_string_view. + // + // When using left alignment and the width option the padding is added + // after outputting __str so the length can be determined while outputting + // __str. The same holds true for the precision, during outputting __str it + // can be validated whether the precision threshold has been reached. For + // now these optimizations aren't implemented. Instead the base class + // handles these options. + // TODO FMT Implement these improvements. + if (__specs.__has_width() || __specs.__has_precision()) + return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); + + // No formatting required, copy the string to the output. + auto __out_it = __ctx.out(); + while (*__str) + *__out_it++ = *__str++; + return __out_it; + } +}; + +// Formatter char*. +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT*, _CharT> + : public formatter { + using _Base = formatter; + + _LIBCPP_HIDE_FROM_ABI auto format(_CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) { + return _Base::format(__str, __ctx); + } +}; + +// Formatter char[]. +template <__fmt_char_type _CharT, size_t _Size> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT[_Size], _CharT> + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(_CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) { + return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx); + } +}; + +// Formatter const char[]. +template <__fmt_char_type _CharT, size_t _Size> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(const _CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) { + return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx); + } +}; + +// Formatter std::string. +template <__fmt_char_type _CharT, class _Traits, class _Allocator> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(const basic_string<_CharT, _Traits, _Allocator>& __str, auto& __ctx) const + -> decltype(__ctx.out()) { + // Drop _Traits and _Allocator to have one std::basic_string formatter. + return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx); + } +}; + +// Formatter std::string_view. +template <__fmt_char_type _CharT, class _Traits> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_string<_CharT> { + using _Base = __formatter_string<_CharT>; + + _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT, _Traits> __str, auto& __ctx) const + -> decltype(__ctx.out()) { + // Drop _Traits to have one std::basic_string_view formatter. + return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx); + } +}; + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_STRING_H diff --git a/gnu/llvm/libcxx/include/__format/formatter_tuple.h b/gnu/llvm/libcxx/include/__format/formatter_tuple.h new file mode 100644 index 00000000000..82f5ada6e01 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/formatter_tuple.h @@ -0,0 +1,178 @@ +// -*- 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___FORMAT_FORMATTER_TUPLE_H +#define _LIBCPP___FORMAT_FORMATTER_TUPLE_H + +#include <__algorithm/ranges_copy.h> +#include <__availability> +#include <__chrono/statically_widen.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/format_args.h> +#include <__format/format_context.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/formatter.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__iterator/back_insert_iterator.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/integer_sequence.h> +#include <__utility/pair.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +template <__fmt_char_type _CharT, class _Tuple, formattable<_CharT>... _Args> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple { + _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) { + __separator_ = __separator; + } + _LIBCPP_HIDE_FROM_ABI constexpr void + set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) { + __opening_bracket_ = __opening_bracket; + __closing_bracket_ = __closing_bracket; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) { + const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_tuple); + + // [format.tuple]/7 + // ... For each element e in underlying_, if e.set_debug_format() + // is a valid expression, calls e.set_debug_format(). + // TODO FMT this can be removed when P2733 is accepted. + std::__for_each_index_sequence(make_index_sequence(), [&] { + std::__set_debug_format(std::get<_Index>(__underlying_)); + }); + + const _CharT* __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + if (*__begin == _CharT('m')) { + if constexpr (sizeof...(_Args) == 2) { + set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": ")); + set_brackets({}, {}); + ++__begin; + } else + std::__throw_format_error("The format specifier m requires a pair or a two-element tuple"); + } else if (*__begin == _CharT('n')) { + set_brackets({}, {}); + ++__begin; + } + + if (__begin != __end && *__begin != _CharT('}')) + std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + template + typename _FormatContext::iterator _LIBCPP_HIDE_FROM_ABI + format(conditional_t<(formattable && ...), const _Tuple&, _Tuple&> __tuple, + _FormatContext& __ctx) const { + __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); + + if (!__specs.__has_width()) + return __format_tuple(__tuple, __ctx); + + basic_string<_CharT> __str; + + // Since the output is written to a different iterator a new context is + // created. Since the underlying formatter uses the default formatting it + // doesn't need a locale or the formatting arguments. So creating a new + // context works. + // + // This solution works for this formatter, but it will not work for the + // range_formatter. In that patch a generic solution is work in progress. + // Once that is finished it can be used here. (The range_formatter will use + // these features so it's easier to add it there and then port it.) + // + // TODO FMT Use formatting wrapping used in the range_formatter. + basic_format_context __c = std::__format_context_create( + back_insert_iterator{__str}, + basic_format_args>, _CharT>>{}); + + __format_tuple(__tuple, __c); + + return __formatter::__write_string_no_precision(basic_string_view{__str}, __ctx.out(), __specs); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_tuple(auto&& __tuple, _FormatContext& __ctx) const { + __ctx.advance_to(std::ranges::copy(__opening_bracket_, __ctx.out()).out); + + std::__for_each_index_sequence(make_index_sequence(), [&] { + if constexpr (_Index) + __ctx.advance_to(std::ranges::copy(__separator_, __ctx.out()).out); + + // During review Victor suggested to make the exposition only + // __underlying_ member a local variable. Currently the Standard + // requires nested debug-enabled formatter specializations not to + // output escaped output. P2733 fixes that bug, once accepted the + // code below can be used. + // (Note when a paper allows parsing a tuple-underlying-spec the + // exposition only member needs to be a class member. Earlier + // revisions of P2286 proposed that, but this was not pursued, + // due to time constrains and complexity of the matter.) + // TODO FMT This can be updated after P2733 is accepted. +# if 0 + // P2286 uses an exposition only member in the formatter + // tuple, _CharT>...> __underlying_; + // This was used in earlier versions of the paper since + // __underlying_.parse(...) was called. This is no longer the case + // so we can reduce the scope of the formatter. + // + // It does require the underlying's parse effect to be moved here too. + using _Arg = tuple_element<_Index, decltype(__tuple)>; + formatter, _CharT> __underlying; + + // [format.tuple]/7 + // ... For each element e in underlying_, if e.set_debug_format() + // is a valid expression, calls e.set_debug_format(). + std::__set_debug_format(__underlying); +# else + __ctx.advance_to(std::get<_Index>(__underlying_).format(std::get<_Index>(__tuple), __ctx)); +# endif + }); + + return std::ranges::copy(__closing_bracket_, __ctx.out()).out; + } + + __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left}; + +private: + tuple, _CharT>...> __underlying_; + basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", "); + basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "("); + basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ")"); +}; + +template <__fmt_char_type _CharT, formattable<_CharT>... _Args> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_tuple<_CharT, pair<_Args...>, _Args...> {}; + +template <__fmt_char_type _CharT, formattable<_CharT>... _Args> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter, _CharT> + : public __formatter_tuple<_CharT, tuple<_Args...>, _Args...> {}; + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_FORMATTER_TUPLE_H diff --git a/gnu/llvm/libcxx/include/__format/parser_std_format_spec.h b/gnu/llvm/libcxx/include/__format/parser_std_format_spec.h new file mode 100644 index 00000000000..c03cec97963 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/parser_std_format_spec.h @@ -0,0 +1,954 @@ +// -*- 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___FORMAT_PARSER_STD_FORMAT_SPEC_H +#define _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H + +/// \file Contains the std-format-spec parser. +/// +/// Most of the code can be reused in the chrono-format-spec. +/// This header has some support for the chrono-format-spec since it doesn't +/// affect the std-format-spec. + +#include <__algorithm/find_if.h> +#include <__algorithm/min.h> +#include <__assert> +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__debug> +#include <__format/format_arg.h> +#include <__format/format_error.h> +#include <__format/format_parse_context.h> +#include <__format/format_string.h> +#include <__format/unicode.h> +#include <__variant/monostate.h> +#include +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __format_spec { + +template +_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT> +__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { + // This function is a wrapper to call the real parser. But it does the + // validation for the pre-conditions and post-conditions. + if (__begin == __end) + std::__throw_format_error("End of input while parsing format-spec arg-id"); + + __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); + + if (__r.__ptr == __end || *__r.__ptr != _CharT('}')) + std::__throw_format_error("Invalid arg-id"); + + ++__r.__ptr; + return __r; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr uint32_t +__substitute_arg_id(basic_format_arg<_Context> __format_arg) { + // [format.string.std]/8 + // If the corresponding formatting argument is not of integral type... + // This wording allows char and bool too. LWG-3720 changes the wording to + // If the corresponding formatting argument is not of standard signed or + // unsigned integer type, + // This means the 128-bit will not be valid anymore. + // TODO FMT Verify this resolution is accepted and add a test to verify + // 128-bit integrals fail and switch to visit_format_arg. + return _VSTD::__visit_format_arg( + [](auto __arg) -> uint32_t { + using _Type = decltype(__arg); + if constexpr (integral<_Type>) { + if constexpr (signed_integral<_Type>) { + if (__arg < 0) + std::__throw_format_error("A format-spec arg-id replacement shouldn't have a negative value"); + } + + using _CT = common_type_t<_Type, decltype(__format::__number_max)>; + if (static_cast<_CT>(__arg) > + static_cast<_CT>(__format::__number_max)) + std::__throw_format_error("A format-spec arg-id replacement exceeds the maximum supported value"); + + return __arg; + } else if constexpr (same_as<_Type, monostate>) + std::__throw_format_error("Argument index out of bounds"); + else + std::__throw_format_error("A format-spec arg-id replacement argument isn't an integral type"); + }, + __format_arg); +} + +/// These fields are a filter for which elements to parse. +/// +/// They default to false so when a new field is added it needs to be opted in +/// explicitly. +// TODO FMT Use an ABI tag for this struct. +struct __fields { + uint8_t __sign_ : 1 {false}; + uint8_t __alternate_form_ : 1 {false}; + uint8_t __zero_padding_ : 1 {false}; + uint8_t __precision_ : 1 {false}; + uint8_t __locale_specific_form_ : 1 {false}; + uint8_t __type_ : 1 {false}; + // Determines the valid values for fill. + // + // Originally the fill could be any character except { and }. Range-based + // formatters use the colon to mark the beginning of the + // underlying-format-spec. To avoid parsing ambiguities these formatter + // specializations prohibit the use of the colon as a fill character. + uint8_t __allow_colon_in_fill_ : 1 {false}; +}; + +// By not placing this constant in the formatter class it's not duplicated for +// char and wchar_t. +inline constexpr __fields __fields_integral{ + .__sign_ = true, + .__alternate_form_ = true, + .__zero_padding_ = true, + .__locale_specific_form_ = true, + .__type_ = true}; +inline constexpr __fields __fields_floating_point{ + .__sign_ = true, + .__alternate_form_ = true, + .__zero_padding_ = true, + .__precision_ = true, + .__locale_specific_form_ = true, + .__type_ = true}; +inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true}; +inline constexpr __fields __fields_pointer{.__type_ = true}; + +# if _LIBCPP_STD_VER > 20 +inline constexpr __fields __fields_tuple{.__type_ = false, .__allow_colon_in_fill_ = true}; +inline constexpr __fields __fields_range{.__type_ = false, .__allow_colon_in_fill_ = true}; +# endif + +enum class _LIBCPP_ENUM_VIS __alignment : uint8_t { + /// No alignment is set in the format string. + __default, + __left, + __center, + __right, + __zero_padding +}; + +enum class _LIBCPP_ENUM_VIS __sign : uint8_t { + /// No sign is set in the format string. + /// + /// The sign isn't allowed for certain format-types. By using this value + /// it's possible to detect whether or not the user explicitly set the sign + /// flag. For formatting purposes it behaves the same as \ref __minus. + __default, + __minus, + __plus, + __space +}; + +enum class _LIBCPP_ENUM_VIS __type : uint8_t { + __default, + __string, + __binary_lower_case, + __binary_upper_case, + __octal, + __decimal, + __hexadecimal_lower_case, + __hexadecimal_upper_case, + __pointer, + __char, + __hexfloat_lower_case, + __hexfloat_upper_case, + __scientific_lower_case, + __scientific_upper_case, + __fixed_lower_case, + __fixed_upper_case, + __general_lower_case, + __general_upper_case, + __debug +}; + +struct __std { + __alignment __alignment_ : 3; + __sign __sign_ : 2; + bool __alternate_form_ : 1; + bool __locale_specific_form_ : 1; + __type __type_; +}; + +struct __chrono { + __alignment __alignment_ : 3; + bool __locale_specific_form_ : 1; + bool __weekday_name_ : 1; + bool __weekday_ : 1; + bool __day_of_year_ : 1; + bool __week_of_year_ : 1; + bool __month_name_ : 1; +}; + +/// Contains the parsed formatting specifications. +/// +/// This contains information for both the std-format-spec and the +/// chrono-format-spec. This results in some unused members for both +/// specifications. However these unused members don't increase the size +/// of the structure. +/// +/// This struct doesn't cross ABI boundaries so its layout doesn't need to be +/// kept stable. +template +struct __parsed_specifications { + union { + // The field __alignment_ is the first element in __std_ and __chrono_. + // This allows the code to always inspect this value regards which member + // of the union is the active member [class.union.general]/2. + // + // This is needed since the generic output routines handle the alignment of + // the output. + __alignment __alignment_ : 3; + __std __std_; + __chrono __chrono_; + }; + + /// The requested width. + /// + /// When the format-spec used an arg-id for this field it has already been + /// replaced with the value of that arg-id. + int32_t __width_; + + /// The requested precision. + /// + /// When the format-spec used an arg-id for this field it has already been + /// replaced with the value of that arg-id. + int32_t __precision_; + + _CharT __fill_; + + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_width() const { return __width_ > 0; } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_precision() const { return __precision_ >= 0; } +}; + +// Validate the struct is small and cheap to copy since the struct is passed by +// value in formatting functions. +static_assert(sizeof(__parsed_specifications) == 16); +static_assert(is_trivially_copyable_v<__parsed_specifications>); +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +static_assert(sizeof(__parsed_specifications) == 16); +static_assert(is_trivially_copyable_v<__parsed_specifications>); +# endif + +/// The parser for the std-format-spec. +/// +/// Note this class is a member of std::formatter specializations. It's +/// expected developers will create their own formatter specializations that +/// inherit from the std::formatter specializations. This means this class +/// must be ABI stable. To aid the stability the unused bits in the class are +/// set to zero. That way they can be repurposed if a future revision of the +/// Standards adds new fields to std-format-spec. +template +class _LIBCPP_TEMPLATE_VIS __parser { +public: + _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields) + -> decltype(__parse_ctx.begin()) { + + const _CharT* __begin = __parse_ctx.begin(); + const _CharT* __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + if (__parse_fill_align(__begin, __end, __fields.__allow_colon_in_fill_) && __begin == __end) + return __begin; + + if (__fields.__sign_ && __parse_sign(__begin) && __begin == __end) + return __begin; + + if (__fields.__alternate_form_ && __parse_alternate_form(__begin) && __begin == __end) + return __begin; + + if (__fields.__zero_padding_ && __parse_zero_padding(__begin) && __begin == __end) + return __begin; + + if (__parse_width(__begin, __end, __parse_ctx) && __begin == __end) + return __begin; + + if (__fields.__precision_ && __parse_precision(__begin, __end, __parse_ctx) && __begin == __end) + return __begin; + + if (__fields.__locale_specific_form_ && __parse_locale_specific_form(__begin) && __begin == __end) + return __begin; + + if (__fields.__type_) { + __parse_type(__begin); + + // When __type_ is false the calling parser is expected to do additional + // parsing. In that case that parser should do the end of format string + // validation. + if (__begin != __end && *__begin != _CharT('}')) + std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + } + + return __begin; + } + + /// \returns the `__parsed_specifications` with the resolved dynamic sizes.. + _LIBCPP_HIDE_FROM_ABI + __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const { + return __parsed_specifications<_CharT>{ + .__std_ = __std{.__alignment_ = __alignment_, + .__sign_ = __sign_, + .__alternate_form_ = __alternate_form_, + .__locale_specific_form_ = __locale_specific_form_, + .__type_ = __type_}, + .__width_{__get_width(__ctx)}, + .__precision_{__get_precision(__ctx)}, + .__fill_{__fill_}}; + } + + _LIBCPP_HIDE_FROM_ABI __parsed_specifications<_CharT> __get_parsed_chrono_specifications(auto& __ctx) const { + return __parsed_specifications<_CharT>{ + .__chrono_ = + __chrono{.__alignment_ = __alignment_, + .__locale_specific_form_ = __locale_specific_form_, + .__weekday_name_ = __weekday_name_, + .__weekday_ = __weekday_, + .__day_of_year_ = __day_of_year_, + .__week_of_year_ = __week_of_year_, + .__month_name_ = __month_name_}, + .__width_{__get_width(__ctx)}, + .__precision_{__get_precision(__ctx)}, + .__fill_{__fill_}}; + } + + __alignment __alignment_ : 3 {__alignment::__default}; + __sign __sign_ : 2 {__sign::__default}; + bool __alternate_form_ : 1 {false}; + bool __locale_specific_form_ : 1 {false}; + bool __reserved_0_ : 1 {false}; + __type __type_{__type::__default}; + + // These flags are only used for formatting chrono. Since the struct has + // padding space left it's added to this structure. + bool __weekday_name_ : 1 {false}; + bool __weekday_ : 1 {false}; + + bool __day_of_year_ : 1 {false}; + bool __week_of_year_ : 1 {false}; + + bool __month_name_ : 1 {false}; + + uint8_t __reserved_1_ : 3 {0}; + uint8_t __reserved_2_ : 6 {0}; + // These two flags are only used internally and not part of the + // __parsed_specifications. Therefore put them at the end. + bool __width_as_arg_ : 1 {false}; + bool __precision_as_arg_ : 1 {false}; + + /// The requested width, either the value or the arg-id. + int32_t __width_{0}; + + /// The requested precision, either the value or the arg-id. + int32_t __precision_{-1}; + + // LWG 3576 will probably change this to always accept a Unicode code point + // To avoid changing the size with that change align the field so when it + // becomes 32-bit its alignment will remain the same. That also means the + // size will remain the same. (D2572 addresses the solution for LWG 3576.) + _CharT __fill_{_CharT(' ')}; + +private: + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alignment(_CharT __c) { + switch (__c) { + case _CharT('<'): + __alignment_ = __alignment::__left; + return true; + + case _CharT('^'): + __alignment_ = __alignment::__center; + return true; + + case _CharT('>'): + __alignment_ = __alignment::__right; + return true; + } + return false; + } + + // range-fill and tuple-fill are identical + _LIBCPP_HIDE_FROM_ABI constexpr bool + __parse_fill_align(const _CharT*& __begin, const _CharT* __end, bool __use_range_fill) { + _LIBCPP_ASSERT(__begin != __end, "when called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); + if (__begin + 1 != __end) { + if (__parse_alignment(*(__begin + 1))) { + if (__use_range_fill && (*__begin == _CharT('{') || *__begin == _CharT('}') || *__begin == _CharT(':'))) + std::__throw_format_error("The format-spec range-fill field contains an invalid character"); + else if (*__begin == _CharT('{') || *__begin == _CharT('}')) + std::__throw_format_error("The format-spec fill field contains an invalid character"); + + __fill_ = *__begin; + __begin += 2; + return true; + } + } + + if (!__parse_alignment(*__begin)) + return false; + + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(const _CharT*& __begin) { + switch (*__begin) { + case _CharT('-'): + __sign_ = __sign::__minus; + break; + case _CharT('+'): + __sign_ = __sign::__plus; + break; + case _CharT(' '): + __sign_ = __sign::__space; + break; + default: + return false; + } + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(const _CharT*& __begin) { + if (*__begin != _CharT('#')) + return false; + + __alternate_form_ = true; + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(const _CharT*& __begin) { + if (*__begin != _CharT('0')) + return false; + + if (__alignment_ == __alignment::__default) + __alignment_ = __alignment::__zero_padding; + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(const _CharT*& __begin, const _CharT* __end, auto& __parse_ctx) { + if (*__begin == _CharT('0')) + std::__throw_format_error("A format-spec width field shouldn't have a leading zero"); + + if (*__begin == _CharT('{')) { + __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); + __width_as_arg_ = true; + __width_ = __r.__value; + __begin = __r.__ptr; + return true; + } + + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + return false; + + __format::__parse_number_result __r = __format::__parse_number(__begin, __end); + __width_ = __r.__value; + _LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, " + "due to validations in this function"); + __begin = __r.__ptr; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(const _CharT*& __begin, const _CharT* __end, + auto& __parse_ctx) { + if (*__begin != _CharT('.')) + return false; + + ++__begin; + if (__begin == __end) + std::__throw_format_error("End of input while parsing format-spec precision"); + + if (*__begin == _CharT('{')) { + __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); + __precision_as_arg_ = true; + __precision_ = __arg_id.__value; + __begin = __arg_id.__ptr; + return true; + } + + if (*__begin < _CharT('0') || *__begin > _CharT('9')) + std::__throw_format_error("The format-spec precision field doesn't contain a value or arg-id"); + + __format::__parse_number_result __r = __format::__parse_number(__begin, __end); + __precision_ = __r.__value; + __precision_as_arg_ = false; + __begin = __r.__ptr; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(const _CharT*& __begin) { + if (*__begin != _CharT('L')) + return false; + + __locale_specific_form_ = true; + ++__begin; + return true; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin) { + // Determines the type. It does not validate whether the selected type is + // valid. Most formatters have optional fields that are only allowed for + // certain types. These parsers need to do validation after the type has + // been parsed. So its easier to implement the validation for all types in + // the specific parse function. + switch (*__begin) { + case 'A': + __type_ = __type::__hexfloat_upper_case; + break; + case 'B': + __type_ = __type::__binary_upper_case; + break; + case 'E': + __type_ = __type::__scientific_upper_case; + break; + case 'F': + __type_ = __type::__fixed_upper_case; + break; + case 'G': + __type_ = __type::__general_upper_case; + break; + case 'X': + __type_ = __type::__hexadecimal_upper_case; + break; + case 'a': + __type_ = __type::__hexfloat_lower_case; + break; + case 'b': + __type_ = __type::__binary_lower_case; + break; + case 'c': + __type_ = __type::__char; + break; + case 'd': + __type_ = __type::__decimal; + break; + case 'e': + __type_ = __type::__scientific_lower_case; + break; + case 'f': + __type_ = __type::__fixed_lower_case; + break; + case 'g': + __type_ = __type::__general_lower_case; + break; + case 'o': + __type_ = __type::__octal; + break; + case 'p': + __type_ = __type::__pointer; + break; + case 's': + __type_ = __type::__string; + break; + case 'x': + __type_ = __type::__hexadecimal_lower_case; + break; +# if _LIBCPP_STD_VER > 20 + case '?': + __type_ = __type::__debug; + break; +# endif + default: + return; + } + ++__begin; + } + + _LIBCPP_HIDE_FROM_ABI + int32_t __get_width(auto& __ctx) const { + if (!__width_as_arg_) + return __width_; + + return __format_spec::__substitute_arg_id(__ctx.arg(__width_)); + } + + _LIBCPP_HIDE_FROM_ABI + int32_t __get_precision(auto& __ctx) const { + if (!__precision_as_arg_) + return __precision_; + + return __format_spec::__substitute_arg_id(__ctx.arg(__precision_)); + } +}; + +// Validates whether the reserved bitfields don't change the size. +static_assert(sizeof(__parser) == 16); +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +static_assert(sizeof(__parser) == 16); +# endif + +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_string(__format_spec::__type __type) { + switch (__type) { + case __format_spec::__type::__default: + case __format_spec::__type::__string: + case __format_spec::__type::__debug: + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a string argument"); + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser) { + if (__parser.__sign_ != __sign::__default) + std::__throw_format_error("A sign field isn't allowed in this format-spec"); + + if (__parser.__alternate_form_) + std::__throw_format_error("An alternate form field isn't allowed in this format-spec"); + + if (__parser.__alignment_ == __alignment::__zero_padding) + std::__throw_format_error("A zero-padding field isn't allowed in this format-spec"); + + if (__parser.__alignment_ == __alignment::__default) + __parser.__alignment_ = __alignment::__left; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser) { + __format_spec::__process_display_type_bool_string(__parser); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser) { + switch (__parser.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__string: + __format_spec::__process_display_type_bool_string(__parser); + break; + + case __format_spec::__type::__binary_lower_case: + case __format_spec::__type::__binary_upper_case: + case __format_spec::__type::__octal: + case __format_spec::__type::__decimal: + case __format_spec::__type::__hexadecimal_lower_case: + case __format_spec::__type::__hexadecimal_upper_case: + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a bool argument"); + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser) { + switch (__parser.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__char: + case __format_spec::__type::__debug: + __format_spec::__process_display_type_char(__parser); + break; + + case __format_spec::__type::__binary_lower_case: + case __format_spec::__type::__binary_upper_case: + case __format_spec::__type::__octal: + case __format_spec::__type::__decimal: + case __format_spec::__type::__hexadecimal_lower_case: + case __format_spec::__type::__hexadecimal_upper_case: + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a char argument"); + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser) { + switch (__parser.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__binary_lower_case: + case __format_spec::__type::__binary_upper_case: + case __format_spec::__type::__octal: + case __format_spec::__type::__decimal: + case __format_spec::__type::__hexadecimal_lower_case: + case __format_spec::__type::__hexadecimal_upper_case: + break; + + case __format_spec::__type::__char: + __format_spec::__process_display_type_char(__parser); + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for an integer argument"); + } +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser) { + switch (__parser.__type_) { + case __format_spec::__type::__default: + case __format_spec::__type::__hexfloat_lower_case: + case __format_spec::__type::__hexfloat_upper_case: + // Precision specific behavior will be handled later. + break; + case __format_spec::__type::__scientific_lower_case: + case __format_spec::__type::__scientific_upper_case: + case __format_spec::__type::__fixed_lower_case: + case __format_spec::__type::__fixed_upper_case: + case __format_spec::__type::__general_lower_case: + case __format_spec::__type::__general_upper_case: + if (!__parser.__precision_as_arg_ && __parser.__precision_ == -1) + // Set the default precision for the call to to_chars. + __parser.__precision_ = 6; + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a floating-point argument"); + } +} + +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type) { + switch (__type) { + case __format_spec::__type::__default: + case __format_spec::__type::__pointer: + break; + + default: + std::__throw_format_error("The format-spec type has a type not supported for a pointer argument"); + } +} + +template +struct __column_width_result { + /// The number of output columns. + size_t __width_; + /// One beyond the last code unit used in the estimation. + /// + /// This limits the original output to fit in the wanted number of columns. + const _CharT* __last_; +}; + +template +__column_width_result(size_t, const _CharT*) -> __column_width_result<_CharT>; + +/// Since a column width can be two it's possible that the requested column +/// width can't be achieved. Depending on the intended usage the policy can be +/// selected. +/// - When used as precision the maximum width may not be exceeded and the +/// result should be "rounded down" to the previous boundary. +/// - When used as a width we're done once the minimum is reached, but +/// exceeding is not an issue. Rounding down is an issue since that will +/// result in writing fill characters. Therefore the result needs to be +/// "rounded up". +enum class __column_width_rounding { __down, __up }; + +# ifndef _LIBCPP_HAS_NO_UNICODE + +namespace __detail { + +/// Converts a code point to the column width. +/// +/// The estimations are conforming to [format.string.general]/11 +/// +/// This version expects a value less than 0x1'0000, which is a 3-byte UTF-8 +/// character. +_LIBCPP_HIDE_FROM_ABI constexpr int __column_width_3(uint32_t __c) noexcept { + _LIBCPP_ASSERT(__c < 0x10000, "Use __column_width_4 or __column_width for larger values"); + + // clang-format off + return 1 + (__c >= 0x1100 && (__c <= 0x115f || + (__c >= 0x2329 && (__c <= 0x232a || + (__c >= 0x2e80 && (__c <= 0x303e || + (__c >= 0x3040 && (__c <= 0xa4cf || + (__c >= 0xac00 && (__c <= 0xd7a3 || + (__c >= 0xf900 && (__c <= 0xfaff || + (__c >= 0xfe10 && (__c <= 0xfe19 || + (__c >= 0xfe30 && (__c <= 0xfe6f || + (__c >= 0xff00 && (__c <= 0xff60 || + (__c >= 0xffe0 && (__c <= 0xffe6 + )))))))))))))))))))); + // clang-format on +} + +/// @overload +/// +/// This version expects a value greater than or equal to 0x1'0000, which is a +/// 4-byte UTF-8 character. +_LIBCPP_HIDE_FROM_ABI constexpr int __column_width_4(uint32_t __c) noexcept { + _LIBCPP_ASSERT(__c >= 0x10000, "Use __column_width_3 or __column_width for smaller values"); + + // clang-format off + return 1 + (__c >= 0x1'f300 && (__c <= 0x1'f64f || + (__c >= 0x1'f900 && (__c <= 0x1'f9ff || + (__c >= 0x2'0000 && (__c <= 0x2'fffd || + (__c >= 0x3'0000 && (__c <= 0x3'fffd + )))))))); + // clang-format on +} + +/// @overload +/// +/// The general case, accepting all values. +_LIBCPP_HIDE_FROM_ABI constexpr int __column_width(uint32_t __c) noexcept { + if (__c < 0x10000) + return __detail::__column_width_3(__c); + + return __detail::__column_width_4(__c); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width_grapheme_clustering( + const _CharT* __first, const _CharT* __last, size_t __maximum, __column_width_rounding __rounding) noexcept { + __unicode::__extended_grapheme_cluster_view<_CharT> __view{__first, __last}; + + __column_width_result<_CharT> __result{0, __first}; + while (__result.__last_ != __last && __result.__width_ <= __maximum) { + typename __unicode::__extended_grapheme_cluster_view<_CharT>::__cluster __cluster = __view.__consume(); + int __width = __detail::__column_width(__cluster.__code_point_); + + // When the next entry would exceed the maximum width the previous width + // might be returned. For example when a width of 100 is requested the + // returned width might be 99, since the next code point has an estimated + // column width of 2. This depends on the rounding flag. + // When the maximum is exceeded the loop will abort the next iteration. + if (__rounding == __column_width_rounding::__down && __result.__width_ + __width > __maximum) + return __result; + + __result.__width_ += __width; + __result.__last_ = __cluster.__last_; + } + + return __result; +} + +} // namespace __detail + +// Unicode can be stored in several formats: UTF-8, UTF-16, and UTF-32. +// Depending on format the relation between the number of code units stored and +// the number of output columns differs. The first relation is the number of +// code units forming a code point. (The text assumes the code units are +// unsigned.) +// - UTF-8 The number of code units is between one and four. The first 127 +// Unicode code points match the ASCII character set. When the highest bit is +// set it means the code point has more than one code unit. +// - UTF-16: The number of code units is between 1 and 2. When the first +// code unit is in the range [0xd800,0xdfff) it means the code point uses two +// code units. +// - UTF-32: The number of code units is always one. +// +// The code point to the number of columns is specified in +// [format.string.std]/11. This list might change in the future. +// +// Another thing to be taken into account is Grapheme clustering. This means +// that in some cases multiple code points are combined one element in the +// output. For example: +// - an ASCII character with a combined diacritical mark +// - an emoji with a skin tone modifier +// - a group of combined people emoji to create a family +// - a combination of flag emoji +// +// See also: +// - [format.string.general]/11 +// - https://en.wikipedia.org/wiki/UTF-8#Encoding +// - https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF + +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_ascii(char32_t __c) { return __c < 0x80; } + +/// Determines the number of output columns needed to render the input. +/// +/// \note When the scanner encounters malformed Unicode it acts as-if every +/// code unit is a one column code point. Typically a terminal uses the same +/// strategy and replaces every malformed code unit with a one column +/// replacement character. +/// +/// \param __first Points to the first element of the input range. +/// \param __last Points beyond the last element of the input range. +/// \param __maximum The maximum number of output columns. The returned number +/// of estimated output columns will not exceed this value. +/// \param __rounding Selects the rounding method. +/// \c __down result.__width_ <= __maximum +/// \c __up result.__width_ <= __maximum + 1 +template +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width( + basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding __rounding) noexcept { + // The width estimation is done in two steps: + // - Quickly process for the ASCII part. ASCII has the following properties + // - One code unit is one code point + // - Every code point has an estimated width of one + // - When needed it will a Unicode Grapheme clustering algorithm to find + // the proper place for truncation. + + if (__str.empty() || __maximum == 0) + return {0, __str.begin()}; + + // ASCII has one caveat; when an ASCII character is followed by a non-ASCII + // character they might be part of an extended grapheme cluster. For example: + // an ASCII letter and a COMBINING ACUTE ACCENT + // The truncate should happen after the COMBINING ACUTE ACCENT. Therefore we + // need to scan one code unit beyond the requested precision. When this code + // unit is non-ASCII we omit the current code unit and let the Grapheme + // clustering algorithm do its work. + const _CharT* __it = __str.begin(); + if (__format_spec::__is_ascii(*__it)) { + do { + --__maximum; + ++__it; + if (__it == __str.end()) + return {__str.size(), __str.end()}; + + if (__maximum == 0) { + if (__format_spec::__is_ascii(*__it)) + return {static_cast(__it - __str.begin()), __it}; + + break; + } + } while (__format_spec::__is_ascii(*__it)); + --__it; + ++__maximum; + } + + ptrdiff_t __ascii_size = __it - __str.begin(); + __column_width_result __result = + __detail::__estimate_column_width_grapheme_clustering(__it, __str.end(), __maximum, __rounding); + + __result.__width_ += __ascii_size; + return __result; +} +# else // !defined(_LIBCPP_HAS_NO_UNICODE) +template +_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> +__estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding) noexcept { + // When Unicode isn't supported assume ASCII and every code unit is one code + // point. In ASCII the estimated column width is always one. Thus there's no + // need for rounding. + size_t __width_ = _VSTD::min(__str.size(), __maximum); + return {__width_, __str.begin() + __width_}; +} + +# endif // !defined(_LIBCPP_HAS_NO_UNICODE) + +} // namespace __format_spec + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H diff --git a/gnu/llvm/libcxx/include/__format/range_default_formatter.h b/gnu/llvm/libcxx/include/__format/range_default_formatter.h new file mode 100644 index 00000000000..774887b0530 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/range_default_formatter.h @@ -0,0 +1,201 @@ +// -*- 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___FORMAT_RANGE_DEFAULT_FORMATTER_H +#define _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__availability> +#include <__chrono/statically_widen.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/concepts.h> +#include <__format/formatter.h> +#include <__format/range_formatter.h> +#include <__ranges/concepts.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/pair.h> +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +template +concept __const_formattable_range = + ranges::input_range && formattable, _CharT>; + +template +using __fmt_maybe_const = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>; + +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow") +_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow") +// This shadows map, set, and string. +enum class range_format { disabled, map, set, sequence, string, debug_string }; +_LIBCPP_DIAGNOSTIC_POP + +// There is no definition of this struct, it's purely intended to be used to +// generate diagnostics. +template +struct _LIBCPP_TEMPLATE_VIS __instantiated_the_primary_template_of_format_kind; + +template +constexpr range_format format_kind = [] { + // [format.range.fmtkind]/1 + // A program that instantiates the primary template of format_kind is ill-formed. + static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type"); + return range_format::disabled; +}(); + +template + requires same_as<_Rp, remove_cvref_t<_Rp>> +inline constexpr range_format format_kind<_Rp> = [] { + // [format.range.fmtkind]/2 + + // 2.1 If same_as>, R> is true, + // Otherwise format_kind is range_format::disabled. + if constexpr (same_as>, _Rp>) + return range_format::disabled; + // 2.2 Otherwise, if the qualified-id R::key_type is valid and denotes a type: + else if constexpr (requires { typename _Rp::key_type; }) { + // 2.2.1 If the qualified-id R::mapped_type is valid and denotes a type ... + if constexpr (requires { typename _Rp::mapped_type; } && + // 2.2.1 ... If either U is a specialization of pair or U is a specialization + // of tuple and tuple_size_v == 2 + __fmt_pair_like>>) + return range_format::map; + else + // 2.2.2 Otherwise format_kind is range_format::set. + return range_format::set; + } else + // 2.3 Otherwise, format_kind is range_format::sequence. + return range_format::sequence; +}(); + +// This is a non-standard work-around to fix instantiation of +// formatter +// const _CharT[N] satisfies the ranges::input_range concept. +// remove_cvref_t is _CharT[N] so it does not satisfy the +// requirement of the above specialization. Instead it will instantiate the +// primary template, which is ill-formed. +// +// An alternative solution is to remove the offending formatter. +// +// https://godbolt.org/z/bqjhhaexx +// +// The removal is proposed in LWG3833, but use the work-around until the issue +// has been adopted. +// TODO FMT Implement LWG3833. +template +inline constexpr range_format format_kind = range_format::disabled; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter; + +// Required specializations + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter { +private: + using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>; + range_formatter>, _CharT> __underlying_; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) { + __underlying_.set_separator(__separator); + } + _LIBCPP_HIDE_FROM_ABI constexpr void + set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) { + __underlying_.set_brackets(__opening_bracket, __closing_bracket); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return __underlying_.parse(__ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename FormatContext::iterator format(__maybe_const_r& __range, FormatContext& __ctx) const { + return __underlying_.format(__range, __ctx); + } +}; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter { +private: + using __maybe_const_map = __fmt_maybe_const<_Rp, _CharT>; + using __element_type = remove_cvref_t>; + range_formatter<__element_type, _CharT> __underlying_; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter() + requires(__fmt_pair_like<__element_type>) + { + __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}")); + __underlying_.underlying().set_brackets({}, {}); + __underlying_.underlying().set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": ")); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return __underlying_.parse(__ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + format(__maybe_const_map& __range, _FormatContext& __ctx) const { + return __underlying_.format(__range, __ctx); + } +}; + +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter { +private: + using __maybe_const_set = __fmt_maybe_const<_Rp, _CharT>; + using __element_type = remove_cvref_t>; + range_formatter<__element_type, _CharT> __underlying_; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter() { + __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}")); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return __underlying_.parse(__ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + format(__maybe_const_set& __range, _FormatContext& __ctx) const { + return __underlying_.format(__range, __ctx); + } +}; + +template + requires(_Kp == range_format::string || _Kp == range_format::debug_string) +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<_Kp, _Rp, _CharT> { + __range_default_formatter() = delete; // TODO FMT Implement +}; + +template + requires(format_kind<_Rp> != range_format::disabled && formattable, _CharT>) +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Rp, _CharT> + : __range_default_formatter, _Rp, _CharT> {}; + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H diff --git a/gnu/llvm/libcxx/include/__format/range_formatter.h b/gnu/llvm/libcxx/include/__format/range_formatter.h new file mode 100644 index 00000000000..9ea61a70350 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/range_formatter.h @@ -0,0 +1,255 @@ +// -*- 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___FORMAT_RANGE_FORMATTER_H +#define _LIBCPP___FORMAT_RANGE_FORMATTER_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__algorithm/ranges_copy.h> +#include <__availability> +#include <__chrono/statically_widen.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__format/buffer.h> +#include <__format/concepts.h> +#include <__format/format_args.h> +#include <__format/format_context.h> +#include <__format/format_error.h> +#include <__format/formatter.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__iterator/back_insert_iterator.h> +#include <__ranges/concepts.h> +#include <__ranges/data.h> +#include <__ranges/size.h> +#include <__type_traits/remove_cvref.h> +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 20 + +template + requires same_as, _Tp> && formattable<_Tp, _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter { + _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) { + __separator_ = __separator; + } + _LIBCPP_HIDE_FROM_ABI constexpr void + set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) { + __opening_bracket_ = __opening_bracket; + __closing_bracket_ = __closing_bracket; + } + + _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() { return __underlying_; } + _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const { return __underlying_; } + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) { + const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_range); + const _CharT* __end = __parse_ctx.end(); + if (__begin == __end) + return __begin; + + // The n field overrides a possible m type, therefore delay applying the + // effect of n until the type has been procesed. + bool __clear_brackets = (*__begin == _CharT('n')); + if (__clear_brackets) { + ++__begin; + if (__begin == __end) { + // Since there is no more data, clear the brackets before returning. + set_brackets({}, {}); + return __begin; + } + } + + __parse_type(__begin, __end); + if (__clear_brackets) + set_brackets({}, {}); + if (__begin == __end) + return __begin; + + bool __has_range_underlying_spec = *__begin == _CharT(':'); + if (__parser_.__type_ != __format_spec::__type::__default) { + // [format.range.formatter]/6 + // If the range-type is s or ?s, then there shall be no n option and no + // range-underlying-spec. + if (__clear_brackets) { + if (__parser_.__type_ == __format_spec::__type::__string) + std::__throw_format_error("The n option and type s can't be used together"); + std::__throw_format_error("The n option and type ?s can't be used together"); + } + if (__has_range_underlying_spec) { + if (__parser_.__type_ == __format_spec::__type::__string) + std::__throw_format_error("Type s and an underlying format specification can't be used together"); + std::__throw_format_error("Type ?s and an underlying format specification can't be used together"); + } + } else if (!__has_range_underlying_spec) + std::__set_debug_format(__underlying_); + + if (__has_range_underlying_spec) { + // range-underlying-spec: + // : format-spec + ++__begin; + if (__begin == __end) + return __begin; + + __parse_ctx.advance_to(__begin); + __begin = __underlying_.parse(__parse_ctx); + } + + if (__begin != __end && *__begin != _CharT('}')) + std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + + return __begin; + } + + template + requires formattable, _CharT> && + same_as>, _Tp> + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Rp&& __range, _FormatContext& __ctx) const { + __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); + + if (!__specs.__has_width()) + return __format_range(__range, __ctx, __specs); + + // The size of the buffer needed is: + // - open bracket characters + // - close bracket character + // - n elements where every element may have a different size + // - (n -1) separators + // The size of the element is hard to predict, knowing the type helps but + // it depends on the format-spec. As an initial estimate we guess 6 + // characters. + // Typically both brackets are 1 character and the separator is 2 + // characters. Which means there will be + // (n - 1) * 2 + 1 + 1 = n * 2 character + // So estimate 8 times the range size as buffer. + std::size_t __capacity_hint = 0; + if constexpr (std::ranges::sized_range<_Rp>) + __capacity_hint = 8 * ranges::size(__range); + __format::__retarget_buffer<_CharT> __buffer{__capacity_hint}; + basic_format_context::__iterator, _CharT> __c{ + __buffer.__make_output_iterator(), __ctx}; + + __format_range(__range, __c, __specs); + + return __formatter::__write_string_no_precision(__buffer.__view(), __ctx.out(), __specs); + } + + template + typename _FormatContext::iterator _LIBCPP_HIDE_FROM_ABI + __format_range(_Rp&& __range, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) const { + if constexpr (same_as<_Tp, _CharT>) { + switch (__specs.__std_.__type_) { + case __format_spec::__type::__string: + case __format_spec::__type::__debug: + return __format_as_string(__range, __ctx, __specs.__std_.__type_ == __format_spec::__type::__debug); + default: + return __format_as_sequence(__range, __ctx); + } + } else + return __format_as_sequence(__range, __ctx); + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + __format_as_string(_Rp&& __range, _FormatContext& __ctx, bool __debug_format) const { + // When the range is contiguous use a basic_string_view instead to avoid a + // copy of the underlying data. The basic_string_view formatter + // specialization is the "basic" string formatter in libc++. + if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>) { + std::formatter, _CharT> __formatter; + if (__debug_format) + __formatter.set_debug_format(); + return __formatter.format( + basic_string_view<_CharT>{ + ranges::data(__range), + ranges::size(__range), + }, + __ctx); + } else { + std::formatter, _CharT> __formatter; + if (__debug_format) + __formatter.set_debug_format(); + // P2106's from_range has not been implemented yet. Instead use a simple + // copy operation. + // TODO FMT use basic_string's "from_range" constructor. + // return std::formatter, _CharT>{}.format(basic_string<_CharT>{from_range, __range}, __ctx); + basic_string<_CharT> __str; + ranges::copy(__range, back_insert_iterator{__str}); + return __formatter.format(__str, __ctx); + } + } + + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + __format_as_sequence(_Rp&& __range, _FormatContext& __ctx) const { + __ctx.advance_to(ranges::copy(__opening_bracket_, __ctx.out()).out); + bool __use_separator = false; + for (auto&& __e : __range) { + if (__use_separator) + __ctx.advance_to(ranges::copy(__separator_, __ctx.out()).out); + else + __use_separator = true; + + __ctx.advance_to(__underlying_.format(__e, __ctx)); + } + + return ranges::copy(__closing_bracket_, __ctx.out()).out; + } + + __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left}; + +private: + _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin, const _CharT* __end) { + switch (*__begin) { + case _CharT('m'): + if constexpr (__fmt_pair_like<_Tp>) { + set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}")); + set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ", ")); + ++__begin; + } else + std::__throw_format_error("The range-format-spec type m requires two elements for a pair or tuple"); + break; + + case _CharT('s'): + if constexpr (same_as<_Tp, _CharT>) { + __parser_.__type_ = __format_spec::__type::__string; + ++__begin; + } else + std::__throw_format_error("The range-format-spec type s requires formatting a character type"); + break; + + case _CharT('?'): + ++__begin; + if (__begin == __end || *__begin != _CharT('s')) + std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + if constexpr (same_as<_Tp, _CharT>) { + __parser_.__type_ = __format_spec::__type::__debug; + ++__begin; + } else + std::__throw_format_error("The range-format-spec type ?s requires formatting a character type"); + } + } + + formatter<_Tp, _CharT> __underlying_; + basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", "); + basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "["); + basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "]"); +}; + +#endif //_LIBCPP_STD_VER > 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_RANGE_FORMATTER_H diff --git a/gnu/llvm/libcxx/include/__format/unicode.h b/gnu/llvm/libcxx/include/__format/unicode.h new file mode 100644 index 00000000000..43272587608 --- /dev/null +++ b/gnu/llvm/libcxx/include/__format/unicode.h @@ -0,0 +1,489 @@ +// -*- 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___FORMAT_UNICODE_H +#define _LIBCPP___FORMAT_UNICODE_H + +#include <__assert> +#include <__config> +#include <__format/extended_grapheme_cluster_table.h> +#include <__type_traits/make_unsigned.h> +#include <__utility/unreachable.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +namespace __unicode { + +# if _LIBCPP_STD_VER > 20 + +/// The result of consuming a code point using P2286' semantics +/// +/// TODO FMT Combine __consume and __consume_p2286 in one function. +struct __consume_p2286_result { + // A size of 0 means well formed. This to differenciate between + // a valid code point and a code unit that's invalid like 0b11111xxx. + int __ill_formed_size; + + // If well formed the consumed code point. + // Otherwise the ill-formed code units as unsigned 8-bit values. They are + // stored in reverse order, to make it easier to extract the values. + char32_t __value; +}; + +# endif // _LIBCPP_STD_VER > 20 + +# ifndef _LIBCPP_HAS_NO_UNICODE + +/// Implements the grapheme cluster boundary rules +/// +/// These rules are used to implement format's width estimation as stated in +/// [format.string.std]/11 +/// +/// The Standard refers to UAX \#29 for Unicode 12.0.0 +/// https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules +/// +/// The data tables used are +/// https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakProperty.txt +/// https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt +/// https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt (for testing only) + +inline constexpr char32_t __replacement_character = U'\ufffd'; + +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(const char* __char, int __count) { + do { + if ((*__char & 0b1000'0000) != 0b1000'0000) + return false; + --__count; + ++__char; + } while (__count); + return true; +} + +/// Helper class to extract a code unit from a Unicode character range. +/// +/// The stored range is a view. There are multiple specialization for different +/// character types. +template +class __code_point_view; + +/// UTF-8 specialization. +template <> +class __code_point_view { +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const char* __first, const char* __last) + : __first_(__first), __last_(__last) {} + + _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } + _LIBCPP_HIDE_FROM_ABI constexpr const char* __position() const noexcept { return __first_; } + + _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + // Based on the number of leading 1 bits the number of code units in the + // code point can be determined. See + // https://en.wikipedia.org/wiki/UTF-8#Encoding + switch (_VSTD::countl_one(static_cast(*__first_))) { + case 0: + return *__first_++; + + case 2: + if (__last_ - __first_ < 2 || !__unicode::__is_continuation(__first_ + 1, 1)) [[unlikely]] + break; + else { + char32_t __value = static_cast(*__first_++) & 0x1f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return __value; + } + + case 3: + if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]] + break; + else { + char32_t __value = static_cast(*__first_++) & 0x0f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return __value; + } + + case 4: + if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]] + break; + else { + char32_t __value = static_cast(*__first_++) & 0x07; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return __value; + } + } + // An invalid number of leading ones can be garbage or a code unit in the + // middle of a code point. By consuming one code unit the parser may get + // "in sync" after a few code units. + ++__first_; + return __replacement_character; + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + // Based on the number of leading 1 bits the number of code units in the + // code point can be determined. See + // https://en.wikipedia.org/wiki/UTF-8#Encoding + switch (std::countl_one(static_cast(*__first_))) { + case 0: + return {0, static_cast(*__first_++)}; + + case 2: + if (__last_ - __first_ < 2) [[unlikely]] + break; + + if (__unicode::__is_continuation(__first_ + 1, 1)) { + char32_t __value = static_cast(*__first_++) & 0x1f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return {0, __value}; + } + break; + + case 3: + if (__last_ - __first_ < 3) [[unlikely]] + break; + + if (__unicode::__is_continuation(__first_ + 1, 2)) { + char32_t __value = static_cast(*__first_++) & 0x0f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + return {0, __value}; + } + break; + + case 4: + if (__last_ - __first_ < 4) [[unlikely]] + break; + + if (__unicode::__is_continuation(__first_ + 1, 3)) { + char32_t __value = static_cast(*__first_++) & 0x07; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + __value <<= 6; + __value |= static_cast(*__first_++) & 0x3f; + + if (__value > 0x10FFFF) // Outside the valid Unicode range? + return {4, __value}; + + return {0, __value}; + } + break; + } + // An invalid number of leading ones can be garbage or a code unit in the + // middle of a code point. By consuming one code unit the parser may get + // "in sync" after a few code units. + return {1, static_cast(*__first_++)}; + } +# endif // _LIBCPP_STD_VER > 20 + +private: + const char* __first_; + const char* __last_; +}; + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_high(wchar_t __value) { + return __value >= 0xd800 && __value <= 0xdbff; +} + +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_low(wchar_t __value) { + return __value >= 0xdc00 && __value <= 0xdfff; +} + +/// This specialization depends on the size of wchar_t +/// - 2 UTF-16 (for example Windows and AIX) +/// - 4 UTF-32 (for example Linux) +template <> +class __code_point_view { +public: + static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "sizeof(wchar_t) has a not implemented value"); + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const wchar_t* __first, const wchar_t* __last) + : __first_(__first), __last_(__last) {} + + _LIBCPP_HIDE_FROM_ABI constexpr const wchar_t* __position() const noexcept { return __first_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } + + _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + if constexpr (sizeof(wchar_t) == 2) { + char32_t __result = *__first_++; + // Is the code unit part of a surrogate pair? See + // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF + if (__result >= 0xd800 && __result <= 0xDfff) { + // Malformed Unicode. + if (__first_ == __last_) [[unlikely]] + return __replacement_character; + + __result -= 0xd800; + __result <<= 10; + __result += *__first_++ - 0xdc00; + __result += 0x10000; + } + return __result; + + } else if constexpr (sizeof(wchar_t) == 4) { + char32_t __result = *__first_++; + if (__result > 0x10FFFF) [[unlikely]] + return __replacement_character; + return __result; + } else { + __libcpp_unreachable(); + } + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + char32_t __result = *__first_++; + if constexpr (sizeof(wchar_t) == 2) { + // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF + if (__is_surrogate_pair_high(__result)) { + // Malformed Unicode. + if (__first_ == __last_ || !__is_surrogate_pair_low(*(__first_ + 1))) [[unlikely]] + return {1, __result}; + + __result -= 0xd800; + __result <<= 10; + __result += *__first_++ - 0xdc00; + __result += 0x10000; + } else if (__is_surrogate_pair_low(__result)) + // A code point shouldn't start with the low surrogate pair + return {1, __result}; + } else { + if (__result > 0x10FFFF) [[unlikely]] + return {1, __result}; + } + + return {0, __result}; + } +# endif // _LIBCPP_STD_VER > 20 + +private: + const wchar_t* __first_; + const wchar_t* __last_; +}; +# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +_LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break( + bool& __ri_break_allowed, + bool __has_extened_pictographic, + __extended_grapheme_custer_property_boundary::__property __prev, + __extended_grapheme_custer_property_boundary::__property __next) { + using __extended_grapheme_custer_property_boundary::__property; + + __has_extened_pictographic |= __prev == __property::__Extended_Pictographic; + + // https://www.unicode.org/reports/tr29/tr29-39.html#Grapheme_Cluster_Boundary_Rules + + // *** Break at the start and end of text, unless the text is empty. *** + + _LIBCPP_ASSERT(__prev != __property::__sot, "should be handled in the constructor"); // GB1 + _LIBCPP_ASSERT(__prev != __property::__eot, "should be handled by our caller"); // GB2 + + // *** Do not break between a CR and LF. Otherwise, break before and after controls. *** + if (__prev == __property::__CR && __next == __property::__LF) // GB3 + return false; + + if (__prev == __property::__Control || __prev == __property::__CR || __prev == __property::__LF) // GB4 + return true; + + if (__next == __property::__Control || __next == __property::__CR || __next == __property::__LF) // GB5 + return true; + + // *** Do not break Hangul syllable sequences. *** + if (__prev == __property::__L && + (__next == __property::__L || __next == __property::__V || __next == __property::__LV || + __next == __property::__LVT)) // GB6 + return false; + + if ((__prev == __property::__LV || __prev == __property::__V) && + (__next == __property::__V || __next == __property::__T)) // GB7 + return false; + + if ((__prev == __property::__LVT || __prev == __property::__T) && __next == __property::__T) // GB8 + return false; + + // *** Do not break before extending characters or ZWJ. *** + if (__next == __property::__Extend || __next == __property::__ZWJ) + return false; // GB9 + + // *** Do not break before SpacingMarks, or after Prepend characters. *** + if (__next == __property::__SpacingMark) // GB9a + return false; + + if (__prev == __property::__Prepend) // GB9b + return false; + + // *** Do not break within emoji modifier sequences or emoji zwj sequences. *** + + // GB11 \p{Extended_Pictographic} Extend* ZWJ x \p{Extended_Pictographic} + // + // Note that several parts of this rule are matched by GB9: Any x (Extend | ZWJ) + // - \p{Extended_Pictographic} x Extend + // - Extend x Extend + // - \p{Extended_Pictographic} x ZWJ + // - Extend x ZWJ + // + // So the only case left to test is + // - \p{Extended_Pictographic}' x ZWJ x \p{Extended_Pictographic} + // where \p{Extended_Pictographic}' is stored in __has_extened_pictographic + if (__has_extened_pictographic && __prev == __property::__ZWJ && __next == __property::__Extended_Pictographic) + return false; + + // *** Do not break within emoji flag sequences *** + + // That is, do not break between regional indicator (RI) symbols if there + // is an odd number of RI characters before the break point. + + if (__prev == __property::__Regional_Indicator && __next == __property::__Regional_Indicator) { // GB12 + GB13 + __ri_break_allowed = !__ri_break_allowed; + return __ri_break_allowed; + } + + // *** Otherwise, break everywhere. *** + return true; // GB999 +} + +/// Helper class to extract an extended grapheme cluster from a Unicode character range. +/// +/// This function is used to determine the column width of an extended grapheme +/// cluster. In order to do that only the first code point is evaluated. +/// Therefore only this code point is extracted. +template +class __extended_grapheme_cluster_view { +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(const _CharT* __first, const _CharT* __last) + : __code_point_view_(__first, __last), + __next_code_point_(__code_point_view_.__consume()), + __next_prop_(__extended_grapheme_custer_property_boundary::__get_property(__next_code_point_)) {} + + struct __cluster { + /// The first code point of the extended grapheme cluster. + /// + /// The first code point is used to estimate the width of the extended + /// grapheme cluster. + char32_t __code_point_; + + /// Points one beyond the last code unit in the extended grapheme cluster. + /// + /// It's expected the caller has the start position and thus can determine + /// the code unit range of the extended grapheme cluster. + const _CharT* __last_; + }; + + _LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() { + _LIBCPP_ASSERT( + __next_prop_ != __extended_grapheme_custer_property_boundary::__property::__eot, + "can't move beyond the end of input"); + char32_t __code_point = __next_code_point_; + if (!__code_point_view_.__at_end()) + return {__code_point, __get_break()}; + + __next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot; + return {__code_point, __code_point_view_.__position()}; + } + +private: + __code_point_view<_CharT> __code_point_view_; + + char32_t __next_code_point_; + __extended_grapheme_custer_property_boundary::__property __next_prop_; + + _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __get_break() { + bool __ri_break_allowed = true; + bool __has_extened_pictographic = false; + while (true) { + const _CharT* __result = __code_point_view_.__position(); + __extended_grapheme_custer_property_boundary::__property __prev = __next_prop_; + if (__code_point_view_.__at_end()) { + __next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot; + return __result; + } + __next_code_point_ = __code_point_view_.__consume(); + __next_prop_ = __extended_grapheme_custer_property_boundary::__get_property(__next_code_point_); + + __has_extened_pictographic |= + __prev == __extended_grapheme_custer_property_boundary::__property::__Extended_Pictographic; + + if (__at_extended_grapheme_cluster_break(__ri_break_allowed, __has_extened_pictographic, __prev, __next_prop_)) + return __result; + } + } +}; + +template +__extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_grapheme_cluster_view<_CharT>; + +# else // _LIBCPP_HAS_NO_UNICODE + +// For ASCII every character is a "code point". +// This makes it easier to write code agnostic of the _LIBCPP_HAS_NO_UNICODE define. +template +class __code_point_view { +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const _CharT* __first, const _CharT* __last) + : __first_(__first), __last_(__last) {} + + _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __position() const noexcept { return __first_; } + + _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + return *__first_++; + } + +# if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept { + _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + + return {0, std::make_unsigned_t<_CharT>(*__first_++)}; + } +# endif // _LIBCPP_STD_VER > 20 + +private: + const _CharT* __first_; + const _CharT* __last_; +}; + +# endif // _LIBCPP_HAS_NO_UNICODE + +} // namespace __unicode + +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_UNICODE_H diff --git a/gnu/llvm/libcxx/include/__functional/binary_function.h b/gnu/llvm/libcxx/include/__functional/binary_function.h index 8ca7b06662a..fdedb8b177d 100644 --- a/gnu/llvm/libcxx/include/__functional/binary_function.h +++ b/gnu/llvm/libcxx/include/__functional/binary_function.h @@ -13,19 +13,42 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) + template -struct _LIBCPP_TEMPLATE_VIS binary_function +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binary_function { typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; }; +#endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) + +template struct __binary_function_keep_layout_base { +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using first_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg1; + using second_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg2; + using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; +#endif +}; + +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") +template +using __binary_function = binary_function<_Arg1, _Arg2, _Result>; +_LIBCPP_DIAGNOSTIC_POP +#else +template +using __binary_function = __binary_function_keep_layout_base<_Arg1, _Arg2, _Result>; +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H diff --git a/gnu/llvm/libcxx/include/__functional/binary_negate.h b/gnu/llvm/libcxx/include/__functional/binary_negate.h index 4fc3f1ba287..73ecea99710 100644 --- a/gnu/llvm/libcxx/include/__functional/binary_negate.h +++ b/gnu/llvm/libcxx/include/__functional/binary_negate.h @@ -14,7 +14,7 @@ #include <__functional/binary_function.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -23,23 +23,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate - : public binary_function + : public __binary_function { _Predicate __pred_; public: - _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_SINCE_CXX14 binary_negate(const _Predicate& __pred) : __pred_(__pred) {} - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const typename _Predicate::first_argument_type& __x, const typename _Predicate::second_argument_type& __y) const {return !__pred_(__x, __y);} }; template -_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY binary_negate<_Predicate> not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);} diff --git a/gnu/llvm/libcxx/include/__functional/bind.h b/gnu/llvm/libcxx/include/__functional/bind.h index 79dfad723c6..297e4e5103a 100644 --- a/gnu/llvm/libcxx/include/__functional/bind.h +++ b/gnu/llvm/libcxx/include/__functional/bind.h @@ -11,34 +11,40 @@ #define _LIBCPP___FUNCTIONAL_BIND_H #include <__config> -#include <__functional/weak_result_type.h> #include <__functional/invoke.h> +#include <__functional/weak_result_type.h> #include #include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -template struct __is_bind_expression : public false_type {}; -template struct _LIBCPP_TEMPLATE_VIS is_bind_expression - : public __is_bind_expression::type> {}; +template +struct is_bind_expression : _If< + _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, + false_type, + is_bind_expression<__remove_cvref_t<_Tp> > +> {}; #if _LIBCPP_STD_VER > 14 template -_LIBCPP_INLINE_VAR constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value; +inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value; #endif -template struct __is_placeholder : public integral_constant {}; -template struct _LIBCPP_TEMPLATE_VIS is_placeholder - : public __is_placeholder::type> {}; +template +struct is_placeholder : _If< + _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, + integral_constant, + is_placeholder<__remove_cvref_t<_Tp> > +> {}; #if _LIBCPP_STD_VER > 14 template -_LIBCPP_INLINE_VAR constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value; +inline constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value; #endif namespace placeholders @@ -58,22 +64,22 @@ _LIBCPP_FUNC_VIS extern const __ph<8> _8; _LIBCPP_FUNC_VIS extern const __ph<9> _9; _LIBCPP_FUNC_VIS extern const __ph<10> _10; #else -/* _LIBCPP_INLINE_VAR */ constexpr __ph<1> _1{}; -/* _LIBCPP_INLINE_VAR */ constexpr __ph<2> _2{}; -/* _LIBCPP_INLINE_VAR */ constexpr __ph<3> _3{}; -/* _LIBCPP_INLINE_VAR */ constexpr __ph<4> _4{}; -/* _LIBCPP_INLINE_VAR */ constexpr __ph<5> _5{}; -/* _LIBCPP_INLINE_VAR */ constexpr __ph<6> _6{}; -/* _LIBCPP_INLINE_VAR */ constexpr __ph<7> _7{}; -/* _LIBCPP_INLINE_VAR */ constexpr __ph<8> _8{}; -/* _LIBCPP_INLINE_VAR */ constexpr __ph<9> _9{}; -/* _LIBCPP_INLINE_VAR */ constexpr __ph<10> _10{}; +/* inline */ constexpr __ph<1> _1{}; +/* inline */ constexpr __ph<2> _2{}; +/* inline */ constexpr __ph<3> _3{}; +/* inline */ constexpr __ph<4> _4{}; +/* inline */ constexpr __ph<5> _5{}; +/* inline */ constexpr __ph<6> _6{}; +/* inline */ constexpr __ph<7> _7{}; +/* inline */ constexpr __ph<8> _8{}; +/* inline */ constexpr __ph<9> _9{}; +/* inline */ constexpr __ph<10> _10{}; #endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) -} // placeholders +} // namespace placeholders template -struct __is_placeholder > +struct is_placeholder > : public integral_constant {}; @@ -97,7 +103,7 @@ __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) template inline _LIBCPP_INLINE_VISIBILITY -typename _EnableIf +typename __enable_if_t < is_bind_expression<_Ti>::value, __invoke_of<_Ti&, _Uj...> @@ -258,10 +264,7 @@ __apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, } template -class __bind -#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public __weak_result_type::type> -#endif +class __bind : public __weak_result_type::type> { protected: typedef typename decay<_Fp>::type _Fd; @@ -276,16 +279,16 @@ public: class = typename enable_if < is_constructible<_Fd, _Gp>::value && - !is_same::type, + !is_same<__libcpp_remove_reference_t<_Gp>, __bind>::value >::type> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bind(_Gp&& __f, _BA&& ...__bound_args) : __f_(_VSTD::forward<_Gp>(__f)), __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {} template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type operator()(_Args&& ...__args) { @@ -294,7 +297,7 @@ public: } template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return >::type operator()(_Args&& ...__args) const { @@ -304,7 +307,7 @@ public: }; template -struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; +struct is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; template class __bind_r @@ -321,16 +324,16 @@ public: class = typename enable_if < is_constructible<_Fd, _Gp>::value && - !is_same::type, + !is_same<__libcpp_remove_reference_t<_Gp>, __bind_r>::value >::type> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args) : base(_VSTD::forward<_Gp>(__f), _VSTD::forward<_BA>(__bound_args)...) {} template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if < is_convertible >::type, @@ -344,7 +347,7 @@ public: } template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if < is_convertible >::type, @@ -359,10 +362,10 @@ public: }; template -struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; +struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...> bind(_Fp&& __f, _BoundArgs&&... __bound_args) { @@ -371,7 +374,7 @@ bind(_Fp&& __f, _BoundArgs&&... __bound_args) } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...> bind(_Fp&& __f, _BoundArgs&&... __bound_args) { diff --git a/gnu/llvm/libcxx/include/__functional/bind_back.h b/gnu/llvm/libcxx/include/__functional/bind_back.h new file mode 100644 index 00000000000..f0a6e49875a --- /dev/null +++ b/gnu/llvm/libcxx/include/__functional/bind_back.h @@ -0,0 +1,64 @@ +// -*- 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___FUNCTIONAL_BIND_BACK_H +#define _LIBCPP___FUNCTIONAL_BIND_BACK_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> +#include <__utility/integer_sequence.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template > +struct __bind_back_op; + +template +struct __bind_back_op<_NBound, index_sequence<_Ip...>> { + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __f, _BoundArgs&& __bound_args, _Args&&... __args) const + noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...))) + -> decltype( _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...)) + { return _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...); } +}; + +template +struct __bind_back_t : __perfect_forward<__bind_back_op>, _Fn, _BoundArgs> { + using __perfect_forward<__bind_back_op>, _Fn, _BoundArgs>::__perfect_forward; +}; + +template , _Fn>, + is_move_constructible>, + is_constructible, _Args>..., + is_move_constructible>... + >::value +>> +_LIBCPP_HIDE_FROM_ABI +constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) + noexcept(noexcept(__bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)))) + -> decltype( __bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...))) + { return __bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_BIND_BACK_H diff --git a/gnu/llvm/libcxx/include/__functional/bind_front.h b/gnu/llvm/libcxx/include/__functional/bind_front.h index 8690499f2b0..22fb3a69dc7 100644 --- a/gnu/llvm/libcxx/include/__functional/bind_front.h +++ b/gnu/llvm/libcxx/include/__functional/bind_front.h @@ -11,38 +11,44 @@ #define _LIBCPP___FUNCTIONAL_BIND_FRONT_H #include <__config> -#include <__functional/perfect_forward.h> #include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 17 -struct __bind_front_op -{ - template - constexpr static auto __call(_Args&&... __args) - noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) - -> decltype( _VSTD::invoke(_VSTD::forward<_Args>(__args)...)) - { return _VSTD::invoke(_VSTD::forward<_Args>(__args)...); } +struct __bind_front_op { + template + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Args&& ...__args) const + noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) + -> decltype( _VSTD::invoke(_VSTD::forward<_Args>(__args)...)) + { return _VSTD::invoke(_VSTD::forward<_Args>(__args)...); } +}; + +template +struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> { + using __perfect_forward<__bind_front_op, _Fn, _BoundArgs...>::__perfect_forward; }; -template, _Fn>, - is_move_constructible>, - is_constructible, _Args>..., - is_move_constructible>... - >::value>> -constexpr auto bind_front(_Fn&& __f, _Args&&... __args) -{ - return __perfect_forward<__bind_front_op, _Fn, _Args...>(_VSTD::forward<_Fn>(__f), - _VSTD::forward<_Args>(__args)...); +template , _Fn>, + is_move_constructible>, + is_constructible, _Args>..., + is_move_constructible>... + >::value +>> +_LIBCPP_HIDE_FROM_ABI +constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { + return __bind_front_t, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); } #endif // _LIBCPP_STD_VER > 17 diff --git a/gnu/llvm/libcxx/include/__functional/binder1st.h b/gnu/llvm/libcxx/include/__functional/binder1st.h index 5dd8f5cf015..dea22c70e1f 100644 --- a/gnu/llvm/libcxx/include/__functional/binder1st.h +++ b/gnu/llvm/libcxx/include/__functional/binder1st.h @@ -14,7 +14,7 @@ #include <__functional/unary_function.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -23,8 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st - : public unary_function + : public __unary_function { protected: __Operation op; diff --git a/gnu/llvm/libcxx/include/__functional/binder2nd.h b/gnu/llvm/libcxx/include/__functional/binder2nd.h index 3ed5f5bf454..c98a146b6a6 100644 --- a/gnu/llvm/libcxx/include/__functional/binder2nd.h +++ b/gnu/llvm/libcxx/include/__functional/binder2nd.h @@ -14,7 +14,7 @@ #include <__functional/unary_function.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -23,8 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd - : public unary_function + : public __unary_function { protected: __Operation op; diff --git a/gnu/llvm/libcxx/include/__functional/boyer_moore_searcher.h b/gnu/llvm/libcxx/include/__functional/boyer_moore_searcher.h new file mode 100644 index 00000000000..a6750893ee5 --- /dev/null +++ b/gnu/llvm/libcxx/include/__functional/boyer_moore_searcher.h @@ -0,0 +1,315 @@ +//===----------------------------------------------------------------------===// +// +// 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___FUNCTIONAL_BOYER_MOORE_SEARCHER_H +#define _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#include <__algorithm/fill_n.h> +#include <__config> +#include <__functional/hash.h> +#include <__functional/operations.h> +#include <__iterator/distance.h> +#include <__iterator/iterator_traits.h> +#include <__memory/shared_ptr.h> +#include <__utility/pair.h> +#include +#include +#include + +#if _LIBCPP_STD_VER > 14 + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _BMSkipTable; + +// General case for BM data searching; use a map +template +class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> { +private: + using value_type = _Value; + using key_type = _Key; + + const value_type __default_value_; + unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_; + +public: + _LIBCPP_HIDE_FROM_ABI + explicit _BMSkipTable(size_t __sz, value_type __default_value, _Hash __hash, _BinaryPredicate __pred) + : __default_value_(__default_value), + __table_(__sz, __hash, __pred) {} + + _LIBCPP_HIDE_FROM_ABI void insert(const key_type& __key, value_type __val) { + __table_[__key] = __val; + } + + _LIBCPP_HIDE_FROM_ABI value_type operator[](const key_type& __key) const { + auto __it = __table_.find(__key); + return __it == __table_.end() ? __default_value_ : __it->second; + } +}; + +// Special case small numeric values; use an array +template +class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> { +private: + using value_type = _Value; + using key_type = _Key; + + using unsigned_key_type = make_unsigned_t; + std::array __table_; + static_assert(numeric_limits::max() < 256); + +public: + _LIBCPP_HIDE_FROM_ABI explicit _BMSkipTable(size_t, value_type __default_value, _Hash, _BinaryPredicate) { + std::fill_n(__table_.data(), __table_.size(), __default_value); + } + + _LIBCPP_HIDE_FROM_ABI void insert(key_type __key, value_type __val) { + __table_[static_cast(__key)] = __val; + } + + _LIBCPP_HIDE_FROM_ABI value_type operator[](key_type __key) const { + return __table_[static_cast(__key)]; + } +}; + +template ::value_type>, + class _BinaryPredicate = equal_to<>> +class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher { +private: + using difference_type = typename std::iterator_traits<_RandomAccessIterator1>::difference_type; + using value_type = typename std::iterator_traits<_RandomAccessIterator1>::value_type; + using __skip_table_type = _BMSkipTable + && sizeof(value_type) == 1 + && is_same_v<_Hash, hash> + && is_same_v<_BinaryPredicate, equal_to<>>>; + +public: + boyer_moore_searcher(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _Hash __hash = _Hash(), + _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__first), + __last_(__last), + __pred_(__pred), + __pattern_length_(__last - __first), + __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, -1, __hash, __pred_)), + __suffix_(std::__allocate_shared_unbounded_array( + allocator(), __pattern_length_ + 1)) { + difference_type __i = 0; + while (__first != __last) { + __skip_table_->insert(*__first, __i); + ++__first; + ++__i; + } + __build_suffix_table(__first_, __last_, __pred_); + } + + template + pair<_RandomAccessIterator2, _RandomAccessIterator2> + operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { + static_assert(__is_same_uncvref::value_type, + typename iterator_traits<_RandomAccessIterator2>::value_type>::value, + "Corpus and Pattern iterators must point to the same type"); + if (__first == __last) + return std::make_pair(__last, __last); + if (__first_ == __last_) + return std::make_pair(__first, __first); + + if (__pattern_length_ > (__last - __first)) + return std::make_pair(__last, __last); + return __search(__first, __last); + } + +private: + _RandomAccessIterator1 __first_; + _RandomAccessIterator1 __last_; + _BinaryPredicate __pred_; + difference_type __pattern_length_; + shared_ptr<__skip_table_type> __skip_table_; + shared_ptr __suffix_; + + template + pair<_RandomAccessIterator2, _RandomAccessIterator2> + __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { + _RandomAccessIterator2 __current = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; + const __skip_table_type& __skip_table = *__skip_table_; + + while (__current <= __last) { + difference_type __j = __pattern_length_; + while (__pred_(__first_[__j - 1], __current[__j - 1])) { + --__j; + if (__j == 0) + return std::make_pair(__current, __current + __pattern_length_); + } + + difference_type __k = __skip_table[__current[__j - 1]]; + difference_type __m = __j - __k - 1; + if (__k < __j && __m > __suffix_[__j]) + __current += __m; + else + __current += __suffix_[__j]; + } + return std::make_pair(__l, __l); + } + + template + void __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) { + const size_t __count = __last - __first; + + __prefix[0] = 0; + size_t __k = 0; + + for (size_t __i = 1; __i != __count; ++__i) { + while (__k > 0 && !__pred(__first[__k], __first[__i])) + __k = __prefix[__k - 1]; + + if (__pred(__first[__k], __first[__i])) + ++__k; + __prefix[__i] = __k; + } + } + + void __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) { + const size_t __count = __last - __first; + + if (__count == 0) + return; + + vector __scratch(__count); + + __compute_bm_prefix(__first, __last, __pred, __scratch); + for (size_t __i = 0; __i <= __count; ++__i) + __suffix_[__i] = __count - __scratch[__count - 1]; + + using _ReverseIter = reverse_iterator<_RandomAccessIterator1>; + __compute_bm_prefix(_ReverseIter(__last), _ReverseIter(__first), __pred, __scratch); + + for (size_t __i = 0; __i != __count; ++__i) { + const size_t __j = __count - __scratch[__i]; + const difference_type __k = __i - __scratch[__i] + 1; + + if (__suffix_[__j] > __k) + __suffix_[__j] = __k; + } + } +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(boyer_moore_searcher); + +template ::value_type>, + class _BinaryPredicate = equal_to<>> +class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher { +private: + using difference_type = typename iterator_traits<_RandomAccessIterator1>::difference_type; + using value_type = typename iterator_traits<_RandomAccessIterator1>::value_type; + using __skip_table_type = _BMSkipTable + && sizeof(value_type) == 1 + && is_same_v<_Hash, hash> + && is_same_v<_BinaryPredicate, equal_to<>>>; +public: + boyer_moore_horspool_searcher(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _Hash __hash = _Hash(), + _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__first), + __last_(__last), + __pred_(__pred), + __pattern_length_(__last - __first), + __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, __pattern_length_, __hash, __pred_)) { + if (__first == __last) + return; + --__last; + difference_type __i = 0; + while (__first != __last) { + __skip_table_->insert(*__first, __pattern_length_ - 1 - __i); + ++__first; + ++__i; + } + } + + template + pair<_RandomAccessIterator2, _RandomAccessIterator2> + operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { + static_assert(__is_same_uncvref::value_type, + typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value, + "Corpus and Pattern iterators must point to the same type"); + if (__first == __last) + return std::make_pair(__last, __last); + if (__first_ == __last_) + return std::make_pair(__first, __first); + + if (__pattern_length_ > __last - __first) + return std::make_pair(__last, __last); + + return __search(__first, __last); + } + +private: + _RandomAccessIterator1 __first_; + _RandomAccessIterator1 __last_; + _BinaryPredicate __pred_; + difference_type __pattern_length_; + shared_ptr<__skip_table_type> __skip_table_; + + template + pair<_RandomAccessIterator2, _RandomAccessIterator2> + __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { + _RandomAccessIterator2 __current = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; + const __skip_table_type& __skip_table = *__skip_table_; + + while (__current <= __last) { + difference_type __j = __pattern_length_; + while (__pred_(__first_[__j - 1], __current[__j - 1])) { + --__j; + if (__j == 0) + return std::make_pair(__current, __current + __pattern_length_); + } + __current += __skip_table[__current[__pattern_length_ - 1]]; + } + return std::make_pair(__l, __l); + } +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(boyer_moore_horspool_searcher); + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_STD_VER > 14 + +#endif // _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H diff --git a/gnu/llvm/libcxx/include/__functional/compose.h b/gnu/llvm/libcxx/include/__functional/compose.h new file mode 100644 index 00000000000..25213f28b1f --- /dev/null +++ b/gnu/llvm/libcxx/include/__functional/compose.h @@ -0,0 +1,52 @@ +// -*- 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___FUNCTIONAL_COMPOSE_H +#define _LIBCPP___FUNCTIONAL_COMPOSE_H + +#include <__config> +#include <__functional/invoke.h> +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +struct __compose_op { + template + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Fn1&& __f1, _Fn2&& __f2, _Args&&... __args) const + noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)))) + -> decltype( _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...))) + { return _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)); } +}; + +template +struct __compose_t : __perfect_forward<__compose_op, _Fn1, _Fn2> { + using __perfect_forward<__compose_op, _Fn1, _Fn2>::__perfect_forward; +}; + +template +_LIBCPP_HIDE_FROM_ABI +constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2) + noexcept(noexcept(__compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)))) + -> decltype( __compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2))) + { return __compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)); } + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FUNCTIONAL_COMPOSE_H diff --git a/gnu/llvm/libcxx/include/__functional/default_searcher.h b/gnu/llvm/libcxx/include/__functional/default_searcher.h index 1acbc1883af..e4151e589f7 100644 --- a/gnu/llvm/libcxx/include/__functional/default_searcher.h +++ b/gnu/llvm/libcxx/include/__functional/default_searcher.h @@ -12,12 +12,13 @@ #include <__algorithm/search.h> #include <__config> +#include <__functional/identity.h> #include <__functional/operations.h> #include <__iterator/iterator_traits.h> -#include +#include <__utility/pair.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -28,26 +29,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD template> class _LIBCPP_TEMPLATE_VIS default_searcher { public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 default_searcher(_ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate()) : __first_(__f), __last_(__l), __pred_(__p) {} template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator2, _ForwardIterator2> operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { - return _VSTD::__search(__f, __l, __first_, __last_, __pred_, - typename iterator_traits<_ForwardIterator>::iterator_category(), - typename iterator_traits<_ForwardIterator2>::iterator_category()); + auto __proj = __identity(); + return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj); } private: _ForwardIterator __first_; _ForwardIterator __last_; _BinaryPredicate __pred_; - }; +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher); #endif // _LIBCPP_STD_VER > 14 diff --git a/gnu/llvm/libcxx/include/__functional/function.h b/gnu/llvm/libcxx/include/__functional/function.h index ba629e1d145..9f92f618146 100644 --- a/gnu/llvm/libcxx/include/__functional/function.h +++ b/gnu/llvm/libcxx/include/__functional/function.h @@ -10,37 +10,60 @@ #ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H #define _LIBCPP___FUNCTIONAL_FUNCTION_H +#include <__assert> #include <__config> #include <__functional/binary_function.h> #include <__functional/invoke.h> #include <__functional/unary_function.h> #include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__memory/allocator.h> +#include <__memory/allocator_destructor.h> #include <__memory/allocator_traits.h> +#include <__memory/builtin_new_allocator.h> #include <__memory/compressed_pair.h> -#include <__memory/shared_ptr.h> +#include <__memory/unique_ptr.h> +#include <__type_traits/strip_signature.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/piecewise_construct.h> +#include <__utility/swap.h> #include -#include // TODO: replace with <__memory/__builtin_new_allocator.h> +#include +#include #include -#include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_BEGIN_NAMESPACE_STD // bad_function_call +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") class _LIBCPP_EXCEPTION_ABI bad_function_call : public exception { -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION public: - virtual ~bad_function_call() _NOEXCEPT; +// Note that when a key function is not used, every translation unit that uses +// bad_function_call will end up containing a weak definition of the vtable and +// typeinfo. +#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION + ~bad_function_call() _NOEXCEPT override; +#else + ~bad_function_call() _NOEXCEPT override {} +#endif - virtual const char* what() const _NOEXCEPT; +#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE + const char* what() const _NOEXCEPT override; #endif }; +_LIBCPP_DIAGNOSTIC_POP _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_bad_function_call() @@ -52,14 +75,7 @@ void __throw_bad_function_call() #endif } -#if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated) -# define _LIBCPP_DEPRECATED_CXX03_FUNCTION \ - __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type"))) -#else -# define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */ -#endif - -template class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined +template class _LIBCPP_TEMPLATE_VIS function; // undefined namespace __function { @@ -71,7 +87,7 @@ struct __maybe_derive_from_unary_function template struct __maybe_derive_from_unary_function<_Rp(_A1)> - : public unary_function<_A1, _Rp> + : public __unary_function<_A1, _Rp> { }; @@ -82,7 +98,7 @@ struct __maybe_derive_from_binary_function template struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> - : public binary_function<_A1, _A2, _Rp> + : public __binary_function<_A1, _A2, _Rp> { }; @@ -110,8 +126,6 @@ bool __not_null(_Rp (^__p)(_Args...)) { return __p; } } // namespace __function -#ifndef _LIBCPP_CXX03_LANG - namespace __function { // __alloc_func holds a functor and an allocator. @@ -126,8 +140,8 @@ class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> __compressed_pair<_Fp, _Ap> __f_; public: - typedef _LIBCPP_NODEBUG_TYPE _Fp _Target; - typedef _LIBCPP_NODEBUG_TYPE _Ap _Alloc; + typedef _LIBCPP_NODEBUG _Fp _Target; + typedef _LIBCPP_NODEBUG _Ap _Alloc; _LIBCPP_INLINE_VISIBILITY const _Target& __target() const { return __f_.first(); } @@ -176,9 +190,7 @@ class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> __alloc_func* __clone() const { typedef allocator_traits<_Alloc> __alloc_traits; - typedef - typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type - _AA; + typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; _AA __a(__f_.second()); typedef __allocator_destructor<_AA> _Dp; unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); @@ -191,8 +203,7 @@ class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> static void __destroy_and_delete(__alloc_func* __f) { typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type - _FunAlloc; + typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; _FunAlloc __a(__f->__get_allocator()); __f->destroy(); __a.deallocate(__f, 1); @@ -204,7 +215,7 @@ class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { _Fp __f_; public: - typedef _LIBCPP_NODEBUG_TYPE _Fp _Target; + typedef _LIBCPP_NODEBUG _Fp _Target; _LIBCPP_INLINE_VISIBILITY const _Target& __target() const { return __f_; } @@ -251,16 +262,16 @@ class __base<_Rp(_ArgTypes...)> __base& operator=(const __base&); public: _LIBCPP_INLINE_VISIBILITY __base() {} - _LIBCPP_INLINE_VISIBILITY virtual ~__base() {} + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} virtual __base* __clone() const = 0; virtual void __clone(__base*) const = 0; virtual void destroy() _NOEXCEPT = 0; virtual void destroy_deallocate() _NOEXCEPT = 0; virtual _Rp operator()(_ArgTypes&& ...) = 0; -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI virtual const void* target(const type_info&) const _NOEXCEPT = 0; virtual const std::type_info& target_type() const _NOEXCEPT = 0; -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; // __func implements __base for a given functor type. @@ -294,10 +305,10 @@ public: virtual void destroy() _NOEXCEPT; virtual void destroy_deallocate() _NOEXCEPT; virtual _Rp operator()(_ArgTypes&&... __arg); -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI virtual const void* target(const type_info&) const _NOEXCEPT; virtual const std::type_info& target_type() const _NOEXCEPT; -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; template @@ -305,7 +316,7 @@ __base<_Rp(_ArgTypes...)>* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const { typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + typedef __rebind_alloc<__alloc_traits, __func> _Ap; _Ap __a(__f_.__get_allocator()); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); @@ -332,7 +343,7 @@ void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT { typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; + typedef __rebind_alloc<__alloc_traits, __func> _Ap; _Ap __a(__f_.__get_allocator()); __f_.destroy(); __a.deallocate(this, 1); @@ -345,14 +356,14 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI template const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { if (__ti == typeid(_Fp)) - return &__f_.__target(); + return _VSTD::addressof(__f_.__target()); return nullptr; } @@ -363,7 +374,7 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT return typeid(_Fp); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI // __value_func creates a value-type from a __func. @@ -371,14 +382,16 @@ template class __value_func; template class __value_func<_Rp(_ArgTypes...)> { + _LIBCPP_SUPPRESS_DEPRECATED_PUSH typename aligned_storage<3 * sizeof(void*)>::type __buf_; + _LIBCPP_SUPPRESS_DEPRECATED_POP typedef __base<_Rp(_ArgTypes...)> __func; __func* __f_; - _LIBCPP_NO_CFI static __func* __as_base(void* p) + _LIBCPP_NO_CFI static __func* __as_base(void* __p) { - return reinterpret_cast<__func*>(p); + return reinterpret_cast<__func*>(__p); } public: @@ -391,8 +404,7 @@ template class __value_func<_Rp(_ArgTypes...)> { typedef allocator_traits<_Alloc> __alloc_traits; typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; - typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type - _FunAlloc; + typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; if (__function::__not_null(__f)) { @@ -505,7 +517,9 @@ template class __value_func<_Rp(_ArgTypes...)> return; if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) { + _LIBCPP_SUPPRESS_DEPRECATED_PUSH typename aligned_storage::type __tempbuf; + _LIBCPP_SUPPRESS_DEPRECATED_POP __func* __t = __as_base(&__tempbuf); __f_->__clone(__t); __f_->destroy(); @@ -539,7 +553,7 @@ template class __value_func<_Rp(_ArgTypes...)> _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI _LIBCPP_INLINE_VISIBILITY const std::type_info& target_type() const _NOEXCEPT { @@ -555,7 +569,7 @@ template class __value_func<_Rp(_ArgTypes...)> return nullptr; return (const _Tp*)__f_->target(typeid(_Tp)); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; // Storage for a functor object, to be used with __policy to manage copy and @@ -602,7 +616,7 @@ struct __policy { static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr, true, -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI &typeid(void) #else nullptr @@ -628,7 +642,7 @@ struct __policy __choose_policy(/* is_small = */ false_type) { static const _LIBCPP_CONSTEXPR __policy __policy_ = { &__large_clone<_Fun>, &__large_destroy<_Fun>, false, -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI &typeid(typename _Fun::_Target) #else nullptr @@ -643,7 +657,7 @@ struct __policy { static const _LIBCPP_CONSTEXPR __policy __policy_ = { nullptr, nullptr, false, -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI &typeid(typename _Fun::_Target) #else nullptr @@ -656,8 +670,7 @@ struct __policy // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is // faster for types that can be passed in registers. template -using __fast_forward = - typename conditional::value, _Tp, _Tp&&>::type; +using __fast_forward = __conditional_t::value, _Tp, _Tp&&>; // __policy_invoker calls an instance of __alloc_func held in __policy_storage. @@ -733,8 +746,7 @@ template class __policy_func<_Rp(_ArgTypes...)> { typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type - _FunAlloc; + typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; if (__function::__not_null(__f)) { @@ -849,7 +861,7 @@ template class __policy_func<_Rp(_ArgTypes...)> return !__policy_->__is_null; } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI _LIBCPP_INLINE_VISIBILITY const std::type_info& target_type() const _NOEXCEPT { @@ -866,10 +878,10 @@ template class __policy_func<_Rp(_ArgTypes...)> else return reinterpret_cast(&__buf_.__small); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; -#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC) +#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) extern "C" void *_Block_copy(const void *); extern "C" void _Block_release(const void *); @@ -884,14 +896,22 @@ class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> public: _LIBCPP_INLINE_VISIBILITY explicit __func(__block_type const& __f) +#ifdef _LIBCPP_HAS_OBJC_ARC + : __f_(__f) +#else : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) +#endif { } // [TODO] add && to save on a retain _LIBCPP_INLINE_VISIBILITY explicit __func(__block_type __f, const _Alloc& /* unused */) +#ifdef _LIBCPP_HAS_OBJC_ARC + : __f_(__f) +#else : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) +#endif { } virtual __base<_Rp(_ArgTypes...)>* __clone() const { @@ -907,8 +927,10 @@ public: } virtual void destroy() _NOEXCEPT { +#ifndef _LIBCPP_HAS_OBJC_ARC if (__f_) _Block_release(__f_); +#endif __f_ = 0; } @@ -923,7 +945,7 @@ public: return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI virtual const void* target(type_info const& __ti) const _NOEXCEPT { if (__ti == typeid(__func::__block_type)) return &__f_; @@ -933,19 +955,17 @@ public: virtual const std::type_info& target_type() const _NOEXCEPT { return typeid(__func::__block_type); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; -#endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC +#endif // _LIBCPP_HAS_EXTENSION_BLOCKS -} // __function +} // namespace __function template class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> -#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES) : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> -#endif { #ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION typedef __function::__value_func<_Rp(_ArgTypes...)> __func; @@ -956,7 +976,7 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> __func __f_; template , function>, + _IsNotSame<__remove_cvref_t<_Fp>, function>, __invokable<_Fp, _ArgTypes...> >::value> struct __callable; @@ -1036,60 +1056,21 @@ public: // function invocation: _Rp operator()(_ArgTypes...) const; -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI // function target access: const std::type_info& target_type() const _NOEXCEPT; template _Tp* target() _NOEXCEPT; template const _Tp* target() const _NOEXCEPT; -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI }; -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +#if _LIBCPP_STD_VER >= 17 template function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; -template -struct __strip_signature; - -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); }; - -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); }; - -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); }; - -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); }; -template -struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); }; - template::type> function(_Fp) -> function<_Stripped>; -#endif // !_LIBCPP_HAS_NO_DEDUCTION_GUIDES +#endif // _LIBCPP_STD_VER >= 17 template function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} @@ -1175,7 +1156,7 @@ function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_NO_RTTI +#ifndef _LIBCPP_HAS_NO_RTTI template const std::type_info& @@ -1200,7 +1181,7 @@ function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT return __f_.template target<_Tp>(); } -#endif // _LIBCPP_NO_RTTI +#endif // _LIBCPP_HAS_NO_RTTI template inline _LIBCPP_INLINE_VISIBILITY @@ -1228,1582 +1209,8 @@ void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {return __x.swap(__y);} -#else // _LIBCPP_CXX03_LANG - -namespace __function { - -template class __base; - -template -class __base<_Rp()> -{ - __base(const __base&); - __base& operator=(const __base&); -public: - __base() {} - virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() = 0; - virtual void destroy_deallocate() = 0; - virtual _Rp operator()() = 0; -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const = 0; - virtual const std::type_info& target_type() const = 0; -#endif // _LIBCPP_NO_RTTI -}; - -template -class __base<_Rp(_A0)> -{ - __base(const __base&); - __base& operator=(const __base&); -public: - __base() {} - virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() = 0; - virtual void destroy_deallocate() = 0; - virtual _Rp operator()(_A0) = 0; -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const = 0; - virtual const std::type_info& target_type() const = 0; -#endif // _LIBCPP_NO_RTTI -}; - -template -class __base<_Rp(_A0, _A1)> -{ - __base(const __base&); - __base& operator=(const __base&); -public: - __base() {} - virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() = 0; - virtual void destroy_deallocate() = 0; - virtual _Rp operator()(_A0, _A1) = 0; -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const = 0; - virtual const std::type_info& target_type() const = 0; -#endif // _LIBCPP_NO_RTTI -}; - -template -class __base<_Rp(_A0, _A1, _A2)> -{ - __base(const __base&); - __base& operator=(const __base&); -public: - __base() {} - virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() = 0; - virtual void destroy_deallocate() = 0; - virtual _Rp operator()(_A0, _A1, _A2) = 0; -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const = 0; - virtual const std::type_info& target_type() const = 0; -#endif // _LIBCPP_NO_RTTI -}; - -template class __func; - -template -class __func<_Fp, _Alloc, _Rp()> - : public __base<_Rp()> -{ - __compressed_pair<_Fp, _Alloc> __f_; -public: - explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} - explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} - virtual __base<_Rp()>* __clone() const; - virtual void __clone(__base<_Rp()>*) const; - virtual void destroy(); - virtual void destroy_deallocate(); - virtual _Rp operator()(); -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const; - virtual const std::type_info& target_type() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -__base<_Rp()>* -__func<_Fp, _Alloc, _Rp()>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); - return __hold.release(); -} - -template -void -__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const -{ - ::new ((void*)__p) __func(__f_.first(), __f_.second()); -} - -template -void -__func<_Fp, _Alloc, _Rp()>::destroy() -{ - __f_.~__compressed_pair<_Fp, _Alloc>(); -} - -template -void -__func<_Fp, _Alloc, _Rp()>::destroy_deallocate() -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); - __a.deallocate(this, 1); -} - -template -_Rp -__func<_Fp, _Alloc, _Rp()>::operator()() -{ - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first()); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const void* -__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const -{ - if (__ti == typeid(_Fp)) - return &__f_.first(); - return (const void*)0; -} - -template -const std::type_info& -__func<_Fp, _Alloc, _Rp()>::target_type() const -{ - return typeid(_Fp); -} - -#endif // _LIBCPP_NO_RTTI - -template -class __func<_Fp, _Alloc, _Rp(_A0)> - : public __base<_Rp(_A0)> -{ - __compressed_pair<_Fp, _Alloc> __f_; -public: - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) - : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} - virtual __base<_Rp(_A0)>* __clone() const; - virtual void __clone(__base<_Rp(_A0)>*) const; - virtual void destroy(); - virtual void destroy_deallocate(); - virtual _Rp operator()(_A0); -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const; - virtual const std::type_info& target_type() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -__base<_Rp(_A0)>* -__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); - return __hold.release(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const -{ - ::new ((void*)__p) __func(__f_.first(), __f_.second()); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0)>::destroy() -{ - __f_.~__compressed_pair<_Fp, _Alloc>(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate() -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); - __a.deallocate(this, 1); -} - -template -_Rp -__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0) -{ - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), __a0); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const void* -__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const -{ - if (__ti == typeid(_Fp)) - return &__f_.first(); - return (const void*)0; -} - -template -const std::type_info& -__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const -{ - return typeid(_Fp); -} - -#endif // _LIBCPP_NO_RTTI - -template -class __func<_Fp, _Alloc, _Rp(_A0, _A1)> - : public __base<_Rp(_A0, _A1)> -{ - __compressed_pair<_Fp, _Alloc> __f_; -public: - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) - : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} - virtual __base<_Rp(_A0, _A1)>* __clone() const; - virtual void __clone(__base<_Rp(_A0, _A1)>*) const; - virtual void destroy(); - virtual void destroy_deallocate(); - virtual _Rp operator()(_A0, _A1); -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const; - virtual const std::type_info& target_type() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -__base<_Rp(_A0, _A1)>* -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); - return __hold.release(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const -{ - ::new ((void*)__p) __func(__f_.first(), __f_.second()); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy() -{ - __f_.~__compressed_pair<_Fp, _Alloc>(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate() -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); - __a.deallocate(this, 1); -} - -template -_Rp -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) -{ - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), __a0, __a1); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const void* -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const -{ - if (__ti == typeid(_Fp)) - return &__f_.first(); - return (const void*)0; -} - -template -const std::type_info& -__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const -{ - return typeid(_Fp); -} - -#endif // _LIBCPP_NO_RTTI - -template -class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> - : public __base<_Rp(_A0, _A1, _A2)> -{ - __compressed_pair<_Fp, _Alloc> __f_; -public: - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) - : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} - virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const; - virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const; - virtual void destroy(); - virtual void destroy_deallocate(); - virtual _Rp operator()(_A0, _A1, _A2); -#ifndef _LIBCPP_NO_RTTI - virtual const void* target(const type_info&) const; - virtual const std::type_info& target_type() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -__base<_Rp(_A0, _A1, _A2)>* -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) __func(__f_.first(), _Alloc(__a)); - return __hold.release(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const -{ - ::new ((void*)__p) __func(__f_.first(), __f_.second()); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy() -{ - __f_.~__compressed_pair<_Fp, _Alloc>(); -} - -template -void -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate() -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); - __a.deallocate(this, 1); -} - -template -_Rp -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) -{ - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), __a0, __a1, __a2); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const void* -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const -{ - if (__ti == typeid(_Fp)) - return &__f_.first(); - return (const void*)0; -} - -template -const std::type_info& -__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const -{ - return typeid(_Fp); -} - -#endif // _LIBCPP_NO_RTTI - -} // __function - -template -class _LIBCPP_TEMPLATE_VIS function<_Rp()> -{ - typedef __function::__base<_Rp()> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; - -public: - typedef _Rp result_type; - - // 20.7.16.2.1, construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} - _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} - function(const function&); - template - function(_Fp, - typename enable_if::value>::type* = 0); - - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) : __f_(0) {} - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} - template - function(allocator_arg_t, const _Alloc&, const function&); - template - function(allocator_arg_t, const _Alloc& __a, _Fp __f, - typename enable_if::value>::type* = 0); - - function& operator=(const function&); - function& operator=(nullptr_t); - template - typename enable_if - < - !is_integral<_Fp>::value, - function& - >::type - operator=(_Fp); - - ~function(); - - // 20.7.16.2.2, function modifiers: - void swap(function&); - template - _LIBCPP_INLINE_VISIBILITY - void assign(_Fp __f, const _Alloc& __a) - {function(allocator_arg, __a, __f).swap(*this);} - - // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} +_LIBCPP_END_NAMESPACE_STD -private: - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2()>&) const;// = delete; - template - bool operator!=(const function<_R2()>&) const;// = delete; -public: - // 20.7.16.2.4, function invocation: - _Rp operator()() const; - -#ifndef _LIBCPP_NO_RTTI - // 20.7.16.2.5, function target access: - const std::type_info& target_type() const; - template _Tp* target(); - template const _Tp* target() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -function<_Rp()>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp()>::function(_Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new ((void*)__f_) _FF(__f); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} - -template -template -function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp()> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new ((void*)__f_) _FF(__f, __a0); - } - else - { - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); - __f_ = __hold.release(); - } - } -} - -template -function<_Rp()>& -function<_Rp()>::operator=(const function& __f) -{ - if (__f) - function(__f).swap(*this); - else - *this = nullptr; - return *this; -} - -template -function<_Rp()>& -function<_Rp()>::operator=(nullptr_t) -{ - __base* __t = __f_; - __f_ = 0; - if (__t == (__base*)&__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); - return *this; -} - -template -template -typename enable_if -< - !is_integral<_Fp>::value, - function<_Rp()>& ->::type -function<_Rp()>::operator=(_Fp __f) -{ - function(_VSTD::move(__f)).swap(*this); - return *this; -} - -template -function<_Rp()>::~function() -{ - if (__f_ == (__base*)&__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} - -template -void -function<_Rp()>::swap(function& __f) -{ - if (_VSTD::addressof(__f) == this) - return; - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) - { - typename aligned_storage::type __tempbuf; - __base* __t = (__base*)&__tempbuf; - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); - __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f_ == (__base*)&__buf_) - { - __f_->__clone((__base*)&__f.__buf_); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f.__f_ == (__base*)&__f.__buf_) - { - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = (__base*)&__buf_; - } - else - _VSTD::swap(__f_, __f.__f_); -} - -template -_Rp -function<_Rp()>::operator()() const -{ - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const std::type_info& -function<_Rp()>::target_type() const -{ - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); -} - -template -template -_Tp* -function<_Rp()>::target() -{ - if (__f_ == 0) - return (_Tp*)0; - return (_Tp*) const_cast(__f_->target(typeid(_Tp))); -} - -template -template -const _Tp* -function<_Rp()>::target() const -{ - if (__f_ == 0) - return (const _Tp*)0; - return (const _Tp*)__f_->target(typeid(_Tp)); -} - -#endif // _LIBCPP_NO_RTTI - -template -class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)> - : public unary_function<_A0, _Rp> -{ - typedef __function::__base<_Rp(_A0)> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; - -public: - typedef _Rp result_type; - - // 20.7.16.2.1, construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} - _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} - function(const function&); - template - function(_Fp, - typename enable_if::value>::type* = 0); - - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) : __f_(0) {} - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} - template - function(allocator_arg_t, const _Alloc&, const function&); - template - function(allocator_arg_t, const _Alloc& __a, _Fp __f, - typename enable_if::value>::type* = 0); - - function& operator=(const function&); - function& operator=(nullptr_t); - template - typename enable_if - < - !is_integral<_Fp>::value, - function& - >::type - operator=(_Fp); - - ~function(); - - // 20.7.16.2.2, function modifiers: - void swap(function&); - template - _LIBCPP_INLINE_VISIBILITY - void assign(_Fp __f, const _Alloc& __a) - {function(allocator_arg, __a, __f).swap(*this);} - - // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} - -private: - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2(_B0)>&) const;// = delete; - template - bool operator!=(const function<_R2(_B0)>&) const;// = delete; -public: - // 20.7.16.2.4, function invocation: - _Rp operator()(_A0) const; - -#ifndef _LIBCPP_NO_RTTI - // 20.7.16.2.5, function target access: - const std::type_info& target_type() const; - template _Tp* target(); - template const _Tp* target() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -function<_Rp(_A0)>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0)>::function(_Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new ((void*)__f_) _FF(__f); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} - -template -template -function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new ((void*)__f_) _FF(__f, __a0); - } - else - { - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); - __f_ = __hold.release(); - } - } -} - -template -function<_Rp(_A0)>& -function<_Rp(_A0)>::operator=(const function& __f) -{ - if (__f) - function(__f).swap(*this); - else - *this = nullptr; - return *this; -} - -template -function<_Rp(_A0)>& -function<_Rp(_A0)>::operator=(nullptr_t) -{ - __base* __t = __f_; - __f_ = 0; - if (__t == (__base*)&__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); - return *this; -} - -template -template -typename enable_if -< - !is_integral<_Fp>::value, - function<_Rp(_A0)>& ->::type -function<_Rp(_A0)>::operator=(_Fp __f) -{ - function(_VSTD::move(__f)).swap(*this); - return *this; -} - -template -function<_Rp(_A0)>::~function() -{ - if (__f_ == (__base*)&__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} - -template -void -function<_Rp(_A0)>::swap(function& __f) -{ - if (_VSTD::addressof(__f) == this) - return; - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) - { - typename aligned_storage::type __tempbuf; - __base* __t = (__base*)&__tempbuf; - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); - __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f_ == (__base*)&__buf_) - { - __f_->__clone((__base*)&__f.__buf_); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f.__f_ == (__base*)&__f.__buf_) - { - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = (__base*)&__buf_; - } - else - _VSTD::swap(__f_, __f.__f_); -} - -template -_Rp -function<_Rp(_A0)>::operator()(_A0 __a0) const -{ - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(__a0); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const std::type_info& -function<_Rp(_A0)>::target_type() const -{ - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); -} - -template -template -_Tp* -function<_Rp(_A0)>::target() -{ - if (__f_ == 0) - return (_Tp*)0; - return (_Tp*) const_cast(__f_->target(typeid(_Tp))); -} - -template -template -const _Tp* -function<_Rp(_A0)>::target() const -{ - if (__f_ == 0) - return (const _Tp*)0; - return (const _Tp*)__f_->target(typeid(_Tp)); -} - -#endif // _LIBCPP_NO_RTTI - -template -class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)> - : public binary_function<_A0, _A1, _Rp> -{ - typedef __function::__base<_Rp(_A0, _A1)> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; - -public: - typedef _Rp result_type; - - // 20.7.16.2.1, construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} - _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} - function(const function&); - template - function(_Fp, - typename enable_if::value>::type* = 0); - - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) : __f_(0) {} - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} - template - function(allocator_arg_t, const _Alloc&, const function&); - template - function(allocator_arg_t, const _Alloc& __a, _Fp __f, - typename enable_if::value>::type* = 0); - - function& operator=(const function&); - function& operator=(nullptr_t); - template - typename enable_if - < - !is_integral<_Fp>::value, - function& - >::type - operator=(_Fp); - - ~function(); - - // 20.7.16.2.2, function modifiers: - void swap(function&); - template - _LIBCPP_INLINE_VISIBILITY - void assign(_Fp __f, const _Alloc& __a) - {function(allocator_arg, __a, __f).swap(*this);} - - // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} - -private: - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete; - template - bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete; -public: - // 20.7.16.2.4, function invocation: - _Rp operator()(_A0, _A1) const; - -#ifndef _LIBCPP_NO_RTTI - // 20.7.16.2.5, function target access: - const std::type_info& target_type() const; - template _Tp* target(); - template const _Tp* target() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -function<_Rp(_A0, _A1)>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0, _A1)>::function(_Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new ((void*)__f_) _FF(__f); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} - -template -template -function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new ((void*)__f_) _FF(__f, __a0); - } - else - { - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); - __f_ = __hold.release(); - } - } -} - -template -function<_Rp(_A0, _A1)>& -function<_Rp(_A0, _A1)>::operator=(const function& __f) -{ - if (__f) - function(__f).swap(*this); - else - *this = nullptr; - return *this; -} - -template -function<_Rp(_A0, _A1)>& -function<_Rp(_A0, _A1)>::operator=(nullptr_t) -{ - __base* __t = __f_; - __f_ = 0; - if (__t == (__base*)&__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); - return *this; -} - -template -template -typename enable_if -< - !is_integral<_Fp>::value, - function<_Rp(_A0, _A1)>& ->::type -function<_Rp(_A0, _A1)>::operator=(_Fp __f) -{ - function(_VSTD::move(__f)).swap(*this); - return *this; -} - -template -function<_Rp(_A0, _A1)>::~function() -{ - if (__f_ == (__base*)&__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} - -template -void -function<_Rp(_A0, _A1)>::swap(function& __f) -{ - if (_VSTD::addressof(__f) == this) - return; - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) - { - typename aligned_storage::type __tempbuf; - __base* __t = (__base*)&__tempbuf; - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); - __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f_ == (__base*)&__buf_) - { - __f_->__clone((__base*)&__f.__buf_); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f.__f_ == (__base*)&__f.__buf_) - { - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = (__base*)&__buf_; - } - else - _VSTD::swap(__f_, __f.__f_); -} - -template -_Rp -function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const -{ - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(__a0, __a1); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const std::type_info& -function<_Rp(_A0, _A1)>::target_type() const -{ - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); -} - -template -template -_Tp* -function<_Rp(_A0, _A1)>::target() -{ - if (__f_ == 0) - return (_Tp*)0; - return (_Tp*) const_cast(__f_->target(typeid(_Tp))); -} - -template -template -const _Tp* -function<_Rp(_A0, _A1)>::target() const -{ - if (__f_ == 0) - return (const _Tp*)0; - return (const _Tp*)__f_->target(typeid(_Tp)); -} - -#endif // _LIBCPP_NO_RTTI - -template -class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)> -{ - typedef __function::__base<_Rp(_A0, _A1, _A2)> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; - -public: - typedef _Rp result_type; - - // 20.7.16.2.1, construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} - _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} - function(const function&); - template - function(_Fp, - typename enable_if::value>::type* = 0); - - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) : __f_(0) {} - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} - template - function(allocator_arg_t, const _Alloc&, const function&); - template - function(allocator_arg_t, const _Alloc& __a, _Fp __f, - typename enable_if::value>::type* = 0); - - function& operator=(const function&); - function& operator=(nullptr_t); - template - typename enable_if - < - !is_integral<_Fp>::value, - function& - >::type - operator=(_Fp); - - ~function(); - - // 20.7.16.2.2, function modifiers: - void swap(function&); - template - _LIBCPP_INLINE_VISIBILITY - void assign(_Fp __f, const _Alloc& __a) - {function(allocator_arg, __a, __f).swap(*this);} - - // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} - -private: - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; - template - bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; -public: - // 20.7.16.2.4, function invocation: - _Rp operator()(_A0, _A1, _A2) const; - -#ifndef _LIBCPP_NO_RTTI - // 20.7.16.2.5, function target access: - const std::type_info& target_type() const; - template _Tp* target(); - template const _Tp* target() const; -#endif // _LIBCPP_NO_RTTI -}; - -template -function<_Rp(_A0, _A1, _A2)>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&, - const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) - { - __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} - -template -template -function<_Rp(_A0, _A1, _A2)>::function(_Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new ((void*)__f_) _FF(__f); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _FF(__f, allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} - -template -template -function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, - typename enable_if::value>::type*) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF; - if (sizeof(_FF) <= sizeof(__buf_)) - { - __f_ = (__base*)&__buf_; - ::new ((void*)__f_) _FF(__f, __a0); - } - else - { - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _FF(__f, _Alloc(__a)); - __f_ = __hold.release(); - } - } -} - -template -function<_Rp(_A0, _A1, _A2)>& -function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) -{ - if (__f) - function(__f).swap(*this); - else - *this = nullptr; - return *this; -} - -template -function<_Rp(_A0, _A1, _A2)>& -function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t) -{ - __base* __t = __f_; - __f_ = 0; - if (__t == (__base*)&__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); - return *this; -} - -template -template -typename enable_if -< - !is_integral<_Fp>::value, - function<_Rp(_A0, _A1, _A2)>& ->::type -function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) -{ - function(_VSTD::move(__f)).swap(*this); - return *this; -} - -template -function<_Rp(_A0, _A1, _A2)>::~function() -{ - if (__f_ == (__base*)&__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} - -template -void -function<_Rp(_A0, _A1, _A2)>::swap(function& __f) -{ - if (_VSTD::addressof(__f) == this) - return; - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) - { - typename aligned_storage::type __tempbuf; - __base* __t = (__base*)&__tempbuf; - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); - __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f_ == (__base*)&__buf_) - { - __f_->__clone((__base*)&__f.__buf_); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; - } - else if (__f.__f_ == (__base*)&__f.__buf_) - { - __f.__f_->__clone((__base*)&__buf_); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = (__base*)&__buf_; - } - else - _VSTD::swap(__f_, __f.__f_); -} - -template -_Rp -function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const -{ - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(__a0, __a1, __a2); -} - -#ifndef _LIBCPP_NO_RTTI - -template -const std::type_info& -function<_Rp(_A0, _A1, _A2)>::target_type() const -{ - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); -} - -template -template -_Tp* -function<_Rp(_A0, _A1, _A2)>::target() -{ - if (__f_ == 0) - return (_Tp*)0; - return (_Tp*) const_cast(__f_->target(typeid(_Tp))); -} - -template -template -const _Tp* -function<_Rp(_A0, _A1, _A2)>::target() const -{ - if (__f_ == 0) - return (const _Tp*)0; - return (const _Tp*)__f_->target(typeid(_Tp)); -} - -#endif // _LIBCPP_NO_RTTI - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const function<_Fp>& __f, nullptr_t) {return !__f;} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(nullptr_t, const function<_Fp>& __f) {return !__f;} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} - -template -inline _LIBCPP_INLINE_VISIBILITY -void -swap(function<_Fp>& __x, function<_Fp>& __y) -{return __x.swap(__y);} - -#endif - -_LIBCPP_END_NAMESPACE_STD +#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H diff --git a/gnu/llvm/libcxx/include/__functional/hash.h b/gnu/llvm/libcxx/include/__functional/hash.h index ebcbbad1338..39382aa9bff 100644 --- a/gnu/llvm/libcxx/include/__functional/hash.h +++ b/gnu/llvm/libcxx/include/__functional/hash.h @@ -10,25 +10,28 @@ #define _LIBCPP___FUNCTIONAL_HASH_H #include <__config> +#include <__functional/invoke.h> #include <__functional/unary_function.h> -#include <__tuple> +#include <__fwd/hash.h> +#include <__tuple_dir/sfinae_helpers.h> +#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_default_constructible.h> +#include <__type_traits/is_enum.h> +#include <__type_traits/is_move_constructible.h> +#include <__type_traits/underlying_type.h> #include <__utility/forward.h> #include <__utility/move.h> #include <__utility/pair.h> #include <__utility/swap.h> +#include #include #include -#include #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template @@ -65,7 +68,7 @@ __murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len) const unsigned char* __data = static_cast(__key); for (; __len >= 4; __data += 4, __len -= 4) { - _Size __k = __loadword<_Size>(__data); + _Size __k = std::__loadword<_Size>(__data); __k *= __m; __k ^= __k >> __r; __k *= __m; @@ -130,14 +133,18 @@ struct __murmur2_or_cityhash<_Size, 64> _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { if (__len > 8) { - const _Size __a = __loadword<_Size>(__s); - const _Size __b = __loadword<_Size>(__s + __len - 8); + const _Size __a = std::__loadword<_Size>(__s); + const _Size __b = std::__loadword<_Size>(__s + __len - 8); return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b; } if (__len >= 4) { - const uint32_t __a = __loadword(__s); - const uint32_t __b = __loadword(__s + __len - 4); + const uint32_t __a = std::__loadword(__s); + const uint32_t __b = std::__loadword(__s + __len - 4); +#ifdef _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION + return __hash_len_16(__len + (static_cast<_Size>(__a) << 3), __b); +#else return __hash_len_16(__len + (__a << 3), __b); +#endif } if (__len > 0) { const unsigned char __a = static_cast(__s[0]); @@ -154,10 +161,10 @@ struct __murmur2_or_cityhash<_Size, 64> static _Size __hash_len_17_to_32(const char *__s, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { - const _Size __a = __loadword<_Size>(__s) * __k1; - const _Size __b = __loadword<_Size>(__s + 8); - const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2; - const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0; + const _Size __a = std::__loadword<_Size>(__s) * __k1; + const _Size __b = std::__loadword<_Size>(__s + 8); + const _Size __c = std::__loadword<_Size>(__s + __len - 8) * __k2; + const _Size __d = std::__loadword<_Size>(__s + __len - 16) * __k0; return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d, __a + __rotate(__b ^ __k3, 20) - __c + __len); } @@ -182,10 +189,10 @@ struct __murmur2_or_cityhash<_Size, 64> const char* __s, _Size __a, _Size __b) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { - return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s), - __loadword<_Size>(__s + 8), - __loadword<_Size>(__s + 16), - __loadword<_Size>(__s + 24), + return __weak_hash_len_32_with_seeds(std::__loadword<_Size>(__s), + std::__loadword<_Size>(__s + 8), + std::__loadword<_Size>(__s + 16), + std::__loadword<_Size>(__s + 24), __a, __b); } @@ -194,23 +201,23 @@ struct __murmur2_or_cityhash<_Size, 64> static _Size __hash_len_33_to_64(const char *__s, size_t __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { - _Size __z = __loadword<_Size>(__s + 24); - _Size __a = __loadword<_Size>(__s) + - (__len + __loadword<_Size>(__s + __len - 16)) * __k0; + _Size __z = std::__loadword<_Size>(__s + 24); + _Size __a = std::__loadword<_Size>(__s) + + (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0; _Size __b = __rotate(__a + __z, 52); _Size __c = __rotate(__a, 37); - __a += __loadword<_Size>(__s + 8); + __a += std::__loadword<_Size>(__s + 8); __c += __rotate(__a, 7); - __a += __loadword<_Size>(__s + 16); + __a += std::__loadword<_Size>(__s + 16); _Size __vf = __a + __z; _Size __vs = __b + __rotate(__a, 31) + __c; - __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32); - __z += __loadword<_Size>(__s + __len - 8); + __a = std::__loadword<_Size>(__s + 16) + std::__loadword<_Size>(__s + __len - 32); + __z += std::__loadword<_Size>(__s + __len - 8); __b = __rotate(__a + __z, 52); __c = __rotate(__a, 37); - __a += __loadword<_Size>(__s + __len - 24); + __a += std::__loadword<_Size>(__s + __len - 24); __c += __rotate(__a, 7); - __a += __loadword<_Size>(__s + __len - 16); + __a += std::__loadword<_Size>(__s + __len - 16); _Size __wf = __a + __z; _Size __ws = __b + __rotate(__a, 31) + __c; _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0); @@ -236,26 +243,26 @@ __murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len) // For strings over 64 bytes we hash the end first, and then as we // loop we keep 56 bytes of state: v, w, x, y, and z. - _Size __x = __loadword<_Size>(__s + __len - 40); - _Size __y = __loadword<_Size>(__s + __len - 16) + - __loadword<_Size>(__s + __len - 56); - _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len, - __loadword<_Size>(__s + __len - 24)); + _Size __x = std::__loadword<_Size>(__s + __len - 40); + _Size __y = std::__loadword<_Size>(__s + __len - 16) + + std::__loadword<_Size>(__s + __len - 56); + _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, + std::__loadword<_Size>(__s + __len - 24)); pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z); pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x); - __x = __x * __k1 + __loadword<_Size>(__s); + __x = __x * __k1 + std::__loadword<_Size>(__s); // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. __len = (__len - 1) & ~static_cast<_Size>(63); do { - __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1; - __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1; + __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1; + __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1; __x ^= __w.second; - __y += __v.first + __loadword<_Size>(__s + 40); + __y += __v.first + std::__loadword<_Size>(__s + 40); __z = __rotate(__z + __w.first, 33) * __k1; __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, - __y + __loadword<_Size>(__s + 16)); + __y + std::__loadword<_Size>(__s + 16)); _VSTD::swap(__z, __x); __s += 64; __len -= 64; @@ -268,18 +275,10 @@ __murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len) template struct __scalar_hash; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template struct __scalar_hash<_Tp, 0> -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function<_Tp, size_t> -#endif + : public __unary_function<_Tp, size_t> { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(_Tp __v) const _NOEXCEPT { @@ -294,18 +293,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP } }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template struct __scalar_hash<_Tp, 1> -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function<_Tp, size_t> -#endif + : public __unary_function<_Tp, size_t> { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(_Tp __v) const _NOEXCEPT { @@ -319,18 +310,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP } }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template struct __scalar_hash<_Tp, 2> -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function<_Tp, size_t> -#endif + : public __unary_function<_Tp, size_t> { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(_Tp __v) const _NOEXCEPT { @@ -348,18 +331,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP } }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template struct __scalar_hash<_Tp, 3> -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function<_Tp, size_t> -#endif + : public __unary_function<_Tp, size_t> { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(_Tp __v) const _NOEXCEPT { @@ -378,18 +353,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP } }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template struct __scalar_hash<_Tp, 4> -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function<_Tp, size_t> -#endif + : public __unary_function<_Tp, size_t> { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(_Tp __v) const _NOEXCEPT { @@ -421,18 +388,10 @@ inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { return _HashT()(__p); } -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function<_Tp*, size_t> -#endif + : public __unary_function<_Tp*, size_t> { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(_Tp* __v) const _NOEXCEPT { @@ -446,232 +405,118 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP } }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(bool __v) const _NOEXCEPT {return static_cast(__v);} }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef char argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(char __v) const _NOEXCEPT {return static_cast(__v);} }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef signed char argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(signed char __v) const _NOEXCEPT {return static_cast(__v);} }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned char argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast(__v);} }; #ifndef _LIBCPP_HAS_NO_CHAR8_T -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef char8_t argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast(__v);} }; #endif // !_LIBCPP_HAS_NO_CHAR8_T -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef char16_t argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast(__v);} }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef char32_t argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast(__v);} }; -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - -_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef wchar_t argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast(__v);} }; +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef short argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(short __v) const _NOEXCEPT {return static_cast(__v);} }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned short argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast(__v);} }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef int argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(int __v) const _NOEXCEPT {return static_cast(__v);} }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned int argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast(__v);} }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef long argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(long __v) const _NOEXCEPT {return static_cast(__v);} }; -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef unsigned long argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast(__v);} }; @@ -782,25 +627,15 @@ struct _LIBCPP_TEMPLATE_VIS hash } }; -#if _LIBCPP_STD_VER > 11 - -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template ::value> struct _LIBCPP_TEMPLATE_VIS __enum_hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function<_Tp, size_t> -#endif + : public __unary_function<_Tp, size_t> { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(_Tp __v) const _NOEXCEPT { typedef typename underlying_type<_Tp>::type type; - return hash{}(static_cast(__v)); + return hash()(static_cast(__v)); } }; template @@ -814,22 +649,13 @@ template struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp> { }; -#endif #if _LIBCPP_STD_VER > 14 -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <> struct _LIBCPP_TEMPLATE_VIS hash -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public unary_function -#endif + : public __unary_function { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef nullptr_t argument_type; -#endif _LIBCPP_INLINE_VISIBILITY size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; @@ -839,35 +665,33 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP #ifndef _LIBCPP_CXX03_LANG template -using __check_hash_requirements _LIBCPP_NODEBUG_TYPE = integral_constant::value && is_move_constructible<_Hash>::value && __invokable_r::value >; template > -using __has_enabled_hash _LIBCPP_NODEBUG_TYPE = integral_constant::value && is_default_constructible<_Hash>::value >; #if _LIBCPP_STD_VER > 14 template -using __enable_hash_helper_imp _LIBCPP_NODEBUG_TYPE = _Type; +using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type; template -using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = __enable_hash_helper_imp<_Type, +using __enable_hash_helper _LIBCPP_NODEBUG = __enable_hash_helper_imp<_Type, typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type >; #else template -using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = _Type; +using __enable_hash_helper _LIBCPP_NODEBUG = _Type; #endif #endif // !_LIBCPP_CXX03_LANG _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___FUNCTIONAL_HASH_H diff --git a/gnu/llvm/libcxx/include/__functional/identity.h b/gnu/llvm/libcxx/include/__functional/identity.h index 6b8346b3b2a..2fe3acca089 100644 --- a/gnu/llvm/libcxx/include/__functional/identity.h +++ b/gnu/llvm/libcxx/include/__functional/identity.h @@ -11,14 +11,23 @@ #define _LIBCPP___FUNCTIONAL_IDENTITY_H #include <__config> -#include +#include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD +struct __identity { + template + _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT { + return std::forward<_Tp>(__t); + } + + using is_transparent = void; +}; + #if _LIBCPP_STD_VER > 17 struct identity { diff --git a/gnu/llvm/libcxx/include/__functional/invoke.h b/gnu/llvm/libcxx/include/__functional/invoke.h index 0e167c75d69..48e6eac3ce9 100644 --- a/gnu/llvm/libcxx/include/__functional/invoke.h +++ b/gnu/llvm/libcxx/include/__functional/invoke.h @@ -11,82 +11,528 @@ #define _LIBCPP___FUNCTIONAL_INVOKE_H #include <__config> -#include <__functional/weak_result_type.h> +#include <__type_traits/add_lvalue_reference.h> +#include <__type_traits/apply_cv.h> +#include <__type_traits/conditional.h> +#include <__type_traits/decay.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_base_of.h> +#include <__type_traits/is_core_convertible.h> +#include <__type_traits/is_member_function_pointer.h> +#include <__type_traits/is_member_object_pointer.h> +#include <__type_traits/is_reference_wrapper.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_void.h> +#include <__type_traits/nat.h> +#include <__type_traits/remove_cv.h> +#include <__utility/declval.h> #include <__utility/forward.h> -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif +// TODO: Disentangle the type traits and std::invoke properly + _LIBCPP_BEGIN_NAMESPACE_STD -template ::value> -struct __invoke_void_return_wrapper +struct __any { -#ifndef _LIBCPP_CXX03_LANG - template - static _Ret __call(_Args&&... __args) { - return _VSTD::__invoke(_VSTD::forward<_Args>(__args)...); - } + __any(...); +}; + +template +struct __member_pointer_traits_imp +{ +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> +{ + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false> +{ + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false> +{ + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false> +{ + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false> +{ + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false> +{ + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false> +{ + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false> +{ + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false> +{ + typedef _Class& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false> +{ + typedef _Class& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false> +{ + typedef _Class const& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false> +{ + typedef _Class const& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false> +{ + typedef _Class volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false> +{ + typedef _Class volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false> +{ + typedef _Class const volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false> +{ + typedef _Class const volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false> +{ + typedef _Class&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false> +{ + typedef _Class&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false> +{ + typedef _Class const&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false> +{ + typedef _Class const&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false> +{ + typedef _Class volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false> +{ + typedef _Class volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false> +{ + typedef _Class const volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); +}; + +template +struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false> +{ + typedef _Class const volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); +}; + +template +struct __member_pointer_traits_imp<_Rp _Class::*, false, true> +{ + typedef _Class _ClassType; + typedef _Rp _ReturnType; +}; + +template +struct __member_pointer_traits + : public __member_pointer_traits_imp<__remove_cv_t<_MP>, + is_member_function_pointer<_MP>::value, + is_member_object_pointer<_MP>::value> +{ +// typedef ... _ClassType; +// typedef ... _ReturnType; +// typedef ... _FnType; +}; + +template +struct __member_pointer_class_type {}; + +template +struct __member_pointer_class_type<_Ret _ClassType::*> { + typedef _ClassType type; +}; + +template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet1 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type> +using __enable_if_bullet2 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet3 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet4 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type> +using __enable_if_bullet5 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + +template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet6 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + +// __invoke forward declarations + +// fall back - none of the bullets + +template +__nat __invoke(__any, _Args&& ...__args); + +// bullets 1, 2 and 3 + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))) + { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); } + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...))) + { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); } + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))) + { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); } + +// bullets 4, 5 and 6 + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().*std::declval<_Fp>()) +__invoke(_Fp&& __f, _A0&& __a0) + _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f)) + { return static_cast<_A0&&>(__a0).*__f; } + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype(std::declval<_A0>().get().*std::declval<_Fp>()) +__invoke(_Fp&& __f, _A0&& __a0) + _NOEXCEPT_(noexcept(__a0.get().*__f)) + { return __a0.get().*__f; } + +template > +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype((*std::declval<_A0>()).*std::declval<_Fp>()) +__invoke(_Fp&& __f, _A0&& __a0) + _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f)) + { return (*static_cast<_A0&&>(__a0)).*__f; } + +// bullet 7 + +template +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR decltype(std::declval<_Fp>()(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _Args&& ...__args) + _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))) + { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); } + +// __invokable +template +struct __invokable_r +{ + template + static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int); + template + static __nat __try_call(...); + + // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, + // or incomplete array types as required by the standard. + using _Result = decltype(__try_call<_Fp, _Args...>(0)); + + using type = __conditional_t< + _IsNotSame<_Result, __nat>::value, + __conditional_t::value, true_type, __is_core_convertible<_Result, _Ret> >, + false_type>; + static const bool value = type::value; +}; +template +using __invokable = __invokable_r; + +template +struct __nothrow_invokable_r_imp { + static const bool value = false; +}; + +template +struct __nothrow_invokable_r_imp +{ + typedef __nothrow_invokable_r_imp _ThisT; + + template + static void __test_noexcept(_Tp) _NOEXCEPT; + +#ifdef _LIBCPP_CXX03_LANG + static const bool value = false; #else - template - static _Ret __call(_Fn __f) { - return _VSTD::__invoke(__f); - } + static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>( + _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...))); +#endif +}; - template - static _Ret __call(_Fn __f, _A0& __a0) { - return _VSTD::__invoke(__f, __a0); - } +template +struct __nothrow_invokable_r_imp +{ +#ifdef _LIBCPP_CXX03_LANG + static const bool value = false; +#else + static const bool value = noexcept( + _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)); +#endif +}; - template - static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { - return _VSTD::__invoke(__f, __a0, __a1); - } +template +using __nothrow_invokable_r = + __nothrow_invokable_r_imp< + __invokable_r<_Ret, _Fp, _Args...>::value, + is_void<_Ret>::value, + _Ret, _Fp, _Args... + >; + +template +using __nothrow_invokable = + __nothrow_invokable_r_imp< + __invokable<_Fp, _Args...>::value, + true, void, _Fp, _Args... + >; + +template +struct __invoke_of + : public enable_if< + __invokable<_Fp, _Args...>::value, + typename __invokable_r::_Result> +{ +}; - template - static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ - return _VSTD::__invoke(__f, __a0, __a1, __a2); +template ::value> +struct __invoke_void_return_wrapper +{ + template + static _Ret __call(_Args&&... __args) { + return std::__invoke(std::forward<_Args>(__args)...); } -#endif }; template struct __invoke_void_return_wrapper<_Ret, true> { -#ifndef _LIBCPP_CXX03_LANG template static void __call(_Args&&... __args) { - _VSTD::__invoke(_VSTD::forward<_Args>(__args)...); - } -#else - template - static void __call(_Fn __f) { - _VSTD::__invoke(__f); + std::__invoke(std::forward<_Args>(__args)...); } +}; - template - static void __call(_Fn __f, _A0& __a0) { - _VSTD::__invoke(__f, __a0); - } +#if _LIBCPP_STD_VER > 14 - template - static void __call(_Fn __f, _A0& __a0, _A1& __a1) { - _VSTD::__invoke(__f, __a0, __a1); - } +// is_invocable - template - static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { - _VSTD::__invoke(__f, __a0, __a1, __a2); - } -#endif +template +struct _LIBCPP_TEMPLATE_VIS is_invocable + : integral_constant::value> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_invocable_r + : integral_constant::value> {}; + +template +inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; + +template +inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value; + +// is_nothrow_invocable + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable + : integral_constant::value> {}; + +template +struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r + : integral_constant::value> {}; + +template +inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value; + +template +inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; + +template +struct _LIBCPP_TEMPLATE_VIS invoke_result + : __invoke_of<_Fn, _Args...> +{ }; -#if _LIBCPP_STD_VER > 14 +template +using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; template -_LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 invoke_result_t<_Fn, _Args...> invoke(_Fn&& __f, _Args&&... __args) noexcept(is_nothrow_invocable_v<_Fn, _Args...>) { diff --git a/gnu/llvm/libcxx/include/__functional/is_transparent.h b/gnu/llvm/libcxx/include/__functional/is_transparent.h index 4a72aa8e29e..c7a0ee9ee7b 100644 --- a/gnu/llvm/libcxx/include/__functional/is_transparent.h +++ b/gnu/llvm/libcxx/include/__functional/is_transparent.h @@ -14,7 +14,7 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -25,8 +25,7 @@ template struct __is_transparent : false_type {}; template -struct __is_transparent<_Tp, _Up, - typename __void_t::type> +struct __is_transparent<_Tp, _Up, __void_t > : true_type {}; #endif diff --git a/gnu/llvm/libcxx/include/__functional/mem_fn.h b/gnu/llvm/libcxx/include/__functional/mem_fn.h index 1fa070a42cc..8b51627079c 100644 --- a/gnu/llvm/libcxx/include/__functional/mem_fn.h +++ b/gnu/llvm/libcxx/include/__functional/mem_fn.h @@ -11,22 +11,20 @@ #define _LIBCPP___FUNCTIONAL_MEM_FN_H #include <__config> -#include <__functional/weak_result_type.h> #include <__functional/binary_function.h> #include <__functional/invoke.h> -#include +#include <__functional/weak_result_type.h> +#include <__utility/forward.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD template -class __mem_fn -#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public __weak_result_type<_Tp> -#endif +class __mem_fn : public __weak_result_type<_Tp> { public: // types @@ -35,121 +33,21 @@ private: type __f_; public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn(type __f) _NOEXCEPT : __f_(__f) {} -#ifndef _LIBCPP_CXX03_LANG // invoke template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename __invoke_return::type operator() (_ArgTypes&&... __args) const { - return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...); + return std::__invoke(__f_, std::forward<_ArgTypes>(__args)...); } -#else - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return0::type - operator() (_A0& __a0) const { - return _VSTD::__invoke(__f_, __a0); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return0::type - operator() (_A0 const& __a0) const { - return _VSTD::__invoke(__f_, __a0); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0& __a0, _A1& __a1) const { - return _VSTD::__invoke(__f_, __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0 const& __a0, _A1& __a1) const { - return _VSTD::__invoke(__f_, __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0& __a0, _A1 const& __a1) const { - return _VSTD::__invoke(__f_, __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0 const& __a0, _A1 const& __a1) const { - return _VSTD::__invoke(__f_, __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { - return _VSTD::__invoke(__f_, __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { - return _VSTD::__invoke(__f_, __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { - return _VSTD::__invoke(__f_, __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { - return _VSTD::__invoke(__f_, __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { - return _VSTD::__invoke(__f_, __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { - return _VSTD::__invoke(__f_, __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { - return _VSTD::__invoke(__f_, __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { - return _VSTD::__invoke(__f_, __a0, __a1, __a2); - } -#endif }; template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> mem_fn(_Rp _Tp::* __pm) _NOEXCEPT { diff --git a/gnu/llvm/libcxx/include/__functional/mem_fun_ref.h b/gnu/llvm/libcxx/include/__functional/mem_fun_ref.h index 4616da0b074..65aab0696c1 100644 --- a/gnu/llvm/libcxx/include/__functional/mem_fun_ref.h +++ b/gnu/llvm/libcxx/include/__functional/mem_fun_ref.h @@ -11,11 +11,11 @@ #define _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H #include <__config> -#include <__functional/unary_function.h> #include <__functional/binary_function.h> +#include <__functional/unary_function.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t - : public unary_function<_Tp*, _Sp> + : public __unary_function<_Tp*, _Sp> { _Sp (_Tp::*__p_)(); public: @@ -36,7 +36,7 @@ public: template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t - : public binary_function<_Tp*, _Ap, _Sp> + : public __binary_function<_Tp*, _Ap, _Sp> { _Sp (_Tp::*__p_)(_Ap); public: @@ -60,7 +60,7 @@ mem_fun(_Sp (_Tp::*__f)(_Ap)) template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t - : public unary_function<_Tp, _Sp> + : public __unary_function<_Tp, _Sp> { _Sp (_Tp::*__p_)(); public: @@ -72,7 +72,7 @@ public: template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t - : public binary_function<_Tp, _Ap, _Sp> + : public __binary_function<_Tp, _Ap, _Sp> { _Sp (_Tp::*__p_)(_Ap); public: @@ -96,7 +96,7 @@ mem_fun_ref(_Sp (_Tp::*__f)(_Ap)) template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t - : public unary_function + : public __unary_function { _Sp (_Tp::*__p_)() const; public: @@ -108,7 +108,7 @@ public: template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t - : public binary_function + : public __binary_function { _Sp (_Tp::*__p_)(_Ap) const; public: @@ -132,7 +132,7 @@ mem_fun(_Sp (_Tp::*__f)(_Ap) const) template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t - : public unary_function<_Tp, _Sp> + : public __unary_function<_Tp, _Sp> { _Sp (_Tp::*__p_)() const; public: @@ -144,7 +144,7 @@ public: template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t - : public binary_function<_Tp, _Ap, _Sp> + : public __binary_function<_Tp, _Ap, _Sp> { _Sp (_Tp::*__p_)(_Ap) const; public: diff --git a/gnu/llvm/libcxx/include/__functional/not_fn.h b/gnu/llvm/libcxx/include/__functional/not_fn.h index 632be5ff096..79d9a8710bd 100644 --- a/gnu/llvm/libcxx/include/__functional/not_fn.h +++ b/gnu/llvm/libcxx/include/__functional/not_fn.h @@ -11,33 +11,40 @@ #define _LIBCPP___FUNCTIONAL_NOT_FN_H #include <__config> -#include <__functional/perfect_forward.h> #include <__functional/invoke.h> -#include +#include <__functional/perfect_forward.h> +#include <__utility/forward.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 -struct __not_fn_op -{ - template - static _LIBCPP_CONSTEXPR_AFTER_CXX17 auto __call(_Args&&... __args) - noexcept(noexcept(!_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) - -> decltype( !_VSTD::invoke(_VSTD::forward<_Args>(__args)...)) - { return !_VSTD::invoke(_VSTD::forward<_Args>(__args)...); } +struct __not_fn_op { + template + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX20 auto operator()(_Args&&... __args) const + noexcept(noexcept(!_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) + -> decltype( !_VSTD::invoke(_VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(_VSTD::forward<_Args>(__args)...); } +}; + +template +struct __not_fn_t : __perfect_forward<__not_fn_op, _Fn> { + using __perfect_forward<__not_fn_op, _Fn>::__perfect_forward; }; -template, _Fn> && - is_move_constructible_v<_Fn>>> -_LIBCPP_CONSTEXPR_AFTER_CXX17 auto not_fn(_Fn&& __f) -{ - return __perfect_forward<__not_fn_op, _Fn>(_VSTD::forward<_Fn>(__f)); +template , _Fn> && + is_move_constructible_v> +>> +_LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) { + return __not_fn_t>(_VSTD::forward<_Fn>(__f)); } #endif // _LIBCPP_STD_VER > 14 diff --git a/gnu/llvm/libcxx/include/__functional/operations.h b/gnu/llvm/libcxx/include/__functional/operations.h index 667d17988bc..8a781efbdbb 100644 --- a/gnu/llvm/libcxx/include/__functional/operations.h +++ b/gnu/llvm/libcxx/include/__functional/operations.h @@ -16,710 +16,561 @@ #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD // Arithmetic operations -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS plus -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, _Tp> -#endif + : __binary_function<_Tp, _Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef _Tp __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x + __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS plus { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS minus -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, _Tp> -#endif + : __binary_function<_Tp, _Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef _Tp __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x - __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS minus { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS multiplies -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, _Tp> -#endif + : __binary_function<_Tp, _Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef _Tp __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x * __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS multiplies { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS divides -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, _Tp> -#endif + : __binary_function<_Tp, _Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef _Tp __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x / __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS divides { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS modulus -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, _Tp> -#endif + : __binary_function<_Tp, _Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef _Tp __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x % __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS modulus { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS negate -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : unary_function<_Tp, _Tp> -#endif + : __unary_function<_Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef _Tp __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x) const {return -__x;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS negate { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_Tp&& __x) const - _NOEXCEPT_(noexcept(- _VSTD::forward<_Tp>(__x))) - -> decltype (- _VSTD::forward<_Tp>(__x)) - { return - _VSTD::forward<_Tp>(__x); } + noexcept(noexcept(- _VSTD::forward<_Tp>(__x))) + -> decltype( - _VSTD::forward<_Tp>(__x)) + { return - _VSTD::forward<_Tp>(__x); } typedef void is_transparent; }; #endif // Bitwise operations -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS bit_and -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, _Tp> -#endif + : __binary_function<_Tp, _Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef _Tp __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x & __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS bit_and { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif #if _LIBCPP_STD_VER > 11 -_LIBCPP_SUPPRESS_DEPRECATED_PUSH template struct _LIBCPP_TEMPLATE_VIS bit_not -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : unary_function<_Tp, _Tp> -#endif + : __unary_function<_Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x) const {return ~__x;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not); template <> struct _LIBCPP_TEMPLATE_VIS bit_not { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_Tp&& __x) const - _NOEXCEPT_(noexcept(~_VSTD::forward<_Tp>(__x))) - -> decltype (~_VSTD::forward<_Tp>(__x)) - { return ~_VSTD::forward<_Tp>(__x); } + noexcept(noexcept(~_VSTD::forward<_Tp>(__x))) + -> decltype( ~_VSTD::forward<_Tp>(__x)) + { return ~_VSTD::forward<_Tp>(__x); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS bit_or -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, _Tp> -#endif + : __binary_function<_Tp, _Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef _Tp __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x | __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS bit_or { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS bit_xor -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, _Tp> -#endif + : __binary_function<_Tp, _Tp, _Tp> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef _Tp __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x ^ __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS bit_xor { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif // Comparison operations -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS equal_to -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, bool> -#endif + : __binary_function<_Tp, _Tp, bool> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef bool __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __x == __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS equal_to { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS not_equal_to -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, bool> -#endif + : __binary_function<_Tp, _Tp, bool> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef bool __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __x != __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS not_equal_to { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS less -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, bool> -#endif + : __binary_function<_Tp, _Tp, bool> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef bool __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __x < __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS less { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS less_equal -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, bool> -#endif + : __binary_function<_Tp, _Tp, bool> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef bool __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __x <= __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS less_equal { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS greater_equal -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, bool> -#endif + : __binary_function<_Tp, _Tp, bool> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef bool __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __x >= __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS greater_equal { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS greater -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, bool> -#endif + : __binary_function<_Tp, _Tp, bool> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef bool __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __x > __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS greater { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif // Logical operations -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS logical_and -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, bool> -#endif + : __binary_function<_Tp, _Tp, bool> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef bool __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __x && __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS logical_and { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS logical_not -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : unary_function<_Tp, bool> -#endif + : __unary_function<_Tp, bool> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef bool __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x) const {return !__x;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS logical_not { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_Tp&& __x) const - _NOEXCEPT_(noexcept(!_VSTD::forward<_Tp>(__x))) - -> decltype (!_VSTD::forward<_Tp>(__x)) - { return !_VSTD::forward<_Tp>(__x); } + noexcept(noexcept(!_VSTD::forward<_Tp>(__x))) + -> decltype( !_VSTD::forward<_Tp>(__x)) + { return !_VSTD::forward<_Tp>(__x); } typedef void is_transparent; }; #endif -_LIBCPP_SUPPRESS_DEPRECATED_PUSH #if _LIBCPP_STD_VER > 11 template #else template #endif struct _LIBCPP_TEMPLATE_VIS logical_or -#if !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : binary_function<_Tp, _Tp, bool> -#endif + : __binary_function<_Tp, _Tp, bool> { -_LIBCPP_SUPPRESS_DEPRECATED_POP typedef bool __result_type; // used by valarray -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp first_argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp second_argument_type; -#endif - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __x || __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or); #if _LIBCPP_STD_VER > 11 template <> struct _LIBCPP_TEMPLATE_VIS logical_or { template - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const - _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))) - -> decltype (_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); } + noexcept(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))) + -> decltype( _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)) + { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); } typedef void is_transparent; }; #endif diff --git a/gnu/llvm/libcxx/include/__functional/perfect_forward.h b/gnu/llvm/libcxx/include/__functional/perfect_forward.h index a5678e1593b..9ffea1a8c75 100644 --- a/gnu/llvm/libcxx/include/__functional/perfect_forward.h +++ b/gnu/llvm/libcxx/include/__functional/perfect_forward.h @@ -11,75 +11,81 @@ #define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H #include <__config> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> #include #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 -template::value>::type> +template struct __perfect_forward_impl; -template -struct __perfect_forward_impl<_Op, __tuple_types<_Bound...>, __tuple_indices<_Idxs...>> -{ - tuple<_Bound...> __bound_; - - template - _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) & - noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...))) - -> decltype( _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...)) - {return _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...);} - - template - _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) const& - noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...))) - -> decltype( _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...)) - {return _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...);} - - template - _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) && - noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., - _VSTD::forward<_Args>(__args)...))) - -> decltype( _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., - _VSTD::forward<_Args>(__args)...)) - {return _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., - _VSTD::forward<_Args>(__args)...);} - - template - _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) const&& - noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., - _VSTD::forward<_Args>(__args)...))) - -> decltype( _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., - _VSTD::forward<_Args>(__args)...)) - {return _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., - _VSTD::forward<_Args>(__args)...);} - - template>::type, - class = _EnableIf>> - constexpr __perfect_forward_impl(__perfect_forward_impl const& __other) - : __bound_(__other.__bound_) {} - - template>::type, - class = _EnableIf>> - constexpr __perfect_forward_impl(__perfect_forward_impl && __other) - : __bound_(_VSTD::move(__other.__bound_)) {} - - template - explicit constexpr __perfect_forward_impl(_BoundArgs&&... __bound) : - __bound_(_VSTD::forward<_BoundArgs>(__bound)...) { } +template +struct __perfect_forward_impl<_Op, index_sequence<_Idx...>, _BoundArgs...> { +private: + tuple<_BoundArgs...> __bound_args_; + +public: + template , _Args&&...> + >> + explicit constexpr __perfect_forward_impl(_Args&&... __bound_args) + : __bound_args_(_VSTD::forward<_Args>(__bound_args)...) {} + + __perfect_forward_impl(__perfect_forward_impl const&) = default; + __perfect_forward_impl(__perfect_forward_impl&&) = default; + + __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default; + __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default; + + template >> + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) & + noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...))) + -> decltype( _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...)) + { return _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...); } + + template >> + auto operator()(_Args&&...) & = delete; + + template >> + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const& + noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...))) + -> decltype( _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...)) + { return _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...); } + + template >> + auto operator()(_Args&&...) const& = delete; + + template >> + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) && + noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...))) + -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...)) + { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...); } + + template >> + auto operator()(_Args&&...) && = delete; + + template >> + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&& + noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...))) + -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...)) + { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...); } + + template >> + auto operator()(_Args&&...) const&& = delete; }; -template -using __perfect_forward = - __perfect_forward_impl<_Op, __tuple_types...>>; +// __perfect_forward implements a perfect-forwarding call wrapper as explained in [func.require]. +template +using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>; #endif // _LIBCPP_STD_VER > 14 diff --git a/gnu/llvm/libcxx/include/__functional/pointer_to_binary_function.h b/gnu/llvm/libcxx/include/__functional/pointer_to_binary_function.h index d4a6c1674ae..b2676c58f88 100644 --- a/gnu/llvm/libcxx/include/__functional/pointer_to_binary_function.h +++ b/gnu/llvm/libcxx/include/__functional/pointer_to_binary_function.h @@ -14,7 +14,7 @@ #include <__functional/binary_function.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function - : public binary_function<_Arg1, _Arg2, _Result> + : public __binary_function<_Arg1, _Arg2, _Result> { _Result (*__f_)(_Arg1, _Arg2); public: diff --git a/gnu/llvm/libcxx/include/__functional/pointer_to_unary_function.h b/gnu/llvm/libcxx/include/__functional/pointer_to_unary_function.h index 0ac4561cc30..77d07adf20f 100644 --- a/gnu/llvm/libcxx/include/__functional/pointer_to_unary_function.h +++ b/gnu/llvm/libcxx/include/__functional/pointer_to_unary_function.h @@ -14,7 +14,7 @@ #include <__functional/unary_function.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function - : public unary_function<_Arg, _Result> + : public __unary_function<_Arg, _Result> { _Result (*__f_)(_Arg); public: diff --git a/gnu/llvm/libcxx/include/__functional/ranges_operations.h b/gnu/llvm/libcxx/include/__functional/ranges_operations.h index 777c5352510..87081dd56a0 100644 --- a/gnu/llvm/libcxx/include/__functional/ranges_operations.h +++ b/gnu/llvm/libcxx/include/__functional/ranges_operations.h @@ -10,17 +10,19 @@ #ifndef _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H #define _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H +#include <__concepts/equality_comparable.h> +#include <__concepts/totally_ordered.h> #include <__config> -#include -#include +#include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 + namespace ranges { struct equal_to { @@ -90,7 +92,8 @@ struct greater_equal { }; } // namespace ranges -#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/gnu/llvm/libcxx/include/__functional/reference_wrapper.h b/gnu/llvm/libcxx/include/__functional/reference_wrapper.h index 09f4a649450..c377b643770 100644 --- a/gnu/llvm/libcxx/include/__functional/reference_wrapper.h +++ b/gnu/llvm/libcxx/include/__functional/reference_wrapper.h @@ -11,22 +11,22 @@ #define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H #include <__config> +#include <__functional/invoke.h> #include <__functional/weak_result_type.h> #include <__memory/addressof.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> #include <__utility/forward.h> -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD template -class _LIBCPP_TEMPLATE_VIS reference_wrapper -#if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES) - : public __weak_result_type<_Tp> -#endif +class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> { public: // types @@ -34,155 +34,39 @@ public: private: type* __f_; -#ifndef _LIBCPP_CXX03_LANG static void __fun(_Tp&) _NOEXCEPT; static void __fun(_Tp&&) = delete; -#endif public: - // construct/copy/destroy -#ifdef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - reference_wrapper(type& __f) _NOEXCEPT - : __f_(_VSTD::addressof(__f)) {} -#else - template ::value, decltype(__fun(declval<_Up>())) >> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 - reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) { + template ::value, decltype(__fun(std::declval<_Up>())) > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(std::declval<_Up>()))) { type& __f = static_cast<_Up&&>(__u); __f_ = _VSTD::addressof(__f); } -#endif // access - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 operator type&() const _NOEXCEPT {return *__f_;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT {return *__f_;} -#ifndef _LIBCPP_CXX03_LANG // invoke template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of::type operator() (_ArgTypes&&... __args) const { - return _VSTD::__invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); - } -#else - - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return::type - operator() () const { - return _VSTD::__invoke(get()); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return0::type - operator() (_A0& __a0) const { - return _VSTD::__invoke(get(), __a0); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return0::type - operator() (_A0 const& __a0) const { - return _VSTD::__invoke(get(), __a0); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0& __a0, _A1& __a1) const { - return _VSTD::__invoke(get(), __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0 const& __a0, _A1& __a1) const { - return _VSTD::__invoke(get(), __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0& __a0, _A1 const& __a1) const { - return _VSTD::__invoke(get(), __a0, __a1); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return1::type - operator() (_A0 const& __a0, _A1 const& __a1) const { - return _VSTD::__invoke(get(), __a0, __a1); + return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { - return _VSTD::__invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { - return _VSTD::__invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { - return _VSTD::__invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { - return _VSTD::__invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { - return _VSTD::__invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { - return _VSTD::__invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { - return _VSTD::__invoke(get(), __a0, __a1, __a2); - } - - template - _LIBCPP_INLINE_VISIBILITY - typename __invoke_return2::type - operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { - return _VSTD::__invoke(get(), __a0, __a1, __a2); - } -#endif // _LIBCPP_CXX03_LANG }; -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +#if _LIBCPP_STD_VER > 14 template reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; #endif template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT { @@ -190,15 +74,15 @@ ref(_Tp& __t) _NOEXCEPT } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return _VSTD::ref(__t.get()); + return __t; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper cref(const _Tp& __t) _NOEXCEPT { @@ -206,17 +90,15 @@ cref(const _Tp& __t) _NOEXCEPT } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper cref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return _VSTD::cref(__t.get()); + return __t; } -#ifndef _LIBCPP_CXX03_LANG template void ref(const _Tp&&) = delete; template void cref(const _Tp&&) = delete; -#endif _LIBCPP_END_NAMESPACE_STD diff --git a/gnu/llvm/libcxx/include/__functional/unary_function.h b/gnu/llvm/libcxx/include/__functional/unary_function.h index 8084ef4b034..f07cac175a9 100644 --- a/gnu/llvm/libcxx/include/__functional/unary_function.h +++ b/gnu/llvm/libcxx/include/__functional/unary_function.h @@ -12,23 +12,40 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) + template -struct _LIBCPP_TEMPLATE_VIS unary_function +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 unary_function { typedef _Arg argument_type; typedef _Result result_type; }; -_LIBCPP_END_NAMESPACE_STD +#endif // _LIBCPP_STD_VER <= 14 + +template struct __unary_function_keep_layout_base { +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg; + using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; +#endif +}; -_LIBCPP_POP_MACROS +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") +template +using __unary_function = unary_function<_Arg, _Result>; +_LIBCPP_DIAGNOSTIC_POP +#else +template +using __unary_function = __unary_function_keep_layout_base<_Arg, _Result>; +#endif + +_LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H diff --git a/gnu/llvm/libcxx/include/__functional/unary_negate.h b/gnu/llvm/libcxx/include/__functional/unary_negate.h index 71257cf40c0..ab87e86d189 100644 --- a/gnu/llvm/libcxx/include/__functional/unary_negate.h +++ b/gnu/llvm/libcxx/include/__functional/unary_negate.h @@ -14,7 +14,7 @@ #include <__functional/unary_function.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -23,20 +23,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate - : public unary_function + : public __unary_function { _Predicate __pred_; public: - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY explicit unary_negate(const _Predicate& __pred) : __pred_(__pred) {} - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY bool operator()(const typename _Predicate::argument_type& __x) const {return !__pred_(__x);} }; template -_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY unary_negate<_Predicate> not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);} diff --git a/gnu/llvm/libcxx/include/__functional/unwrap_ref.h b/gnu/llvm/libcxx/include/__functional/unwrap_ref.h index 4d091ec35c5..da000d80b8c 100644 --- a/gnu/llvm/libcxx/include/__functional/unwrap_ref.h +++ b/gnu/llvm/libcxx/include/__functional/unwrap_ref.h @@ -10,24 +10,22 @@ #define _LIBCPP___FUNCTIONAL_UNWRAP_REF_H #include <__config> +#include <__type_traits/decay.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -struct __unwrap_reference { typedef _LIBCPP_NODEBUG_TYPE _Tp type; }; +struct __unwrap_reference { typedef _LIBCPP_NODEBUG _Tp type; }; template class reference_wrapper; template -struct __unwrap_reference > { typedef _LIBCPP_NODEBUG_TYPE _Tp& type; }; +struct __unwrap_reference > { typedef _LIBCPP_NODEBUG _Tp& type; }; template struct decay; @@ -57,6 +55,4 @@ struct __unwrap_ref_decay _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___FUNCTIONAL_UNWRAP_REF_H diff --git a/gnu/llvm/libcxx/include/__functional/weak_result_type.h b/gnu/llvm/libcxx/include/__functional/weak_result_type.h index 2ee85acf1ef..18d1bf718c4 100644 --- a/gnu/llvm/libcxx/include/__functional/weak_result_type.h +++ b/gnu/llvm/libcxx/include/__functional/weak_result_type.h @@ -12,11 +12,14 @@ #include <__config> #include <__functional/binary_function.h> +#include <__functional/invoke.h> #include <__functional/unary_function.h> -#include +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_same.h> +#include <__utility/declval.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -25,11 +28,10 @@ template struct __has_result_type { private: - struct __two {char __lx; char __lxx;}; - template static __two __test(...); - template static char __test(typename _Up::result_type* = 0); + template static false_type __test(...); + template static true_type __test(typename _Up::result_type* = 0); public: - static const bool value = sizeof(__test<_Tp>(0)) == 1; + static const bool value = decltype(__test<_Tp>(0))::value; }; // __weak_result_type @@ -41,8 +43,9 @@ private: struct __two {char __lx; char __lxx;}; static __two __test(...); template - static unary_function<_Ap, _Rp> - __test(const volatile unary_function<_Ap, _Rp>*); + static __unary_function<_Ap, _Rp> + __test(const volatile __unary_function<_Ap, _Rp>*); + public: static const bool value = !is_same::value; typedef decltype(__test((_Tp*)0)) type; @@ -55,8 +58,9 @@ private: struct __two {char __lx; char __lxx;}; static __two __test(...); template - static binary_function<_A1, _A2, _Rp> - __test(const volatile binary_function<_A1, _A2, _Rp>*); + static __binary_function<_A1, _A2, _Rp> + __test(const volatile __binary_function<_A1, _A2, _Rp>*); + public: static const bool value = !is_same::value; typedef decltype(__test((_Tp*)0)) type; @@ -89,7 +93,9 @@ struct __weak_result_type_imp // bool is true : public __maybe_derive_from_unary_function<_Tp>, public __maybe_derive_from_binary_function<_Tp> { - typedef _LIBCPP_NODEBUG_TYPE typename _Tp::result_type result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; +#endif }; template @@ -110,62 +116,68 @@ struct __weak_result_type template struct __weak_result_type<_Rp ()> { - typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; template struct __weak_result_type<_Rp (&)()> { - typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; template struct __weak_result_type<_Rp (*)()> { - typedef _LIBCPP_NODEBUG_TYPE _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; // 1 argument case template struct __weak_result_type<_Rp (_A1)> - : public unary_function<_A1, _Rp> + : public __unary_function<_A1, _Rp> { }; template struct __weak_result_type<_Rp (&)(_A1)> - : public unary_function<_A1, _Rp> + : public __unary_function<_A1, _Rp> { }; template struct __weak_result_type<_Rp (*)(_A1)> - : public unary_function<_A1, _Rp> + : public __unary_function<_A1, _Rp> { }; template struct __weak_result_type<_Rp (_Cp::*)()> - : public unary_function<_Cp*, _Rp> + : public __unary_function<_Cp*, _Rp> { }; template struct __weak_result_type<_Rp (_Cp::*)() const> - : public unary_function + : public __unary_function { }; template struct __weak_result_type<_Rp (_Cp::*)() volatile> - : public unary_function + : public __unary_function { }; template struct __weak_result_type<_Rp (_Cp::*)() const volatile> - : public unary_function + : public __unary_function { }; @@ -173,309 +185,110 @@ struct __weak_result_type<_Rp (_Cp::*)() const volatile> template struct __weak_result_type<_Rp (_A1, _A2)> - : public binary_function<_A1, _A2, _Rp> + : public __binary_function<_A1, _A2, _Rp> { }; template struct __weak_result_type<_Rp (*)(_A1, _A2)> - : public binary_function<_A1, _A2, _Rp> + : public __binary_function<_A1, _A2, _Rp> { }; template struct __weak_result_type<_Rp (&)(_A1, _A2)> - : public binary_function<_A1, _A2, _Rp> + : public __binary_function<_A1, _A2, _Rp> { }; template struct __weak_result_type<_Rp (_Cp::*)(_A1)> - : public binary_function<_Cp*, _A1, _Rp> + : public __binary_function<_Cp*, _A1, _Rp> { }; template struct __weak_result_type<_Rp (_Cp::*)(_A1) const> - : public binary_function + : public __binary_function { }; template struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> - : public binary_function + : public __binary_function { }; template struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> - : public binary_function + : public __binary_function { }; - -#ifndef _LIBCPP_CXX03_LANG // 3 or more arguments template struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> { - typedef _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; template struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> { - typedef _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; template struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> { - typedef _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; template struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> { - typedef _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; template struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> { - typedef _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; template struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> { - typedef _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; template struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> { - typedef _Rp result_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; +#endif }; template struct __invoke_return { - typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type; -}; - -#else // defined(_LIBCPP_CXX03_LANG) - -template -struct __enable_invoke_imp; - -template -struct __enable_invoke_imp<_Ret, _T1, true, true> { - typedef _Ret _Bullet1; - typedef _Bullet1 type; -}; - -template -struct __enable_invoke_imp<_Ret, _T1, true, false> { - typedef _Ret _Bullet2; - typedef _Bullet2 type; -}; - -template -struct __enable_invoke_imp<_Ret, _T1, false, true> { - typedef typename add_lvalue_reference< - typename __apply_cv<_T1, _Ret>::type - >::type _Bullet3; - typedef _Bullet3 type; -}; - -template -struct __enable_invoke_imp<_Ret, _T1, false, false> { - typedef typename add_lvalue_reference< - typename __apply_cv()), _Ret>::type - >::type _Bullet4; - typedef _Bullet4 type; -}; - -template -struct __enable_invoke_imp<_Ret, _T1*, false, false> { - typedef typename add_lvalue_reference< - typename __apply_cv<_T1, _Ret>::type - >::type _Bullet4; - typedef _Bullet4 type; -}; - -template , - class _Ret = typename _Traits::_ReturnType, - class _Class = typename _Traits::_ClassType> -struct __enable_invoke : __enable_invoke_imp< - _Ret, _T1, - is_member_function_pointer<_Fn>::value, - is_base_of<_Class, typename remove_reference<_T1>::type>::value> -{ -}; - -__nat __invoke(__any, ...); - -// first bullet - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1) { - return (__t1.*__f)(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1, _A0& __a0) { - return (__t1.*__f)(__a0); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { - return (__t1.*__f)(__a0, __a1); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { - return (__t1.*__f)(__a0, __a1, __a2); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1) { - return ((*__t1).*__f)(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1, _A0& __a0) { - return ((*__t1).*__f)(__a0); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { - return ((*__t1).*__f)(__a0, __a1); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { - return ((*__t1).*__f)(__a0, __a1, __a2); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet3 -__invoke(_Fn __f, _T1& __t1) { - return __t1.*__f; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet4 -__invoke(_Fn __f, _T1& __t1) { - return (*__t1).*__f; -} - -// fifth bullet - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(declval<_Fp&>()()) -__invoke(_Fp& __f) -{ - return __f(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(declval<_Fp&>()(declval<_A0&>())) -__invoke(_Fp& __f, _A0& __a0) -{ - return __f(__a0); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>())) -__invoke(_Fp& __f, _A0& __a0, _A1& __a1) -{ - return __f(__a0, __a1); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>())) -__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) -{ - return __f(__a0, __a1, __a2); -} - -template >::value> -struct __invoke_return -{ - typedef typename __weak_result_type<_Fp>::result_type type; + typedef decltype(_VSTD::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type; }; -template -struct __invoke_return<_Fp, false> -{ - typedef decltype(_VSTD::__invoke(declval<_Fp&>())) type; -}; - -template -struct __invoke_return0 -{ - typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>())) type; -}; - -template -struct __invoke_return0<_Rp _Tp::*, _A0> -{ - typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; -}; - -template -struct __invoke_return1 -{ - typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(), - declval<_A1&>())) type; -}; - -template -struct __invoke_return1<_Rp _Class::*, _A0, _A1> { - typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; -}; - -template -struct __invoke_return2 -{ - typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(), - declval<_A1&>(), - declval<_A2&>())) type; -}; - -template -struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> { - typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type; -}; - -#endif // !defined(_LIBCPP_CXX03_LANG) - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H diff --git a/gnu/llvm/libcxx/include/__fwd/array.h b/gnu/llvm/libcxx/include/__fwd/array.h new file mode 100644 index 00000000000..9a79effb617 --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/array.h @@ -0,0 +1,26 @@ +//===---------------------------------------------------------------------===// +// +// 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___FWD_ARRAY_H +#define _LIBCPP___FWD_ARRAY_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS array; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_ARRAY_H diff --git a/gnu/llvm/libcxx/include/__fwd/get.h b/gnu/llvm/libcxx/include/__fwd/get.h new file mode 100644 index 00000000000..ec1fab4602d --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/get.h @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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___FWD_GET_H +#define _LIBCPP___FWD_GET_H + +#include <__concepts/copyable.h> +#include <__config> +#include <__fwd/array.h> +#include <__fwd/pair.h> +#include <__fwd/subrange.h> +#include <__fwd/tuple.h> +#include <__tuple_dir/tuple_element.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename tuple_element<_Ip, tuple<_Tp...> >::type& +get(tuple<_Tp...>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const typename tuple_element<_Ip, tuple<_Tp...> >::type& +get(const tuple<_Tp...>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename tuple_element<_Ip, tuple<_Tp...> >::type&& +get(tuple<_Tp...>&&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const typename tuple_element<_Ip, tuple<_Tp...> >::type&& +get(const tuple<_Tp...>&&) _NOEXCEPT; + +#endif //_LIBCPP_CXX03_LANG + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename tuple_element<_Ip, pair<_T1, _T2> >::type& +get(pair<_T1, _T2>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const typename tuple_element<_Ip, pair<_T1, _T2> >::type& +get(const pair<_T1, _T2>&) _NOEXCEPT; + +#ifndef _LIBCPP_CXX03_LANG +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +get(pair<_T1, _T2>&&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +get(const pair<_T1, _T2>&&) _NOEXCEPT; +#endif + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp& +get(array<_Tp, _Size>&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const _Tp& +get(const array<_Tp, _Size>&) _NOEXCEPT; + +#ifndef _LIBCPP_CXX03_LANG +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +_Tp&& +get(array<_Tp, _Size>&&) _NOEXCEPT; + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 +const _Tp&& +get(const array<_Tp, _Size>&&) _NOEXCEPT; +#endif + +#if _LIBCPP_STD_VER >= 20 + +namespace ranges { + +template + requires((_Index == 0 && copyable<_Iter>) || _Index == 1) +_LIBCPP_HIDE_FROM_ABI constexpr auto get(const subrange<_Iter, _Sent, _Kind>& __subrange); + +template + requires(_Index < 2) +_LIBCPP_HIDE_FROM_ABI constexpr auto get(subrange<_Iter, _Sent, _Kind>&& __subrange); + +} // namespace ranges + +using ranges::get; + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_GET_H diff --git a/gnu/llvm/libcxx/include/__fwd/hash.h b/gnu/llvm/libcxx/include/__fwd/hash.h new file mode 100644 index 00000000000..af9eca876a1 --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/hash.h @@ -0,0 +1,25 @@ +//===---------------------------------------------------------------------===// +// +// 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___FWD_HASH_H +#define _LIBCPP___FWD_HASH_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS hash; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_HASH_H diff --git a/gnu/llvm/libcxx/include/__fwd/memory_resource.h b/gnu/llvm/libcxx/include/__fwd/memory_resource.h new file mode 100644 index 00000000000..718a9078d3c --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/memory_resource.h @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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___FWD_MEMORY_RESOURCE_H +#define _LIBCPP___FWD_MEMORY_RESOURCE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace pmr { +template +class _LIBCPP_TEMPLATE_VIS polymorphic_allocator; +} // namespace pmr + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_MEMORY_RESOURCE_H diff --git a/gnu/llvm/libcxx/include/__fwd/pair.h b/gnu/llvm/libcxx/include/__fwd/pair.h new file mode 100644 index 00000000000..3844014de3a --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/pair.h @@ -0,0 +1,25 @@ +//===---------------------------------------------------------------------===// +// +// 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___FWD_PAIR_H +#define _LIBCPP___FWD_PAIR_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS pair; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_PAIR_H diff --git a/gnu/llvm/libcxx/include/__fwd/span.h b/gnu/llvm/libcxx/include/__fwd/span.h new file mode 100644 index 00000000000..943cb13fa1b --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/span.h @@ -0,0 +1,37 @@ +// -*- 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___FWD_SPAN_H +#define _LIBCPP___FWD_SPAN_H + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +inline constexpr size_t dynamic_extent = numeric_limits::max(); +template class span; + +#endif + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FWD_SPAN_H diff --git a/gnu/llvm/libcxx/include/__fwd/string.h b/gnu/llvm/libcxx/include/__fwd/string.h new file mode 100644 index 00000000000..7ab5561b758 --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/string.h @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// 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___FWD_STRING_H +#define _LIBCPP___FWD_STRING_H + +#include <__config> +#include <__fwd/memory_resource.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS char_traits; +template <> +struct char_traits; + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +template <> +struct char_traits; +#endif + +template <> +struct char_traits; +template <> +struct char_traits; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <> +struct char_traits; +#endif + +template +class _LIBCPP_TEMPLATE_VIS allocator; + +template , class _Allocator = allocator<_CharT> > +class _LIBCPP_TEMPLATE_VIS basic_string; + +using string = basic_string; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wstring = basic_string; +#endif + +#ifndef _LIBCPP_HAS_NO_CHAR8_T +using u8string = basic_string; +#endif + +using u16string = basic_string; +using u32string = basic_string; + +#if _LIBCPP_STD_VER >= 17 + +namespace pmr { +template > +using basic_string = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>; + +using string = basic_string; + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wstring = basic_string; +# endif + +# ifndef _LIBCPP_HAS_NO_CHAR8_T +using u8string = basic_string; +# endif + +using u16string = basic_string; +using u32string = basic_string; + +} // namespace pmr + +#endif // _LIBCPP_STD_VER >= 17 + +// clang-format off +template +class _LIBCPP_PREFERRED_NAME(string) +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_PREFERRED_NAME(wstring) +#endif +#ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_PREFERRED_NAME(u8string) +#endif + _LIBCPP_PREFERRED_NAME(u16string) + _LIBCPP_PREFERRED_NAME(u32string) +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_PREFERRED_NAME(pmr::string) +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_PREFERRED_NAME(pmr::wstring) +# endif +# ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_PREFERRED_NAME(pmr::u8string) +# endif + _LIBCPP_PREFERRED_NAME(pmr::u16string) + _LIBCPP_PREFERRED_NAME(pmr::u32string) +#endif + basic_string; +// clang-format on + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_STRING_H diff --git a/gnu/llvm/libcxx/include/__fwd/string_view.h b/gnu/llvm/libcxx/include/__fwd/string_view.h new file mode 100644 index 00000000000..4818990248d --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/string_view.h @@ -0,0 +1,50 @@ +// -*- 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___FWD_STRING_VIEW_H +#define _LIBCPP___FWD_STRING_VIEW_H + +#include <__config> +#include // char_traits + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template > +class _LIBCPP_TEMPLATE_VIS basic_string_view; + +typedef basic_string_view string_view; +#ifndef _LIBCPP_HAS_NO_CHAR8_T +typedef basic_string_view u8string_view; +#endif +typedef basic_string_view u16string_view; +typedef basic_string_view u32string_view; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +typedef basic_string_view wstring_view; +#endif + +// clang-format off +template +class _LIBCPP_PREFERRED_NAME(string_view) +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_PREFERRED_NAME(wstring_view) +#endif +#ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_PREFERRED_NAME(u8string_view) +#endif + _LIBCPP_PREFERRED_NAME(u16string_view) + _LIBCPP_PREFERRED_NAME(u32string_view) + basic_string_view; +// clang-format on +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_STRING_VIEW_H diff --git a/gnu/llvm/libcxx/include/__fwd/subrange.h b/gnu/llvm/libcxx/include/__fwd/subrange.h new file mode 100644 index 00000000000..8f7239247ef --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/subrange.h @@ -0,0 +1,38 @@ +//===---------------------------------------------------------------------===// +// +// 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___FWD_SUBRANGE_H +#define _LIBCPP___FWD_SUBRANGE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 20 + +#include <__iterator/concepts.h> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized }; + +template _Sent, subrange_kind _Kind> + requires(_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _Iter>) +class _LIBCPP_TEMPLATE_VIS subrange; + +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +#endif // _LIBCPP___FWD_SUBRANGE_H diff --git a/gnu/llvm/libcxx/include/__fwd/tuple.h b/gnu/llvm/libcxx/include/__fwd/tuple.h new file mode 100644 index 00000000000..16b3fabbb99 --- /dev/null +++ b/gnu/llvm/libcxx/include/__fwd/tuple.h @@ -0,0 +1,29 @@ +//===---------------------------------------------------------------------===// +// +// 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___FWD_TUPLE_H +#define _LIBCPP___FWD_TUPLE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG + +template +class _LIBCPP_TEMPLATE_VIS tuple; + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_TUPLE_H diff --git a/gnu/llvm/libcxx/include/__hash_table b/gnu/llvm/libcxx/include/__hash_table index df0f7c80db2..f8896c8664e 100644 --- a/gnu/llvm/libcxx/include/__hash_table +++ b/gnu/llvm/libcxx/include/__hash_table @@ -7,22 +7,35 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP__HASH_TABLE -#define _LIBCPP__HASH_TABLE +#ifndef _LIBCPP___HASH_TABLE +#define _LIBCPP___HASH_TABLE -#include <__bits> // __libcpp_clz +#include <__algorithm/max.h> +#include <__algorithm/min.h> +#include <__assert> +#include <__bit/countl.h> #include <__config> #include <__debug> -#include +#include <__functional/hash.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__memory/allocator_traits.h> +#include <__memory/compressed_pair.h> +#include <__memory/pointer_traits.h> +#include <__memory/swap_allocator.h> +#include <__memory/unique_ptr.h> +#include <__type_traits/can_extract_key.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/pair.h> +#include <__utility/swap.h> #include +#include #include -#include -#include #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -44,7 +57,7 @@ template struct __is_hash_value_type : false_type {}; template -struct __is_hash_value_type<_One> : __is_hash_value_type_imp::type> {}; +struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {}; _LIBCPP_FUNC_VIS size_t __next_prime(size_t __n); @@ -54,16 +67,13 @@ struct __hash_node_base { typedef typename pointer_traits<_NodePtr>::element_type __node_type; typedef __hash_node_base __first_node; - typedef typename __rebind_pointer<_NodePtr, __first_node>::type __node_base_pointer; + typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer; typedef _NodePtr __node_pointer; #if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB) typedef __node_base_pointer __next_pointer; #else - typedef typename conditional< - is_pointer<__node_pointer>::value, - __node_base_pointer, - __node_pointer>::type __next_pointer; + typedef __conditional_t::value, __node_base_pointer, __node_pointer> __next_pointer; #endif __next_pointer __next_; @@ -92,7 +102,7 @@ template struct _LIBCPP_STANDALONE_DEBUG __hash_node : public __hash_node_base < - typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type + __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > > { typedef _Tp __node_value_type; @@ -175,16 +185,14 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { template _LIBCPP_INLINE_VISIBILITY - static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value, - __container_value_type const&>::type + static __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&> __get_value(_Up& __t) { return __t.__get_value(); } template _LIBCPP_INLINE_VISIBILITY - static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, - __container_value_type const&>::type + static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&> __get_value(_Up& __t) { return __t; } @@ -206,9 +214,9 @@ struct __hash_map_pointer_types {}; template struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { typedef typename _KVTypes::__map_value_type _Mv; - typedef typename __rebind_pointer<_AllocPtr, _Mv>::type + typedef __rebind_pointer_t<_AllocPtr, _Mv> __map_value_type_pointer; - typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type + typedef __rebind_pointer_t<_AllocPtr, const _Mv> __const_map_value_type_pointer; }; @@ -226,21 +234,21 @@ public: typedef ptrdiff_t difference_type; typedef size_t size_type; - typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; + typedef __rebind_pointer_t<_NodePtr, void> __void_pointer; typedef typename pointer_traits<_NodePtr>::element_type __node_type; typedef _NodePtr __node_pointer; typedef __hash_node_base<__node_pointer> __node_base_type; - typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type + typedef __rebind_pointer_t<_NodePtr, __node_base_type> __node_base_pointer; typedef typename __node_base_type::__next_pointer __next_pointer; typedef _Tp __node_value_type; - typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type + typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer; - typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type + typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer; private: @@ -248,7 +256,7 @@ private: "_NodePtr should never be a pointer to const"); static_assert((is_same::element_type, void>::value), "_VoidPtr does not point to unqualified void type"); - static_assert((is_same::type, + static_assert((is_same<__rebind_pointer_t<_VoidPtr, __node_type>, _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); }; @@ -267,7 +275,7 @@ struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : template struct __make_hash_node_types { typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; - typedef typename __rebind_pointer<_VoidPtr, _NodeTp>::type _NodePtr; + typedef __rebind_pointer_t<_VoidPtr, _NodeTp> _NodePtr; typedef __hash_node_types<_NodePtr> type; }; @@ -288,17 +296,15 @@ public: typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_INLINE_VISIBILITY __hash_iterator(const __hash_iterator& __i) : __node_(__i.__node_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -310,14 +316,14 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_iterator& operator=(const __hash_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; } return *this; } -#endif // _LIBCPP_DEBUG_LEVEL == 2 +#endif // _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_INLINE_VISIBILITY reference operator*() const { @@ -359,19 +365,15 @@ public: {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY - __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT + explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT : __node_(__node) { + (void)__c; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE __get_db()->__insert_ic(this, __c); - } -#else - _LIBCPP_INLINE_VISIBILITY - __hash_iterator(__next_pointer __node) _NOEXCEPT - : __node_(__node) - {} #endif + } template friend class __hash_table; template friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; @@ -400,26 +402,24 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__iterator_copy(this, &__x); +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); #endif } -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __hash_const_iterator& __i) : __node_(__i.__node_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -431,14 +431,14 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_iterator& operator=(const __hash_const_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; } return *this; } -#endif // _LIBCPP_DEBUG_LEVEL == 2 +#endif // _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_INLINE_VISIBILITY reference operator*() const { @@ -479,19 +479,15 @@ public: {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT + explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT : __node_(__node) { + (void)__c; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE __get_db()->__insert_ic(this, __c); - } -#else - _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(__next_pointer __node) _NOEXCEPT - : __node_(__node) - {} #endif + } template friend class __hash_table; template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; template friend class _LIBCPP_TEMPLATE_VIS unordered_map; @@ -517,19 +513,17 @@ public: typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_INLINE_VISIBILITY __hash_local_iterator(const __hash_local_iterator& __i) : __node_(__i.__node_), __bucket_(__i.__bucket_), __bucket_count_(__i.__bucket_count_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -541,16 +535,16 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_local_iterator& operator=(const __hash_local_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; __bucket_ = __i.__bucket_; __bucket_count_ = __i.__bucket_count_; } return *this; } -#endif // _LIBCPP_DEBUG_LEVEL == 2 +#endif // _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_INLINE_VISIBILITY reference operator*() const { @@ -571,7 +565,7 @@ public: _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to increment a non-incrementable unordered container local_iterator"); __node_ = __node_->__next_; - if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) __node_ = nullptr; return *this; } @@ -594,30 +588,20 @@ public: {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator(__next_pointer __node, size_t __bucket, - size_t __bucket_count, const void* __c) _NOEXCEPT + explicit __hash_local_iterator(__next_pointer __node, size_t __bucket, + size_t __bucket_count, const void* __c) _NOEXCEPT : __node_(__node), __bucket_(__bucket), __bucket_count_(__bucket_count) { + (void)__c; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE __get_db()->__insert_ic(this, __c); +#endif if (__node_ != nullptr) __node_ = __node_->__next_; } -#else - _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator(__next_pointer __node, size_t __bucket, - size_t __bucket_count) _NOEXCEPT - : __node_(__node), - __bucket_(__bucket), - __bucket_count_(__bucket_count) - { - if (__node_ != nullptr) - __node_ = __node_->__next_; - } -#endif template friend class __hash_table; template friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; @@ -636,8 +620,8 @@ class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator typedef pointer_traits<__node_pointer> __pointer_traits; typedef typename __pointer_traits::element_type __node; - typedef typename remove_const<__node>::type __non_const_node; - typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type + typedef __remove_const_t<__node> __non_const_node; + typedef __rebind_pointer_t<__node_pointer, __non_const_node> __non_const_node_pointer; public: typedef __hash_local_iterator<__non_const_node_pointer> @@ -651,9 +635,7 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_i(this); -#endif + _VSTD::__debug_db_insert_i(this); } _LIBCPP_INLINE_VISIBILITY @@ -662,19 +644,19 @@ public: __bucket_(__x.__bucket_), __bucket_count_(__x.__bucket_count_) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__iterator_copy(this, &__x); +#ifdef _LIBCPP_ENABLE_DEBUG_MODE + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); #endif } -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator(const __hash_const_local_iterator& __i) : __node_(__i.__node_), __bucket_(__i.__bucket_), __bucket_count_(__i.__bucket_count_) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); } _LIBCPP_INLINE_VISIBILITY @@ -686,16 +668,16 @@ public: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) { - if (this != &__i) + if (this != _VSTD::addressof(__i)) { - __get_db()->__iterator_copy(this, &__i); + __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); __node_ = __i.__node_; __bucket_ = __i.__bucket_; __bucket_count_ = __i.__bucket_count_; } return *this; } -#endif // _LIBCPP_DEBUG_LEVEL == 2 +#endif // _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_INLINE_VISIBILITY reference operator*() const { @@ -716,7 +698,7 @@ public: _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to increment a non-incrementable unordered container const_local_iterator"); __node_ = __node_->__next_; - if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) __node_ = nullptr; return *this; } @@ -739,30 +721,20 @@ public: {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL == 2 _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, - size_t __bucket_count, const void* __c) _NOEXCEPT + explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, + size_t __bucket_count, const void* __c) _NOEXCEPT : __node_(__node_ptr), __bucket_(__bucket), __bucket_count_(__bucket_count) { + (void)__c; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE __get_db()->__insert_ic(this, __c); +#endif if (__node_ != nullptr) __node_ = __node_->__next_; } -#else - _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, - size_t __bucket_count) _NOEXCEPT - : __node_(__node_ptr), - __bucket_(__bucket), - __bucket_count_(__bucket_count) - { - if (__node_ != nullptr) - __node_ = __node_->__next_; - } -#endif template friend class __hash_table; template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; }; @@ -926,7 +898,7 @@ public: // Create __node typedef typename _NodeTypes::__node_type __node; - typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; + typedef __rebind_alloc<__alloc_traits, __node> __node_allocator; typedef allocator_traits<__node_allocator> __node_traits; typedef typename _NodeTypes::__void_pointer __void_pointer; typedef typename _NodeTypes::__node_pointer __node_pointer; @@ -941,15 +913,14 @@ private: // the pointer using 'pointer_traits'. static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), "Allocator does not rebind pointers in a sane manner."); - typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type - __node_base_allocator; + typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator; typedef allocator_traits<__node_base_allocator> __node_base_traits; static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), "Allocator does not rebind pointers in a sane manner."); private: - typedef typename __rebind_alloc_helper<__node_traits, __next_pointer>::type __pointer_allocator; + typedef __rebind_alloc<__node_traits, __next_pointer> __pointer_allocator; typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; @@ -1082,10 +1053,8 @@ public: template _LIBCPP_INLINE_VISIBILITY - typename enable_if< - __can_extract_map_key<_First, key_type, __container_value_type>::value, - pair - >::type __emplace_unique(_First&& __f, _Second&& __s) { + __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair > + __emplace_unique(_First&& __f, _Second&& __s) { return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), _VSTD::forward<_Second>(__s)); } @@ -1129,9 +1098,7 @@ public: return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x)); } - template ::value - >::type> + template ::value> > _LIBCPP_INLINE_VISIBILITY pair __insert_unique(_Pp&& __x) { return __emplace_unique(_VSTD::forward<_Pp>(__x)); @@ -1185,9 +1152,16 @@ public: #endif void clear() _NOEXCEPT; - void rehash(size_type __n); - _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) - {rehash(static_cast(ceil(__n / max_load_factor())));} + _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash(__n); } + _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash(__n); } + _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n) + { + __rehash_unique(static_cast(std::ceil(__n / max_load_factor()))); + } + _LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n) + { + __rehash_multi(static_cast(std::ceil(__n / max_load_factor()))); + } _LIBCPP_INLINE_VISIBILITY size_type bucket_count() const _NOEXCEPT @@ -1210,7 +1184,7 @@ public: { _LIBCPP_ASSERT(bucket_count() > 0, "unordered container::bucket(key) called when bucket_count() == 0"); - return __constrain_hash(hash_function()(__k), bucket_count()); + return std::__constrain_hash(hash_function()(__k), bucket_count()); } template @@ -1284,11 +1258,7 @@ public: { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::begin(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL == 2 return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); -#else - return local_iterator(__bucket_list_[__n], __n, bucket_count()); -#endif } _LIBCPP_INLINE_VISIBILITY @@ -1297,11 +1267,7 @@ public: { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::end(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL == 2 return local_iterator(nullptr, __n, bucket_count(), this); -#else - return local_iterator(nullptr, __n, bucket_count()); -#endif } _LIBCPP_INLINE_VISIBILITY @@ -1310,11 +1276,7 @@ public: { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::cbegin(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL == 2 return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); -#else - return const_local_iterator(__bucket_list_[__n], __n, bucket_count()); -#endif } _LIBCPP_INLINE_VISIBILITY @@ -1323,24 +1285,21 @@ public: { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::cend(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL == 2 return const_local_iterator(nullptr, __n, bucket_count(), this); -#else - return const_local_iterator(nullptr, __n, bucket_count()); -#endif } -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE bool __dereferenceable(const const_iterator* __i) const; bool __decrementable(const const_iterator* __i) const; bool __addable(const const_iterator* __i, ptrdiff_t __n) const; bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; -#endif // _LIBCPP_DEBUG_LEVEL == 2 +#endif // _LIBCPP_ENABLE_DEBUG_MODE private: - void __rehash(size_type __n); + template void __rehash(size_type __n); + template void __do_rehash(size_type __n); template __node_holder __construct_node(_Args&& ...__args); @@ -1474,7 +1433,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) { if (size() > 0) { - __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); __u.__p1_.first().__next_ = nullptr; __u.size() = 0; @@ -1498,7 +1457,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, { __p1_.first().__next_ = __u.__p1_.first().__next_; __u.__p1_.first().__next_ = nullptr; - __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); size() = __u.size(); __u.size() = 0; @@ -1517,9 +1476,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() #endif __deallocate_node(__p1_.first().__next_); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__erase_c(this); -#endif + std::__debug_db_erase_c(this); } template @@ -1541,7 +1498,7 @@ template __hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) { - if (this != &__u) + if (this != _VSTD::addressof(__u)) { __copy_assign_alloc(__u); hash_function() = __u.hash_function(); @@ -1561,7 +1518,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) while (__np != nullptr) { __next_pointer __next = __np->__next_; -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE __c_node* __c = __get_db()->__find_c_and_lock(this); for (__i_node** __p = __c->end_; __p != __c->beg_; ) { @@ -1617,14 +1574,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( __p1_.first().__next_ = __u.__p1_.first().__next_; if (size() > 0) { - __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); __u.__p1_.first().__next_ = nullptr; __u.size() = 0; } -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, &__u); -#endif + std::__debug_db_swap(this, std::addressof(__u)); } template @@ -1774,11 +1729,7 @@ inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(__p1_.first().__next_, this); -#else - return iterator(__p1_.first().__next_); -#endif } template @@ -1786,11 +1737,7 @@ inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(nullptr, this); -#else - return iterator(nullptr); -#endif } template @@ -1798,11 +1745,7 @@ inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 return const_iterator(__p1_.first().__next_, this); -#else - return const_iterator(__p1_.first().__next_); -#endif } template @@ -1810,11 +1753,7 @@ inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL == 2 return const_iterator(nullptr, this); -#else - return const_iterator(nullptr); -#endif } template @@ -1850,12 +1789,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( if (__bc != 0) { - size_t __chash = __constrain_hash(__hash, __bc); + size_t __chash = std::__constrain_hash(__hash, __bc); __next_pointer __ndptr = __bucket_list_[__chash]; if (__ndptr != nullptr) { for (__ndptr = __ndptr->__next_; __ndptr != nullptr && - __constrain_hash(__ndptr->__hash(), __bc) == __chash; + std::__constrain_hash(__ndptr->__hash(), __bc) == __chash; __ndptr = __ndptr->__next_) { if (key_eq()(__ndptr->__upcast()->__value_, __value)) @@ -1865,8 +1804,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( } if (size()+1 > __bc * max_load_factor() || __bc == 0) { - rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), - size_type(ceil(float(size() + 1) / max_load_factor())))); + __rehash_unique(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), + size_type(std::ceil(float(size() + 1) / max_load_factor())))); } return nullptr; } @@ -1882,7 +1821,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( __node_pointer __nd) _NOEXCEPT { size_type __bc = bucket_count(); - size_t __chash = __constrain_hash(__nd->__hash(), __bc); + size_t __chash = std::__constrain_hash(__nd->__hash(), __bc); // insert_after __bucket_list_[__chash], or __first_node if bucket is null __next_pointer __pn = __bucket_list_[__chash]; if (__pn == nullptr) @@ -1893,7 +1832,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( // fix up __bucket_list_ __bucket_list_[__chash] = __pn; if (__nd->__next_ != nullptr) - __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); + __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); } else { @@ -1919,11 +1858,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ __existing_node = __nd->__ptr(); __inserted = true; } -#if _LIBCPP_DEBUG_LEVEL == 2 return pair(iterator(__existing_node, this), __inserted); -#else - return pair(iterator(__existing_node), __inserted); -#endif } // Prepare the container for an insertion of the value __cp_val with the hash @@ -1941,16 +1876,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( size_type __bc = bucket_count(); if (size()+1 > __bc * max_load_factor() || __bc == 0) { - rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), - size_type(ceil(float(size() + 1) / max_load_factor())))); + __rehash_multi(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), + size_type(std::ceil(float(size() + 1) / max_load_factor())))); __bc = bucket_count(); } - size_t __chash = __constrain_hash(__cp_hash, __bc); + size_t __chash = std::__constrain_hash(__cp_hash, __bc); __next_pointer __pn = __bucket_list_[__chash]; if (__pn != nullptr) { for (bool __found = false; __pn->__next_ != nullptr && - __constrain_hash(__pn->__next_->__hash(), __bc) == __chash; + std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash; __pn = __pn->__next_) { // __found key_eq() action @@ -1982,7 +1917,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( __node_pointer __cp, __next_pointer __pn) _NOEXCEPT { size_type __bc = bucket_count(); - size_t __chash = __constrain_hash(__cp->__hash_, __bc); + size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); if (__pn == nullptr) { __pn =__p1_.first().__ptr(); @@ -1991,7 +1926,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( // fix up __bucket_list_ __bucket_list_[__chash] = __pn; if (__cp->__next_ != nullptr) - __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)] + __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)] = __cp->__ptr(); } else @@ -2000,7 +1935,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( __pn->__next_ = __cp->__ptr(); if (__cp->__next_ != nullptr) { - size_t __nhash = __constrain_hash(__cp->__next_->__hash(), __bc); + size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc); if (__nhash != __chash) __bucket_list_[__nhash] = __cp->__ptr(); } @@ -2017,11 +1952,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); __node_insert_multi_perform(__cp, __pn); -#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(__cp->__ptr(), this); -#else - return iterator(__cp->__ptr()); -#endif } template @@ -2029,11 +1960,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( const_iterator __p, __node_pointer __cp) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); if (__p != end() && key_eq()(*__p, __cp->__value_)) { __next_pointer __np = __p.__node_; @@ -2041,22 +1970,18 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( size_type __bc = bucket_count(); if (size()+1 > __bc * max_load_factor() || __bc == 0) { - rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), - size_type(ceil(float(size() + 1) / max_load_factor())))); + __rehash_multi(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), + size_type(std::ceil(float(size() + 1) / max_load_factor())))); __bc = bucket_count(); } - size_t __chash = __constrain_hash(__cp->__hash_, __bc); + size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); __next_pointer __pp = __bucket_list_[__chash]; while (__pp->__next_ != __np) __pp = __pp->__next_; __cp->__next_ = __np; __pp->__next_ = static_cast<__next_pointer>(__cp); ++size(); -#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(static_cast<__next_pointer>(__cp), this); -#else - return iterator(static_cast<__next_pointer>(__cp)); -#endif } return __node_insert_multi(__cp); } @@ -2076,12 +2001,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& size_t __chash; if (__bc != 0) { - __chash = __constrain_hash(__hash, __bc); + __chash = std::__constrain_hash(__hash, __bc); __nd = __bucket_list_[__chash]; if (__nd != nullptr) { for (__nd = __nd->__next_; __nd != nullptr && - (__nd->__hash() == __hash || __constrain_hash(__nd->__hash(), __bc) == __chash); + (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); __nd = __nd->__next_) { if (key_eq()(__nd->__upcast()->__value_, __k)) @@ -2093,10 +2018,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); if (size()+1 > __bc * max_load_factor() || __bc == 0) { - rehash(_VSTD::max(2 * __bc + !__is_hash_power2(__bc), - size_type(ceil(float(size() + 1) / max_load_factor())))); + __rehash_unique(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), + size_type(std::ceil(float(size() + 1) / max_load_factor())))); __bc = bucket_count(); - __chash = __constrain_hash(__hash, __bc); + __chash = std::__constrain_hash(__hash, __bc); } // insert_after __bucket_list_[__chash], or __first_node if bucket is null __next_pointer __pn = __bucket_list_[__chash]; @@ -2108,7 +2033,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& // fix up __bucket_list_ __bucket_list_[__chash] = __pn; if (__h->__next_ != nullptr) - __bucket_list_[__constrain_hash(__h->__next_->__hash(), __bc)] + __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] = __h.get()->__ptr(); } else @@ -2122,11 +2047,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __inserted = true; } __done: -#if _LIBCPP_DEBUG_LEVEL == 2 return pair(iterator(__nd, this), __inserted); -#else - return pair(iterator(__nd), __inserted); -#endif } template @@ -2158,11 +2079,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" + " referring to this unordered container"); __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); iterator __r = __node_insert_multi(__p, __h.get()); __h.release(); @@ -2302,37 +2221,37 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( #endif // _LIBCPP_STD_VER > 14 template +template void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { if (__n == 1) __n = 2; else if (__n & (__n - 1)) - __n = __next_prime(__n); + __n = std::__next_prime(__n); size_type __bc = bucket_count(); if (__n > __bc) - __rehash(__n); + __do_rehash<_UniqueKeys>(__n); else if (__n < __bc) { __n = _VSTD::max ( __n, - __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) : - __next_prime(size_t(ceil(float(size()) / max_load_factor()))) + std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) : + std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor()))) ); if (__n < __bc) - __rehash(__n); + __do_rehash<_UniqueKeys>(__n); } } template +template void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) { -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__invalidate_all(this); -#endif + std::__debug_db_invalidate_all(this); __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); __bucket_list_.reset(__nbc > 0 ? __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); @@ -2345,13 +2264,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) __next_pointer __cp = __pp->__next_; if (__cp != nullptr) { - size_type __chash = __constrain_hash(__cp->__hash(), __nbc); + size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc); __bucket_list_[__chash] = __pp; size_type __phash = __chash; - for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr; + for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) { - __chash = __constrain_hash(__cp->__hash(), __nbc); + __chash = std::__constrain_hash(__cp->__hash(), __nbc); if (__chash == __phash) __pp = __cp; else @@ -2365,11 +2284,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) else { __next_pointer __np = __cp; - for (; __np->__next_ != nullptr && - key_eq()(__cp->__upcast()->__value_, - __np->__next_->__upcast()->__value_); - __np = __np->__next_) - ; + if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) + { + for (; __np->__next_ != nullptr && + key_eq()(__cp->__upcast()->__value_, + __np->__next_->__upcast()->__value_); + __np = __np->__next_) + ; + } __pp->__next_ = __np->__next_; __np->__next_ = __bucket_list_[__chash]->__next_; __bucket_list_[__chash]->__next_ = __cp; @@ -2390,22 +2312,18 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) size_type __bc = bucket_count(); if (__bc != 0) { - size_t __chash = __constrain_hash(__hash, __bc); + size_t __chash = std::__constrain_hash(__hash, __bc); __next_pointer __nd = __bucket_list_[__chash]; if (__nd != nullptr) { for (__nd = __nd->__next_; __nd != nullptr && (__nd->__hash() == __hash - || __constrain_hash(__nd->__hash(), __bc) == __chash); + || std::__constrain_hash(__nd->__hash(), __bc) == __chash); __nd = __nd->__next_) { if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__value_, __k)) -#if _LIBCPP_DEBUG_LEVEL == 2 return iterator(__nd, this); -#else - return iterator(__nd); -#endif } } } @@ -2421,22 +2339,18 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const size_type __bc = bucket_count(); if (__bc != 0) { - size_t __chash = __constrain_hash(__hash, __bc); + size_t __chash = std::__constrain_hash(__hash, __bc); __next_pointer __nd = __bucket_list_[__chash]; if (__nd != nullptr) { for (__nd = __nd->__next_; __nd != nullptr && (__hash == __nd->__hash() - || __constrain_hash(__nd->__hash(), __bc) == __chash); + || std::__constrain_hash(__nd->__hash(), __bc) == __chash); __nd = __nd->__next_) { if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__value_, __k)) -#if _LIBCPP_DEBUG_LEVEL == 2 return const_iterator(__nd, this); -#else - return const_iterator(__nd); -#endif } } @@ -2484,16 +2398,12 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) { __next_pointer __np = __p.__node_; -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container erase(iterator) called with an iterator not" - " referring to this container"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, + "unordered container erase(iterator) called with an iterator not" + " referring to this container"); _LIBCPP_ASSERT(__p != end(), - "unordered container erase(iterator) called with a non-dereferenceable iterator"); + "unordered container erase(iterator) called with a non-dereferenceable iterator"); iterator __r(__np, this); -#else - iterator __r(__np); -#endif ++__r; remove(__p); return __r; @@ -2504,25 +2414,19 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_iterator __last) { -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, - "unordered container::erase(iterator, iterator) called with an iterator not" - " referring to this container"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, - "unordered container::erase(iterator, iterator) called with an iterator not" - " referring to this container"); -#endif + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, + "unordered container::erase(iterator, iterator) called with an iterator not" + " referring to this container"); for (const_iterator __p = __first; __first != __last; __p = __first) { ++__first; erase(__p); } __next_pointer __np = __last.__node_; -#if _LIBCPP_DEBUG_LEVEL == 2 return iterator (__np, this); -#else - return iterator (__np); -#endif } template @@ -2563,7 +2467,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT // current node __next_pointer __cn = __p.__node_; size_type __bc = bucket_count(); - size_t __chash = __constrain_hash(__cn->__hash(), __bc); + size_t __chash = std::__constrain_hash(__cn->__hash(), __bc); // find previous node __next_pointer __pn = __bucket_list_[__chash]; for (; __pn->__next_ != __cn; __pn = __pn->__next_) @@ -2572,16 +2476,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT // if __pn is not in same bucket (before begin is not in same bucket) && // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) if (__pn == __p1_.first().__ptr() - || __constrain_hash(__pn->__hash(), __bc) != __chash) + || std::__constrain_hash(__pn->__hash(), __bc) != __chash) { if (__cn->__next_ == nullptr - || __constrain_hash(__cn->__next_->__hash(), __bc) != __chash) + || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash) __bucket_list_[__chash] = nullptr; } // if __cn->__next_ is not in same bucket (nullptr is in same bucket) if (__cn->__next_ != nullptr) { - size_t __nhash = __constrain_hash(__cn->__next_->__hash(), __bc); + size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc); if (__nhash != __chash) __bucket_list_[__nhash] = __pn; } @@ -2589,7 +2493,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT __pn->__next_ = __cn->__next_; __cn->__next_ = nullptr; --size(); -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE __c_node* __c = __get_db()->__find_c_and_lock(this); for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) { @@ -2735,14 +2639,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) __p2_.swap(__u.__p2_); __p3_.swap(__u.__p3_); if (size() > 0) - __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); if (__u.size() > 0) - __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = + __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = __u.__p1_.first().__ptr(); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, &__u); -#endif + std::__debug_db_swap(this, std::addressof(__u)); } template @@ -2757,8 +2659,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const if (__np != nullptr) { for (__np = __np->__next_; __np != nullptr && - __constrain_hash(__np->__hash(), __bc) == __n; - __np = __np->__next_, ++__r) + std::__constrain_hash(__np->__hash(), __bc) == __n; + __np = __np->__next_, (void) ++__r) ; } return __r; @@ -2774,7 +2676,7 @@ swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, __x.swap(__y); } -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE template bool @@ -2804,10 +2706,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, return false; } -#endif // _LIBCPP_DEBUG_LEVEL == 2 +#endif // _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP__HASH_TABLE +#endif // _LIBCPP___HASH_TABLE diff --git a/gnu/llvm/libcxx/include/__ios/fpos.h b/gnu/llvm/libcxx/include/__ios/fpos.h new file mode 100644 index 00000000000..87f0135fc3e --- /dev/null +++ b/gnu/llvm/libcxx/include/__ios/fpos.h @@ -0,0 +1,79 @@ +// -*- 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___IOS_FPOS_H +#define _LIBCPP___IOS_FPOS_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS fpos { +private: + _StateT __st_; + streamoff __off_; + +public: + _LIBCPP_HIDE_FROM_ABI fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {} + + _LIBCPP_HIDE_FROM_ABI operator streamoff() const { return __off_; } + + _LIBCPP_HIDE_FROM_ABI _StateT state() const { return __st_; } + _LIBCPP_HIDE_FROM_ABI void state(_StateT __st) { __st_ = __st; } + + _LIBCPP_HIDE_FROM_ABI fpos& operator+=(streamoff __off) { + __off_ += __off; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI fpos operator+(streamoff __off) const { + fpos __t(*this); + __t += __off; + return __t; + } + + _LIBCPP_HIDE_FROM_ABI fpos& operator-=(streamoff __off) { + __off_ -= __off; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI fpos operator-(streamoff __off) const { + fpos __t(*this); + __t -= __off; + return __t; + } +}; + +template +inline _LIBCPP_HIDE_FROM_ABI +streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { + return streamoff(__x) - streamoff(__y); +} + +template +inline _LIBCPP_HIDE_FROM_ABI +bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { + return streamoff(__x) == streamoff(__y); +} + +template +inline _LIBCPP_HIDE_FROM_ABI +bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { + return streamoff(__x) != streamoff(__y); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___IOS_FPOS_H diff --git a/gnu/llvm/libcxx/include/__iterator/access.h b/gnu/llvm/libcxx/include/__iterator/access.h index c0576b45902..0b8d5230171 100644 --- a/gnu/llvm/libcxx/include/__iterator/access.h +++ b/gnu/llvm/libcxx/include/__iterator/access.h @@ -14,16 +14,13 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* begin(_Tp (&__array)[_Np]) { @@ -31,7 +28,7 @@ begin(_Tp (&__array)[_Np]) } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* end(_Tp (&__array)[_Np]) { @@ -41,7 +38,7 @@ end(_Tp (&__array)[_Np]) #if !defined(_LIBCPP_CXX03_LANG) template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(_Cp& __c) -> decltype(__c.begin()) { @@ -49,7 +46,7 @@ begin(_Cp& __c) -> decltype(__c.begin()) } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(const _Cp& __c) -> decltype(__c.begin()) { @@ -57,7 +54,7 @@ begin(const _Cp& __c) -> decltype(__c.begin()) } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(_Cp& __c) -> decltype(__c.end()) { @@ -65,7 +62,7 @@ end(_Cp& __c) -> decltype(__c.end()) } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(const _Cp& __c) -> decltype(__c.end()) { @@ -75,14 +72,14 @@ end(const _Cp& __c) -> decltype(__c.end()) #if _LIBCPP_STD_VER > 11 template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c)) { return _VSTD::begin(__c); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c)) { return _VSTD::end(__c); @@ -129,6 +126,4 @@ end(const _Cp& __c) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_ACCESS_H diff --git a/gnu/llvm/libcxx/include/__iterator/advance.h b/gnu/llvm/libcxx/include/__iterator/advance.h index 47bce1ddfbe..154c2736f31 100644 --- a/gnu/llvm/libcxx/include/__iterator/advance.h +++ b/gnu/llvm/libcxx/include/__iterator/advance.h @@ -10,36 +10,37 @@ #ifndef _LIBCPP___ITERATOR_ADVANCE_H #define _LIBCPP___ITERATOR_ADVANCE_H +#include <__assert> +#include <__concepts/assignable.h> +#include <__concepts/same_as.h> #include <__config> -#include <__debug> -#include <__function_like.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_integral.h> +#include <__utility/convert_to_integral.h> +#include <__utility/declval.h> #include <__utility/move.h> +#include <__utility/unreachable.h> #include -#include #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void __advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { for (; __n > 0; --__n) ++__i; } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { if (__n >= 0) for (; __n > 0; --__n) @@ -50,16 +51,16 @@ void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { __i += __n; } template < class _InputIter, class _Distance, - class _IntegralDistance = decltype(_VSTD::__convert_to_integral(declval<_Distance>())), - class = _EnableIf::value> > -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + class _IntegralDistance = decltype(_VSTD::__convert_to_integral(std::declval<_Distance>())), + class = __enable_if_t::value> > +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void advance(_InputIter& __i, _Distance __orig_n) { typedef typename iterator_traits<_InputIter>::difference_type _Difference; _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n)); @@ -68,18 +69,15 @@ void advance(_InputIter& __i, _Distance __orig_n) { _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); } -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 -namespace ranges { // [range.iter.op.advance] -struct __advance_fn final : private __function_like { -private: - template - _LIBCPP_HIDE_FROM_ABI - static constexpr _Tp __magnitude_geq(_Tp __a, _Tp __b) noexcept { - return __a < 0 ? (__a <= __b) : (__a >= __b); - } +namespace ranges { +namespace __advance { + +struct __fn { +private: template _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) { @@ -99,8 +97,6 @@ private: } public: - constexpr explicit __advance_fn(__tag __x) noexcept : __function_like(__x) {} - // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative. template _LIBCPP_HIDE_FROM_ABI @@ -125,41 +121,46 @@ public: } } - // Preconditions: Either `assignable_from || sized_sentinel_for` is modeled, or [i, bound) denotes a range. + // Preconditions: Either `assignable_from || sized_sentinel_for` is modeled, or [i, bound_sentinel) denotes a range. template _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_Ip& __i, _Sp __bound) const { - // If `I` and `S` model `assignable_from`, equivalent to `i = std::move(bound)`. + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const { + // If `I` and `S` model `assignable_from`, equivalent to `i = std::move(bound_sentinel)`. if constexpr (assignable_from<_Ip&, _Sp>) { - __i = _VSTD::move(__bound); + __i = _VSTD::move(__bound_sentinel); } - // Otherwise, if `S` and `I` model `sized_sentinel_for`, equivalent to `ranges::advance(i, bound - i)`. + // Otherwise, if `S` and `I` model `sized_sentinel_for`, equivalent to `ranges::advance(i, bound_sentinel - i)`. else if constexpr (sized_sentinel_for<_Sp, _Ip>) { - (*this)(__i, __bound - __i); + (*this)(__i, __bound_sentinel - __i); } - // Otherwise, while `bool(i != bound)` is true, increments `i`. + // Otherwise, while `bool(i != bound_sentinel)` is true, increments `i`. else { - while (__i != __bound) { + while (__i != __bound_sentinel) { ++__i; } } } // Preconditions: - // * If `n > 0`, [i, bound) denotes a range. - // * If `n == 0`, [i, bound) or [bound, i) denotes a range. - // * If `n < 0`, [bound, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as`. - // Returns: `n - M`, where `M` is the difference between the the ending and starting position. + // * If `n > 0`, [i, bound_sentinel) denotes a range. + // * If `n == 0`, [i, bound_sentinel) or [bound_sentinel, i) denotes a range. + // * If `n < 0`, [bound_sentinel, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as`. + // Returns: `n - M`, where `M` is the difference between the ending and starting position. template _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, _Sp __bound) const { + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, + _Sp __bound_sentinel) const { _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>), "If `n < 0`, then `bidirectional_iterator && same_as` must be true."); // If `S` and `I` model `sized_sentinel_for`: if constexpr (sized_sentinel_for<_Sp, _Ip>) { - // If |n| >= |bound - i|, equivalent to `ranges::advance(i, bound)`. - if (const auto __M = __bound - __i; __magnitude_geq(__n, __M)) { - (*this)(__i, __bound); + // If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`. + // __magnitude_geq(a, b) returns |a| >= |b|, assuming they have the same sign. + auto __magnitude_geq = [](auto __a, auto __b) { + return __a == 0 ? __b == 0 : + __a > 0 ? __a >= __b : + __a <= __b; + }; + if (const auto __M = __bound_sentinel - __i; __magnitude_geq(__n, __M)) { + (*this)(__i, __bound_sentinel); return __n - __M; } @@ -167,16 +168,16 @@ public: (*this)(__i, __n); return 0; } else { - // Otherwise, if `n` is non-negative, while `bool(i != bound)` is true, increments `i` but at + // Otherwise, if `n` is non-negative, while `bool(i != bound_sentinel)` is true, increments `i` but at // most `n` times. - while (__i != __bound && __n > 0) { + while (__i != __bound_sentinel && __n > 0) { ++__i; --__n; } - // Otherwise, while `bool(i != bound)` is true, decrements `i` but at most `-n` times. + // Otherwise, while `bool(i != bound_sentinel)` is true, decrements `i` but at most `-n` times. if constexpr (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>) { - while (__i != __bound && __n < 0) { + while (__i != __bound_sentinel && __n < 0) { --__i; ++__n; } @@ -184,17 +185,19 @@ public: return __n; } - _LIBCPP_UNREACHABLE(); + __libcpp_unreachable(); } }; -inline constexpr auto advance = __advance_fn(__function_like::__tag()); +} // namespace __advance + +inline namespace __cpo { + inline constexpr auto advance = __advance::__fn{}; +} // namespace __cpo } // namespace ranges -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_ADVANCE_H diff --git a/gnu/llvm/libcxx/include/__iterator/back_insert_iterator.h b/gnu/llvm/libcxx/include/__iterator/back_insert_iterator.h index f34cb863bc0..4c00a7e3979 100644 --- a/gnu/llvm/libcxx/include/__iterator/back_insert_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/back_insert_iterator.h @@ -18,12 +18,9 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH @@ -48,20 +45,23 @@ public: typedef void reference; typedef _Container container_type; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_) - {container->push_back(__value_); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(const typename _Container::value_type& __value) + {container->push_back(__value); return *this;} #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(typename _Container::value_type&& __value_) - {container->push_back(_VSTD::move(__value_)); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(typename _Container::value_type&& __value) + {container->push_back(_VSTD::move(__value)); return *this;} #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator*() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator++() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator operator++(int) {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator*() {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator++() {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator operator++(int) {return *this;} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Container* __get_container() const { return container; } }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(back_insert_iterator); template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator<_Container> back_inserter(_Container& __x) { @@ -70,6 +70,4 @@ back_inserter(_Container& __x) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/bounded_iter.h b/gnu/llvm/libcxx/include/__iterator/bounded_iter.h new file mode 100644 index 00000000000..2682f2a68a2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__iterator/bounded_iter.h @@ -0,0 +1,231 @@ +// -*- 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___ITERATOR_BOUNDED_ITER_H +#define _LIBCPP___ITERATOR_BOUNDED_ITER_H + +#include <__assert> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_convertible.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Iterator wrapper that carries the valid range it is allowed to access. +// +// This is a simple iterator wrapper for contiguous iterators that points +// within a [begin, end) range and carries these bounds with it. The iterator +// ensures that it is pointing within that [begin, end) range when it is +// dereferenced. +// +// Arithmetic operations are allowed and the bounds of the resulting iterator +// are not checked. Hence, it is possible to create an iterator pointing outside +// its range, but it is not possible to dereference it. +template ::value > > +struct __bounded_iter { + using value_type = typename iterator_traits<_Iterator>::value_type; + using difference_type = typename iterator_traits<_Iterator>::difference_type; + using pointer = typename iterator_traits<_Iterator>::pointer; + using reference = typename iterator_traits<_Iterator>::reference; + using iterator_category = typename iterator_traits<_Iterator>::iterator_category; +#if _LIBCPP_STD_VER > 17 + using iterator_concept = contiguous_iterator_tag; +#endif + + // Create a singular iterator. + // + // Such an iterator does not point to any object and is conceptually out of bounds, so it is + // not dereferenceable. Observing operations like comparison and assignment are valid. + _LIBCPP_HIDE_FROM_ABI __bounded_iter() = default; + + _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter const&) = default; + _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter&&) = default; + + template ::value > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT + : __current_(__other.__current_), + __begin_(__other.__begin_), + __end_(__other.__end_) {} + + // Assign a bounded iterator to another one, rebinding the bounds of the iterator as well. + _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter const&) = default; + _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter&&) = default; + +private: + // Create an iterator wrapping the given iterator, and whose bounds are described + // by the provided [begin, end) range. + // + // This constructor does not check whether the resulting iterator is within its bounds. + // However, it does check that the provided [begin, end) range is a valid range (that + // is, begin <= end). + // + // Since it is non-standard for iterators to have this constructor, __bounded_iter must + // be created via `std::__make_bounded_iter`. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter( + _Iterator __current, _Iterator __begin, _Iterator __end) + : __current_(__current), __begin_(__begin), __end_(__end) { + _LIBCPP_ASSERT(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range"); + } + + template + friend _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It, _It, _It); + +public: + // Dereference and indexing operations. + // + // These operations check that the iterator is dereferenceable, that is within [begin, end). + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { + _LIBCPP_ASSERT( + __in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator"); + return *__current_; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT { + _LIBCPP_ASSERT( + __in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator"); + return std::__to_address(__current_); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT { + _LIBCPP_ASSERT( + __in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range"); + return __current_[__n]; + } + + // Arithmetic operations. + // + // These operations do not check that the resulting iterator is within the bounds, since that + // would make it impossible to create a past-the-end iterator. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator++() _NOEXCEPT { + ++__current_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter operator++(int) _NOEXCEPT { + __bounded_iter __tmp(*this); + ++*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator--() _NOEXCEPT { + --__current_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter operator--(int) _NOEXCEPT { + __bounded_iter __tmp(*this); + --*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator+=(difference_type __n) _NOEXCEPT { + __current_ += __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter + operator+(__bounded_iter const& __self, difference_type __n) _NOEXCEPT { + __bounded_iter __tmp(__self); + __tmp += __n; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter + operator+(difference_type __n, __bounded_iter const& __self) _NOEXCEPT { + __bounded_iter __tmp(__self); + __tmp += __n; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator-=(difference_type __n) _NOEXCEPT { + __current_ -= __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter + operator-(__bounded_iter const& __self, difference_type __n) _NOEXCEPT { + __bounded_iter __tmp(__self); + __tmp -= __n; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend difference_type + operator-(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ - __y.__current_; + } + + // Comparison operations. + // + // These operations do not check whether the iterators are within their bounds. + // The valid range for each iterator is also not considered as part of the comparison, + // i.e. two iterators pointing to the same location will be considered equal even + // if they have different validity ranges. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator==(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ == __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator!=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ != __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator<(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ < __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator>(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ > __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator<=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ <= __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator>=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ >= __y.__current_; + } + +private: + // Return whether the given iterator is in the bounds of this __bounded_iter. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Iterator const& __iter) const { + return __iter >= __begin_ && __iter < __end_; + } + + template + friend struct pointer_traits; + _Iterator __current_; // current iterator + _Iterator __begin_, __end_; // valid range represented as [begin, end) +}; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It __it, _It __begin, _It __end) { + return __bounded_iter<_It>(std::move(__it), std::move(__begin), std::move(__end)); +} + +#if _LIBCPP_STD_VER <= 17 +template +struct __is_cpp17_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {}; +#endif + +template +struct pointer_traits<__bounded_iter<_Iterator> > { + using pointer = __bounded_iter<_Iterator>; + using element_type = typename pointer_traits<_Iterator>::element_type; + using difference_type = typename pointer_traits<_Iterator>::difference_type; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __it) _NOEXCEPT { + return std::__to_address(__it.__current_); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H diff --git a/gnu/llvm/libcxx/include/__iterator/common_iterator.h b/gnu/llvm/libcxx/include/__iterator/common_iterator.h index fb01d8bd4b9..f7883e2c372 100644 --- a/gnu/llvm/libcxx/include/__iterator/common_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/common_iterator.h @@ -10,60 +10,53 @@ #ifndef _LIBCPP___ITERATOR_COMMON_ITERATOR_H #define _LIBCPP___ITERATOR_COMMON_ITERATOR_H +#include <__assert> +#include <__concepts/assignable.h> +#include <__concepts/constructible.h> +#include <__concepts/convertible_to.h> +#include <__concepts/copyable.h> +#include <__concepts/derived_from.h> +#include <__concepts/equality_comparable.h> +#include <__concepts/same_as.h> #include <__config> -#include <__debug> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> -#include +#include <__type_traits/is_pointer.h> +#include <__utility/declval.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 + +template +concept __can_use_postfix_proxy = + constructible_from, iter_reference_t<_Iter>> && + move_constructible>; template _Sent> requires (!same_as<_Iter, _Sent> && copyable<_Iter>) class common_iterator { - class __proxy { - friend common_iterator; - - iter_value_t<_Iter> __value; - // We can move __x because the only caller verifies that __x is not a reference. - constexpr __proxy(iter_reference_t<_Iter>&& __x) - : __value(_VSTD::move(__x)) {} - - public: - const iter_value_t<_Iter>* operator->() const { - return _VSTD::addressof(__value); + struct __proxy { + constexpr const iter_value_t<_Iter>* operator->() const noexcept { + return _VSTD::addressof(__value_); } + iter_value_t<_Iter> __value_; }; - class __postfix_proxy { - friend common_iterator; - - iter_value_t<_Iter> __value; - constexpr __postfix_proxy(iter_reference_t<_Iter>&& __x) - : __value(_VSTD::forward>(__x)) {} - - public: - constexpr static bool __valid_for_iter = - constructible_from, iter_reference_t<_Iter>> && - move_constructible>; - - const iter_value_t<_Iter>& operator*() const { - return __value; + struct __postfix_proxy { + constexpr const iter_value_t<_Iter>& operator*() const noexcept { + return __value_; } + iter_value_t<_Iter> __value_; }; public: @@ -78,7 +71,7 @@ public: requires convertible_to && convertible_to constexpr common_iterator(const common_iterator<_I2, _S2>& __other) : __hold_([&]() -> variant<_Iter, _Sent> { - _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Constructed from valueless iterator."); + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); if (__other.__hold_.index() == 0) return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)}; return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)}; @@ -88,7 +81,7 @@ public: requires convertible_to && convertible_to && assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&> common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { - _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Assigned from valueless iterator."); + _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); auto __idx = __hold_.index(); auto __other_idx = __other.__hold_.index(); @@ -108,18 +101,16 @@ public: return *this; } - decltype(auto) operator*() + constexpr decltype(auto) operator*() { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot dereference sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); return *_VSTD::__unchecked_get<_Iter>(__hold_); } - decltype(auto) operator*() const + constexpr decltype(auto) operator*() const requires __dereferenceable { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot dereference sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); return *_VSTD::__unchecked_get<_Iter>(__hold_); } @@ -130,38 +121,33 @@ public: is_reference_v> || constructible_from, iter_reference_t<_I2>>) { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot dereference sentinel. Common iterator not holding an iterator."); - + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { return _VSTD::__unchecked_get<_Iter>(__hold_); } else if constexpr (is_reference_v>) { auto&& __tmp = *_VSTD::__unchecked_get<_Iter>(__hold_); return _VSTD::addressof(__tmp); } else { - return __proxy(*_VSTD::__unchecked_get<_Iter>(__hold_)); + return __proxy{*_VSTD::__unchecked_get<_Iter>(__hold_)}; } } common_iterator& operator++() { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot increment sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this; } decltype(auto) operator++(int) { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__hold_), - "Cannot increment sentinel. Common iterator not holding an iterator."); - + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); if constexpr (forward_iterator<_Iter>) { auto __tmp = *this; ++*this; return __tmp; - } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __referenceable; } || - !__postfix_proxy::__valid_for_iter) { + } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __can_reference; } || + !__can_use_postfix_proxy<_Iter>) { return _VSTD::__unchecked_get<_Iter>(__hold_)++; } else { - __postfix_proxy __p(**this); + auto __p = __postfix_proxy{**this}; ++*this; return __p; } @@ -169,10 +155,10 @@ public: template _S2> requires sentinel_for<_Sent, _I2> - friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() && - !__y.__hold_.valueless_by_exception(), - "One or both common_iterators are valueless. (Cannot compare valueless iterators.)"); + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -188,10 +174,10 @@ public: template _S2> requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2> - friend bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() && - !__y.__hold_.valueless_by_exception(), - "One or both common_iterators are valueless. (Cannot compare valueless iterators.)"); + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -210,10 +196,10 @@ public: template _I2, sized_sentinel_for<_Iter> _S2> requires sized_sentinel_for<_Sent, _I2> - friend iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception() && - !__y.__hold_.valueless_by_exception(), - "One or both common_iterators are valueless. (Cannot subtract valueless iterators.)"); + _LIBCPP_HIDE_FROM_ABI + friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); + _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -230,24 +216,21 @@ public: return _VSTD::__unchecked_get<_Sent>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_); } - friend iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) - noexcept(noexcept(ranges::iter_move(declval()))) + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) + noexcept(noexcept(ranges::iter_move(std::declval()))) requires input_iterator<_Iter> { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__i.__hold_), - "Cannot iter_move a sentinel. Common iterator not holding an iterator."); + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_)); } template _I2, class _S2> - friend void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) - noexcept(noexcept(ranges::iter_swap(declval(), declval()))) + _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) + noexcept(noexcept(ranges::iter_swap(std::declval(), std::declval()))) { - _LIBCPP_ASSERT(holds_alternative<_Iter>(__x.__hold_), - "Cannot swap __y with a sentinel. Common iterator (__x) not holding an iterator."); - _LIBCPP_ASSERT(holds_alternative<_Iter>(__y.__hold_), - "Cannot swap __x with a sentinel. Common iterator (__y) not holding an iterator."); - return ranges::iter_swap( _VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_Iter>(__y.__hold_)); + _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT(std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_)); } }; @@ -274,10 +257,10 @@ struct __arrow_type_or_void { template requires __common_iter_has_ptr_op<_Iter, _Sent> struct __arrow_type_or_void<_Iter, _Sent> { - using type = decltype(declval>().operator->()); + using type = decltype(std::declval&>().operator->()); }; -template +template struct iterator_traits> { using iterator_concept = _If, forward_iterator_tag, @@ -291,11 +274,8 @@ struct iterator_traits> { using reference = iter_reference_t<_Iter>; }; - -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/concepts.h b/gnu/llvm/libcxx/include/__iterator/concepts.h index 6eb4aef1052..d9d40a4249f 100644 --- a/gnu/llvm/libcxx/include/__iterator/concepts.h +++ b/gnu/llvm/libcxx/include/__iterator/concepts.h @@ -10,28 +10,43 @@ #ifndef _LIBCPP___ITERATOR_CONCEPTS_H #define _LIBCPP___ITERATOR_CONCEPTS_H +#include <__concepts/arithmetic.h> +#include <__concepts/assignable.h> +#include <__concepts/common_reference_with.h> +#include <__concepts/constructible.h> +#include <__concepts/copyable.h> +#include <__concepts/derived_from.h> +#include <__concepts/equality_comparable.h> +#include <__concepts/invocable.h> +#include <__concepts/movable.h> +#include <__concepts/predicate.h> +#include <__concepts/regular.h> +#include <__concepts/relation.h> +#include <__concepts/same_as.h> +#include <__concepts/semiregular.h> +#include <__concepts/totally_ordered.h> #include <__config> +#include <__functional/invoke.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iter_move.h> #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> #include <__memory/pointer_traits.h> +#include <__type_traits/add_pointer.h> +#include <__type_traits/common_reference.h> +#include <__type_traits/is_pointer.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/remove_cvref.h> #include <__utility/forward.h> -#include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) - -// clang-format off +#if _LIBCPP_STD_VER > 17 // [iterator.concept.readable] template @@ -72,6 +87,8 @@ concept __signed_integer_like = signed_integral<_Tp>; template concept weakly_incrementable = + // TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173). + !same_as<_Ip, bool> && // Currently, clang does not handle bool correctly. movable<_Ip> && requires(_Ip __i) { typename iter_difference_t<_Ip>; @@ -93,7 +110,7 @@ concept incrementable = template concept input_or_output_iterator = requires(_Ip __i) { - { *__i } -> __referenceable; + { *__i } -> __can_reference; } && weakly_incrementable<_Ip>; @@ -172,7 +189,6 @@ concept contiguous_iterator = derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> && is_lvalue_reference_v> && same_as, remove_cvref_t>> && - (is_pointer_v<_Ip> || requires { sizeof(__pointer_traits_element_type<_Ip>); }) && requires(const _Ip& __i) { { _VSTD::to_address(__i) } -> same_as>>; }; @@ -258,15 +274,27 @@ concept indirectly_movable_storable = constructible_from, iter_rvalue_reference_t<_In>> && assignable_from&, iter_rvalue_reference_t<_In>>; +template +concept indirectly_copyable = + indirectly_readable<_In> && + indirectly_writable<_Out, iter_reference_t<_In>>; + +template +concept indirectly_copyable_storable = + indirectly_copyable<_In, _Out> && + indirectly_writable<_Out, iter_value_t<_In>&> && + indirectly_writable<_Out, const iter_value_t<_In>&> && + indirectly_writable<_Out, iter_value_t<_In>&&> && + indirectly_writable<_Out, const iter_value_t<_In>&&> && + copyable> && + constructible_from, iter_reference_t<_In>> && + assignable_from&, iter_reference_t<_In>>; + // Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle // (both iter_swap and indirectly_swappable require indirectly_readable). -// clang-format on - -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_CONCEPTS_H diff --git a/gnu/llvm/libcxx/include/__iterator/counted_iterator.h b/gnu/llvm/libcxx/include/__iterator/counted_iterator.h index 7136aaf0258..5fdbff4b486 100644 --- a/gnu/llvm/libcxx/include/__iterator/counted_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/counted_iterator.h @@ -6,32 +6,37 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// + #ifndef _LIBCPP___ITERATOR_COUNTED_ITERATOR_H #define _LIBCPP___ITERATOR_COUNTED_ITERATOR_H +#include <__assert> +#include <__concepts/assignable.h> +#include <__concepts/common_with.h> +#include <__concepts/constructible.h> +#include <__concepts/convertible_to.h> +#include <__concepts/same_as.h> #include <__config> -#include <__debug> #include <__iterator/concepts.h> #include <__iterator/default_sentinel.h> +#include <__iterator/incrementable_traits.h> #include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> -#include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> #include <__memory/pointer_traits.h> -#include -#include +#include <__type_traits/add_pointer.h> +#include <__type_traits/conditional.h> +#include <__utility/move.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 template struct __counted_iterator_concept {}; @@ -66,7 +71,7 @@ class counted_iterator , public __counted_iterator_value_type<_Iter> { public: - [[no_unique_address]] _Iter __current_ = _Iter(); + _LIBCPP_NO_UNIQUE_ADDRESS _Iter __current_ = _Iter(); iter_difference_t<_Iter> __count_ = 0; using iterator_type = _Iter; @@ -97,7 +102,7 @@ public: } _LIBCPP_HIDE_FROM_ABI - constexpr const _Iter& base() const& { return __current_; } + constexpr const _Iter& base() const& noexcept { return __current_; } _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return _VSTD::move(__current_); } @@ -264,7 +269,7 @@ public: } template _I2> - friend constexpr strong_ordering operator<=>( + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering operator<=>( const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) { return __rhs.__count_ <=> __lhs.__count_; @@ -289,6 +294,7 @@ public: return ranges::iter_swap(__x.__current_, __y.__current_); } }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(counted_iterator); template requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>> @@ -297,10 +303,8 @@ struct iterator_traits> : iterator_traits<_Iter> { add_pointer_t>, void>; }; -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/data.h b/gnu/llvm/libcxx/include/__iterator/data.h index cd8e37b96b6..88eb752b642 100644 --- a/gnu/llvm/libcxx/include/__iterator/data.h +++ b/gnu/llvm/libcxx/include/__iterator/data.h @@ -15,12 +15,9 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 @@ -51,6 +48,4 @@ constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.beg _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_DATA_H diff --git a/gnu/llvm/libcxx/include/__iterator/default_sentinel.h b/gnu/llvm/libcxx/include/__iterator/default_sentinel.h index 934a56fd9e2..669032aa972 100644 --- a/gnu/llvm/libcxx/include/__iterator/default_sentinel.h +++ b/gnu/llvm/libcxx/include/__iterator/default_sentinel.h @@ -13,23 +13,18 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 struct default_sentinel_t { }; inline constexpr default_sentinel_t default_sentinel{}; -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H diff --git a/gnu/llvm/libcxx/include/__iterator/distance.h b/gnu/llvm/libcxx/include/__iterator/distance.h index 33e4af84d36..681e20d045b 100644 --- a/gnu/llvm/libcxx/include/__iterator/distance.h +++ b/gnu/llvm/libcxx/include/__iterator/distance.h @@ -11,19 +11,23 @@ #define _LIBCPP___ITERATOR_DISTANCE_H #include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/size.h> +#include <__type_traits/decay.h> +#include <__type_traits/remove_cvref.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type __distance(_InputIter __first, _InputIter __last, input_iterator_tag) { @@ -34,7 +38,7 @@ __distance(_InputIter __first, _InputIter __last, input_iterator_tag) } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_RandIter>::difference_type __distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) { @@ -42,15 +46,63 @@ __distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type distance(_InputIter __first, _InputIter __last) { return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); } -_LIBCPP_END_NAMESPACE_STD +#if _LIBCPP_STD_VER > 17 + +// [range.iter.op.distance] + +namespace ranges { +namespace __distance { + +struct __fn { + template _Sp> + requires (!sized_sentinel_for<_Sp, _Ip>) + _LIBCPP_HIDE_FROM_ABI + constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const { + iter_difference_t<_Ip> __n = 0; + while (__first != __last) { + ++__first; + ++__n; + } + return __n; + } + + template> _Sp> + _LIBCPP_HIDE_FROM_ABI + constexpr iter_difference_t<_Ip> operator()(_Ip&& __first, _Sp __last) const { + if constexpr (sized_sentinel_for<_Sp, __remove_cvref_t<_Ip>>) { + return __last - __first; + } else { + return __last - decay_t<_Ip>(__first); + } + } -_LIBCPP_POP_MACROS + template + _LIBCPP_HIDE_FROM_ABI + constexpr range_difference_t<_Rp> operator()(_Rp&& __r) const { + if constexpr (sized_range<_Rp>) { + return static_cast>(ranges::size(__r)); + } else { + return operator()(ranges::begin(__r), ranges::end(__r)); + } + } +}; + +} // namespace __distance + +inline namespace __cpo { + inline constexpr auto distance = __distance::__fn{}; +} // namespace __cpo +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___ITERATOR_DISTANCE_H diff --git a/gnu/llvm/libcxx/include/__iterator/empty.h b/gnu/llvm/libcxx/include/__iterator/empty.h index 4dd59f5cccb..748ca9ecbd5 100644 --- a/gnu/llvm/libcxx/include/__iterator/empty.h +++ b/gnu/llvm/libcxx/include/__iterator/empty.h @@ -15,12 +15,9 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 @@ -44,6 +41,4 @@ constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() = _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_EMPTY_H diff --git a/gnu/llvm/libcxx/include/__iterator/erase_if_container.h b/gnu/llvm/libcxx/include/__iterator/erase_if_container.h index a5dfd072053..d7c71a947a2 100644 --- a/gnu/llvm/libcxx/include/__iterator/erase_if_container.h +++ b/gnu/llvm/libcxx/include/__iterator/erase_if_container.h @@ -13,12 +13,9 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template @@ -40,6 +37,4 @@ __libcpp_erase_if_container(_Container& __c, _Predicate& __pred) { _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H diff --git a/gnu/llvm/libcxx/include/__iterator/front_insert_iterator.h b/gnu/llvm/libcxx/include/__iterator/front_insert_iterator.h index 0421dd5c4b2..e278359d870 100644 --- a/gnu/llvm/libcxx/include/__iterator/front_insert_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/front_insert_iterator.h @@ -18,12 +18,9 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH @@ -48,20 +45,21 @@ public: typedef void reference; typedef _Container container_type; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_) - {container->push_front(__value_); return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(const typename _Container::value_type& __value) + {container->push_front(__value); return *this;} #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(typename _Container::value_type&& __value_) - {container->push_front(_VSTD::move(__value_)); return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(typename _Container::value_type&& __value) + {container->push_front(_VSTD::move(__value)); return *this;} #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator*() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator++() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator operator++(int) {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator operator++(int) {return *this;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(front_insert_iterator); template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator<_Container> front_inserter(_Container& __x) { @@ -70,6 +68,4 @@ front_inserter(_Container& __x) _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/incrementable_traits.h b/gnu/llvm/libcxx/include/__iterator/incrementable_traits.h index 5a433982ba2..3d06dc05359 100644 --- a/gnu/llvm/libcxx/include/__iterator/incrementable_traits.h +++ b/gnu/llvm/libcxx/include/__iterator/incrementable_traits.h @@ -10,20 +10,23 @@ #ifndef _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H #define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H +#include <__concepts/arithmetic.h> #include <__config> -#include -#include +#include <__type_traits/conditional.h> +#include <__type_traits/is_object.h> +#include <__type_traits/is_primary_template.h> +#include <__type_traits/make_signed.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 // [incrementable.traits] template struct incrementable_traits {}; @@ -54,7 +57,7 @@ concept __has_integral_minus = template<__has_integral_minus _Tp> requires (!__has_member_difference_type<_Tp>) struct incrementable_traits<_Tp> { - using difference_type = make_signed_t() - declval<_Tp>())>; + using difference_type = make_signed_t() - std::declval<_Tp>())>; }; template @@ -68,10 +71,8 @@ using iter_difference_t = typename conditional_t<__is_primary_template >, iterator_traits > >::difference_type; -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H diff --git a/gnu/llvm/libcxx/include/__iterator/indirectly_comparable.h b/gnu/llvm/libcxx/include/__iterator/indirectly_comparable.h new file mode 100644 index 00000000000..868190fc48d --- /dev/null +++ b/gnu/llvm/libcxx/include/__iterator/indirectly_comparable.h @@ -0,0 +1,34 @@ +// -*- 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___ITERATOR_INDIRECTLY_COMPARABLE_H +#define _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H + +#include <__config> +#include <__functional/identity.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept indirectly_comparable = + indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H diff --git a/gnu/llvm/libcxx/include/__iterator/insert_iterator.h b/gnu/llvm/libcxx/include/__iterator/insert_iterator.h index 26581418247..ecaea61c61e 100644 --- a/gnu/llvm/libcxx/include/__iterator/insert_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/insert_iterator.h @@ -14,18 +14,24 @@ #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> +#include <__ranges/access.h> #include <__utility/move.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +#if _LIBCPP_STD_VER > 17 +template +using __insert_iterator_iter_t = ranges::iterator_t<_Container>; +#else +template +using __insert_iterator_iter_t = typename _Container::iterator; +#endif + _LIBCPP_SUPPRESS_DEPRECATED_PUSH template class _LIBCPP_TEMPLATE_VIS insert_iterator @@ -36,7 +42,7 @@ class _LIBCPP_TEMPLATE_VIS insert_iterator _LIBCPP_SUPPRESS_DEPRECATED_POP protected: _Container* container; - typename _Container::iterator iter; // FIXME: `ranges::iterator_t` in C++20 mode + __insert_iterator_iter_t<_Container> iter; public: typedef output_iterator_tag iterator_category; typedef void value_type; @@ -49,29 +55,27 @@ public: typedef void reference; typedef _Container container_type; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i) : container(_VSTD::addressof(__x)), iter(__i) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_) - {iter = container->insert(iter, __value_); ++iter; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(const typename _Container::value_type& __value) + {iter = container->insert(iter, __value); ++iter; return *this;} #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(typename _Container::value_type&& __value_) - {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(typename _Container::value_type&& __value) + {iter = container->insert(iter, _VSTD::move(__value)); ++iter; return *this;} #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator*() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++(int) {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator*() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++() {return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++(int) {return *this;} }; template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator<_Container> -inserter(_Container& __x, typename _Container::iterator __i) +inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i) { return insert_iterator<_Container>(__x, __i); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/istream_iterator.h b/gnu/llvm/libcxx/include/__iterator/istream_iterator.h index f39faa6d590..a056961c10a 100644 --- a/gnu/llvm/libcxx/include/__iterator/istream_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/istream_iterator.h @@ -11,18 +11,17 @@ #define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H #include <__config> +#include <__iterator/default_sentinel.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> +#include #include // for forward declarations of char_traits and basic_istream #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH @@ -48,6 +47,9 @@ private: _Tp __value_; public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {} +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {} +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s)) { if (!(*__in_stream_ >> __value_)) @@ -71,11 +73,11 @@ public: operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); - template - friend _LIBCPP_INLINE_VISIBILITY - bool - operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, - const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); +#if _LIBCPP_STD_VER > 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) { + return __i.__in_stream_ == nullptr; + } +#endif // _LIBCPP_STD_VER > 17 }; template @@ -87,6 +89,7 @@ operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, return __x.__in_stream_ == __y.__in_stream_; } +#if _LIBCPP_STD_VER <= 17 template inline _LIBCPP_INLINE_VISIBILITY bool @@ -95,9 +98,8 @@ operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, { return !(__x == __y); } +#endif // _LIBCPP_STD_VER <= 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/istreambuf_iterator.h b/gnu/llvm/libcxx/include/__iterator/istreambuf_iterator.h index 119698d54ce..bc53a6a1c80 100644 --- a/gnu/llvm/libcxx/include/__iterator/istreambuf_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/istreambuf_iterator.h @@ -11,17 +11,15 @@ #define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H #include <__config> +#include <__iterator/default_sentinel.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include // for forward declaration of basic_streambuf #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH @@ -52,7 +50,8 @@ private: { char_type __keep_; streambuf_type* __sbuf_; - _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s) + _LIBCPP_INLINE_VISIBILITY + explicit __proxy(char_type __c, streambuf_type* __s) : __keep_(__c), __sbuf_(__s) {} friend class istreambuf_iterator; public: @@ -68,6 +67,10 @@ private: } public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} +#if _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept + : istreambuf_iterator() {} +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT : __sbuf_(__s.rdbuf()) {} _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT @@ -89,6 +92,12 @@ public: _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const {return __test_for_eof() == __b.__test_for_eof();} + +#if _LIBCPP_STD_VER > 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) { + return __i.__test_for_eof(); + } +#endif // _LIBCPP_STD_VER > 17 }; template @@ -97,14 +106,14 @@ bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a, const istreambuf_iterator<_CharT,_Traits>& __b) {return __a.equal(__b);} +#if _LIBCPP_STD_VER <= 17 template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a, const istreambuf_iterator<_CharT,_Traits>& __b) {return !__a.equal(__b);} +#endif // _LIBCPP_STD_VER <= 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/iter_move.h b/gnu/llvm/libcxx/include/__iterator/iter_move.h index 5540799e197..a7d9413fb84 100644 --- a/gnu/llvm/libcxx/include/__iterator/iter_move.h +++ b/gnu/llvm/libcxx/include/__iterator/iter_move.h @@ -10,82 +10,95 @@ #ifndef _LIBCPP___ITERATOR_ITER_MOVE_H #define _LIBCPP___ITERATOR_ITER_MOVE_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/iterator_traits.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> #include <__utility/forward.h> -#include // __class_or_enum -#include -#include +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 + +// [iterator.cust.move] + +namespace ranges { +namespace __iter_move { -namespace ranges::__iter_move { void iter_move(); -template -concept __unqualified_iter_move = requires(_Ip&& __i) { - iter_move(_VSTD::forward<_Ip>(__i)); -}; +template +concept __unqualified_iter_move = + __class_or_enum> && + requires (_Tp&& __t) { + // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap + iter_move(std::forward<_Tp>(__t)); + }; + +template +concept __move_deref = + !__unqualified_iter_move<_Tp> && + requires (_Tp&& __t) { + *__t; + requires is_lvalue_reference_v; + }; + +template +concept __just_deref = + !__unqualified_iter_move<_Tp> && + !__move_deref<_Tp> && + requires (_Tp&& __t) { + *__t; + requires (!is_lvalue_reference_v); + }; + +// [iterator.cust.move] -// [iterator.cust.move]/1 -// The name ranges::iter_move denotes a customization point object. -// The expression ranges::iter_move(E) for a subexpression E is -// expression-equivalent to: struct __fn { - // [iterator.cust.move]/1.1 - // iter_move(E), if E has class or enumeration type and iter_move(E) is a - // well-formed expression when treated as an unevaluated operand, [...] + // NOLINTBEGIN(libcpp-robust-against-adl) iter_move ADL calls should only be made through ranges::iter_move template - requires __class_or_enum> && __unqualified_iter_move<_Ip> + requires __unqualified_iter_move<_Ip> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const - noexcept(noexcept(iter_move(_VSTD::forward<_Ip>(__i)))) + noexcept(noexcept(iter_move(std::forward<_Ip>(__i)))) { - return iter_move(_VSTD::forward<_Ip>(__i)); + return iter_move(std::forward<_Ip>(__i)); } + // NOLINTEND(libcpp-robust-against-adl) - // [iterator.cust.move]/1.2 - // Otherwise, if the expression *E is well-formed: - // 1.2.1 if *E is an lvalue, std::move(*E); - // 1.2.2 otherwise, *E. template - requires (!(__class_or_enum> && __unqualified_iter_move<_Ip>)) && - requires(_Ip&& __i) { *_VSTD::forward<_Ip>(__i); } - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const - noexcept(noexcept(*_VSTD::forward<_Ip>(__i))) - { - if constexpr (is_lvalue_reference_v(__i))>) { - return _VSTD::move(*_VSTD::forward<_Ip>(__i)); - } else { - return *_VSTD::forward<_Ip>(__i); - } - } + requires __move_deref<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const + noexcept(noexcept(std::move(*std::forward<_Ip>(__i)))) + -> decltype( std::move(*std::forward<_Ip>(__i))) + { return std::move(*std::forward<_Ip>(__i)); } - // [iterator.cust.move]/1.3 - // Otherwise, ranges::iter_move(E) is ill-formed. + template + requires __just_deref<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const + noexcept(noexcept(*std::forward<_Ip>(__i))) + -> decltype( *std::forward<_Ip>(__i)) + { return *std::forward<_Ip>(__i); } }; -} // namespace ranges::__iter_move +} // namespace __iter_move -namespace ranges::inline __cpo { +inline namespace __cpo { inline constexpr auto iter_move = __iter_move::__fn{}; -} +} // namespace __cpo +} // namespace ranges template<__dereferenceable _Tp> -requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __referenceable; } -using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<_Tp&>())); + requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; } +using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>())); -#endif // !_LIBCPP_HAS_NO_RANGES +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_ITER_MOVE_H diff --git a/gnu/llvm/libcxx/include/__iterator/iter_swap.h b/gnu/llvm/libcxx/include/__iterator/iter_swap.h index d70da09b4ab..d4c0dca1f63 100644 --- a/gnu/llvm/libcxx/include/__iterator/iter_swap.h +++ b/gnu/llvm/libcxx/include/__iterator/iter_swap.h @@ -6,28 +6,31 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// + #ifndef _LIBCPP___ITERATOR_ITER_SWAP_H #define _LIBCPP___ITERATOR_ITER_SWAP_H +#include <__concepts/class_or_enum.h> +#include <__concepts/swappable.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/iter_move.h> #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> -#include <__ranges/access.h> -#include -#include +#include <__type_traits/remove_cvref.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 + +// [iter.cust.swap] namespace ranges { namespace __iter_swap { @@ -35,16 +38,21 @@ namespace __iter_swap { void iter_swap(_I1, _I2) = delete; template - concept __unqualified_iter_swap = requires(_T1&& __x, _T2&& __y) { - iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)); - }; + concept __unqualified_iter_swap = + (__class_or_enum> || __class_or_enum>) && + requires (_T1&& __x, _T2&& __y) { + // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap + iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)); + }; template concept __readable_swappable = indirectly_readable<_T1> && indirectly_readable<_T2> && swappable_with, iter_reference_t<_T2>>; + struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap template requires __unqualified_iter_swap<_T1, _T2> _LIBCPP_HIDE_FROM_ABI @@ -53,6 +61,7 @@ namespace __iter_swap { { (void)iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)); } + // NOLINTEND(libcpp-robust-against-adl) template requires (!__unqualified_iter_swap<_T1, _T2>) && @@ -73,19 +82,18 @@ namespace __iter_swap { constexpr void operator()(_T1&& __x, _T2&& __y) const noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) && noexcept(*__y = ranges::iter_move(__x)) && - noexcept(*_VSTD::forward<_T1>(__x) = declval>())) + noexcept(*_VSTD::forward<_T1>(__x) = std::declval>())) { iter_value_t<_T2> __old(ranges::iter_move(__y)); *__y = ranges::iter_move(__x); *_VSTD::forward<_T1>(__x) = _VSTD::move(__old); } }; -} // end namespace __iter_swap +} // namespace __iter_swap inline namespace __cpo { inline constexpr auto iter_swap = __iter_swap::__fn{}; } // namespace __cpo - } // namespace ranges template @@ -98,10 +106,8 @@ concept indirectly_swappable = ranges::iter_swap(__i2, __i1); }; -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_ITER_SWAP_H diff --git a/gnu/llvm/libcxx/include/__iterator/iterator.h b/gnu/llvm/libcxx/include/__iterator/iterator.h index dfd481e3571..b417eeab79b 100644 --- a/gnu/llvm/libcxx/include/__iterator/iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/iterator.h @@ -14,12 +14,9 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template +#include <__concepts/constructible.h> +#include <__concepts/convertible_to.h> +#include <__concepts/copyable.h> +#include <__concepts/equality_comparable.h> +#include <__concepts/same_as.h> +#include <__concepts/totally_ordered.h> #include <__config> +#include <__fwd/pair.h> #include <__iterator/incrementable_traits.h> #include <__iterator/readable_traits.h> -#include -#include +#include <__type_traits/add_const.h> +#include <__type_traits/common_reference.h> +#include <__type_traits/conditional.h> +#include <__type_traits/disjunction.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_object.h> +#include <__type_traits/is_primary_template.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/is_valid_expansion.h> +#include <__type_traits/remove_const.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/remove_cvref.h> +#include <__type_traits/void_t.h> +#include <__utility/declval.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 template using __with_reference = _Tp&; template -concept __referenceable = requires { +concept __can_reference = requires { typename __with_reference<_Tp>; }; template concept __dereferenceable = requires(_Tp& __t) { - { *__t } -> __referenceable; // not required to be equality-preserving + { *__t } -> __can_reference; // not required to be equality-preserving }; // [iterator.traits] template<__dereferenceable _Tp> -using iter_reference_t = decltype(*declval<_Tp&>()); +using iter_reference_t = decltype(*std::declval<_Tp&>()); -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 template struct _LIBCPP_TEMPLATE_VIS iterator_traits; @@ -79,7 +97,7 @@ struct __iter_concept_category_test { }; struct __iter_concept_random_fallback { template - using _Apply = _EnableIf< + using _Apply = __enable_if_t< __is_primary_template >::value, random_access_iterator_tag >; @@ -108,15 +126,14 @@ template struct __has_iterator_typedefs { private: - struct __two {char __lx; char __lxx;}; - template static __two __test(...); - template static char __test(typename __void_t::type* = 0, - typename __void_t::type* = 0, - typename __void_t::type* = 0, - typename __void_t::type* = 0, - typename __void_t::type* = 0); + template static false_type __test(...); + template static true_type __test(__void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr); public: - static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1; + static const bool value = decltype(__test<_Tp>(0,0,0,0,0))::value; }; @@ -124,35 +141,34 @@ template struct __has_iterator_category { private: - struct __two {char __lx; char __lxx;}; - template static __two __test(...); - template static char __test(typename _Up::iterator_category* = nullptr); + template static false_type __test(...); + template static true_type __test(typename _Up::iterator_category* = nullptr); public: - static const bool value = sizeof(__test<_Tp>(nullptr)) == 1; + static const bool value = decltype(__test<_Tp>(nullptr))::value; }; template struct __has_iterator_concept { private: - struct __two {char __lx; char __lxx;}; - template static __two __test(...); - template static char __test(typename _Up::iterator_concept* = nullptr); + template static false_type __test(...); + template static true_type __test(typename _Up::iterator_concept* = nullptr); public: - static const bool value = sizeof(__test<_Tp>(nullptr)) == 1; + static const bool value = decltype(__test<_Tp>(nullptr))::value; }; -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 -// The `cpp17-*-iterator` exposition-only concepts are easily confused with the Cpp17*Iterator tables, -// so they've been banished to a namespace that makes it obvious they have a niche use-case. +// The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements +// from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to +// a "detail" namespace indicating they have a niche use-case. namespace __iterator_traits_detail { template concept __cpp17_iterator = requires(_Ip __i) { - { *__i } -> __referenceable; + { *__i } -> __can_reference; { ++__i } -> same_as<_Ip&>; - { *__i++ } -> __referenceable; + { *__i++ } -> __can_reference; } && copyable<_Ip>; @@ -201,7 +217,7 @@ concept __cpp17_random_access_iterator = { __i + __n } -> same_as<_Ip>; { __n + __i } -> same_as<_Ip>; { __i - __n } -> same_as<_Ip>; - { __i - __i } -> same_as; + { __i - __i } -> same_as; // NOLINT(misc-redundant-expression) ; This is llvm.org/PR54114 { __i[__n] } -> convertible_to>; }; } // namespace __iterator_traits_detail @@ -257,7 +273,7 @@ struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typ template requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>) struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { - using type = decltype(declval<_Ip&>().operator->()); + using type = decltype(std::declval<_Ip&>().operator->()); }; // Otherwise, `reference` names `iter-reference-t`. @@ -365,7 +381,7 @@ struct iterator_traits : __iterator_traits<_Ip> { using __primary_template = iterator_traits; }; -#else // !defined(_LIBCPP_HAS_NO_RANGES) +#else // _LIBCPP_STD_VER > 17 template struct __iterator_traits {}; @@ -402,16 +418,16 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits using __primary_template = iterator_traits; }; -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 template -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 requires is_object_v<_Tp> #endif struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> { typedef ptrdiff_t difference_type; - typedef typename remove_cv<_Tp>::type value_type; + typedef __remove_cv_t<_Tp> value_type; typedef _Tp* pointer; typedef _Tp& reference; typedef random_access_iterator_tag iterator_category; @@ -471,30 +487,53 @@ template struct __is_cpp17_contiguous_iterator<_Up*> : true_type {}; +template +class __wrap_iter; + template struct __is_exactly_cpp17_input_iterator : public integral_constant::value && !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {}; -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template +struct __is_exactly_cpp17_forward_iterator + : public integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value> {}; + +template +struct __is_exactly_cpp17_bidirectional_iterator + : public integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value> {}; + template using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; template -using __iter_key_type = remove_const_t::value_type::first_type>; +using __iter_key_type = __remove_const_t::value_type::first_type>; template using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type; template using __iter_to_alloc_type = pair< - add_const_t::value_type::first_type>, + typename add_const::value_type::first_type>::type, typename iterator_traits<_InputIterator>::value_type::second_type>; -#endif // _LIBCPP_HAS_NO_DEDUCTION_GUIDES -_LIBCPP_END_NAMESPACE_STD +template +using __iterator_category_type = typename iterator_traits<_Iter>::iterator_category; -_LIBCPP_POP_MACROS +template +using __iterator_pointer_type = typename iterator_traits<_Iter>::pointer; + +template +using __iter_diff_t = typename iterator_traits<_Iter>::difference_type; + +template +using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; + +_LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___ITERATOR_ITERATOR_TRAITS_H diff --git a/gnu/llvm/libcxx/include/__iterator/iterator_with_data.h b/gnu/llvm/libcxx/include/__iterator/iterator_with_data.h new file mode 100644 index 00000000000..06c2fa699c3 --- /dev/null +++ b/gnu/llvm/libcxx/include/__iterator/iterator_with_data.h @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===// +// +// 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___ITERATOR_ITERATOR_WITH_DATA_H +#define _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H + +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 20 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class __iterator_with_data { + _Iterator __iter_{}; + _Data __data_{}; + +public: + using value_type = iter_value_t<_Iterator>; + using difference_type = iter_difference_t<_Iterator>; + + _LIBCPP_HIDE_FROM_ABI __iterator_with_data() = default; + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data(_Iterator __iter, _Data __data) + : __iter_(std::move(__iter)), __data_(std::move(__data)) {} + + constexpr _LIBCPP_HIDE_FROM_ABI _Iterator __get_iter() const { return __iter_; } + + constexpr _LIBCPP_HIDE_FROM_ABI _Data __get_data() && { return std::move(__data_); } + + friend constexpr _LIBCPP_HIDE_FROM_ABI bool + operator==(const __iterator_with_data& __lhs, const __iterator_with_data& __rhs) { + return __lhs.__iter_ == __rhs.__iter_; + } + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator++() { + ++__iter_; + return *this; + } + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator++(int) { + auto __tmp = *this; + __iter_++; + return __tmp; + } + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator--() + requires bidirectional_iterator<_Iterator> + { + --__iter_; + return *this; + } + + constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator--(int) + requires bidirectional_iterator<_Iterator> + { + auto __tmp = *this; + --__iter_; + return __tmp; + } + + constexpr _LIBCPP_HIDE_FROM_ABI iter_reference_t<_Iterator> operator*() const { return *__iter_; } + + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iterator> + iter_move(const __iterator_with_data& __iter) noexcept(noexcept(ranges::iter_move(__iter.__iter_))) { + return ranges::iter_move(__iter.__iter_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(const __iterator_with_data& __lhs, + const __iterator_with_data& __rhs) noexcept(noexcept(ranges::iter_swap(__lhs.__iter_, __rhs.__iter_))) + requires indirectly_swappable<_Iterator> + { + return ranges::iter_swap(__lhs.__data_, __rhs.__iter_); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 20 + +#endif // _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H diff --git a/gnu/llvm/libcxx/include/__iterator/mergeable.h b/gnu/llvm/libcxx/include/__iterator/mergeable.h new file mode 100644 index 00000000000..b9f2d081dc7 --- /dev/null +++ b/gnu/llvm/libcxx/include/__iterator/mergeable.h @@ -0,0 +1,41 @@ +// -*- 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___ITERATOR_MERGEABLE_H +#define _LIBCPP___ITERATOR_MERGEABLE_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept mergeable = + input_iterator<_Input1> && + input_iterator<_Input2> && + weakly_incrementable<_Output> && + indirectly_copyable<_Input1, _Output> && + indirectly_copyable<_Input2, _Output> && + indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_MERGEABLE_H diff --git a/gnu/llvm/libcxx/include/__iterator/move_iterator.h b/gnu/llvm/libcxx/include/__iterator/move_iterator.h index 7819743bdb3..fa806dbaf70 100644 --- a/gnu/llvm/libcxx/include/__iterator/move_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/move_iterator.h @@ -10,180 +10,326 @@ #ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H #define _LIBCPP___ITERATOR_MOVE_ITERATOR_H +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/assignable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/derived_from.h> +#include <__concepts/same_as.h> #include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> #include <__iterator/iterator_traits.h> -#include +#include <__iterator/move_sentinel.h> +#include <__iterator/readable_traits.h> +#include <__type_traits/conditional.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/is_same.h> +#include <__type_traits/remove_reference.h> +#include <__utility/declval.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD +#if _LIBCPP_STD_VER > 17 +template +struct __move_iter_category_base {}; + +template + requires requires { typename iterator_traits<_Iter>::iterator_category; } +struct __move_iter_category_base<_Iter> { + using iterator_category = _If< + derived_from::iterator_category, random_access_iterator_tag>, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category + >; +}; + +template +concept __move_iter_comparable = requires { + { std::declval() == std::declval<_Sent>() } -> convertible_to; +}; +#endif // _LIBCPP_STD_VER > 17 + template class _LIBCPP_TEMPLATE_VIS move_iterator +#if _LIBCPP_STD_VER > 17 + : public __move_iter_category_base<_Iter> +#endif { -private: - _Iter __i; public: - typedef _Iter iterator_type; +#if _LIBCPP_STD_VER > 17 + using iterator_type = _Iter; + using iterator_concept = input_iterator_tag; + // iterator_category is inherited and not always present + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using pointer = _Iter; + using reference = iter_rvalue_reference_t<_Iter>; +#else + typedef _Iter iterator_type; + typedef _If< + __is_cpp17_random_access_iterator<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category + > iterator_category; typedef typename iterator_traits::value_type value_type; typedef typename iterator_traits::difference_type difference_type; typedef iterator_type pointer; - typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category> iterator_category; -#if _LIBCPP_STD_VER > 17 - typedef input_iterator_tag iterator_concept; -#endif -#ifndef _LIBCPP_CXX03_LANG typedef typename iterator_traits::reference __reference; typedef typename conditional< is_reference<__reference>::value, - typename remove_reference<__reference>::type&&, + __libcpp_remove_reference_t<__reference>&&, __reference >::type reference; -#else - typedef typename iterator_traits::reference reference; -#endif +#endif // _LIBCPP_STD_VER > 17 + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator& operator++() { ++__current_; return *this; } + + _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + pointer operator->() const { return __current_; } + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator() requires is_constructible_v<_Iter> : __current_() {} + + template + requires (!_IsSame<_Up, _Iter>::value) && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} + + template + requires (!_IsSame<_Up, _Iter>::value) && + convertible_to && + assignable_from<_Iter&, const _Up&> + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator() : __i() {} + _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - explicit move_iterator(_Iter __x) : __i(__x) {} + _LIBCPP_HIDE_FROM_ABI constexpr + reference operator*() const { return ranges::iter_move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr + reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); } + + _LIBCPP_HIDE_FROM_ABI constexpr + auto operator++(int) + requires forward_iterator<_Iter> + { + move_iterator __tmp(*this); ++__current_; return __tmp; + } - template ::value && is_convertible<_Up const&, _Iter>::value + _LIBCPP_HIDE_FROM_ABI constexpr + void operator++(int) { ++__current_; } +#else + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator() : __current_() {} + + template ::value && is_convertible::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} - template ::value && - is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter&, _Up const&>::value + is_convertible::value && + is_assignable<_Iter&, const _Up&>::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator=(const move_iterator<_Up>& __u) { - __i = __u.base(); + __current_ = __u.base(); return *this; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reference operator*() const { return static_cast(*__i); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - pointer operator->() const { return __i;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator++() {++__i; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator--() {--__i; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator+ (difference_type __n) const {return move_iterator(__i + __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator+=(difference_type __n) {__i += __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator operator- (difference_type __n) const {return move_iterator(__i - __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reference operator[](difference_type __n) const { return static_cast(__i[__n]); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + _Iter base() const { return __current_; } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + reference operator*() const { return static_cast(*__current_); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + reference operator[](difference_type __n) const { return static_cast(__current_[__n]); } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } +#endif // _LIBCPP_STD_VER > 17 + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator& operator--() { --__current_; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 + move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } + +#if _LIBCPP_STD_VER > 17 + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) + requires __move_iter_comparable<_Iter, _Sent> + { + return __x.base() == __y.base(); + } + + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) + { + return __x.base() - __y.base(); + } + + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) + { + return __x.base() - __y.base(); + } + + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i) + noexcept(noexcept(ranges::iter_move(__i.__current_))) + { + return ranges::iter_move(__i.__current_); + } + + template _It2> + friend _LIBCPP_HIDE_FROM_ABI constexpr + void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y) + noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) + { + return ranges::iter_swap(__x.__current_, __y.__current_); + } +#endif // _LIBCPP_STD_VER > 17 + +private: + template friend class move_iterator; + + _Iter __current_; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() == __y.base(); } +#if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { - return __x.base() < __y.base(); + return __x.base() != __y.base(); } +#endif // _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { - return __x.base() != __y.base(); + return __x.base() < __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() > __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { - return __x.base() >= __y.base(); + return __x.base() <= __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -bool -operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { - return __x.base() <= __y.base(); + return __x.base() >= __y.base(); +} + +#if _LIBCPP_STD_VER > 17 +template _Iter2> +inline _LIBCPP_HIDE_FROM_ABI constexpr +auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> compare_three_way_result_t<_Iter1, _Iter2> +{ + return __x.base() <=> __y.base(); } +#endif // _LIBCPP_STD_VER > 17 #ifndef _LIBCPP_CXX03_LANG template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -auto -operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) --> decltype(__x.base() - __y.base()) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 +auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> decltype(__x.base() - __y.base()) { return __x.base() - __y.base(); } #else template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_HIDE_FROM_ABI typename move_iterator<_Iter1>::difference_type operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() - __y.base(); } -#endif +#endif // !_LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 17 +template +inline _LIBCPP_HIDE_FROM_ABI constexpr +move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) + requires requires { { __x.base() + __n } -> same_as<_Iter>; } +{ + return __x + __n; +} +#else template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) { return move_iterator<_Iter>(__x.base() + __n); } +#endif // _LIBCPP_STD_VER > 17 template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> make_move_iterator(_Iter __i) { - return move_iterator<_Iter>(__i); + return move_iterator<_Iter>(std::move(__i)); } _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/move_sentinel.h b/gnu/llvm/libcxx/include/__iterator/move_sentinel.h new file mode 100644 index 00000000000..0d7336a1dc2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__iterator/move_sentinel.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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___ITERATOR_MOVE_SENTINEL_H +#define _LIBCPP___ITERATOR_MOVE_SENTINEL_H + +#include <__concepts/assignable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/semiregular.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +class _LIBCPP_TEMPLATE_VIS move_sentinel +{ +public: + _LIBCPP_HIDE_FROM_ABI + move_sentinel() = default; + + _LIBCPP_HIDE_FROM_ABI constexpr + explicit move_sentinel(_Sent __s) : __last_(std::move(__s)) {} + + template + requires convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr + move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {} + + template + requires assignable_from<_Sent&, const _S2&> + _LIBCPP_HIDE_FROM_ABI constexpr + move_sentinel& operator=(const move_sentinel<_S2>& __s) + { __last_ = __s.base(); return *this; } + + constexpr _Sent base() const { return __last_; } + +private: + _Sent __last_ = _Sent(); +}; + +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel); + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H diff --git a/gnu/llvm/libcxx/include/__iterator/next.h b/gnu/llvm/libcxx/include/__iterator/next.h index 1eecaa9750b..49970ae2480 100644 --- a/gnu/llvm/libcxx/include/__iterator/next.h +++ b/gnu/llvm/libcxx/include/__iterator/next.h @@ -10,26 +10,22 @@ #ifndef _LIBCPP___ITERATOR_NEXT_H #define _LIBCPP___ITERATOR_NEXT_H +#include <__assert> #include <__config> -#include <__debug> -#include <__function_like.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> -#include +#include <__type_traits/enable_if.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, @@ -39,13 +35,14 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 return __x; } -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 + +// [range.iter.op.next] namespace ranges { -struct __next_fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __next_fn(__tag __x) noexcept : __function_like(__x) {} +namespace __next { +struct __fn { template _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { @@ -61,27 +58,27 @@ struct __next_fn final : private __function_like { } template _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, _Sp __bound) const { - ranges::advance(__x, __bound); + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, _Sp __bound_sentinel) const { + ranges::advance(__x, __bound_sentinel); return __x; } template _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound) const { - ranges::advance(__x, __n, __bound); + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound_sentinel) const { + ranges::advance(__x, __n, __bound_sentinel); return __x; } }; -inline constexpr auto next = __next_fn(__function_like::__tag()); +} // namespace __next + +inline namespace __cpo { + inline constexpr auto next = __next::__fn{}; +} // namespace __cpo } // namespace ranges -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - -#endif // _LIBCPP___ITERATOR_PRIMITIVES_H +#endif // _LIBCPP___ITERATOR_NEXT_H diff --git a/gnu/llvm/libcxx/include/__iterator/ostream_iterator.h b/gnu/llvm/libcxx/include/__iterator/ostream_iterator.h index 5b4466c8639..d16f5a26eba 100644 --- a/gnu/llvm/libcxx/include/__iterator/ostream_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/ostream_iterator.h @@ -14,15 +14,13 @@ #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> +#include #include // for forward declarations of char_traits and basic_ostream #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH @@ -55,9 +53,9 @@ public: : __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {} _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {} - _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_) + _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value) { - *__out_stream_ << __value_; + *__out_stream_ << __value; if (__delim_) *__out_stream_ << __delim_; return *this; @@ -70,6 +68,4 @@ public: _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/ostreambuf_iterator.h b/gnu/llvm/libcxx/include/__iterator/ostreambuf_iterator.h index 90309dacd42..b75f7b6e846 100644 --- a/gnu/llvm/libcxx/include/__iterator/ostreambuf_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/ostreambuf_iterator.h @@ -13,15 +13,13 @@ #include <__config> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> +#include #include // for forward declaration of basic_streambuf #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH @@ -67,7 +65,7 @@ public: template friend - _LIBCPP_HIDDEN + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator<_Ch, _Tr> __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s, const _Ch* __ob, const _Ch* __op, const _Ch* __oe, @@ -76,6 +74,4 @@ public: _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H diff --git a/gnu/llvm/libcxx/include/__iterator/permutable.h b/gnu/llvm/libcxx/include/__iterator/permutable.h new file mode 100644 index 00000000000..28d193eaae2 --- /dev/null +++ b/gnu/llvm/libcxx/include/__iterator/permutable.h @@ -0,0 +1,35 @@ +// -*- 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___ITERATOR_PERMUTABLE_H +#define _LIBCPP___ITERATOR_PERMUTABLE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template +concept permutable = + forward_iterator<_Iterator> && + indirectly_movable_storable<_Iterator, _Iterator> && + indirectly_swappable<_Iterator, _Iterator>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_PERMUTABLE_H diff --git a/gnu/llvm/libcxx/include/__iterator/prev.h b/gnu/llvm/libcxx/include/__iterator/prev.h index cb8a5713550..af1e1bab115 100644 --- a/gnu/llvm/libcxx/include/__iterator/prev.h +++ b/gnu/llvm/libcxx/include/__iterator/prev.h @@ -10,26 +10,22 @@ #ifndef _LIBCPP___ITERATOR_PREV_H #define _LIBCPP___ITERATOR_PREV_H +#include <__assert> #include <__config> -#include <__debug> -#include <__function_like.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> -#include +#include <__type_traits/enable_if.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, @@ -38,13 +34,14 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 return __x; } -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 + +// [range.iter.op.prev] namespace ranges { -struct __prev_fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __prev_fn(__tag __x) noexcept : __function_like(__x) {} +namespace __prev { +struct __fn { template _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { @@ -60,20 +57,21 @@ struct __prev_fn final : private __function_like { } template - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound) const { - ranges::advance(__x, -__n, __bound); + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound_iter) const { + ranges::advance(__x, -__n, __bound_iter); return __x; } }; -inline constexpr auto prev = __prev_fn(__function_like::__tag()); +} // namespace __prev + +inline namespace __cpo { + inline constexpr auto prev = __prev::__fn{}; +} // namespace __cpo } // namespace ranges -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_PREV_H diff --git a/gnu/llvm/libcxx/include/__iterator/projected.h b/gnu/llvm/libcxx/include/__iterator/projected.h index 7064a5eb919..19c076b2e56 100644 --- a/gnu/llvm/libcxx/include/__iterator/projected.h +++ b/gnu/llvm/libcxx/include/__iterator/projected.h @@ -6,24 +6,22 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// + #ifndef _LIBCPP___ITERATOR_PROJECTED_H #define _LIBCPP___ITERATOR_PROJECTED_H #include <__config> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> -#include +#include <__type_traits/remove_cvref.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 template _Proj> struct projected { @@ -36,10 +34,8 @@ struct incrementable_traits> { using difference_type = iter_difference_t<_It>; }; -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_PROJECTED_H diff --git a/gnu/llvm/libcxx/include/__iterator/readable_traits.h b/gnu/llvm/libcxx/include/__iterator/readable_traits.h index fbad106e4ee..8f17757c5a3 100644 --- a/gnu/llvm/libcxx/include/__iterator/readable_traits.h +++ b/gnu/llvm/libcxx/include/__iterator/readable_traits.h @@ -10,20 +10,23 @@ #ifndef _LIBCPP___ITERATOR_READABLE_TRAITS_H #define _LIBCPP___ITERATOR_READABLE_TRAITS_H +#include <__concepts/same_as.h> #include <__config> -#include -#include +#include <__type_traits/conditional.h> +#include <__type_traits/is_array.h> +#include <__type_traits/is_object.h> +#include <__type_traits/is_primary_template.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/remove_cvref.h> +#include <__type_traits/remove_extent.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RANGES) +#if _LIBCPP_STD_VER > 17 // [readable.traits] template struct __cond_value_type {}; @@ -60,14 +63,14 @@ template<__has_member_element_type _Tp> struct indirectly_readable_traits<_Tp> : __cond_value_type {}; -// Pre-emptively applies LWG3541 template<__has_member_value_type _Tp> -requires __has_member_element_type<_Tp> + requires __has_member_element_type<_Tp> struct indirectly_readable_traits<_Tp> {}; + template<__has_member_value_type _Tp> -requires __has_member_element_type<_Tp> && - same_as, - remove_cv_t> + requires __has_member_element_type<_Tp> && + same_as, + remove_cv_t> struct indirectly_readable_traits<_Tp> : __cond_value_type {}; @@ -82,10 +85,8 @@ using iter_value_t = typename conditional_t<__is_primary_template >, iterator_traits > >::value_type; -#endif // !defined(_LIBCPP_HAS_NO_RANGES) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H diff --git a/gnu/llvm/libcxx/include/__iterator/reverse_access.h b/gnu/llvm/libcxx/include/__iterator/reverse_access.h index 66cc3568c1c..79b599c47c1 100644 --- a/gnu/llvm/libcxx/include/__iterator/reverse_access.h +++ b/gnu/llvm/libcxx/include/__iterator/reverse_access.h @@ -16,94 +16,85 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_CXX03_LANG) - #if _LIBCPP_STD_VER > 11 template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) { return reverse_iterator<_Tp*>(__array + _Np); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) { return reverse_iterator<_Tp*>(__array); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin(initializer_list<_Ep> __il) { return reverse_iterator(__il.end()); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend(initializer_list<_Ep> __il) { return reverse_iterator(__il.begin()); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) { return __c.rbegin(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) { return __c.rbegin(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(_Cp& __c) -> decltype(__c.rend()) { return __c.rend(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(const _Cp& __c) -> decltype(__c.rend()) { return __c.rend(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c)) { return _VSTD::rbegin(__c); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c)) { return _VSTD::rend(__c); } -#endif - -#endif // !defined(_LIBCPP_CXX03_LANG) +#endif // _LIBCPP_STD_VER > 11 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___ITERATOR_REVERSE_ACCESS_H diff --git a/gnu/llvm/libcxx/include/__iterator/reverse_iterator.h b/gnu/llvm/libcxx/include/__iterator/reverse_iterator.h index 76424a89a19..f272e03c17a 100644 --- a/gnu/llvm/libcxx/include/__iterator/reverse_iterator.h +++ b/gnu/llvm/libcxx/include/__iterator/reverse_iterator.h @@ -10,28 +10,42 @@ #ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H +#include <__algorithm/unwrap_iter.h> +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/convertible_to.h> #include <__config> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/prev.h> +#include <__iterator/readable_traits.h> +#include <__iterator/segmented_iterator.h> #include <__memory/addressof.h> -#include +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__type_traits/conditional.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_nothrow_copy_constructible.h> +#include <__type_traits/is_pointer.h> +#include <__type_traits/is_same.h> +#include <__utility/declval.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -struct __is_stashing_iterator : false_type {}; - -template -struct __is_stashing_iterator<_Tp, typename __void_t::type> - : true_type {}; - _LIBCPP_SUPPRESS_DEPRECATED_PUSH template class _LIBCPP_TEMPLATE_VIS reverse_iterator @@ -46,159 +60,240 @@ class _LIBCPP_TEMPLATE_VIS reverse_iterator _LIBCPP_SUPPRESS_DEPRECATED_POP private: #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES - _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break + _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break #endif - static_assert(!__is_stashing_iterator<_Iter>::value, - "The specified iterator type cannot be used with reverse_iterator; " - "Using stashing iterators with reverse_iterator causes undefined behavior"); +#if _LIBCPP_STD_VER > 17 + static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>, + "reverse_iterator requires It to be a bidirectional iterator."); +#endif // _LIBCPP_STD_VER > 17 protected: _Iter current; public: - typedef _Iter iterator_type; - typedef typename iterator_traits<_Iter>::difference_type difference_type; - typedef typename iterator_traits<_Iter>::reference reference; - typedef typename iterator_traits<_Iter>::pointer pointer; - typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category> iterator_category; - typedef typename iterator_traits<_Iter>::value_type value_type; + using iterator_type = _Iter; + using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category>; + using pointer = typename iterator_traits<_Iter>::pointer; #if _LIBCPP_STD_VER > 17 - typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, - random_access_iterator_tag, - bidirectional_iterator_tag> iterator_concept; + using iterator_concept = _If, random_access_iterator_tag, bidirectional_iterator_tag>; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; +#else + using value_type = typename iterator_traits<_Iter>::value_type; + using difference_type = typename iterator_traits<_Iter>::difference_type; + using reference = typename iterator_traits<_Iter>::reference; #endif #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reverse_iterator() : __t(), current() {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator() : __t_(), current() {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {} - template ::value && is_convertible<_Up const&, _Iter>::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator(const reverse_iterator<_Up>& __u) - : __t(__u.base()), current(__u.base()) + : __t_(__u.base()), current(__u.base()) { } - template ::value && is_convertible<_Up const&, _Iter>::value && - is_assignable<_Up const&, _Iter>::value + is_assignable<_Iter&, _Up const&>::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { - __t = current = __u.base(); + __t_ = current = __u.base(); return *this; } #else - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator() : current() {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x) : current(__x) {} - template ::value && is_convertible<_Up const&, _Iter>::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator(const reverse_iterator<_Up>& __u) : current(__u.base()) { } - template ::value && is_convertible<_Up const&, _Iter>::value && - is_assignable<_Up const&, _Iter>::value + is_assignable<_Iter&, _Up const&>::value > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { current = __u.base(); return *this; } #endif - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter base() const {return current;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator*() const {_Iter __tmp = current; return *--__tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - pointer operator->() const {return _VSTD::addressof(operator*());} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY + constexpr pointer operator->() const + requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); } + { + if constexpr (is_pointer_v<_Iter>) { + return std::prev(current); + } else { + return std::prev(current).operator->(); + } + } +#else + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + pointer operator->() const { + return std::addressof(operator*()); + } +#endif // _LIBCPP_STD_VER > 17 + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator++() {--current; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator--() {++current; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reference operator[](difference_type __n) const {return *(*this + __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 + reference operator[](difference_type __n) const {return *(*this + __n);} + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI friend constexpr + iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) + noexcept(is_nothrow_copy_constructible_v<_Iter> && + noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { + auto __tmp = __i.base(); + return ranges::iter_move(--__tmp); + } + + template _Iter2> + _LIBCPP_HIDE_FROM_ABI friend constexpr + void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y) + noexcept(is_nothrow_copy_constructible_v<_Iter> && + is_nothrow_copy_constructible_v<_Iter2> && + noexcept(ranges::iter_swap(--std::declval<_Iter&>(), --std::declval<_Iter2&>()))) { + auto __xtmp = __x.base(); + auto __ytmp = __y.base(); + ranges::iter_swap(--__xtmp, --__ytmp); + } +#endif // _LIBCPP_STD_VER > 17 }; template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() == __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() == __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() > __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() > __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() != __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() != __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() < __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() < __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() <= __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() <= __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() >= __y.base() } -> convertible_to; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() >= __y.base(); } +#if _LIBCPP_STD_VER > 17 +template _Iter2> +_LIBCPP_HIDE_FROM_ABI constexpr +compare_three_way_result_t<_Iter1, _Iter2> +operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +{ + return __y.base() <=> __x.base(); +} +#endif // _LIBCPP_STD_VER > 17 + #ifndef _LIBCPP_CXX03_LANG template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 auto operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) -> decltype(__y.base() - __x.base()) @@ -216,24 +311,223 @@ operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _ #endif template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Iter> operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) { return reverse_iterator<_Iter>(__x.base() - __n); } +#if _LIBCPP_STD_VER > 17 +template + requires (!sized_sentinel_for<_Iter1, _Iter2>) +inline constexpr bool disable_sized_sentinel_for, reverse_iterator<_Iter2>> = true; +#endif // _LIBCPP_STD_VER > 17 + #if _LIBCPP_STD_VER > 11 template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) { return reverse_iterator<_Iter>(__i); } #endif -_LIBCPP_END_NAMESPACE_STD +#if _LIBCPP_STD_VER <= 17 +template +using __unconstrained_reverse_iterator = reverse_iterator<_Iter>; +#else + +// __unconstrained_reverse_iterator allows us to use reverse iterators in the implementation of algorithms by working +// around a language issue in C++20. +// In C++20, when a reverse iterator wraps certain C++20-hostile iterators, calling comparison operators on it will +// result in a compilation error. However, calling comparison operators on the pristine hostile iterator is not +// an error. Thus, we cannot use reverse_iterators in the implementation of an algorithm that accepts a +// C++20-hostile iterator. This class is an internal workaround -- it is a copy of reverse_iterator with +// tweaks to make it support hostile iterators. +// +// A C++20-hostile iterator is one that defines a comparison operator where one of the arguments is an exact match +// and the other requires an implicit conversion, for example: +// friend bool operator==(const BaseIter&, const DerivedIter&); +// +// C++20 rules for rewriting equality operators create another overload of this function with parameters reversed: +// friend bool operator==(const DerivedIter&, const BaseIter&); +// +// This creates an ambiguity in overload resolution. +// +// Clang treats this ambiguity differently in different contexts. When operator== is actually called in the function +// body, the code is accepted with a warning. When a concept requires operator== to be a valid expression, however, +// it evaluates to false. Thus, the implementation of reverse_iterator::operator== can actually call operator== on its +// base iterators, but the constraints on reverse_iterator::operator== prevent it from being considered during overload +// resolution. This class simply removes the problematic constraints from comparison functions. +template +class __unconstrained_reverse_iterator { + _Iter __iter_; + +public: + static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>); + + using iterator_type = _Iter; + using iterator_category = + _If<__is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>; + using pointer = __iterator_pointer_type<_Iter>; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator() = default; + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator(const __unconstrained_reverse_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr explicit __unconstrained_reverse_iterator(_Iter __iter) : __iter_(__iter) {} + + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() const { return __iter_; } + _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { + auto __tmp = __iter_; + return *--__tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { + if constexpr (is_pointer_v<_Iter>) { + return std::prev(__iter_); + } else { + return std::prev(__iter_).operator->(); + } + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr + iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i) + noexcept(is_nothrow_copy_constructible_v<_Iter> && + noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { + auto __tmp = __i.base(); + return ranges::iter_move(--__tmp); + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator++() { + --__iter_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator++(int) { + auto __tmp = *this; + --__iter_; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator--() { + ++__iter_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator--(int) { + auto __tmp = *this; + ++__iter_; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator+=(difference_type __n) { + __iter_ -= __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator-=(difference_type __n) { + __iter_ += __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator+(difference_type __n) const { + return __unconstrained_reverse_iterator(__iter_ - __n); + } + + _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator-(difference_type __n) const { + return __unconstrained_reverse_iterator(__iter_ + __n); + } + + _LIBCPP_HIDE_FROM_ABI constexpr difference_type operator-(const __unconstrained_reverse_iterator& __other) const { + return __other.__iter_ - __iter_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const { return *(*this + __n); } + + // Deliberately unconstrained unlike the comparison functions in `reverse_iterator` -- see the class comment for the + // rationale. + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() == __rhs.base(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator!=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() != __rhs.base(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator<(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() > __rhs.base(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator>(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() < __rhs.base(); + } -_LIBCPP_POP_MACROS + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator<=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() >= __rhs.base(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator>=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { + return __lhs.base() <= __rhs.base(); + } +}; + +#endif // _LIBCPP_STD_VER <= 17 + +template