Vendor import of libc++ trunk r351319 (just before the release_80

branch point):
https://llvm.org/svn/llvm-project/libcxx/trunk@351319
This commit is contained in:
Dimitry Andric 2019-01-19 10:05:35 +00:00
parent 315d10f09e
commit 6012fe9abb
1057 changed files with 40289 additions and 7106 deletions

View File

@ -27,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")
@ -50,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()
@ -77,7 +82,12 @@ option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of libc++fs.a"
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++")
@ -111,15 +121,12 @@ cmake_dependent_option(LIBCXX_INSTALL_FILESYSTEM_LIBRARY
"Install libc++fs.a" ON
"LIBCXX_ENABLE_FILESYSTEM;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++.")
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)
@ -175,7 +182,7 @@ cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY
cmake_dependent_option(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY
"Statically link the ABI library to shared library" ON
"LIBCXX_ENABLE_STATIC_ABI_LIBRARY;LIBCXX_ENABLE_STATIC" OFF)
"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
@ -276,6 +283,9 @@ endif()
option(LIBCXX_CONFIGURE_IDE "Configure libcxx for use within an IDE"
${LIBCXX_CONFIGURE_IDE_DEFAULT})
option(LIBCXX_HERMETIC_STATIC_LIBRARY
"Do not export any symbols from the static library." OFF)
#===============================================================================
# Check option configurations
#===============================================================================
@ -502,14 +512,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()
@ -544,11 +556,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
@ -621,47 +651,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)
@ -724,6 +774,18 @@ include_directories(include)
add_subdirectory(include)
add_subdirectory(lib)
set(LIBCXX_TEST_DEPS "")
if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
list(APPEND LIBCXX_TEST_DEPS cxx_experimental)
endif()
if (LIBCXX_ENABLE_FILESYSTEM)
list(APPEND LIBCXX_TEST_DEPS cxx_filesystem)
endif()
if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY)
list(APPEND LIBCXX_TEST_DEPS cxx_external_threads)
endif()
if (LIBCXX_INCLUDE_BENCHMARKS)
add_subdirectory(benchmarks)

View File

@ -14,7 +14,7 @@ Full text of the relevant licenses is included below.
University of Illinois/NCSA
Open Source License
Copyright (c) 2009-2017 by the contributors listed in CREDITS.TXT
Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT
All rights reserved.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,124 @@
#include <array>
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <tuple>
#include <vector>
#include "benchmark/benchmark.h"
#include "CartesianBenchmarks.hpp"
#include "GenerateInput.hpp"
namespace {
template <typename I, typename N>
std::array<I, 10> every_10th_percentile_N(I first, N n) {
N step = n / 10;
std::array<I, 10> res;
for (size_t i = 0; i < 10; ++i) {
res[i] = first;
std::advance(first, step);
}
return res;
}
template <class IntT>
struct TestIntBase {
static std::vector<IntT> generateInput(size_t size) {
std::vector<IntT> Res(size);
std::generate(Res.begin(), Res.end(),
[] { return getRandomInteger<IntT>(); });
return Res;
}
};
struct TestInt32 : TestIntBase<std::int32_t> {
static constexpr const char* Name = "TestInt32";
};
struct TestInt64 : TestIntBase<std::int64_t> {
static constexpr const char* Name = "TestInt64";
};
struct TestUint32 : TestIntBase<std::uint32_t> {
static constexpr const char* Name = "TestUint32";
};
struct TestMediumString {
static constexpr const char* Name = "TestMediumString";
static constexpr size_t StringSize = 32;
static std::vector<std::string> generateInput(size_t size) {
std::vector<std::string> Res(size);
std::generate(Res.begin(), Res.end(), [] { return getRandomString(StringSize); });
return Res;
}
};
using AllTestTypes = std::tuple<TestInt32, TestInt64, TestUint32, TestMediumString>;
struct LowerBoundAlg {
template <class I, class V>
I operator()(I first, I last, const V& value) const {
return std::lower_bound(first, last, value);
}
static constexpr const char* Name = "LowerBoundAlg";
};
struct UpperBoundAlg {
template <class I, class V>
I operator()(I first, I last, const V& value) const {
return std::upper_bound(first, last, value);
}
static constexpr const char* Name = "UpperBoundAlg";
};
struct EqualRangeAlg {
template <class I, class V>
std::pair<I, I> operator()(I first, I last, const V& value) const {
return std::equal_range(first, last, value);
}
static constexpr const char* Name = "EqualRangeAlg";
};
using AllAlgs = std::tuple<LowerBoundAlg, UpperBoundAlg, EqualRangeAlg>;
template <class Alg, class TestType>
struct PartitionPointBench {
size_t Quantity;
std::string name() const {
return std::string("PartitionPointBench_") + Alg::Name + "_" +
TestType::Name + '/' + std::to_string(Quantity);
}
void run(benchmark::State& state) const {
auto Data = TestType::generateInput(Quantity);
std::sort(Data.begin(), Data.end());
auto Every10Percentile = every_10th_percentile_N(Data.begin(), Data.size());
for (auto _ : state) {
for (auto Test : Every10Percentile)
benchmark::DoNotOptimize(Alg{}(Data.begin(), Data.end(), *Test));
}
}
};
} // 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 << 8, 1 << 10, 1 << 20};
makeCartesianProductBenchmark<PartitionPointBench, AllAlgs, AllTestTypes>(
Quantities);
benchmark::RunSpecifiedBenchmarks();
}

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,6 +8,9 @@ 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

View File

@ -41,7 +41,7 @@ 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}

View File

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

View File

@ -222,6 +222,15 @@ libc++ specific options
Define libc++ destination prefix.
.. option:: LIBCXX_HERMETIC_STATIC_LIBRARY:BOOL
**Default**: ``OFF``
Do not export any symbols from the static libc++ library. This is useful when
This is useful when the static libc++ library is being linked into shared
libraries that may be used in with other shared libraries that use different
C++ library. We want to avoid avoid exporting any libc++ symbols in that case.
.. _libc++experimental options:
libc++experimental Specific Options
@ -316,6 +325,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**:: ``""``
@ -332,6 +350,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
--------------------------
@ -351,6 +378,20 @@ The following options allow building libc++ for a different ABI version.
Build the "unstable" ABI version of libc++. Includes all ABI changing features
on top of the current stable version.
.. option:: LIBCXX_ABI_NAMESPACE:STRING
**Default**: ``__n`` where ``n`` is the current ABI version.
This option defines the name of the inline ABI versioning namespace. It can be used for building
custom versions of libc++ with unique symbol names in order to prevent conflicts or ODR issues
with other libc++ versions.
.. warning::
When providing a custom namespace, it's the users responsibility to ensure the name won't cause
conflicts with other names defined by libc++, both now and in the future. In particular, inline
namespaces of the form ``__[0-9]+`` are strictly reserved by libc++ and may not be used by users.
Doing otherwise could cause conflicts and hinder libc++ ABI evolution.
.. option:: LIBCXX_ABI_DEFINES:STRING
**Default**: ``""``

View File

