Merge to upstream r348296.

Test: ./run_tests.py --bitness 32
Test: ./run_tests.py --bitness 64
Test: ./run_tests.py --bitness 64 --host
Bug: None
Change-Id: I79cdb1e5f146e42e383426c8e12a231b53a9459a
This commit is contained in:
Dan Albert
2019-01-08 15:37:39 -08:00
1102 changed files with 53262 additions and 12185 deletions

View File

@@ -11,6 +11,10 @@ endif()
if(POLICY CMP0022)
cmake_policy(SET CMP0022 NEW) # Required when interacting with LLVM and Clang
endif()
if(POLICY CMP0068)
cmake_policy(SET CMP0068 NEW)
set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON)
endif()
# Add path for custom modules
set(CMAKE_MODULE_PATH
@@ -23,7 +27,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
project(libcxx CXX C)
set(PACKAGE_NAME libcxx)
set(PACKAGE_VERSION 7.0.0svn)
set(PACKAGE_VERSION 8.0.0svn)
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org")
@@ -46,9 +50,14 @@ MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
"${PROJECT_NAME} requires an out of source build. Please create a separate
build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there."
)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
message(STATUS "Configuring for clang-cl")
set(LIBCXX_TARGETING_CLANG_CL ON)
endif()
if (MSVC)
set(LIBCXX_TARGETING_MSVC ON)
message(STATUS "Configuring for MSVC")
else()
set(LIBCXX_TARGETING_MSVC OFF)
endif()
@@ -68,12 +77,17 @@ set(ENABLE_FILESYSTEM_DEFAULT ${LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY})
if (WIN32)
set(ENABLE_FILESYSTEM_DEFAULT OFF)
endif()
option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of libc++experimental.a"
option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of libc++fs.a"
${ENABLE_FILESYSTEM_DEFAULT})
option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
# Benchmark options -----------------------------------------------------------
option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependancies" ON)
option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependencies" ON)
set(LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT --benchmark_min_time=0.01)
set(LIBCXX_BENCHMARK_TEST_ARGS "${LIBCXX_BENCHMARK_TEST_ARGS_DEFAULT}" CACHE STRING
"Arguments to pass when running the benchmarks using check-cxx-benchmarks")
set(LIBCXX_BENCHMARK_NATIVE_STDLIB "" CACHE STRING
"Build the benchmarks against the specified native STL.
The value must be one of libc++/libstdc++")
@@ -93,19 +107,26 @@ set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING
"Define suffix of library directory name (32/64)")
option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON)
option(LIBCXX_INSTALL_LIBRARY "Install the libc++ library." ON)
cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY
"Install the static libc++ library." ON
"LIBCXX_ENABLE_STATIC;LIBCXX_INSTALL_LIBRARY" OFF)
cmake_dependent_option(LIBCXX_INSTALL_SHARED_LIBRARY
"Install the shared libc++ library." ON
"LIBCXX_ENABLE_SHARED;LIBCXX_INSTALL_LIBRARY" OFF)
option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON)
cmake_dependent_option(LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY
"Install libc++experimental.a" ON
"LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY;LIBCXX_INSTALL_LIBRARY" OFF)
if (FUCHSIA)
set(DEFAULT_ABI_VERSION 2)
else()
set(DEFAULT_ABI_VERSION 1)
endif()
set(LIBCXX_ABI_VERSION ${DEFAULT_ABI_VERSION} CACHE STRING "ABI version of libc++.")
cmake_dependent_option(LIBCXX_INSTALL_FILESYSTEM_LIBRARY
"Install libc++fs.a" ON
"LIBCXX_ENABLE_FILESYSTEM;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_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.")
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_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
@@ -155,13 +176,21 @@ endif()
# cannot be used with LIBCXX_ENABLE_ABI_LINKER_SCRIPT.
option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "Statically link the ABI library" 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)
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)
# 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".
set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE OFF)
if (LLVM_HAVE_LINK_VERSION_SCRIPT AND NOT LIBCXX_ENABLE_STATIC_ABI_LIBRARY
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 PYTHONINTERP_FOUND
@@ -356,7 +385,7 @@ if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
endif()
endif()
if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
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_ENABLE_ABI_LINKER_SCRIPT")
@@ -379,19 +408,29 @@ set(LIBCXX_COMPILER ${CMAKE_CXX_COMPILER})
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 (LLVM_LIBRARY_OUTPUT_INTDIR)
string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
${PACKAGE_VERSION})
if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
set(DEFAULT_INSTALL_PREFIX lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/${LLVM_DEFAULT_TARGET_TRIPLE}/)
set(DEFAULT_INSTALL_HEADER_PREFIX lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/)
set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}/${LLVM_DEFAULT_TARGET_TRIPLE}/lib${LIBCXX_LIBDIR_SUFFIX})
set(LIBCXX_HEADER_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION})
elseif(LLVM_LIBRARY_OUTPUT_INTDIR)
set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
set(LIBCXX_HEADER_DIR ${LLVM_BINARY_DIR})
else()
set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
endif()
file(MAKE_DIRECTORY "${LIBCXX_BINARY_INCLUDE_DIR}")
set(LIBCXX_INSTALL_PREFIX "" CACHE STRING
set(LIBCXX_INSTALL_PREFIX ${DEFAULT_INSTALL_PREFIX} CACHE STRING
"Define libc++ destination prefix.")
if (NOT LIBCXX_INSTALL_PREFIX MATCHES "^$|.*/")
message(FATAL_ERROR "LIBCXX_INSTALL_PREFIX has to end with \"/\".")
endif()
set(LIBCXX_INSTALL_HEADER_PREFIX ${DEFAULT_INSTALL_HEADER_PREFIX} CACHE STRING
"Define libc++ header destination prefix.")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR})
@@ -470,14 +509,16 @@ remove_flags(-Wno-pedantic -pedantic-errors -pedantic)
# Required flags ==============================================================
set(LIBCXX_STANDARD_VER c++11 CACHE INTERNAL "internal option to change build dialect")
if (LIBCXX_HAS_MUSL_LIBC)
if (LIBCXX_HAS_MUSL_LIBC OR LIBCXX_TARGETING_CLANG_CL)
# musl's pthread implementations uses volatile types in their structs which is
# not a constexpr in C++11 but is in C++14, so we use C++14 with musl.
set(LIBCXX_STANDARD_VER c++14 CACHE INTERNAL "internal option to change build dialect")
endif()
add_compile_flags_if_supported(-std=${LIBCXX_STANDARD_VER})
add_compile_flags_if_supported("/std:${LIBCXX_STANDARD_VER}")
mangle_name("LIBCXX_SUPPORTS_STD_EQ_${LIBCXX_STANDARD_VER}_FLAG" SUPPORTS_DIALECT_NAME)
if(NOT ${SUPPORTS_DIALECT_NAME})
mangle_name("LIBCXX_SUPPORTS_STD_COLON_${LIBCXX_STANDARD_VER}_FLAG" SUPPORTS_DIALECT_NAME_MSVC)
if(NOT ${SUPPORTS_DIALECT_NAME} AND NOT ${SUPPORTS_DIALECT_NAME_MSVC})
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" AND NOT "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
message(FATAL_ERROR "C++11 or greater is required but the compiler does not support ${LIBCXX_STANDARD_VER}")
endif()
@@ -512,11 +553,29 @@ add_definitions(-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
add_compile_flags_if_supported(
-Wall -Wextra -W -Wwrite-strings
-Wno-unused-parameter -Wno-long-long
-Werror=return-type)
-Werror=return-type -Wextra-semi)
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
add_compile_flags_if_supported(
-Wno-user-defined-literals
-Wno-covered-switch-default)
if (LIBCXX_TARGETING_CLANG_CL)
add_compile_flags_if_supported(
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-c++11-compat
-Wno-undef
-Wno-reserved-id-macro
-Wno-gnu-include-next
-Wno-gcc-compat # For ignoring "'diagnose_if' is a clang extension" warnings
-Wno-zero-as-null-pointer-constant # FIXME: Remove this and fix all occurrences.
-Wno-deprecated-dynamic-exception-spec # For auto_ptr
-Wno-sign-conversion
-Wno-old-style-cast
-Wno-deprecated # FIXME: Remove this and fix all occurrences.
-Wno-shift-sign-overflow # FIXME: Why do we need this with clang-cl but not clang?
-Wno-double-promotion # FIXME: remove me
)
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
add_compile_flags_if_supported(
-Wno-literal-suffix
@@ -589,47 +648,67 @@ endif()
# Sanitizer flags =============================================================
function(get_sanitizer_flags OUT_VAR USE_SANITIZER)
set(SANITIZER_FLAGS)
set(USE_SANITIZER "${USE_SANITIZER}")
# NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC.
# But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do.
if (USE_SANITIZER AND NOT MSVC)
append_flags_if_supported(SANITIZER_FLAGS "-fno-omit-frame-pointer")
append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only")
if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND
NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
append_flags_if_supported(SANITIZER_FLAGS "-gline-tables-only")
endif()
if (USE_SANITIZER STREQUAL "Address")
append_flags(SANITIZER_FLAGS "-fsanitize=address")
elseif (USE_SANITIZER MATCHES "Memory(WithOrigins)?")
append_flags(SANITIZER_FLAGS -fsanitize=memory)
if (USE_SANITIZER STREQUAL "MemoryWithOrigins")
append_flags(SANITIZER_FLAGS "-fsanitize-memory-track-origins")
endif()
elseif (USE_SANITIZER STREQUAL "Undefined")
append_flags(SANITIZER_FLAGS "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
elseif (USE_SANITIZER STREQUAL "Thread")
append_flags(SANITIZER_FLAGS -fsanitize=thread)
else()
message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${USE_SANITIZER}")
endif()
elseif(USE_SANITIZER AND MSVC)
message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.")
endif()
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")
# NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC.
# But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do.
if (LLVM_USE_SANITIZER AND NOT MSVC)
add_flags_if_supported("-fno-omit-frame-pointer")
add_flags_if_supported("-gline-tables-only")
if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND
NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
add_flags_if_supported("-gline-tables-only")
endif()
if (LLVM_USE_SANITIZER STREQUAL "Address")
add_flags("-fsanitize=address")
elseif (LLVM_USE_SANITIZER MATCHES "Memory(WithOrigins)?")
add_flags(-fsanitize=memory)
if (LLVM_USE_SANITIZER STREQUAL "MemoryWithOrigins")
add_flags("-fsanitize-memory-track-origins")
endif()
elseif (LLVM_USE_SANITIZER STREQUAL "Undefined")
add_flags("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
elseif (LLVM_USE_SANITIZER STREQUAL "Thread")
add_flags(-fsanitize=thread)
else()
message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}")
endif()
elseif(LLVM_USE_SANITIZER AND MSVC)
message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.")
endif()
endif()
get_sanitizer_flags(SANITIZER_FLAGS "${LLVM_USE_SANITIZER}")
if (LIBCXX_STANDALONE_BUILD AND SANITIZER_FLAGS)
add_flags(${SANITIZER_FLAGS})
endif()
# Configuration file flags =====================================================
if (NOT LIBCXX_ABI_VERSION EQUAL DEFAULT_ABI_VERSION)
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(WARNING "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_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)
@@ -692,6 +771,18 @@ include_directories(include)
add_subdirectory(include)
add_subdirectory(lib)
set(LIBCXX_TEST_DEPS "")
if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
list(APPEND LIBCXX_TEST_DEPS cxx_experimental)
endif()
if (LIBCXX_ENABLE_FILESYSTEM)
list(APPEND LIBCXX_TEST_DEPS cxx_filesystem)
endif()
if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
list(APPEND LIBCXX_TEST_DEPS cxx_external_threads)
endif()
if (LIBCXX_INCLUDE_BENCHMARKS)
add_subdirectory(benchmarks)

View File

@@ -9,7 +9,7 @@ cd C:\projects\deps
:: Setup Compiler
::###########################################################################
if NOT EXIST llvm-installer.exe (
appveyor DownloadFile http://prereleases.llvm.org/win-snapshots/LLVM-7.0.0-r325576-win32.exe -FileName llvm-installer.exe
appveyor DownloadFile https://prereleases.llvm.org/win-snapshots/LLVM-8.0.0-r345380-win32.exe -FileName llvm-installer.exe
)
if "%CLANG_VERSION%"=="ToT" (
START /WAIT llvm-installer.exe /S /D=C:\"Program Files\LLVM"

View File

@@ -18,14 +18,6 @@ environment:
GENERATOR: Ninja
MAKE_PROGRAM: ninja
APPVEYOR_SAVE_CACHE_ON_ERROR: true
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_OPTIONS: -DCMAKE_C_COMPILER=clang-cl.exe -DCMAKE_CXX_COMPILER=clang-cl.exe
CLANG_VERSION: 4
MSVC_SETUP_PATH: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
MSVC_SETUP_ARG: x86_amd64
GENERATOR: Ninja
MAKE_PROGRAM: ninja
APPVEYOR_SAVE_CACHE_ON_ERROR: true
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
MINGW_PATH: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin
GENERATOR: MinGW Makefiles

View File

@@ -11,17 +11,21 @@ set(BENCHMARK_LIBCXX_COMPILE_FLAGS
-isystem ${LIBCXX_SOURCE_DIR}/include
-L${LIBCXX_LIBRARY_DIR}
-Wl,-rpath,${LIBCXX_LIBRARY_DIR}
${SANITIZER_FLAGS}
)
if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH)
list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS
-L${LIBCXX_CXX_ABI_LIBRARY_PATH}
-Wl,-rpath,${LIBCXX_CXX_ABI_LIBRARY_PATH})
endif()
if (LIBCXX_NEEDS_SITE_CONFIG)
list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS -include "${LIBCXX_BINARY_DIR}/__config_site")
endif()
split_list(BENCHMARK_LIBCXX_COMPILE_FLAGS)
ExternalProject_Add(google-benchmark-libcxx
EXCLUDE_FROM_ALL ON
DEPENDS cxx
DEPENDS cxx cxx-headers
PREFIX benchmark-libcxx
SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark
INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx
@@ -67,8 +71,19 @@ add_custom_target(cxx-benchmarks)
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)
check_flag_supported("-std=c++17")
mangle_name("LIBCXX_SUPPORTS_STD_EQ_c++17_FLAG" BENCHMARK_SUPPORTS_STD_CXX17_FLAG)
if (${BENCHMARK_SUPPORTS_STD_CXX17_FLAG})
set(BENCHMARK_DIALECT_FLAG "-std=c++17")
else()
# If the compiler doesn't support -std=c++17, attempt to fall back to -std=c++1z while still
# requiring C++17 language features.
set(BENCHMARK_DIALECT_FLAG "-std=c++1z")
endif()
set(BENCHMARK_TEST_COMPILE_FLAGS
-std=c++17 -O2
${BENCHMARK_DIALECT_FLAG} -O2
-I${BENCHMARK_LIBCXX_INSTALL}/include
-I${LIBCXX_SOURCE_DIR}/test/support
)
@@ -76,11 +91,18 @@ set(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS
-nostdinc++
-isystem ${LIBCXX_SOURCE_DIR}/include
${BENCHMARK_TEST_COMPILE_FLAGS}
${SANITIZER_FLAGS}
-Wno-user-defined-literals
)
if (LIBCXX_NEEDS_SITE_CONFIG)
list(APPEND BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS
-include "${LIBCXX_BINARY_DIR}/__config_site")
endif()
set(BENCHMARK_TEST_LIBCXX_LINK_FLAGS
-nodefaultlibs
-L${BENCHMARK_LIBCXX_INSTALL}/lib/
${SANITIZER_FLAGS}
)
set(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS
${BENCHMARK_NATIVE_TARGET_FLAGS}
@@ -95,10 +117,25 @@ 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)
macro(add_benchmark_test name source_file)
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()
endif()
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})
add_dependencies(${libcxx_target} cxx google-benchmark-libcxx)
add_dependencies(${libcxx_target} cxx cxx-headers google-benchmark-libcxx)
add_dependencies(cxx-benchmarks ${libcxx_target})
if (LIBCXX_ENABLE_SHARED)
target_link_libraries(${libcxx_target} cxx_shared)
@@ -108,7 +145,13 @@ macro(add_benchmark_test name source_file)
if (TARGET cxx_experimental)
target_link_libraries(${libcxx_target} cxx_experimental)
endif()
if (TARGET cxx_filesystem)
target_link_libraries(${libcxx_target} cxx_filesystem)
endif()
target_link_libraries(${libcxx_target} -lbenchmark)
if (LLVM_USE_SANITIZER)
target_link_libraries(${libcxx_target} -ldl)
endif()
set_target_properties(${libcxx_target}
PROPERTIES
OUTPUT_NAME "${name}.libcxx.out"
@@ -116,15 +159,19 @@ macro(add_benchmark_test name source_file)
COMPILE_FLAGS "${BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS}"
LINK_FLAGS "${BENCHMARK_TEST_LIBCXX_LINK_FLAGS}")
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})
add_dependencies(${native_target} google-benchmark-native
google-benchmark-libcxx)
target_link_libraries(${native_target} -lbenchmark)
if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++")
target_link_libraries(${native_target} -lstdc++fs)
target_link_libraries(${native_target} ${LIBSTDCXX_FILESYSTEM_LIB})
elseif (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++")
target_link_libraries(${native_target} -lc++experimental)
target_link_libraries(${native_target} -lc++fs -lc++experimental)
endif()
if (LIBCXX_HAS_PTHREAD_LIB)
target_link_libraries(${native_target} -pthread)
@@ -138,7 +185,7 @@ macro(add_benchmark_test name source_file)
COMPILE_FLAGS "${BENCHMARK_TEST_NATIVE_COMPILE_FLAGS}"
LINK_FLAGS "${BENCHMARK_TEST_NATIVE_LINK_FLAGS}")
endif()
endmacro()
endfunction()
#==============================================================================
@@ -155,3 +202,23 @@ foreach(test_path ${BENCHMARK_TESTS})
endif()
add_benchmark_test(${test_name} ${test_file})
endforeach()
if (LIBCXX_INCLUDE_TESTS)
include(AddLLVM)
if (NOT DEFINED LIBCXX_TEST_DEPS)
message(FATAL_ERROR "Expected LIBCXX_TEST_DEPS to be defined")
endif()
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py)
set(BENCHMARK_LIT_ARGS "--show-all --show-xfail --show-unsupported ${LIT_ARGS_DEFAULT}")
add_lit_target(check-cxx-benchmarks
"Running libcxx benchmarks tests"
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS cxx-benchmarks ${LIBCXX_TEST_DEPS}
ARGS ${BENCHMARK_LIT_ARGS})
endif()

View File

@@ -0,0 +1,135 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <string>
#include <tuple>
#include <type_traits>
#include <vector>
#include "benchmark/benchmark.h"
#include "test_macros.h"
namespace internal {
template <class D, class E, size_t I>
struct EnumValue : std::integral_constant<E, static_cast<E>(I)> {
static std::string name() { return std::string("_") + D::Names[I]; }
};
template <class D, class E, size_t ...Idxs>
constexpr auto makeEnumValueTuple(std::index_sequence<Idxs...>) {
return std::make_tuple(EnumValue<D, E, Idxs>{}...);
}
template <class B>
static auto skip(const B& Bench, int) -> decltype(Bench.skip()) {
return Bench.skip();
}
template <class B>
static auto skip(const B& Bench, char) {
return false;
}
template <class B, class Args, size_t... Is>
void makeBenchmarkFromValuesImpl(const Args& A, std::index_sequence<Is...>) {
for (auto& V : A) {
B Bench{std::get<Is>(V)...};
if (!internal::skip(Bench, 0)) {
benchmark::RegisterBenchmark(Bench.name().c_str(),
[=](benchmark::State& S) { Bench.run(S); });
}
}
}
template <class B, class... Args>
void makeBenchmarkFromValues(const std::vector<std::tuple<Args...> >& A) {
makeBenchmarkFromValuesImpl<B>(A, std::index_sequence_for<Args...>());
}
template <template <class...> class B, class Args, class... U>
void makeBenchmarkImpl(const Args& A, std::tuple<U...> t) {
makeBenchmarkFromValues<B<U...> >(A);
}
template <template <class...> class B, class Args, class... U,
class... T, class... Tuples>
void makeBenchmarkImpl(const Args& A, std::tuple<U...>, std::tuple<T...>,
Tuples... rest) {
(internal::makeBenchmarkImpl<B>(A, std::tuple<U..., T>(), rest...), ...);
}
template <class R, class T>
void allValueCombinations(R& Result, const T& Final) {
return Result.push_back(Final);
}
template <class R, class T, class V, class... Vs>
void allValueCombinations(R& Result, const T& Prev, const V& Value,
const Vs&... Values) {
for (const auto& E : Value) {
allValueCombinations(Result, std::tuple_cat(Prev, std::make_tuple(E)),
Values...);
}
}
} // namespace internal
// CRTP class that enables using enum types as a dimension for
// makeCartesianProductBenchmark below.
// The type passed to `B` will be a std::integral_constant<E, e>, with the
// additional static function `name()` that returns the stringified name of the
// label.
//
// Eg:
// enum class MyEnum { A, B };
// struct AllMyEnum : EnumValuesAsTuple<AllMyEnum, MyEnum, 2> {
// static constexpr absl::string_view Names[] = {"A", "B"};
// };
template <class Derived, class EnumType, size_t NumLabels>
using EnumValuesAsTuple =
decltype(internal::makeEnumValueTuple<Derived, EnumType>(
std::make_index_sequence<NumLabels>{}));
// Instantiates B<T0, T1, ..., TN> where <Ti...> are the combinations in the
// cartesian product of `Tuples...`, and pass (arg0, ..., argN) as constructor
// arguments where `(argi...)` are the combination in the cartesian product of
// the runtime values of `A...`.
// B<T...> requires:
// - std::string name(args...): The name of the benchmark.
// - void run(benchmark::State&, args...): The body of the benchmark.
// It can also optionally provide:
// - bool skip(args...): When `true`, skips the combination. Default is false.
//
// Returns int to facilitate registration. The return value is unspecified.
template <template <class...> class B, class... Tuples, class... Args>
int makeCartesianProductBenchmark(const Args&... A) {
std::vector<std::tuple<typename Args::value_type...> > V;
internal::allValueCombinations(V, std::tuple<>(), A...);
internal::makeBenchmarkImpl<B>(V, std::tuple<>(), Tuples()...);
return 0;
}
template <class B, class... Args>
int makeCartesianProductBenchmark(const Args&... A) {
std::vector<std::tuple<typename Args::value_type...> > V;
internal::allValueCombinations(V, std::tuple<>(), A...);
internal::makeBenchmarkFromValues<B>(V);
return 0;
}
// When `opaque` is true, this function hides the runtime state of `value` from
// the optimizer.
// It returns `value`.
template <class T>
TEST_ALWAYS_INLINE inline T maybeOpaque(T value, bool opaque) {
if (opaque) benchmark::DoNotOptimize(value);
return value;
}

View File

@@ -1,62 +1,270 @@
#include <unordered_set>
#include <vector>
#include <algorithm>
#include <cstdint>
#include <map>
#include <random>
#include <string>
#include <utility>
#include <vector>
#include "benchmark/benchmark.h"
#include "CartesianBenchmarks.hpp"
#include "GenerateInput.hpp"
#include "benchmark/benchmark.h"
#include "test_macros.h"
constexpr std::size_t TestNumInputs = 1024;
namespace {
template <class GenInputs>
void BM_Sort(benchmark::State& st, GenInputs gen) {
using ValueType = typename decltype(gen(0))::value_type;
const auto in = gen(st.range(0));
std::vector<ValueType> inputs[5];
auto reset_inputs = [&]() {
for (auto& C : inputs) {
C = in;
benchmark::DoNotOptimize(C.data());
}
};
reset_inputs();
while (st.KeepRunning()) {
for (auto& I : inputs) {
std::sort(I.data(), I.data() + I.size());
benchmark::DoNotOptimize(I.data());
}
st.PauseTiming();
reset_inputs();
benchmark::ClobberMemory();
st.ResumeTiming();
}
enum class ValueType { Uint32, String };
struct AllValueTypes : EnumValuesAsTuple<AllValueTypes, ValueType, 2> {
static constexpr const char* Names[] = {"uint32", "string"};
};
template <class V>
using Value =
std::conditional_t<V() == ValueType::Uint32, uint32_t, std::string>;
enum class Order {
Random,
Ascending,
Descending,
SingleElement,
PipeOrgan,
Heap
};
struct AllOrders : EnumValuesAsTuple<AllOrders, Order, 6> {
static constexpr const char* Names[] = {"Random", "Ascending",
"Descending", "SingleElement",
"PipeOrgan", "Heap"};
};
void fillValues(std::vector<uint32_t>& V, size_t N, Order O) {
if (O == Order::SingleElement) {
V.resize(N, 0);
} else {
while (V.size() < N)
V.push_back(V.size());
}
}
BENCHMARK_CAPTURE(BM_Sort, random_uint32,
getRandomIntegerInputs<uint32_t>)->Arg(TestNumInputs);
void fillValues(std::vector<std::string>& V, size_t N, Order O) {
BENCHMARK_CAPTURE(BM_Sort, sorted_ascending_uint32,
getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
if (O == Order::SingleElement) {
V.resize(N, getRandomString(1024));
} else {
while (V.size() < N)
V.push_back(getRandomString(1024));
}
}
BENCHMARK_CAPTURE(BM_Sort, sorted_descending_uint32,
getReverseSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
template <class T>
void sortValues(T& V, Order O) {
assert(std::is_sorted(V.begin(), V.end()));
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;
}
}
BENCHMARK_CAPTURE(BM_Sort, single_element_uint32,
getDuplicateIntegerInputs<uint32_t>)->Arg(TestNumInputs);
template <class ValueType>
std::vector<std::vector<Value<ValueType> > > makeOrderedValues(size_t N,
Order O) {
// Let's make sure that all random sequences of the same size are the same.
// That way we can compare the different algorithms with the same input.
static std::map<std::pair<size_t, Order>, std::vector<Value<ValueType> > >
Cached;
BENCHMARK_CAPTURE(BM_Sort, pipe_organ_uint32,
getPipeOrganIntegerInputs<uint32_t>)->Arg(TestNumInputs);
auto& Values = Cached[{N, O}];
if (Values.empty()) {
fillValues(Values, N, O);
sortValues(Values, O);
};
const size_t NumCopies = std::max(size_t{1}, 1000 / N);
return { NumCopies, Values };
}
BENCHMARK_CAPTURE(BM_Sort, random_strings,
getRandomStringInputs)->Arg(TestNumInputs);
template <class T, class U>
TEST_ALWAYS_INLINE void resetCopies(benchmark::State& state, T& Copies,
U& Orig) {
state.PauseTiming();
for (auto& Copy : Copies)
Copy = Orig;
state.ResumeTiming();
}
BENCHMARK_CAPTURE(BM_Sort, sorted_ascending_strings,
getSortedStringInputs)->Arg(TestNumInputs);
template <class ValueType, class F>
void runOpOnCopies(benchmark::State& state, size_t Quantity, Order O,
bool CountElements, F f) {
auto Copies = makeOrderedValues<ValueType>(Quantity, O);
const auto Orig = Copies[0];
BENCHMARK_CAPTURE(BM_Sort, sorted_descending_strings,
getReverseSortedStringInputs)->Arg(TestNumInputs);
const size_t Batch = CountElements ? Copies.size() * Quantity : Copies.size();
while (state.KeepRunningBatch(Batch)) {
for (auto& Copy : Copies) {
f(Copy);
benchmark::DoNotOptimize(Copy);
}
resetCopies(state, Copies, Orig);
}
}
BENCHMARK_CAPTURE(BM_Sort, single_element_strings,
getDuplicateStringInputs)->Arg(TestNumInputs);
template <class ValueType, class Order>
struct Sort {
size_t Quantity;
void run(benchmark::State& state) const {
runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
std::sort(Copy.begin(), Copy.end());
});
}
BENCHMARK_MAIN();
bool skip() const { return Order() == ::Order::Heap; }
std::string name() const {
return "BM_Sort" + ValueType::name() + Order::name() + "_" +
std::to_string(Quantity);
};
};
template <class ValueType, class Order>
struct StableSort {
size_t Quantity;
void run(benchmark::State& state) const {
runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](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);
};
};
template <class ValueType, class Order>
struct MakeHeap {
size_t Quantity;
void run(benchmark::State& state) const {
runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](auto& Copy) {
std::make_heap(Copy.begin(), Copy.end());
});
}
std::string name() const {
return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" +
std::to_string(Quantity);
};
};
template <class ValueType>
struct SortHeap {
size_t Quantity;
void run(benchmark::State& state) const {
runOpOnCopies<ValueType>(
state, Quantity, Order::Heap, false,
[](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); });
}
std::string name() const {
return "BM_SortHeap" + ValueType::name() + "_" + std::to_string(Quantity);
};
};
template <class ValueType, class Order>
struct MakeThenSortHeap {
size_t Quantity;
void run(benchmark::State& state) const {
runOpOnCopies<ValueType>(state, Quantity, Order(), false, [](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);
};
};
template <class ValueType, class Order>
struct PushHeap {
size_t Quantity;
void run(benchmark::State& state) const {
runOpOnCopies<ValueType>(state, Quantity, Order(), true, [](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);
};
};
template <class ValueType>
struct PopHeap {
size_t Quantity;
void run(benchmark::State& state) const {
runOpOnCopies<ValueType>(state, Quantity, Order(), true, [](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;
const std::vector<size_t> Quantities = {1 << 0, 1 << 2, 1 << 4, 1 << 6,
1 << 8, 1 << 10, 1 << 14, 1 << 18};
makeCartesianProductBenchmark<Sort, AllValueTypes, AllOrders>(Quantities);
makeCartesianProductBenchmark<StableSort, AllValueTypes, AllOrders>(
Quantities);
makeCartesianProductBenchmark<MakeHeap, AllValueTypes, AllOrders>(Quantities);
makeCartesianProductBenchmark<SortHeap, AllValueTypes>(Quantities);
makeCartesianProductBenchmark<MakeThenSortHeap, AllValueTypes, AllOrders>(
Quantities);
makeCartesianProductBenchmark<PushHeap, AllValueTypes, AllOrders>(Quantities);
makeCartesianProductBenchmark<PopHeap, AllValueTypes>(Quantities);
benchmark::RunSpecifiedBenchmarks();
}

View File

@@ -0,0 +1,232 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include "CartesianBenchmarks.hpp"
#include "benchmark/benchmark.h"
#include "test_macros.h"
namespace {
enum class FunctionType {
Null,
FunctionPointer,
MemberFunctionPointer,
MemberPointer,
SmallTrivialFunctor,
SmallNonTrivialFunctor,
LargeTrivialFunctor,
LargeNonTrivialFunctor
};
struct AllFunctionTypes : EnumValuesAsTuple<AllFunctionTypes, FunctionType, 8> {
static constexpr const char* Names[] = {"Null",
"FuncPtr",
"MemFuncPtr",
"MemPtr",
"SmallTrivialFunctor",
"SmallNonTrivialFunctor",
"LargeTrivialFunctor",
"LargeNonTrivialFunctor"};
};
enum class Opacity { kOpaque, kTransparent };
struct AllOpacity : EnumValuesAsTuple<AllOpacity, Opacity, 2> {
static constexpr const char* Names[] = {"Opaque", "Transparent"};
};
struct S {
int function() const { return 0; }
int field = 0;
};
int FunctionWithS(const S*) { return 0; }
struct SmallTrivialFunctor {
int operator()(const S*) const { return 0; }
};
struct SmallNonTrivialFunctor {
SmallNonTrivialFunctor() {}
SmallNonTrivialFunctor(const SmallNonTrivialFunctor&) {}
~SmallNonTrivialFunctor() {}
int operator()(const S*) const { return 0; }
};
struct LargeTrivialFunctor {
LargeTrivialFunctor() {
// Do not spend time initializing the padding.
}
int padding[16];
int operator()(const S*) const { return 0; }
};
struct LargeNonTrivialFunctor {
int padding[16];
LargeNonTrivialFunctor() {
// Do not spend time initializing the padding.
}
LargeNonTrivialFunctor(const LargeNonTrivialFunctor&) {}
~LargeNonTrivialFunctor() {}
int operator()(const S*) const { return 0; }
};
using Function = std::function<int(const S*)>;
TEST_ALWAYS_INLINE
inline Function MakeFunction(FunctionType type, bool opaque = false) {
switch (type) {
case FunctionType::Null:
return nullptr;
case FunctionType::FunctionPointer:
return maybeOpaque(FunctionWithS, opaque);
case FunctionType::MemberFunctionPointer:
return maybeOpaque(&S::function, opaque);
case FunctionType::MemberPointer:
return maybeOpaque(&S::field, opaque);
case FunctionType::SmallTrivialFunctor:
return maybeOpaque(SmallTrivialFunctor{}, opaque);
case FunctionType::SmallNonTrivialFunctor:
return maybeOpaque(SmallNonTrivialFunctor{}, opaque);
case FunctionType::LargeTrivialFunctor:
return maybeOpaque(LargeTrivialFunctor{}, opaque);
case FunctionType::LargeNonTrivialFunctor:
return maybeOpaque(LargeNonTrivialFunctor{}, opaque);
}
}
template <class Opacity, class FunctionType>
struct ConstructAndDestroy {
static void run(benchmark::State& state) {
for (auto _ : state) {
if (Opacity() == ::Opacity::kOpaque) {
benchmark::DoNotOptimize(MakeFunction(FunctionType(), true));
} else {
MakeFunction(FunctionType());
}
}
}
static std::string name() {
return "BM_ConstructAndDestroy" + FunctionType::name() + Opacity::name();
}
};
template <class FunctionType>
struct Copy {
static void run(benchmark::State& state) {
auto value = MakeFunction(FunctionType());
for (auto _ : state) {
benchmark::DoNotOptimize(value);
auto copy = value; // NOLINT
benchmark::DoNotOptimize(copy);
}
}
static std::string name() { return "BM_Copy" + FunctionType::name(); }
};
template <class FunctionType>
struct Move {
static void run(benchmark::State& state) {
Function values[2] = {MakeFunction(FunctionType())};
int i = 0;
for (auto _ : state) {
benchmark::DoNotOptimize(values);
benchmark::DoNotOptimize(values[i ^ 1] = std::move(values[i]));
i ^= 1;
}
}
static std::string name() {
return "BM_Move" + FunctionType::name();
}
};
template <class Function1, class Function2>
struct Swap {
static void run(benchmark::State& state) {
Function values[2] = {MakeFunction(Function1()), MakeFunction(Function2())};
for (auto _ : state) {
benchmark::DoNotOptimize(values);
values[0].swap(values[1]);
}
}
static bool skip() { return Function1() > Function2(); }
static std::string name() {
return "BM_Swap" + Function1::name() + Function2::name();
}
};
template <class FunctionType>
struct OperatorBool {
static void run(benchmark::State& state) {
auto f = MakeFunction(FunctionType());
for (auto _ : state) {
benchmark::DoNotOptimize(f);
benchmark::DoNotOptimize(static_cast<bool>(f));
}
}
static std::string name() { return "BM_OperatorBool" + FunctionType::name(); }
};
template <class FunctionType>
struct Invoke {
static void run(benchmark::State& state) {
S s;
const auto value = MakeFunction(FunctionType());
for (auto _ : state) {
benchmark::DoNotOptimize(value);
benchmark::DoNotOptimize(value(&s));
}
}
static bool skip() { return FunctionType() == ::FunctionType::Null; }
static std::string name() { return "BM_Invoke" + FunctionType::name(); }
};
template <class FunctionType>
struct InvokeInlined {
static void run(benchmark::State& state) {
S s;
for (auto _ : state) {
MakeFunction(FunctionType())(&s);
}
}
static bool skip() { return FunctionType() == ::FunctionType::Null; }
static std::string name() {
return "BM_InvokeInlined" + FunctionType::name();
}
};
} // namespace
int main(int argc, char** argv) {
benchmark::Initialize(&argc, argv);
if (benchmark::ReportUnrecognizedArguments(argc, argv))
return 1;
makeCartesianProductBenchmark<ConstructAndDestroy, AllOpacity,
AllFunctionTypes>();
makeCartesianProductBenchmark<Copy, AllFunctionTypes>();
makeCartesianProductBenchmark<Move, AllFunctionTypes>();
makeCartesianProductBenchmark<Swap, AllFunctionTypes, AllFunctionTypes>();
makeCartesianProductBenchmark<OperatorBool, AllFunctionTypes>();
makeCartesianProductBenchmark<Invoke, AllFunctionTypes>();
makeCartesianProductBenchmark<InvokeInlined, AllFunctionTypes>();
benchmark::RunSpecifiedBenchmarks();
}

23
benchmarks/lit.cfg.py Normal file
View File

@@ -0,0 +1,23 @@
# -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79:
# Configuration file for the 'lit' test runner.
import os
import site
site.addsitedir(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'utils'))
from libcxx.test.googlebenchmark import GoogleBenchmark
# Tell pylint that we know config and lit_config exist somewhere.
if 'PYLINT_IMPORT' in os.environ:
config = object()
lit_config = object()
# name: The name of this test suite.
config.name = 'libc++ benchmarks'
config.suffixes = []
config.test_exec_root = os.path.join(config.libcxx_obj_root, 'benchmarks')
config.test_source_root = config.test_exec_root
config.test_format = GoogleBenchmark(test_sub_dirs='.',
test_suffix='.libcxx.out',
benchmark_args=config.benchmark_args)

View File

@@ -0,0 +1,10 @@
@LIT_SITE_CFG_IN_HEADER@
import sys
config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@"
config.libcxx_obj_root = "@LIBCXX_BINARY_DIR@"
config.benchmark_args = "@LIBCXX_BENCHMARK_TEST_ARGS@".split(';')
# Let the main config do the real work.
lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/benchmarks/lit.cfg.py")

View File

@@ -0,0 +1,249 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <cstdint>
#include <memory>
#include <random>
#include <set>
#include <string>
#include <vector>
#include "CartesianBenchmarks.hpp"
#include "benchmark/benchmark.h"
#include "test_macros.h"
namespace {
enum class HitType { Hit, Miss };
struct AllHitTypes : EnumValuesAsTuple<AllHitTypes, HitType, 2> {
static constexpr const char* Names[] = {"Hit", "Miss"};
};
enum class AccessPattern { Ordered, Random };
struct AllAccessPattern
: EnumValuesAsTuple<AllAccessPattern, AccessPattern, 2> {
static constexpr const char* Names[] = {"Ordered", "Random"};
};
void sortKeysBy(std::vector<uint64_t>& Keys, AccessPattern AP) {
if (AP == AccessPattern::Random) {
std::random_device R;
std::mt19937 M(R());
std::shuffle(std::begin(Keys), std::end(Keys), M);
}
}
struct TestSets {
std::vector<std::set<uint64_t> > Sets;
std::vector<uint64_t> Keys;
};
TestSets makeTestingSets(size_t TableSize, size_t NumTables, HitType Hit,
AccessPattern Access) {
TestSets R;
R.Sets.resize(1);
for (uint64_t I = 0; I < TableSize; ++I) {
R.Sets[0].insert(2 * I);
R.Keys.push_back(Hit == HitType::Hit ? 2 * I : 2 * I + 1);
}
R.Sets.resize(NumTables, R.Sets[0]);
sortKeysBy(R.Keys, Access);
return R;
}
struct Base {
size_t TableSize;
size_t NumTables;
Base(size_t T, size_t N) : TableSize(T), NumTables(N) {}
bool skip() const {
size_t Total = TableSize * NumTables;
return Total < 100 || Total > 1000000;
}
std::string baseName() const {
return "_TableSize" + std::to_string(TableSize) + "_NumTables" +
std::to_string(NumTables);
}
};
template <class Access>
struct Create : Base {
using Base::Base;
void run(benchmark::State& State) const {
std::vector<uint64_t> Keys(TableSize);
std::iota(Keys.begin(), Keys.end(), uint64_t{0});
sortKeysBy(Keys, Access());
while (State.KeepRunningBatch(TableSize * NumTables)) {
std::vector<std::set<uint64_t>> Sets(NumTables);
for (auto K : Keys) {
for (auto& Set : Sets) {
benchmark::DoNotOptimize(Set.insert(K));
}
}
}
}
std::string name() const {
return "BM_Create" + Access::name() + baseName();
}
};
template <class Hit, class Access>
struct Find : Base {
using Base::Base;
void run(benchmark::State& State) const {
auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());
while (State.KeepRunningBatch(TableSize * NumTables)) {
for (auto K : Data.Keys) {
for (auto& Set : Data.Sets) {
benchmark::DoNotOptimize(Set.find(K));
}
}
}
}
std::string name() const {
return "BM_Find" + Hit::name() + Access::name() + baseName();
}
};
template <class Hit, class Access>
struct FindNeEnd : Base {
using Base::Base;
void run(benchmark::State& State) const {
auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());
while (State.KeepRunningBatch(TableSize * NumTables)) {
for (auto K : Data.Keys) {
for (auto& Set : Data.Sets) {
benchmark::DoNotOptimize(Set.find(K) != Set.end());
}
}
}
}
std::string name() const {
return "BM_FindNeEnd" + Hit::name() + Access::name() + baseName();
}
};
template <class Access>
struct InsertHit : Base {
using Base::Base;
void run(benchmark::State& State) const {
auto Data = makeTestingSets(TableSize, NumTables, HitType::Hit, Access());
while (State.KeepRunningBatch(TableSize * NumTables)) {
for (auto K : Data.Keys) {
for (auto& Set : Data.Sets) {
benchmark::DoNotOptimize(Set.insert(K));
}
}
}
}
std::string name() const {
return "BM_InsertHit" + Access::name() + baseName();
}
};
template <class Access>
struct InsertMissAndErase : Base {
using Base::Base;
void run(benchmark::State& State) const {
auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss, Access());
while (State.KeepRunningBatch(TableSize * NumTables)) {
for (auto K : Data.Keys) {
for (auto& Set : Data.Sets) {
benchmark::DoNotOptimize(Set.erase(Set.insert(K).first));
}
}
}
}
std::string name() const {
return "BM_InsertMissAndErase" + Access::name() + baseName();
}
};
struct IterateRangeFor : Base {
using Base::Base;
void run(benchmark::State& State) const {
auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
AccessPattern::Ordered);
while (State.KeepRunningBatch(TableSize * NumTables)) {
for (auto& Set : Data.Sets) {
for (auto& V : Set) {
benchmark::DoNotOptimize(V);
}
}
}
}
std::string name() const { return "BM_IterateRangeFor" + baseName(); }
};
struct IterateBeginEnd : Base {
using Base::Base;
void run(benchmark::State& State) const {
auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
AccessPattern::Ordered);
while (State.KeepRunningBatch(TableSize * NumTables)) {
for (auto& Set : Data.Sets) {
for (auto it = Set.begin(); it != Set.end(); ++it) {
benchmark::DoNotOptimize(*it);
}
}
}
}
std::string name() const { return "BM_IterateBeginEnd" + baseName(); }
};
} // namespace
int main(int argc, char** argv) {
benchmark::Initialize(&argc, argv);
if (benchmark::ReportUnrecognizedArguments(argc, argv))
return 1;
const std::vector<size_t> TableSize{1, 10, 100, 1000, 10000, 100000, 1000000};
const std::vector<size_t> NumTables{1, 10, 100, 1000, 10000, 100000, 1000000};
makeCartesianProductBenchmark<Create, AllAccessPattern>(TableSize, NumTables);
makeCartesianProductBenchmark<Find, AllHitTypes, AllAccessPattern>(
TableSize, NumTables);
makeCartesianProductBenchmark<FindNeEnd, AllHitTypes, AllAccessPattern>(
TableSize, NumTables);
makeCartesianProductBenchmark<InsertHit, AllAccessPattern>(
TableSize, NumTables);
makeCartesianProductBenchmark<InsertMissAndErase, AllAccessPattern>(
TableSize, NumTables);
makeCartesianProductBenchmark<IterateRangeFor>(TableSize, NumTables);
makeCartesianProductBenchmark<IterateBeginEnd>(TableSize, NumTables);
benchmark::RunSpecifiedBenchmarks();
}

View File

@@ -1,9 +1,12 @@
#include <unordered_set>
#include <vector>
#include <cstdint>
#include "benchmark/benchmark.h"
#include <cstdint>
#include <new>
#include <vector>
#include "CartesianBenchmarks.hpp"
#include "GenerateInput.hpp"
#include "benchmark/benchmark.h"
#include "test_macros.h"
constexpr std::size_t MAX_STRING_LEN = 8 << 14;
@@ -11,7 +14,7 @@ constexpr std::size_t MAX_STRING_LEN = 8 << 14;
static void BM_StringFindNoMatch(benchmark::State &state) {
std::string s1(state.range(0), '-');
std::string s2(8, '*');
while (state.KeepRunning())
for (auto _ : state)
benchmark::DoNotOptimize(s1.find(s2));
}
BENCHMARK(BM_StringFindNoMatch)->Range(10, MAX_STRING_LEN);
@@ -20,7 +23,7 @@ BENCHMARK(BM_StringFindNoMatch)->Range(10, MAX_STRING_LEN);
static void BM_StringFindAllMatch(benchmark::State &state) {
std::string s1(MAX_STRING_LEN, '-');
std::string s2(state.range(0), '-');
while (state.KeepRunning())
for (auto _ : state)
benchmark::DoNotOptimize(s1.find(s2));
}
BENCHMARK(BM_StringFindAllMatch)->Range(1, MAX_STRING_LEN);
@@ -30,7 +33,7 @@ static void BM_StringFindMatch1(benchmark::State &state) {
std::string s1(MAX_STRING_LEN / 2, '*');
s1 += std::string(state.range(0), '-');
std::string s2(state.range(0), '-');
while (state.KeepRunning())
for (auto _ : state)
benchmark::DoNotOptimize(s1.find(s2));
}
BENCHMARK(BM_StringFindMatch1)->Range(1, MAX_STRING_LEN / 4);
@@ -41,9 +44,332 @@ static void BM_StringFindMatch2(benchmark::State &state) {
s1 += std::string(state.range(0), '-');
s1 += std::string(state.range(0), '*');
std::string s2(state.range(0), '-');
while (state.KeepRunning())
for (auto _ : state)
benchmark::DoNotOptimize(s1.find(s2));
}
BENCHMARK(BM_StringFindMatch2)->Range(1, MAX_STRING_LEN / 4);
BENCHMARK_MAIN();
static void BM_StringCtorDefault(benchmark::State &state) {
for (auto _ : state) {
std::string Default;
benchmark::DoNotOptimize(Default);
}
}
BENCHMARK(BM_StringCtorDefault);
enum class Length { Empty, Small, Large, Huge };
struct AllLengths : EnumValuesAsTuple<AllLengths, Length, 4> {
static constexpr const char* Names[] = {"Empty", "Small", "Large", "Huge"};
};
enum class Opacity { Opaque, Transparent };
struct AllOpacity : EnumValuesAsTuple<AllOpacity, Opacity, 2> {
static constexpr const char* Names[] = {"Opaque", "Transparent"};
};
enum class DiffType { Control, ChangeFirst, ChangeMiddle, ChangeLast };
struct AllDiffTypes : EnumValuesAsTuple<AllDiffTypes, DiffType, 4> {
static constexpr const char* Names[] = {"Control", "ChangeFirst",
"ChangeMiddle", "ChangeLast"};
};
TEST_ALWAYS_INLINE const char* getSmallString(DiffType D) {
switch (D) {
case DiffType::Control:
return "0123456";
case DiffType::ChangeFirst:
return "-123456";
case DiffType::ChangeMiddle:
return "012-456";
case DiffType::ChangeLast:
return "012345-";
}
}
TEST_ALWAYS_INLINE const char* getLargeString(DiffType D) {
#define LARGE_STRING_FIRST "123456789012345678901234567890"
#define LARGE_STRING_SECOND "234567890123456789012345678901"
switch (D) {
case DiffType::Control:
return "0" LARGE_STRING_FIRST "1" LARGE_STRING_SECOND "2";
case DiffType::ChangeFirst:
return "-" LARGE_STRING_FIRST "1" LARGE_STRING_SECOND "2";
case DiffType::ChangeMiddle:
return "0" LARGE_STRING_FIRST "-" LARGE_STRING_SECOND "2";
case DiffType::ChangeLast:
return "0" LARGE_STRING_FIRST "1" LARGE_STRING_SECOND "-";
}
}
TEST_ALWAYS_INLINE const char* getHugeString(DiffType D) {
#define HUGE_STRING0 "0123456789"
#define HUGE_STRING1 HUGE_STRING0 HUGE_STRING0 HUGE_STRING0 HUGE_STRING0
#define HUGE_STRING2 HUGE_STRING1 HUGE_STRING1 HUGE_STRING1 HUGE_STRING1
#define HUGE_STRING3 HUGE_STRING2 HUGE_STRING2 HUGE_STRING2 HUGE_STRING2
#define HUGE_STRING4 HUGE_STRING3 HUGE_STRING3 HUGE_STRING3 HUGE_STRING3
switch (D) {
case DiffType::Control:
return "0123456789" HUGE_STRING4 "0123456789" HUGE_STRING4 "0123456789";
case DiffType::ChangeFirst:
return "-123456789" HUGE_STRING4 "0123456789" HUGE_STRING4 "0123456789";
case DiffType::ChangeMiddle:
return "0123456789" HUGE_STRING4 "01234-6789" HUGE_STRING4 "0123456789";
case DiffType::ChangeLast:
return "0123456789" HUGE_STRING4 "0123456789" HUGE_STRING4 "012345678-";
}
}
TEST_ALWAYS_INLINE std::string makeString(Length L,
DiffType D = DiffType::Control,
Opacity O = Opacity::Transparent) {
switch (L) {
case Length::Empty:
return maybeOpaque("", O == Opacity::Opaque);
case Length::Small:
return maybeOpaque(getSmallString(D), O == Opacity::Opaque);
case Length::Large:
return maybeOpaque(getLargeString(D), O == Opacity::Opaque);
case Length::Huge:
return maybeOpaque(getHugeString(D), O == Opacity::Opaque);
}
}
template <class Length, class Opaque>
struct StringConstructDestroyCStr {
static void run(benchmark::State& state) {
for (auto _ : state) {
benchmark::DoNotOptimize(
makeString(Length(), DiffType::Control, Opaque()));
}
}
static std::string name() {
return "BM_StringConstructDestroyCStr" + Length::name() + Opaque::name();
}
};
template <class Length, bool MeasureCopy, bool MeasureDestroy>
static void StringCopyAndDestroy(benchmark::State& state) {
static constexpr size_t NumStrings = 1024;
auto Orig = makeString(Length());
std::aligned_storage<sizeof(std::string)>::type Storage[NumStrings];
while (state.KeepRunningBatch(NumStrings)) {
if (!MeasureCopy)
state.PauseTiming();
for (size_t I = 0; I < NumStrings; ++I) {
::new (static_cast<void*>(Storage + I)) std::string(Orig);
}
if (!MeasureCopy)
state.ResumeTiming();
if (!MeasureDestroy)
state.PauseTiming();
for (size_t I = 0; I < NumStrings; ++I) {
using S = std::string;
reinterpret_cast<S*>(Storage + I)->~S();
}
if (!MeasureDestroy)
state.ResumeTiming();
}
}
template <class Length>
struct StringCopy {
static void run(benchmark::State& state) {
StringCopyAndDestroy<Length, true, false>(state);
}
static std::string name() { return "BM_StringCopy" + Length::name(); }
};
template <class Length>
struct StringDestroy {
static void run(benchmark::State& state) {
StringCopyAndDestroy<Length, false, true>(state);
}
static std::string name() { return "BM_StringDestroy" + Length::name(); }
};
template <class Length>
struct StringMove {
static void run(benchmark::State& state) {
// Keep two object locations and move construct back and forth.
std::aligned_storage<sizeof(std::string), alignof(std::string)>::type Storage[2];
using S = std::string;
size_t I = 0;
S *newS = new (static_cast<void*>(Storage)) std::string(makeString(Length()));
for (auto _ : state) {
// Switch locations.
I ^= 1;
benchmark::DoNotOptimize(Storage);
// Move construct into the new location,
S *tmpS = new (static_cast<void*>(Storage + I)) S(std::move(*newS));
// then destroy the old one.
newS->~S();
newS = tmpS;
}
newS->~S();
}
static std::string name() { return "BM_StringMove" + Length::name(); }
};
enum class Relation { Eq, Less, Compare };
struct AllRelations : EnumValuesAsTuple<AllRelations, Relation, 3> {
static constexpr const char* Names[] = {"Eq", "Less", "Compare"};
};
template <class Rel, class LHLength, class RHLength, class DiffType>
struct StringRelational {
static void run(benchmark::State& state) {
auto Lhs = makeString(RHLength());
auto Rhs = makeString(LHLength(), DiffType());
for (auto _ : state) {
benchmark::DoNotOptimize(Lhs);
benchmark::DoNotOptimize(Rhs);
switch (Rel()) {
case Relation::Eq:
benchmark::DoNotOptimize(Lhs == Rhs);
break;
case Relation::Less:
benchmark::DoNotOptimize(Lhs < Rhs);
break;
case Relation::Compare:
benchmark::DoNotOptimize(Lhs.compare(Rhs));
break;
}
}
}
static bool skip() {
// Eq is commutative, so skip half the matrix.
if (Rel() == Relation::Eq && LHLength() > RHLength())
return true;
// We only care about control when the lengths differ.
if (LHLength() != RHLength() && DiffType() != ::DiffType::Control)
return true;
// For empty, only control matters.
if (LHLength() == Length::Empty && DiffType() != ::DiffType::Control)
return true;
return false;
}
static std::string name() {
return "BM_StringRelational" + Rel::name() + LHLength::name() +
RHLength::name() + DiffType::name();
}
};
enum class Depth { Shallow, Deep };
struct AllDepths : EnumValuesAsTuple<AllDepths, Depth, 2> {
static constexpr const char* Names[] = {"Shallow", "Deep"};
};
enum class Temperature { Hot, Cold };
struct AllTemperatures : EnumValuesAsTuple<AllTemperatures, Temperature, 2> {
static constexpr const char* Names[] = {"Hot", "Cold"};
};
template <class Temperature, class Depth, class Length>
struct StringRead {
void run(benchmark::State& state) const {
static constexpr size_t NumStrings =
Temperature() == ::Temperature::Hot
? 1 << 10
: /* Enough strings to overflow the cache */ 1 << 20;
static_assert((NumStrings & (NumStrings - 1)) == 0,
"NumStrings should be a power of two to reduce overhead.");
std::vector<std::string> Values(NumStrings, makeString(Length()));
size_t I = 0;
for (auto _ : state) {
// Jump long enough to defeat cache locality, and use a value that is
// coprime with NumStrings to ensure we visit every element.
I = (I + 17) % NumStrings;
const auto& V = Values[I];
// Read everything first. Escaping data() through DoNotOptimize might
// cause the compiler to have to recalculate information about `V` due to
// aliasing.
const char* const Data = V.data();
const size_t Size = V.size();
benchmark::DoNotOptimize(Data);
benchmark::DoNotOptimize(Size);
if (Depth() == ::Depth::Deep) {
// Read into the payload. This mainly shows the benefit of SSO when the
// data is cold.
benchmark::DoNotOptimize(*Data);
}
}
}
static bool skip() {
// Huge does not give us anything that Large doesn't have. Skip it.
if (Length() == ::Length::Huge) {
return true;
}
return false;
}
std::string name() const {
return "BM_StringRead" + Temperature::name() + Depth::name() +
Length::name();
}
};
void sanityCheckGeneratedStrings() {
for (auto Lhs : {Length::Empty, Length::Small, Length::Large, Length::Huge}) {
const auto LhsString = makeString(Lhs);
for (auto Rhs :
{Length::Empty, Length::Small, Length::Large, Length::Huge}) {
if (Lhs > Rhs)
continue;
const auto RhsString = makeString(Rhs);
// The smaller one must be a prefix of the larger one.
if (RhsString.find(LhsString) != 0) {
fprintf(stderr, "Invalid autogenerated strings for sizes (%d,%d).\n",
static_cast<int>(Lhs), static_cast<int>(Rhs));
std::abort();
}
}
}
// Verify the autogenerated diffs
for (auto L : {Length::Small, Length::Large, Length::Huge}) {
const auto Control = makeString(L);
const auto Verify = [&](std::string Exp, size_t Pos) {
// Only change on the Pos char.
if (Control[Pos] != Exp[Pos]) {
Exp[Pos] = Control[Pos];
if (Control == Exp)
return;
}
fprintf(stderr, "Invalid autogenerated diff with size %d\n",
static_cast<int>(L));
std::abort();
};
Verify(makeString(L, DiffType::ChangeFirst), 0);
Verify(makeString(L, DiffType::ChangeMiddle), Control.size() / 2);
Verify(makeString(L, DiffType::ChangeLast), Control.size() - 1);
}
}
int main(int argc, char** argv) {
benchmark::Initialize(&argc, argv);
if (benchmark::ReportUnrecognizedArguments(argc, argv))
return 1;
sanityCheckGeneratedStrings();
makeCartesianProductBenchmark<StringConstructDestroyCStr, AllLengths,
AllOpacity>();
makeCartesianProductBenchmark<StringCopy, AllLengths>();
makeCartesianProductBenchmark<StringMove, AllLengths>();
makeCartesianProductBenchmark<StringDestroy, AllLengths>();
makeCartesianProductBenchmark<StringRelational, AllRelations, AllLengths,
AllLengths, AllDiffTypes>();
makeCartesianProductBenchmark<StringRead, AllTemperatures, AllDepths,
AllLengths>();
benchmark::RunSpecifiedBenchmarks();
}

View File

@@ -1,7 +1,9 @@
#include "benchmark/benchmark.h"
#include "test_macros.h"
#include <sstream>
double __attribute__((noinline)) istream_numbers();
TEST_NOINLINE double istream_numbers();
double istream_numbers() {
const char *a[] = {

View File

@@ -9,25 +9,26 @@
#include "ContainerBenchmarks.hpp"
#include "GenerateInput.hpp"
#include "test_macros.h"
using namespace ContainerBenchmarks;
constexpr std::size_t TestNumInputs = 1024;
template <class _Size>
inline __attribute__((__always_inline__))
inline TEST_ALWAYS_INLINE
_Size loadword(const void* __p) {
_Size __r;
std::memcpy(&__r, __p, sizeof(__r));
return __r;
}
inline __attribute__((__always_inline__))
inline TEST_ALWAYS_INLINE
std::size_t rotate_by_at_least_1(std::size_t __val, int __shift) {
return (__val >> __shift) | (__val << (64 - __shift));
}
inline __attribute__((__always_inline__))
inline TEST_ALWAYS_INLINE
std::size_t hash_len_16(std::size_t __u, std::size_t __v) {
const std::size_t __mul = 0x9ddfea08eb382d69ULL;
std::size_t __a = (__u ^ __v) * __mul;
@@ -40,7 +41,7 @@ std::size_t hash_len_16(std::size_t __u, std::size_t __v) {
template <std::size_t _Len>
inline __attribute__((__always_inline__))
inline TEST_ALWAYS_INLINE
std::size_t hash_len_0_to_8(const char* __s) {
static_assert(_Len == 4 || _Len == 8, "");
const uint64_t __a = loadword<uint32_t>(__s);
@@ -50,7 +51,7 @@ std::size_t hash_len_0_to_8(const char* __s) {
struct UInt32Hash {
UInt32Hash() = default;
inline __attribute__((__always_inline__))
inline TEST_ALWAYS_INLINE
std::size_t operator()(uint32_t data) const {
return hash_len_0_to_8<4>(reinterpret_cast<const char*>(&data));
}
@@ -58,7 +59,7 @@ struct UInt32Hash {
struct UInt64Hash {
UInt64Hash() = default;
inline __attribute__((__always_inline__))
inline TEST_ALWAYS_INLINE
std::size_t operator()(uint64_t data) const {
return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
}
@@ -66,7 +67,7 @@ struct UInt64Hash {
struct UInt128Hash {
UInt128Hash() = default;
inline __attribute__((__always_inline__))
inline TEST_ALWAYS_INLINE
std::size_t operator()(__uint128_t data) const {
const __uint128_t __mask = static_cast<std::size_t>(-1);
const std::size_t __a = (std::size_t)(data & __mask);
@@ -77,7 +78,7 @@ struct UInt128Hash {
struct UInt32Hash2 {
UInt32Hash2() = default;
inline __attribute__((__always_inline__))
inline TEST_ALWAYS_INLINE
std::size_t operator()(uint32_t data) const {
const uint32_t __m = 0x5bd1e995;
const uint32_t __r = 24;
@@ -97,7 +98,7 @@ struct UInt32Hash2 {
struct UInt64Hash2 {
UInt64Hash2() = default;
inline __attribute__((__always_inline__))
inline TEST_ALWAYS_INLINE
std::size_t operator()(uint64_t data) const {
return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
}

View File

@@ -8,12 +8,16 @@ function(find_compiler_rt_library name dest)
if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET)
list(APPEND CLANG_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}")
endif()
get_property(LIBCXX_CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE)
string(REPLACE " " ";" LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS}")
list(APPEND CLANG_COMMAND ${LIBCXX_CXX_FLAGS})
execute_process(
COMMAND ${CLANG_COMMAND}
RESULT_VARIABLE HAD_ERROR
OUTPUT_VARIABLE LIBRARY_FILE
)
string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE)
file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE)
string(REPLACE "builtins" "${name}" LIBRARY_FILE "${LIBRARY_FILE}")
if (NOT HAD_ERROR AND EXISTS "${LIBRARY_FILE}")
message(STATUS "Found compiler-rt library: ${LIBRARY_FILE}")
@@ -37,6 +41,7 @@ function(find_compiler_rt_dir dest)
OUTPUT_VARIABLE LIBRARY_DIR
)
string(STRIP "${LIBRARY_DIR}" LIBRARY_DIR)
file(TO_CMAKE_PATH "${LIBRARY_DIR}" LIBRARY_DIR)
set(LIBRARY_DIR "${LIBRARY_DIR}/darwin")
else()
set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXX_COMPILE_FLAGS}
@@ -47,6 +52,7 @@ function(find_compiler_rt_dir dest)
OUTPUT_VARIABLE LIBRARY_FILE
)
string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE)
file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE)
get_filename_component(LIBRARY_DIR "${LIBRARY_FILE}" DIRECTORY)
endif()
if (NOT HAD_ERROR AND EXISTS "${LIBRARY_DIR}")

View File

@@ -32,14 +32,6 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs)
set(LIBCXX_CXX_ABI_LIBRARY ${abilib})
set(LIBCXX_ABILIB_FILES ${abifiles})
# The place in the build tree where we store out-of-source headers.
file(MAKE_DIRECTORY "${LIBCXX_BUILD_HEADERS_ROOT}")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/c++/v1")
foreach(_d ${abidirs})
file(MAKE_DIRECTORY "${LIBCXX_BINARY_INCLUDE_DIR}/${_d}")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/c++/v1/${_d}")
endforeach()
foreach(fpath ${LIBCXX_ABILIB_FILES})
set(found FALSE)
foreach(incpath ${LIBCXX_CXX_ABI_INCLUDE_PATHS})
@@ -49,23 +41,25 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs)
get_filename_component(ifile ${fpath} NAME)
set(src ${incpath}/${fpath})
set(dst ${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}/${fpath})
set(dst ${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}/${ifile})
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}")
set(dst "${CMAKE_BINARY_DIR}/include/c++/v1/${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 (NOT LIBCXX_USING_INSTALLED_LLVM AND LIBCXX_HEADER_DIR)
set(dst "${LIBCXX_HEADER_DIR}/include/c++/v1/${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}")
endif()
if (LIBCXX_INSTALL_HEADERS)
install(FILES "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}"
DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1/${dstdir}
DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1/${dstdir}
COMPONENT cxx-headers
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
)
@@ -104,10 +98,10 @@ if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxabi")
if (LIBCXX_CXX_ABI_INTREE)
# Link against just-built "cxxabi" target.
if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
set(CXXABI_LIBNAME cxxabi_static)
if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
set(CXXABI_LIBNAME cxxabi_static)
else()
set(CXXABI_LIBNAME cxxabi_shared)
set(CXXABI_LIBNAME cxxabi_shared)
endif()
set(LIBCXX_LIBCPPABI_VERSION "2" PARENT_SCOPE)
else()

View File

@@ -16,6 +16,7 @@ macro(mangle_name str output)
string(REGEX REPLACE "^-+" "" strippedStr "${strippedStr}")
string(REGEX REPLACE "-+$" "" strippedStr "${strippedStr}")
string(REPLACE "-" "_" strippedStr "${strippedStr}")
string(REPLACE ":" "_COLON_" strippedStr "${strippedStr}")
string(REPLACE "=" "_EQ_" strippedStr "${strippedStr}")
string(REPLACE "+" "X" strippedStr "${strippedStr}")
string(TOUPPER "${strippedStr}" ${output})
@@ -44,6 +45,29 @@ macro(check_flag_supported flag)
check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
endmacro()
macro(append_flags DEST)
foreach(value ${ARGN})
list(APPEND ${DEST} ${value})
list(APPEND ${DEST} ${value})
endforeach()
endmacro()
# If the specified 'condition' is true then append the specified list of flags to DEST
macro(append_flags_if condition DEST)
if (${condition})
list(APPEND ${DEST} ${ARGN})
endif()
endmacro()
# Add each flag in the list specified by DEST if that flag is supported by the current compiler.
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})
endforeach()
endmacro()
# Add a macro definition if condition is true.
macro(define_if condition def)
if (${condition})

View File

@@ -46,10 +46,11 @@ macro(find_llvm_parts)
OUTPUT_VARIABLE CONFIG_OUTPUT
ERROR_QUIET)
if(NOT HAD_ERROR)
string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH)
string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH_FROM_LLVM_CONFIG)
file(TO_CMAKE_PATH "${LLVM_CMAKE_PATH_FROM_LLVM_CONFIG}" LLVM_CMAKE_PATH)
else()
set(LLVM_CMAKE_PATH
"${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
file(TO_CMAKE_PATH "${LLVM_BINARY_DIR}" LLVM_BINARY_DIR_CMAKE_STYLE)
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
endif()
else()
set(LLVM_FOUND OFF)

View File

@@ -242,11 +242,15 @@ libc++experimental Specific Options
.. option:: LIBCXX_ENABLE_FILESYSTEM:BOOL
**Default**: ``LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY``
**Default**: ``ON``
Build filesystem as part of libc++experimental.a. This allows filesystem
to be disabled without turning off the entire experimental library.
Build filesystem as a standalone library libc++fs.a.
.. option:: LIBCXX_INSTALL_FILESYSTEM_LIBRARY:BOOL
**Default**: ``LIBCXX_ENABLE_FILESYSTEM AND LIBCXX_INSTALL_LIBRARY``
Install libc++fs.a alongside libc++.
.. _ABI Library Specific Options:
@@ -312,6 +316,15 @@ libc++ Feature Options
Build the libc++ benchmark tests and the Google Benchmark library needed
to support them.
.. option:: LIBCXX_BENCHMARK_TEST_ARGS:STRING
**Default**: ``--benchmark_min_time=0.01``
A semicolon list of arguments to pass when running the libc++ benchmarks using the
``check-cxx-benchmarks`` rule. By default we run the benchmarks for a very short amount of time,
since the primary use of ``check-cxx-benchmarks`` is to get test and sanitizer coverage, not to
get accurate measurements.
.. option:: LIBCXX_BENCHMARK_NATIVE_STDLIB:STRING
**Default**:: ``""``
@@ -328,6 +341,15 @@ 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
--------------------------
@@ -347,6 +369,20 @@ The following options allow building libc++ for a different ABI version.
Build the "unstable" ABI version of libc++. Includes all ABI changing features
on top of the current stable version.
.. option:: LIBCXX_ABI_NAMESPACE:STRING
**Default**: ``__n`` where ``n`` is the current ABI version.
This option defines the name of the inline ABI versioning namespace. It can be used for building
custom versions of libc++ with unique symbol names in order to prevent conflicts or ODR issues
with other libc++ versions.
.. warning::
When providing a custom namespace, it's the users 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.
.. option:: LIBCXX_ABI_DEFINES:STRING
**Default**: ``""``

View File

@@ -24,11 +24,11 @@ systems. For example::
// Define availability macros.
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE)
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
#else if defined(_LIBCPP_USE_AVAILABILITY_SOME_OTHER_VENDOR)
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
#else
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
#else
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
#endif
When the library is updated by the platform vendor, the markup can be updated.
@@ -43,9 +43,9 @@ For example::
In the source code, the macro can be added on a class if the full class requires
type info from the library for example::
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
: public std::logic_error {
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
: public std::logic_error {
or on a particular symbol:
@@ -65,14 +65,12 @@ availability.
the test-suite against the host system library. Alternatively a path to the
directory containing a specific prebuilt libc++ can be used, for example:
`--param=use_system_cxx_lib=/path/to/macOS/10.8/`.
* The `with_availability` boolean parameter enables the availability markup.
Tests can be marked as XFAIL based on multiple features made available by lit:
* if either `use_system_cxx_lib` or `with_availability` is passed to lit,
assuming `--param=platform=macosx10.8` is passed as well the following
features will be available:
* if `use_system_cxx_lib` is passed to lit, assuming `--param=platform=macosx10.8`
is passed as well the following features will be available:
- availability
- availability=x86_64
@@ -81,7 +79,7 @@ Tests can be marked as XFAIL based on multiple features made available by lit:
- availability=x86_64-apple-macosx10.8
- availability=macosx10.8
This feature is used to XFAIL a test that *is* using a class of a method marked
This feature is used to XFAIL a test that *is* using a class or a method marked
as unavailable *and* that is expected to *fail* if deployed on an older system.
* if `use_system_cxx_lib` is passed to lit, the following features will also
@@ -94,9 +92,9 @@ Tests can be marked as XFAIL based on multiple features made available by lit:
- with_system_cxx_lib=x86_64-apple-macosx10.8
- with_system_cxx_lib=macosx10.8
This feature is used to XFAIL a test that is *not* using a class of a method
This feature is used to XFAIL a test that is *not* using a class or a method
marked as unavailable *but* that is expected to fail if deployed on an older
system. For example if we know that it exhibits a but in the libc on a
system. For example if we know that it exhibits a bug in the libc on a
particular system version.
* if `with_availability` is passed to lit, the following features will also
@@ -109,6 +107,6 @@ Tests can be marked as XFAIL based on multiple features made available by lit:
- availability_markup=x86_64-apple-macosx10.8
- availability_markup=macosx10.8
This feature is used to XFAIL a test that *is* using a class of a method
This feature is used to XFAIL a test that *is* using a class or a method
marked as unavailable *but* that is expected to *pass* if deployed on an older
system. For example if it is using a symbol in a statically evaluated context.

View File

@@ -28,7 +28,7 @@ Design Goals
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 dependant on
* 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.

View File

@@ -0,0 +1,494 @@
==============
File Time Type
==============
.. contents::
:local:
.. _file-time-type-motivation:
Motivation
==========
The filesystem library provides interfaces for getting and setting the last
write time of a file or directory. The interfaces use the ``file_time_type``
type, which is a specialization of ``chrono::time_point`` for the
"filesystem clock". According to [fs.filesystem.syn]
trivial-clock is an implementation-defined type that satisfies the
Cpp17TrivialClock requirements ([time.clock.req]) and that is capable of
representing and measuring file time values. Implementations should ensure
that the resolution and range of file_­time_­type reflect the operating
system dependent resolution and range of file time values.
On POSIX systems, file times are represented using the ``timespec`` struct,
which is defined as follows:
.. code-block:: cpp
struct timespec {
time_t tv_sec;
long tv_nsec;
};
To represent the range and resolution of ``timespec``, we need to (A) have
nanosecond resolution, and (B) use more than 64 bits (assuming a 64 bit ``time_t``).
As the standard requires us to use the ``chrono`` interface, we have to define
our own filesystem clock which specifies the period and representation of
the time points and duration it provides. It will look like this:
.. code-block:: cpp
struct _FilesystemClock {
using period = nano;
using rep = TBD; // What is this?
using duration = chrono::duration<rep, period>;
using time_point = chrono::time_point<_FilesystemClock>;
// ... //
};
using file_time_type = _FilesystemClock::time_point;
To get nanosecond resolution, we simply define ``period`` to be ``std::nano``.
But what type can we use as the arithmetic representation that is capable
of representing the range of the ``timespec`` struct?
Problems To Consider
====================
Before considering solutions, let's consider the problems they should solve,
and how important solving those problems are:
Having a Smaller Range than ``timespec``
----------------------------------------
One solution to the range problem is to simply reduce the resolution of
``file_time_type`` to be less than that of nanoseconds. This is what libc++'s
initial implementation of ``file_time_type`` did; it's also what
``std::system_clock`` does. As a result, it can represent time points about
292 thousand years on either side of the epoch, as opposed to only 292 years
at nanosecond resolution.
``timespec`` can represent time points +/- 292 billion years from the epoch
(just in case you needed a time point 200 billion years before the big bang,
and with nanosecond resolution).
To get the same range, we would need to drop our resolution to that of seconds
to come close to having the same range.
This begs the question, is the range problem "really a problem"? Sane usages
of file time stamps shouldn't exceed +/- 300 years, so should we care to support it?
I believe the answer is yes. We're not designing the filesystem time API, we're
providing glorified C++ wrappers for it. If the underlying API supports
a value, then we should too. Our wrappers should not place artificial restrictions
on users that are not present in the underlying filesystem.
Having a smaller range that the underlying filesystem forces the
implementation to report ``value_too_large`` errors when it encounters a time
point that it can't represent. This can cause the call to ``last_write_time``
to throw in cases where the user was confident the call should succeed. (See below)
.. code-block:: cpp
#include <filesystem>
using namespace std::filesystem;
// Set the times using the system interface.
void set_file_times(const char* path, struct timespec ts) {
timespec both_times[2];
both_times[0] = ts;
both_times[1] = ts;
int result = ::utimensat(AT_FDCWD, path, both_times, 0);
assert(result != -1);
}
// Called elsewhere to set the file time to something insane, and way
// out of the 300 year range we might expect.
void some_bad_persons_code() {
struct timespec new_times;
new_times.tv_sec = numeric_limits<time_t>::max();
new_times.tv_nsec = 0;
set_file_times("/tmp/foo", new_times); // OK, supported by most FSes
}
int main() {
path p = "/tmp/foo";
file_status st = status(p);
if (!exists(st) || !is_regular_file(st))
return 1;
if ((st.permissions() & perms::others_read) == perms::none)
return 1;
// It seems reasonable to assume this call should succeed.
file_time_type tp = last_write_time(p); // BAD! Throws value_too_large.
}
Having a Smaller Resolution than ``timespec``
---------------------------------------------
As mentioned in the previous section, one way to solve the range problem
is by reducing the resolution. But matching the range of ``timespec`` using a
64 bit representation requires limiting the resolution to seconds.
So we might ask: Do users "need" nanosecond precision? Is seconds not good enough?
I limit my consideration of the point to this: Why was it not good enough for
the underlying system interfaces? If it wasn't good enough for them, then it
isn't good enough for us. Our job is to match the filesystems range and
representation, not design it.
Having a Larger Range than ``timespec``
----------------------------------------
We should also consider the opposite problem of having a ``file_time_type``
that is able to represent a larger range than ``timespec``. At least in
this case ``last_write_time`` can be used to get and set all possible values
supported by the underlying filesystem; meaning ``last_write_time(p)`` will
never throw a overflow error when retrieving a value.
However, this introduces a new problem, where users are allowed to attempt to
create a time point beyond what the filesystem can represent. Two particular
values which cause this are ``file_time_type::min()`` and
``file_time_type::max()``. As a result, the following code would throw:
.. code-block:: cpp
void test() {
last_write_time("/tmp/foo", file_time_type::max()); // Throws
last_write_time("/tmp/foo", file_time_type::min()); // Throws.
}
Apart from cases explicitly using ``min`` and ``max``, I don't see users taking
a valid time point, adding a couple hundred billions of years in error,
and then trying to update a file's write time to that value very often.
Compared to having a smaller range, this problem seems preferable. At least
now we can represent any time point the filesystem can, so users won't be forced
to revert back to system interfaces to avoid limitations in the C++ STL.
I posit that we should only consider this concern *after* we have something
with at least the same range and resolution of the underlying filesystem. The
latter two problems are much more important to solve.
Potential Solutions And Their Complications
===========================================
Source Code Portability Across Implementations
-----------------------------------------------
As we've discussed, ``file_time_type`` needs a representation that uses more
than 64 bits. The possible solutions include using ``__int128_t``, emulating a
128 bit integer using a class, or potentially defining a ``timespec`` like
arithmetic type. All three will allow us to, at minimum, match the range
and resolution, and the last one might even allow us to match them exactly.
But when considering these potential solutions we need to consider more than
just the values they can represent. We need to consider the effects they will
have on users and their code. For example, each of them breaks the following
code in some way:
.. code-block:: cpp
// Bug caused by an unexpected 'rep' type returned by count.
void print_time(path p) {
// __int128_t doesn't have streaming operators, and neither would our
// custom arithmetic types.
cout << last_write_time(p).time_since_epoch().count() << endl;
}
// Overflow during creation bug.
file_time_type timespec_to_file_time_type(struct timespec ts) {
// woops! chrono::seconds and chrono::nanoseconds use a 64 bit representation
// this may overflow before it's converted to a file_time_type.
auto dur = seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec);
return file_time_type(dur);
}
file_time_type correct_timespec_to_file_time_type(struct timespec ts) {
// This is the correct version of the above example, where we
// avoid using the chrono typedefs as they're not sufficient.
// Can we expect users to avoid this bug?
using fs_seconds = chrono::duration<file_time_type::rep>;
using fs_nanoseconds = chrono::duration<file_time_type::rep, nano>;
auto dur = fs_seconds(ts.tv_sec) + fs_nanoseconds(tv.tv_nsec);
return file_time_type(dur);
}
// Implicit truncation during conversion bug.
intmax_t get_time_in_seconds(path p) {
using fs_seconds = duration<file_time_type::rep, ratio<1, 1> >;
auto tp = last_write_time(p);
// This works with truncation for __int128_t, but what does it do for
// our custom arithmetic types.
return duration_cast<fs_seconds>().count();
}
Each of the above examples would require a user to adjust their filesystem code
to the particular eccentricities of the representation, hopefully only in such
a way that the code is still portable across implementations.
At least some of the above issues are unavoidable, no matter what
representation we choose. But some representations may be quirkier than others,
and, as I'll argue later, using an actual arithmetic type (``__int128_t``)
provides the least aberrant behavior.
Chrono and ``timespec`` Emulation.
----------------------------------
One of the options we've considered is using something akin to ``timespec``
to represent the ``file_time_type``. It only seems natural seeing as that's
what the underlying system uses, and because it might allow us to match
the range and resolution exactly. But would it work with chrono? And could
it still act at all like a ``timespec`` struct?
For ease of consideration, let's consider what the implementation might
look like.
.. code-block:: cpp
struct fs_timespec_rep {
fs_timespec_rep(long long v)
: tv_sec(v / nano::den), tv_nsec(v % nano::den)
{ }
private:
time_t tv_sec;
long tv_nsec;
};
bool operator==(fs_timespec_rep, fs_timespec_rep);
fs_int128_rep operator+(fs_timespec_rep, fs_timespec_rep);
// ... arithmetic operators ... //
The first thing to notice is that we can't construct ``fs_timespec_rep`` like
a ``timespec`` by passing ``{secs, nsecs}``. Instead we're limited to
constructing it from a single 64 bit integer.
We also can't allow the user to inspect the ``tv_sec`` or ``tv_nsec`` values
directly. A ``chrono::duration`` represents its value as a tick period and a
number of ticks stored using ``rep``. The representation is unaware of the
tick period it is being used to represent, but ``timespec`` is setup to assume
a nanosecond tick period; which is the only case where the names ``tv_sec``
and ``tv_nsec`` match the values they store.
When we convert a nanosecond duration to seconds, ``fs_timespec_rep`` will
use ``tv_sec`` to represent the number of giga seconds, and ``tv_nsec`` the
remaining seconds. Let's consider how this might cause a bug were users allowed
to manipulate the fields directly.
.. code-block:: cpp
template <class Period>
timespec convert_to_timespec(duration<fs_time_rep, Period> dur) {
fs_timespec_rep rep = dur.count();
return {rep.tv_sec, rep.tv_nsec}; // Oops! Period may not be nanoseconds.
}
template <class Duration>
Duration convert_to_duration(timespec ts) {
Duration dur({ts.tv_sec, ts.tv_nsec}); // Oops! Period may not be nanoseconds.
return file_time_type(dur);
file_time_type tp = last_write_time(p);
auto dur =
}
time_t extract_seconds(file_time_type tp) {
// Converting to seconds is a silly bug, but I could see it happening.
using SecsT = chrono::duration<file_time_type::rep, ratio<1, 1>>;
auto secs = duration_cast<Secs>(tp.time_since_epoch());
// tv_sec is now representing gigaseconds.
return secs.count().tv_sec; // Oops!
}
Despite ``fs_timespec_rep`` not being usable in any manner resembling
``timespec``, it still might buy us our goal of matching its range exactly,
right?
Sort of. Chrono provides a specialization point which specifies the minimum
and maximum values for a custom representation. It looks like this:
.. code-block:: cpp
template <>
struct duration_values<fs_timespec_rep> {
static fs_timespec_rep zero();
static fs_timespec_rep min();
static fs_timespec_rep max() { // assume friendship.
fs_timespec_rep val;
val.tv_sec = numeric_limits<time_t>::max();
val.tv_nsec = nano::den - 1;
return val;
}
};
Notice that ``duration_values`` doesn't tell the representation what tick
period it's actually representing. This would indeed correctly limit the range
of ``duration<fs_timespec_rep, nano>`` to exactly that of ``timespec``. But
nanoseconds isn't the only tick period it will be used to represent. For
example:
.. code-block:: cpp
void test() {
using rep = file_time_type::rep;
using fs_nsec = duration<rep, nano>;
using fs_sec = duration<rep>;
fs_nsec nsecs(fs_seconds::max()); // Truncates
}
Though the above example may appear silly, I think it follows from the incorrect
notion that using a ``timespec`` rep in chrono actually makes it act as if it
were an actual ``timespec``.
Interactions with 32 bit ``time_t``
-----------------------------------
Up until now we've only be considering cases where ``time_t`` is 64 bits, but what
about 32 bit systems/builds where ``time_t`` is 32 bits? (this is the common case
for 32 bit builds).
When ``time_t`` is 32 bits, we can implement ``file_time_type`` simply using 64-bit
``long long``. There is no need to get either ``__int128_t`` or ``timespec`` emulation
involved. And nor should we, as it would suffer from the numerous complications
described by this paper.
Obviously our implementation for 32-bit builds should act as similarly to the
64-bit build as possible. Code which compiles in one, should compile in the other.
This consideration is important when choosing between ``__int128_t`` and
emulating ``timespec``. The solution which provides the most uniformity with
the least eccentricity is the preferable one.
Summary
=======
The ``file_time_type`` time point is used to represent the write times for files.
Its job is to act as part of a C++ wrapper for less ideal system interfaces. The
underlying filesystem uses the ``timespec`` struct for the same purpose.
However, the initial implementation of ``file_time_type`` could not represent
either the range or resolution of ``timespec``, making it unsuitable. Fixing
this requires an implementation which uses more than 64 bits to store the
time point.
We primarily considered two solutions: Using ``__int128_t`` and using a
arithmetic emulation of ``timespec``. Each has its pros and cons, and both
come with more than one complication.
The Potential Solutions
-----------------------
``long long`` - The Status Quo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Pros:
* As a type ``long long`` plays the nicest with others:
* It works with streaming operators and other library entities which support
builtin integer types, but don't support ``__int128_t``.
* Its the representation used by chrono's ``nanosecond`` and ``second`` typedefs.
Cons:
* It cannot provide the same resolution as ``timespec`` unless we limit it
to a range of +/- 300 years from the epoch.
* It cannot provide the same range as ``timespec`` unless we limit its resolution
to seconds.
* ``last_write_time`` has to report an error when the time reported by the filesystem
is unrepresentable.
__int128_t
~~~~~~~~~~~
Pros:
* It is an integer type.
* It makes the implementation simple and efficient.
* Acts exactly like other arithmetic types.
* Can be implicitly converted to a builtin integer type by the user.
* This is important for doing things like:
.. code-block:: cpp
void c_interface_using_time_t(const char* p, time_t);
void foo(path p) {
file_time_type tp = last_write_time(p);
time_t secs = duration_cast<seconds>(tp.time_since_epoch()).count();
c_interface_using_time_t(p.c_str(), secs);
}
Cons:
* It isn't always available (but on 64 bit machines, it normally is).
* It causes ``file_time_type`` to have a larger range than ``timespec``.
* It doesn't always act the same as other builtin integer types. For example
with ``cout`` or ``to_string``.
* Allows implicit truncation to 64 bit integers.
* It can be implicitly converted to a builtin integer type by the user,
truncating its value.
Arithmetic ``timespec`` Emulation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Pros:
* It has the exact same range and resolution of ``timespec`` when representing
a nanosecond tick period.
* It's always available, unlike ``__int128_t``.
Cons:
* It has a larger range when representing any period longer than a nanosecond.
* Doesn't actually allow users to use it like a ``timespec``.
* The required representation of using ``tv_sec`` to store the giga tick count
and ``tv_nsec`` to store the remainder adds nothing over a 128 bit integer,
but complicates a lot.
* It isn't a builtin integer type, and can't be used anything like one.
* Chrono can be made to work with it, but not nicely.
* Emulating arithmetic classes come with their own host of problems regarding
overload resolution (Each operator needs three SFINAE constrained versions of
it in order to act like builtin integer types).
* It offers little over simply using ``__int128_t``.
* It acts the most differently than implementations using an actual integer type,
which has a high chance of breaking source compatibility.
Selected Solution - Using ``__int128_t``
=========================================
The solution I selected for libc++ is using ``__int128_t`` when available,
and otherwise falling back to using ``long long`` with nanosecond precision.
When ``__int128_t`` is available, or when ``time_t`` is 32-bits, the implementation
provides same resolution and a greater range than ``timespec``. Otherwise
it still provides the same resolution, but is limited to a range of +/- 300
years. This final case should be rather rare, as ``__int128_t``
is normally available in 64-bit builds, and ``time_t`` is normally 32-bits
during 32-bit builds.
Although falling back to ``long long`` and nanosecond precision is less than
ideal, it also happens to be the implementation provided by both libstdc++
and MSVC. (So that makes it better, right?)
Although the ``timespec`` emulation solution is feasible and would largely
do what we want, it comes with too many complications, potential problems
and discrepancies when compared to "normal" chrono time points and durations.
An emulation of a builtin arithmetic type using a class is never going to act
exactly the same, and the difference will be felt by users. It's not reasonable
to expect them to tolerate and work around these differences. And once
we commit to an ABI it will be too late to change. Committing to this seems
risky.
Therefore, ``__int128_t`` seems like the better solution.

View File

@@ -22,11 +22,11 @@ Visibility Macros
Mark a symbol as being exported by the libc++ library. This attribute must
be applied to the declaration of all functions exported by the libc++ dylib.
**_LIBCPP_EXTERN_VIS**
**_LIBCPP_EXPORTED_FROM_ABI**
Mark a symbol as being exported by the libc++ library. This attribute may
only be applied to objects defined in the libc++ library. On Windows this
macro applies `dllimport`/`dllexport` to the symbol. On all other platforms
this macro has no effect.
only be applied to objects defined in the libc++ runtime library. On Windows,
this macro applies `dllimport`/`dllexport` to the symbol, and on other
platforms it gives the symbol default visibility.
**_LIBCPP_OVERRIDABLE_FUNC_VIS**
Mark a symbol as being exported by the libc++ library, but allow it to be
@@ -40,11 +40,59 @@ Visibility Macros
this macro therefore expands to `__declspec(dllexport)` when building the
library and has an empty definition otherwise.
**_LIBCPP_INLINE_VISIBILITY**
Mark a function as hidden and force inlining whenever possible.
**_LIBCPP_HIDE_FROM_ABI**
Mark a function as not being part of the ABI of any final linked image that
uses it.
**_LIBCPP_ALWAYS_INLINE**
A synonym for `_LIBCPP_INLINE_VISIBILITY`
**_LIBCPP_HIDE_FROM_ABI_AFTER_V1**
Mark a function as being hidden from the ABI (per `_LIBCPP_HIDE_FROM_ABI`)
when libc++ is built with an ABI version after ABI v1. This macro is used to
maintain ABI compatibility for symbols that have been historically exported
by libc++ in v1 of the ABI, but that we don't want to export in the future.
This macro works as follows. When we build libc++, we either hide the symbol
from the ABI (if the symbol is not part of the ABI in the version we're
building), or we leave it included. From user code (i.e. when we're not
building libc++), the macro always marks symbols as internal so that programs
built using new libc++ headers stop relying on symbols that are removed from
the ABI in a future version. Each time we release a new stable version of the
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.
@@ -139,15 +187,6 @@ Visibility Macros
against the libc++ headers after making `_LIBCPP_TYPE_VIS` and
`_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` expand to default visibility.
**_LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY**
Mark a member function of a class template as visible and always inline. This
macro should only be applied to member functions of class templates that are
externally instantiated. It is important that these symbols are not marked
as hidden as that will prevent the dylib definition from being found.
This macro is used to maintain ABI compatibility for symbols that have been
historically exported by the libc++ library but are now marked inline.
**_LIBCPP_EXCEPTION_ABI**
Mark the member functions, typeinfo, and vtable of the type as being exported
by the libc++ library. This macro must be applied to all *exception types*.
@@ -155,6 +194,22 @@ 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
=====

View File

@@ -5,7 +5,7 @@
# out-of-tree builds.
# You can set these variables from the command line.
SPHINXOPTS = -n -W
SPHINXOPTS = -n -W -v
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build

62
docs/ReleaseNotes.rst Normal file
View File

@@ -0,0 +1,62 @@
========================================
Libc++ 8.0.0 (In-Progress) Release Notes
========================================
.. contents::
:local:
:depth: 2
Written by the `Libc++ Team <https://libcxx.llvm.org>`_
.. warning::
These are in-progress notes for the upcoming libc++ 8 release.
Release notes for previous releases can be found on
`the Download Page <https://releases.llvm.org/download.html>`_.
Introduction
============
This document contains the release notes for the libc++ C++ Standard Library,
part of the LLVM Compiler Infrastructure, release 8.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 <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM releases may
be downloaded from the `LLVM releases web site <https://llvm.org/releases/>`_.
For more information about libc++, please see the `Libc++ Web Site
<https://libcxx.llvm.org>`_ or the `LLVM Web Site <https://llvm.org>`_.
Note that if you are reading this file from a Subversion checkout or the
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 <https://llvm.org/releases/>`_.
What's New in Libc++ 8.0.0?
===========================
New Features
------------
API Changes
-----------
- Building libc++ for Mac OSX 10.6 is not supported anymore.
- Starting with LLVM 8.0.0, users that wish to link together translation units
built with different versions of libc++'s headers into the same final linked
image MUST define the _LIBCPP_HIDE_FROM_ABI_PER_TU macro to 1 when building
those translation units. Not defining _LIBCPP_HIDE_FROM_ABI_PER_TU to 1 and
linking translation units built with different versions of libc++'s headers
together may lead to ODR violations and ABI issues. On the flipside, code
size improvements should be expected for everyone not defining the macro.
- Starting with LLVM 8.0.0, std::dynarray has been removed from the library.
std::dynarray was a feature proposed for C++14 that was pulled from the
Standard at the last minute and was never standardized. Since there are no
plans to standardize this facility it is being removed.
- Starting with LLVM 8.0.0, std::bad_array_length has been removed from the
library. std::bad_array_length was a feature proposed for C++14 alongside
std::dynarray, but it never actually made it into the C++ Standard. There
are no plans to standardize this feature at this time. Formally speaking,
this removal constitutes an ABI break because the symbols were shipped in
the shared library. However, on macOS systems, the feature was not usable
because it was hidden behind availability annotations. We do not expect
any actual breakage to happen from this change.

View File

@@ -49,6 +49,24 @@ An example of using ``LD_LIBRARY_PATH``:
$ export LD_LIBRARY_PATH=<libcxx-install-prefix>/lib
$ ./a.out # Searches for libc++ along LD_LIBRARY_PATH
Using ``<filesystem>`` and libc++fs
====================================
Libc++ provides the implementation of the filesystem library in a separate
library. Users of ``<filesystem>`` and ``<experimental/filesystem>`` are
required to link ``-lc++fs``.
.. note::
Prior to libc++ 7.0, users of ``<experimental/filesystem>`` were required
to link libc++experimental.
.. warning::
The Filesystem library is still experimental in nature. As such normal
guarantees about ABI stability and backwards compatibility do not yet apply
to it. In the future, this restriction will be removed.
Using libc++experimental and ``<experimental/...>``
=====================================================
@@ -65,6 +83,9 @@ installed. For information on building libc++experimental from source see
:ref:`Building Libc++ <build instructions>` and
:ref:`libc++experimental CMake Options <libc++experimental options>`.
Note that as of libc++ 7.0 using the ``<experimental/filesystem>`` requires linking
libc++fs instead of libc++experimental.
Also see the `Experimental Library Implementation Status <http://libcxx.llvm.org/ts1z_status.html>`__
page.
@@ -205,6 +226,26 @@ 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]] <nodiscard extension>` 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]] <nodiscard extension>`
for more information.
**_LIBCPP_ENABLE_DEPRECATION_WARNINGS**:
This macro enables warnings when using deprecated components. For example,
when compiling in C++11 mode, using `std::auto_ptr` with the macro defined
will trigger a warning saying that `std::auto_ptr` is deprecated. By default,
this macro is not defined.
C++17 Specific Configuration Macros
-----------------------------------
**_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES**:
@@ -217,3 +258,58 @@ C++17 Specific Configuration Macros
**_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR**:
This macro is used to re-enable `std::auto_ptr` in C++17.
C++2a 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]] <nodiscard extension>`
for more information.
Libc++ Extensions
=================
This section documents various extensions provided by libc++, how they're
provided, and any information regarding how to use them.
.. _nodiscard extension:
Extended applications of ``[[nodiscard]]``
------------------------------------------
The ``[[nodiscard]]`` attribute is intended to help users find bugs where
function return values are ignored when they shouldn't be. After C++17 the
C++ standard has started to declared such library functions as ``[[nodiscard]]``.
However, this application is limited and applies only to dialects after C++17.
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:
1. Backporting ``[[nodiscard]]`` to entities declared as such by the
standard in newer dialects, but not in the present one.
2. Extended applications of ``[[nodiscard]]``, at the libraries 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 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``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This section lists all extended applications of ``[[nodiscard]]`` to entities
which no dialect declares as such (See the second form described above).
* ``get_temporary_buffer``

View File

@@ -40,16 +40,16 @@ master_doc = 'index'
# General information about the project.
project = u'libc++'
copyright = u'2011-2017, LLVM Project'
copyright = u'2011-2018, LLVM Project'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '7.0'
version = '8.0'
# The full version, including alpha/beta/rc tags.
release = '7.0'
release = '8.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -241,7 +241,7 @@ texinfo_documents = [
#texinfo_show_urls = 'footnote'
# FIXME: Define intersphinx configration.
# FIXME: Define intersphinx configuration.
intersphinx_mapping = {}

View File

@@ -34,6 +34,7 @@ Getting Started with libc++
.. toctree::
:maxdepth: 2
ReleaseNotes
UsingLibcxx
BuildingLibcxx
TestingLibcxx
@@ -79,8 +80,8 @@ reasons, but some of the major ones are:
Platform and Compiler Support
-----------------------------
libc++ is known to work on the following platforms, using gcc-4.2 and
clang (lack of C++11 language support disables some functionality).
libc++ is known to work on the following platforms, using gcc and
clang.
Note that functionality provided by ``<atomic>`` is only functional with clang
and GCC.
@@ -104,7 +105,7 @@ C++ Dialect Support
* C++11 - Complete
* `C++14 - Complete <http://libcxx.llvm.org/cxx1y_status.html>`__
* `C++1z - In Progress <http://libcxx.llvm.org/cxx1z_status.html>`__
* `C++17 - In Progress <http://libcxx.llvm.org/cxx1z_status.html>`__
* `Post C++14 Technical Specifications - In Progress <http://libcxx.llvm.org/ts1z_status.html>`__
Notes and Known Issues
@@ -134,6 +135,7 @@ Design Documents
DesignDocs/ABIVersioning
DesignDocs/VisibilityMacros
DesignDocs/ThreadingSupportAPI
DesignDocs/FileTimeType
* `<atomic> design <http://libcxx.llvm.org/atomic_design.html>`_
* `<type_traits> design <http://libcxx.llvm.org/type_traits_design.html>`_
@@ -159,21 +161,18 @@ and `Getting started with LLVM <http://llvm.org/docs/GettingStarted.html>`__.
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 `cfe-dev mailing list`_ or on IRC.
Please include "libc++" in your subject.
can post a message to the `libcxx-dev mailing list`_ or on IRC.
**Patches**
If you want to contribute a patch to libc++, the best place for that is
`Phabricator <http://llvm.org/docs/Phabricator.html>`_. Please include [libcxx] in the subject and
add `cfe-commits` as a subscriber. Also make sure you are subscribed to the
`cfe-commits mailing list <http://lists.llvm.org/mailman/listinfo/cfe-commits>`_.
`Phabricator <http://llvm.org/docs/Phabricator.html>`_. Please add `libcxx-commits` as a subscriber.
Also make sure you are subscribed to the `libcxx-commits mailing list <http://lists.llvm.org/mailman/listinfo/libcxx-commits>`_.
**Discussion and Questions**
Send discussions and questions to the
`cfe-dev mailing list <http://lists.llvm.org/mailman/listinfo/cfe-dev>`_.
Please include [libcxx] in the subject.
`libcxx-dev mailing list <http://lists.llvm.org/mailman/listinfo/libcxx-dev>`_.
@@ -182,7 +181,7 @@ Quick Links
* `LLVM Homepage <http://llvm.org/>`_
* `libc++abi Homepage <http://libcxxabi.llvm.org/>`_
* `LLVM Bugzilla <https://bugs.llvm.org/>`_
* `cfe-commits Mailing List`_
* `cfe-dev Mailing List`_
* `libcxx-commits Mailing List`_
* `libcxx-dev Mailing List`_
* `Browse libc++ -- SVN <http://llvm.org/svn/llvm-project/libcxx/trunk/>`_
* `Browse libc++ -- ViewVC <http://llvm.org/viewvc/llvm-project/libcxx/trunk/>`_

View File

@@ -8,18 +8,18 @@
//
//===----------------------------------------------------------------------===//
// A set of routines to use when fuzzing the algorithms in libc++
// Each one tests a single algorithm.
// A set of routines to use when fuzzing the algorithms in libc++
// Each one tests a single algorithm.
//
// They all have the form of:
// int `algorithm`(const uint8_t *data, size_t size);
// They all have the form of:
// int `algorithm`(const uint8_t *data, size_t size);
//
// They perform the operation, and then check to see if the results are correct.
// If so, they return zero, and non-zero otherwise.
// They perform the operation, and then check to see if the results are correct.
// If so, they return zero, and non-zero otherwise.
//
// For example, sort calls std::sort, then checks two things:
// (1) The resulting vector is sorted
// (2) The resulting vector contains the same elements as the original data.
// For example, sort calls std::sort, then checks two things:
// (1) The resulting vector is sorted
// (2) The resulting vector contains the same elements as the original data.
@@ -32,574 +32,587 @@
#include <iostream>
// If we had C++14, we could use the four iterator version of is_permutation and equal
// If we had C++14, we could use the four iterator version of is_permutation and equal
namespace fuzzing {
// This is a struct we can use to test the stable_XXX algorithms.
// perform the operation on the key, then check the order of the payload.
// This is a struct we can use to test the stable_XXX algorithms.
// perform the operation on the key, then check the order of the payload.
struct stable_test {
uint8_t key;
size_t payload;
stable_test(uint8_t k) : key(k), payload(0) {}
stable_test(uint8_t k, size_t p) : key(k), payload(p) {}
};
uint8_t key;
size_t payload;
stable_test(uint8_t k) : key(k), payload(0) {}
stable_test(uint8_t k, size_t p) : key(k), payload(p) {}
};
void swap(stable_test &lhs, stable_test &rhs)
{
using std::swap;
swap(lhs.key, rhs.key);
swap(lhs.payload, rhs.payload);
using std::swap;
swap(lhs.key, rhs.key);
swap(lhs.payload, rhs.payload);
}
struct key_less
{
bool operator () (const stable_test &lhs, const stable_test &rhs) const
{
return lhs.key < rhs.key;
}
bool operator () (const stable_test &lhs, const stable_test &rhs) const
{
return lhs.key < rhs.key;
}
};
struct payload_less
{
bool operator () (const stable_test &lhs, const stable_test &rhs) const
{
return lhs.payload < rhs.payload;
}
bool operator () (const stable_test &lhs, const stable_test &rhs) const
{
return lhs.payload < rhs.payload;
}
};
struct total_less
{
bool operator () (const stable_test &lhs, const stable_test &rhs) const
{
return lhs.key == rhs.key ? lhs.payload < rhs.payload : lhs.key < rhs.key;
}
bool operator () (const stable_test &lhs, const stable_test &rhs) const
{
return lhs.key == rhs.key ? lhs.payload < rhs.payload : lhs.key < rhs.key;
}
};
bool operator==(const stable_test &lhs, const stable_test &rhs)
{
return lhs.key == rhs.key && lhs.payload == rhs.payload;
{
return lhs.key == rhs.key && lhs.payload == rhs.payload;
}
template<typename T>
struct is_even
{
bool operator () (const T &t) const
{
return t % 2 == 0;
}
bool operator () (const T &t) const
{
return t % 2 == 0;
}
};
template<>
struct is_even<stable_test>
{
bool operator () (const stable_test &t) const
{
return t.key % 2 == 0;
}
bool operator () (const stable_test &t) const
{
return t.key % 2 == 0;
}
};
typedef std::vector<uint8_t> Vec;
typedef std::vector<stable_test> StableVec;
typedef StableVec::const_iterator SVIter;
// Cheap version of is_permutation
// Builds a set of buckets for each of the key values.
// Sums all the payloads.
// Not 100% perfect, but _way_ faster
// Cheap version of is_permutation
// Builds a set of buckets for each of the key values.
// Sums all the payloads.
// Not 100% perfect, but _way_ faster
bool is_permutation(SVIter first1, SVIter last1, SVIter first2)
{
size_t xBuckets[256] = {0};
size_t xPayloads[256] = {0};
size_t yBuckets[256] = {0};
size_t yPayloads[256] = {0};
for (; first1 != last1; ++first1, ++first2)
{
xBuckets [first1->key]++;
xPayloads[first1->key] += first1->payload;
size_t xBuckets[256] = {0};
size_t xPayloads[256] = {0};
size_t yBuckets[256] = {0};
size_t yPayloads[256] = {0};
yBuckets [first2->key]++;
yPayloads[first2->key] += first2->payload;
}
for (size_t i = 0; i < 256; ++i)
{
if (xBuckets[i] != yBuckets[i])
return false;
if (xPayloads[i] != yPayloads[i])
return false;
}
for (; first1 != last1; ++first1, ++first2)
{
xBuckets [first1->key]++;
xPayloads[first1->key] += first1->payload;
return true;
yBuckets [first2->key]++;
yPayloads[first2->key] += first2->payload;
}
for (size_t i = 0; i < 256; ++i)
{
if (xBuckets[i] != yBuckets[i])
return false;
if (xPayloads[i] != yPayloads[i])
return false;
}
return true;
}
template <typename Iter1, typename Iter2>
bool is_permutation(Iter1 first1, Iter1 last1, Iter2 first2)
{
static_assert((std::is_same<typename std::iterator_traits<Iter1>::value_type, uint8_t>::value), "");
static_assert((std::is_same<typename std::iterator_traits<Iter2>::value_type, uint8_t>::value), "");
size_t xBuckets[256] = {0};
size_t yBuckets[256] = {0};
for (; first1 != last1; ++first1, ++first2)
{
xBuckets [*first1]++;
yBuckets [*first2]++;
}
for (size_t i = 0; i < 256; ++i)
if (xBuckets[i] != yBuckets[i])
return false;
static_assert((std::is_same<typename std::iterator_traits<Iter1>::value_type, uint8_t>::value), "");
static_assert((std::is_same<typename std::iterator_traits<Iter2>::value_type, uint8_t>::value), "");
return true;
size_t xBuckets[256] = {0};
size_t yBuckets[256] = {0};
for (; first1 != last1; ++first1, ++first2)
{
xBuckets [*first1]++;
yBuckets [*first2]++;
}
for (size_t i = 0; i < 256; ++i)
if (xBuckets[i] != yBuckets[i])
return false;
return true;
}
// == sort ==
// == sort ==
int sort(const uint8_t *data, size_t size)
{
Vec working(data, data + size);
std::sort(working.begin(), working.end());
Vec working(data, data + size);
std::sort(working.begin(), working.end());
if (!std::is_sorted(working.begin(), working.end())) return 1;
if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
if (!std::is_sorted(working.begin(), working.end())) return 1;
if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
}
// == stable_sort ==
// == stable_sort ==
int stable_sort(const uint8_t *data, size_t size)
{
StableVec input;
for (size_t i = 0; i < size; ++i)
input.push_back(stable_test(data[i], i));
StableVec working = input;
std::stable_sort(working.begin(), working.end(), key_less());
StableVec input;
for (size_t i = 0; i < size; ++i)
input.push_back(stable_test(data[i], i));
StableVec working = input;
std::stable_sort(working.begin(), working.end(), key_less());
if (!std::is_sorted(working.begin(), working.end(), key_less())) return 1;
auto iter = working.begin();
while (iter != working.end())
{
auto range = std::equal_range(iter, working.end(), *iter, key_less());
if (!std::is_sorted(range.first, range.second, total_less())) return 2;
iter = range.second;
}
if (!fuzzing::is_permutation(input.cbegin(), input.cend(), working.cbegin())) return 99;
return 0;
if (!std::is_sorted(working.begin(), working.end(), key_less())) return 1;
auto iter = working.begin();
while (iter != working.end())
{
auto range = std::equal_range(iter, working.end(), *iter, key_less());
if (!std::is_sorted(range.first, range.second, total_less())) return 2;
iter = range.second;
}
if (!fuzzing::is_permutation(input.cbegin(), input.cend(), working.cbegin())) return 99;
return 0;
}
// == partition ==
// == partition ==
int partition(const uint8_t *data, size_t size)
{
Vec working(data, data + size);
auto iter = std::partition(working.begin(), working.end(), is_even<uint8_t>());
Vec working(data, data + size);
auto iter = std::partition(working.begin(), working.end(), is_even<uint8_t>());
if (!std::all_of (working.begin(), iter, is_even<uint8_t>())) return 1;
if (!std::none_of(iter, working.end(), is_even<uint8_t>())) return 2;
if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
if (!std::all_of (working.begin(), iter, is_even<uint8_t>())) return 1;
if (!std::none_of(iter, working.end(), is_even<uint8_t>())) return 2;
if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
}
// == partition_copy ==
// == partition_copy ==
int partition_copy(const uint8_t *data, size_t size)
{
Vec v1, v2;
auto iter = std::partition_copy(data, data + size,
std::back_inserter<Vec>(v1), std::back_inserter<Vec>(v2),
is_even<uint8_t>());
Vec v1, v2;
auto iter = std::partition_copy(data, data + size,
std::back_inserter<Vec>(v1), std::back_inserter<Vec>(v2),
is_even<uint8_t>());
// The two vectors should add up to the original size
if (v1.size() + v2.size() != size) return 1;
// The two vectors should add up to the original size
if (v1.size() + v2.size() != size) return 1;
// All of the even values should be in the first vector, and none in the second
if (!std::all_of (v1.begin(), v1.end(), is_even<uint8_t>())) return 2;
if (!std::none_of(v2.begin(), v2.end(), is_even<uint8_t>())) return 3;
// All of the even values should be in the first vector, and none in the second
if (!std::all_of (v1.begin(), v1.end(), is_even<uint8_t>())) return 2;
if (!std::none_of(v2.begin(), v2.end(), is_even<uint8_t>())) return 3;
// Every value in both vectors has to be in the original
for (auto v: v1)
if (std::find(data, data + size, v) == data + size) return 4;
for (auto v: v2)
if (std::find(data, data + size, v) == data + size) return 5;
return 0;
// Every value in both vectors has to be in the original
// Make a copy of the input, and sort it
Vec v0{data, data + size};
std::sort(v0.begin(), v0.end());
// Sort each vector and ensure that all of the elements appear in the original input
std::sort(v1.begin(), v1.end());
if (!std::includes(v0.begin(), v0.end(), v1.begin(), v1.end())) return 4;
std::sort(v2.begin(), v2.end());
if (!std::includes(v0.begin(), v0.end(), v2.begin(), v2.end())) return 5;
// This, while simple, is really slow - 20 seconds on a 500K element input.
// for (auto v: v1)
// if (std::find(data, data + size, v) == data + size) return 4;
//
// for (auto v: v2)
// if (std::find(data, data + size, v) == data + size) return 5;
return 0;
}
// == stable_partition ==
// == stable_partition ==
int stable_partition (const uint8_t *data, size_t size)
{
StableVec input;
for (size_t i = 0; i < size; ++i)
input.push_back(stable_test(data[i], i));
StableVec working = input;
auto iter = std::stable_partition(working.begin(), working.end(), is_even<stable_test>());
StableVec input;
for (size_t i = 0; i < size; ++i)
input.push_back(stable_test(data[i], i));
StableVec working = input;
auto iter = std::stable_partition(working.begin(), working.end(), is_even<stable_test>());
if (!std::all_of (working.begin(), iter, is_even<stable_test>())) return 1;
if (!std::none_of(iter, working.end(), is_even<stable_test>())) return 2;
if (!std::is_sorted(working.begin(), iter, payload_less())) return 3;
if (!std::is_sorted(iter, working.end(), payload_less())) return 4;
if (!fuzzing::is_permutation(input.cbegin(), input.cend(), working.cbegin())) return 99;
return 0;
if (!std::all_of (working.begin(), iter, is_even<stable_test>())) return 1;
if (!std::none_of(iter, working.end(), is_even<stable_test>())) return 2;
if (!std::is_sorted(working.begin(), iter, payload_less())) return 3;
if (!std::is_sorted(iter, working.end(), payload_less())) return 4;
if (!fuzzing::is_permutation(input.cbegin(), input.cend(), working.cbegin())) return 99;
return 0;
}
// == nth_element ==
// use the first element as a position into the data
// == nth_element ==
// use the first element as a position into the data
int nth_element (const uint8_t *data, size_t size)
{
if (size <= 1) return 0;
const size_t partition_point = data[0] % size;
Vec working(data + 1, data + size);
const auto partition_iter = working.begin() + partition_point;
std::nth_element(working.begin(), partition_iter, working.end());
if (size <= 1) return 0;
const size_t partition_point = data[0] % size;
Vec working(data + 1, data + size);
const auto partition_iter = working.begin() + partition_point;
std::nth_element(working.begin(), partition_iter, working.end());
// nth may be the end iterator, in this case nth_element has no effect.
if (partition_iter == working.end())
{
if (!std::equal(data + 1, data + size, working.begin())) return 98;
}
else
{
const uint8_t nth = *partition_iter;
if (!std::all_of(working.begin(), partition_iter, [=](uint8_t v) { return v <= nth; }))
return 1;
if (!std::all_of(partition_iter, working.end(), [=](uint8_t v) { return v >= nth; }))
return 2;
if (!fuzzing::is_permutation(data + 1, data + size, working.cbegin())) return 99;
}
// nth may be the end iterator, in this case nth_element has no effect.
if (partition_iter == working.end())
{
if (!std::equal(data + 1, data + size, working.begin())) return 98;
}
else
{
const uint8_t nth = *partition_iter;
if (!std::all_of(working.begin(), partition_iter, [=](uint8_t v) { return v <= nth; }))
return 1;
if (!std::all_of(partition_iter, working.end(), [=](uint8_t v) { return v >= nth; }))
return 2;
if (!fuzzing::is_permutation(data + 1, data + size, working.cbegin())) return 99;
}
return 0;
return 0;
}
// == partial_sort ==
// use the first element as a position into the data
// == partial_sort ==
// use the first element as a position into the data
int partial_sort (const uint8_t *data, size_t size)
{
if (size <= 1) return 0;
const size_t sort_point = data[0] % size;
Vec working(data + 1, data + size);
const auto sort_iter = working.begin() + sort_point;
std::partial_sort(working.begin(), sort_iter, working.end());
if (size <= 1) return 0;
const size_t sort_point = data[0] % size;
Vec working(data + 1, data + size);
const auto sort_iter = working.begin() + sort_point;
std::partial_sort(working.begin(), sort_iter, working.end());
if (sort_iter != working.end())
{
const uint8_t nth = *std::min_element(sort_iter, working.end());
if (!std::all_of(working.begin(), sort_iter, [=](uint8_t v) { return v <= nth; }))
return 1;
if (!std::all_of(sort_iter, working.end(), [=](uint8_t v) { return v >= nth; }))
return 2;
}
if (!std::is_sorted(working.begin(), sort_iter)) return 3;
if (!fuzzing::is_permutation(data + 1, data + size, working.cbegin())) return 99;
if (sort_iter != working.end())
{
const uint8_t nth = *std::min_element(sort_iter, working.end());
if (!std::all_of(working.begin(), sort_iter, [=](uint8_t v) { return v <= nth; }))
return 1;
if (!std::all_of(sort_iter, working.end(), [=](uint8_t v) { return v >= nth; }))
return 2;
}
if (!std::is_sorted(working.begin(), sort_iter)) return 3;
if (!fuzzing::is_permutation(data + 1, data + size, working.cbegin())) return 99;
return 0;
return 0;
}
// == partial_sort_copy ==
// use the first element as a count
// == partial_sort_copy ==
// use the first element as a count
int partial_sort_copy (const uint8_t *data, size_t size)
{
if (size <= 1) return 0;
const size_t num_results = data[0] % size;
Vec results(num_results);
(void) std::partial_sort_copy(data + 1, data + size, results.begin(), results.end());
if (size <= 1) return 0;
const size_t num_results = data[0] % size;
Vec results(num_results);
(void) std::partial_sort_copy(data + 1, data + size, results.begin(), results.end());
// The results have to be sorted
if (!std::is_sorted(results.begin(), results.end())) return 1;
// All the values in results have to be in the original data
for (auto v: results)
if (std::find(data + 1, data + size, v) == data + size) return 2;
// The results have to be sorted
if (!std::is_sorted(results.begin(), results.end())) return 1;
// All the values in results have to be in the original data
for (auto v: results)
if (std::find(data + 1, data + size, v) == data + size) return 2;
// The things in results have to be the smallest N in the original data
Vec sorted(data + 1, data + size);
std::sort(sorted.begin(), sorted.end());
if (!std::equal(results.begin(), results.end(), sorted.begin())) return 3;
return 0;
// The things in results have to be the smallest N in the original data
Vec sorted(data + 1, data + size);
std::sort(sorted.begin(), sorted.end());
if (!std::equal(results.begin(), results.end(), sorted.begin())) return 3;
return 0;
}
// The second sequence has been "uniqued"
// The second sequence has been "uniqued"
template <typename Iter1, typename Iter2>
static bool compare_unique(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2)
{
assert(first1 != last1 && first2 != last2);
if (*first1 != *first2) return false;
assert(first1 != last1 && first2 != last2);
if (*first1 != *first2) return false;
uint8_t last_value = *first1;
++first1; ++first2;
while(first1 != last1 && first2 != last2)
{
// Skip over dups in the first sequence
while (*first1 == last_value)
if (++first1 == last1) return false;
if (*first1 != *first2) return false;
last_value = *first1;
++first1; ++first2;
}
uint8_t last_value = *first1;
++first1; ++first2;
while(first1 != last1 && first2 != last2)
{
// Skip over dups in the first sequence
while (*first1 == last_value)
if (++first1 == last1) return false;
if (*first1 != *first2) return false;
last_value = *first1;
++first1; ++first2;
}
// Still stuff left in the 'uniqued' sequence - oops
if (first1 == last1 && first2 != last2) return false;
// Still stuff left in the 'uniqued' sequence - oops
if (first1 == last1 && first2 != last2) return false;
// Still stuff left in the original sequence - better be all the same
while (first1 != last1)
{
if (*first1 != last_value) return false;
++first1;
}
return true;
// Still stuff left in the original sequence - better be all the same
while (first1 != last1)
{
if (*first1 != last_value) return false;
++first1;
}
return true;
}
// == unique ==
// == unique ==
int unique (const uint8_t *data, size_t size)
{
Vec working(data, data + size);
std::sort(working.begin(), working.end());
Vec results = working;
Vec::iterator new_end = std::unique(results.begin(), results.end());
Vec::iterator it; // scratch iterator
// Check the size of the unique'd sequence.
// it should only be zero if the input sequence was empty.
if (results.begin() == new_end)
return working.size() == 0 ? 0 : 1;
// 'results' is sorted
if (!std::is_sorted(results.begin(), new_end)) return 2;
Vec working(data, data + size);
std::sort(working.begin(), working.end());
Vec results = working;
Vec::iterator new_end = std::unique(results.begin(), results.end());
Vec::iterator it; // scratch iterator
// All the elements in 'results' must be different
it = results.begin();
uint8_t prev_value = *it++;
for (; it != new_end; ++it)
{
if (*it == prev_value) return 3;
prev_value = *it;
}
// Every element in 'results' must be in 'working'
for (it = results.begin(); it != new_end; ++it)
if (std::find(working.begin(), working.end(), *it) == working.end())
return 4;
// Every element in 'working' must be in 'results'
for (auto v : working)
if (std::find(results.begin(), new_end, v) == new_end)
return 5;
return 0;
// Check the size of the unique'd sequence.
// it should only be zero if the input sequence was empty.
if (results.begin() == new_end)
return working.size() == 0 ? 0 : 1;
// 'results' is sorted
if (!std::is_sorted(results.begin(), new_end)) return 2;
// All the elements in 'results' must be different
it = results.begin();
uint8_t prev_value = *it++;
for (; it != new_end; ++it)
{
if (*it == prev_value) return 3;
prev_value = *it;
}
// Every element in 'results' must be in 'working'
for (it = results.begin(); it != new_end; ++it)
if (std::find(working.begin(), working.end(), *it) == working.end())
return 4;
// Every element in 'working' must be in 'results'
for (auto v : working)
if (std::find(results.begin(), new_end, v) == new_end)
return 5;
return 0;
}
// == unique_copy ==
// == unique_copy ==
int unique_copy (const uint8_t *data, size_t size)
{
Vec working(data, data + size);
std::sort(working.begin(), working.end());
Vec results;
(void) std::unique_copy(working.begin(), working.end(),
std::back_inserter<Vec>(results));
Vec::iterator it; // scratch iterator
// Check the size of the unique'd sequence.
// it should only be zero if the input sequence was empty.
if (results.size() == 0)
return working.size() == 0 ? 0 : 1;
// 'results' is sorted
if (!std::is_sorted(results.begin(), results.end())) return 2;
Vec working(data, data + size);
std::sort(working.begin(), working.end());
Vec results;
(void) std::unique_copy(working.begin(), working.end(),
std::back_inserter<Vec>(results));
Vec::iterator it; // scratch iterator
// All the elements in 'results' must be different
it = results.begin();
uint8_t prev_value = *it++;
for (; it != results.end(); ++it)
{
if (*it == prev_value) return 3;
prev_value = *it;
}
// Every element in 'results' must be in 'working'
for (auto v : results)
if (std::find(working.begin(), working.end(), v) == working.end())
return 4;
// Every element in 'working' must be in 'results'
for (auto v : working)
if (std::find(results.begin(), results.end(), v) == results.end())
return 5;
return 0;
// Check the size of the unique'd sequence.
// it should only be zero if the input sequence was empty.
if (results.size() == 0)
return working.size() == 0 ? 0 : 1;
// 'results' is sorted
if (!std::is_sorted(results.begin(), results.end())) return 2;
// All the elements in 'results' must be different
it = results.begin();
uint8_t prev_value = *it++;
for (; it != results.end(); ++it)
{
if (*it == prev_value) return 3;
prev_value = *it;
}
// Every element in 'results' must be in 'working'
for (auto v : results)
if (std::find(working.begin(), working.end(), v) == working.end())
return 4;
// Every element in 'working' must be in 'results'
for (auto v : working)
if (std::find(results.begin(), results.end(), v) == results.end())
return 5;
return 0;
}
// -- regex fuzzers
// -- regex fuzzers
static int regex_helper(const uint8_t *data, size_t size, std::regex::flag_type flag)
{
if (size > 0)
{
try
{
std::string s((const char *)data, size);
std::regex re(s, flag);
return std::regex_match(s, re) ? 1 : 0;
}
catch (std::regex_error &ex) {}
}
return 0;
if (size > 0)
{
try
{
std::string s((const char *)data, size);
std::regex re(s, flag);
return std::regex_match(s, re) ? 1 : 0;
}
catch (std::regex_error &ex) {}
}
return 0;
}
int regex_ECMAScript (const uint8_t *data, size_t size)
{
(void) regex_helper(data, size, std::regex_constants::ECMAScript);
return 0;
(void) regex_helper(data, size, std::regex_constants::ECMAScript);
return 0;
}
int regex_POSIX (const uint8_t *data, size_t size)
{
(void) regex_helper(data, size, std::regex_constants::basic);
return 0;
(void) regex_helper(data, size, std::regex_constants::basic);
return 0;
}
int regex_extended (const uint8_t *data, size_t size)
{
(void) regex_helper(data, size, std::regex_constants::extended);
return 0;
(void) regex_helper(data, size, std::regex_constants::extended);
return 0;
}
int regex_awk (const uint8_t *data, size_t size)
{
(void) regex_helper(data, size, std::regex_constants::awk);
return 0;
(void) regex_helper(data, size, std::regex_constants::awk);
return 0;
}
int regex_grep (const uint8_t *data, size_t size)
{
(void) regex_helper(data, size, std::regex_constants::grep);
return 0;
(void) regex_helper(data, size, std::regex_constants::grep);
return 0;
}
int regex_egrep (const uint8_t *data, size_t size)
{
(void) regex_helper(data, size, std::regex_constants::egrep);
return 0;
(void) regex_helper(data, size, std::regex_constants::egrep);
return 0;
}
// -- heap fuzzers
// -- heap fuzzers
int make_heap (const uint8_t *data, size_t size)
{
Vec working(data, data + size);
std::make_heap(working.begin(), working.end());
Vec working(data, data + size);
std::make_heap(working.begin(), working.end());
if (!std::is_heap(working.begin(), working.end())) return 1;
if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
if (!std::is_heap(working.begin(), working.end())) return 1;
if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
}
int push_heap (const uint8_t *data, size_t size)
{
if (size < 2) return 0;
if (size < 2) return 0;
// Make a heap from the first half of the data
Vec working(data, data + size);
auto iter = working.begin() + (size / 2);
std::make_heap(working.begin(), iter);
if (!std::is_heap(working.begin(), iter)) return 1;
// Make a heap from the first half of the data
Vec working(data, data + size);
auto iter = working.begin() + (size / 2);
std::make_heap(working.begin(), iter);
if (!std::is_heap(working.begin(), iter)) return 1;
// Now push the rest onto the heap, one at a time
++iter;
for (; iter != working.end(); ++iter) {
std::push_heap(working.begin(), iter);
if (!std::is_heap(working.begin(), iter)) return 2;
}
// Now push the rest onto the heap, one at a time
++iter;
for (; iter != working.end(); ++iter) {
std::push_heap(working.begin(), iter);
if (!std::is_heap(working.begin(), iter)) return 2;
}
if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
}
int pop_heap (const uint8_t *data, size_t size)
{
if (size < 2) return 0;
Vec working(data, data + size);
std::make_heap(working.begin(), working.end());
if (size < 2) return 0;
Vec working(data, data + size);
std::make_heap(working.begin(), working.end());
// Pop things off, one at a time
auto iter = --working.end();
while (iter != working.begin()) {
std::pop_heap(working.begin(), iter);
if (!std::is_heap(working.begin(), --iter)) return 2;
}
// Pop things off, one at a time
auto iter = --working.end();
while (iter != working.begin()) {
std::pop_heap(working.begin(), iter);
if (!std::is_heap(working.begin(), --iter)) return 2;
}
return 0;
return 0;
}
// -- search fuzzers
// -- search fuzzers
int search (const uint8_t *data, size_t size)
{
if (size < 2) return 0;
const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::max();
assert(pat_size <= size - 1);
const uint8_t *pat_begin = data + 1;
const uint8_t *pat_end = pat_begin + pat_size;
const uint8_t *data_end = data + size;
assert(pat_end <= data_end);
// std::cerr << "data[0] = " << size_t(data[0]) << " ";
// std::cerr << "Pattern size = " << pat_size << "; corpus is " << size - 1 << std::endl;
auto it = std::search(pat_end, data_end, pat_begin, pat_end);
if (it != data_end) // not found
if (!std::equal(pat_begin, pat_end, it))
return 1;
return 0;
if (size < 2) return 0;
const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::max();
assert(pat_size <= size - 1);
const uint8_t *pat_begin = data + 1;
const uint8_t *pat_end = pat_begin + pat_size;
const uint8_t *data_end = data + size;
assert(pat_end <= data_end);
// std::cerr << "data[0] = " << size_t(data[0]) << " ";
// std::cerr << "Pattern size = " << pat_size << "; corpus is " << size - 1 << std::endl;
auto it = std::search(pat_end, data_end, pat_begin, pat_end);
if (it != data_end) // not found
if (!std::equal(pat_begin, pat_end, it))
return 1;
return 0;
}
template <typename S>
static int search_helper (const uint8_t *data, size_t size)
{
if (size < 2) return 0;
const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::max();
const uint8_t *pat_begin = data + 1;
const uint8_t *pat_end = pat_begin + pat_size;
const uint8_t *data_end = data + size;
if (size < 2) return 0;
auto it = std::search(pat_end, data_end, S(pat_begin, pat_end));
if (it != data_end) // not found
if (!std::equal(pat_begin, pat_end, it))
return 1;
return 0;
const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::max();
const uint8_t *pat_begin = data + 1;
const uint8_t *pat_end = pat_begin + pat_size;
const uint8_t *data_end = data + size;
auto it = std::search(pat_end, data_end, S(pat_begin, pat_end));
if (it != data_end) // not found
if (!std::equal(pat_begin, pat_end, it))
return 1;
return 0;
}
// These are still in std::experimental
// These are still in std::experimental
// int search_boyer_moore (const uint8_t *data, size_t size)
// {
// return search_helper<std::boyer_moore_searcher<const uint8_t *>>(data, size);
// return search_helper<std::boyer_moore_searcher<const uint8_t *>>(data, size);
// }
//
//
// int search_boyer_moore_horspool (const uint8_t *data, size_t size)
// {
// return search_helper<std::boyer_moore_horspool_searcher<const uint8_t *>>(data, size);
// return search_helper<std::boyer_moore_horspool_searcher<const uint8_t *>>(data, size);
// }
// -- set operation fuzzers
// -- set operation fuzzers
template <typename S>
static void set_helper (const uint8_t *data, size_t size, Vec &v1, Vec &v2)
{
assert(size > 1);
const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::max();
const uint8_t *pat_begin = data + 1;
const uint8_t *pat_end = pat_begin + pat_size;
const uint8_t *data_end = data + size;
v1.assign(pat_begin, pat_end);
v2.assign(pat_end, data_end);
assert(size > 1);
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::max();
const uint8_t *pat_begin = data + 1;
const uint8_t *pat_end = pat_begin + pat_size;
const uint8_t *data_end = data + size;
v1.assign(pat_begin, pat_end);
v2.assign(pat_end, data_end);
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
}
} // namespace fuzzing

View File

@@ -2,6 +2,7 @@ set(files
__bit_reference
__bsd_locale_defaults.h
__bsd_locale_fallbacks.h
__errc
__debug
__functional_03
__functional_base
@@ -10,6 +11,7 @@ set(files
__libcpp_version
__locale
__mutex_base
__node_handle
__nullptr
__split_buffer
__sso_allocator
@@ -23,6 +25,7 @@ set(files
any
array
atomic
bit
bitset
cassert
ccomplex
@@ -30,6 +33,7 @@ set(files
cerrno
cfenv
cfloat
charconv
chrono
cinttypes
ciso646
@@ -65,7 +69,6 @@ set(files
experimental/chrono
experimental/coroutine
experimental/deque
experimental/dynarray
experimental/filesystem
experimental/forward_list
experimental/functional
@@ -92,6 +95,7 @@ set(files
ext/__hash
ext/hash_map
ext/hash_set
filesystem
float.h
forward_list
fstream
@@ -127,6 +131,7 @@ set(files
set
setjmp.h
shared_mutex
span
sstream
stack
stdbool.h
@@ -203,8 +208,8 @@ else()
)
endif()
if(NOT LIBCXX_USING_INSTALLED_LLVM AND LLVM_BINARY_DIR)
set(output_dir ${LLVM_BINARY_DIR}/include/c++/v1)
if(NOT LIBCXX_USING_INSTALLED_LLVM AND LIBCXX_HEADER_DIR)
set(output_dir ${LIBCXX_HEADER_DIR}/include/c++/v1)
set(out_files)
foreach(f ${files})
@@ -228,17 +233,17 @@ if(NOT LIBCXX_USING_INSTALLED_LLVM AND LLVM_BINARY_DIR)
list(APPEND out_files ${dst})
endif()
add_custom_target(cxx_headers ALL DEPENDS ${out_files} ${LIBCXX_CXX_ABI_HEADER_TARGET})
add_custom_target(cxx-headers ALL DEPENDS ${out_files} ${LIBCXX_CXX_ABI_HEADER_TARGET})
else()
add_custom_target(cxx_headers)
add_custom_target(cxx-headers)
endif()
set_target_properties(cxx_headers PROPERTIES FOLDER "Misc")
set_target_properties(cxx-headers PROPERTIES FOLDER "Misc")
if (LIBCXX_INSTALL_HEADERS)
foreach(file ${files})
get_filename_component(dir ${file} DIRECTORY)
install(FILES ${file}
DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1/${dir}
DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1/${dir}
COMPONENT cxx-headers
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
)
@@ -247,7 +252,7 @@ if (LIBCXX_INSTALL_HEADERS)
if (LIBCXX_NEEDS_SITE_CONFIG)
# Install the generated header as __config.
install(FILES ${LIBCXX_BINARY_DIR}/__generated_config
DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1
DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
RENAME __config
COMPONENT cxx-headers)

View File

@@ -12,6 +12,7 @@
#define _LIBCPP___BIT_REFERENCE
#include <__config>
#include <bit>
#include <algorithm>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -254,18 +255,18 @@ __count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type
__storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
__storage_type __dn = _VSTD::min(__clz_f, __n);
__storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
__r = _VSTD::__pop_count(*__first.__seg_ & __m);
__r = _VSTD::__popcount(*__first.__seg_ & __m);
__n -= __dn;
++__first.__seg_;
}
// do middle whole words
for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
__r += _VSTD::__pop_count(*__first.__seg_);
__r += _VSTD::__popcount(*__first.__seg_);
// do last partial word
if (__n > 0)
{
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
__r += _VSTD::__pop_count(*__first.__seg_ & __m);
__r += _VSTD::__popcount(*__first.__seg_ & __m);
}
return __r;
}
@@ -285,18 +286,18 @@ __count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_typ
__storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
__storage_type __dn = _VSTD::min(__clz_f, __n);
__storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
__r = _VSTD::__pop_count(~*__first.__seg_ & __m);
__r = _VSTD::__popcount(~*__first.__seg_ & __m);
__n -= __dn;
++__first.__seg_;
}
// do middle whole words
for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
__r += _VSTD::__pop_count(~*__first.__seg_);
__r += _VSTD::__popcount(~*__first.__seg_);
// do last partial word
if (__n > 0)
{
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
__r += _VSTD::__pop_count(~*__first.__seg_ & __m);
__r += _VSTD::__popcount(~*__first.__seg_ & __m);
}
return __r;
}

View File

@@ -24,28 +24,28 @@
_LIBCPP_BEGIN_NAMESPACE_STD
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l)
{
__libcpp_locale_guard __current(__l);
return MB_CUR_MAX;
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
wint_t __libcpp_btowc_l(int __c, locale_t __l)
{
__libcpp_locale_guard __current(__l);
return btowc(__c);
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
int __libcpp_wctob_l(wint_t __c, locale_t __l)
{
__libcpp_locale_guard __current(__l);
return wctob(__c);
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
size_t __len, mbstate_t *__ps, locale_t __l)
{
@@ -53,14 +53,14 @@ size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
{
__libcpp_locale_guard __current(__l);
return wcrtomb(__s, __wc, __ps);
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
size_t __len, mbstate_t *__ps, locale_t __l)
{
@@ -68,7 +68,7 @@ size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
mbstate_t *__ps, locale_t __l)
{
@@ -76,28 +76,28 @@ size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
return mbrtowc(__pwc, __s, __n, __ps);
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
{
__libcpp_locale_guard __current(__l);
return mbtowc(__pwc, __pmb, __max);
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
{
__libcpp_locale_guard __current(__l);
return mbrlen(__s, __n, __ps);
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
lconv *__libcpp_localeconv_l(locale_t __l)
{
__libcpp_locale_guard __current(__l);
return localeconv();
}
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
mbstate_t *__ps, locale_t __l)
{

View File

@@ -33,16 +33,24 @@
# define _GNUC_VER_NEW 0
#endif
#define _LIBCPP_VERSION 7000
#define _LIBCPP_VERSION 8000
#ifndef _LIBCPP_ABI_VERSION
# ifdef __Fuchsia__
# define _LIBCPP_ABI_VERSION 2
# else
# define _LIBCPP_ABI_VERSION 1
# endif
# define _LIBCPP_ABI_VERSION 1
#endif
#ifndef _LIBCPP_STD_VER
# if __cplusplus <= 201103L
# define _LIBCPP_STD_VER 11
# elif __cplusplus <= 201402L
# define _LIBCPP_STD_VER 14
# elif __cplusplus <= 201703L
# define _LIBCPP_STD_VER 17
# else
# define _LIBCPP_STD_VER 18 // current year, or date of c++2a ratification
# endif
#endif // _LIBCPP_STD_VER
#if defined(__ELF__)
# define _LIBCPP_OBJECT_FORMAT_ELF 1
#elif defined(__MACH__)
@@ -111,7 +119,9 @@
#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y
#define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y)
#define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION)
#ifndef _LIBCPP_ABI_NAMESPACE
# define _LIBCPP_ABI_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION)
#endif
#if __cplusplus < 201103L
#define _LIBCPP_CXX03_LANG
@@ -149,10 +159,8 @@
#define __has_keyword(__x) !(__is_identifier(__x))
#ifdef __has_include
# define __libcpp_has_include(__x) __has_include(__x)
#else
# define __libcpp_has_include(__x) 0
#ifndef __has_include
#define __has_include(...) 0
#endif
#if defined(__clang__)
@@ -318,6 +326,31 @@
# define _LIBCPP_NO_CFI
#endif
#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
# if defined(__FreeBSD__)
# define _LIBCPP_HAS_QUICK_EXIT
# define _LIBCPP_HAS_C11_FEATURES
# elif defined(__Fuchsia__)
# define _LIBCPP_HAS_QUICK_EXIT
# define _LIBCPP_HAS_TIMESPEC_GET
# define _LIBCPP_HAS_C11_FEATURES
# elif defined(__linux__)
# if !defined(_LIBCPP_HAS_MUSL_LIBC)
# if _LIBCPP_GLIBC_PREREQ(2, 15) || defined(__BIONIC__)
# define _LIBCPP_HAS_QUICK_EXIT
# endif
# if _LIBCPP_GLIBC_PREREQ(2, 17)
# define _LIBCPP_HAS_C11_FEATURES
# define _LIBCPP_HAS_TIMESPEC_GET
# endif
# else // defined(_LIBCPP_HAS_MUSL_LIBC)
# define _LIBCPP_HAS_QUICK_EXIT
# define _LIBCPP_HAS_TIMESPEC_GET
# define _LIBCPP_HAS_C11_FEATURES
# endif
# endif // __linux__
#endif
#if defined(_LIBCPP_COMPILER_CLANG)
// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for
@@ -420,28 +453,6 @@ typedef __char32_t char32_t;
#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
#endif
#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
# if defined(__FreeBSD__)
# define _LIBCPP_HAS_QUICK_EXIT
# define _LIBCPP_HAS_C11_FEATURES
# elif defined(__Fuchsia__)
# define _LIBCPP_HAS_QUICK_EXIT
# define _LIBCPP_HAS_C11_FEATURES
# elif defined(__linux__)
# if !defined(_LIBCPP_HAS_MUSL_LIBC)
# if _LIBCPP_GLIBC_PREREQ(2, 15) || defined(__BIONIC__)
# define _LIBCPP_HAS_QUICK_EXIT
# endif
# if _LIBCPP_GLIBC_PREREQ(2, 17)
# define _LIBCPP_HAS_C11_FEATURES
# endif
# else // defined(_LIBCPP_HAS_MUSL_LIBC)
# define _LIBCPP_HAS_QUICK_EXIT
# define _LIBCPP_HAS_C11_FEATURES
# endif
# endif // __linux__
#endif
#if !(__has_feature(cxx_noexcept))
#define _LIBCPP_HAS_NO_NOEXCEPT
#endif
@@ -454,16 +465,6 @@ typedef __char32_t char32_t;
#define _LIBCPP_IS_LITERAL(T) __is_literal(T)
#endif
// Inline namespaces are available in Clang regardless of C++ dialect.
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD } }
#define _VSTD std::_LIBCPP_NAMESPACE
namespace std {
inline namespace _LIBCPP_NAMESPACE {
}
}
#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer)
#define _LIBCPP_HAS_NO_ASAN
#endif
@@ -481,6 +482,13 @@ namespace std {
#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS
#endif
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
// No apple compilers support ""d and ""y at this time.
#if _LIBCPP_CLANG_VER < 800 || defined(__apple_build_version__)
#define _LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS
#endif
#elif defined(_LIBCPP_COMPILER_GCC)
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
@@ -498,7 +506,7 @@ namespace std {
#define _LIBCPP_HAS_IS_BASE_OF
#endif
#if !__EXCEPTIONS
#if !__EXCEPTIONS && !defined(_LIBCPP_NO_EXCEPTIONS)
#define _LIBCPP_NO_EXCEPTIONS
#endif
@@ -551,15 +559,6 @@ namespace std {
#endif // __GXX_EXPERIMENTAL_CXX0X__
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD } }
#define _VSTD std::_LIBCPP_NAMESPACE
namespace std {
inline namespace _LIBCPP_NAMESPACE {
}
}
#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__)
#define _LIBCPP_HAS_NO_ASAN
#endif
@@ -572,6 +571,8 @@ namespace std {
#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS
#endif
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
#elif defined(_LIBCPP_COMPILER_MSVC)
#define _LIBCPP_TOSTRING2(x) #x
@@ -593,17 +594,14 @@ namespace std {
#define _ALIGNAS_TYPE(x) alignas(x)
#define _LIBCPP_HAS_NO_VARIADICS
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
#define _LIBCPP_END_NAMESPACE_STD }
#define _VSTD std
namespace std {
}
#define _LIBCPP_WEAK
#define _LIBCPP_HAS_NO_ASAN
#define _LIBCPP_ALWAYS_INLINE __forceinline
#define _LIBCPP_HAS_NO_VECTOR_EXTENSION
#elif defined(_LIBCPP_COMPILER_IBM)
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
@@ -623,17 +621,12 @@ namespace std {
#define __MULTILOCALE_API
#endif
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD } }
#define _VSTD std::_LIBCPP_NAMESPACE
namespace std {
inline namespace _LIBCPP_NAMESPACE {
}
}
#define _LIBCPP_HAS_NO_ASAN
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
#define _LIBCPP_HAS_NO_VECTOR_EXTENSION
#endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM]
#if defined(_LIBCPP_OBJECT_FORMAT_COFF)
@@ -649,37 +642,29 @@ namespace std {
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
# define _LIBCPP_OVERRIDABLE_FUNC_VIS
# define _LIBCPP_EXPORTED_FROM_ABI
#elif defined(_LIBCPP_BUILDING_LIBRARY)
# define _LIBCPP_DLL_VIS __declspec(dllexport)
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS
# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport)
#else
# define _LIBCPP_DLL_VIS __declspec(dllimport)
# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
# define _LIBCPP_OVERRIDABLE_FUNC_VIS
# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
#endif
#define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS
#define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS
#define _LIBCPP_EXTERN_VIS _LIBCPP_DLL_VIS
#define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS
#define _LIBCPP_HIDDEN
#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
#define _LIBCPP_TEMPLATE_VIS
#define _LIBCPP_ENUM_VIS
#if defined(_LIBCPP_COMPILER_MSVC)
# define _LIBCPP_INLINE_VISIBILITY __forceinline
# define _LIBCPP_ALWAYS_INLINE __forceinline
# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __forceinline
#else
# define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__))
# define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__ ((__always_inline__))
#endif
#endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
#ifndef _LIBCPP_HIDDEN
@@ -727,8 +712,8 @@ namespace std {
# endif
#endif
#ifndef _LIBCPP_EXTERN_VIS
#define _LIBCPP_EXTERN_VIS
#ifndef _LIBCPP_EXPORTED_FROM_ABI
# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
#endif
#ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS
@@ -763,30 +748,69 @@ namespace std {
#define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
#endif
#ifndef _LIBCPP_INLINE_VISIBILITY
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
# define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
#if __has_attribute(internal_linkage)
# define _LIBCPP_INTERNAL_LINKAGE __attribute__ ((internal_linkage))
#else
# define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE
#endif
#if __has_attribute(exclude_from_explicit_instantiation)
# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__ ((__exclude_from_explicit_instantiation__))
#else
// Try to approximate the effect of exclude_from_explicit_instantiation
// (which is that entities are not assumed to be provided by explicit
// template instantitations in the dylib) by always inlining those entities.
# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
#endif
#ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU
# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
# define _LIBCPP_HIDE_FROM_ABI_PER_TU 0
# else
# define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__))
# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1
# endif
#endif
#ifndef _LIBCPP_ALWAYS_INLINE
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
# define _LIBCPP_ALWAYS_INLINE __attribute__ ((__visibility__("hidden"), __always_inline__))
#ifndef _LIBCPP_HIDE_FROM_ABI
# if _LIBCPP_HIDE_FROM_ABI_PER_TU
# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE
# else
# define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
# endif
#endif
#ifndef _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__visibility__("default"), __always_inline__))
#ifdef _LIBCPP_BUILDING_LIBRARY
# if _LIBCPP_ABI_VERSION > 1
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
# else
# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__always_inline__))
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1
# endif
#else
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
#endif
// Just so we can migrate to the new macros gradually.
#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI
// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect.
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD } }
#define _VSTD std::_LIBCPP_ABI_NAMESPACE
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 17
#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
_LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem {
#else
#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \
_LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem {
#endif
#define _LIBCPP_END_NAMESPACE_FILESYSTEM \
_LIBCPP_END_NAMESPACE_STD } }
#define _VSTD_FS _VSTD::__fs::filesystem
#ifndef _LIBCPP_PREFERRED_OVERLOAD
# if __has_attribute(__enable_if__)
# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, "")))
@@ -889,9 +913,9 @@ template <unsigned> struct __static_assert_check {};
# define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx
# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
__lx __v_; \
_LIBCPP_ALWAYS_INLINE x(__lx __v) : __v_(__v) {} \
_LIBCPP_ALWAYS_INLINE explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
_LIBCPP_ALWAYS_INLINE operator int() const {return __v_;} \
_LIBCPP_INLINE_VISIBILITY x(__lx __v) : __v_(__v) {} \
_LIBCPP_INLINE_VISIBILITY explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
_LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;} \
};
#else // _LIBCPP_HAS_NO_STRONG_ENUMS
# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x
@@ -947,7 +971,14 @@ template <unsigned> struct __static_assert_check {};
// If we are getting operator new from the MSVC CRT, then allocation overloads
// for align_val_t were added in 19.12, aka VS 2017 version 15.3.
#if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912
#define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
#define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
#elif defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
#define _LIBCPP_DEFER_NEW_TO_VCRUNTIME
#if !defined(__cpp_aligned_new)
// We're defering to Microsoft's STL to provide aligned new et al. We don't
// have it unless the language feature test macro is defined.
#define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
#endif
#endif
#if defined(__APPLE__)
@@ -955,13 +986,13 @@ template <unsigned> struct __static_assert_check {};
defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
# endif
# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
# if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060
# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
# endif
# endif
#endif // defined(__APPLE__)
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \
(defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || \
(!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606))
# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
#endif
#if defined(__APPLE__) || defined(__FreeBSD__)
#define _LIBCPP_HAS_DEFAULTRUNELOCALE
@@ -971,30 +1002,42 @@ template <unsigned> struct __static_assert_check {};
#define _LIBCPP_WCTYPE_IS_MASK
#endif
#ifndef _LIBCPP_STD_VER
# if __cplusplus <= 201103L
# define _LIBCPP_STD_VER 11
# elif __cplusplus <= 201402L
# define _LIBCPP_STD_VER 14
# elif __cplusplus <= 201703L
# define _LIBCPP_STD_VER 17
// Deprecation macros.
// Deprecations warnings are only enabled when _LIBCPP_ENABLE_DEPRECATION_WARNINGS is defined.
#if defined(_LIBCPP_ENABLE_DEPRECATION_WARNINGS)
# if __has_attribute(deprecated)
# define _LIBCPP_DEPRECATED __attribute__ ((deprecated))
# elif _LIBCPP_STD_VER > 11
# define _LIBCPP_DEPRECATED [[deprecated]]
# else
# define _LIBCPP_STD_VER 18 // current year, or date of c++2a ratification
# define _LIBCPP_DEPRECATED
# endif
#endif // _LIBCPP_STD_VER
#if _LIBCPP_STD_VER > 11
# define _LIBCPP_DEPRECATED [[deprecated]]
#else
# define _LIBCPP_DEPRECATED
#endif
#if !defined(_LIBCPP_CXX03_LANG)
# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED
#else
# define _LIBCPP_DEPRECATED_IN_CXX11
#endif
#if _LIBCPP_STD_VER >= 14
# define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED
#else
# define _LIBCPP_DEPRECATED_IN_CXX14
#endif
#if _LIBCPP_STD_VER >= 17
# define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
#else
# define _LIBCPP_DEPRECATED_IN_CXX17
#endif
#if _LIBCPP_STD_VER <= 11
# define _LIBCPP_EXPLICIT_AFTER_CXX11
# define _LIBCPP_DEPRECATED_AFTER_CXX11
#else
# define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
# define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]]
#endif
#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
@@ -1015,8 +1058,30 @@ template <unsigned> struct __static_assert_check {};
# define _LIBCPP_CONSTEXPR_AFTER_CXX17
#endif
#if __has_cpp_attribute(nodiscard) && _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17)
# define _LIBCPP_NODISCARD_AFTER_CXX17 [[nodiscard]]
// The _LIBCPP_NODISCARD_ATTRIBUTE should only be used to define other
// NODISCARD macros to the correct attribute.
#if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC)
# define _LIBCPP_NODISCARD_ATTRIBUTE [[nodiscard]]
#elif defined(_LIBCPP_COMPILER_CLANG) && !defined(_LIBCPP_CXX03_LANG)
# define _LIBCPP_NODISCARD_ATTRIBUTE [[clang::warn_unused_result]]
#else
// We can't use GCC's [[gnu::warn_unused_result]] and
// __attribute__((warn_unused_result)), because GCC does not silence them via
// (void) cast.
# define _LIBCPP_NODISCARD_ATTRIBUTE
#endif
// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not
// specified as such as an extension.
#if defined(_LIBCPP_ENABLE_NODISCARD) && !defined(_LIBCPP_DISABLE_NODISCARD_EXT)
# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD_ATTRIBUTE
#else
# define _LIBCPP_NODISCARD_EXT
#endif
#if !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17) && \
(_LIBCPP_STD_VER > 17 || defined(_LIBCPP_ENABLE_NODISCARD))
# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD_ATTRIBUTE
#else
# define _LIBCPP_NODISCARD_AFTER_CXX17
#endif
@@ -1033,6 +1098,14 @@ template <unsigned> struct __static_assert_check {};
# define _LIBCPP_EXPLICIT_MOVE(x) (x)
#endif
#ifndef _LIBCPP_CONSTEXPR_IF_NODEBUG
#if defined(_LIBCPP_DEBUG) || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
#define _LIBCPP_CONSTEXPR_IF_NODEBUG
#else
#define _LIBCPP_CONSTEXPR_IF_NODEBUG constexpr
#endif
#endif
#ifndef _LIBCPP_HAS_NO_ASAN
_LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
const void *, const void *, const void *, const void *);
@@ -1065,10 +1138,11 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
defined(__Fuchsia__) || \
defined(__NetBSD__) || \
defined(__linux__) || \
defined(__GNU__) || \
defined(__APPLE__) || \
defined(__CloudABI__) || \
defined(__sun__) || \
(defined(__MINGW32__) && __libcpp_has_include(<pthread.h>))
(defined(__MINGW32__) && __has_include(<pthread.h>))
# define _LIBCPP_HAS_THREAD_API_PTHREAD
# elif defined(_LIBCPP_WIN32API)
# define _LIBCPP_HAS_THREAD_API_WIN32
@@ -1170,8 +1244,12 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# define _LIBCPP_DIAGNOSE_ERROR(...)
#endif
#if __has_attribute(fallthough) || _GNUC_VER >= 700
// Use a function like macro to imply that it must be followed by a semicolon
#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
# define _LIBCPP_FALLTHROUGH() [[fallthrough]]
#elif __has_cpp_attribute(clang::fallthrough)
# define _LIBCPP_FALLTHROUGH() [[clang::fallthrough]]
#elif __has_attribute(fallthough) || _GNUC_VER >= 700
# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__))
#else
# define _LIBCPP_FALLTHROUGH() ((void)0)
@@ -1225,9 +1303,15 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH __attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST __attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \
__attribute__((availability(macosx,strict,introduced=10.14))) \
__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(ios,strict,introduced=10.0))) \
@@ -1251,8 +1335,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
__attribute__((availability(ios,strict,introduced=7.0)))
#else
# define _LIBCPP_AVAILABILITY_SHARED_MUTEX
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS
# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE
@@ -1264,14 +1348,15 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
// Define availability that depends on _LIBCPP_NO_EXCEPTIONS.
#ifdef _LIBCPP_NO_EXCEPTIONS
# define _LIBCPP_AVAILABILITY_DYNARRAY
# define _LIBCPP_AVAILABILITY_FUTURE
# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
#else
# define _LIBCPP_AVAILABILITY_DYNARRAY _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR
# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST \
_LIBCPP_AVAILABILITY_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR
# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
#endif
// Availability of stream API in the dylib got dropped and re-added. The

View File

@@ -14,6 +14,7 @@
#cmakedefine _LIBCPP_ABI_UNSTABLE
#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
@@ -27,6 +28,7 @@
#cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL
#cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
#cmakedefine _LIBCPP_NO_VCRUNTIME
#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@
@_LIBCPP_ABI_DEFINES@

View File

@@ -74,7 +74,7 @@ typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&);
/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT
/// fails.
extern _LIBCPP_EXTERN_VIS __libcpp_debug_function_type __libcpp_debug_function;
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

218
include/__errc Normal file
View File

@@ -0,0 +1,218 @@
// -*- C++ -*-
//===---------------------------- __errc ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ERRC
#define _LIBCPP___ERRC
/*
system_error synopsis
namespace std
{
enum class errc
{
address_family_not_supported, // EAFNOSUPPORT
address_in_use, // EADDRINUSE
address_not_available, // EADDRNOTAVAIL
already_connected, // EISCONN
argument_list_too_long, // E2BIG
argument_out_of_domain, // EDOM
bad_address, // EFAULT
bad_file_descriptor, // EBADF
bad_message, // EBADMSG
broken_pipe, // EPIPE
connection_aborted, // ECONNABORTED
connection_already_in_progress, // EALREADY
connection_refused, // ECONNREFUSED
connection_reset, // ECONNRESET
cross_device_link, // EXDEV
destination_address_required, // EDESTADDRREQ
device_or_resource_busy, // EBUSY
directory_not_empty, // ENOTEMPTY
executable_format_error, // ENOEXEC
file_exists, // EEXIST
file_too_large, // EFBIG
filename_too_long, // ENAMETOOLONG
function_not_supported, // ENOSYS
host_unreachable, // EHOSTUNREACH
identifier_removed, // EIDRM
illegal_byte_sequence, // EILSEQ
inappropriate_io_control_operation, // ENOTTY
interrupted, // EINTR
invalid_argument, // EINVAL
invalid_seek, // ESPIPE
io_error, // EIO
is_a_directory, // EISDIR
message_size, // EMSGSIZE
network_down, // ENETDOWN
network_reset, // ENETRESET
network_unreachable, // ENETUNREACH
no_buffer_space, // ENOBUFS
no_child_process, // ECHILD
no_link, // ENOLINK
no_lock_available, // ENOLCK
no_message_available, // ENODATA
no_message, // ENOMSG
no_protocol_option, // ENOPROTOOPT
no_space_on_device, // ENOSPC
no_stream_resources, // ENOSR
no_such_device_or_address, // ENXIO
no_such_device, // ENODEV
no_such_file_or_directory, // ENOENT
no_such_process, // ESRCH
not_a_directory, // ENOTDIR
not_a_socket, // ENOTSOCK
not_a_stream, // ENOSTR
not_connected, // ENOTCONN
not_enough_memory, // ENOMEM
not_supported, // ENOTSUP
operation_canceled, // ECANCELED
operation_in_progress, // EINPROGRESS
operation_not_permitted, // EPERM
operation_not_supported, // EOPNOTSUPP
operation_would_block, // EWOULDBLOCK
owner_dead, // EOWNERDEAD
permission_denied, // EACCES
protocol_error, // EPROTO
protocol_not_supported, // EPROTONOSUPPORT
read_only_file_system, // EROFS
resource_deadlock_would_occur, // EDEADLK
resource_unavailable_try_again, // EAGAIN
result_out_of_range, // ERANGE
state_not_recoverable, // ENOTRECOVERABLE
stream_timeout, // ETIME
text_file_busy, // ETXTBSY
timed_out, // ETIMEDOUT
too_many_files_open_in_system, // ENFILE
too_many_files_open, // EMFILE
too_many_links, // EMLINK
too_many_symbolic_link_levels, // ELOOP
value_too_large, // EOVERFLOW
wrong_protocol_type // EPROTOTYPE
};
*/
#include <__config>
#include <cerrno>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
// Some error codes are not present on all platforms, so we provide equivalents
// for them:
//enum class errc
_LIBCPP_DECLARE_STRONG_ENUM(errc)
{
address_family_not_supported = EAFNOSUPPORT,
address_in_use = EADDRINUSE,
address_not_available = EADDRNOTAVAIL,
already_connected = EISCONN,
argument_list_too_long = E2BIG,
argument_out_of_domain = EDOM,
bad_address = EFAULT,
bad_file_descriptor = EBADF,
bad_message = EBADMSG,
broken_pipe = EPIPE,
connection_aborted = ECONNABORTED,
connection_already_in_progress = EALREADY,
connection_refused = ECONNREFUSED,
connection_reset = ECONNRESET,
cross_device_link = EXDEV,
destination_address_required = EDESTADDRREQ,
device_or_resource_busy = EBUSY,
directory_not_empty = ENOTEMPTY,
executable_format_error = ENOEXEC,
file_exists = EEXIST,
file_too_large = EFBIG,
filename_too_long = ENAMETOOLONG,
function_not_supported = ENOSYS,
host_unreachable = EHOSTUNREACH,
identifier_removed = EIDRM,
illegal_byte_sequence = EILSEQ,
inappropriate_io_control_operation = ENOTTY,
interrupted = EINTR,
invalid_argument = EINVAL,
invalid_seek = ESPIPE,
io_error = EIO,
is_a_directory = EISDIR,
message_size = EMSGSIZE,
network_down = ENETDOWN,
network_reset = ENETRESET,
network_unreachable = ENETUNREACH,
no_buffer_space = ENOBUFS,
no_child_process = ECHILD,
no_link = ENOLINK,
no_lock_available = ENOLCK,
#ifdef ENODATA
no_message_available = ENODATA,
#else
no_message_available = ENOMSG,
#endif
no_message = ENOMSG,
no_protocol_option = ENOPROTOOPT,
no_space_on_device = ENOSPC,
#ifdef ENOSR
no_stream_resources = ENOSR,
#else
no_stream_resources = ENOMEM,
#endif
no_such_device_or_address = ENXIO,
no_such_device = ENODEV,
no_such_file_or_directory = ENOENT,
no_such_process = ESRCH,
not_a_directory = ENOTDIR,
not_a_socket = ENOTSOCK,
#ifdef ENOSTR
not_a_stream = ENOSTR,
#else
not_a_stream = EINVAL,
#endif
not_connected = ENOTCONN,
not_enough_memory = ENOMEM,
not_supported = ENOTSUP,
operation_canceled = ECANCELED,
operation_in_progress = EINPROGRESS,
operation_not_permitted = EPERM,
operation_not_supported = EOPNOTSUPP,
operation_would_block = EWOULDBLOCK,
owner_dead = EOWNERDEAD,
permission_denied = EACCES,
protocol_error = EPROTO,
protocol_not_supported = EPROTONOSUPPORT,
read_only_file_system = EROFS,
resource_deadlock_would_occur = EDEADLK,
resource_unavailable_try_again = EAGAIN,
result_out_of_range = ERANGE,
state_not_recoverable = ENOTRECOVERABLE,
#ifdef ETIME
stream_timeout = ETIME,
#else
stream_timeout = ETIMEDOUT,
#endif
text_file_busy = ETXTBSY,
timed_out = ETIMEDOUT,
too_many_files_open_in_system = ENFILE,
too_many_files_open = EMFILE,
too_many_links = EMLINK,
too_many_symbolic_link_levels = ELOOP,
value_too_large = EOVERFLOW,
wrong_protocol_type = EPROTOTYPE
};
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc)
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ERRC

View File

@@ -50,7 +50,7 @@ template <class _Tp>
#endif
struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool>
{
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
bool operator()(const _Tp& __x, const _Tp& __y) const
{return __x < __y;}
};
@@ -59,7 +59,7 @@ struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool>
template <>
struct _LIBCPP_TEMPLATE_VIS less<void>
{
template <class _T1, class _T2>
template <class _T1, class _T2>
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
auto operator()(_T1&& __t, _T2&& __u) const
_NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)))
@@ -552,7 +552,7 @@ template <class _Tp, class, class = void>
struct __is_transparent : false_type {};
template <class _Tp, class _Up>
struct __is_transparent<_Tp, _Up,
struct __is_transparent<_Tp, _Up,
typename __void_t<typename _Tp::is_transparent>::type>
: true_type {};
#endif
@@ -561,8 +561,8 @@ struct __is_transparent<_Tp, _Up,
struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { };
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_MEMORY)
extern const allocator_arg_t allocator_arg;
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
#else
/* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
#endif

View File

@@ -859,6 +859,17 @@ public:
template <class> friend class __hash_map_node_destructor;
};
#if _LIBCPP_STD_VER > 14
template <class _NodeType, class _Alloc>
struct __generic_container_node_destructor;
template <class _Tp, class _VoidPtr, class _Alloc>
struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
: __hash_node_destructor<_Alloc>
{
using __hash_node_destructor<_Alloc>::__hash_node_destructor;
};
#endif
#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Hash, class _Equal, class _Alloc>
@@ -1047,8 +1058,26 @@ public:
);
}
private:
_LIBCPP_INLINE_VISIBILITY
__next_pointer __node_insert_multi_prepare(size_t __cp_hash,
value_type& __cp_val);
_LIBCPP_INLINE_VISIBILITY
void __node_insert_multi_perform(__node_pointer __cp,
__next_pointer __pn) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
__next_pointer __node_insert_unique_prepare(size_t __nd_hash,
value_type& __nd_val);
_LIBCPP_INLINE_VISIBILITY
void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT;
public:
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
_LIBCPP_INLINE_VISIBILITY
iterator __node_insert_multi(__node_pointer __nd);
_LIBCPP_INLINE_VISIBILITY
iterator __node_insert_multi(const_iterator __p,
__node_pointer __nd);
@@ -1151,6 +1180,36 @@ public:
return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
}
#if _LIBCPP_STD_VER > 14
template <class _NodeHandle, class _InsertReturnType>
_LIBCPP_INLINE_VISIBILITY
_InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_unique(const_iterator __hint,
_NodeHandle&& __nh);
template <class _Table>
_LIBCPP_INLINE_VISIBILITY
void __node_handle_merge_unique(_Table& __source);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_multi(_NodeHandle&& __nh);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
template <class _Table>
_LIBCPP_INLINE_VISIBILITY
void __node_handle_merge_multi(_Table& __source);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle __node_handle_extract(key_type const& __key);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle __node_handle_extract(const_iterator __it);
#endif
void clear() _NOEXCEPT;
void rehash(size_type __n);
_LIBCPP_INLINE_VISIBILITY void reserve(size_type __n)
@@ -1814,73 +1873,112 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT
}
}
// Prepare the container for an insertion of the value __value with the hash
// __hash. This does a lookup into the container to see if __value is already
// present, and performs a rehash if necessary. Returns a pointer to the
// existing element if it exists, otherwise nullptr.
//
// Note that this function does forward exceptions if key_eq() throws, and never
// mutates __value or actually inserts into the map.
template <class _Tp, class _Hash, class _Equal, class _Alloc>
pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
_LIBCPP_INLINE_VISIBILITY
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
size_t __hash, value_type& __value)
{
__nd->__hash_ = hash_function()(__nd->__value_);
size_type __bc = bucket_count();
bool __inserted = false;
__next_pointer __ndptr;
size_t __chash;
if (__bc != 0)
{
__chash = __constrain_hash(__nd->__hash_, __bc);
__ndptr = __bucket_list_[__chash];
size_t __chash = __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;
__ndptr = __ndptr->__next_)
{
if (key_eq()(__ndptr->__upcast()->__value_, __nd->__value_))
goto __done;
if (key_eq()(__ndptr->__upcast()->__value_, __value))
return __ndptr;
}
}
}
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
__chash = __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)
{
__pn =__p1_.first().__ptr();
__nd->__next_ = __pn->__next_;
__pn->__next_ = __nd->__ptr();
// fix up __bucket_list_
__bucket_list_[__chash] = __pn;
if (__nd->__next_ != nullptr)
__bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
}
else
{
__nd->__next_ = __pn->__next_;
__pn->__next_ = __nd->__ptr();
}
__ndptr = __nd->__ptr();
// increment size
++size();
__inserted = true;
rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
}
__done:
#if _LIBCPP_DEBUG_LEVEL >= 2
return pair<iterator, bool>(iterator(__ndptr, this), __inserted);
#else
return pair<iterator, bool>(iterator(__ndptr), __inserted);
#endif
return nullptr;
}
// Insert the node __nd into the container by pushing it into the right bucket,
// and updating size(). Assumes that __nd->__hash is up-to-date, and that
// rehashing has already occurred and that no element with the same key exists
// in the map.
template <class _Tp, class _Hash, class _Equal, class _Alloc>
_LIBCPP_INLINE_VISIBILITY
void
__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);
// insert_after __bucket_list_[__chash], or __first_node if bucket is null
__next_pointer __pn = __bucket_list_[__chash];
if (__pn == nullptr)
{
__pn =__p1_.first().__ptr();
__nd->__next_ = __pn->__next_;
__pn->__next_ = __nd->__ptr();
// fix up __bucket_list_
__bucket_list_[__chash] = __pn;
if (__nd->__next_ != nullptr)
__bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
}
else
{
__nd->__next_ = __pn->__next_;
__pn->__next_ = __nd->__ptr();
}
++size();
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
{
__nd->__hash_ = hash_function()(__nd->__value_);
__next_pointer __existing_node =
__node_insert_unique_prepare(__nd->__hash(), __nd->__value_);
// Insert the node, unless it already exists in the container.
bool __inserted = false;
if (__existing_node == nullptr)
{
__node_insert_unique_perform(__nd);
__existing_node = __nd->__ptr();
__inserted = true;
}
#if _LIBCPP_DEBUG_LEVEL >= 2
return pair<iterator, bool>(iterator(__existing_node, this), __inserted);
#else
return pair<iterator, bool>(iterator(__existing_node), __inserted);
#endif
}
// Prepare the container for an insertion of the value __cp_val with the hash
// __cp_hash. This does a lookup into the container to see if __cp_value is
// already present, and performs a rehash if necessary. Returns a pointer to the
// last occurance of __cp_val in the map.
//
// Note that this function does forward exceptions if key_eq() throws, and never
// mutates __value or actually inserts into the map.
template <class _Tp, class _Hash, class _Equal, class _Alloc>
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
size_t __cp_hash, value_type& __cp_val)
{
__cp->__hash_ = hash_function()(__cp->__value_);
size_type __bc = bucket_count();
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
@@ -1888,8 +1986,44 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
}
size_t __chash = __constrain_hash(__cp->__hash_, __bc);
size_t __chash = __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;
__pn = __pn->__next_)
{
// __found key_eq() action
// false false loop
// true true loop
// false true set __found to true
// true false break
if (__found != (__pn->__next_->__hash() == __cp_hash &&
key_eq()(__pn->__next_->__upcast()->__value_, __cp_val)))
{
if (!__found)
__found = true;
else
break;
}
}
}
return __pn;
}
// Insert the node __cp into the container after __pn (which is the last node in
// the bucket that compares equal to __cp). Rehashing, and checking for
// uniqueness has already been performed (in __node_insert_multi_prepare), so
// all we need to do is update the bucket and size(). Assumes that __cp->__hash
// is up-to-date.
template <class _Tp, class _Hash, class _Equal, class _Alloc>
void
__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);
if (__pn == nullptr)
{
__pn =__p1_.first().__ptr();
@@ -1903,24 +2037,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
}
else
{
for (bool __found = false; __pn->__next_ != nullptr &&
__constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
__pn = __pn->__next_)
{
// __found key_eq() action
// false false loop
// true true loop
// false true set __found to true
// true false break
if (__found != (__pn->__next_->__hash() == __cp->__hash_ &&
key_eq()(__pn->__next_->__upcast()->__value_, __cp->__value_)))
{
if (!__found)
__found = true;
else
break;
}
}
__cp->__next_ = __pn->__next_;
__pn->__next_ = __cp->__ptr();
if (__cp->__next_ != nullptr)
@@ -1931,6 +2047,17 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
}
}
++size();
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
{
__cp->__hash_ = hash_function()(__cp->__value_);
__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
@@ -2126,6 +2253,138 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
#endif // _LIBCPP_CXX03_LANG
#if _LIBCPP_STD_VER > 14
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle, class _InsertReturnType>
_LIBCPP_INLINE_VISIBILITY
_InsertReturnType
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
_NodeHandle&& __nh)
{
if (__nh.empty())
return _InsertReturnType{end(), false, _NodeHandle()};
pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
if (__result.second)
__nh.__release();
return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)};
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
const_iterator, _NodeHandle&& __nh)
{
if (__nh.empty())
return end();
pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
if (__result.second)
__nh.__release();
return __result.first;
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
key_type const& __key)
{
iterator __i = find(__key);
if (__i == end())
return _NodeHandle();
return __node_handle_extract<_NodeHandle>(__i);
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
const_iterator __p)
{
allocator_type __alloc(__node_alloc());
return _NodeHandle(remove(__p).release(), __alloc);
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _Table>
_LIBCPP_INLINE_VISIBILITY
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(
_Table& __source)
{
static_assert(is_same<__node, typename _Table::__node>::value, "");
for (typename _Table::iterator __it = __source.begin();
__it != __source.end();)
{
__node_pointer __src_ptr = __it.__node_->__upcast();
size_t __hash = hash_function()(__src_ptr->__value_);
__next_pointer __existing_node =
__node_insert_unique_prepare(__hash, __src_ptr->__value_);
auto __prev_iter = __it++;
if (__existing_node == nullptr)
{
(void)__source.remove(__prev_iter).release();
__src_ptr->__hash_ = __hash;
__node_insert_unique_perform(__src_ptr);
}
}
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
_NodeHandle&& __nh)
{
if (__nh.empty())
return end();
iterator __result = __node_insert_multi(__nh.__ptr_);
__nh.__release();
return __result;
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
const_iterator __hint, _NodeHandle&& __nh)
{
if (__nh.empty())
return end();
iterator __result = __node_insert_multi(__hint, __nh.__ptr_);
__nh.__release();
return __result;
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _Table>
_LIBCPP_INLINE_VISIBILITY
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
_Table& __source)
{
static_assert(is_same<typename _Table::__node, __node>::value, "");
for (typename _Table::iterator __it = __source.begin();
__it != __source.end();)
{
__node_pointer __src_ptr = __it.__node_->__upcast();
size_t __src_hash = hash_function()(__src_ptr->__value_);
__next_pointer __pn =
__node_insert_multi_prepare(__src_hash, __src_ptr->__value_);
(void)__source.remove(__it++).release();
__src_ptr->__hash_ = __src_hash;
__node_insert_multi_perform(__src_ptr, __pn);
}
}
#endif // _LIBCPP_STD_VER > 14
template <class _Tp, class _Hash, class _Equal, class _Alloc>
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)

View File

@@ -1 +1 @@
7000
8000

View File

@@ -469,7 +469,7 @@ public:
static const mask alnum = alpha | digit;
static const mask graph = alnum | punct;
_LIBCPP_ALWAYS_INLINE ctype_base() {}
_LIBCPP_INLINE_VISIBILITY ctype_base() {}
};
template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
@@ -482,77 +482,77 @@ class _LIBCPP_TYPE_VIS ctype<wchar_t>
public:
typedef wchar_t char_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit ctype(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool is(mask __m, char_type __c) const
{
return do_is(__m, __c);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
{
return do_is(__low, __high, __vec);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
{
return do_scan_is(__m, __low, __high);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
{
return do_scan_not(__m, __low, __high);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
char_type toupper(char_type __c) const
{
return do_toupper(__c);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* toupper(char_type* __low, const char_type* __high) const
{
return do_toupper(__low, __high);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
char_type tolower(char_type __c) const
{
return do_tolower(__c);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* tolower(char_type* __low, const char_type* __high) const
{
return do_tolower(__low, __high);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
char_type widen(char __c) const
{
return do_widen(__c);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char* widen(const char* __low, const char* __high, char_type* __to) const
{
return do_widen(__low, __high, __to);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
char narrow(char_type __c, char __dfault) const
{
return do_narrow(__c, __dfault);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
{
return do_narrow(__low, __high, __dfault, __to);
@@ -587,13 +587,13 @@ public:
explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool is(mask __m, char_type __c) const
{
return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
{
for (; __low != __high; ++__low, ++__vec)
@@ -601,7 +601,7 @@ public:
return __low;
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
{
for (; __low != __high; ++__low)
@@ -610,7 +610,7 @@ public:
return __low;
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
{
for (; __low != __high; ++__low)
@@ -619,49 +619,49 @@ public:
return __low;
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
char_type toupper(char_type __c) const
{
return do_toupper(__c);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* toupper(char_type* __low, const char_type* __high) const
{
return do_toupper(__low, __high);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
char_type tolower(char_type __c) const
{
return do_tolower(__c);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char_type* tolower(char_type* __low, const char_type* __high) const
{
return do_tolower(__low, __high);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
char_type widen(char __c) const
{
return do_widen(__c);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char* widen(const char* __low, const char* __high, char_type* __to) const
{
return do_widen(__low, __high, __to);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
char narrow(char_type __c, char __dfault) const
{
return do_narrow(__c, __dfault);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
{
return do_narrow(__low, __high, __dfault, __to);
@@ -674,7 +674,7 @@ public:
#else
static const size_t table_size = 256; // FIXME: Don't hardcode this.
#endif
_LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
_LIBCPP_INLINE_VISIBILITY const mask* table() const _NOEXCEPT {return __tab_;}
static const mask* classic_table() _NOEXCEPT;
#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
static const int* __classic_upper_table() _NOEXCEPT;
@@ -854,7 +854,7 @@ tolower(_CharT __c, const locale& __loc)
class _LIBCPP_TYPE_VIS codecvt_base
{
public:
_LIBCPP_ALWAYS_INLINE codecvt_base() {}
_LIBCPP_INLINE_VISIBILITY codecvt_base() {}
enum result {ok, partial, error, noconv};
};
@@ -874,11 +874,11 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result out(state_type& __st,
const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
@@ -886,14 +886,14 @@ public:
return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
{
return do_unshift(__st, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result in(state_type& __st,
const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
@@ -901,25 +901,25 @@ public:
return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int encoding() const _NOEXCEPT
{
return do_encoding();
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool always_noconv() const _NOEXCEPT
{
return do_always_noconv();
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
{
return do_length(__st, __frm, __end, __mx);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int max_length() const _NOEXCEPT
{
return do_max_length();
@@ -928,7 +928,7 @@ public:
static locale::id id;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt(const char*, size_t __refs = 0)
: locale::facet(__refs) {}
@@ -963,7 +963,7 @@ public:
explicit codecvt(size_t __refs = 0);
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result out(state_type& __st,
const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
@@ -971,14 +971,14 @@ public:
return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
{
return do_unshift(__st, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result in(state_type& __st,
const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
@@ -986,25 +986,25 @@ public:
return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int encoding() const _NOEXCEPT
{
return do_encoding();
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool always_noconv() const _NOEXCEPT
{
return do_always_noconv();
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
{
return do_length(__st, __frm, __end, __mx);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int max_length() const _NOEXCEPT
{
return do_max_length();
@@ -1043,11 +1043,11 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result out(state_type& __st,
const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
@@ -1055,14 +1055,14 @@ public:
return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
{
return do_unshift(__st, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result in(state_type& __st,
const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
@@ -1070,25 +1070,25 @@ public:
return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int encoding() const _NOEXCEPT
{
return do_encoding();
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool always_noconv() const _NOEXCEPT
{
return do_always_noconv();
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
{
return do_length(__st, __frm, __end, __mx);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int max_length() const _NOEXCEPT
{
return do_max_length();
@@ -1097,7 +1097,7 @@ public:
static locale::id id;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt(const char*, size_t __refs = 0)
: locale::facet(__refs) {}
@@ -1129,11 +1129,11 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result out(state_type& __st,
const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
@@ -1141,14 +1141,14 @@ public:
return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
{
return do_unshift(__st, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
result in(state_type& __st,
const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
@@ -1156,25 +1156,25 @@ public:
return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int encoding() const _NOEXCEPT
{
return do_encoding();
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool always_noconv() const _NOEXCEPT
{
return do_always_noconv();
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
{
return do_length(__st, __frm, __end, __mx);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int max_length() const _NOEXCEPT
{
return do_max_length();
@@ -1183,7 +1183,7 @@ public:
static locale::id id;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt(const char*, size_t __refs = 0)
: locale::facet(__refs) {}
@@ -1210,10 +1210,10 @@ class _LIBCPP_TEMPLATE_VIS codecvt_byname
: public codecvt<_InternT, _ExternT, _StateT>
{
public:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt_byname(const char* __nm, size_t __refs = 0)
: codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt_byname(const string& __nm, size_t __refs = 0)
: codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
protected:
@@ -1244,7 +1244,7 @@ template <>
struct __narrow_to_utf8<8>
{
template <class _OutputIterator, class _CharT>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_OutputIterator
operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
{
@@ -1255,16 +1255,16 @@ struct __narrow_to_utf8<8>
};
template <>
struct __narrow_to_utf8<16>
struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
: public codecvt<char16_t, char, mbstate_t>
{
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
__narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
~__narrow_to_utf8();
_LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
template <class _OutputIterator, class _CharT>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_OutputIterator
operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
{
@@ -1289,16 +1289,16 @@ struct __narrow_to_utf8<16>
};
template <>
struct __narrow_to_utf8<32>
struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
: public codecvt<char32_t, char, mbstate_t>
{
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
__narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
~__narrow_to_utf8();
_LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
template <class _OutputIterator, class _CharT>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_OutputIterator
operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
{
@@ -1334,7 +1334,7 @@ template <>
struct __widen_from_utf8<8>
{
template <class _OutputIterator>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_OutputIterator
operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
{
@@ -1345,16 +1345,16 @@ struct __widen_from_utf8<8>
};
template <>
struct __widen_from_utf8<16>
struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
: public codecvt<char16_t, char, mbstate_t>
{
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
__widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
~__widen_from_utf8();
_LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
template <class _OutputIterator>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_OutputIterator
operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
{
@@ -1379,16 +1379,16 @@ struct __widen_from_utf8<16>
};
template <>
struct __widen_from_utf8<32>
struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
: public codecvt<char32_t, char, mbstate_t>
{
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
__widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
~__widen_from_utf8();
_LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
template <class _OutputIterator>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_OutputIterator
operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
{
@@ -1426,11 +1426,11 @@ public:
explicit numpunct(size_t __refs = 0);
_LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
_LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
_LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
_LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
_LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
_LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
_LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
_LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
_LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
_LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
static locale::id id;
@@ -1457,11 +1457,11 @@ public:
explicit numpunct(size_t __refs = 0);
_LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
_LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
_LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
_LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
_LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
_LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
_LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
_LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
_LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
_LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
static locale::id id;

View File

@@ -74,11 +74,11 @@ struct _LIBCPP_TYPE_VIS defer_lock_t {};
struct _LIBCPP_TYPE_VIS try_to_lock_t {};
struct _LIBCPP_TYPE_VIS adopt_lock_t {};
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_MUTEX)
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
extern const defer_lock_t defer_lock;
extern const try_to_lock_t try_to_lock;
extern const adopt_lock_t adopt_lock;
extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock;
extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock;
extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock;
#else

210
include/__node_handle Normal file
View File

@@ -0,0 +1,210 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___NODE_HANDLE
#define _LIBCPP___NODE_HANDLE
#include <__config>
#include <memory>
#include <optional>
#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
// Specialized in __tree & __hash_table for their _NodeType.
template <class _NodeType, class _Alloc>
struct __generic_container_node_destructor;
template <class _NodeType, class _Alloc,
template <class, class> class _MapOrSetSpecifics>
class _LIBCPP_TEMPLATE_VIS __basic_node_handle
: public _MapOrSetSpecifics<
_NodeType,
__basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>
{
template <class _Tp, class _Compare, class _Allocator>
friend class __tree;
template <class _Tp, class _Hash, class _Equal, class _Allocator>
friend class __hash_table;
friend struct _MapOrSetSpecifics<
_NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>;
typedef allocator_traits<_Alloc> __alloc_traits;
typedef typename __rebind_pointer<typename __alloc_traits::void_pointer,
_NodeType>::type
__node_pointer_type;
public:
typedef _Alloc allocator_type;
private:
__node_pointer_type __ptr_ = nullptr;
optional<allocator_type> __alloc_;
_LIBCPP_INLINE_VISIBILITY
void __release()
{
__ptr_ = nullptr;
__alloc_ = _VSTD::nullopt;
}
_LIBCPP_INLINE_VISIBILITY
void __destroy_node_pointer()
{
if (__ptr_ != nullptr)
{
typedef typename __allocator_traits_rebind<
allocator_type, _NodeType>::type __node_alloc_type;
__node_alloc_type __alloc(*__alloc_);
__generic_container_node_destructor<_NodeType, __node_alloc_type>(
__alloc, true)(__ptr_);
__ptr_ = nullptr;
}
}
_LIBCPP_INLINE_VISIBILITY
__basic_node_handle(__node_pointer_type __ptr,
allocator_type const& __alloc)
: __ptr_(__ptr), __alloc_(__alloc)
{
}
public:
_LIBCPP_INLINE_VISIBILITY
__basic_node_handle() = default;
_LIBCPP_INLINE_VISIBILITY
__basic_node_handle(__basic_node_handle&& __other) noexcept
: __ptr_(__other.__ptr_),
__alloc_(_VSTD::move(__other.__alloc_))
{
__other.__ptr_ = nullptr;
__other.__alloc_ = _VSTD::nullopt;
}
_LIBCPP_INLINE_VISIBILITY
__basic_node_handle& operator=(__basic_node_handle&& __other)
{
_LIBCPP_ASSERT(
__alloc_ == _VSTD::nullopt ||
__alloc_traits::propagate_on_container_move_assignment::value ||
__alloc_ == __other.__alloc_,
"node_type with incompatible allocator passed to "
"node_type::operator=(node_type&&)");
__destroy_node_pointer();
__ptr_ = __other.__ptr_;
if (__alloc_traits::propagate_on_container_move_assignment::value ||
__alloc_ == _VSTD::nullopt)
__alloc_ = _VSTD::move(__other.__alloc_);
__other.__ptr_ = nullptr;
__other.__alloc_ = _VSTD::nullopt;
return *this;
}
_LIBCPP_INLINE_VISIBILITY
allocator_type get_allocator() const { return *__alloc_; }
_LIBCPP_INLINE_VISIBILITY
explicit operator bool() const { return __ptr_ != nullptr; }
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
bool empty() const { return __ptr_ == nullptr; }
_LIBCPP_INLINE_VISIBILITY
void swap(__basic_node_handle& __other) noexcept(
__alloc_traits::propagate_on_container_swap::value ||
__alloc_traits::is_always_equal::value)
{
using _VSTD::swap;
swap(__ptr_, __other.__ptr_);
if (__alloc_traits::propagate_on_container_swap::value ||
__alloc_ == _VSTD::nullopt || __other.__alloc_ == _VSTD::nullopt)
swap(__alloc_, __other.__alloc_);
}
_LIBCPP_INLINE_VISIBILITY
friend void swap(__basic_node_handle& __a, __basic_node_handle& __b)
noexcept(noexcept(__a.swap(__b))) { __a.swap(__b); }
_LIBCPP_INLINE_VISIBILITY
~__basic_node_handle()
{
__destroy_node_pointer();
}
};
template <class _NodeType, class _Derived>
struct __set_node_handle_specifics
{
typedef typename _NodeType::__node_value_type value_type;
_LIBCPP_INLINE_VISIBILITY
value_type& value() const
{
return static_cast<_Derived const*>(this)->__ptr_->__value_;
}
};
template <class _NodeType, class _Derived>
struct __map_node_handle_specifics
{
typedef typename _NodeType::__node_value_type::key_type key_type;
typedef typename _NodeType::__node_value_type::mapped_type mapped_type;
_LIBCPP_INLINE_VISIBILITY
key_type& key() const
{
return static_cast<_Derived const*>(this)->
__ptr_->__value_.__ref().first;
}
_LIBCPP_INLINE_VISIBILITY
mapped_type& mapped() const
{
return static_cast<_Derived const*>(this)->
__ptr_->__value_.__ref().second;
}
};
template <class _NodeType, class _Alloc>
using __set_node_handle =
__basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>;
template <class _NodeType, class _Alloc>
using __map_node_handle =
__basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>;
template <class _Iterator, class _NodeType>
_LIBCPP_TEMPLATE_VIS
struct __insert_return_type
{
_Iterator position;
bool inserted;
_NodeType node;
};
#endif // _LIBCPP_STD_VER > 14
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif

View File

@@ -27,24 +27,24 @@ struct _LIBCPP_TEMPLATE_VIS nullptr_t
struct __nat {int __for_bool_;};
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
template <class _Tp>
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
operator _Tp* () const {return 0;}
template <class _Tp, class _Up>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
operator _Tp _Up::* () const {return 0;}
friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
};
inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}
#define nullptr _VSTD::__get_nullptr_t()

View File

@@ -57,12 +57,12 @@ public:
}
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type)
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n)
{
if (__p == (pointer)&buf_)
__allocated_ = false;
else
_VSTD::__libcpp_deallocate(__p, __alignof(_Tp));
_VSTD::__libcpp_deallocate(__p, __n * sizeof(_Tp), __alignof(_Tp));
}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}

View File

@@ -70,7 +70,7 @@ typedef pthread_t __libcpp_thread_id;
typedef pthread_t __libcpp_thread_t;
// Thrad Local Storage
// Thread Local Storage
typedef pthread_key_t __libcpp_tls_key;
#define _LIBCPP_TLS_DESTRUCTOR_CC

View File

@@ -796,6 +796,16 @@ public:
template <class> friend class __map_node_destructor;
};
#if _LIBCPP_STD_VER > 14
template <class _NodeType, class _Alloc>
struct __generic_container_node_destructor;
template <class _Tp, class _VoidPtr, class _Alloc>
struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc>
: __tree_node_destructor<_Alloc>
{
using __tree_node_destructor<_Alloc>::__tree_node_destructor;
};
#endif
template <class _Tp, class _NodePtr, class _DiffType>
class _LIBCPP_TEMPLATE_VIS __tree_iterator
@@ -847,7 +857,7 @@ public:
__tree_iterator operator--(int)
{__tree_iterator __t(*this); --(*this); return __t;}
friend _LIBCPP_INLINE_VISIBILITY
friend _LIBCPP_INLINE_VISIBILITY
bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
{return __x.__ptr_ == __y.__ptr_;}
friend _LIBCPP_INLINE_VISIBILITY
@@ -1331,13 +1341,51 @@ public:
#endif // !_LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
_LIBCPP_INLINE_VISIBILITY
iterator __node_insert_unique(const_iterator __p,
__node_pointer __nd);
_LIBCPP_INLINE_VISIBILITY
iterator __node_insert_multi(__node_pointer __nd);
_LIBCPP_INLINE_VISIBILITY
iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
_LIBCPP_INLINE_VISIBILITY iterator
__remove_node_pointer(__node_pointer) _NOEXCEPT;
#if _LIBCPP_STD_VER > 14
template <class _NodeHandle, class _InsertReturnType>
_LIBCPP_INLINE_VISIBILITY
_InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
template <class _Tree>
_LIBCPP_INLINE_VISIBILITY
void __node_handle_merge_unique(_Tree& __source);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_multi(_NodeHandle&&);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
template <class _Tree>
_LIBCPP_INLINE_VISIBILITY
void __node_handle_merge_multi(_Tree& __source);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle __node_handle_extract(key_type const&);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle __node_handle_extract(const_iterator);
#endif
iterator erase(const_iterator __p);
iterator erase(const_iterator __f, const_iterator __l);
template <class _Key>
@@ -1347,7 +1395,7 @@ public:
void __insert_node_at(__parent_pointer __parent,
__node_base_pointer& __child,
__node_base_pointer __new_node);
__node_base_pointer __new_node) _NOEXCEPT;
template <class _Key>
iterator find(const _Key& __v);
@@ -1451,7 +1499,7 @@ private:
void __copy_assign_alloc(const __tree& __t, true_type)
{
if (__node_alloc() != __t.__node_alloc())
clear();
clear();
__node_alloc() = __t.__node_alloc();
}
_LIBCPP_INLINE_VISIBILITY
@@ -1793,7 +1841,7 @@ __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
__node_traits::propagate_on_container_move_assignment::value &&
is_nothrow_move_assignable<value_compare>::value &&
is_nothrow_move_assignable<__node_allocator>::value)
{
__move_assign(__t, integral_constant<bool,
__node_traits::propagate_on_container_move_assignment::value>());
@@ -2092,10 +2140,9 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
}
template <class _Tp, class _Compare, class _Allocator>
void
__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__parent_pointer __parent,
__node_base_pointer& __child,
__node_base_pointer __new_node)
void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
__parent_pointer __parent, __node_base_pointer& __child,
__node_base_pointer __new_node) _NOEXCEPT
{
__new_node->__left_ = nullptr;
__new_node->__right_ = nullptr;
@@ -2345,19 +2392,186 @@ __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
return iterator(__nd);
}
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT
{
iterator __r(__ptr);
++__r;
if (__begin_node() == __ptr)
__begin_node() = __r.__ptr_;
--size();
__tree_remove(__end_node()->__left_,
static_cast<__node_base_pointer>(__ptr));
return __r;
}
#if _LIBCPP_STD_VER > 14
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle, class _InsertReturnType>
_LIBCPP_INLINE_VISIBILITY
_InsertReturnType
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
_NodeHandle&& __nh)
{
if (__nh.empty())
return _InsertReturnType{end(), false, _NodeHandle()};
__node_pointer __ptr = __nh.__ptr_;
__parent_pointer __parent;
__node_base_pointer& __child = __find_equal(__parent,
__ptr->__value_);
if (__child != nullptr)
return _InsertReturnType{
iterator(static_cast<__node_pointer>(__child)),
false, _VSTD::move(__nh)};
__insert_node_at(__parent, __child,
static_cast<__node_base_pointer>(__ptr));
__nh.__release();
return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
}
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(
const_iterator __hint, _NodeHandle&& __nh)
{
if (__nh.empty())
return end();
__node_pointer __ptr = __nh.__ptr_;
__parent_pointer __parent;
__node_base_pointer __dummy;
__node_base_pointer& __child = __find_equal(__hint, __parent, __dummy,
__ptr->__value_);
__node_pointer __r = static_cast<__node_pointer>(__child);
if (__child == nullptr)
{
__insert_node_at(__parent, __child,
static_cast<__node_base_pointer>(__ptr));
__r = __ptr;
__nh.__release();
}
return iterator(__r);
}
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle
__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key)
{
iterator __it = find(__key);
if (__it == end())
return _NodeHandle();
return __node_handle_extract<_NodeHandle>(__it);
}
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle
__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
{
__node_pointer __np = __p.__get_np();
__remove_node_pointer(__np);
return _NodeHandle(__np, __alloc());
}
template <class _Tp, class _Compare, class _Allocator>
template <class _Tree>
_LIBCPP_INLINE_VISIBILITY
void
__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source)
{
static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
for (typename _Tree::iterator __i = __source.begin();
__i != __source.end();)
{
__node_pointer __src_ptr = __i.__get_np();
__parent_pointer __parent;
__node_base_pointer& __child =
__find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_));
++__i;
if (__child != nullptr)
continue;
__source.__remove_node_pointer(__src_ptr);
__insert_node_at(__parent, __child,
static_cast<__node_base_pointer>(__src_ptr));
}
}
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh)
{
if (__nh.empty())
return end();
__node_pointer __ptr = __nh.__ptr_;
__parent_pointer __parent;
__node_base_pointer& __child = __find_leaf_high(
__parent, _NodeTypes::__get_key(__ptr->__value_));
__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
__nh.__release();
return iterator(__ptr);
}
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
const_iterator __hint, _NodeHandle&& __nh)
{
if (__nh.empty())
return end();
__node_pointer __ptr = __nh.__ptr_;
__parent_pointer __parent;
__node_base_pointer& __child = __find_leaf(__hint, __parent,
_NodeTypes::__get_key(__ptr->__value_));
__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
__nh.__release();
return iterator(__ptr);
}
template <class _Tp, class _Compare, class _Allocator>
template <class _Tree>
_LIBCPP_INLINE_VISIBILITY
void
__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source)
{
static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, "");
for (typename _Tree::iterator __i = __source.begin();
__i != __source.end();)
{
__node_pointer __src_ptr = __i.__get_np();
__parent_pointer __parent;
__node_base_pointer& __child = __find_leaf_high(
__parent, _NodeTypes::__get_key(__src_ptr->__value_));
++__i;
__source.__remove_node_pointer(__src_ptr);
__insert_node_at(__parent, __child,
static_cast<__node_base_pointer>(__src_ptr));
}
}
#endif // _LIBCPP_STD_VER > 14
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
{
__node_pointer __np = __p.__get_np();
iterator __r(__p.__ptr_);
++__r;
if (__begin_node() == __p.__ptr_)
__begin_node() = __r.__ptr_;
--size();
iterator __r = __remove_node_pointer(__np);
__node_allocator& __na = __node_alloc();
__tree_remove(__end_node()->__left_,
static_cast<__node_base_pointer>(__np));
__node_traits::destroy(__na, _NodeTypes::__get_ptr(
const_cast<__node_value_type&>(*__p)));
__node_traits::deallocate(__na, __np, 1);

View File

@@ -645,13 +645,8 @@ template <class BidirectionalIterator, class Compare>
#include <functional>
#include <iterator>
#include <cstddef>
#if defined(__IBMCPP__)
#include "support/ibm/support.h"
#endif
#if defined(_LIBCPP_COMPILER_MSVC)
#include <intrin.h>
#endif
#include <bit>
#include <version>
#include <__debug>
@@ -671,10 +666,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _T1, class _T2 = _T1>
struct __equal_to
{
_LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
_LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;}
_LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;}
_LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;}
_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 <class _T1>
@@ -788,135 +783,6 @@ struct __debug_less
#endif // _LIBCPP_DEBUG
// Precondition: __x != 0
inline _LIBCPP_INLINE_VISIBILITY
unsigned __ctz(unsigned __x) {
#ifndef _LIBCPP_COMPILER_MSVC
return static_cast<unsigned>(__builtin_ctz(__x));
#else
static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
static_assert(sizeof(unsigned long) == 4, "");
unsigned long where;
// Search from LSB to MSB for first set bit.
// Returns zero if no set bit is found.
if (_BitScanForward(&where, __x))
return where;
return 32;
#endif
}
inline _LIBCPP_INLINE_VISIBILITY
unsigned long __ctz(unsigned long __x) {
#ifndef _LIBCPP_COMPILER_MSVC
return static_cast<unsigned long>(__builtin_ctzl(__x));
#else
static_assert(sizeof(unsigned long) == sizeof(unsigned), "");
return __ctz(static_cast<unsigned>(__x));
#endif
}
inline _LIBCPP_INLINE_VISIBILITY
unsigned long long __ctz(unsigned long long __x) {
#ifndef _LIBCPP_COMPILER_MSVC
return static_cast<unsigned long long>(__builtin_ctzll(__x));
#else
unsigned long where;
// Search from LSB to MSB for first set bit.
// Returns zero if no set bit is found.
#if defined(_LIBCPP_HAS_BITSCAN64)
(defined(_M_AMD64) || defined(__x86_64__))
if (_BitScanForward64(&where, __x))
return static_cast<int>(where);
#else
// Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
// Scan the Low Word.
if (_BitScanForward(&where, static_cast<unsigned long>(__x)))
return where;
// Scan the High Word.
if (_BitScanForward(&where, static_cast<unsigned long>(__x >> 32)))
return where + 32; // Create a bit offset from the LSB.
#endif
return 64;
#endif // _LIBCPP_COMPILER_MSVC
}
// Precondition: __x != 0
inline _LIBCPP_INLINE_VISIBILITY
unsigned __clz(unsigned __x) {
#ifndef _LIBCPP_COMPILER_MSVC
return static_cast<unsigned>(__builtin_clz(__x));
#else
static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
static_assert(sizeof(unsigned long) == 4, "");
unsigned long where;
// Search from LSB to MSB for first set bit.
// Returns zero if no set bit is found.
if (_BitScanReverse(&where, __x))
return 31 - where;
return 32; // Undefined Behavior.
#endif
}
inline _LIBCPP_INLINE_VISIBILITY
unsigned long __clz(unsigned long __x) {
#ifndef _LIBCPP_COMPILER_MSVC
return static_cast<unsigned long>(__builtin_clzl (__x));
#else
static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
return __clz(static_cast<unsigned>(__x));
#endif
}
inline _LIBCPP_INLINE_VISIBILITY
unsigned long long __clz(unsigned long long __x) {
#ifndef _LIBCPP_COMPILER_MSVC
return static_cast<unsigned long long>(__builtin_clzll(__x));
#else
unsigned long where;
// BitScanReverse scans from MSB to LSB for first set bit.
// Returns 0 if no set bit is found.
#if defined(_LIBCPP_HAS_BITSCAN64)
if (_BitScanReverse64(&where, __x))
return static_cast<int>(63 - where);
#else
// Scan the high 32 bits.
if (_BitScanReverse(&where, static_cast<unsigned long>(__x >> 32)))
return 63 - (where + 32); // Create a bit offset from the MSB.
// Scan the low 32 bits.
if (_BitScanReverse(&where, static_cast<unsigned long>(__x)))
return 63 - where;
#endif
return 64; // Undefined Behavior.
#endif // _LIBCPP_COMPILER_MSVC
}
inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned __x) {
#ifndef _LIBCPP_COMPILER_MSVC
return __builtin_popcount (__x);
#else
static_assert(sizeof(unsigned) == 4, "");
return __popcnt(__x);
#endif
}
inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long __x) {
#ifndef _LIBCPP_COMPILER_MSVC
return __builtin_popcountl (__x);
#else
static_assert(sizeof(unsigned long) == 4, "");
return __popcnt(__x);
#endif
}
inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long long __x) {
#ifndef _LIBCPP_COMPILER_MSVC
return __builtin_popcountll(__x);
#else
static_assert(sizeof(unsigned long long) == 8, "");
return __popcnt64(__x);
#endif
}
// all_of
template <class _InputIterator, class _Predicate>
@@ -1708,7 +1574,7 @@ __unwrap_iter(move_iterator<_Tp*> __i)
#if _LIBCPP_DEBUG_LEVEL < 2
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
typename enable_if
<
is_trivially_copy_assignable<_Tp>::value,
@@ -1722,7 +1588,7 @@ __unwrap_iter(__wrap_iter<_Tp*> __i)
#else
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
typename enable_if
<
is_trivially_copy_assignable<_Tp>::value,
@@ -2533,6 +2399,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
static_assert(__is_forward_iterator<_ForwardIterator>::value,
"std::min_element requires a ForwardIterator");
if (__first != __last)
{
_ForwardIterator __i = __first;
@@ -2597,6 +2465,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
static_assert(__is_forward_iterator<_ForwardIterator>::value,
"std::max_element requires a ForwardIterator");
if (__first != __last)
{
_ForwardIterator __i = __first;
@@ -2683,6 +2553,8 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11
std::pair<_ForwardIterator, _ForwardIterator>
minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
static_assert(__is_forward_iterator<_ForwardIterator>::value,
"std::minmax_element requires a ForwardIterator");
std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first);
if (__first != __last)
{
@@ -3027,10 +2899,11 @@ template<class _IntType>
template<class _URNG>
typename uniform_int_distribution<_IntType>::result_type
uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{
typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
uint32_t, uint64_t>::type _UIntType;
const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1);
const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
if (_Rp == 1)
return __p.a();
const size_t _Dt = numeric_limits<_UIntType>::digits;
@@ -3080,7 +2953,7 @@ public:
_LIBCPP_FUNC_VIS __rs_default __rs_get();
template <class _RandomAccessIterator>
void
_LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
@@ -3101,7 +2974,7 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
}
template <class _RandomAccessIterator, class _RandomNumberGenerator>
void
_LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
#ifndef _LIBCPP_CXX03_LANG
_RandomNumberGenerator&& __rand)
@@ -3116,7 +2989,8 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
for (--__last; __first < __last; ++__first, --__d)
{
difference_type __i = __rand(__d);
swap(*__first, *(__first + __i));
if (__i != difference_type(0))
swap(*__first, *(__first + __i));
}
}
}
@@ -3737,6 +3611,7 @@ __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
// stable, 4-10 compares, 0-9 swaps
template <class _Compare, class _ForwardIterator>
_LIBCPP_HIDDEN
unsigned
__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
_ForwardIterator __x4, _ForwardIterator __x5, _Compare __c)
@@ -4214,14 +4089,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
{
#ifdef _LIBCPP_DEBUG
typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
__debug_less<_Compare> __c(__comp);
return __lower_bound<_Comp_ref>(__first, __last, __value_, __c);
#else // _LIBCPP_DEBUG
typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
#endif // _LIBCPP_DEBUG
}
template <class _ForwardIterator, class _Tp>
@@ -4262,14 +4131,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_ForwardIterator
upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
{
#ifdef _LIBCPP_DEBUG
typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
__debug_less<_Compare> __c(__comp);
return __upper_bound<_Comp_ref>(__first, __last, __value_, __c);
#else // _LIBCPP_DEBUG
typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp);
#endif // _LIBCPP_DEBUG
}
template <class _ForwardIterator, class _Tp>

View File

@@ -87,13 +87,14 @@ namespace std {
#include <typeinfo>
#include <type_traits>
#include <cstdlib>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
namespace std {
class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
{
public:
virtual const char* what() const _NOEXCEPT;
@@ -104,13 +105,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
void __throw_bad_any_cast()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_any_cast();
#else
_VSTD::abort();
_VSTD::abort();
#endif
}
@@ -304,7 +306,7 @@ private:
__any_imp::_Buffer __buf;
};
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
void * __call(_Action __a, any * __other = nullptr,
type_info const * __info = nullptr,
const void* __fallback_info = nullptr) const
@@ -312,7 +314,7 @@ private:
return __h(__a, this, __other, __info, __fallback_info);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
void * __call(_Action __a, any * __other = nullptr,
type_info const * __info = nullptr,
const void* __fallback_info = nullptr)
@@ -576,6 +578,7 @@ any make_any(initializer_list<_Up> __il, _Args&&... __args) {
template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
_ValueType any_cast(any const & __v)
{
using _RawValueType = __uncvref_t<_ValueType>;
@@ -590,6 +593,7 @@ _ValueType any_cast(any const & __v)
template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
_ValueType any_cast(any & __v)
{
using _RawValueType = __uncvref_t<_ValueType>;
@@ -604,6 +608,7 @@ _ValueType any_cast(any & __v)
template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
_ValueType any_cast(any && __v)
{
using _RawValueType = __uncvref_t<_ValueType>;

View File

@@ -112,6 +112,7 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
#include <algorithm>
#include <stdexcept>
#include <cstdlib> // for _LIBCPP_UNREACHABLE
#include <version>
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -367,7 +368,7 @@ array(_Tp, _Args...)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
bool
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
@@ -375,7 +376,7 @@ operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
bool
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return !(__x == __y);
@@ -383,7 +384,7 @@ operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
bool
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
@@ -392,7 +393,7 @@ operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
bool
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return __y < __x;
@@ -400,7 +401,7 @@ operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
bool
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return !(__y < __x);
@@ -408,7 +409,7 @@ operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
bool
_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
{
return !(__x < __y);

View File

@@ -544,6 +544,7 @@ void atomic_signal_fence(memory_order m) noexcept;
#include <cstddef>
#include <cstdint>
#include <type_traits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -559,10 +560,6 @@ void atomic_signal_fence(memory_order m) noexcept;
#error C++ standard library is incompatible with <stdatomic.h>
#endif
#if _LIBCPP_STD_VER > 14
# define __cpp_lib_atomic_is_always_lock_free 201603L
#endif
#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
__m == memory_order_acquire || \

158
include/bit Normal file
View File

@@ -0,0 +1,158 @@
// -*- C++ -*-
//===------------------------------ bit ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
#ifndef _LIBCPP_BIT
#define _LIBCPP_BIT
/*
bit synopsis
namespace std {
} // namespace std
*/
#include <__config>
#include <version>
#if defined(__IBMCPP__)
#include "support/ibm/support.h"
#endif
#if defined(_LIBCPP_COMPILER_MSVC)
#include <intrin.h>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_COMPILER_MSVC
inline _LIBCPP_INLINE_VISIBILITY
int __ctz(unsigned __x) { return __builtin_ctz(__x); }
inline _LIBCPP_INLINE_VISIBILITY
int __ctz(unsigned long __x) { return __builtin_ctzl(__x); }
inline _LIBCPP_INLINE_VISIBILITY
int __ctz(unsigned long long __x) { return __builtin_ctzll(__x); }
inline _LIBCPP_INLINE_VISIBILITY
int __clz(unsigned __x) { return __builtin_clz(__x); }
inline _LIBCPP_INLINE_VISIBILITY
int __clz(unsigned long __x) { return __builtin_clzl(__x); }
inline _LIBCPP_INLINE_VISIBILITY
int __clz(unsigned long long __x) { return __builtin_clzll(__x); }
inline _LIBCPP_INLINE_VISIBILITY
int __popcount(unsigned __x) { return __builtin_popcount(__x); }
inline _LIBCPP_INLINE_VISIBILITY
int __popcount(unsigned long __x) { return __builtin_popcountl(__x); }
inline _LIBCPP_INLINE_VISIBILITY
int __popcount(unsigned long long __x) { return __builtin_popcountll(__x); }
#else // _LIBCPP_COMPILER_MSVC
// Precondition: __x != 0
inline _LIBCPP_INLINE_VISIBILITY
int __ctz(unsigned __x) {
static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
static_assert(sizeof(unsigned long) == 4, "");
unsigned long __where;
if (_BitScanForward(&__where, __x))
return static_cast<int>(__where);
return 32;
}
inline _LIBCPP_INLINE_VISIBILITY
int __ctz(unsigned long __x) {
static_assert(sizeof(unsigned long) == sizeof(unsigned), "");
return __ctz(static_cast<unsigned>(__x));
}
inline _LIBCPP_INLINE_VISIBILITY
int __ctz(unsigned long long __x) {
unsigned long __where;
#if defined(_LIBCPP_HAS_BITSCAN64)
(defined(_M_AMD64) || defined(__x86_64__))
if (_BitScanForward64(&__where, __x))
return static_cast<int>(__where);
#else
// Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
if (_BitScanForward(&__where, static_cast<unsigned long>(__x)))
return static_cast<int>(__where);
if (_BitScanForward(&__where, static_cast<unsigned long>(__x >> 32)))
return static_cast<int>(__where + 32);
#endif
return 64;
}
// Precondition: __x != 0
inline _LIBCPP_INLINE_VISIBILITY
int __clz(unsigned __x) {
static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
static_assert(sizeof(unsigned long) == 4, "");
unsigned long __where;
if (_BitScanReverse(&__where, __x))
return static_cast<int>(31 - __where);
return 32; // Undefined Behavior.
}
inline _LIBCPP_INLINE_VISIBILITY
int __clz(unsigned long __x) {
static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
return __clz(static_cast<unsigned>(__x));
}
inline _LIBCPP_INLINE_VISIBILITY
int __clz(unsigned long long __x) {
unsigned long __where;
#if defined(_LIBCPP_HAS_BITSCAN64)
if (_BitScanReverse64(&__where, __x))
return static_cast<int>(63 - __where);
#else
// Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls.
if (_BitScanReverse(&__where, static_cast<unsigned long>(__x >> 32)))
return static_cast<int>(63 - (__where + 32));
if (_BitScanReverse(&__where, static_cast<unsigned long>(__x)))
return static_cast<int>(63 - __where);
#endif
return 64; // Undefined Behavior.
}
inline _LIBCPP_INLINE_VISIBILITY int __popcount(unsigned __x) {
static_assert(sizeof(unsigned) == 4, "");
return __popcnt(__x);
}
inline _LIBCPP_INLINE_VISIBILITY int __popcount(unsigned long __x) {
static_assert(sizeof(unsigned long) == 4, "");
return __popcnt(__x);
}
inline _LIBCPP_INLINE_VISIBILITY int __popcount(unsigned long long __x) {
static_assert(sizeof(unsigned long long) == 8, "");
return __popcnt64(__x);
}
#endif // _LIBCPP_COMPILER_MSVC
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_BIT

View File

@@ -238,9 +238,9 @@ __bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT
size_t __sz = _Size;
for (size_t __i = 0; __i < sizeof(__t)/sizeof(__t[0]); ++__i, __v >>= __bits_per_word, __sz -= __bits_per_word )
if ( __sz < __bits_per_word)
__t[__i] = static_cast<__storage_type>(__v) & ( 1ULL << __sz ) - 1;
__t[__i] = static_cast<__storage_type>(__v) & ( 1ULL << __sz ) - 1;
else
__t[__i] = static_cast<__storage_type>(__v);
__t[__i] = static_cast<__storage_type>(__v);
_VSTD::copy(__t, __t + sizeof(__t)/sizeof(__t[0]), __first_);
_VSTD::fill(__first_ + sizeof(__t)/sizeof(__t[0]), __first_ + sizeof(__first_)/sizeof(__first_[0]),
@@ -254,7 +254,7 @@ __bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT
{
__first_[0] = __v;
if (_Size < __bits_per_word)
__first_[0] &= ( 1ULL << _Size ) - 1;
__first_[0] &= ( 1ULL << _Size ) - 1;
_VSTD::fill(__first_ + 1, __first_ + sizeof(__first_)/sizeof(__first_[0]), __storage_type(0));
}
@@ -269,9 +269,9 @@ __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
#if __SIZEOF_SIZE_T__ == 8
: __first_{__v}
#elif __SIZEOF_SIZE_T__ == 4
: __first_{static_cast<__storage_type>(__v),
_Size >= 2 * __bits_per_word ? static_cast<__storage_type>(__v >> __bits_per_word)
: static_cast<__storage_type>((__v >> __bits_per_word) & (__storage_type(1) << (_Size - __bits_per_word)) - 1)}
: __first_{static_cast<__storage_type>(__v),
_Size >= 2 * __bits_per_word ? static_cast<__storage_type>(__v >> __bits_per_word)
: static_cast<__storage_type>((__v >> __bits_per_word) & (__storage_type(1) << (_Size - __bits_per_word)) - 1)}
#else
#error This constructor has not been ported to this platform
#endif

View File

@@ -20,11 +20,18 @@ Macros:
FLT_EVAL_METHOD // C99
FLT_RADIX
FLT_HAS_SUBNORM // C11
DBL_HAS_SUBNORM // C11
LDBL_HAS_SUBNORM // C11
FLT_MANT_DIG
DBL_MANT_DIG
LDBL_MANT_DIG
DECIMAL_DIG // C99
FLT_DECIMAL_DIG // C11
DBL_DECIMAL_DIG // C11
LDBL_DECIMAL_DIG // C11
FLT_DIG
DBL_DIG
@@ -58,6 +65,9 @@ Macros:
DBL_MIN
LDBL_MIN
FLT_TRUE_MIN // C11
DBL_TRUE_MIN // C11
LDBL_TRUE_MIN // C11
*/
#include <__config>

617
include/charconv Normal file
View File

@@ -0,0 +1,617 @@
// -*- C++ -*-
//===------------------------------ charconv ------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_CHARCONV
#define _LIBCPP_CHARCONV
/*
charconv synopsis
namespace std {
// floating-point format for primitive numerical conversion
enum class chars_format {
scientific = unspecified,
fixed = unspecified,
hex = unspecified,
general = fixed | scientific
};
// 23.20.2, primitive numerical output conversion
struct to_chars_result {
char* ptr;
errc ec;
};
to_chars_result to_chars(char* first, char* last, see below value,
int base = 10);
to_chars_result to_chars(char* first, char* last, float value);
to_chars_result to_chars(char* first, char* last, double value);
to_chars_result to_chars(char* first, char* last, long double value);
to_chars_result to_chars(char* first, char* last, float value,
chars_format fmt);
to_chars_result to_chars(char* first, char* last, double value,
chars_format fmt);
to_chars_result to_chars(char* first, char* last, long double value,
chars_format fmt);
to_chars_result to_chars(char* first, char* last, float value,
chars_format fmt, int precision);
to_chars_result to_chars(char* first, char* last, double value,
chars_format fmt, int precision);
to_chars_result to_chars(char* first, char* last, long double value,
chars_format fmt, int precision);
// 23.20.3, primitive numerical input conversion
struct from_chars_result {
const char* ptr;
errc ec;
};
from_chars_result from_chars(const char* first, const char* last,
see below& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last,
float& value,
chars_format fmt = chars_format::general);
from_chars_result from_chars(const char* first, const char* last,
double& value,
chars_format fmt = chars_format::general);
from_chars_result from_chars(const char* first, const char* last,
long double& value,
chars_format fmt = chars_format::general);
} // namespace std
*/
#include <__errc>
#include <type_traits>
#include <limits>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __itoa {
_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
}
#if _LIBCPP_STD_VER > 11
enum class _LIBCPP_ENUM_VIS chars_format
{
scientific = 0x1,
fixed = 0x2,
hex = 0x4,
general = fixed | scientific
};
struct _LIBCPP_TYPE_VIS to_chars_result
{
char* ptr;
errc ec;
};
struct _LIBCPP_TYPE_VIS from_chars_result
{
const char* ptr;
errc ec;
};
void to_chars(char*, char*, bool, int = 10) = delete;
void from_chars(const char*, const char*, bool, int = 10) = delete;
namespace __itoa
{
static constexpr uint64_t __pow10_64[] = {
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),
};
static constexpr uint32_t __pow10_32[] = {
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),
};
template <typename _Tp, typename = void>
struct _LIBCPP_HIDDEN __traits_base
{
using type = uint64_t;
#if !defined(_LIBCPP_COMPILER_MSVC)
static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
{
auto __t = (64 - __builtin_clzll(__v | 1)) * 1233 >> 12;
return __t - (__v < __pow10_64[__t]) + 1;
}
#endif
static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
{
return __u64toa(__v, __p);
}
static _LIBCPP_INLINE_VISIBILITY auto& __pow() { return __pow10_64; }
};
template <typename _Tp>
struct _LIBCPP_HIDDEN
__traits_base<_Tp, decltype(void(uint32_t{declval<_Tp>()}))>
{
using type = uint32_t;
#if !defined(_LIBCPP_COMPILER_MSVC)
static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
{
auto __t = (32 - __builtin_clz(__v | 1)) * 1233 >> 12;
return __t - (__v < __pow10_32[__t]) + 1;
}
#endif
static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
{
return __u32toa(__v, __p);
}
static _LIBCPP_INLINE_VISIBILITY auto& __pow() { return __pow10_32; }
};
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY bool
__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
{
auto __c = __a * __b;
__r = __c;
return __c > (numeric_limits<unsigned char>::max)();
}
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY bool
__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r)
{
auto __c = __a * __b;
__r = __c;
return __c > (numeric_limits<unsigned short>::max)();
}
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY bool
__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r)
{
static_assert(is_unsigned<_Tp>::value, "");
#if !defined(_LIBCPP_COMPILER_MSVC)
return __builtin_mul_overflow(__a, __b, &__r);
#else
bool __did = __b && ((numeric_limits<_Tp>::max)() / __b) < __a;
__r = __a * __b;
return __did;
#endif
}
template <typename _Tp, typename _Up>
inline _LIBCPP_INLINE_VISIBILITY bool
__mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
{
return __mul_overflowed(__a, static_cast<_Tp>(__b), __r);
}
template <typename _Tp>
struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
{
static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
using __traits_base<_Tp>::__pow;
using typename __traits_base<_Tp>::type;
// precondition: at least one non-zero character available
static _LIBCPP_INLINE_VISIBILITY char const*
__read(char const* __p, char const* __ep, type& __a, type& __b)
{
type __cprod[digits];
int __j = digits - 1;
int __i = digits;
do
{
if (!('0' <= *__p && *__p <= '9'))
break;
__cprod[--__i] = *__p++ - '0';
} while (__p != __ep && __i != 0);
__a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1,
__cprod[__i]);
if (__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
--__p;
return __p;
}
template <typename _It1, typename _It2, class _Up>
static _LIBCPP_INLINE_VISIBILITY _Up
__inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init)
{
for (; __first1 < __last1; ++__first1, ++__first2)
__init = __init + *__first1 * *__first2;
return __init;
}
};
} // namespace __itoa
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY _Tp
__complement(_Tp __x)
{
static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
return _Tp(~__x + 1);
}
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY auto
__to_unsigned(_Tp __x)
{
return static_cast<make_unsigned_t<_Tp>>(__x);
}
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
{
auto __x = __to_unsigned(__value);
if (__value < 0 && __first != __last)
{
*__first++ = '-';
__x = __complement(__x);
}
return __to_chars_itoa(__first, __last, __x, false_type());
}
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
{
using __tx = __itoa::__traits<_Tp>;
auto __diff = __last - __first;
#if !defined(_LIBCPP_COMPILER_MSVC)
if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
return {__tx::__convert(__value, __first), {}};
else
return {__last, errc::value_too_large};
#else
if (__tx::digits <= __diff)
return {__tx::__convert(__value, __first), {}};
else
{
char __buf[__tx::digits];
auto __p = __tx::__convert(__value, __buf);
auto __len = __p - __buf;
if (__len <= __diff)
{
memcpy(__first, __buf, __len);
return {__first + __len, {}};
}
else
return {__last, errc::value_too_large};
}
#endif
}
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
true_type)
{
auto __x = __to_unsigned(__value);
if (__value < 0 && __first != __last)
{
*__first++ = '-';
__x = __complement(__x);
}
return __to_chars_integral(__first, __last, __x, __base, false_type());
}
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
false_type)
{
if (__base == 10)
return __to_chars_itoa(__first, __last, __value, false_type());
auto __p = __last;
while (__p != __first)
{
auto __c = __value % __base;
__value /= __base;
*--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
if (__value == 0)
break;
}
auto __len = __last - __p;
if (__value != 0 || !__len)
return {__last, errc::value_too_large};
else
{
memmove(__first, __p, __len);
return {__first + __len, {}};
}
}
template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
to_chars(char* __first, char* __last, _Tp __value)
{
return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>());
}
template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
to_chars(char* __first, char* __last, _Tp __value, int __base)
{
_LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
return __to_chars_integral(__first, __last, __value, __base,
is_signed<_Tp>());
}
template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
inline _LIBCPP_INLINE_VISIBILITY from_chars_result
__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
{
using __tl = numeric_limits<_Tp>;
decltype(__to_unsigned(__value)) __x;
bool __neg = (__first != __last && *__first == '-');
auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
switch (__r.ec)
{
case errc::invalid_argument:
return {__first, __r.ec};
case errc::result_out_of_range:
return __r;
default:
break;
}
if (__neg)
{
if (__x <= __complement(__to_unsigned(__tl::min())))
{
__x = __complement(__x);
memcpy(&__value, &__x, sizeof(__x));
return __r;
}
}
else
{
if (__x <= (__tl::max)())
{
__value = __x;
return __r;
}
}
return {__r.ptr, errc::result_out_of_range};
}
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY bool
__in_pattern(_Tp __c)
{
return '0' <= __c && __c <= '9';
}
struct _LIBCPP_HIDDEN __in_pattern_result
{
bool __ok;
int __val;
explicit _LIBCPP_INLINE_VISIBILITY operator bool() const { return __ok; }
};
template <typename _Tp>
inline _LIBCPP_INLINE_VISIBILITY __in_pattern_result
__in_pattern(_Tp __c, int __base)
{
if (__base <= 10)
return {'0' <= __c && __c < '0' + __base, __c - '0'};
else if (__in_pattern(__c))
return {true, __c - '0'};
else if ('a' <= __c && __c < 'a' + __base - 10)
return {true, __c - 'a' + 10};
else
return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10};
}
template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
inline _LIBCPP_INLINE_VISIBILITY from_chars_result
__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
_Ts... __args)
{
auto __find_non_zero = [](_It __first, _It __last) {
for (; __first != __last; ++__first)
if (*__first != '0')
break;
return __first;
};
auto __p = __find_non_zero(__first, __last);
if (__p == __last || !__in_pattern(*__p, __args...))
{
if (__p == __first)
return {__first, errc::invalid_argument};
else
{
__value = 0;
return {__p, {}};
}
}
auto __r = __f(__p, __last, __value, __args...);
if (__r.ec == errc::result_out_of_range)
{
for (; __r.ptr != __last; ++__r.ptr)
{
if (!__in_pattern(*__r.ptr, __args...))
break;
}
}
return __r;
}
template <typename _Tp, enable_if_t<is_unsigned<_Tp>::value, int> = 0>
inline _LIBCPP_INLINE_VISIBILITY from_chars_result
__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
{
using __tx = __itoa::__traits<_Tp>;
using __output_type = typename __tx::type;
return __subject_seq_combinator(
__first, __last, __value,
[](const char* __first, const char* __last,
_Tp& __value) -> from_chars_result {
__output_type __a, __b;
auto __p = __tx::__read(__first, __last, __a, __b);
if (__p == __last || !__in_pattern(*__p))
{
__output_type __m = (numeric_limits<_Tp>::max)();
if (__m >= __a && __m - __a >= __b)
{
__value = __a + __b;
return {__p, {}};
}
}
return {__p, errc::result_out_of_range};
});
}
template <typename _Tp, enable_if_t<is_signed<_Tp>::value, int> = 0>
inline _LIBCPP_INLINE_VISIBILITY from_chars_result
__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
{
using __t = decltype(__to_unsigned(__value));
return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
}
template <typename _Tp, enable_if_t<is_unsigned<_Tp>::value, int> = 0>
inline _LIBCPP_INLINE_VISIBILITY from_chars_result
__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
int __base)
{
if (__base == 10)
return __from_chars_atoi(__first, __last, __value);
return __subject_seq_combinator(
__first, __last, __value,
[](const char* __p, const char* __last, _Tp& __value,
int __base) -> from_chars_result {
using __tl = numeric_limits<_Tp>;
auto __digits = __tl::digits / log2f(float(__base));
_Tp __a = __in_pattern(*__p++, __base).__val, __b = 0;
for (int __i = 1; __p != __last; ++__i, ++__p)
{
if (auto __c = __in_pattern(*__p, __base))
{
if (__i < __digits - 1)
__a = __a * __base + __c.__val;
else
{
if (!__itoa::__mul_overflowed(__a, __base, __a))
++__p;
__b = __c.__val;
break;
}
}
else
break;
}
if (__p == __last || !__in_pattern(*__p, __base))
{
if ((__tl::max)() - __a >= __b)
{
__value = __a + __b;
return {__p, {}};
}
}
return {__p, errc::result_out_of_range};
},
__base);
}
template <typename _Tp, enable_if_t<is_signed<_Tp>::value, int> = 0>
inline _LIBCPP_INLINE_VISIBILITY from_chars_result
__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
int __base)
{
using __t = decltype(__to_unsigned(__value));
return __sign_combinator(__first, __last, __value,
__from_chars_integral<__t>, __base);
}
template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
inline _LIBCPP_INLINE_VISIBILITY from_chars_result
from_chars(const char* __first, const char* __last, _Tp& __value)
{
return __from_chars_atoi(__first, __last, __value);
}
template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
inline _LIBCPP_INLINE_VISIBILITY from_chars_result
from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
{
_LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
return __from_chars_integral(__first, __last, __value, __base);
}
#endif // _LIBCPP_STD_VER > 11
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP_CHARCONV

File diff suppressed because it is too large Load Diff

View File

@@ -303,6 +303,7 @@ long double truncl(long double x);
#include <__config>
#include <math.h>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -547,7 +548,7 @@ hypot(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT
#endif
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type
__libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT
{
@@ -559,7 +560,7 @@ __libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT
}
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type
__libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT
{
@@ -567,7 +568,7 @@ __libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT
}
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type
__libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT
{
@@ -579,7 +580,7 @@ __libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT
}
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type
__libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT
{
@@ -587,7 +588,7 @@ __libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT
}
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type
__libcpp_isfinite_or_builtin(_A1 __lcpp_x) _NOEXCEPT
{
@@ -599,7 +600,7 @@ __libcpp_isfinite_or_builtin(_A1 __lcpp_x) _NOEXCEPT
}
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type
__libcpp_isfinite_or_builtin(_A1 __lcpp_x) _NOEXCEPT
{

View File

@@ -86,7 +86,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -121,7 +121,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -156,7 +156,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -186,11 +186,11 @@ class _LIBCPP_TEMPLATE_VIS codecvt_utf8
: public __codecvt_utf8<_Elem>
{
public:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt_utf8(size_t __refs = 0)
: __codecvt_utf8<_Elem>(__refs, _Maxcode, _Mode) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~codecvt_utf8() {}
};
@@ -209,7 +209,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -244,7 +244,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -279,7 +279,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -314,7 +314,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -349,7 +349,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -384,7 +384,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -414,11 +414,11 @@ class _LIBCPP_TEMPLATE_VIS codecvt_utf16
: public __codecvt_utf16<_Elem, _Mode & little_endian>
{
public:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt_utf16(size_t __refs = 0)
: __codecvt_utf16<_Elem, _Mode & little_endian>(__refs, _Maxcode, _Mode) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~codecvt_utf16() {}
};
@@ -437,7 +437,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -472,7 +472,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -507,7 +507,7 @@ public:
typedef char extern_type;
typedef mbstate_t state_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
codecvt_mode _Mode)
: codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
@@ -537,11 +537,11 @@ class _LIBCPP_TEMPLATE_VIS codecvt_utf8_utf16
: public __codecvt_utf8_utf16<_Elem>
{
public:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit codecvt_utf8_utf16(size_t __refs = 0)
: __codecvt_utf8_utf16<_Elem>(__refs, _Maxcode, _Mode) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~codecvt_utf8_utf16() {}
};

View File

@@ -88,14 +88,14 @@ public:
static const weak_equality equivalent;
static const weak_equality nonequivalent;
friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept;
friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept;
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept;
friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept;
#endif
private:
@@ -148,20 +148,20 @@ public:
static const strong_equality nonequivalent;
// conversion
constexpr operator weak_equality() const noexcept {
_LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept {
return __value_ == _EqResult::__zero ? weak_equality::equivalent
: weak_equality::nonequivalent;
}
// comparisons
friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept;
friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept;
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept;
friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept;
#endif
private:
_EqResult __value_;
@@ -235,22 +235,22 @@ public:
}
// comparisons
friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
#endif
private:
@@ -351,22 +351,22 @@ public:
}
// comparisons
friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
#endif
private:
@@ -477,22 +477,22 @@ public:
}
// comparisons
friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
#endif
private:

View File

@@ -245,6 +245,7 @@ template<class T, class charT, class traits>
#include <stdexcept>
#include <cmath>
#include <sstream>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header

View File

@@ -35,6 +35,7 @@ Types:
*/
#include <__config>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -50,7 +51,7 @@ using ::ptrdiff_t;
using ::size_t;
#if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) || \
defined(__DEFINED_max_align_t)
defined(__DEFINED_max_align_t) || defined(__NetBSD__)
// Re-use the compiler's <stddef.h> max_align_t where possible.
using ::max_align_t;
#else
@@ -66,10 +67,10 @@ enum class byte : unsigned char {};
constexpr byte operator| (byte __lhs, byte __rhs) noexcept
{
return static_cast<byte>(
static_cast<unsigned char>(
static_cast<unsigned int>(__lhs) | static_cast<unsigned int>(__rhs)
));
return static_cast<byte>(
static_cast<unsigned char>(
static_cast<unsigned int>(__lhs) | static_cast<unsigned int>(__rhs)
));
}
constexpr byte& operator|=(byte& __lhs, byte __rhs) noexcept
@@ -77,10 +78,10 @@ constexpr byte& operator|=(byte& __lhs, byte __rhs) noexcept
constexpr byte operator& (byte __lhs, byte __rhs) noexcept
{
return static_cast<byte>(
static_cast<unsigned char>(
static_cast<unsigned int>(__lhs) & static_cast<unsigned int>(__rhs)
));
return static_cast<byte>(
static_cast<unsigned char>(
static_cast<unsigned int>(__lhs) & static_cast<unsigned int>(__rhs)
));
}
constexpr byte& operator&=(byte& __lhs, byte __rhs) noexcept
@@ -88,13 +89,13 @@ constexpr byte& operator&=(byte& __lhs, byte __rhs) noexcept
constexpr byte operator^ (byte __lhs, byte __rhs) noexcept
{
return static_cast<byte>(
static_cast<unsigned char>(
static_cast<unsigned int>(__lhs) ^ static_cast<unsigned int>(__rhs)
));
return static_cast<byte>(
static_cast<unsigned char>(
static_cast<unsigned int>(__lhs) ^ static_cast<unsigned int>(__rhs)
));
}
constexpr byte& operator^=(byte& __lhs, byte __rhs) noexcept
constexpr byte& operator^=(byte& __lhs, byte __rhs) noexcept
{ return __lhs = __lhs ^ __rhs; }
constexpr byte operator~ (byte __b) noexcept

View File

@@ -151,11 +151,11 @@ using ::mbtowc;
using ::wctomb;
using ::mbstowcs;
using ::wcstombs;
#ifdef _LIBCPP_HAS_QUICK_EXIT
#if !defined(_LIBCPP_CXX03_LANG) && defined(_LIBCPP_HAS_QUICK_EXIT)
using ::at_quick_exit;
using ::quick_exit;
#endif
#ifdef _LIBCPP_HAS_C11_FEATURES
#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES)
using ::aligned_alloc;
#endif

View File

@@ -18,7 +18,8 @@ Macros:
NULL
CLOCKS_PER_SEC
TIME_UTC // C++17
namespace std
{
@@ -28,7 +29,8 @@ Types:
size_t
time_t
tm
timespec // C++17
clock_t clock();
double difftime(time_t time1, time_t time0);
time_t mktime(tm* timeptr);
@@ -39,7 +41,7 @@ tm* gmtime(const time_t* timer);
tm* localtime(const time_t* timer);
size_t strftime(char* restrict s, size_t maxsize, const char* restrict format,
const tm* restrict timeptr);
int timespec_get( struct timespec *ts, int base); // C++17
} // std
*/
@@ -57,6 +59,9 @@ using ::clock_t;
using ::size_t;
using ::time_t;
using ::tm;
#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES)
using ::timespec;
#endif
using ::clock;
using ::difftime;
using ::mktime;
@@ -68,6 +73,9 @@ using ::gmtime;
using ::localtime;
#endif
using ::strftime;
#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET)
using ::timespec_get;
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@@ -161,6 +161,7 @@ template <class T, class Allocator>
#include <iterator>
#include <algorithm>
#include <stdexcept>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header

View File

@@ -81,6 +81,7 @@ template <class E> void rethrow_if_nested(const E& e);
#include <cstddef>
#include <cstdlib>
#include <type_traits>
#include <version>
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
#include <vcruntime_exception.h>
@@ -163,7 +164,7 @@ public:
};
template<class _Ep>
exception_ptr
_LIBCPP_INLINE_VISIBILITY exception_ptr
make_exception_ptr(_Ep __e) _NOEXCEPT
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -222,7 +223,7 @@ _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr p);
template <class _E> void *__GetExceptionInfo(_E);
template<class _Ep>
exception_ptr
_LIBCPP_INLINE_VISIBILITY exception_ptr
make_exception_ptr(_Ep __e) _NOEXCEPT
{
return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e));
@@ -259,7 +260,7 @@ struct __throw_with_nested;
template <class _Tp, class _Up>
struct __throw_with_nested<_Tp, _Up, true> {
_LIBCPP_NORETURN static inline _LIBCPP_ALWAYS_INLINE void
_LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
#ifndef _LIBCPP_CXX03_LANG
__do_throw(_Tp&& __t)
#else
@@ -272,7 +273,7 @@ struct __throw_with_nested<_Tp, _Up, true> {
template <class _Tp, class _Up>
struct __throw_with_nested<_Tp, _Up, false> {
_LIBCPP_NORETURN static inline _LIBCPP_ALWAYS_INLINE void
_LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
#ifndef _LIBCPP_CXX03_LANG
__do_throw(_Tp&& __t)
#else

View File

@@ -52,8 +52,6 @@
#define _VSTD_CORO _VSTD_EXPERIMENTAL::coroutines_v1
#define _VSTD_FS ::std::experimental::filesystem::v1
#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD \
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 {
@@ -66,4 +64,11 @@
#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI \
} _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
// TODO: support more targets
#if defined(__AVX__)
#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 32
#else
#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 16
#endif
#endif

View File

@@ -283,6 +283,7 @@ public:
_LIBCPP_CONSTEXPR_AFTER_CXX17 void destroy() const _NOEXCEPT {}
private:
_LIBCPP_INLINE_VISIBILITY
friend coroutine_handle<noop_coroutine_promise> noop_coroutine() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT {

View File

@@ -1,305 +0,0 @@
// -*- C++ -*-
//===-------------------------- dynarray ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_DYNARRAY
#define _LIBCPP_DYNARRAY
/*
dynarray synopsis
namespace std { namespace experimental {
template< typename T >
class dynarray
{
// types:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef implementation-defined iterator;
typedef implementation-defined const_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
public:
// construct/copy/destroy:
explicit dynarray(size_type c);
dynarray(size_type c, const T& v);
dynarray(const dynarray& d);
dynarray(initializer_list<T>);
template <class Alloc>
dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc);
template <class Alloc>
dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc);
template <class Alloc>
dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc);
template <class Alloc>
dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);
dynarray& operator=(const dynarray&) = delete;
~dynarray();
// iterators:
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator crbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
// capacity:
size_type size() const noexcept;
size_type max_size() const noexcept;
bool empty() const noexcept;
// element access:
reference operator[](size_type n);
const_reference operator[](size_type n) const;
reference front();
const_reference front() const;
reference back();
const_reference back() const;
const_reference at(size_type n) const;
reference at(size_type n);
// data access:
T* data() noexcept;
const T* data() const noexcept;
// mutating member functions:
void fill(const T& v);
};
}} // std::experimental
*/
#include <__config>
#if _LIBCPP_STD_VER > 11
#include <__functional_base>
#include <iterator>
#include <stdexcept>
#include <initializer_list>
#include <new>
#include <algorithm>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
namespace std { namespace experimental { inline namespace __array_extensions_v1 {
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_DYNARRAY dynarray
{
public:
// types:
typedef dynarray __self;
typedef _Tp value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
private:
size_t __size_;
value_type * __base_;
_LIBCPP_ALWAYS_INLINE dynarray () noexcept : __size_(0), __base_(nullptr) {}
static inline _LIBCPP_INLINE_VISIBILITY
value_type* __allocate(size_t __count) {
if (numeric_limits<size_t>::max() / sizeof (value_type) <= __count)
__throw_bad_array_length();
return static_cast<value_type *>(
_VSTD::__libcpp_allocate(sizeof(value_type) * __count, __alignof(value_type)));
}
static inline _LIBCPP_INLINE_VISIBILITY
void __deallocate_value(value_type* __ptr ) noexcept {
_VSTD::__libcpp_deallocate(static_cast<void *>(__ptr), __alignof(value_type));
}
public:
_LIBCPP_INLINE_VISIBILITY
explicit dynarray(size_type __c);
_LIBCPP_INLINE_VISIBILITY
dynarray(size_type __c, const value_type& __v);
_LIBCPP_INLINE_VISIBILITY
dynarray(const dynarray& __d);
_LIBCPP_INLINE_VISIBILITY
dynarray(initializer_list<value_type>);
// We're not implementing these right now.
// Updated with the resolution of LWG issue #2255
// template <typename _Alloc>
// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c);
// template <typename _Alloc>
// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v);
// template <typename _Alloc>
// dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d);
// template <typename _Alloc>
// dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>);
dynarray& operator=(const dynarray&) = delete;
_LIBCPP_INLINE_VISIBILITY
~dynarray();
// iterators:
inline _LIBCPP_INLINE_VISIBILITY iterator begin() noexcept { return iterator(data()); }
inline _LIBCPP_INLINE_VISIBILITY const_iterator begin() const noexcept { return const_iterator(data()); }
inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); }
inline _LIBCPP_INLINE_VISIBILITY iterator end() noexcept { return iterator(data() + __size_); }
inline _LIBCPP_INLINE_VISIBILITY const_iterator end() const noexcept { return const_iterator(data() + __size_); }
inline _LIBCPP_INLINE_VISIBILITY const_iterator cend() const noexcept { return const_iterator(data() + __size_); }
inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
// capacity:
inline _LIBCPP_INLINE_VISIBILITY size_type size() const noexcept { return __size_; }
inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; }
inline _LIBCPP_INLINE_VISIBILITY bool empty() const noexcept { return __size_ == 0; }
// element access:
inline _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) { return data()[__n]; }
inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; }
inline _LIBCPP_INLINE_VISIBILITY reference front() { return data()[0]; }
inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; }
inline _LIBCPP_INLINE_VISIBILITY reference back() { return data()[__size_-1]; }
inline _LIBCPP_INLINE_VISIBILITY const_reference back() const { return data()[__size_-1]; }
inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const;
inline _LIBCPP_INLINE_VISIBILITY reference at(size_type __n);
// data access:
inline _LIBCPP_INLINE_VISIBILITY _Tp* data() noexcept { return __base_; }
inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; }
// mutating member functions:
inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); }
};
template <class _Tp>
inline
dynarray<_Tp>::dynarray(size_type __c) : dynarray ()
{
__base_ = __allocate (__c);
value_type *__data = data ();
for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
::new (__data) value_type;
}
template <class _Tp>
inline
dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray ()
{
__base_ = __allocate (__c);
value_type *__data = data ();
for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
::new (__data) value_type (__v);
}
template <class _Tp>
inline
dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray ()
{
size_t sz = __il.size();
__base_ = __allocate (sz);
value_type *__data = data ();
auto src = __il.begin();
for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
::new (__data) value_type (*src);
}
template <class _Tp>
inline
dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray ()
{
size_t sz = __d.size();
__base_ = __allocate (sz);
value_type *__data = data ();
auto src = __d.begin();
for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
::new (__data) value_type (*src);
}
template <class _Tp>
inline
dynarray<_Tp>::~dynarray()
{
value_type *__data = data () + __size_;
for ( size_t i = 0; i < __size_; ++i )
(--__data)->value_type::~value_type();
__deallocate_value( __base_ );
}
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
typename dynarray<_Tp>::reference
dynarray<_Tp>::at(size_type __n)
{
if (__n >= __size_)
__throw_out_of_range("dynarray::at");
return data()[__n];
}
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
typename dynarray<_Tp>::const_reference
dynarray<_Tp>::at(size_type __n) const
{
if (__n >= __size_)
__throw_out_of_range("dynarray::at");
return data()[__n];
}
}}}
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, class _Alloc>
struct _LIBCPP_TEMPLATE_VIS uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {};
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // if _LIBCPP_STD_VER > 11
#endif // _LIBCPP_DYNARRAY

File diff suppressed because it is too large Load Diff

View File

@@ -651,6 +651,7 @@ public:
*/
#include <experimental/__config>
#include <algorithm>
#include <array>
#include <cstddef>
#include <functional>
@@ -661,26 +662,246 @@ public:
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
#if _LIBCPP_STD_VER >= 17
enum class _StorageKind {
_Scalar,
_Array,
_VecExt,
};
template <_StorageKind __kind, int _Np>
struct __simd_abi {};
template <class _Tp, class _Abi>
struct __simd_storage_traits {};
class __simd_storage {};
template <class _Tp, int __num_element>
struct __simd_storage_traits<_Tp,
__simd_abi<_StorageKind::_Array, __num_element>> {
using type = std::array<_Tp, __num_element>;
class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> {
std::array<_Tp, __num_element> __storage_;
template <class, class>
friend struct simd;
template <class, class>
friend struct simd_mask;
public:
_Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
void __set(size_t __index, _Tp __val) noexcept {
__storage_[__index] = __val;
}
};
template <class _Tp>
struct __simd_storage_traits<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
using type = _Tp;
class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
_Tp __storage_;
template <class, class>
friend struct simd;
template <class, class>
friend struct simd_mask;
public:
_Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; };
void __set(size_t __index, _Tp __val) noexcept {
(&__storage_)[__index] = __val;
}
};
#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
constexpr size_t __floor_pow_of_2(size_t __val) {
return ((__val - 1) & __val) == 0 ? __val
: __floor_pow_of_2((__val - 1) & __val);
}
constexpr size_t __ceil_pow_of_2(size_t __val) {
return __val == 1 ? 1 : __floor_pow_of_2(__val - 1) << 1;
}
template <class _Tp, size_t __bytes>
struct __vec_ext_traits {
#if !defined(_LIBCPP_COMPILER_CLANG)
typedef _Tp type __attribute__((vector_size(__ceil_pow_of_2(__bytes))));
#endif
};
#if defined(_LIBCPP_COMPILER_CLANG)
#define _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT) \
template <> \
struct __vec_ext_traits<_TYPE, sizeof(_TYPE) * _NUM_ELEMENT> { \
using type = \
_TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT))); \
}
#define _LIBCPP_SPECIALIZE_VEC_EXT_32(_TYPE) \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 1); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 2); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 3); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 4); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 5); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 6); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 7); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 8); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 9); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 10); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 11); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 12); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 13); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 14); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 15); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 16); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 17); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 18); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 19); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 20); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 21); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 22); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 23); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 24); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 25); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 26); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 27); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 28); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 29); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 30); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 31); \
_LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 32);
_LIBCPP_SPECIALIZE_VEC_EXT_32(char);
_LIBCPP_SPECIALIZE_VEC_EXT_32(char16_t);
_LIBCPP_SPECIALIZE_VEC_EXT_32(char32_t);
_LIBCPP_SPECIALIZE_VEC_EXT_32(wchar_t);
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed char);
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed short);
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed int);
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long);
_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long long);
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned char);
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned short);
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned int);
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long);
_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long long);
_LIBCPP_SPECIALIZE_VEC_EXT_32(float);
_LIBCPP_SPECIALIZE_VEC_EXT_32(double);
_LIBCPP_SPECIALIZE_VEC_EXT_32(long double);
#undef _LIBCPP_SPECIALIZE_VEC_EXT_32
#undef _LIBCPP_SPECIALIZE_VEC_EXT
#endif
template <class _Tp, int __num_element>
class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> {
using _StorageType =
typename __vec_ext_traits<_Tp, sizeof(_Tp) * __num_element>::type;
_StorageType __storage_;
template <class, class>
friend struct simd;
template <class, class>
friend struct simd_mask;
public:
_Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
void __set(size_t __index, _Tp __val) noexcept {
__storage_[__index] = __val;
}
};
#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
template <class _Vp, class _Tp, class _Abi>
class __simd_reference {
static_assert(std::is_same<_Vp, _Tp>::value, "");
template <class, class>
friend struct simd;
template <class, class>
friend struct simd_mask;
__simd_storage<_Tp, _Abi>* __ptr_;
size_t __index_;
__simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index)
: __ptr_(__ptr), __index_(__index) {}
__simd_reference(const __simd_reference&) = default;
public:
__simd_reference() = delete;
__simd_reference& operator=(const __simd_reference&) = delete;
operator _Vp() const { return __ptr_->__get(__index_); }
__simd_reference operator=(_Vp __value) && {
__ptr_->__set(__index_, __value);
return *this;
}
__simd_reference operator++() && {
return std::move(*this) = __ptr_->__get(__index_) + 1;
}
_Vp operator++(int) && {
auto __val = __ptr_->__get(__index_);
__ptr_->__set(__index_, __val + 1);
return __val;
}
__simd_reference operator--() && {
return std::move(*this) = __ptr_->__get(__index_) - 1;
}
_Vp operator--(int) && {
auto __val = __ptr_->__get(__index_);
__ptr_->__set(__index_, __val - 1);
return __val;
}
__simd_reference operator+=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) + __value;
}
__simd_reference operator-=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) - __value;
}
__simd_reference operator*=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) * __value;
}
__simd_reference operator/=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) / __value;
}
__simd_reference operator%=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) % __value;
}
__simd_reference operator>>=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) >> __value;
}
__simd_reference operator<<=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) << __value;
}
__simd_reference operator&=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) & __value;
}
__simd_reference operator|=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) | __value;
}
__simd_reference operator^=(_Vp __value) && {
return std::move(*this) = __ptr_->__get(__index_) ^ __value;
}
};
template <class _To, class _From>
@@ -720,6 +941,17 @@ constexpr _Tp __variadic_sum(_Up __first, _Args... __rest) {
return static_cast<_Tp>(__first) + __variadic_sum<_Tp>(__rest...);
}
template <class _Tp>
struct __nodeduce {
using type = _Tp;
};
template <class _Tp>
constexpr bool __vectorizable() {
return std::is_arithmetic<_Tp>::value && !std::is_const<_Tp>::value &&
!std::is_volatile<_Tp>::value && !std::is_same<_Tp, bool>::value;
}
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD_ABI
@@ -728,14 +960,21 @@ using scalar = __simd_abi<_StorageKind::_Scalar, 1>;
template <int _Np>
using fixed_size = __simd_abi<_StorageKind::_Array, _Np>;
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR constexpr int max_fixed_size = 32;
#endif
_LIBCPP_INLINE_VAR constexpr size_t max_fixed_size = 32;
template <class _Tp>
using compatible = fixed_size<16 / sizeof(_Tp)>;
#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
template <class _Tp>
using native = compatible<_Tp>;
using native = __simd_abi<_StorageKind::_VecExt,
_LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>;
#else
template <class _Tp>
using native =
fixed_size<_Tp, _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>;
#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
@@ -749,14 +988,10 @@ struct element_aligned_tag {};
struct vector_aligned_tag {};
template <size_t>
struct overaligned_tag {};
#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VAR constexpr element_aligned_tag element_aligned{};
_LIBCPP_INLINE_VAR constexpr vector_aligned_tag vector_aligned{};
#if !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <size_t _Np>
_LIBCPP_INLINE_VAR constexpr overaligned_tag<_Np> overaligned{};
#endif
#endif
// traits [simd.traits]
template <class _Tp>
@@ -794,7 +1029,6 @@ template <size_t _Align>
struct is_simd_flag_type<overaligned_tag<_Align>>
: std::integral_constant<bool, true> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR constexpr bool is_abi_tag_v = is_abi_tag<_Tp>::value;
template <class _Tp>
@@ -804,7 +1038,6 @@ _LIBCPP_INLINE_VAR constexpr bool is_simd_mask_v = is_simd_mask<_Tp>::value;
template <class _Tp>
_LIBCPP_INLINE_VAR constexpr bool is_simd_flag_type_v =
is_simd_flag_type<_Tp>::value;
#endif
template <class _Tp, size_t _Np>
struct abi_for_size {
using type = simd_abi::fixed_size<_Np>;
@@ -824,17 +1057,16 @@ struct simd_size<_Tp, __simd_abi<__kind, _Np>>
"Element type should be vectorizable");
};
// TODO: implement it.
template <class _Tp, class _Up = typename _Tp::value_type>
struct memory_alignment;
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
_LIBCPP_INLINE_VAR constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value;
template <class _Tp, class _Up = typename _Tp::value_type>
_LIBCPP_INLINE_VAR constexpr size_t memory_alignment_v =
memory_alignment<_Tp, _Up>::value;
#endif
// class template simd [simd.class]
template <class _Tp>
@@ -972,11 +1204,6 @@ template <class _MaskType, class _Tp>
class where_expression;
// masked assignment [simd.mask.where]
template <class _Tp>
struct __nodeduce {
using type = _Tp;
};
template <class _Tp, class _Abi>
where_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>>
where(const typename simd<_Tp, _Abi>::mask_type&, simd<_Tp, _Abi>&) noexcept;
@@ -1113,7 +1340,23 @@ public:
// TODO: implement simd
template <class _Tp, class _Abi>
class simd {
public:
using value_type = _Tp;
using reference = __simd_reference<_Tp, _Tp, _Abi>;
using mask_type = simd_mask<_Tp, _Abi>;
using abi_type = _Abi;
simd() = default;
simd(const simd&) = default;
simd& operator=(const simd&) = default;
static constexpr size_t size() noexcept {
return simd_size<_Tp, _Abi>::value;
}
private:
__simd_storage<_Tp, _Abi> __s_;
template <class _Up>
static constexpr bool __can_broadcast() {
return (std::is_arithmetic<_Up>::value &&
@@ -1126,57 +1369,97 @@ private:
std::is_unsigned<_Tp>::value);
}
public:
using value_type = _Tp;
// TODO: this is strawman implementation. Turn it into a proxy type.
using reference = _Tp&;
using mask_type = simd_mask<_Tp, _Abi>;
using abi_type = _Abi;
static constexpr size_t size() noexcept {
return simd_size<_Tp, _Abi>::value;
template <class _Generator, size_t... __indicies>
static constexpr decltype(
std::forward_as_tuple(std::declval<_Generator>()(
std::integral_constant<size_t, __indicies>())...),
bool())
__can_generate(std::index_sequence<__indicies...>) {
return !__variadic_sum<bool>(
!__can_broadcast<decltype(std::declval<_Generator>()(
std::integral_constant<size_t, __indicies>()))>()...);
}
simd() = default;
template <class _Generator>
static bool __can_generate(...) {
return false;
}
template <class _Generator, size_t... __indicies>
void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) {
int __not_used[]{((*this)[__indicies] =
__g(std::integral_constant<size_t, __indicies>()),
0)...};
(void)__not_used;
}
public:
// implicit type conversion constructor
template <class _Up,
class = typename std::enable_if<
std::is_same<_Abi, simd_abi::fixed_size<size()>>::value &&
__is_non_narrowing_arithmetic_convertible<_Up, _Tp>()>::type>
simd(const simd<_Up, simd_abi::fixed_size<size()>>&) {}
simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) {
for (size_t __i = 0; __i < size(); __i++) {
(*this)[__i] = static_cast<_Tp>(__v[__i]);
}
}
// implicit broadcast constructor
template <class _Up,
class = typename std::enable_if<__can_broadcast<_Up>()>::type>
simd(_Up&&);
simd(_Up&& __rv) {
auto __v = static_cast<_Tp>(__rv);
for (size_t __i = 0; __i < size(); __i++) {
(*this)[__i] = __v;
}
}
// generator constructor
// TODO: for now only check for the index 0. This is because C++11 doesn't
// have index_sequence, and it's hard to check for all indicies without using
// index_sequence.
template <class _Generator,
int = decltype(simd(std::declval<_Generator>()(
std::integral_constant<size_t, 0>())),
int())()>
explicit simd(_Generator&&);
int = typename std::enable_if<
__can_generate<_Generator>(std::make_index_sequence<size()>()),
int>::type()>
explicit simd(_Generator&& __g) {
__generator_init(std::forward<_Generator>(__g),
std::make_index_sequence<size()>());
}
// load constructor
template <class _Up, class _Flags>
simd(const _Up*, _Flags);
template <
class _Up, class _Flags,
class = typename std::enable_if<__vectorizable<_Up>()>::type,
class = typename std::enable_if<is_simd_flag_type<_Flags>::value>::type>
simd(const _Up* __buffer, _Flags) {
// TODO: optimize for overaligned flags
for (size_t __i = 0; __i < size(); __i++) {
(*this)[__i] = static_cast<_Tp>(__buffer[__i]);
}
}
// loads [simd.load]
template <class _Up, class _Flags>
void copy_from(const _Up*, _Flags);
typename std::enable_if<__vectorizable<_Up>() &&
is_simd_flag_type<_Flags>::value>::type
copy_from(const _Up* __buffer, _Flags) {
*this = simd(__buffer, _Flags());
}
// stores [simd.store]
template <class _Up, class _Flags>
void copy_to(_Up*, _Flags) const;
typename std::enable_if<__vectorizable<_Up>() &&
is_simd_flag_type<_Flags>::value>::type
copy_to(_Up* __buffer, _Flags) const {
// TODO: optimize for overaligned flags
for (size_t __i = 0; __i < size(); __i++) {
__buffer[__i] = static_cast<_Up>((*this)[__i]);
}
}
// scalar access [simd.subscr]
reference operator[](size_t);
value_type operator[](size_t) const;
reference operator[](size_t __i) { return reference(&__s_, __i); }
value_type operator[](size_t __i) const { return __s_.__get(__i); }
// unary operators [simd.unary]
simd& operator++();
@@ -1280,6 +1563,8 @@ public:
friend simd_mask operator!=(const simd_mask&, const simd_mask&) noexcept;
};
#endif // _LIBCPP_STD_VER >= 17
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
#endif /* _LIBCPP_EXPERIMENTAL_SIMD */

2679
include/filesystem Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,14 @@ Macros:
DBL_MANT_DIG
LDBL_MANT_DIG
FLT_HAS_SUBNORM // C11
DBL_HAS_SUBNORM // C11
LDBL_HAS_SUBNORM // C11
DECIMAL_DIG // C99
FLT_DECIMAL_DIG // C11
DBL_DECIMAL_DIG // C11
LDBL_DECIMAL_DIG // C11
FLT_DIG
DBL_DIG
@@ -58,6 +65,10 @@ Macros:
DBL_MIN
LDBL_MIN
FLT_TRUE_MIN // C11
DBL_TRUE_MIN // C11
LDBL_TRUE_MIN // C11
*/
#include <__config>

View File

@@ -177,6 +177,7 @@ template <class T, class Allocator>
#include <limits>
#include <iterator>
#include <algorithm>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header

View File

@@ -38,6 +38,7 @@ public:
bool is_open() const;
basic_filebuf* open(const char* s, ios_base::openmode mode);
basic_filebuf* open(const string& s, ios_base::openmode mode);
basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17
basic_filebuf* close();
protected:
@@ -77,6 +78,8 @@ public:
basic_ifstream();
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
explicit basic_ifstream(const filesystem::path& p,
ios_base::openmode mode = ios_base::in); // C++17
basic_ifstream(basic_ifstream&& rhs);
basic_ifstream& operator=(basic_ifstream&& rhs);
@@ -86,6 +89,8 @@ public:
bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::in);
void open(const string& s, ios_base::openmode mode = ios_base::in);
void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17
void close();
};
@@ -110,6 +115,8 @@ public:
basic_ofstream();
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
explicit basic_ofstream(const filesystem::path& p,
ios_base::openmode mode = ios_base::out); // C++17
basic_ofstream(basic_ofstream&& rhs);
basic_ofstream& operator=(basic_ofstream&& rhs);
@@ -119,6 +126,9 @@ public:
bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::out);
void open(const string& s, ios_base::openmode mode = ios_base::out);
void open(const filesystem::path& p,
ios_base::openmode mode = ios_base::out); // C++17
void close();
};
@@ -143,6 +153,8 @@ public:
basic_fstream();
explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
explicit basic_fstream(const filesystem::path& p,
ios_base::openmode mode = ios_base::in|ios_base::out); C++17
basic_fstream(basic_fstream&& rhs);
basic_fstream& operator=(basic_fstream&& rhs);
@@ -152,6 +164,9 @@ public:
bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
void open(const filesystem::path& s,
ios_base::openmode mode = ios_base::in|ios_base::out); // C++17
void close();
};
@@ -170,6 +185,8 @@ typedef basic_fstream<wchar_t> wfstream;
#include <istream>
#include <__locale>
#include <cstdio>
#include <cstdlib>
#include <filesystem>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -217,10 +234,23 @@ public:
#endif
_LIBCPP_INLINE_VISIBILITY
basic_filebuf* open(const string& __s, ios_base::openmode __mode);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) {
return open(__p.c_str(), __mode);
}
#endif
_LIBCPP_INLINE_VISIBILITY
basic_filebuf* __open(int __fd, ios_base::openmode __mode);
#endif
basic_filebuf* close();
protected:
_LIBCPP_INLINE_VISIBILITY
inline static const char*
__make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
protected:
// 27.9.1.5 Overridden virtual functions:
virtual int_type underflow();
virtual int_type pbackfail(int_type __c = traits_type::eof());
@@ -234,25 +264,25 @@ protected:
virtual void imbue(const locale& __loc);
private:
char* __extbuf_;
const char* __extbufnext_;
const char* __extbufend_;
char __extbuf_min_[8];
size_t __ebs_;
char_type* __intbuf_;
size_t __ibs_;
FILE* __file_;
const codecvt<char_type, char, state_type>* __cv_;
state_type __st_;
state_type __st_last_;
ios_base::openmode __om_;
ios_base::openmode __cm_;
bool __owns_eb_;
bool __owns_ib_;
bool __always_noconv_;
char* __extbuf_;
const char* __extbufnext_;
const char* __extbufend_;
char __extbuf_min_[8];
size_t __ebs_;
char_type* __intbuf_;
size_t __ibs_;
FILE* __file_;
const codecvt<char_type, char, state_type>* __cv_;
state_type __st_;
state_type __st_last_;
ios_base::openmode __om_;
ios_base::openmode __cm_;
bool __owns_eb_;
bool __owns_ib_;
bool __always_noconv_;
bool __read_mode();
void __write_mode();
bool __read_mode();
void __write_mode();
};
template <class _CharT, class _Traits>
@@ -473,6 +503,46 @@ basic_filebuf<_CharT, _Traits>::is_open() const
return __file_ != 0;
}
template <class _CharT, class _Traits>
const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(
ios_base::openmode __mode) _NOEXCEPT {
switch (__mode & ~ios_base::ate) {
case ios_base::out:
case ios_base::out | ios_base::trunc:
return "w";
case ios_base::out | ios_base::app:
case ios_base::app:
return "a";
case ios_base::in:
return "r";
case ios_base::in | ios_base::out:
return "r+";
case ios_base::in | ios_base::out | ios_base::trunc:
return "w+";
case ios_base::in | ios_base::out | ios_base::app:
case ios_base::in | ios_base::app:
return "a+";
case ios_base::out | ios_base::binary:
case ios_base::out | ios_base::trunc | ios_base::binary:
return "wb";
case ios_base::out | ios_base::app | ios_base::binary:
case ios_base::app | ios_base::binary:
return "ab";
case ios_base::in | ios_base::binary:
return "rb";
case ios_base::in | ios_base::out | ios_base::binary:
return "r+b";
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
return "w+b";
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
case ios_base::in | ios_base::app | ios_base::binary:
return "a+b";
default:
return nullptr;
}
_LIBCPP_UNREACHABLE();
}
#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>*
@@ -481,79 +551,49 @@ basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
basic_filebuf<_CharT, _Traits>* __rt = 0;
if (__file_ == 0)
{
if (const char* __mdstr = __make_mdstring(__mode)) {
__rt = this;
const char* __mdstr;
switch (__mode & ~ios_base::ate)
{
case ios_base::out:
case ios_base::out | ios_base::trunc:
__mdstr = "w";
break;
case ios_base::out | ios_base::app:
case ios_base::app:
__mdstr = "a";
break;
case ios_base::in:
__mdstr = "r";
break;
case ios_base::in | ios_base::out:
__mdstr = "r+";
break;
case ios_base::in | ios_base::out | ios_base::trunc:
__mdstr = "w+";
break;
case ios_base::in | ios_base::out | ios_base::app:
case ios_base::in | ios_base::app:
__mdstr = "a+";
break;
case ios_base::out | ios_base::binary:
case ios_base::out | ios_base::trunc | ios_base::binary:
__mdstr = "wb";
break;
case ios_base::out | ios_base::app | ios_base::binary:
case ios_base::app | ios_base::binary:
__mdstr = "ab";
break;
case ios_base::in | ios_base::binary:
__mdstr = "rb";
break;
case ios_base::in | ios_base::out | ios_base::binary:
__mdstr = "r+b";
break;
case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
__mdstr = "w+b";
break;
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
case ios_base::in | ios_base::app | ios_base::binary:
__mdstr = "a+b";
break;
default:
__rt = 0;
break;
}
if (__rt)
{
__file_ = fopen(__s, __mdstr);
if (__file_)
{
__om_ = __mode;
if (__mode & ios_base::ate)
{
if (fseek(__file_, 0, SEEK_END))
{
fclose(__file_);
__file_ = 0;
__rt = 0;
}
}
__file_ = fopen(__s, __mdstr);
if (__file_) {
__om_ = __mode;
if (__mode & ios_base::ate) {
if (fseek(__file_, 0, SEEK_END)) {
fclose(__file_);
__file_ = 0;
__rt = 0;
}
else
__rt = 0;
}
}
} else
__rt = 0;
}
}
return __rt;
}
template <class _CharT, class _Traits>
_LIBCPP_INLINE_VISIBILITY basic_filebuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
basic_filebuf<_CharT, _Traits>* __rt = 0;
if (__file_ == 0) {
if (const char* __mdstr = __make_mdstring(__mode)) {
__rt = this;
__file_ = fdopen(__fd, __mdstr);
if (__file_) {
__om_ = __mode;
if (__mode & ios_base::ate) {
if (fseek(__file_, 0, SEEK_END)) {
fclose(__file_);
__file_ = 0;
__rt = 0;
}
}
} else
__rt = 0;
}
}
return __rt;
}
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
// This is basically the same as the char* overload except that it uses _wfopen
// and long mode strings.
@@ -1110,6 +1150,11 @@ public:
#endif
_LIBCPP_INLINE_VISIBILITY
explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
: basic_ifstream(__p.c_str(), __mode) {}
#endif // _LIBCPP_STD_VER >= 17
#endif
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
@@ -1131,6 +1176,16 @@ public:
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
#endif
void open(const string& __s, ios_base::openmode __mode = ios_base::in);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
void open(const filesystem::path& __p,
ios_base::openmode __mode = ios_base::in) {
return open(__p.c_str(), __mode);
}
#endif // _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
void __open(int __fd, ios_base::openmode __mode);
#endif
_LIBCPP_INLINE_VISIBILITY
void close();
@@ -1265,6 +1320,15 @@ basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo
else
this->setstate(ios_base::failbit);
}
template <class _CharT, class _Traits>
void basic_ifstream<_CharT, _Traits>::__open(int __fd,
ios_base::openmode __mode) {
if (__sb_.__open(__fd, __mode | ios_base::in))
this->clear();
else
this->setstate(ios_base::failbit);
}
#endif
template <class _CharT, class _Traits>
@@ -1299,6 +1363,13 @@ public:
#endif
_LIBCPP_INLINE_VISIBILITY
explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
: basic_ofstream(__p.c_str(), __mode) {}
#endif // _LIBCPP_STD_VER >= 17
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
basic_ofstream(basic_ofstream&& __rhs);
@@ -1319,6 +1390,15 @@ public:
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
#endif
void open(const string& __s, ios_base::openmode __mode = ios_base::out);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
{ return open(__p.c_str(), __mode); }
#endif // _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
void __open(int __fd, ios_base::openmode __mode);
#endif
_LIBCPP_INLINE_VISIBILITY
void close();
@@ -1453,6 +1533,15 @@ basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo
else
this->setstate(ios_base::failbit);
}
template <class _CharT, class _Traits>
void basic_ofstream<_CharT, _Traits>::__open(int __fd,
ios_base::openmode __mode) {
if (__sb_.__open(__fd, __mode | ios_base::out))
this->clear();
else
this->setstate(ios_base::failbit);
}
#endif
template <class _CharT, class _Traits>
@@ -1488,6 +1577,13 @@ public:
#endif
_LIBCPP_INLINE_VISIBILITY
explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
: basic_fstream(__p.c_str(), __mode) {}
#endif // _LIBCPP_STD_VER >= 17
#endif
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
@@ -1509,6 +1605,13 @@ public:
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#endif
void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#if _LIBCPP_STD_VER >= 17
_LIBCPP_INLINE_VISIBILITY
void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in|ios_base::out)
{ return open(__p.c_str(), __mode); }
#endif // _LIBCPP_STD_VER >= 17
#endif
_LIBCPP_INLINE_VISIBILITY
void close();

View File

@@ -68,6 +68,11 @@ template <class T> reference_wrapper<const T> cref(const T& t) noexcept;
template <class T> void cref(const T&& t) = delete;
template <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
template <class T> struct unwrap_reference; // since C++20
template <class T> struct unwrap_ref_decay : unwrap_reference<decay_t<T>> { }; // since C++20
template <class T> using unwrap_reference_t = typename unwrap_reference<T>::type; // since C++20
template <class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; // since C++20
template <class T> // <class T=void> in C++14
struct plus : binary_function<T, T, T>
{
@@ -183,7 +188,7 @@ struct bit_xor : unary_function<T, bool>
};
template <class Predicate>
class unary_negate
class unary_negate // deprecated in C++17
: public unary_function<typename Predicate::argument_type, bool>
{
public:
@@ -191,10 +196,11 @@ public:
bool operator()(const typename Predicate::argument_type& x) const;
};
template <class Predicate> unary_negate<Predicate> not1(const Predicate& pred);
template <class Predicate> // deprecated in C++17
unary_negate<Predicate> not1(const Predicate& pred);
template <class Predicate>
class binary_negate
class binary_negate // deprecated in C++17
: public binary_function<typename Predicate::first_argument_type,
typename Predicate::second_argument_type,
bool>
@@ -205,7 +211,8 @@ public:
const typename Predicate::second_argument_type& y) const;
};
template <class Predicate> binary_negate<Predicate> not2(const Predicate& pred);
template <class Predicate> // deprecated in C++17
binary_negate<Predicate> not2(const Predicate& pred);
template <class F> unspecified not_fn(F&& f); // C++17
@@ -487,6 +494,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited
#include <memory>
#include <tuple>
#include <utility>
#include <version>
#include <__functional_base>
@@ -980,7 +988,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_not<void>
#endif
template <class _Predicate>
class _LIBCPP_TEMPLATE_VIS unary_negate
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate
: public unary_function<typename _Predicate::argument_type, bool>
{
_Predicate __pred_;
@@ -994,19 +1002,19 @@ public:
};
template <class _Predicate>
inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
unary_negate<_Predicate>
not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);}
template <class _Predicate>
class _LIBCPP_TEMPLATE_VIS binary_negate
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate
: public binary_function<typename _Predicate::first_argument_type,
typename _Predicate::second_argument_type,
bool>
{
_Predicate __pred_;
public:
_LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11
_LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11
binary_negate(const _Predicate& __pred) : __pred_(__pred) {}
_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
@@ -1016,13 +1024,13 @@ public:
};
template <class _Predicate>
inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
binary_negate<_Predicate>
not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);}
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS)
template <class __Operation>
class _LIBCPP_TEMPLATE_VIS binder1st
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st
: public unary_function<typename __Operation::second_argument_type,
typename __Operation::result_type>
{
@@ -1042,13 +1050,13 @@ public:
};
template <class __Operation, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
binder1st<__Operation>
bind1st(const __Operation& __op, const _Tp& __x)
{return binder1st<__Operation>(__op, __x);}
template <class __Operation>
class _LIBCPP_TEMPLATE_VIS binder2nd
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd
: public unary_function<typename __Operation::first_argument_type,
typename __Operation::result_type>
{
@@ -1068,13 +1076,13 @@ public:
};
template <class __Operation, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
binder2nd<__Operation>
bind2nd(const __Operation& __op, const _Tp& __x)
{return binder2nd<__Operation>(__op, __x);}
template <class _Arg, class _Result>
class _LIBCPP_TEMPLATE_VIS pointer_to_unary_function
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function
: public unary_function<_Arg, _Result>
{
_Result (*__f_)(_Arg);
@@ -1086,13 +1094,13 @@ public:
};
template <class _Arg, class _Result>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
pointer_to_unary_function<_Arg,_Result>
ptr_fun(_Result (*__f)(_Arg))
{return pointer_to_unary_function<_Arg,_Result>(__f);}
template <class _Arg1, class _Arg2, class _Result>
class _LIBCPP_TEMPLATE_VIS pointer_to_binary_function
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function
: public binary_function<_Arg1, _Arg2, _Result>
{
_Result (*__f_)(_Arg1, _Arg2);
@@ -1104,13 +1112,14 @@ public:
};
template <class _Arg1, class _Arg2, class _Result>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
pointer_to_binary_function<_Arg1,_Arg2,_Result>
ptr_fun(_Result (*__f)(_Arg1,_Arg2))
{return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);}
template<class _Sp, class _Tp>
class _LIBCPP_TEMPLATE_VIS mem_fun_t : public unary_function<_Tp*, _Sp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t
: public unary_function<_Tp*, _Sp>
{
_Sp (_Tp::*__p_)();
public:
@@ -1121,7 +1130,8 @@ public:
};
template<class _Sp, class _Tp, class _Ap>
class _LIBCPP_TEMPLATE_VIS mem_fun1_t : public binary_function<_Tp*, _Ap, _Sp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t
: public binary_function<_Tp*, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap);
public:
@@ -1132,19 +1142,20 @@ public:
};
template<class _Sp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
mem_fun_t<_Sp,_Tp>
mem_fun(_Sp (_Tp::*__f)())
{return mem_fun_t<_Sp,_Tp>(__f);}
template<class _Sp, class _Tp, class _Ap>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
mem_fun1_t<_Sp,_Tp,_Ap>
mem_fun(_Sp (_Tp::*__f)(_Ap))
{return mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
template<class _Sp, class _Tp>
class _LIBCPP_TEMPLATE_VIS mem_fun_ref_t : public unary_function<_Tp, _Sp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t
: public unary_function<_Tp, _Sp>
{
_Sp (_Tp::*__p_)();
public:
@@ -1155,7 +1166,8 @@ public:
};
template<class _Sp, class _Tp, class _Ap>
class _LIBCPP_TEMPLATE_VIS mem_fun1_ref_t : public binary_function<_Tp, _Ap, _Sp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t
: public binary_function<_Tp, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap);
public:
@@ -1166,19 +1178,20 @@ public:
};
template<class _Sp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
mem_fun_ref_t<_Sp,_Tp>
mem_fun_ref(_Sp (_Tp::*__f)())
{return mem_fun_ref_t<_Sp,_Tp>(__f);}
template<class _Sp, class _Tp, class _Ap>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
mem_fun1_ref_t<_Sp,_Tp,_Ap>
mem_fun_ref(_Sp (_Tp::*__f)(_Ap))
{return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
template <class _Sp, class _Tp>
class _LIBCPP_TEMPLATE_VIS const_mem_fun_t : public unary_function<const _Tp*, _Sp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t
: public unary_function<const _Tp*, _Sp>
{
_Sp (_Tp::*__p_)() const;
public:
@@ -1189,7 +1202,8 @@ public:
};
template <class _Sp, class _Tp, class _Ap>
class _LIBCPP_TEMPLATE_VIS const_mem_fun1_t : public binary_function<const _Tp*, _Ap, _Sp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t
: public binary_function<const _Tp*, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap) const;
public:
@@ -1200,19 +1214,20 @@ public:
};
template <class _Sp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
const_mem_fun_t<_Sp,_Tp>
mem_fun(_Sp (_Tp::*__f)() const)
{return const_mem_fun_t<_Sp,_Tp>(__f);}
template <class _Sp, class _Tp, class _Ap>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
const_mem_fun1_t<_Sp,_Tp,_Ap>
mem_fun(_Sp (_Tp::*__f)(_Ap) const)
{return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
template <class _Sp, class _Tp>
class _LIBCPP_TEMPLATE_VIS const_mem_fun_ref_t : public unary_function<_Tp, _Sp>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t
: public unary_function<_Tp, _Sp>
{
_Sp (_Tp::*__p_)() const;
public:
@@ -1223,7 +1238,7 @@ public:
};
template <class _Sp, class _Tp, class _Ap>
class _LIBCPP_TEMPLATE_VIS const_mem_fun1_ref_t
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t
: public binary_function<_Tp, _Ap, _Sp>
{
_Sp (_Tp::*__p_)(_Ap) const;
@@ -1235,13 +1250,13 @@ public:
};
template <class _Sp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
const_mem_fun_ref_t<_Sp,_Tp>
mem_fun_ref(_Sp (_Tp::*__f)() const)
{return const_mem_fun_ref_t<_Sp,_Tp>(__f);}
template <class _Sp, class _Tp, class _Ap>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY
const_mem_fun1_ref_t<_Sp,_Tp,_Ap>
mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const)
{return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
@@ -1399,13 +1414,13 @@ public:
#endif
};
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_bad_function_call()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_function_call();
#else
_VSTD::abort();
_VSTD::abort();
#endif
}
@@ -1790,7 +1805,7 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp _
typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF;
typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
_Ap __a(__a0);
if (sizeof(_FF) <= sizeof(__buf_) &&
if (sizeof(_FF) <= sizeof(__buf_) &&
is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value)
{
__f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f), _Alloc(__a));
@@ -2005,7 +2020,7 @@ namespace placeholders
template <int _Np> struct __ph {};
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND)
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
_LIBCPP_FUNC_VIS extern const __ph<1> _1;
_LIBCPP_FUNC_VIS extern const __ph<2> _2;
_LIBCPP_FUNC_VIS extern const __ph<3> _3;
@@ -2027,7 +2042,7 @@ _LIBCPP_FUNC_VIS extern const __ph<10> _10;
/* _LIBCPP_INLINE_VAR */ constexpr __ph<8> _8{};
/* _LIBCPP_INLINE_VAR */ constexpr __ph<9> _9{};
/* _LIBCPP_INLINE_VAR */ constexpr __ph<10> _10{};
#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND)
#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
} // placeholders
@@ -2105,53 +2120,53 @@ __mu(_Ti& __ti, _Uj&)
template <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh,
class _TupleUj>
struct ____mu_return;
struct __mu_return_impl;
template <bool _Invokable, class _Ti, class ..._Uj>
struct ____mu_return_invokable // false
struct __mu_return_invokable // false
{
typedef __nat type;
};
template <class _Ti, class ..._Uj>
struct ____mu_return_invokable<true, _Ti, _Uj...>
struct __mu_return_invokable<true, _Ti, _Uj...>
{
typedef typename __invoke_of<_Ti&, _Uj...>::type type;
};
template <class _Ti, class ..._Uj>
struct ____mu_return<_Ti, false, true, false, tuple<_Uj...> >
: public ____mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> >
: public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
{
};
template <class _Ti, class _TupleUj>
struct ____mu_return<_Ti, false, false, true, _TupleUj>
struct __mu_return_impl<_Ti, false, false, true, _TupleUj>
{
typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
_TupleUj>::type&& type;
};
template <class _Ti, class _TupleUj>
struct ____mu_return<_Ti, true, false, false, _TupleUj>
struct __mu_return_impl<_Ti, true, false, false, _TupleUj>
{
typedef typename _Ti::type& type;
};
template <class _Ti, class _TupleUj>
struct ____mu_return<_Ti, false, false, false, _TupleUj>
struct __mu_return_impl<_Ti, false, false, false, _TupleUj>
{
typedef _Ti& type;
};
template <class _Ti, class _TupleUj>
struct __mu_return
: public ____mu_return<_Ti,
__is_reference_wrapper<_Ti>::value,
is_bind_expression<_Ti>::value,
0 < is_placeholder<_Ti>::value &&
is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value,
_TupleUj>
: public __mu_return_impl<_Ti,
__is_reference_wrapper<_Ti>::value,
is_bind_expression<_Ti>::value,
0 < is_placeholder<_Ti>::value &&
is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value,
_TupleUj>
{
};
@@ -2340,8 +2355,6 @@ bind(_Fp&& __f, _BoundArgs&&... __bound_args)
#if _LIBCPP_STD_VER > 14
#define __cpp_lib_invoke 201411
template <class _Fn, class ..._Args>
result_of_t<_Fn&&(_Args&&...)>
invoke(_Fn&& __f, _Args&&... __args)
@@ -2497,7 +2510,7 @@ template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
class _LIBCPP_TYPE_VIS default_searcher {
public:
_LIBCPP_INLINE_VISIBILITY
default_searcher(_ForwardIterator __f, _ForwardIterator __l,
default_searcher(_ForwardIterator __f, _ForwardIterator __l,
_BinaryPredicate __p = _BinaryPredicate())
: __first_(__f), __last_(__l), __pred_(__p) {}
@@ -2519,6 +2532,14 @@ private:
#endif // _LIBCPP_STD_VER > 14
#if _LIBCPP_STD_VER > 17
template <class _Tp>
using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
template <class _Tp>
using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
#endif // > C++17
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_FUNCTIONAL

View File

@@ -409,7 +409,7 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
#ifdef _LIBCXX_UNDERLYING_TYPE
#ifdef _LIBCPP_UNDERLYING_TYPE
typedef underlying_type<launch>::type __launch_underlying_type;
#else
typedef int __launch_underlying_type;
@@ -514,7 +514,7 @@ public:
virtual ~future_error() _NOEXCEPT;
};
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
#ifndef _LIBCPP_NO_EXCEPTIONS
_LIBCPP_AVAILABILITY_FUTURE_ERROR
#endif
@@ -556,13 +556,14 @@ public:
{return (__state_ & __constructed) || (__exception_ != nullptr);}
_LIBCPP_INLINE_VISIBILITY
void __set_future_attached()
{
void __attach_future() {
lock_guard<mutex> __lk(__mut_);
bool __has_future_attached = (__state_ & __future_attached) != 0;
if (__has_future_attached)
__throw_future_error(future_errc::future_already_retrieved);
this->__add_shared();
__state_ |= __future_attached;
}
_LIBCPP_INLINE_VISIBILITY
bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
_LIBCPP_INLINE_VISIBILITY
void __set_deferred() {__state_ |= deferred;}
@@ -1154,10 +1155,7 @@ template <class _Rp>
future<_Rp>::future(__assoc_state<_Rp>* __state)
: __state_(__state)
{
if (__state_->__has_future_attached())
__throw_future_error(future_errc::future_already_retrieved);
__state_->__add_shared();
__state_->__set_future_attached();
__state_->__attach_future();
}
struct __release_shared_count
@@ -1257,10 +1255,7 @@ template <class _Rp>
future<_Rp&>::future(__assoc_state<_Rp&>* __state)
: __state_(__state)
{
if (__state_->__has_future_attached())
__throw_future_error(future_errc::future_already_retrieved);
__state_->__add_shared();
__state_->__set_future_attached();
__state_->__attach_future();
}
template <class _Rp>

View File

@@ -61,7 +61,7 @@ class _LIBCPP_TEMPLATE_VIS initializer_list
const _Ep* __begin_;
size_t __size_;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_AFTER_CXX11
initializer_list(const _Ep* __b, size_t __s) _NOEXCEPT
: __begin_(__b),
@@ -76,19 +76,19 @@ public:
typedef const _Ep* iterator;
typedef const _Ep* const_iterator;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_AFTER_CXX11
initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_AFTER_CXX11
size_t size() const _NOEXCEPT {return __size_;}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_AFTER_CXX11
const _Ep* begin() const _NOEXCEPT {return __begin_;}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_AFTER_CXX11
const _Ep* end() const _NOEXCEPT {return __begin_ + __size_;}
};

View File

@@ -46,6 +46,7 @@ template <class charT, class traits, class Allocator>
#include <__config>
#include <__string>
#include <istream>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header

View File

@@ -337,9 +337,9 @@ protected:
}
void init(void* __sb);
_LIBCPP_ALWAYS_INLINE void* rdbuf() const {return __rdbuf_;}
_LIBCPP_INLINE_VISIBILITY void* rdbuf() const {return __rdbuf_;}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
void rdbuf(void* __sb)
{
__rdbuf_ = __sb;
@@ -351,7 +351,7 @@ protected:
void move(ios_base&);
void swap(ios_base&) _NOEXCEPT;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
void set_rdbuf(void* __sb)
{
__rdbuf_ = __sb;
@@ -599,26 +599,26 @@ public:
// we give it internal linkage.
#if defined(_LIBCPP_CXX03_LANG)
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
operator __cxx03_bool::__bool_type() const {
return !fail() ? &__cxx03_bool::__true_value : nullptr;
}
#else
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_EXPLICIT operator bool() const {return !fail();}
#endif
_LIBCPP_ALWAYS_INLINE bool operator!() const {return fail();}
_LIBCPP_ALWAYS_INLINE iostate rdstate() const {return ios_base::rdstate();}
_LIBCPP_ALWAYS_INLINE void clear(iostate __state = goodbit) {ios_base::clear(__state);}
_LIBCPP_ALWAYS_INLINE void setstate(iostate __state) {ios_base::setstate(__state);}
_LIBCPP_ALWAYS_INLINE bool good() const {return ios_base::good();}
_LIBCPP_ALWAYS_INLINE bool eof() const {return ios_base::eof();}
_LIBCPP_ALWAYS_INLINE bool fail() const {return ios_base::fail();}
_LIBCPP_ALWAYS_INLINE bool bad() const {return ios_base::bad();}
_LIBCPP_INLINE_VISIBILITY bool operator!() const {return fail();}
_LIBCPP_INLINE_VISIBILITY iostate rdstate() const {return ios_base::rdstate();}
_LIBCPP_INLINE_VISIBILITY void clear(iostate __state = goodbit) {ios_base::clear(__state);}
_LIBCPP_INLINE_VISIBILITY void setstate(iostate __state) {ios_base::setstate(__state);}
_LIBCPP_INLINE_VISIBILITY bool good() const {return ios_base::good();}
_LIBCPP_INLINE_VISIBILITY bool eof() const {return ios_base::eof();}
_LIBCPP_INLINE_VISIBILITY bool fail() const {return ios_base::fail();}
_LIBCPP_INLINE_VISIBILITY bool bad() const {return ios_base::bad();}
_LIBCPP_ALWAYS_INLINE iostate exceptions() const {return ios_base::exceptions();}
_LIBCPP_ALWAYS_INLINE void exceptions(iostate __iostate) {ios_base::exceptions(__iostate);}
_LIBCPP_INLINE_VISIBILITY iostate exceptions() const {return ios_base::exceptions();}
_LIBCPP_INLINE_VISIBILITY void exceptions(iostate __iostate) {ios_base::exceptions(__iostate);}
// 27.5.4.1 Constructor/destructor:
_LIBCPP_INLINE_VISIBILITY
@@ -652,7 +652,7 @@ public:
char_type widen(char __c) const;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
basic_ios() {// purposefully does no initialization
}
_LIBCPP_INLINE_VISIBILITY
@@ -661,7 +661,7 @@ protected:
_LIBCPP_INLINE_VISIBILITY
void move(basic_ios& __rhs);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
void move(basic_ios&& __rhs) {move(__rhs);}
#endif
_LIBCPP_INLINE_VISIBILITY

View File

@@ -186,7 +186,7 @@ public:
typedef typename traits_type::off_type off_type;
// 27.7.1.1.1 Constructor/destructor:
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb) : __gc_(0)
{ this->init(__sb); }
virtual ~basic_istream();
@@ -200,7 +200,7 @@ protected:
basic_istream& operator=(basic_istream&& __rhs);
#endif
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void swap(basic_istream& __rhs) {
_VSTD::swap(__gc_, __rhs.__gc_);
basic_ios<char_type, traits_type>::swap(__rhs);
@@ -216,16 +216,16 @@ public:
class _LIBCPP_TEMPLATE_VIS sentry;
// 27.7.1.2 Formatted input:
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&))
{ return __pf(*this); }
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& operator>>(basic_ios<char_type, traits_type>&
(*__pf)(basic_ios<char_type, traits_type>&))
{ __pf(*this); return *this; }
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& operator>>(ios_base& (*__pf)(ios_base&))
{ __pf(*this); return *this; }
@@ -249,7 +249,7 @@ public:
streamsize gcount() const {return __gc_;}
int_type get();
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& get(char_type& __c) {
int_type __ch = get();
if (__ch != traits_type::eof())
@@ -257,19 +257,19 @@ public:
return *this;
}
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& get(char_type* __s, streamsize __n)
{ return get(__s, __n, this->widen('\n')); }
basic_istream& get(char_type* __s, streamsize __n, char_type __dlm);
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& get(basic_streambuf<char_type, traits_type>& __sb)
{ return get(__sb, this->widen('\n')); }
basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm);
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_istream& getline(char_type* __s, streamsize __n)
{ return getline(__s, __n, this->widen('\n')); }
@@ -358,386 +358,168 @@ basic_istream<_CharT, _Traits>::~basic_istream()
{
}
template <class _CharT, class _Traits>
template <class _Tp, class _CharT, class _Traits>
_LIBCPP_INLINE_VISIBILITY
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n)
{
__input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
typename basic_istream<_CharT, _Traits>::sentry __s(__is);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
typedef istreambuf_iterator<_CharT, _Traits> _Ip;
typedef num_get<_CharT, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __err, __n);
__is.setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
__is.__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return __is;
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n)
{
return _VSTD::__input_arithmetic<unsigned short>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(unsigned int& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic<unsigned int>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(long& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic<long>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(unsigned long& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic<unsigned long>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(long long& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic<long long>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(unsigned long long& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic<unsigned long long>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(float& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic<float>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(double& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic<double>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(long double& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic<long double>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(bool& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic<bool>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(void*& __n)
{
return _VSTD::__input_arithmetic<void*>(*this, __n);
}
template <class _Tp, class _CharT, class _Traits>
_LIBCPP_INLINE_VISIBILITY
basic_istream<_CharT, _Traits>&
__input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
typename basic_istream<_CharT, _Traits>::sentry __s(__is);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
typedef istreambuf_iterator<_CharT, _Traits> _Ip;
typedef num_get<_CharT, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
this->setstate(__err);
long __temp;
use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __err, __temp);
if (__temp < numeric_limits<_Tp>::min())
{
__err |= ios_base::failbit;
__n = numeric_limits<_Tp>::min();
}
else if (__temp > numeric_limits<_Tp>::max())
{
__err |= ios_base::failbit;
__n = numeric_limits<_Tp>::max();
}
else
__n = static_cast<_Tp>(__temp);
__is.setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
__is.__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return __is;
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(short& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
long __temp;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp);
if (__temp < numeric_limits<short>::min())
{
__err |= ios_base::failbit;
__n = numeric_limits<short>::min();
}
else if (__temp > numeric_limits<short>::max())
{
__err |= ios_base::failbit;
__n = numeric_limits<short>::max();
}
else
__n = static_cast<short>(__temp);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic_with_numeric_limits<short>(*this, __n);
}
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(int& __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
sentry __s(*this);
if (__s)
{
typedef istreambuf_iterator<char_type, traits_type> _Ip;
typedef num_get<char_type, _Ip> _Fp;
ios_base::iostate __err = ios_base::goodbit;
long __temp;
use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp);
if (__temp < numeric_limits<int>::min())
{
__err |= ios_base::failbit;
__n = numeric_limits<int>::min();
}
else if (__temp > numeric_limits<int>::max())
{
__err |= ios_base::failbit;
__n = numeric_limits<int>::max();
}
else
__n = static_cast<int>(__temp);
this->setstate(__err);
}
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
return *this;
return _VSTD::__input_arithmetic_with_numeric_limits<int>(*this, __n);
}
template<class _CharT, class _Traits>
_LIBCPP_INLINE_VISIBILITY
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
__input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
@@ -746,13 +528,10 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
if (__sen)
{
streamsize __n = __is.width();
if (__n <= 0)
__n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1;
streamsize __c = 0;
auto __s = __p;
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
ios_base::iostate __err = ios_base::goodbit;
while (__c < __n-1)
while (__s != __p + (__n-1))
{
typename _Traits::int_type __i = __is.rdbuf()->sgetc();
if (_Traits::eq_int_type(__i, _Traits::eof()))
@@ -764,12 +543,11 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
if (__ct.is(__ct.space, __ch))
break;
*__s++ = __ch;
++__c;
__is.rdbuf()->sbumpc();
}
*__s = _CharT();
__is.width(0);
if (__c == 0)
if (__s == __p)
__err |= ios_base::failbit;
__is.setstate(__err);
}
@@ -783,6 +561,48 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
return __is;
}
#if _LIBCPP_STD_VER > 17
template<class _CharT, class _Traits, size_t _Np>
inline _LIBCPP_INLINE_VISIBILITY
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT (&__buf)[_Np])
{
auto __n = _Np;
if (__is.width() > 0)
__n = _VSTD::min(size_t(__is.width()), _Np);
return _VSTD::__input_c_string(__is, __buf, __n);
}
template<class _Traits, size_t _Np>
inline _LIBCPP_INLINE_VISIBILITY
basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __is, unsigned char (&__buf)[_Np])
{
return __is >> (char(&)[_Np])__buf;
}
template<class _Traits, size_t _Np>
inline _LIBCPP_INLINE_VISIBILITY
basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __is, signed char (&__buf)[_Np])
{
return __is >> (char(&)[_Np])__buf;
}
#else
template<class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
{
streamsize __n = __is.width();
if (__n <= 0)
__n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1;
return _VSTD::__input_c_string(__is, __s, size_t(__n));
}
template<class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_istream<char, _Traits>&
@@ -799,6 +619,8 @@ operator>>(basic_istream<char, _Traits>& __is, signed char* __s)
return __is >> (char*)__s;
}
#endif // _LIBCPP_STD_VER > 17
template<class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
@@ -1457,7 +1279,7 @@ public:
typedef typename traits_type::off_type off_type;
// constructor/destructor
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
: basic_istream<_CharT, _Traits>(__sb)
{}
@@ -1472,7 +1294,7 @@ protected:
inline _LIBCPP_INLINE_VISIBILITY
basic_iostream& operator=(basic_iostream&& __rhs);
#endif
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void swap(basic_iostream& __rhs)
{ basic_istream<char_type, traits_type>::swap(__rhs); }
public:

View File

@@ -418,6 +418,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <type_traits>
#include <cstddef>
#include <initializer_list>
#include <version>
#ifdef __APPLE__
#include <Availability.h>
#endif
@@ -436,6 +437,23 @@ struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_t
struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
template <class _Tp>
struct __has_iterator_typedefs
{
private:
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename std::__void_t<typename _Up::iterator_category>::type* = 0,
typename std::__void_t<typename _Up::difference_type>::type* = 0,
typename std::__void_t<typename _Up::value_type>::type* = 0,
typename std::__void_t<typename _Up::reference>::type* = 0,
typename std::__void_t<typename _Up::pointer>::type* = 0
);
public:
static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1;
};
template <class _Tp>
struct __has_iterator_category
{
@@ -478,7 +496,7 @@ struct __iterator_traits<_Iter, true>
template <class _Iter>
struct _LIBCPP_TEMPLATE_VIS iterator_traits
: __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {};
: __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {};
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>
@@ -1217,38 +1235,38 @@ make_move_iterator(_Iter __i)
template <class _Iter> class __wrap_iter;
template <class _Iter1, class _Iter2>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
#ifndef _LIBCPP_CXX03_LANG
template <class _Iter1, class _Iter2>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
auto
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
-> decltype(__x.base() - __y.base());
@@ -1260,7 +1278,7 @@ operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBU
#endif
template <class _Iter>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
__wrap_iter<_Iter>
operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT_DEBUG;
@@ -1272,7 +1290,7 @@ template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1,
#if _LIBCPP_DEBUG_LEVEL < 2
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
typename enable_if
<
is_trivially_copy_assignable<_Tp>::value,
@@ -1283,7 +1301,7 @@ __unwrap_iter(__wrap_iter<_Tp*>);
#else
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
typename enable_if
<
is_trivially_copy_assignable<_Tp>::value,
@@ -1306,7 +1324,7 @@ public:
private:
iterator_type __i;
public:
_LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT_DEBUG
#if _LIBCPP_STD_VER > 11
: __i{}
#endif
@@ -1315,22 +1333,23 @@ public:
__get_db()->__insert_i(this);
#endif
}
template <class _Up> _LIBCPP_INLINE_VISIBILITY __wrap_iter(const __wrap_iter<_Up>& __u,
typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT_DEBUG
: __i(__u.base())
template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
__wrap_iter(const __wrap_iter<_Up>& __u,
typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT_DEBUG
: __i(__u.base())
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__iterator_copy(this, &__u);
#endif
}
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
__wrap_iter(const __wrap_iter& __x)
: __i(__x.base())
{
__get_db()->__iterator_copy(this, &__x);
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
__wrap_iter& operator=(const __wrap_iter& __x)
{
if (this != &__x)
@@ -1340,13 +1359,13 @@ public:
}
return *this;
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
~__wrap_iter()
{
__get_db()->__erase_i(this);
}
#endif
_LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT_DEBUG
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
@@ -1354,7 +1373,7 @@ public:
#endif
return *__i;
}
_LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer operator->() const _NOEXCEPT_DEBUG
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
@@ -1362,7 +1381,7 @@ public:
#endif
return (pointer)_VSTD::addressof(*__i);
}
_LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT_DEBUG
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
@@ -1371,9 +1390,10 @@ public:
++__i;
return *this;
}
_LIBCPP_INLINE_VISIBILITY __wrap_iter operator++(int) _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator++(int) _NOEXCEPT_DEBUG
{__wrap_iter __tmp(*this); ++(*this); return __tmp;}
_LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT_DEBUG
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
@@ -1382,11 +1402,11 @@ public:
--__i;
return *this;
}
_LIBCPP_INLINE_VISIBILITY __wrap_iter operator--(int) _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator--(int) _NOEXCEPT_DEBUG
{__wrap_iter __tmp(*this); --(*this); return __tmp;}
_LIBCPP_INLINE_VISIBILITY __wrap_iter operator+ (difference_type __n) const _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator+ (difference_type __n) const _NOEXCEPT_DEBUG
{__wrap_iter __w(*this); __w += __n; return __w;}
_LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT_DEBUG
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
@@ -1395,11 +1415,11 @@ public:
__i += __n;
return *this;
}
_LIBCPP_INLINE_VISIBILITY __wrap_iter operator- (difference_type __n) const _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator- (difference_type __n) const _NOEXCEPT_DEBUG
{return *this + (-__n);}
_LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT_DEBUG
{*this += -__n; return *this;}
_LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const _NOEXCEPT_DEBUG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator[](difference_type __n) const _NOEXCEPT_DEBUG
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
@@ -1408,67 +1428,68 @@ public:
return __i[__n];
}
_LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT_DEBUG {return __i;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT_DEBUG {return __i;}
private:
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
{
__get_db()->__insert_ic(this, __p);
}
#else
_LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT_DEBUG : __i(__x) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT_DEBUG : __i(__x) {}
#endif
template <class _Up> friend class __wrap_iter;
template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
template <class _Tp, ptrdiff_t> friend class _LIBCPP_TEMPLATE_VIS span;
template <class _Iter1, class _Iter2>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
bool
operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
bool
operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
bool
operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
bool
operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
bool
operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
template <class _Iter1, class _Iter2>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
bool
operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
#ifndef _LIBCPP_CXX03_LANG
template <class _Iter1, class _Iter2>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
auto
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
-> decltype(__x.base() - __y.base());
#else
template <class _Iter1, class _Iter2>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
typename __wrap_iter<_Iter1>::difference_type
operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
#endif
template <class _Iter1>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
__wrap_iter<_Iter1>
operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT_DEBUG;
@@ -1479,7 +1500,7 @@ private:
#if _LIBCPP_DEBUG_LEVEL < 2
template <class _Tp>
friend
_LIBCPP_CONSTEXPR_IF_NODEBUG friend
typename enable_if
<
is_trivially_copy_assignable<_Tp>::value,
@@ -1488,7 +1509,7 @@ private:
__unwrap_iter(__wrap_iter<_Tp*>);
#else
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
typename enable_if
<
is_trivially_copy_assignable<_Tp>::value,
@@ -1499,7 +1520,7 @@ private:
};
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
{
@@ -1507,7 +1528,7 @@ operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
{
@@ -1519,7 +1540,7 @@ operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
{
@@ -1527,7 +1548,7 @@ operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
{
@@ -1535,7 +1556,7 @@ operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
{
@@ -1543,7 +1564,7 @@ operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX
}
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
{
@@ -1551,7 +1572,7 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX
}
template <class _Iter1>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG
{
@@ -1559,7 +1580,7 @@ operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX
}
template <class _Iter1>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG
{
@@ -1567,7 +1588,7 @@ operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXC
}
template <class _Iter1>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG
{
@@ -1575,7 +1596,7 @@ operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX
}
template <class _Iter1>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
bool
operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG
{
@@ -1584,7 +1605,7 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX
#ifndef _LIBCPP_CXX03_LANG
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
auto
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
-> decltype(__x.base() - __y.base())
@@ -1597,7 +1618,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC
}
#else
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
typename __wrap_iter<_Iter1>::difference_type
operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
{
@@ -1610,7 +1631,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC
#endif
template <class _Iter>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
__wrap_iter<_Iter>
operator+(typename __wrap_iter<_Iter>::difference_type __n,
__wrap_iter<_Iter> __x) _NOEXCEPT_DEBUG

View File

@@ -82,6 +82,7 @@ template<> class numeric_limits<cv char>;
template<> class numeric_limits<cv signed char>;
template<> class numeric_limits<cv unsigned char>;
template<> class numeric_limits<cv wchar_t>;
template<> class numeric_limits<cv char8_t>; // C++20
template<> class numeric_limits<cv char16_t>;
template<> class numeric_limits<cv char32_t>;

View File

@@ -181,6 +181,7 @@ template <class T, class Alloc>
#include <iterator>
#include <algorithm>
#include <type_traits>
#include <version>
#include <__debug>
@@ -1169,7 +1170,7 @@ list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l)
base::__end_.__next_ = __f;
}
// Link in nodes [__f, __l] at the front of the list
// Link in nodes [__f, __l] at the back of the list
template <class _Tp, class _Alloc>
inline
void
@@ -2208,7 +2209,7 @@ template <class _Comp>
void
list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
{
if (this != &__c)
if (this != _VSTD::addressof(__c))
{
iterator __f1 = begin();
iterator __e1 = end();

View File

@@ -573,81 +573,81 @@ public:
typedef _CharT char_type;
typedef _InputIterator iter_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit num_get(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, bool& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, long& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, long long& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, unsigned short& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, unsigned int& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, unsigned long& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, unsigned long long& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, float& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, double& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, long double& __v) const
{
return do_get(__b, __e, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, void*& __v) const
{
@@ -657,7 +657,7 @@ public:
static locale::id id;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~num_get() {}
template <class _Fp>
@@ -727,7 +727,7 @@ locale::id
num_get<_CharT, _InputIterator>::id;
template <class _Tp>
_Tp
_LIBCPP_HIDDEN _Tp
__num_get_signed_integral(const char* __a, const char* __a_end,
ios_base::iostate& __err, int __base)
{
@@ -762,7 +762,7 @@ __num_get_signed_integral(const char* __a, const char* __a_end,
}
template <class _Tp>
_Tp
_LIBCPP_HIDDEN _Tp
__num_get_unsigned_integral(const char* __a, const char* __a_end,
ios_base::iostate& __err, int __base)
{
@@ -1261,60 +1261,60 @@ public:
typedef _CharT char_type;
typedef _OutputIterator iter_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit num_put(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
bool __v) const
{
return do_put(__s, __iob, __fl, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
long __v) const
{
return do_put(__s, __iob, __fl, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
long long __v) const
{
return do_put(__s, __iob, __fl, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
unsigned long __v) const
{
return do_put(__s, __iob, __fl, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
unsigned long long __v) const
{
return do_put(__s, __iob, __fl, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
double __v) const
{
return do_put(__s, __iob, __fl, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
long double __v) const
{
return do_put(__s, __iob, __fl, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
const void* __v) const
{
@@ -1324,7 +1324,7 @@ public:
static locale::id id;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~num_put() {}
virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
@@ -1738,7 +1738,7 @@ protected:
virtual const string_type& __x() const;
virtual const string_type& __X() const;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~__time_get_c_storage() {}
};
@@ -1770,52 +1770,52 @@ public:
typedef time_base::dateorder dateorder;
typedef basic_string<char_type> string_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit time_get(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
dateorder date_order() const
{
return this->do_date_order();
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, tm* __tm) const
{
return do_get_time(__b, __e, __iob, __err, __tm);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, tm* __tm) const
{
return do_get_date(__b, __e, __iob, __err, __tm);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, tm* __tm) const
{
return do_get_weekday(__b, __e, __iob, __err, __tm);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, tm* __tm) const
{
return do_get_monthname(__b, __e, __iob, __err, __tm);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, tm* __tm) const
{
return do_get_year(__b, __e, __iob, __err, __tm);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
ios_base::iostate& __err, tm *__tm,
char __fmt, char __mod = 0) const
@@ -1830,7 +1830,7 @@ public:
static locale::id id;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~time_get() {}
virtual dateorder do_date_order() const;
@@ -2399,7 +2399,7 @@ protected:
explicit __time_get_storage(const char* __nm);
explicit __time_get_storage(const string& __nm);
_LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
_LIBCPP_INLINE_VISIBILITY ~__time_get_storage() {}
time_base::dateorder __do_date_order() const;
@@ -2408,6 +2408,23 @@ private:
string_type __analyze(char __fmt, const ctype<_CharT>&);
};
#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \
template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
/**/
_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)
#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
class _LIBCPP_TEMPLATE_VIS time_get_byname
: public time_get<_CharT, _InputIterator>,
@@ -2458,7 +2475,7 @@ class _LIBCPP_TYPE_VIS __time_put
{
locale_t __loc_;
protected:
_LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
_LIBCPP_INLINE_VISIBILITY __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
__time_put(const char* __nm);
__time_put(const string& __nm);
~__time_put();
@@ -2477,14 +2494,14 @@ public:
typedef _CharT char_type;
typedef _OutputIterator iter_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit time_put(size_t __refs = 0)
: locale::facet(__refs) {}
iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
const char_type* __pb, const char_type* __pe) const;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
const tm* __tm, char __fmt, char __mod = 0) const
{
@@ -2494,16 +2511,16 @@ public:
static locale::id id;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~time_put() {}
virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
char __fmt, char __mod) const;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit time_put(const char* __nm, size_t __refs)
: locale::facet(__refs),
__time_put(__nm) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit time_put(const string& __nm, size_t __refs)
: locale::facet(__refs),
__time_put(__nm) {}
@@ -2572,16 +2589,16 @@ class _LIBCPP_TEMPLATE_VIS time_put_byname
: public time_put<_CharT, _OutputIterator>
{
public:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit time_put_byname(const char* __nm, size_t __refs = 0)
: time_put<_CharT, _OutputIterator>(__nm, __refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit time_put_byname(const string& __nm, size_t __refs = 0)
: time_put<_CharT, _OutputIterator>(__nm, __refs) {}
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~time_put_byname() {}
};
@@ -2596,7 +2613,7 @@ public:
enum part {none, space, symbol, sign, value};
struct pattern {char field[4];};
_LIBCPP_ALWAYS_INLINE money_base() {}
_LIBCPP_INLINE_VISIBILITY money_base() {}
};
// moneypunct
@@ -2610,25 +2627,25 @@ public:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit moneypunct(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
_LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
_LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
_LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();}
_LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
_LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
_LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();}
_LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();}
_LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();}
_LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
_LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
_LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
_LIBCPP_INLINE_VISIBILITY string_type curr_symbol() const {return do_curr_symbol();}
_LIBCPP_INLINE_VISIBILITY string_type positive_sign() const {return do_positive_sign();}
_LIBCPP_INLINE_VISIBILITY string_type negative_sign() const {return do_negative_sign();}
_LIBCPP_INLINE_VISIBILITY int frac_digits() const {return do_frac_digits();}
_LIBCPP_INLINE_VISIBILITY pattern pos_format() const {return do_pos_format();}
_LIBCPP_INLINE_VISIBILITY pattern neg_format() const {return do_neg_format();}
static locale::id id;
static const bool intl = _International;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~moneypunct() {}
virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
@@ -2668,16 +2685,16 @@ public:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
: moneypunct<_CharT, _International>(__refs) {init(__nm);}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
: moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~moneypunct_byname() {}
virtual char_type do_decimal_point() const {return __decimal_point_;}
@@ -2723,7 +2740,7 @@ protected:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
_LIBCPP_ALWAYS_INLINE __money_get() {}
_LIBCPP_INLINE_VISIBILITY __money_get() {}
static void __gather_info(bool __intl, const locale& __loc,
money_base::pattern& __pat, char_type& __dp,
@@ -2781,18 +2798,18 @@ public:
typedef _InputIterator iter_type;
typedef basic_string<char_type> string_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit money_get(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
ios_base::iostate& __err, long double& __v) const
{
return do_get(__b, __e, __intl, __iob, __err, __v);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
ios_base::iostate& __err, string_type& __v) const
{
@@ -2803,7 +2820,7 @@ public:
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~money_get() {}
virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
@@ -3163,7 +3180,7 @@ protected:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
_LIBCPP_ALWAYS_INLINE __money_put() {}
_LIBCPP_INLINE_VISIBILITY __money_put() {}
static void __gather_info(bool __intl, bool __neg, const locale& __loc,
money_base::pattern& __pat, char_type& __dp,
@@ -3339,18 +3356,18 @@ public:
typedef _OutputIterator iter_type;
typedef basic_string<char_type> string_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit money_put(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
long double __units) const
{
return do_put(__s, __intl, __iob, __fl, __units);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
const string_type& __digits) const
{
@@ -3360,7 +3377,7 @@ public:
static locale::id id;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~money_put() {}
virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
@@ -3489,7 +3506,7 @@ class _LIBCPP_TYPE_VIS messages_base
public:
typedef ptrdiff_t catalog;
_LIBCPP_ALWAYS_INLINE messages_base() {}
_LIBCPP_INLINE_VISIBILITY messages_base() {}
};
template <class _CharT>
@@ -3501,24 +3518,24 @@ public:
typedef _CharT char_type;
typedef basic_string<_CharT> string_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit messages(size_t __refs = 0)
: locale::facet(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
catalog open(const basic_string<char>& __nm, const locale& __loc) const
{
return do_open(__nm, __loc);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
string_type get(catalog __c, int __set, int __msgid,
const string_type& __dflt) const
{
return do_get(__c, __set, __msgid, __dflt);
}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
void close(catalog __c) const
{
do_close(__c);
@@ -3527,7 +3544,7 @@ public:
static locale::id id;
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~messages() {}
virtual catalog do_open(const basic_string<char>&, const locale&) const;
@@ -3600,16 +3617,16 @@ public:
typedef messages_base::catalog catalog;
typedef basic_string<_CharT> string_type;
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit messages_byname(const char*, size_t __refs = 0)
: messages<_CharT>(__refs) {}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
explicit messages_byname(const string&, size_t __refs = 0)
: messages<_CharT>(__refs) {}
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
~messages_byname() {}
};
@@ -3637,43 +3654,43 @@ private:
wstring_convert(const wstring_convert& __wc);
wstring_convert& operator=(const wstring_convert& __wc);
public:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
wstring_convert(_Codecvt* __pcvt, state_type __state);
_LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
const wide_string& __wide_err = wide_string());
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
wstring_convert(wstring_convert&& __wc);
#endif
~wstring_convert();
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
wide_string from_bytes(char __byte)
{return from_bytes(&__byte, &__byte+1);}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
wide_string from_bytes(const char* __ptr)
{return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
wide_string from_bytes(const byte_string& __str)
{return from_bytes(__str.data(), __str.data() + __str.size());}
wide_string from_bytes(const char* __first, const char* __last);
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
byte_string to_bytes(_Elem __wchar)
{return to_bytes(&__wchar, &__wchar+1);}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
byte_string to_bytes(const _Elem* __wptr)
{return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
byte_string to_bytes(const wide_string& __wstr)
{return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
byte_string to_bytes(const _Elem* __first, const _Elem* __last);
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
size_t converted() const _NOEXCEPT {return __cvtcount_;}
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
state_type state() const {return __cvtstate_;}
};

View File

@@ -40,6 +40,8 @@ public:
typedef implementation-defined const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef unspecified node_type; // C++17
typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
class value_compare
: public binary_function<value_type, value_type, bool>
@@ -137,6 +139,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type> il);
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
insert_return_type insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
template <class... Args>
@@ -160,6 +167,15 @@ public:
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
template<class C2>
void merge(map<Key, T, C2, Allocator>& source); // C++17
template<class C2>
void merge(map<Key, T, C2, Allocator>&& source); // C++17
template<class C2>
void merge(multimap<Key, T, C2, Allocator>& source); // C++17
template<class C2>
void merge(multimap<Key, T, C2, Allocator>&& source); // C++17
void swap(map& m)
noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
is_nothrow_swappable<key_compare>::value); // C++17
@@ -260,6 +276,7 @@ public:
typedef implementation-defined const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef unspecified node_type; // C++17
class value_compare
: public binary_function<value_type,value_type,bool>
@@ -349,12 +366,26 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type> il);
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
iterator insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
template<class C2>
void merge(multimap<Key, T, C2, Allocator>& source); // C++17
template<class C2>
void merge(multimap<Key, T, C2, Allocator>&& source); // C++17
template<class C2>
void merge(map<Key, T, C2, Allocator>& source); // C++17
template<class C2>
void merge(map<Key, T, C2, Allocator>&& source); // C++17
void swap(multimap& m)
noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
is_nothrow_swappable<key_compare>::value); // C++17
@@ -440,12 +471,14 @@ swap(multimap<Key, T, Compare, Allocator>& x,
#include <__config>
#include <__tree>
#include <__node_handle>
#include <iterator>
#include <memory>
#include <utility>
#include <functional>
#include <initializer_list>
#include <type_traits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -906,6 +939,16 @@ public:
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
#if _LIBCPP_STD_VER > 14
typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
typedef __insert_return_type<iterator, node_type> insert_return_type;
#endif
template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
friend class _LIBCPP_TEMPLATE_VIS map;
template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
friend class _LIBCPP_TEMPLATE_VIS multimap;
_LIBCPP_INLINE_VISIBILITY
map()
_NOEXCEPT_(
@@ -1253,6 +1296,67 @@ public:
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__tree_.clear();}
#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VISIBILITY
insert_return_type insert(node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to map::insert()");
return __tree_.template __node_handle_insert_unique<
node_type, insert_return_type>(_VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to map::insert()");
return __tree_.template __node_handle_insert_unique<node_type>(
__hint.__i_, _VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(key_type const& __key)
{
return __tree_.template __node_handle_extract<node_type>(__key);
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(const_iterator __it)
{
return __tree_.template __node_handle_extract<node_type>(__it.__i_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
#endif
_LIBCPP_INLINE_VISIBILITY
void swap(map& __m)
_NOEXCEPT_(__is_nothrow_swappable<__base>::value)
@@ -1562,6 +1666,15 @@ public:
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
#if _LIBCPP_STD_VER > 14
typedef __map_node_handle<typename __base::__node, allocator_type> node_type;
#endif
template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
friend class _LIBCPP_TEMPLATE_VIS map;
template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
friend class _LIBCPP_TEMPLATE_VIS multimap;
_LIBCPP_INLINE_VISIBILITY
multimap()
_NOEXCEPT_(
@@ -1800,8 +1913,71 @@ public:
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __f, const_iterator __l)
{return __tree_.erase(__f.__i_, __l.__i_);}
#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VISIBILITY
void clear() {__tree_.clear();}
iterator insert(node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to multimap::insert()");
return __tree_.template __node_handle_insert_multi<node_type>(
_VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to multimap::insert()");
return __tree_.template __node_handle_insert_multi<node_type>(
__hint.__i_, _VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(key_type const& __key)
{
return __tree_.template __node_handle_extract<node_type>(__key);
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(const_iterator __it)
{
return __tree_.template __node_handle_extract<node_type>(
__it.__i_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
return __tree_.__node_handle_merge_multi(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
return __tree_.__node_handle_merge_multi(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
return __tree_.__node_handle_merge_multi(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
return __tree_.__node_handle_merge_multi(__source.__tree_);
}
#endif
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__tree_.clear();}
_LIBCPP_INLINE_VISIBILITY
void swap(multimap& __m)

View File

@@ -314,7 +314,7 @@ extern "C++" {
#ifdef signbit
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_signbit(_A1 __lcpp_x) _NOEXCEPT
{
@@ -376,7 +376,7 @@ signbit(_A1) _NOEXCEPT
#ifdef fpclassify
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
int
__libcpp_fpclassify(_A1 __lcpp_x) _NOEXCEPT
{
@@ -422,7 +422,7 @@ fpclassify(_A1 __lcpp_x) _NOEXCEPT
#ifdef isfinite
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT
{
@@ -456,7 +456,7 @@ isfinite(_A1) _NOEXCEPT
#ifdef isinf
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT
{
@@ -504,7 +504,7 @@ isinf(long double __lcpp_x) _NOEXCEPT { return __libcpp_isinf(__lcpp_x); }
#ifdef isnan
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT
{
@@ -548,7 +548,7 @@ isnan(long double __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); }
#ifdef isnormal
template <class _A1>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_isnormal(_A1 __lcpp_x) _NOEXCEPT
{
@@ -578,7 +578,7 @@ isnormal(_A1 __lcpp_x) _NOEXCEPT
#ifdef isgreater
template <class _A1, class _A2>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
@@ -608,7 +608,7 @@ isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
#ifdef isgreaterequal
template <class _A1, class _A2>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
@@ -638,7 +638,7 @@ isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
#ifdef isless
template <class _A1, class _A2>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
@@ -668,7 +668,7 @@ isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
#ifdef islessequal
template <class _A1, class _A2>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
@@ -698,7 +698,7 @@ islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
#ifdef islessgreater
template <class _A1, class _A2>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
@@ -728,7 +728,7 @@ islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
#ifdef isunordered
template <class _A1, class _A2>
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
bool
__libcpp_isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{

View File

@@ -43,7 +43,7 @@ struct pointer_traits<T*>
template <class U> using rebind = U*;
static pointer pointer_to(<details>) noexcept;
static pointer pointer_to(<details>) noexcept; // constexpr in C++20
};
template <class T> constexpr T* to_address(T* p) noexcept; // C++20
@@ -212,10 +212,10 @@ template <class ForwardIterator>
template <class ForwardIterator, class Size>
ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
template <class Y> struct auto_ptr_ref {}; // removed in C++17
template <class Y> struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17
template<class X>
class auto_ptr // removed in C++17
class auto_ptr // deprecated in C++11, removed in C++17
{
public:
typedef X element_type;
@@ -667,6 +667,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
# include <atomic>
#endif
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -679,7 +680,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ValueType>
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
#if !defined(_LIBCPP_HAS_NO_THREADS) && \
defined(__ATOMIC_RELAXED) && \
@@ -691,7 +692,7 @@ _ValueType __libcpp_relaxed_load(_ValueType const* __value) {
}
template <class _ValueType>
inline _LIBCPP_ALWAYS_INLINE
inline _LIBCPP_INLINE_VISIBILITY
_ValueType __libcpp_acquire_load(_ValueType const* __value) {
#if !defined(_LIBCPP_HAS_NO_THREADS) && \
defined(__ATOMIC_ACQUIRE) && \
@@ -983,7 +984,7 @@ struct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*>
private:
struct __nat {};
public:
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
static pointer pointer_to(typename conditional<is_void<element_type>::value,
__nat, element_type>::type& __r) _NOEXCEPT
{return _VSTD::addressof(__r);}
@@ -1782,7 +1783,7 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator() _NOEXCEPT {}
template <class _Up>
template <class _Up>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator(const allocator<_Up>&) _NOEXCEPT {}
@@ -1790,7 +1791,7 @@ public:
{return _VSTD::addressof(__x);}
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
{return _VSTD::addressof(__x);}
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
{
if (__n > max_size())
@@ -1798,8 +1799,8 @@ public:
" 'n' exceeds maximum supported size");
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
{_VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp));}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
{_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), __alignof(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -1887,7 +1888,7 @@ public:
allocator() _NOEXCEPT {}
template <class _Up>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator(const allocator<_Up>&) _NOEXCEPT {}
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
@@ -1899,8 +1900,8 @@ public:
" 'n' exceeds maximum supported size");
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
{_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __alignof(_Tp));}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
{_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), __alignof(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -1989,10 +1990,10 @@ public:
_LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
{::new(&*__x_) _Tp(__element); return *this;}
{::new(_VSTD::addressof(*__x_)) _Tp(__element); return *this;}
#if _LIBCPP_STD_VER >= 14
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
{::new(&*__x_) _Tp(_VSTD::move(__element)); return *this;}
{::new(_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;}
#endif
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator operator++(int)
@@ -2003,7 +2004,7 @@ public:
};
template <class _Tp>
_LIBCPP_NO_CFI
_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
pair<_Tp*, ptrdiff_t>
get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
{
@@ -2051,18 +2052,18 @@ template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
void return_temporary_buffer(_Tp* __p) _NOEXCEPT
{
_VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp));
_VSTD::__libcpp_deallocate_unsized((void*)__p, __alignof(_Tp));
}
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
template <class _Tp>
struct auto_ptr_ref
struct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref
{
_Tp* __ptr_;
};
template<class _Tp>
class _LIBCPP_TEMPLATE_VIS auto_ptr
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr
{
private:
_Tp* __ptr_;
@@ -2106,7 +2107,7 @@ public:
};
template <>
class _LIBCPP_TEMPLATE_VIS auto_ptr<void>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void>
{
public:
typedef void element_type;
@@ -2130,7 +2131,9 @@ struct __compressed_pair_elem {
_LIBCPP_INLINE_VISIBILITY
constexpr explicit
__compressed_pair_elem(_Up&& __u)
: __value_(_VSTD::forward<_Up>(__u)){};
: __value_(_VSTD::forward<_Up>(__u))
{
}
template <class... _Args, size_t... _Indexes>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -2167,7 +2170,8 @@ struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
_LIBCPP_INLINE_VISIBILITY
constexpr explicit
__compressed_pair_elem(_Up&& __u)
: __value_type(_VSTD::forward<_Up>(__u)){};
: __value_type(_VSTD::forward<_Up>(__u))
{}
template <class... _Args, size_t... _Indexes>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -3483,7 +3487,7 @@ public:
virtual const char* what() const _NOEXCEPT;
};
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_bad_weak_ptr()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -3511,7 +3515,7 @@ public:
explicit __shared_count(long __refs = 0) _NOEXCEPT
: __shared_owners_(__refs) {}
#if defined(_LIBCPP_BUILDING_MEMORY) && \
#if defined(_LIBCPP_BUILDING_LIBRARY) && \
defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
void __add_shared() _NOEXCEPT;
bool __release_shared() _NOEXCEPT;
@@ -3549,7 +3553,7 @@ protected:
virtual ~__shared_weak_count();
public:
#if defined(_LIBCPP_BUILDING_MEMORY) && \
#if defined(_LIBCPP_BUILDING_LIBRARY) && \
defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
void __add_shared() _NOEXCEPT;
void __add_weak() _NOEXCEPT;
@@ -3682,7 +3686,7 @@ private:
virtual void __on_zero_shared_weak() _NOEXCEPT;
public:
_LIBCPP_INLINE_VISIBILITY
_Tp* get() _NOEXCEPT {return &__data_.second();}
_Tp* get() _NOEXCEPT {return _VSTD::addressof(__data_.second());}
};
template <class _Tp, class _Alloc>
@@ -5549,7 +5553,7 @@ struct _LIBCPP_TYPE_VIS pointer_safety
#endif
#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \
defined(_LIBCPP_BUILDING_MEMORY)
defined(_LIBCPP_BUILDING_LIBRARY)
_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
#else
// This function is only offered in C++03 under ABI v1.
@@ -5631,22 +5635,25 @@ struct __temp_value {
_Tp & get() { return *__addr(); }
template<class... _Args>
__temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc)
{ _Traits::construct(__a, __addr(), _VSTD::forward<_Args>(__args)...); }
_LIBCPP_NO_CFI
__temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
_Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)),
_VSTD::forward<_Args>(__args)...);
}
~__temp_value() { _Traits::destroy(__a, __addr()); }
};
#endif
#if _LIBCPP_STD_VER > 14
template<typename _Alloc, typename = void>
template<typename _Alloc, typename = void, typename = void>
struct __is_allocator : false_type {};
template<typename _Alloc>
struct __is_allocator<_Alloc,
void_t<typename _Alloc::value_type, decltype(_VSTD::declval<_Alloc&>().allocate(size_t{}))>>
typename __void_t<typename _Alloc::value_type>::type,
typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type
>
: true_type {};
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@@ -228,6 +228,10 @@ module std [system] {
header "atomic"
export *
}
module bit {
header "bit"
export *
}
module bitset {
header "bitset"
export string
@@ -235,6 +239,10 @@ module std [system] {
export *
}
// No submodule for cassert. It fundamentally needs repeated, textual inclusion.
module charconv {
header "charconv"
export *
}
module chrono {
header "chrono"
export *
@@ -264,6 +272,10 @@ module std [system] {
header "exception"
export *
}
module filesystem {
header "filesystem"
export *
}
module forward_list {
header "forward_list"
export initializer_list
@@ -482,6 +494,7 @@ module std [system] {
// FIXME: These should be private.
module __bit_reference { header "__bit_reference" export * }
module __debug { header "__debug" export * }
module __errc { header "__errc" export * }
module __functional_base { header "__functional_base" export * }
module __hash_table { header "__hash_table" export * }
module __locale { header "__locale" export * }
@@ -493,6 +506,7 @@ module std [system] {
module __tree { header "__tree" export * }
module __tuple { header "__tuple" export * }
module __undef_macros { header "__undef_macros" export * }
module __node_handle { header "__node_handle" export * }
module experimental {
requires cplusplus11
@@ -510,10 +524,6 @@ module std [system] {
header "experimental/deque"
export *
}
module dynarray {
header "experimental/dynarray"
export *
}
module filesystem {
header "experimental/filesystem"
export *
@@ -558,6 +568,10 @@ module std [system] {
header "experimental/set"
export *
}
module span {
header "span"
export *
}
module string {
header "experimental/string"
export *

View File

@@ -194,6 +194,7 @@ template<class Callable, class ...Args>
#ifndef _LIBCPP_CXX03_LANG
#include <tuple>
#endif
#include <version>
#include <__threading_support>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -488,7 +489,7 @@ public:
};
template <class _Mutex>
class _LIBCPP_TEMPLATE_VIS scoped_lock<_Mutex> {
class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) scoped_lock<_Mutex> {
public:
typedef _Mutex mutex_type;
private:

View File

@@ -27,12 +27,6 @@ public:
virtual const char* what() const noexcept;
};
class bad_array_length : public bad_alloc // FIXME: Not part of C++
{
public:
bad_array_length() noexcept;
};
class bad_array_new_length : public bad_alloc // C++14
{
public:
@@ -91,6 +85,7 @@ void operator delete[](void* ptr, void*) noexcept;
#include <exception>
#include <type_traits>
#include <cstddef>
#include <version>
#ifdef _LIBCPP_NO_EXCEPTIONS
#include <cstdlib>
#endif
@@ -103,23 +98,23 @@ void operator delete[](void* ptr, void*) noexcept;
#pragma GCC system_header
#endif
#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
(defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309))
#if !defined(__cpp_sized_deallocation) || __cpp_sized_deallocation < 201309L
#define _LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION
#endif
#if !defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_STD_VER < 14 && \
defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
# define _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
#endif
#if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \
defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
#endif
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \
(!(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER > 14 || \
(defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606)))
# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
#endif
#if !__has_builtin(__builtin_operator_new) || \
__has_builtin(__builtin_operator_new) < 201802L || \
defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || \
!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606
#define _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE
__has_builtin(__builtin_operator_new) < 201802L
#define _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE
#endif
namespace std // purposefully not using versioning namespace
@@ -155,29 +150,14 @@ _LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec
#if defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11)
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
bad_array_length : public bad_alloc {
public:
bad_array_length() _NOEXCEPT;
virtual ~bad_array_length() _NOEXCEPT;
virtual const char* what() const _NOEXCEPT;
};
#define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
#endif // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || _LIBCPP_STD_VER > 14
#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \
!defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME)
#ifndef _LIBCPP_CXX03_LANG
enum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
#else
enum align_val_t { __zero = 0, __max = (size_t)-1 };
#endif
#endif
#endif
} // std
@@ -187,13 +167,13 @@ enum align_val_t { __zero = 0, __max = (size_t)-1 };
#define _THROW_BAD_ALLOC
#endif
#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)
#if !defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME)
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
#endif
@@ -201,16 +181,16 @@ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
#endif
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
#endif
@@ -218,7 +198,7 @@ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
#endif
#endif
@@ -228,7 +208,7 @@ _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator ne
inline _LIBCPP_INLINE_VISIBILITY void operator delete (void*, void*) _NOEXCEPT {}
inline _LIBCPP_INLINE_VISIBILITY void operator delete[](void*, void*) _NOEXCEPT {}
#endif // !_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME
#endif // !_LIBCPP_DEFER_NEW_TO_VCRUNTIME
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -244,7 +224,7 @@ inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t _
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
if (__is_overaligned_for_new(__align)) {
const align_val_t __align_val = static_cast<align_val_t>(__align);
# ifdef _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE
# ifdef _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE
return ::operator new(__size, __align_val);
# else
return __builtin_operator_new(__size, __align_val);
@@ -260,43 +240,98 @@ inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t _
#endif
}
inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __align) {
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
if (__is_overaligned_for_new(__align)) {
const align_val_t __align_val = static_cast<align_val_t>(__align);
# ifdef _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE
return ::operator delete(__ptr, __align_val);
# else
return __builtin_operator_delete(__ptr, __align_val);
# endif
struct _DeallocateCaller {
static inline _LIBCPP_INLINE_VISIBILITY
void __do_deallocate_handle_size_align(void *__ptr, size_t __size, size_t __align) {
#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
((void)__align);
return __do_deallocate_handle_size(__ptr, __size);
#else
if (__is_overaligned_for_new(__align)) {
const align_val_t __align_val = static_cast<align_val_t>(__align);
return __do_deallocate_handle_size(__ptr, __size, __align_val);
} else {
return __do_deallocate_handle_size(__ptr, __size);
}
#endif
}
static inline _LIBCPP_INLINE_VISIBILITY
void __do_deallocate_handle_align(void *__ptr, size_t __align) {
#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
((void)__align);
return __do_call(__ptr);
#else
((void)__align);
if (__is_overaligned_for_new(__align)) {
const align_val_t __align_val = static_cast<align_val_t>(__align);
return __do_call(__ptr, __align_val);
} else {
return __do_call(__ptr);
}
#endif
}
private:
static inline void __do_deallocate_handle_size(void *__ptr, size_t __size) {
#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
((void)__size);
return __do_call(__ptr);
#else
return __do_call(__ptr, __size);
#endif
}
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
static inline void __do_deallocate_handle_size(void *__ptr, size_t __size, align_val_t __align) {
#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
((void)__size);
return __do_call(__ptr, __align);
#else
return __do_call(__ptr, __size, __align);
#endif
}
#endif
private:
template <class _A1, class _A2>
static inline void __do_call(void *__ptr, _A1 __a1, _A2 __a2) {
#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \
defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE)
return ::operator delete(__ptr, __a1, __a2);
#else
return __builtin_operator_delete(__ptr, __a1, __a2);
#endif
}
template <class _A1>
static inline void __do_call(void *__ptr, _A1 __a1) {
#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \
defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE)
return ::operator delete(__ptr, __a1);
#else
return __builtin_operator_delete(__ptr, __a1);
#endif
}
static inline void __do_call(void *__ptr) {
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
return ::operator delete(__ptr);
return ::operator delete(__ptr);
#else
return __builtin_operator_delete(__ptr);
return __builtin_operator_delete(__ptr);
#endif
}
};
inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
_DeallocateCaller::__do_deallocate_handle_size_align(__ptr, __size, __align);
}
#ifdef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
#ifndef _LIBCPP_NO_EXCEPTIONS
_LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
#endif
void __throw_bad_array_length()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_array_length();
#else
_VSTD::abort();
#endif
inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) {
_DeallocateCaller::__do_deallocate_handle_align(__ptr, __align);
}
#endif
template <class _Tp>
_LIBCPP_NODISCARD_AFTER_CXX17 inline
_LIBCPP_NODISCARD_AFTER_CXX17 inline
_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
{
static_assert (!(is_function<_Tp>::value), "can't launder functions" );

View File

@@ -104,15 +104,15 @@ template<class InputIterator, class OutputIterator, class T,
template<class InputIterator, class OutputIterator,
class BinaryOperation, class UnaryOperation>
OutputIterator
transform_inclusive_scan(InputIterator first, InputIterator last,
OutputIterator
transform_inclusive_scan(InputIterator first, InputIterator last,
OutputIterator result,
BinaryOperation binary_op, UnaryOperation unary_op); // C++17
template<class InputIterator, class OutputIterator,
class BinaryOperation, class UnaryOperation, class T>
OutputIterator
transform_inclusive_scan(InputIterator first, InputIterator last,
OutputIterator
transform_inclusive_scan(InputIterator first, InputIterator last,
OutputIterator result,
BinaryOperation binary_op, UnaryOperation unary_op,
T init); // C++17
@@ -142,6 +142,7 @@ template <class M, class N>
#include <iterator>
#include <limits> // for numeric_limits
#include <functional>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header

View File

@@ -156,6 +156,7 @@ template<class T>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -168,7 +169,7 @@ _LIBCPP_PUSH_MACROS
namespace std // purposefully not using versioning namespace
{
class _LIBCPP_EXCEPTION_ABI bad_optional_access
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
: public exception
{
public:
@@ -185,6 +186,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_NORETURN
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
void __throw_bad_optional_access() {
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_optional_access();
@@ -932,6 +934,7 @@ public:
using __base::__get;
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type const& value() const&
{
if (!this->has_value())
@@ -940,6 +943,7 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type& value() &
{
if (!this->has_value())
@@ -948,6 +952,7 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type&& value() &&
{
if (!this->has_value())
@@ -956,6 +961,7 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
constexpr value_type const&& value() const&&
{
if (!this->has_value())

View File

@@ -160,7 +160,7 @@ public:
typedef typename traits_type::off_type off_type;
// 27.7.2.2 Constructor/destructor:
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb)
{ this->init(__sb); }
virtual ~basic_ostream();
@@ -173,7 +173,7 @@ protected:
inline _LIBCPP_INLINE_VISIBILITY
basic_ostream& operator=(basic_ostream&& __rhs);
#endif
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
void swap(basic_ostream& __rhs)
{ basic_ios<char_type, traits_type>::swap(__rhs); }
@@ -190,16 +190,16 @@ public:
class _LIBCPP_TEMPLATE_VIS sentry;
// 27.7.2.6 Formatted output:
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&))
{ return __pf(*this); }
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& operator<<(basic_ios<char_type, traits_type>&
(*__pf)(basic_ios<char_type,traits_type>&))
{ __pf(*this); return *this; }
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& operator<<(ios_base& (*__pf)(ios_base&))
{ __pf(*this); return *this; }
@@ -224,15 +224,15 @@ public:
basic_ostream& flush();
// 27.7.2.5 seeks:
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
pos_type tellp();
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& seekp(pos_type __pos);
inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1
basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
protected:
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
basic_ostream() {} // extension, intentially does not initialize
};
@@ -249,7 +249,7 @@ public:
explicit sentry(basic_ostream<_CharT, _Traits>& __os);
~sentry();
_LIBCPP_ALWAYS_INLINE
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_EXPLICIT
operator bool() const {return __ok_;}
};

View File

@@ -2337,7 +2337,7 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
for (size_t __i = 1; __i < __n; ++__i)
if (__x_[__i] != 0)
return;
__x_[0] = _Max;
__x_[0] = result_type(1) << (__w - 1);
}
}
@@ -2363,7 +2363,7 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
for (size_t __i = 1; __i < __n; ++__i)
if (__x_[__i] != 0)
return;
__x_[0] = _Max;
__x_[0] = result_type(1) << (__w - 1);
}
}

View File

@@ -769,6 +769,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
#include <memory>
#include <vector>
#include <deque>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -968,7 +969,7 @@ public:
};
template <regex_constants::error_type _Ev>
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_regex_error()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -1357,9 +1358,9 @@ public:
virtual ~__node() {}
_LIBCPP_INLINE_VISIBILITY
virtual void __exec(__state&) const {};
virtual void __exec(__state&) const {}
_LIBCPP_INLINE_VISIBILITY
virtual void __exec_split(bool, __state&) const {};
virtual void __exec_split(bool, __state&) const {}
};
// __end_state
@@ -2420,20 +2421,17 @@ __bracket_expression<_CharT, _Traits>::__exec(__state& __s) const
goto __exit;
}
}
// set of "__found" chars =
// When there's at least one of __neg_chars_ and __neg_mask_, the set
// of "__found" chars is
// union(complement(union(__neg_chars_, __neg_mask_)),
// other cases...)
//
// __neg_chars_ and __neg_mask_'d better be handled together, as there
// are no short circuit opportunities.
//
// In addition, when __neg_mask_/__neg_chars_ is empty, they should be
// treated as all ones/all chars.
// It doesn't make sense to check this when there are no __neg_chars_
// and no __neg_mask_.
if (!(__neg_mask_ == 0 && __neg_chars_.empty()))
{
const bool __in_neg_mask = (__neg_mask_ == 0) ||
__traits_.isctype(__ch, __neg_mask_);
const bool __in_neg_mask = __traits_.isctype(__ch, __neg_mask_);
const bool __in_neg_chars =
__neg_chars_.empty() ||
std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) !=
__neg_chars_.end();
if (!(__in_neg_mask || __in_neg_chars))

View File

@@ -108,6 +108,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs>
#include <__config>
#include <memory>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header

View File

@@ -40,6 +40,8 @@ public:
typedef implementation-defined const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef unspecified node_type; // C++17
typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
// construct/copy/destroy:
set()
@@ -115,12 +117,26 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type> il);
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
insert_return_type insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
template<class C2>
void merge(set<Key, C2, Allocator>& source); // C++17
template<class C2>
void merge(set<Key, C2, Allocator>&& source); // C++17
template<class C2>
void merge(multiset<Key, C2, Allocator>& source); // C++17
template<class C2>
void merge(multiset<Key, C2, Allocator>&& source); // C++17
void swap(set& s)
noexcept(
__is_nothrow_swappable<key_compare>::value &&
@@ -222,6 +238,7 @@ public:
typedef implementation-defined const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef unspecified node_type; // C++17
// construct/copy/destroy:
multiset()
@@ -297,12 +314,26 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type> il);
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
iterator insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
template<class C2>
void merge(multiset<Key, C2, Allocator>& source); // C++17
template<class C2>
void merge(multiset<Key, C2, Allocator>&& source); // C++17
template<class C2>
void merge(set<Key, C2, Allocator>& source); // C++17
template<class C2>
void merge(set<Key, C2, Allocator>&& source); // C++17
void swap(multiset& s)
noexcept(
__is_nothrow_swappable<key_compare>::value &&
@@ -387,7 +418,9 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
#include <__config>
#include <__tree>
#include <__node_handle>
#include <functional>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -395,6 +428,9 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Key, class _Compare, class _Allocator>
class multiset;
template <class _Key, class _Compare = less<_Key>,
class _Allocator = allocator<_Key> >
class _LIBCPP_TEMPLATE_VIS set
@@ -429,6 +465,16 @@ public:
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
#if _LIBCPP_STD_VER > 14
typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
typedef __insert_return_type<iterator, node_type> insert_return_type;
#endif
template <class _Key2, class _Compare2, class _Alloc2>
friend class _LIBCPP_TEMPLATE_VIS set;
template <class _Key2, class _Compare2, class _Alloc2>
friend class _LIBCPP_TEMPLATE_VIS multiset;
_LIBCPP_INLINE_VISIBILITY
set()
_NOEXCEPT_(
@@ -467,7 +513,7 @@ public:
#if _LIBCPP_STD_VER > 11
template <class _InputIterator>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY
set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
: set(__f, __l, key_compare(), __a) {}
#endif
@@ -523,7 +569,7 @@ public:
}
#if _LIBCPP_STD_VER > 11
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY
set(initializer_list<value_type> __il, const allocator_type& __a)
: set(__il, key_compare(), __a) {}
#endif
@@ -634,6 +680,67 @@ public:
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__tree_.clear();}
#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VISIBILITY
insert_return_type insert(node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to set::insert()");
return __tree_.template __node_handle_insert_unique<
node_type, insert_return_type>(_VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to set::insert()");
return __tree_.template __node_handle_insert_unique<node_type>(
__hint, _VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(key_type const& __key)
{
return __tree_.template __node_handle_extract<node_type>(__key);
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(const_iterator __it)
{
return __tree_.template __node_handle_extract<node_type>(__it);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(set<key_type, _Compare2, allocator_type>& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(set<key_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multiset<key_type, _Compare2, allocator_type>& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
#endif
_LIBCPP_INLINE_VISIBILITY
void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
{__tree_.swap(__s.__tree_);}
@@ -838,6 +945,15 @@ public:
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
#if _LIBCPP_STD_VER > 14
typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
#endif
template <class _Key2, class _Compare2, class _Alloc2>
friend class _LIBCPP_TEMPLATE_VIS set;
template <class _Key2, class _Compare2, class _Alloc2>
friend class _LIBCPP_TEMPLATE_VIS multiset;
// construct/copy/destroy:
_LIBCPP_INLINE_VISIBILITY
multiset()
@@ -868,7 +984,7 @@ public:
#if _LIBCPP_STD_VER > 11
template <class _InputIterator>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY
multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
: multiset(__f, __l, key_compare(), __a) {}
#endif
@@ -932,7 +1048,7 @@ public:
}
#if _LIBCPP_STD_VER > 11
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY
multiset(initializer_list<value_type> __il, const allocator_type& __a)
: multiset(__il, key_compare(), __a) {}
#endif
@@ -1042,6 +1158,67 @@ public:
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__tree_.clear();}
#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VISIBILITY
iterator insert(node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to multiset::insert()");
return __tree_.template __node_handle_insert_multi<node_type>(
_VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to multiset::insert()");
return __tree_.template __node_handle_insert_multi<node_type>(
__hint, _VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(key_type const& __key)
{
return __tree_.template __node_handle_extract<node_type>(__key);
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(const_iterator __it)
{
return __tree_.template __node_handle_extract<node_type>(__it);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multiset<key_type, _Compare2, allocator_type>& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_multi(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_multi(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(set<key_type, _Compare2, allocator_type>& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_multi(__source.__tree_);
}
template <class _Compare2>
_LIBCPP_INLINE_VISIBILITY
void merge(set<key_type, _Compare2, allocator_type>&& __source)
{
_LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
"merging container with incompatible allocator");
__tree_.__node_handle_merge_multi(__source.__tree_);
}
#endif
_LIBCPP_INLINE_VISIBILITY
void swap(multiset& __s)
_NOEXCEPT_(__is_nothrow_swappable<__base>::value)

View File

@@ -124,12 +124,13 @@ template <class Mutex>
*/
#include <__config>
#include <version>
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_SHARED_MUTEX)
#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_LIBRARY)
#include <__mutex_base>
@@ -143,7 +144,8 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base
struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("shared_mutex"))
__shared_mutex_base
{
mutex __mut_;
condition_variable __gate1_;
@@ -160,14 +162,14 @@ struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base
__shared_mutex_base& operator=(const __shared_mutex_base&) = delete;
// Exclusive ownership
void lock(); // blocking
bool try_lock();
void unlock();
void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); // blocking
bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
// Shared ownership
void lock_shared(); // blocking
bool try_lock_shared();
void unlock_shared();
void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_shared_capability()); // blocking
bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_shared_capability(true));
void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_shared_capability());
// typedef implementation-defined native_handle_type; // See 30.2.3
// native_handle_type native_handle(); // See 30.2.3

564
include/span Normal file
View File

@@ -0,0 +1,564 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
#ifndef _LIBCPP_SPAN
#define _LIBCPP_SPAN
/*
span synopsis
namespace std {
// constants
inline constexpr ptrdiff_t dynamic_extent = -1;
// [views.span], class template span
template <class ElementType, ptrdiff_t Extent = dynamic_extent>
class span;
// [span.objectrep], views of object representation
template <class ElementType, ptrdiff_t Extent>
span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :
(static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept;
template <class ElementType, ptrdiff_t Extent>
span< byte, ((Extent == dynamic_extent) ? dynamic_extent :
(static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;
namespace std {
template <class ElementType, ptrdiff_t Extent = dynamic_extent>
class span {
public:
// constants and types
using element_type = ElementType;
using value_type = remove_cv_t<ElementType>;
using index_type = ptrdiff_t;
using difference_type = ptrdiff_t;
using pointer = element_type*;
using reference = element_type&;
using iterator = implementation-defined;
using const_iterator = implementation-defined;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static constexpr index_type extent = Extent;
// [span.cons], span constructors, copy, assignment, and destructor
constexpr span() noexcept;
constexpr span(pointer ptr, index_type count);
constexpr span(pointer firstElem, pointer lastElem);
template <size_t N>
constexpr span(element_type (&arr)[N]) noexcept;
template <size_t N>
constexpr span(array<value_type, N>& arr) noexcept;
template <size_t N>
constexpr span(const array<value_type, N>& arr) noexcept;
template <class Container>
constexpr span(Container& cont);
template <class Container>
constexpr span(const Container& cont);
constexpr span(const span& other) noexcept = default;
template <class OtherElementType, ptrdiff_t OtherExtent>
constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept;
~span() noexcept = default;
constexpr span& operator=(const span& other) noexcept = default;
// [span.sub], span subviews
template <ptrdiff_t Count>
constexpr span<element_type, Count> first() const;
template <ptrdiff_t Count>
constexpr span<element_type, Count> last() const;
template <ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent>
constexpr span<element_type, see below> subspan() const;
constexpr span<element_type, dynamic_extent> first(index_type count) const;
constexpr span<element_type, dynamic_extent> last(index_type count) const;
constexpr span<element_type, dynamic_extent> subspan(index_type offset, index_type count = dynamic_extent) const;
// [span.obs], span observers
constexpr index_type size() const noexcept;
constexpr index_type size_bytes() const noexcept;
constexpr bool empty() const noexcept;
// [span.elem], span element access
constexpr reference operator[](index_type idx) const;
constexpr reference operator()(index_type idx) const;
constexpr pointer data() const noexcept;
// [span.iterators], span iterator support
constexpr iterator begin() const noexcept;
constexpr iterator end() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
constexpr reverse_iterator rbegin() const noexcept;
constexpr reverse_iterator rend() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
private:
pointer data_; // exposition only
index_type size_; // exposition only
};
template<class T, size_t N>
span(T (&)[N]) -> span<T, N>;
template<class T, size_t N>
span(array<T, N>&) -> span<T, N>;
template<class T, size_t N>
span(const array<T, N>&) -> span<const T, N>;
template<class Container>
span(Container&) -> span<typename Container::value_type>;
template<class Container>
span(const Container&) -> span<const typename Container::value_type>;
} // namespace std
*/
#include <__config>
#include <cstddef> // for ptrdiff_t
#include <iterator> // for iterators
#include <array> // for array
#include <type_traits> // for remove_cv, etc
#include <cstddef> // for byte
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
inline constexpr ptrdiff_t dynamic_extent = -1;
template <typename _Tp, ptrdiff_t _Extent = dynamic_extent> class span;
template <class _Tp>
struct __is_span_impl : public false_type {};
template <class _Tp, ptrdiff_t _Extent>
struct __is_span_impl<span<_Tp, _Extent>> : public true_type {};
template <class _Tp>
struct __is_span : public __is_span_impl<remove_cv_t<_Tp>> {};
template <class _Tp>
struct __is_std_array_impl : public false_type {};
template <class _Tp, size_t _Sz>
struct __is_std_array_impl<array<_Tp, _Sz>> : public true_type {};
template <class _Tp>
struct __is_std_array : public __is_std_array_impl<remove_cv_t<_Tp>> {};
template <class _Tp, class _ElementType, class = void>
struct __is_span_compatible_container : public false_type {};
template <class _Tp, class _ElementType>
struct __is_span_compatible_container<_Tp, _ElementType,
void_t<
// is not a specialization of span
typename enable_if<!__is_span<_Tp>::value, nullptr_t>::type,
// is not a specialization of array
typename enable_if<!__is_std_array<_Tp>::value, nullptr_t>::type,
// is_array_v<Container> is false,
typename enable_if<!is_array_v<_Tp>, nullptr_t>::type,
// data(cont) and size(cont) are well formed
decltype(data(declval<_Tp>())),
decltype(size(declval<_Tp>())),
// remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[]
typename enable_if<
is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[],
_ElementType(*)[]>,
nullptr_t>::type
>>
: public true_type {};
template <typename _Tp, ptrdiff_t _Extent>
class _LIBCPP_TEMPLATE_VIS span {
public:
// constants and types
using element_type = _Tp;
using value_type = remove_cv_t<_Tp>;
using index_type = ptrdiff_t;
using difference_type = ptrdiff_t;
using pointer = _Tp *;
using const_pointer = const _Tp *; // not in standard
using reference = _Tp &;
using const_reference = const _Tp &; // not in standard
using iterator = __wrap_iter<pointer>;
using const_iterator = __wrap_iter<const_pointer>;
using reverse_iterator = _VSTD::reverse_iterator<iterator>;
using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
static constexpr index_type extent = _Extent;
static_assert (_Extent >= 0, "Can't have a span with an extent < 0");
// [span.cons], span constructors, copy, assignment, and destructor
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}
{ static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); }
constexpr span (const span&) noexcept = default;
constexpr span& operator=(const span&) noexcept = default;
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}
{ (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); }
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}
{ (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); }
_LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {}
_LIBCPP_INLINE_VISIBILITY constexpr span( array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
_LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span( _Container& __c,
enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr)
: __data{_VSTD::data(__c)}
{ _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (container)"); }
template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const _Container& __c,
enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr)
: __data{_VSTD::data(__c)}
{ _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (const container)"); }
template <class _OtherElementType>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const span<_OtherElementType, _Extent>& __other,
enable_if_t<
is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
nullptr_t> = nullptr)
: __data{__other.data()} {}
template <class _OtherElementType>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const span<_OtherElementType, dynamic_extent>& __other,
enable_if_t<
is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
nullptr_t> = nullptr) noexcept
: __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); }
// ~span() noexcept = default;
template <ptrdiff_t _Count>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> first() const noexcept
{
static_assert(_Count >= 0, "Count must be >= 0 in span::first()");
static_assert(_Count <= _Extent, "Count out of range in span::first()");
return {data(), _Count};
}
template <ptrdiff_t _Count>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> last() const noexcept
{
static_assert(_Count >= 0, "Count must be >= 0 in span::last()");
static_assert(_Count <= _Extent, "Count out of range in span::last()");
return {data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept
{
_LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::first(count)");
return {data(), __count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> last(index_type __count) const noexcept
{
_LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::last(count)");
return {data() + size() - __count, __count};
}
template <ptrdiff_t _Offset, ptrdiff_t _Count = dynamic_extent>
inline _LIBCPP_INLINE_VISIBILITY
constexpr auto subspan() const noexcept
-> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>
{
_LIBCPP_ASSERT(_Offset >= 0 && _Offset <= size(), "Offset out of range in span::subspan()");
return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent>
subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept
{
_LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)");
_LIBCPP_ASSERT((__count >= 0 && __count <= size()) || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
_LIBCPP_ASSERT(__offset + __count <= size(), "count + offset out of range in span::subspan(offset, count)");
return {data() + __offset, __count};
}
_LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return _Extent; }
_LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return _Extent * sizeof(element_type); }
_LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; }
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>() index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
// [span.iter], span iterator support
_LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
_LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept
{
pointer __p = __data;
__data = __other.__data;
__other.__data = __p;
}
_LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept
{ return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
_LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writeable_bytes() const noexcept
{ return {reinterpret_cast<byte *>(data()), size_bytes()}; }
private:
pointer __data;
};
template <typename _Tp>
class _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> {
private:
public:
// constants and types
using element_type = _Tp;
using value_type = remove_cv_t<_Tp>;
using index_type = ptrdiff_t;
using difference_type = ptrdiff_t;
using pointer = _Tp *;
using const_pointer = const _Tp *; // not in standard
using reference = _Tp &;
using const_reference = const _Tp &; // not in standard
using iterator = __wrap_iter<pointer>;
using const_iterator = __wrap_iter<const_pointer>;
using reverse_iterator = _VSTD::reverse_iterator<iterator>;
using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
static constexpr index_type extent = dynamic_extent;
// [span.cons], span constructors, copy, assignment, and destructor
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {}
constexpr span (const span&) noexcept = default;
constexpr span& operator=(const span&) noexcept = default;
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}, __size{__count} {}
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{distance(__f, __l)} {}
template <size_t _Sz>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {}
template <size_t _Sz>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
template <size_t _Sz>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span( _Container& __c,
enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr)
: __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {}
template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const _Container& __c,
enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr)
: __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {}
template <class _OtherElementType, ptrdiff_t _OtherExtent>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const span<_OtherElementType, _OtherExtent>& __other,
enable_if_t<
is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
nullptr_t> = nullptr) noexcept
: __data{__other.data()}, __size{__other.size()} {}
// ~span() noexcept = default;
template <ptrdiff_t _Count>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> first() const noexcept
{
static_assert(_Count >= 0, "Count must be >= 0 in span::first()");
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()");
return {data(), _Count};
}
template <ptrdiff_t _Count>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> last() const noexcept
{
static_assert(_Count >= 0, "Count must be >= 0 in span::last()");
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()");
return {data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept
{
_LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::first(count)");
return {data(), __count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> last (index_type __count) const noexcept
{
_LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::last(count)");
return {data() + size() - __count, __count};
}
template <ptrdiff_t _Offset, ptrdiff_t _Count = dynamic_extent>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<_Tp, dynamic_extent> subspan() const noexcept
{
_LIBCPP_ASSERT(_Offset >= 0 && _Offset <= size(), "Offset out of range in span::subspan()");
_LIBCPP_ASSERT(_Count == dynamic_extent || _Offset + _Count <= size(), "Count out of range in span::subspan()");
return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
constexpr span<element_type, dynamic_extent>
inline _LIBCPP_INLINE_VISIBILITY
subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept
{
_LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)");
_LIBCPP_ASSERT((__count >= 0 && __count <= size()) || __count == dynamic_extent, "count out of range in span::subspan(offset, count)");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
_LIBCPP_ASSERT(__offset + __count <= size(), "Offset + count out of range in span::subspan(offset, count)");
return {data() + __offset, __count};
}
_LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return __size; }
_LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return __size * sizeof(element_type); }
_LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; }
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>() index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
// [span.iter], span iterator support
_LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
_LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept
{
pointer __p = __data;
__data = __other.__data;
__other.__data = __p;
index_type __sz = __size;
__size = __other.__size;
__other.__size = __sz;
}
_LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept
{ return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
_LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writeable_bytes() const noexcept
{ return {reinterpret_cast<byte *>(data()), size_bytes()}; }
private:
pointer __data;
index_type __size;
};
// as_bytes & as_writeable_bytes
template <class _Tp, ptrdiff_t _Extent>
auto as_bytes(span<_Tp, _Extent> __s) noexcept
-> decltype(__s.__as_bytes())
{ return __s.__as_bytes(); }
template <class _Tp, ptrdiff_t _Extent>
auto as_writeable_bytes(span<_Tp, _Extent> __s) noexcept
-> typename enable_if<!is_const_v<_Tp>, decltype(__s.__as_writeable_bytes())>::type
{ return __s.__as_writeable_bytes(); }
template <class _Tp, ptrdiff_t _Extent>
constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept
{ __lhs.swap(__rhs); }
// Deduction guides
template<class _Tp, size_t _Sz>
span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;
template<class _Tp, size_t _Sz>
span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>;
template<class _Tp, size_t _Sz>
span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>;
template<class _Container>
span(_Container&) -> span<typename _Container::value_type>;
template<class _Container>
span(const _Container&) -> span<const typename _Container::value_type>;
#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_SPAN

View File

@@ -473,12 +473,12 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
{
while (__sz > INT_MAX)
{
this->pbump(INT_MAX);
__sz -= INT_MAX;
this->pbump(INT_MAX);
__sz -= INT_MAX;
}
if (__sz > 0)
this->pbump(__sz);
}
this->pbump(__sz);
}
}
}

View File

@@ -54,7 +54,7 @@ using std::nullptr_t;
// Re-use the compiler's <stddef.h> max_align_t where possible.
#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T) && \
!defined(__DEFINED_max_align_t)
!defined(__DEFINED_max_align_t) && !defined(__NetBSD__)
typedef long double max_align_t;
#endif

View File

@@ -185,73 +185,73 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// in the dylib
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_logic_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw logic_error(__msg);
#else
((void)__msg);
_VSTD::abort();
_VSTD::abort();
#endif
}
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_domain_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw domain_error(__msg);
#else
((void)__msg);
_VSTD::abort();
_VSTD::abort();
#endif
}
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_invalid_argument(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw invalid_argument(__msg);
#else
((void)__msg);
_VSTD::abort();
_VSTD::abort();
#endif
}
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_length_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw length_error(__msg);
#else
((void)__msg);
_VSTD::abort();
_VSTD::abort();
#endif
}
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_out_of_range(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw out_of_range(__msg);
#else
((void)__msg);
_VSTD::abort();
_VSTD::abort();
#endif
}
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_range_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw range_error(__msg);
#else
((void)__msg);
_VSTD::abort();
_VSTD::abort();
#endif
}
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_overflow_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -262,7 +262,7 @@ void __throw_overflow_error(const char*__msg)
#endif
}
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_underflow_error(const char*__msg)
{
#ifndef _LIBCPP_NO_EXCEPTIONS

Some files were not shown because too many files have changed in this diff Show More