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:
185
CMakeLists.txt
185
CMakeLists.txt
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
135
benchmarks/CartesianBenchmarks.hpp
Normal file
135
benchmarks/CartesianBenchmarks.hpp
Normal 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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
232
benchmarks/function.bench.cpp
Normal file
232
benchmarks/function.bench.cpp
Normal 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
23
benchmarks/lit.cfg.py
Normal 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)
|
||||
10
benchmarks/lit.site.cfg.py.in
Normal file
10
benchmarks/lit.site.cfg.py.in
Normal 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")
|
||||
249
benchmarks/ordered_set.bench.cpp
Normal file
249
benchmarks/ordered_set.bench.cpp
Normal 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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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**: ``""``
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
494
docs/DesignDocs/FileTimeType.rst
Normal file
494
docs/DesignDocs/FileTimeType.rst
Normal 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.
|
||||
@@ -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
|
||||
=====
|
||||
|
||||
|
||||
@@ -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
62
docs/ReleaseNotes.rst
Normal 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.
|
||||
@@ -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``
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
|
||||
|
||||
@@ -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/>`_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
345
include/__config
345
include/__config
@@ -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
|
||||
|
||||
@@ -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@
|
||||
|
||||
|
||||
@@ -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
218
include/__errc
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1 +1 @@
|
||||
7000
|
||||
8000
|
||||
|
||||
184
include/__locale
184
include/__locale
@@ -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;
|
||||
|
||||
|
||||
@@ -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
210
include/__node_handle
Normal 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
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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);}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
244
include/__tree
244
include/__tree
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
15
include/any
15
include/any
@@ -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>;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
158
include/bit
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
617
include/charconv
Normal 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
|
||||
1590
include/chrono
1590
include/chrono
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
{
|
||||
|
||||
@@ -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() {}
|
||||
};
|
||||
|
||||
|
||||
110
include/compare
110
include/compare
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
2679
include/filesystem
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
275
include/fstream
275
include/fstream
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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_;}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
34
include/ios
34
include/ios
@@ -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
|
||||
|
||||
408
include/istream
408
include/istream
@@ -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:
|
||||
|
||||
133
include/iterator
133
include/iterator
@@ -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
|
||||
|
||||
@@ -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>;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
197
include/locale
197
include/locale
@@ -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_;}
|
||||
};
|
||||
|
||||
|
||||
178
include/map
178
include/map
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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:
|
||||
|
||||
175
include/new
175
include/new
@@ -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" );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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_;}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
185
include/set
185
include/set
@@ -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)
|
||||
|
||||
@@ -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
564
include/span
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user