@ -24,11 +24,11 @@ systems. For example::
// Define availability macros.
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE)
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
#else if defined(_LIBCPP_USE_AVAILABILITY_SOME_OTHER_VENDOR)
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
#else
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
#else
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
#endif
When the library is updated by the platform vendor, the markup can be updated.
@ -43,9 +43,9 @@ For example::
In the source code, the macro can be added on a class if the full class requires
type info from the library for example::
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
: public std::logic_error {
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
: public std::logic_error {
or on a particular symbol:
@ -55,7 +55,7 @@ or on a particular symbol:
Testing
=======
Some parameters can be passed to lit to run the test-suite and exercising the
Some parameters can be passed to lit to run the test-suite and exercise the
availability.
* The `platform` parameter controls the deployment target. For example lit can
@ -65,14 +65,11 @@ 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 `--param=platform=macosx10.8` is passed, the following features will be available:
- availability
- availability=x86_64
@ -81,11 +78,11 @@ 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
be available:
* if `use_system_cxx_lib` and `--param=platform=macosx10.8` are passed to lit,
the following features will also be available:
- with_system_cxx_lib
- with_system_cxx_lib=x86_64
@ -94,21 +91,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
particular system version.
* if `with_availability` is passed to lit, the following features will also
be available:
- availability_markup
- availability_markup=x86_64
- availability_markup=macosx
- availability_markup=x86_64-macosx
- 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
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.
system. For example, if the test exhibits a bug in the libc on a particular
system version, or if the test uses a symbol that is not available on an
older version of the dylib (but for which there is no availability markup,
otherwise the XFAIL should use `availability` above).

View File

@ -28,7 +28,7 @@ Design Goals
It makes developers lives harder if they have to regenerate the libc++ headers
every time they are modified.
* The solution should not make any of the libc++ headers dependant on
* The solution should not make any of the libc++ headers dependent on
files generated by the build system. The headers should be able to compile
out of the box without any modification.

View File

@ -0,0 +1,44 @@
===================
Feature Test Macros
===================
.. contents::
:local:
Overview
========
Libc++ implements the C++ feature test macros as specified in the C++2a standard,
and before that in non-normative guiding documents (`See cppreference <https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros>`)
Design
======
Feature test macros are tricky to track, implement, test, and document correctly.
They must be available from a list of headers, they may have different values in
different dialects, and they may or may not be implemented by libc++. In order to
track all of these conditions correctly and easily, we want a Single Source of
Truth (SSoT) that defines each feature test macro, its values, the headers it
lives in, and whether or not is is implemented by libc++. From this SSoA we
have enough information to automatically generate the `<version>` header,
the tests, and the documentation.
Therefore we maintain a SSoA in
`libcxx/test/std/language.support/support.limits/support.limits.general/generate_feature_test_macro_components.py`
which doubles as a script to generate the following components:
* The `<version>` header.
* The version tests under `support.limits.general`.
* Documentation of libc++'s implementation of each macro.
Usage
=====
The `generate_feature_test_macro_components.py` script is used to track and
update feature test macros in libc++.
Whenever a feature test macro is added or changed, the table should be updated
and the script should be re-ran. The script will clobber the existing test files
and the documentation and it will generate a new `<version>` header as a
temporary file. The generated `<version>` header should be merged with the
existing one.

View File

@ -22,11 +22,11 @@ Visibility Macros
Mark a symbol as being exported by the libc++ library. This attribute must
be applied to the declaration of all functions exported by the libc++ dylib.
**_LIBCPP_EXTERN_VIS**
**_LIBCPP_EXPORTED_FROM_ABI**
Mark a symbol as being exported by the libc++ library. This attribute may
only be applied to objects defined in the libc++ library. On Windows this
macro applies `dllimport`/`dllexport` to the symbol. On all other platforms
this macro has no effect.
only be applied to objects defined in the libc++ runtime library. On Windows,
this macro applies `dllimport`/`dllexport` to the symbol, and on other
platforms it gives the symbol default visibility.
**_LIBCPP_OVERRIDABLE_FUNC_VIS**
Mark a symbol as being exported by the libc++ library, but allow it to be
@ -42,9 +42,57 @@ Visibility Macros
**_LIBCPP_HIDE_FROM_ABI**
Mark a function as not being part of the ABI of any final linked image that
uses it, and also as being internal to each TU that uses that function. In
other words, the address of a function marked with this attribute is not
guaranteed to be the same across translation units.
uses it.
**_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*.

View File

@ -0,0 +1,200 @@
.. _FeatureTestMacroTable:
==========================
Feature Test Macro Support
==========================
.. contents::
:local:
Overview
========
This file documents the feature test macros currently supported by libc++.
.. _feature-status:
Status
======
.. table:: Current Status
:name: feature-status-table
:widths: auto
================================================= =================
Macro Name Value
================================================= =================
**C++ 14**
-------------------------------------------------------------------
``__cpp_lib_chrono_udls`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_complex_udls`` ``201309L``
------------------------------------------------- -----------------
``__cpp_lib_exchange_function`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_generic_associative_lookup`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_integer_sequence`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_integral_constant_callable`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_is_final`` ``201402L``
------------------------------------------------- -----------------
``__cpp_lib_is_null_pointer`` ``201309L``
------------------------------------------------- -----------------
``__cpp_lib_make_reverse_iterator`` ``201402L``
------------------------------------------------- -----------------
``__cpp_lib_make_unique`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_null_iterators`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_quoted_string_io`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_result_of_sfinae`` ``201210L``
------------------------------------------------- -----------------
``__cpp_lib_robust_nonmodifying_seq_ops`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_shared_timed_mutex`` ``201402L``
------------------------------------------------- -----------------
``__cpp_lib_string_udls`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_transformation_trait_aliases`` ``201304L``
------------------------------------------------- -----------------
``__cpp_lib_transparent_operators`` ``201210L``
------------------------------------------------- -----------------
``__cpp_lib_tuple_element_t`` ``201402L``
------------------------------------------------- -----------------
``__cpp_lib_tuples_by_type`` ``201304L``
------------------------------------------------- -----------------
**C++ 17**
-------------------------------------------------------------------
``__cpp_lib_addressof_constexpr`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_allocator_traits_is_always_equal`` ``201411L``
------------------------------------------------- -----------------
``__cpp_lib_any`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_apply`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_array_constexpr`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_as_const`` ``201510L``
------------------------------------------------- -----------------
``__cpp_lib_atomic_is_always_lock_free`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_bool_constant`` ``201505L``
------------------------------------------------- -----------------
``__cpp_lib_boyer_moore_searcher`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_byte`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_chrono`` ``201611L``
------------------------------------------------- -----------------
``__cpp_lib_clamp`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_enable_shared_from_this`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_execution`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_filesystem`` ``201703L``
------------------------------------------------- -----------------
``__cpp_lib_gcd_lcm`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_hardware_interference_size`` ``201703L``
------------------------------------------------- -----------------
``__cpp_lib_has_unique_object_representations`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_hypot`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_incomplete_container_elements`` ``201505L``
------------------------------------------------- -----------------
``__cpp_lib_invoke`` ``201411L``
------------------------------------------------- -----------------
``__cpp_lib_is_aggregate`` ``201703L``
------------------------------------------------- -----------------
``__cpp_lib_is_invocable`` ``201703L``
------------------------------------------------- -----------------
``__cpp_lib_is_swappable`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_launder`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_logical_traits`` ``201510L``
------------------------------------------------- -----------------
``__cpp_lib_make_from_tuple`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_map_try_emplace`` ``201411L``
------------------------------------------------- -----------------
``__cpp_lib_math_special_functions`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_memory_resource`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_node_extract`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_nonmember_container_access`` ``201411L``
------------------------------------------------- -----------------
``__cpp_lib_not_fn`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_optional`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_parallel_algorithm`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_raw_memory_algorithms`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_sample`` ``201603L``
------------------------------------------------- -----------------
``__cpp_lib_scoped_lock`` ``201703L``
------------------------------------------------- -----------------
``__cpp_lib_shared_mutex`` ``201505L``
------------------------------------------------- -----------------
``__cpp_lib_shared_ptr_arrays`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_shared_ptr_weak_type`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_string_view`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_to_chars`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_transparent_operators`` ``201510L``
------------------------------------------------- -----------------
``__cpp_lib_type_trait_variable_templates`` ``201510L``
------------------------------------------------- -----------------
``__cpp_lib_uncaught_exceptions`` ``201411L``
------------------------------------------------- -----------------
``__cpp_lib_unordered_map_try_emplace`` ``201411L``
------------------------------------------------- -----------------
``__cpp_lib_variant`` ``201606L``
------------------------------------------------- -----------------
``__cpp_lib_void_t`` ``201411L``
------------------------------------------------- -----------------
**C++ 2a**
-------------------------------------------------------------------
``__cpp_lib_atomic_ref`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_bind_front`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_bit_cast`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_char8_t`` ``201811L``
------------------------------------------------- -----------------
``__cpp_lib_concepts`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_constexpr_misc`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_constexpr_swap_algorithms`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_destroying_delete`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_erase_if`` ``201811L``
------------------------------------------------- -----------------
``__cpp_lib_generic_unordered_lookup`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_is_constant_evaluated`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_list_remove_return_type`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_ranges`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_three_way_comparison`` *unimplemented*
================================================= =================

62
docs/ReleaseNotes.rst Normal file
View File

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

View File

@ -138,8 +138,7 @@ configuration. Passing the option on the command line will override the default.
Specify the directory of the libc++ library to use at runtime. This directory
is not added to the linkers search path. This can be used to compile tests
against one version of libc++ and run them using another. The default value
for this option is `cxx_library_root`. This option cannot be used
when use_system_cxx_lib is provided.
for this option is `cxx_library_root`.
.. option:: use_system_cxx_lib=<bool>
@ -155,14 +154,6 @@ configuration. Passing the option on the command line will override the default.
the default value. Otherwise the default value is True on Windows and False
on every other platform.
.. option:: no_default_flags=<bool>
**Default**: False
Disable all default compile and link flags from being added. When this
option is used only flags specified using the compile_flags and link_flags
will be used.
.. option:: compile_flags="<list-of-args>"
Specify additional compile flags as a space delimited string.

View File

@ -203,8 +203,10 @@ thread safety annotations.
This macro disables the additional diagnostics generated by libc++ using the
`diagnose_if` attribute. These additional diagnostics include checks for:
* Giving `set`, `map`, `multiset`, `multimap` a comparator which is not
const callable.
* Giving `set`, `map`, `multiset`, `multimap` and their `unordered_`
counterparts a comparator which is not const callable.
* Giving an unordered associative container a hasher that is not const
callable.
**_LIBCPP_NO_VCRUNTIME**:
Microsoft's C and C++ headers are fairly entangled, and some of their C++
@ -226,6 +228,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**:
@ -238,3 +260,58 @@ C++17 Specific Configuration Macros
**_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR**:
This macro is used to re-enable `std::auto_ptr` in C++17.
C++2a Specific Configuration Macros:
------------------------------------
**_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17**:
This macro can be used to disable diagnostics emitted from functions marked
``[[nodiscard]]`` in dialects after C++17. See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>`
for more information.
Libc++ Extensions
=================
This section documents various extensions provided by libc++, how they're
provided, and any information regarding how to use them.
.. _nodiscard extension:
Extended applications of ``[[nodiscard]]``
------------------------------------------
The ``[[nodiscard]]`` attribute is intended to help users find bugs where
function return values are ignored when they shouldn't be. After C++17 the
C++ standard has started to declared such library functions as ``[[nodiscard]]``.
However, this application is limited and applies only to dialects after C++17.
Users who want help diagnosing misuses of STL functions may desire a more
liberal application of ``[[nodiscard]]``.
For this reason libc++ provides an extension that does just that! The
extension must be enabled by defining ``_LIBCPP_ENABLE_NODISCARD``. The extended
applications of ``[[nodiscard]]`` takes two forms:
1. Backporting ``[[nodiscard]]`` to entities declared as such by the
standard in newer dialects, but not in the present one.
2. Extended applications of ``[[nodiscard]]``, at the libraries discretion,
applied to entities never declared as such by the standard.
Users may also opt-out of additional applications ``[[nodiscard]]`` using
additional macros.
Applications of the first form, which backport ``[[nodiscard]]`` from a newer
dialect may be disabled using macros specific to the dialect it was added. For
example ``_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17``.
Applications of the second form, which are pure extensions, may be disabled
by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``.
Entities declared with ``_LIBCPP_NODISCARD_EXT``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This section lists all extended applications of ``[[nodiscard]]`` to entities
which no dialect declares as such (See the second form described above).
* ``get_temporary_buffer``

View File

@ -40,16 +40,16 @@
# 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_show_urls = 'footnote'
# FIXME: Define intersphinx configration.
# FIXME: Define intersphinx configuration.
intersphinx_mapping = {}

View File

@ -34,11 +34,17 @@ Getting Started with libc++
.. toctree::
:maxdepth: 2
ReleaseNotes
UsingLibcxx
BuildingLibcxx
TestingLibcxx
.. toctree::
:hidden:
FeatureTestMacroTable
Current Status
--------------
@ -79,8 +85,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,8 +110,9 @@ 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>`__
* :ref:`C++ Feature Test Macro Status <feature-status>`
Notes and Known Issues
----------------------
@ -135,6 +142,7 @@ Design Documents
DesignDocs/VisibilityMacros
DesignDocs/ThreadingSupportAPI
DesignDocs/FileTimeType
DesignDocs/FeatureTestMacros
* `<atomic> design <http://libcxx.llvm.org/atomic_design.html>`_
* `<type_traits> design <http://libcxx.llvm.org/type_traits_design.html>`_
@ -160,21 +168,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>`_.
@ -183,7 +188,7 @@ Quick Links
* `LLVM Homepage <http://llvm.org/>`_
* `libc++abi Homepage <http://libcxxabi.llvm.org/>`_
* `LLVM Bugzilla <https://bugs.llvm.org/>`_
* `cfe-commits Mailing List`_
* `cfe-dev Mailing List`_
* `libcxx-commits Mailing List`_
* `libcxx-dev Mailing List`_
* `Browse libc++ -- SVN <http://llvm.org/svn/llvm-project/libcxx/trunk/>`_
* `Browse libc++ -- ViewVC <http://llvm.org/viewvc/llvm-project/libcxx/trunk/>`_

View File

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

View File

@ -25,6 +25,7 @@ set(files
any
array
atomic
bit
bitset
cassert
ccomplex
@ -68,7 +69,6 @@ set(files
experimental/chrono
experimental/coroutine
experimental/deque
experimental/dynarray
experimental/filesystem
experimental/forward_list
experimental/functional

View File

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

View File

@ -33,14 +33,10 @@
# 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
@ -99,6 +95,8 @@
// Use the smallest possible integer type to represent the index of the variant.
// Previously libc++ used "unsigned int" exclusivly.
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
// Unstable attempt to provide a more optimized std::function
# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
#elif _LIBCPP_ABI_VERSION == 1
# if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
// Enable compiling copies of now inline methods into the dylib to support
@ -123,7 +121,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
@ -328,6 +328,43 @@
# 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
#ifndef _LIBCPP_CXX03_LANG
# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
#elif defined(_LIBCPP_COMPILER_CLANG)
# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
#else
// This definition is potentially buggy, but it's only taken with GCC in C++03,
// which we barely support anyway. See llvm.org/PR39713
# define _LIBCPP_ALIGNOF(_Tp) __alignof(_Tp)
#endif
#define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
#if defined(_LIBCPP_COMPILER_CLANG)
// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for
@ -342,7 +379,7 @@
# define _ALIGNAS_TYPE(x) alignas(x)
# define _ALIGNAS(x) alignas(x)
#else
# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
# define _ALIGNAS(x) __attribute__((__aligned__(x)))
#endif
@ -430,28 +467,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
@ -464,16 +479,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
@ -493,10 +498,15 @@ namespace std {
#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)))
#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
#define _LIBCPP_NORETURN __attribute__((noreturn))
@ -563,15 +573,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
@ -607,13 +608,6 @@ 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
@ -625,7 +619,7 @@ namespace std {
#elif defined(_LIBCPP_COMPILER_IBM)
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
#define _ATTRIBUTE(x) __attribute__((x))
#define _LIBCPP_NORETURN __attribute__((noreturn))
@ -641,15 +635,6 @@ 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__))
@ -658,20 +643,6 @@ namespace std {
#endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM]
#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
#if defined(_LIBCPP_OBJECT_FORMAT_COFF)
#ifdef _DLL
@ -685,33 +656,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_EXTERN_TEMPLATE_INLINE_VISIBILITY __forceinline
#else
# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__ ((__always_inline__))
#endif
#endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)
#ifndef _LIBCPP_HIDDEN
@ -759,8 +726,12 @@ namespace std {
# endif
#endif
#ifndef _LIBCPP_EXTERN_VIS
#define _LIBCPP_EXTERN_VIS
#ifndef _LIBCPP_EXPORTED_FROM_ABI
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default")))
# else
# define _LIBCPP_EXPORTED_FROM_ABI
# endif
#endif
#ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS
@ -801,21 +772,63 @@ namespace std {
# define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE
#endif
#ifndef _LIBCPP_HIDE_FROM_ABI
# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE
#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
// Just so we can migrate to _LIBCPP_HIDE_FROM_ABI gradually.
#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI
#ifndef _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__visibility__("default"), __always_inline__))
#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_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__always_inline__))
# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1
# endif
#endif
#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_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
# endif
#endif
#ifdef _LIBCPP_BUILDING_LIBRARY
# if _LIBCPP_ABI_VERSION > 1
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
# else
# 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, "")))
@ -976,7 +989,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__)
@ -984,13 +1004,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
@ -1000,18 +1020,46 @@ template <unsigned> struct __static_assert_check {};
#define _LIBCPP_WCTYPE_IS_MASK
#endif
#if _LIBCPP_STD_VER > 11
# define _LIBCPP_DEPRECATED [[deprecated]]
#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t)
#define _LIBCPP_NO_HAS_CHAR8_T
#endif
// 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_DEPRECATED
# endif
#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)
@ -1032,8 +1080,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
@ -1090,6 +1160,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
defined(__Fuchsia__) || \
defined(__NetBSD__) || \
defined(__linux__) || \
defined(__GNU__) || \
defined(__APPLE__) || \
defined(__CloudABI__) || \
defined(__sun__) || \
@ -1195,8 +1266,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)
@ -1250,9 +1325,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))) \
@ -1276,8 +1357,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
@ -1289,26 +1370,30 @@ _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
// extern template should effectively be available at:
// availability(macosx,introduced=10.9)
// availability(ios,introduced=7.0)
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE) && \
// The stream API was dropped and re-added in the dylib shipped on macOS
// and iOS. We can only assume the dylib to provide these definitions for
// macosx >= 10.9 and ios >= 7.0. Otherwise, the definitions are available
// from the headers, but not from the dylib. Explicit instantiation
// declarations for streams exist conditionally to this; if we provide
// an explicit instantiation declaration and we try to deploy to a dylib
// that does not provide those symbols, we'll get a load-time error.
#if !defined(_LIBCPP_BUILDING_LIBRARY) && \
((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1090) || \
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000))
#define _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
# define _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB
#endif
#if defined(_LIBCPP_COMPILER_IBM)
@ -1351,6 +1436,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY)
#endif // _LIBCPP_NO_AUTO_LINK
#define _LIBCPP_UNUSED_VAR(x) ((void)(x))
#endif // __cplusplus
#endif // _LIBCPP_CONFIG

View File

@ -14,6 +14,7 @@
#cmakedefine _LIBCPP_ABI_UNSTABLE
#cmakedefine _LIBCPP_ABI_FORCE_ITANIUM
#cmakedefine _LIBCPP_ABI_FORCE_MICROSOFT
#cmakedefine _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT
#cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
#cmakedefine _LIBCPP_HAS_NO_STDIN
#cmakedefine _LIBCPP_HAS_NO_STDOUT
@ -27,6 +28,7 @@
#cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL
#cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
#cmakedefine _LIBCPP_NO_VCRUNTIME
#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@
@_LIBCPP_ABI_DEFINES@

View File

@ -74,7 +74,7 @@ typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&);
/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT
/// fails.
extern _LIBCPP_EXTERN_VIS __libcpp_debug_function_type __libcpp_debug_function;
extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function;
/// __libcpp_abort_debug_function - A debug handler that aborts when called.
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS

View File

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

View File

@ -35,15 +35,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Key, class _Tp>
struct __hash_value_type;
template <class _Key, class _Cp, class _Hash,
bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value>
class __unordered_map_hasher;
template <class _Key, class _Cp, class _Pred,
bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
>
class __unordered_map_equal;
#ifndef _LIBCPP_CXX03_LANG
template <class _Tp>
struct __is_hash_value_type_imp : false_type {};
@ -418,7 +409,7 @@ public:
_LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this));
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY
__hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
: __node_(__x.__node_)
{
@ -871,35 +862,32 @@ struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
};
#endif
template <class _Key, class _Hash, class _Equal>
struct __enforce_unordered_container_requirements {
#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Hash, class _Equal, class _Alloc>
struct __diagnose_hash_table_helper {
static constexpr bool __trigger_diagnostics()
_LIBCPP_DIAGNOSE_WARNING(__check_hash_requirements<_Key, _Hash>::value
&& !__invokable<_Hash const&, _Key const&>::value,
"the specified hash functor does not provide a const call operator")
_LIBCPP_DIAGNOSE_WARNING(is_copy_constructible<_Equal>::value
&& !__invokable<_Equal const&, _Key const&, _Key const&>::value,
"the specified comparator type does not provide a const call operator")
{
static_assert(__check_hash_requirements<_Key, _Hash>::value,
"the specified hash does not meet the Hash requirements");
"the specified hash does not meet the Hash requirements");
static_assert(is_copy_constructible<_Equal>::value,
"the specified comparator is required to be copy constructible");
return true;
}
"the specified comparator is required to be copy constructible");
#endif
typedef int type;
};
template <class _Key, class _Value, class _Hash, class _Equal, class _Alloc>
struct __diagnose_hash_table_helper<
__hash_value_type<_Key, _Value>,
__unordered_map_hasher<_Key, __hash_value_type<_Key, _Value>, _Hash>,
__unordered_map_equal<_Key, __hash_value_type<_Key, _Value>, _Equal>,
_Alloc>
: __diagnose_hash_table_helper<_Key, _Hash, _Equal, _Alloc>
{
};
#endif // _LIBCPP_CXX03_LANG
template <class _Key, class _Hash, class _Equal>
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value,
"the specified comparator type does not provide a const call operator")
_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value,
"the specified hash functor does not provide a const call operator")
#endif
typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type
__diagnose_unordered_container_requirements(int);
// This dummy overload is used so that the compiler won't emit a spurious
// "no matching function for call to __diagnose_unordered_xxx" diagnostic
// when the overload above causes a hard error.
template <class _Key, class _Hash, class _Equal>
int __diagnose_unordered_container_requirements(void*);
template <class _Tp, class _Hash, class _Equal, class _Alloc>
class __hash_table
@ -963,10 +951,6 @@ private:
typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits;
typedef typename __bucket_list_deleter::pointer __node_pointer_pointer;
#ifndef _LIBCPP_CXX03_LANG
static_assert(__diagnose_hash_table_helper<_Tp, _Hash, _Equal, _Alloc>::__trigger_diagnostics(), "");
#endif
// --- Member data begin ---
__bucket_list __bucket_list_;
__compressed_pair<__first_node, __node_allocator> __p1_;
@ -1058,8 +1042,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);
@ -1170,6 +1172,9 @@ public:
_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
@ -1177,6 +1182,9 @@ public:
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
@ -1849,73 +1857,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)
{
@ -1923,8 +1970,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();
@ -1938,24 +2021,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)
@ -1966,6 +2031,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
@ -2216,6 +2292,32 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
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
@ -2244,6 +2346,27 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
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>

View File

@ -1 +1 @@
7000
8000

View File

@ -1255,13 +1255,13 @@ 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_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_INLINE_VISIBILITY
@ -1289,13 +1289,13 @@ 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_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_INLINE_VISIBILITY
@ -1345,13 +1345,13 @@ 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_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_INLINE_VISIBILITY
@ -1379,13 +1379,13 @@ 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_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_INLINE_VISIBILITY

View File

@ -76,9 +76,9 @@ struct _LIBCPP_TYPE_VIS adopt_lock_t {};
#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

View File

@ -26,8 +26,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
#define __cpp_lib_node_extract 201606L
// Specialized in __tree & __hash_table for their _NodeType.
template <class _NodeType, class _Alloc>
struct __generic_container_node_destructor;

View File

@ -55,14 +55,14 @@ public:
__allocated_ = true;
return (pointer)&buf_;
}
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_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), _LIBCPP_ALIGNOF(_Tp));
}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}

View File

@ -47,6 +47,7 @@ struct char_traits
template <> struct char_traits<char>;
template <> struct char_traits<wchar_t>;
template <> struct char_traits<char8_t>; // c++20
} // std
@ -389,6 +390,102 @@ char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __
}
#ifndef _LIBCPP_NO_HAS_CHAR8_T
template <>
struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
{
typedef char8_t char_type;
typedef unsigned int int_type;
typedef streamoff off_type;
typedef u8streampos pos_type;
typedef mbstate_t state_type;
static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
{__c1 = __c2;}
static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
{return __c1 == __c2;}
static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
{return __c1 < __c2;}
static constexpr
int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
static constexpr
size_t length(const char_type* __s) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY static constexpr
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
_LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
}
static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
{return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
static inline constexpr int_type not_eof(int_type __c) noexcept
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
static inline constexpr char_type to_char_type(int_type __c) noexcept
{return char_type(__c);}
static inline constexpr int_type to_int_type(char_type __c) noexcept
{return int_type(__c);}
static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
{return __c1 == __c2;}
static inline constexpr int_type eof() noexcept
{return int_type(EOF);}
};
// TODO use '__builtin_strlen' if it ever supports char8_t ??
inline constexpr
size_t
char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
{
size_t __len = 0;
for (; !eq(*__s, char_type(0)); ++__s)
++__len;
return __len;
}
inline constexpr
int
char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
#if __has_feature(cxx_constexpr_string_builtins)
return __builtin_memcmp(__s1, __s2, __n);
#else
for (; __n; --__n, ++__s1, ++__s2)
{
if (lt(*__s1, *__s2))
return -1;
if (lt(*__s2, *__s1))
return 1;
}
return 0;
#endif
}
// TODO use '__builtin_char_memchr' if it ever supports char8_t ??
inline constexpr
const char8_t*
char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
{
for (; __n; --__n)
{
if (eq(*__s, __a))
return __s;
++__s;
}
return 0;
}
#endif // #_LIBCPP_NO_HAS_CHAR8_T
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
template <>

View File

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

View File

@ -40,10 +40,6 @@ template <class _Tp, class _VoidPtr> class __tree_node;
template <class _Key, class _Value>
struct __value_type;
template <class _Key, class _CP, class _Compare,
bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
class __map_value_compare;
template <class _Allocator> class __map_node_destructor;
template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
@ -857,7 +853,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
@ -966,24 +962,12 @@ private:
};
template<class _Tp, class _Compare>
#ifndef _LIBCPP_CXX03_LANG
template <class _Tp, class _Compare, class _Allocator>
struct __diagnose_tree_helper {
static constexpr bool __trigger_diagnostics()
_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
"the specified comparator type does not provide a const call operator")
{ return true; }
};
template <class _Key, class _Value, class _KeyComp, class _Alloc>
struct __diagnose_tree_helper<
__value_type<_Key, _Value>,
__map_value_compare<_Key, __value_type<_Key, _Value>, _KeyComp>,
_Alloc
> : __diagnose_tree_helper<_Key, _KeyComp, _Alloc>
{
};
#endif // !_LIBCPP_CXX03_LANG
_LIBCPP_DIAGNOSE_WARNING(!std::__invokable<_Compare const&, _Tp const&, _Tp const&>::value,
"the specified comparator type does not provide a const call operator")
#endif
int __diagnose_non_const_comparator();
template <class _Tp, class _Compare, class _Allocator>
class __tree
@ -1341,15 +1325,20 @@ 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);
_LIBCPP_INLINE_VISIBILITY iterator
__remove_node_pointer(__node_pointer) _NOEXCEPT;
#if _LIBCPP_STD_VER > 14
template <class _NodeHandle, class _InsertReturnType>
@ -1358,6 +1347,9 @@ public:
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
@ -1365,6 +1357,9 @@ public:
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>
@ -1384,7 +1379,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);
@ -1488,7 +1483,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
@ -1830,7 +1825,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>());
@ -1844,10 +1839,6 @@ __tree<_Tp, _Compare, _Allocator>::~__tree()
{
static_assert((is_copy_constructible<value_compare>::value),
"Comparator must be copy-constructible.");
#ifndef _LIBCPP_CXX03_LANG
static_assert((__diagnose_tree_helper<_Tp, _Compare, _Allocator>::
__trigger_diagnostics()), "");
#endif
destroy(__root());
}
@ -2129,10 +2120,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;
@ -2384,7 +2374,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
template <class _Tp, class _Compare, class _Allocator>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr)
__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT
{
iterator __r(__ptr);
++__r;
@ -2471,6 +2461,30 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p)
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
@ -2507,6 +2521,28 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(
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>

View File

@ -22,36 +22,36 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size;
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size;
#if !defined(_LIBCPP_CXX03_LANG)
template <class _Tp, class...>
using __enable_if_tuple_size_imp = _Tp;
template <class _Tp>
class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
const _Tp,
typename enable_if<!is_volatile<_Tp>::value>::type,
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
template <class _Tp>
class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
volatile _Tp,
typename enable_if<!is_const<_Tp>::value>::type,
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
template <class _Tp>
class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp<
const volatile _Tp,
integral_constant<size_t, sizeof(tuple_size<_Tp>)>>>
: public integral_constant<size_t, tuple_size<_Tp>::value> {};
#else
template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {};
template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {};
template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {};
#endif
template <size_t _Ip, class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_element;
@ -165,7 +165,7 @@ template <class ..._Tp> class _LIBCPP_TEMPLATE_VIS tuple;
template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};
template <class ..._Tp>
class _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> >
struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> >
: public integral_constant<size_t, sizeof...(_Tp)>
{
};
@ -291,7 +291,7 @@ public:
template <class ..._Tp>
class _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> >
struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> >
: public integral_constant<size_t, sizeof...(_Tp)>
{
};

View File

@ -645,13 +645,8 @@ template <class BidirectionalIterator, class Compare>
#include <functional>
#include <iterator>
#include <cstddef>
#if defined(__IBMCPP__)
#include "support/ibm/support.h"
#endif
#if defined(_LIBCPP_COMPILER_MSVC)
#include <intrin.h>
#endif
#include <bit>
#include <version>
#include <__debug>
@ -755,6 +750,32 @@ public:
bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);}
};
// Perform division by two quickly for positive integers (llvm.org/PR39129)
template <typename _Integral>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
typename enable_if
<
is_integral<_Integral>::value,
_Integral
>::type
__half_positive(_Integral __value)
{
return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2);
}
template <typename _Tp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
typename enable_if
<
!is_integral<_Tp>::value,
_Tp
>::type
__half_positive(_Tp __value)
{
return __value / 2;
}
#ifdef _LIBCPP_DEBUG
template <class _Compare>
@ -788,135 +809,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>
@ -2533,6 +2425,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 +2491,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 +2579,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 +2925,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 +2979,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 +3000,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 +3015,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));
}
}
}
@ -3328,7 +3228,7 @@ partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __
difference_type __len = _VSTD::distance(__first, __last);
while (__len != 0)
{
difference_type __l2 = __len / 2;
difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
if (__pred(*__m))
@ -3737,6 +3637,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)
@ -4195,7 +4096,7 @@ __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
difference_type __len = _VSTD::distance(__first, __last);
while (__len != 0)
{
difference_type __l2 = __len / 2;
difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
if (__comp(*__m, __value_))
@ -4214,14 +4115,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>
@ -4243,7 +4138,7 @@ __upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
difference_type __len = _VSTD::distance(__first, __last);
while (__len != 0)
{
difference_type __l2 = __len / 2;
difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
if (__comp(__value_, *__m))
@ -4262,14 +4157,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>
@ -4291,7 +4180,7 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
difference_type __len = _VSTD::distance(__first, __last);
while (__len != 0)
{
difference_type __l2 = __len / 2;
difference_type __l2 = _VSTD::__half_positive(__len);
_ForwardIterator __m = __first;
_VSTD::advance(__m, __l2);
if (__comp(*__m, __value_))

View File

@ -87,13 +87,14 @@ namespace std {
#include <typeinfo>
#include <type_traits>
#include <cstdlib>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
namespace std {
class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
{
public:
virtual const char* what() const _NOEXCEPT;
@ -105,12 +106,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
_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
}
@ -576,6 +578,7 @@ any make_any(initializer_list<_Up> __il, _Args&&... __args) {
template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
_ValueType any_cast(any const & __v)
{
using _RawValueType = __uncvref_t<_ValueType>;
@ -590,6 +593,7 @@ _ValueType any_cast(any const & __v)
template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
_ValueType any_cast(any & __v)
{
using _RawValueType = __uncvref_t<_ValueType>;
@ -604,6 +608,7 @@ _ValueType any_cast(any & __v)
template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
_ValueType any_cast(any && __v)
{
using _RawValueType = __uncvref_t<_ValueType>;

View File

@ -91,7 +91,7 @@ template <class T, size_t N>
template <class T, size_t N >
void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // C++17
template <class T> class tuple_size;
template <class T> struct tuple_size;
template <size_t I, class T> class tuple_element;
template <class T, size_t N> struct tuple_size<array<T, N>>;
template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>;
@ -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);
@ -429,7 +430,7 @@ swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y)
}
template <class _Tp, size_t _Size>
class _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
struct _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
: public integral_constant<size_t, _Size> {};
template <size_t _Ip, class _Tp, size_t _Size>

View File

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

158
include/bit Normal file
View File

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

View File

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

View File

@ -87,8 +87,16 @@ namespace std {
#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
@ -147,9 +155,6 @@ static constexpr uint32_t __pow10_32[] = {
UINT32_C(1000000000),
};
_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
template <typename _Tp, typename = void>
struct _LIBCPP_HIDDEN __traits_base
{
@ -607,4 +612,6 @@ from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP_CHARCONV

File diff suppressed because it is too large Load Diff

View File

@ -303,6 +303,7 @@ long double truncl(long double x);
#include <__config>
#include <math.h>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header

View File

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

View File

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

View File

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

View File

@ -73,7 +73,7 @@ using ::gmtime;
using ::localtime;
#endif
using ::strftime;
#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES)
#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET)
using ::timespec_get;
#endif

View File

@ -150,6 +150,11 @@ template <class T, class Allocator>
void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(deque<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(deque<T, Allocator>& c, Predicate pred); // C++20
} // std
*/
@ -161,6 +166,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
@ -986,7 +992,7 @@ public:
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT;
#else
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value);
#endif
protected:
@ -1155,7 +1161,7 @@ __deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT
#else
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value)
#endif
{
@ -2341,7 +2347,7 @@ deque<_Tp, _Allocator>::__add_front_capacity()
_Dp(__a, __base::__block_size));
__buf.push_back(__hold.get());
__hold.release();
for (typename __base::__map_pointer __i = __base::__map_.begin();
__i != __base::__map_.end(); ++__i)
__buf.push_back(*__i);
@ -2603,6 +2609,7 @@ template <class _Tp, class _Allocator>
void
deque<_Tp, _Allocator>::pop_back()
{
_LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque");
allocator_type& __a = __base::__alloc();
size_type __p = __base::size() + __base::__start_ - 1;
__alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
@ -2853,7 +2860,7 @@ deque<_Tp, _Allocator>::swap(deque& __c)
#if _LIBCPP_STD_VER >= 14
_NOEXCEPT
#else
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value)
#endif
{
@ -2926,6 +2933,19 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
__x.swap(__y);
}
#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(deque<_Tp, _Allocator>& __c, const _Up& __v)
{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); }
template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); }
#endif
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS

View File

@ -81,6 +81,7 @@ template <class E> void rethrow_if_nested(const E& e);
#include <cstddef>
#include <cstdlib>
#include <type_traits>
#include <version>
#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
#include <vcruntime_exception.h>
@ -163,7 +164,7 @@ public:
};
template<class _Ep>
exception_ptr
_LIBCPP_INLINE_VISIBILITY exception_ptr
make_exception_ptr(_Ep __e) _NOEXCEPT
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@ -222,7 +223,7 @@ _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr p);
template <class _E> void *__GetExceptionInfo(_E);
template<class _Ep>
exception_ptr
_LIBCPP_INLINE_VISIBILITY exception_ptr
make_exception_ptr(_Ep __e) _NOEXCEPT
{
return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e));

View File

@ -1,11 +1,21 @@
// -*- C++ -*-
//===------------------------------ any -----------------------------------===//
//===------------------------------- any ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_ANY
#define _LIBCPP_EXPERIMENTAL_ANY
#error "<experimental/any> has been removed. Use <any> instead."
#include <__config>
#ifdef _LIBCPP_WARNING
_LIBCPP_WARNING("<experimental/any> has been removed. Use <any> instead.")
#else
# warning "<experimental/any> has been removed. Use <any> instead."
#endif
#endif // _LIBCPP_EXPERIMENTAL_ANY

View File

@ -1,11 +1,21 @@
// -*- C++ -*-
//===------------------------------ chrono ---------------------------------===//
//===---------------------------- chrono ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_CHRONO
#define _LIBCPP_EXPERIMENTAL_CHRONO
#error "<experimental/chrono> has been removed. Use <chrono> instead."
#include <__config>
#ifdef _LIBCPP_WARNING
_LIBCPP_WARNING("<experimental/chrono> has been removed. Use <chrono> instead.")
#else
# warning "<experimental/chrono> has been removed. Use <chrono> instead."
#endif
#endif // _LIBCPP_EXPERIMENTAL_CHRONO

View File

@ -214,7 +214,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
_Promise& promise() const {
return *static_cast<_Promise*>(
__builtin_coro_promise(this->__handle_, __alignof(_Promise), false));
__builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
}
public:
@ -254,7 +254,7 @@ public:
coroutine_handle __tmp;
__tmp.__handle_ = __builtin_coro_promise(
_VSTD::addressof(const_cast<_RawPromise&>(__promise)),
__alignof(_Promise), true);
_LIBCPP_ALIGNOF(_Promise), true);
return __tmp;
}
};
@ -272,7 +272,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
_Promise& promise() const {
return *static_cast<_Promise*>(
__builtin_coro_promise(this->__handle_, __alignof(_Promise), false));
__builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
}
_LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; }

View File

@ -1,305 +0,0 @@
// -*- C++ -*-
//===-------------------------- dynarray ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_DYNARRAY
#define _LIBCPP_DYNARRAY
/*
dynarray synopsis
namespace std { namespace experimental {
template< typename T >
class dynarray
{
// types:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef implementation-defined iterator;
typedef implementation-defined const_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
public:
// construct/copy/destroy:
explicit dynarray(size_type c);
dynarray(size_type c, const T& v);
dynarray(const dynarray& d);
dynarray(initializer_list<T>);
template <class Alloc>
dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc);
template <class Alloc>
dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc);
template <class Alloc>
dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc);
template <class Alloc>
dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);
dynarray& operator=(const dynarray&) = delete;
~dynarray();
// iterators:
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator crbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
// capacity:
size_type size() const noexcept;
size_type max_size() const noexcept;
bool empty() const noexcept;
// element access:
reference operator[](size_type n);
const_reference operator[](size_type n) const;
reference front();
const_reference front() const;
reference back();
const_reference back() const;
const_reference at(size_type n) const;
reference at(size_type n);
// data access:
T* data() noexcept;
const T* data() const noexcept;
// mutating member functions:
void fill(const T& v);
};
}} // std::experimental
*/
#include <__config>
#if _LIBCPP_STD_VER > 11
#include <__functional_base>
#include <iterator>
#include <stdexcept>
#include <initializer_list>
#include <new>
#include <algorithm>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
namespace std { namespace experimental { inline namespace __array_extensions_v1 {
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_DYNARRAY dynarray
{
public:
// types:
typedef dynarray __self;
typedef _Tp value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
private:
size_t __size_;
value_type * __base_;
_LIBCPP_INLINE_VISIBILITY 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

View File

@ -98,7 +98,7 @@ size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT
// 8.5, memory.resource
class _LIBCPP_TYPE_VIS memory_resource
{
static const size_t __max_align = alignof(max_align_t);
static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t);
// 8.5.2, memory.resource.public
public:
@ -190,7 +190,7 @@ public:
" 'n' exceeds maximum supported size");
}
return static_cast<_ValueType*>(
__res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType))
__res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType))
);
}
@ -198,7 +198,7 @@ public:
void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
_LIBCPP_ASSERT(__n <= __max_size(),
"deallocate called for size which exceeds max_size()");
__res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
__res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType));
}
template <class _Tp, class ..._Ts>
@ -345,7 +345,7 @@ class _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp
&& is_same<typename _CTraits::pointer, char*>::value
&& is_same<typename _CTraits::void_pointer, void*>::value, "");
static const size_t _MaxAlign = alignof(max_align_t);
static const size_t _MaxAlign = _LIBCPP_ALIGNOF(max_align_t);
using _Alloc = typename _CTraits::template rebind_alloc<
typename aligned_storage<_MaxAlign, _MaxAlign>::type

View File

@ -7,5 +7,15 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_NUMERIC
#define _LIBCPP_EXPERIMENTAL_NUMERIC
#error "<experimental/numeric> has been removed. Use <numeric> instead."
#include <__config>
#ifdef _LIBCPP_WARNING
_LIBCPP_WARNING("<experimental/numeric> has been removed. Use <numeric> instead.")
#else
# warning "<experimental/numeric> has been removed. Use <numeric> instead."
#endif
#endif // _LIBCPP_EXPERIMENTAL_NUMERIC

View File

@ -7,5 +7,15 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_OPTIONAL
#define _LIBCPP_EXPERIMENTAL_OPTIONAL
#error "<experimental/optional> has been removed. Use <optional> instead."
#include <__config>
#ifdef _LIBCPP_WARNING
_LIBCPP_WARNING("<experimental/optional> has been removed. Use <optional> instead.")
#else
# warning "<experimental/optional> has been removed. Use <optional> instead."
#endif
#endif // _LIBCPP_EXPERIMENTAL_OPTIONAL

View File

@ -1,11 +1,21 @@
// -*- C++ -*-
//===------------------------------ ratio ---------------------------------===//
//===----------------------------- ratio ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_RATIO
#define _LIBCPP_EXPERIMENTAL_RATIO
#error "<experimental/ratio> has been removed. Use <ratio> instead."
#include <__config>
#ifdef _LIBCPP_WARNING
_LIBCPP_WARNING("<experimental/ratio> has been removed. Use <ratio> instead.")
#else
# warning "<experimental/ratio> has been removed. Use <ratio> instead."
#endif
#endif // _LIBCPP_EXPERIMENTAL_RATIO

View File

@ -3,9 +3,19 @@
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_STRING_VIEW
#define _LIBCPP_EXPERIMENTAL_STRING_VIEW
#error "<experimental/string_view> has been removed. Use <string_view> instead."
#include <__config>
#ifdef _LIBCPP_WARNING
_LIBCPP_WARNING("<experimental/string_view> has been removed. Use <string_view> instead.")
#else
# warning "<experimental/string_view> has been removed. Use <string_view> instead."
#endif
#endif // _LIBCPP_EXPERIMENTAL_STRING_VIEW

View File

@ -7,5 +7,15 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR
#define _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR
#error "<experimental/system_error> has been removed. Use <system_error> instead."
#include <__config>
#ifdef _LIBCPP_WARNING
_LIBCPP_WARNING("<experimental/system_error> has been removed. Use <system_error> instead.")
#else
# warning "<experimental/system_error> has been removed. Use <system_error> instead."
#endif
#endif // _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR

View File

@ -7,5 +7,15 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_TUPLE
#define _LIBCPP_EXPERIMENTAL_TUPLE
#error "<experimental/tuple> has been removed. Use <tuple> instead."
#include <__config>
#ifdef _LIBCPP_WARNING
_LIBCPP_WARNING("<experimental/tuple> has been removed. Use <tuple> instead.")
#else
# warning "<experimental/tuple> has been removed. Use <tuple> instead."
#endif
#endif // _LIBCPP_EXPERIMENTAL_TUPLE

View File

@ -244,6 +244,7 @@
#include <utility>
#include <iomanip> // for quoted
#include <string_view>
#include <version>
#include <__debug>
@ -256,42 +257,8 @@ _LIBCPP_PUSH_MACROS
#ifndef _LIBCPP_CXX03_LANG
#if _LIBCPP_STD_VER >= 17
#define __cpp_lib_filesystem 201703
#endif
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
struct _FilesystemClock {
#if !defined(_LIBCPP_HAS_NO_INT128)
typedef __int128_t rep;
typedef nano period;
#else
typedef long long rep;
typedef nano period;
#endif
typedef chrono::duration<rep, period> duration;
typedef chrono::time_point<_FilesystemClock> time_point;
static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
_LIBCPP_FUNC_VIS static time_point now() noexcept;
_LIBCPP_INLINE_VISIBILITY
static time_t to_time_t(const time_point& __t) noexcept {
typedef chrono::duration<rep> __secs;
return time_t(
chrono::duration_cast<__secs>(__t.time_since_epoch()).count());
}
_LIBCPP_INLINE_VISIBILITY
static time_point from_time_t(time_t __t) noexcept {
typedef chrono::duration<rep> __secs;
return time_point(__secs(__t));
}
};
typedef chrono::time_point<_FilesystemClock> file_time_type;
struct _LIBCPP_TYPE_VIS space_info {
@ -590,7 +557,7 @@ template <class _ECharT>
typename enable_if<__can_convert_char<_ECharT>::value, bool>::type
__is_separator(_ECharT __e) {
return __e == _ECharT('/');
};
}
struct _NullSentinal {};
@ -1184,6 +1151,31 @@ public:
return __is;
}
friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept {
return __lhs.compare(__rhs) == 0;
}
friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept {
return __lhs.compare(__rhs) != 0;
}
friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept {
return __lhs.compare(__rhs) < 0;
}
friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept {
return __lhs.compare(__rhs) <= 0;
}
friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept {
return __lhs.compare(__rhs) > 0;
}
friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept {
return __lhs.compare(__rhs) >= 0;
}
friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
const path& __rhs) {
path __result(__lhs);
__result /= __rhs;
return __result;
}
private:
inline _LIBCPP_INLINE_VISIBILITY path&
__assign_view(__string_view const& __s) noexcept {
@ -1200,43 +1192,6 @@ inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept {
_LIBCPP_FUNC_VIS
size_t hash_value(const path& __p) noexcept;
inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs,
const path& __rhs) noexcept {
return __lhs.compare(__rhs) == 0;
}
inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs,
const path& __rhs) noexcept {
return __lhs.compare(__rhs) != 0;
}
inline _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs,
const path& __rhs) noexcept {
return __lhs.compare(__rhs) < 0;
}
inline _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs,
const path& __rhs) noexcept {
return __lhs.compare(__rhs) <= 0;
}
inline _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs,
const path& __rhs) noexcept {
return __lhs.compare(__rhs) > 0;
}
inline _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs,
const path& __rhs) noexcept {
return __lhs.compare(__rhs) >= 0;
}
inline _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs,
const path& __rhs) {
path __result(__lhs);
__result /= __rhs;
return __result;
}
template <class _Source>
_LIBCPP_INLINE_VISIBILITY
typename enable_if<__is_pathable<_Source>::value, path>::type

View File

@ -167,6 +167,11 @@ template <class T, class Allocator>
void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(forward_list<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20
} // std
*/
@ -177,6 +182,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
@ -1743,6 +1749,18 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
__x.swap(__y);
}
#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.remove_if(__pred); }
template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v)
{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
#endif
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS

View File

@ -702,6 +702,7 @@ basic_filebuf<_CharT, _Traits>::close()
__file_ = 0;
else
__rt = 0;
setbuf(0, 0);
}
return __rt;
}

File diff suppressed because it is too large Load Diff

View File

@ -556,13 +556,14 @@ public:
{return (__state_ & __constructed) || (__exception_ != nullptr);}
_LIBCPP_INLINE_VISIBILITY
void __set_future_attached()
{
void __attach_future() {
lock_guard<mutex> __lk(__mut_);
bool __has_future_attached = (__state_ & __future_attached) != 0;
if (__has_future_attached)
__throw_future_error(future_errc::future_already_retrieved);
this->__add_shared();
__state_ |= __future_attached;
}
_LIBCPP_INLINE_VISIBILITY
bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
_LIBCPP_INLINE_VISIBILITY
void __set_deferred() {__state_ |= deferred;}
@ -1154,10 +1155,7 @@ template <class _Rp>
future<_Rp>::future(__assoc_state<_Rp>* __state)
: __state_(__state)
{
if (__state_->__has_future_attached())
__throw_future_error(future_errc::future_already_retrieved);
__state_->__add_shared();
__state_->__set_future_attached();
__state_->__attach_future();
}
struct __release_shared_count
@ -1257,10 +1255,7 @@ template <class _Rp>
future<_Rp&>::future(__assoc_state<_Rp&>* __state)
: __state_(__state)
{
if (__state_->__has_future_attached())
__throw_future_error(future_errc::future_already_retrieved);
__state_->__add_shared();
__state_->__set_future_attached();
__state_->__attach_future();
}
template <class _Rp>

View File

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

View File

@ -18,6 +18,12 @@ namespace std
{
template<class charT> struct char_traits;
template<> struct char_traits<char>;
template<> struct char_traits<char8_t>; // C++20
template<> struct char_traits<char16_t>;
template<> struct char_traits<char32_t>;
template<> struct char_traits<wchar_t>;
template<class T> class allocator;
class ios_base;
@ -98,6 +104,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_TYPE_VIS ios_base;
template<class _CharT> struct _LIBCPP_TEMPLATE_VIS char_traits;
template<> struct char_traits<char>;
#ifndef _LIBCPP_NO_HAS_CHAR8_T
template<> struct char_traits<char8_t>;
#endif
template<> struct char_traits<char16_t>;
template<> struct char_traits<char32_t>;
template<> struct char_traits<wchar_t>;
template<class _Tp> class _LIBCPP_TEMPLATE_VIS allocator;
template <class _CharT, class _Traits = char_traits<_CharT> >
@ -175,6 +189,9 @@ typedef basic_fstream<wchar_t> wfstream;
template <class _State> class _LIBCPP_TEMPLATE_VIS fpos;
typedef fpos<mbstate_t> streampos;
typedef fpos<mbstate_t> wstreampos;
#ifndef _LIBCPP_NO_HAS_CHAR8_T
typedef fpos<mbstate_t> u8streampos;
#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
typedef fpos<mbstate_t> u16streampos;
typedef fpos<mbstate_t> u32streampos;

View File

@ -160,6 +160,7 @@ template <class charT, class traits, class T>
*/
#include <__config>
#include <version>
#include <ostream>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@ -186,7 +187,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 +201,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 +217,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 +250,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 +258,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')); }
@ -517,8 +518,9 @@ basic_istream<_CharT, _Traits>::operator>>(int& __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
@ -527,13 +529,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()))
@ -545,12 +544,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);
}
@ -564,6 +562,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>&
@ -580,6 +620,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)
@ -1238,7 +1280,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)
{}
@ -1253,7 +1295,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:
@ -1463,7 +1505,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
return __is;
}
#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<wchar_t>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<char>)

View File

@ -418,6 +418,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <type_traits>
#include <cstddef>
#include <initializer_list>
#include <version>
#ifdef __APPLE__
#include <Availability.h>
#endif
@ -436,6 +437,23 @@ struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_t
struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
template <class _Tp>
struct __has_iterator_typedefs
{
private:
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename std::__void_t<typename _Up::iterator_category>::type* = 0,
typename std::__void_t<typename _Up::difference_type>::type* = 0,
typename std::__void_t<typename _Up::value_type>::type* = 0,
typename std::__void_t<typename _Up::reference>::type* = 0,
typename std::__void_t<typename _Up::pointer>::type* = 0
);
public:
static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1;
};
template <class _Tp>
struct __has_iterator_category
{
@ -478,7 +496,7 @@ struct __iterator_traits<_Iter, true>
template <class _Iter>
struct _LIBCPP_TEMPLATE_VIS iterator_traits
: __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {};
: __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {};
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*>

View File

@ -82,6 +82,7 @@ template<> class numeric_limits<cv char>;
template<> class numeric_limits<cv signed char>;
template<> class numeric_limits<cv unsigned char>;
template<> class numeric_limits<cv wchar_t>;
template<> class numeric_limits<cv char8_t>; // C++20
template<> class numeric_limits<cv char16_t>;
template<> class numeric_limits<cv char32_t>;
@ -118,6 +119,7 @@ template<> class numeric_limits<cv long double>;
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
#include <version>
_LIBCPP_BEGIN_NAMESPACE_STD

View File

@ -169,6 +169,11 @@ template <class T, class Alloc>
void swap(list<T,Alloc>& x, list<T,Alloc>& y)
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(list<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(list<T, Allocator>& c, Predicate pred); // C++20
} // std
*/
@ -181,6 +186,7 @@ template <class T, class Alloc>
#include <iterator>
#include <algorithm>
#include <type_traits>
#include <version>
#include <__debug>
@ -1169,7 +1175,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 +2214,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();
@ -2449,6 +2455,18 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
__x.swap(__y);
}
#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.remove_if(__pred); }
template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(list<_Tp, _Allocator>& __c, const _Up& __v)
{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
#endif
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS

View File

@ -187,6 +187,7 @@ template <class charT> class messages_byname;
#include <streambuf>
#include <iterator>
#include <limits>
#include <version>
#ifndef __APPLE__
#include <cstdarg>
#endif
@ -727,7 +728,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 +763,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)
{
@ -2408,6 +2409,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>,
@ -3550,6 +3568,7 @@ messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
__cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
return __cat;
#else // !_LIBCPP_HAS_CATOPEN
_LIBCPP_UNUSED_VAR(__nm);
return -1;
#endif // _LIBCPP_HAS_CATOPEN
}
@ -3573,6 +3592,9 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
__n, __n + strlen(__n));
return __w;
#else // !_LIBCPP_HAS_CATOPEN
_LIBCPP_UNUSED_VAR(__c);
_LIBCPP_UNUSED_VAR(__set);
_LIBCPP_UNUSED_VAR(__msgid);
return __dflt;
#endif // _LIBCPP_HAS_CATOPEN
}
@ -3586,6 +3608,8 @@ messages<_CharT>::do_close(catalog __c) const
__c <<= 1;
nl_catd __cat = (nl_catd)__c;
catclose(__cat);
#else // !_LIBCPP_HAS_CATOPEN
_LIBCPP_UNUSED_VAR(__c);
#endif // _LIBCPP_HAS_CATOPEN
}

View File

@ -167,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
@ -245,6 +254,10 @@ void
swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class T, class Compare, class Allocator, class Predicate>
void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
template <class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key, T>>>
class multimap
@ -368,6 +381,15 @@ public:
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
@ -447,6 +469,9 @@ swap(multimap<Key, T, Compare, Allocator>& x,
multimap<Key, T, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class T, class Compare, class Allocator, class Predicate>
void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
} // std
*/
@ -460,6 +485,7 @@ swap(multimap<Key, T, Compare, Allocator>& x,
#include <functional>
#include <initializer_list>
#include <type_traits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@ -467,7 +493,8 @@ swap(multimap<Key, T, Compare, Allocator>& x,
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Key, class _CP, class _Compare, bool _IsSmall>
template <class _Key, class _CP, class _Compare,
bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
class __map_value_compare
: private _Compare
{
@ -881,6 +908,7 @@ public:
typedef value_type& reference;
typedef const value_type& const_reference;
static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
@ -925,6 +953,11 @@ public:
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_(
@ -1299,6 +1332,38 @@ public:
{
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
@ -1556,6 +1621,14 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
__x.swap(__y);
}
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
#endif
template <class _Key, class _Tp, class _Compare = less<_Key>,
class _Allocator = allocator<pair<const _Key, _Tp> > >
class _LIBCPP_TEMPLATE_VIS multimap
@ -1570,6 +1643,7 @@ public:
typedef value_type& reference;
typedef const value_type& const_reference;
static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
@ -1614,6 +1688,11 @@ public:
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_(
@ -1881,10 +1960,42 @@ public:
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() {__tree_.clear();}
void clear() _NOEXCEPT {__tree_.clear();}
_LIBCPP_INLINE_VISIBILITY
void swap(multimap& __m)
@ -2055,6 +2166,13 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
__x.swap(__y);
}
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
#endif
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_MAP

View File

@ -43,7 +43,7 @@ struct pointer_traits<T*>
template <class U> using rebind = U*;
static pointer pointer_to(<details>) noexcept;
static pointer pointer_to(<details>) noexcept; // constexpr in C++20
};
template <class T> constexpr T* to_address(T* p) noexcept; // C++20
@ -212,10 +212,10 @@ template <class ForwardIterator>
template <class ForwardIterator, class Size>
ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
template <class Y> struct auto_ptr_ref {}; // removed in C++17
template <class Y> struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17
template<class X>
class auto_ptr // removed in C++17
class auto_ptr // deprecated in C++11, removed in C++17
{
public:
typedef X element_type;
@ -667,6 +667,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
# include <atomic>
#endif
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@ -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);}
@ -1459,29 +1460,21 @@ struct __has_select_on_container_copy_construction
#else // _LIBCPP_CXX03_LANG
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _Alloc, class _Pointer, class _Tp, class = void>
struct __has_construct : std::false_type {};
template <class _Alloc, class _Pointer, class ..._Args>
struct __has_construct
: false_type
{
};
template <class _Alloc, class _Pointer, class _Tp>
struct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t<
decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>()))
>::type> : std::true_type {};
#else // _LIBCPP_HAS_NO_VARIADICS
template <class _Alloc, class _Pointer, class _Args>
struct __has_construct
: false_type
{
};
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Alloc, class _Pointer, class = void>
struct __has_destroy : false_type {};
template <class _Alloc, class _Pointer>
struct __has_destroy
: false_type
{
};
struct __has_destroy<_Alloc, _Pointer, typename __void_t<
decltype(_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>()))
>::type> : std::true_type {};
template <class _Alloc>
struct __has_max_size
@ -1509,6 +1502,12 @@ struct __alloc_traits_difference_type<_Alloc, _Ptr, true>
typedef typename _Alloc::difference_type type;
};
template <class _Tp>
struct __is_default_allocator : false_type {};
template <class _Tp>
struct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {};
template <class _Alloc>
struct _LIBCPP_TEMPLATE_VIS allocator_traits
{
@ -1570,9 +1569,10 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
}
template <class _Tp, class _A0>
_LIBCPP_INLINE_VISIBILITY
static void construct(allocator_type&, _Tp* __p, const _A0& __a0)
static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0)
{
::new ((void*)__p) _Tp(__a0);
__construct(__has_construct<allocator_type, _Tp*, const _A0&>(),
__a, __p, __a0);
}
template <class _Tp, class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
@ -1612,7 +1612,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
void
__construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2)
{
for (; __begin1 != __end1; ++__begin1, ++__begin2)
for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)
construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1));
}
@ -1621,7 +1621,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
static
typename enable_if
<
(is_same<allocator_type, allocator<_Tp> >::value
(__is_default_allocator<allocator_type>::value
|| !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
is_trivially_move_constructible<_Tp>::value,
void
@ -1646,23 +1646,25 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1);
}
template <class _Tp>
template <class _SourceTp, class _DestTp,
class _RawSourceTp = typename remove_const<_SourceTp>::type,
class _RawDestTp = typename remove_const<_DestTp>::type>
_LIBCPP_INLINE_VISIBILITY
static
typename enable_if
<
(is_same<allocator_type, allocator<_Tp> >::value
|| !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
is_trivially_move_constructible<_Tp>::value,
is_trivially_move_constructible<_DestTp>::value &&
is_same<_RawSourceTp, _RawDestTp>::value &&
(__is_default_allocator<allocator_type>::value ||
!__has_construct<allocator_type, _DestTp*, _SourceTp&>::value),
void
>::type
__construct_range_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)
__construct_range_forward(allocator_type&, _SourceTp* __begin1, _SourceTp* __end1, _DestTp*& __begin2)
{
typedef typename remove_const<_Tp>::type _Vp;
ptrdiff_t _Np = __end1 - __begin1;
if (_Np > 0)
{
_VSTD::memcpy(const_cast<_Vp*>(__begin2), __begin1, _Np * sizeof(_Tp));
_VSTD::memcpy(const_cast<_RawDestTp*>(__begin2), __begin1, _Np * sizeof(_DestTp));
__begin2 += _Np;
}
}
@ -1685,7 +1687,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
static
typename enable_if
<
(is_same<allocator_type, allocator<_Tp> >::value
(__is_default_allocator<allocator_type>::value
|| !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
is_trivially_move_constructible<_Tp>::value,
void
@ -1720,6 +1722,19 @@ private:
{
::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
}
#else // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp, class _A0>
_LIBCPP_INLINE_VISIBILITY
static void __construct(true_type, allocator_type& __a, _Tp* __p,
const _A0& __a0)
{__a.construct(__p, __a0);}
template <class _Tp, class _A0>
_LIBCPP_INLINE_VISIBILITY
static void __construct(false_type, allocator_type&, _Tp* __p,
const _A0& __a0)
{
::new ((void*)__p) _Tp(__a0);
}
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp>
@ -1782,7 +1797,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,16 +1805,16 @@ 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())
__throw_length_error("allocator<T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_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), _LIBCPP_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 +1902,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
@ -1897,10 +1912,10 @@ public:
if (__n > max_size())
__throw_length_error("allocator<const T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_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), _LIBCPP_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 +2004,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 +2018,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
{
@ -2016,7 +2031,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
while (__n > 0)
{
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
if (__is_overaligned_for_new(__alignof(_Tp)))
if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
{
std::align_val_t __al =
std::align_val_t(std::alignment_of<_Tp>::value);
@ -2027,7 +2042,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
__n * sizeof(_Tp), nothrow));
}
#else
if (__is_overaligned_for_new(__alignof(_Tp)))
if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
{
// Since aligned operator new is unavailable, return an empty
// buffer rather than one with invalid alignment.
@ -2051,18 +2066,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, _LIBCPP_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 +2121,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 +2145,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 +2184,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
@ -3682,7 +3700,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>
@ -5624,15 +5642,18 @@ template <class _Tp, class _Alloc>
struct __temp_value {
typedef allocator_traits<_Alloc> _Traits;
typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __v;
typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
_Alloc &__a;
_Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); }
_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()); }
};

View File

@ -228,6 +228,10 @@ module std [system] {
header "atomic"
export *
}
module bit {
header "bit"
export *
}
module bitset {
header "bitset"
export string
@ -520,10 +524,6 @@ module std [system] {
header "experimental/deque"
export *
}
module dynarray {
header "experimental/dynarray"
export *
}
module filesystem {
header "experimental/filesystem"
export *

View File

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

View File

@ -27,12 +27,6 @@ public:
virtual const char* what() const noexcept;
};
class bad_array_length : public bad_alloc // FIXME: Not part of C++
{
public:
bad_array_length() noexcept;
};
class bad_array_new_length : public bad_alloc // C++14
{
public:
@ -91,6 +85,7 @@ void operator delete[](void* ptr, void*) noexcept;
#include <exception>
#include <type_traits>
#include <cstddef>
#include <version>
#ifdef _LIBCPP_NO_EXCEPTIONS
#include <cstdlib>
#endif
@ -103,23 +98,23 @@ void operator delete[](void* ptr, void*) noexcept;
#pragma GCC system_header
#endif
#if !(defined(_LIBCPP_BUILDING_LIBRARY) || _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_LIBRARY) || _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_LIBRARY) || (_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_INLINE_VISIBILITY
#ifndef _LIBCPP_NO_EXCEPTIONS
_LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
#endif
void __throw_bad_array_length()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
throw bad_array_length();
#else
_VSTD::abort();
#endif
inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) {
_DeallocateCaller::__do_deallocate_handle_align(__ptr, __align);
}
#endif
template <class _Tp>
_LIBCPP_NODISCARD_AFTER_CXX17 inline
_LIBCPP_NODISCARD_AFTER_CXX17 inline
_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
{
static_assert (!(is_function<_Tp>::value), "can't launder functions" );

View File

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

View File

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

View File

@ -140,6 +140,7 @@ template <class charT, class traits, class T>
#include <locale>
#include <iterator>
#include <bitset>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@ -160,7 +161,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 +174,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 +191,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,11 +225,11 @@ 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:
@ -1092,7 +1093,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)
use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
}
#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>)
#endif

View File

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

View File

@ -769,6 +769,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
#include <memory>
#include <vector>
#include <deque>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@ -989,6 +990,10 @@ public:
#if defined(__mips__) && defined(__GLIBC__)
static const char_class_type __regex_word = static_cast<char_class_type>(_ISbit(15));
#elif defined(__NetBSD__)
// NetBSD defines classes up to 0x2000
// see sys/ctype_bits.h, _CTYPE_Q
static const char_class_type __regex_word = 0x8000;
#else
static const char_class_type __regex_word = 0x80;
#endif
@ -1351,9 +1356,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
@ -2414,20 +2419,17 @@ __bracket_expression<_CharT, _Traits>::__exec(__state& __s) const
goto __exit;
}
}
// set of "__found" chars =
// When there's at least one of __neg_chars_ and __neg_mask_, the set
// of "__found" chars is
// union(complement(union(__neg_chars_, __neg_mask_)),
// other cases...)
//
// __neg_chars_ and __neg_mask_'d better be handled together, as there
// are no short circuit opportunities.
//
// In addition, when __neg_mask_/__neg_chars_ is empty, they should be
// treated as all ones/all chars.
// It doesn't make sense to check this when there are no __neg_chars_
// and no __neg_mask_.
if (!(__neg_mask_ == 0 && __neg_chars_.empty()))
{
const bool __in_neg_mask = (__neg_mask_ == 0) ||
__traits_.isctype(__ch, __neg_mask_);
const bool __in_neg_mask = __traits_.isctype(__ch, __neg_mask_);
const bool __in_neg_chars =
__neg_chars_.empty() ||
std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) !=
__neg_chars_.end();
if (!(__in_neg_mask || __in_neg_chars))

View File

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

View File

@ -128,6 +128,15 @@ public:
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 &&
@ -207,6 +216,9 @@ void
swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class Compare, class Allocator, class Predicate>
void erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20
template <class Key, class Compare = less<Key>,
class Allocator = allocator<Key>>
class multiset
@ -316,6 +328,15 @@ public:
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 &&
@ -394,6 +415,9 @@ void
swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class Compare, class Allocator, class Predicate>
void erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
} // std
*/
@ -402,6 +426,7 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
#include <__tree>
#include <__node_handle>
#include <functional>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@ -409,6 +434,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
@ -423,6 +451,7 @@ public:
typedef value_type& reference;
typedef const value_type& const_reference;
static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
@ -448,6 +477,11 @@ public:
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_(
@ -486,7 +520,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
@ -542,7 +576,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
@ -680,6 +714,38 @@ public:
{
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
@ -852,6 +918,13 @@ swap(set<_Key, _Compare, _Allocator>& __x,
__x.swap(__y);
}
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
#endif
template <class _Key, class _Compare = less<_Key>,
class _Allocator = allocator<_Key> >
class _LIBCPP_TEMPLATE_VIS multiset
@ -866,6 +939,7 @@ public:
typedef value_type& reference;
typedef const value_type& const_reference;
static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
@ -890,6 +964,11 @@ public:
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()
@ -920,7 +999,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
@ -984,7 +1063,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
@ -1121,6 +1200,38 @@ public:
{
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
@ -1294,6 +1405,13 @@ swap(multiset<_Key, _Compare, _Allocator>& __x,
__x.swap(__y);
}
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
#endif
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_SET

View File

@ -124,6 +124,7 @@ template <class Mutex>
*/
#include <__config>
#include <version>
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
@ -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

View File

@ -23,27 +23,13 @@ inline constexpr ptrdiff_t dynamic_extent = -1;
template <class ElementType, ptrdiff_t Extent = dynamic_extent>
class span;
// [span.comparison], span comparison operators
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator==(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator!=(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator<(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator<=(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator>(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator>=(span<T, X> l, span<U, Y> r);
// [span.objectrep], views of object representation
template <class ElementType, ptrdiff_t Extent>
span<const byte, ((Extent == dynamic_extent) ? dynamic_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 :
span< byte, ((Extent == dynamic_extent) ? dynamic_extent :
(static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;
@ -123,7 +109,7 @@ private:
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>;
@ -194,8 +180,8 @@ struct __is_span_compatible_container<_Tp, _ElementType,
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(*)[]>,
is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[],
_ElementType(*)[]>,
nullptr_t>::type
>>
: public true_type {};
@ -221,7 +207,7 @@ public:
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
// [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"); }
@ -242,7 +228,7 @@ public:
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))"); }
{ _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (container)"); }
template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY
@ -287,7 +273,7 @@ public:
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
{
@ -315,7 +301,7 @@ public:
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)
@ -331,14 +317,14 @@ public:
_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];
}
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];
}
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
@ -358,7 +344,7 @@ public:
__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()}; }
@ -392,7 +378,7 @@ public:
static constexpr index_type extent = dynamic_extent;
// [span.cons], span constructors, copy, assignment, and destructor
// [span.cons], span constructors, copy, assignment, and destructor
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {}
constexpr span (const span&) noexcept = default;
@ -408,7 +394,7 @@ public:
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} {}
@ -440,7 +426,7 @@ public:
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> first() const noexcept
{
static_assert(_Count >= 0);
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};
}
@ -449,7 +435,7 @@ public:
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> last() const noexcept
{
static_assert(_Count >= 0);
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};
}
@ -460,7 +446,7 @@ public:
_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
{
@ -480,7 +466,7 @@ public:
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)
@ -496,14 +482,14 @@ public:
_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];
}
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];
}
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
@ -539,39 +525,9 @@ private:
index_type __size;
};
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator==(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return equal(__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator!=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return !(__rhs == __lhs); }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator< (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return lexicographical_compare (__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator<=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return !(__rhs < __lhs); }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator> (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return __rhs < __lhs; }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator>=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return !(__lhs < __rhs); }
// as_bytes & as_writeable_bytes
template <class _Tp, ptrdiff_t _Extent>
auto as_bytes(span<_Tp, _Extent> __s) noexcept
auto as_bytes(span<_Tp, _Extent> __s) noexcept
-> decltype(__s.__as_bytes())
{ return __s.__as_bytes(); }
@ -588,7 +544,7 @@ template <class _Tp, ptrdiff_t _Extent>
// 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>;

View File

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

View File

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

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