Merge to upstream r334917.
Bug: None Test: ./run_tests.py --bitness 32 Test: ./run_tests.py --bitness 64 Change-Id: If8594f80130bd7dd55d3c4f8224fde54844b1d4a
This commit is contained in:
@@ -97,7 +97,12 @@ option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON)
|
||||
cmake_dependent_option(LIBCXX_INSTALL_EXPERIMENTAL_LIBRARY
|
||||
"Install libc++experimental.a" ON
|
||||
"LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY;LIBCXX_INSTALL_LIBRARY" OFF)
|
||||
set(LIBCXX_ABI_VERSION 1 CACHE STRING "ABI version of libc++.")
|
||||
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++.")
|
||||
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.")
|
||||
@@ -136,6 +141,9 @@ if (LIBCXX_CXX_ABI STREQUAL "default")
|
||||
elseif (APPLE)
|
||||
set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
|
||||
set(LIBCXX_CXX_ABI_SYSTEM 1)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
set(LIBCXX_CXX_ABI_LIBNAME "libcxxrt")
|
||||
set(LIBCXX_CXX_ABI_INCLUDE_PATHS "/usr/include/c++/v1")
|
||||
else()
|
||||
set(LIBCXX_CXX_ABI_LIBNAME "default")
|
||||
endif()
|
||||
@@ -616,7 +624,7 @@ if (LIBCXX_STANDALONE_BUILD)
|
||||
endif()
|
||||
|
||||
# Configuration file flags =====================================================
|
||||
if (NOT LIBCXX_ABI_VERSION EQUAL "1")
|
||||
if (NOT LIBCXX_ABI_VERSION EQUAL DEFAULT_ABI_VERSION)
|
||||
config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION)
|
||||
endif()
|
||||
config_define_if(LIBCXX_ABI_UNSTABLE _LIBCPP_ABI_UNSTABLE)
|
||||
|
||||
@@ -26,3 +26,4 @@ to libc++.
|
||||
1. Add a test under `test/libcxx` that the header defines `_LIBCPP_VERSION`.
|
||||
2. Update `test/libcxx/double_include.sh.cpp` to include the new header.
|
||||
3. Create a submodule in `include/module.modulemap` for the new header.
|
||||
4. Update the include/CMakeLists.txt file to include the new header.
|
||||
|
||||
@@ -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-6.0.0-r316086-win32.exe -FileName llvm-installer.exe
|
||||
appveyor DownloadFile http://prereleases.llvm.org/win-snapshots/LLVM-7.0.0-r325576-win32.exe -FileName llvm-installer.exe
|
||||
)
|
||||
if "%CLANG_VERSION%"=="ToT" (
|
||||
START /WAIT llvm-installer.exe /S /D=C:\"Program Files\LLVM"
|
||||
|
||||
@@ -68,7 +68,7 @@ set(BENCHMARK_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(BENCHMARK_LIBCXX_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx)
|
||||
set(BENCHMARK_NATIVE_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native)
|
||||
set(BENCHMARK_TEST_COMPILE_FLAGS
|
||||
-std=c++14 -O2
|
||||
-std=c++17 -O2
|
||||
-I${BENCHMARK_LIBCXX_INSTALL}/include
|
||||
-I${LIBCXX_SOURCE_DIR}/test/support
|
||||
)
|
||||
|
||||
@@ -29,14 +29,16 @@ inline std::default_random_engine& getRandomEngine() {
|
||||
return RandEngine;
|
||||
}
|
||||
|
||||
|
||||
inline char getRandomChar() {
|
||||
std::uniform_int_distribution<> LettersDist(0, LettersSize-1);
|
||||
return Letters[LettersDist(getRandomEngine())];
|
||||
}
|
||||
|
||||
template <class IntT>
|
||||
inline IntT getRandomInteger() {
|
||||
std::uniform_int_distribution<IntT> dist;
|
||||
inline IntT getRandomInteger(IntT Min = 0,
|
||||
IntT Max = std::numeric_limits<IntT>::max()) {
|
||||
std::uniform_int_distribution<IntT> dist(Min, Max);
|
||||
return dist(getRandomEngine());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
#include <experimental/filesystem>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "GenerateInput.hpp"
|
||||
#include "test_iterators.h"
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#include "filesystem_include.hpp"
|
||||
|
||||
static const size_t TestNumInputs = 1024;
|
||||
|
||||
|
||||
template <class GenInputs>
|
||||
void BM_PathConstructString(benchmark::State &st, GenInputs gen) {
|
||||
using namespace fs;
|
||||
using fs::path;
|
||||
const auto in = gen(st.range(0));
|
||||
path PP;
|
||||
for (auto& Part : in)
|
||||
@@ -21,14 +18,15 @@ void BM_PathConstructString(benchmark::State &st, GenInputs gen) {
|
||||
const path P(PP.native());
|
||||
benchmark::DoNotOptimize(P.native().data());
|
||||
}
|
||||
st.SetComplexityN(st.range(0));
|
||||
}
|
||||
BENCHMARK_CAPTURE(BM_PathConstructString, large_string,
|
||||
getRandomStringInputs)->Arg(TestNumInputs);
|
||||
getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
|
||||
|
||||
|
||||
template <class GenInputs>
|
||||
void BM_PathConstructCStr(benchmark::State &st, GenInputs gen) {
|
||||
using namespace fs;
|
||||
using fs::path;
|
||||
const auto in = gen(st.range(0));
|
||||
path PP;
|
||||
for (auto& Part : in)
|
||||
@@ -45,7 +43,7 @@ BENCHMARK_CAPTURE(BM_PathConstructCStr, large_string,
|
||||
|
||||
template <template <class...> class ItType, class GenInputs>
|
||||
void BM_PathConstructIter(benchmark::State &st, GenInputs gen) {
|
||||
using namespace fs;
|
||||
using fs::path;
|
||||
using Iter = ItType<std::string::const_iterator>;
|
||||
const auto in = gen(st.range(0));
|
||||
path PP;
|
||||
@@ -60,6 +58,7 @@ void BM_PathConstructIter(benchmark::State &st, GenInputs gen) {
|
||||
const path P(Start, End);
|
||||
benchmark::DoNotOptimize(P.native().data());
|
||||
}
|
||||
st.SetComplexityN(st.range(0));
|
||||
}
|
||||
template <class GenInputs>
|
||||
void BM_PathConstructInputIter(benchmark::State &st, GenInputs gen) {
|
||||
@@ -70,14 +69,14 @@ void BM_PathConstructForwardIter(benchmark::State &st, GenInputs gen) {
|
||||
BM_PathConstructIter<forward_iterator>(st, gen);
|
||||
}
|
||||
BENCHMARK_CAPTURE(BM_PathConstructInputIter, large_string,
|
||||
getRandomStringInputs)->Arg(TestNumInputs);
|
||||
getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
|
||||
BENCHMARK_CAPTURE(BM_PathConstructForwardIter, large_string,
|
||||
getRandomStringInputs)->Arg(TestNumInputs);
|
||||
getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
|
||||
|
||||
|
||||
template <class GenInputs>
|
||||
void BM_PathIterateMultipleTimes(benchmark::State &st, GenInputs gen) {
|
||||
using namespace fs;
|
||||
using fs::path;
|
||||
const auto in = gen(st.range(0));
|
||||
path PP;
|
||||
for (auto& Part : in)
|
||||
@@ -89,14 +88,15 @@ void BM_PathIterateMultipleTimes(benchmark::State &st, GenInputs gen) {
|
||||
}
|
||||
benchmark::ClobberMemory();
|
||||
}
|
||||
st.SetComplexityN(st.range(0));
|
||||
}
|
||||
BENCHMARK_CAPTURE(BM_PathIterateMultipleTimes, iterate_elements,
|
||||
getRandomStringInputs)->Arg(TestNumInputs);
|
||||
getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
|
||||
|
||||
|
||||
template <class GenInputs>
|
||||
void BM_PathIterateOnce(benchmark::State &st, GenInputs gen) {
|
||||
using namespace fs;
|
||||
using fs::path;
|
||||
const auto in = gen(st.range(0));
|
||||
path PP;
|
||||
for (auto& Part : in)
|
||||
@@ -109,13 +109,14 @@ void BM_PathIterateOnce(benchmark::State &st, GenInputs gen) {
|
||||
}
|
||||
benchmark::ClobberMemory();
|
||||
}
|
||||
st.SetComplexityN(st.range(0));
|
||||
}
|
||||
BENCHMARK_CAPTURE(BM_PathIterateOnce, iterate_elements,
|
||||
getRandomStringInputs)->Arg(TestNumInputs);
|
||||
getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
|
||||
|
||||
template <class GenInputs>
|
||||
void BM_PathIterateOnceBackwards(benchmark::State &st, GenInputs gen) {
|
||||
using namespace fs;
|
||||
using fs::path;
|
||||
const auto in = gen(st.range(0));
|
||||
path PP;
|
||||
for (auto& Part : in)
|
||||
@@ -135,4 +136,28 @@ void BM_PathIterateOnceBackwards(benchmark::State &st, GenInputs gen) {
|
||||
BENCHMARK_CAPTURE(BM_PathIterateOnceBackwards, iterate_elements,
|
||||
getRandomStringInputs)->Arg(TestNumInputs);
|
||||
|
||||
static fs::path getRandomPaths(int NumParts, int PathLen) {
|
||||
fs::path Result;
|
||||
while (NumParts--) {
|
||||
std::string Part = getRandomString(PathLen);
|
||||
Result /= Part;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <class GenInput>
|
||||
void BM_LexicallyNormal(benchmark::State &st, GenInput gen, size_t PathLen) {
|
||||
using fs::path;
|
||||
auto In = gen(st.range(0), PathLen);
|
||||
benchmark::DoNotOptimize(&In);
|
||||
while (st.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(In.lexically_normal());
|
||||
}
|
||||
st.SetComplexityN(st.range(0));
|
||||
}
|
||||
BENCHMARK_CAPTURE(BM_LexicallyNormal, small_path,
|
||||
getRandomPaths, /*PathLen*/5)->RangeMultiplier(2)->Range(2, 256)->Complexity();
|
||||
BENCHMARK_CAPTURE(BM_LexicallyNormal, large_path,
|
||||
getRandomPaths, /*PathLen*/32)->RangeMultiplier(2)->Range(2, 256)->Complexity();
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@@ -31,7 +31,14 @@ int main() {
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||
endfunction(check_cxx_atomics)
|
||||
|
||||
# Perform the check for 64bit atomics without libatomic. It may have been
|
||||
# added to the required libraries during in the configuration of LLVM, which
|
||||
# would cause the check for CXX atomics without libatomic to incorrectly pass.
|
||||
set(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
|
||||
list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
|
||||
|
||||
check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
|
||||
@@ -47,12 +47,22 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs)
|
||||
set(found TRUE)
|
||||
get_filename_component(dstdir ${fpath} PATH)
|
||||
get_filename_component(ifile ${fpath} NAME)
|
||||
file(COPY "${incpath}/${fpath}"
|
||||
DESTINATION "${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}"
|
||||
)
|
||||
file(COPY "${incpath}/${fpath}"
|
||||
DESTINATION "${CMAKE_BINARY_DIR}/include/c++/v1/${dstdir}"
|
||||
)
|
||||
set(src ${incpath}/${fpath})
|
||||
|
||||
set(dst ${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}/${fpath})
|
||||
add_custom_command(OUTPUT ${dst}
|
||||
DEPENDS ${src}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
|
||||
COMMENT "Copying C++ ABI header ${fpath}...")
|
||||
list(APPEND abilib_headers "${dst}")
|
||||
|
||||
set(dst "${CMAKE_BINARY_DIR}/include/c++/v1/${dstdir}/${fpath}")
|
||||
add_custom_command(OUTPUT ${dst}
|
||||
DEPENDS ${src}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
|
||||
COMMENT "Copying C++ ABI header ${fpath}...")
|
||||
list(APPEND abilib_headers "${dst}")
|
||||
|
||||
if (LIBCXX_INSTALL_HEADERS)
|
||||
install(FILES "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}"
|
||||
DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1/${dstdir}
|
||||
@@ -60,7 +70,6 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs)
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
endif()
|
||||
list(APPEND abilib_headers "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}")
|
||||
endif()
|
||||
endforeach()
|
||||
if (NOT found)
|
||||
@@ -69,6 +78,8 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs)
|
||||
endforeach()
|
||||
|
||||
include_directories("${LIBCXX_BINARY_INCLUDE_DIR}")
|
||||
add_custom_target(cxx_abi_headers ALL DEPENDS ${abilib_headers})
|
||||
set(LIBCXX_CXX_ABI_HEADER_TARGET "cxx_abi_headers")
|
||||
endmacro()
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ Testing
|
||||
Some parameters can be passed to lit to run the test-suite and exercising the
|
||||
availability.
|
||||
|
||||
* The `platform` parameter controls the deployement target. For example lit can
|
||||
* The `platform` parameter controls the deployment target. For example lit can
|
||||
be invoked with `--param=platform=macosx10.8`. Default is the current host.
|
||||
* The `use_system_cxx_lib` parameter indicates to use another library than the
|
||||
just built one. Invoking lit with `--param=use_system_cxx_lib=true` will run
|
||||
|
||||
@@ -46,7 +46,7 @@ we do NOTHING.
|
||||
|
||||
Otherwise we create a custom installation rule that modifies the installed __config
|
||||
header. The rule first generates a dummy "__config_site" header containing the required
|
||||
#defines. The contents of the dummy header are then prependend to the installed
|
||||
#defines. The contents of the dummy header are then prepended to the installed
|
||||
__config header. By manually prepending the files we avoid the cost of an
|
||||
extra #include and we allow the __config header to be ignorant of the extra
|
||||
configuration all together. An example "__config" header generated when
|
||||
|
||||
@@ -1,47 +1,250 @@
|
||||
if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS)
|
||||
set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE)
|
||||
set(files
|
||||
__bit_reference
|
||||
__bsd_locale_defaults.h
|
||||
__bsd_locale_fallbacks.h
|
||||
__debug
|
||||
__functional_03
|
||||
__functional_base
|
||||
__functional_base_03
|
||||
__hash_table
|
||||
__libcpp_version
|
||||
__locale
|
||||
__mutex_base
|
||||
__nullptr
|
||||
__split_buffer
|
||||
__sso_allocator
|
||||
__std_stream
|
||||
__string
|
||||
__threading_support
|
||||
__tree
|
||||
__tuple
|
||||
__undef_macros
|
||||
algorithm
|
||||
any
|
||||
array
|
||||
atomic
|
||||
bitset
|
||||
cassert
|
||||
ccomplex
|
||||
cctype
|
||||
cerrno
|
||||
cfenv
|
||||
cfloat
|
||||
chrono
|
||||
cinttypes
|
||||
ciso646
|
||||
climits
|
||||
clocale
|
||||
cmath
|
||||
codecvt
|
||||
compare
|
||||
complex
|
||||
complex.h
|
||||
condition_variable
|
||||
csetjmp
|
||||
csignal
|
||||
cstdarg
|
||||
cstdbool
|
||||
cstddef
|
||||
cstdint
|
||||
cstdio
|
||||
cstdlib
|
||||
cstring
|
||||
ctgmath
|
||||
ctime
|
||||
ctype.h
|
||||
cwchar
|
||||
cwctype
|
||||
deque
|
||||
errno.h
|
||||
exception
|
||||
experimental/__config
|
||||
experimental/__memory
|
||||
experimental/algorithm
|
||||
experimental/any
|
||||
experimental/chrono
|
||||
experimental/coroutine
|
||||
experimental/deque
|
||||
experimental/dynarray
|
||||
experimental/filesystem
|
||||
experimental/forward_list
|
||||
experimental/functional
|
||||
experimental/iterator
|
||||
experimental/list
|
||||
experimental/map
|
||||
experimental/memory_resource
|
||||
experimental/numeric
|
||||
experimental/optional
|
||||
experimental/propagate_const
|
||||
experimental/ratio
|
||||
experimental/regex
|
||||
experimental/set
|
||||
experimental/simd
|
||||
experimental/string
|
||||
experimental/string_view
|
||||
experimental/system_error
|
||||
experimental/tuple
|
||||
experimental/type_traits
|
||||
experimental/unordered_map
|
||||
experimental/unordered_set
|
||||
experimental/utility
|
||||
experimental/vector
|
||||
ext/__hash
|
||||
ext/hash_map
|
||||
ext/hash_set
|
||||
float.h
|
||||
forward_list
|
||||
fstream
|
||||
functional
|
||||
future
|
||||
initializer_list
|
||||
inttypes.h
|
||||
iomanip
|
||||
ios
|
||||
iosfwd
|
||||
iostream
|
||||
istream
|
||||
iterator
|
||||
limits
|
||||
limits.h
|
||||
list
|
||||
locale
|
||||
locale.h
|
||||
map
|
||||
math.h
|
||||
memory
|
||||
module.modulemap
|
||||
mutex
|
||||
new
|
||||
numeric
|
||||
optional
|
||||
ostream
|
||||
queue
|
||||
random
|
||||
ratio
|
||||
regex
|
||||
scoped_allocator
|
||||
set
|
||||
setjmp.h
|
||||
shared_mutex
|
||||
sstream
|
||||
stack
|
||||
stdbool.h
|
||||
stddef.h
|
||||
stdexcept
|
||||
stdint.h
|
||||
stdio.h
|
||||
stdlib.h
|
||||
streambuf
|
||||
string
|
||||
string.h
|
||||
string_view
|
||||
strstream
|
||||
system_error
|
||||
tgmath.h
|
||||
thread
|
||||
tuple
|
||||
type_traits
|
||||
typeindex
|
||||
typeinfo
|
||||
unordered_map
|
||||
unordered_set
|
||||
utility
|
||||
valarray
|
||||
variant
|
||||
vector
|
||||
version
|
||||
wchar.h
|
||||
wctype.h
|
||||
)
|
||||
|
||||
if(LIBCXX_INSTALL_SUPPORT_HEADERS)
|
||||
set(files
|
||||
${files}
|
||||
support/android/locale_bionic.h
|
||||
support/fuchsia/xlocale.h
|
||||
support/ibm/limits.h
|
||||
support/ibm/locale_mgmt_aix.h
|
||||
support/ibm/support.h
|
||||
support/ibm/xlocale.h
|
||||
support/musl/xlocale.h
|
||||
support/newlib/xlocale.h
|
||||
support/solaris/floatingpoint.h
|
||||
support/solaris/wchar.h
|
||||
support/solaris/xlocale.h
|
||||
support/win32/limits_msvc_win32.h
|
||||
support/win32/locale_win32.h
|
||||
support/xlocale/__nop_locale_mgmt.h
|
||||
support/xlocale/__posix_l_fallback.h
|
||||
support/xlocale/__strtonum_fallback.h
|
||||
support/xlocale/xlocale.h
|
||||
)
|
||||
endif()
|
||||
|
||||
set(LIBCXX_HEADER_PATTERN
|
||||
PATTERN "*"
|
||||
PATTERN "CMakeLists.txt" EXCLUDE
|
||||
PATTERN ".svn" EXCLUDE
|
||||
PATTERN "__config_site.in" EXCLUDE
|
||||
${LIBCXX_SUPPORT_HEADER_PATTERN}
|
||||
if (LIBCXX_NEEDS_SITE_CONFIG)
|
||||
# Generate a custom __config header. The new header is created
|
||||
# by prepending __config_site to the current __config header.
|
||||
add_custom_command(OUTPUT ${LIBCXX_BINARY_DIR}/__generated_config
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${LIBCXX_SOURCE_DIR}/utils/cat_files.py
|
||||
${LIBCXX_BINARY_DIR}/__config_site
|
||||
${LIBCXX_SOURCE_DIR}/include/__config
|
||||
-o ${LIBCXX_BINARY_DIR}/__generated_config
|
||||
DEPENDS ${LIBCXX_SOURCE_DIR}/include/__config
|
||||
${LIBCXX_BINARY_DIR}/__config_site
|
||||
)
|
||||
# Add a target that executes the generation commands.
|
||||
add_custom_target(cxx-generated-config ALL
|
||||
DEPENDS ${LIBCXX_BINARY_DIR}/__generated_config)
|
||||
set(generated_config_deps cxx-generated-config)
|
||||
else()
|
||||
set(files
|
||||
${files}
|
||||
__config
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT LIBCXX_USING_INSTALLED_LLVM AND LLVM_BINARY_DIR)
|
||||
file(COPY .
|
||||
DESTINATION "${LLVM_BINARY_DIR}/include/c++/v1"
|
||||
FILES_MATCHING
|
||||
${LIBCXX_HEADER_PATTERN}
|
||||
)
|
||||
endif()
|
||||
set(output_dir ${LLVM_BINARY_DIR}/include/c++/v1)
|
||||
|
||||
if (LIBCXX_INSTALL_HEADERS)
|
||||
install(DIRECTORY .
|
||||
DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1
|
||||
COMPONENT cxx-headers
|
||||
FILES_MATCHING
|
||||
${LIBCXX_HEADER_PATTERN}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
set(out_files)
|
||||
foreach(f ${files})
|
||||
set(src ${CMAKE_CURRENT_SOURCE_DIR}/${f})
|
||||
set(dst ${output_dir}/${f})
|
||||
add_custom_command(OUTPUT ${dst}
|
||||
DEPENDS ${src}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
|
||||
COMMENT "Copying CXX header ${f}")
|
||||
list(APPEND out_files ${dst})
|
||||
endforeach()
|
||||
|
||||
if (LIBCXX_NEEDS_SITE_CONFIG)
|
||||
# Generate and install a custom __config header. The new header is created
|
||||
# by prepending __config_site to the current __config header.
|
||||
add_custom_command(OUTPUT ${LIBCXX_BINARY_DIR}/__generated_config
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${LIBCXX_SOURCE_DIR}/utils/cat_files.py
|
||||
${LIBCXX_BINARY_DIR}/__config_site
|
||||
${LIBCXX_SOURCE_DIR}/include/__config
|
||||
-o ${LIBCXX_BINARY_DIR}/__generated_config
|
||||
DEPENDS ${LIBCXX_SOURCE_DIR}/include/__config
|
||||
${LIBCXX_BINARY_DIR}/__config_site
|
||||
# Copy the generated header as __config into build directory.
|
||||
set(src ${LIBCXX_BINARY_DIR}/__generated_config)
|
||||
set(dst ${output_dir}/__config)
|
||||
add_custom_command(OUTPUT ${dst}
|
||||
DEPENDS ${src} ${generated_config_deps}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
|
||||
COMMENT "Copying CXX __config")
|
||||
list(APPEND out_files ${dst})
|
||||
endif()
|
||||
|
||||
add_custom_target(cxx_headers ALL DEPENDS ${out_files} ${LIBCXX_CXX_ABI_HEADER_TARGET})
|
||||
else()
|
||||
add_custom_target(cxx_headers)
|
||||
endif()
|
||||
set_target_properties(cxx_headers PROPERTIES FOLDER "Misc")
|
||||
|
||||
if (LIBCXX_INSTALL_HEADERS)
|
||||
foreach(file ${files})
|
||||
get_filename_component(dir ${file} DIRECTORY)
|
||||
install(FILES ${file}
|
||||
DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1/${dir}
|
||||
COMPONENT cxx-headers
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
# Add a target that executes the generation commands.
|
||||
add_custom_target(generate_config_header ALL
|
||||
DEPENDS ${LIBCXX_BINARY_DIR}/__generated_config)
|
||||
set(generated_config_deps generate_config_header)
|
||||
endforeach()
|
||||
|
||||
if (LIBCXX_NEEDS_SITE_CONFIG)
|
||||
# Install the generated header as __config.
|
||||
install(FILES ${LIBCXX_BINARY_DIR}/__generated_config
|
||||
DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1
|
||||
@@ -51,8 +254,6 @@ if (LIBCXX_INSTALL_HEADERS)
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES)
|
||||
# this target is just needed as a placeholder for the distribution target
|
||||
add_custom_target(cxx-headers)
|
||||
add_custom_target(install-cxx-headers
|
||||
DEPENDS cxx-headers ${generated_config_deps}
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
@@ -61,9 +262,7 @@ if (LIBCXX_INSTALL_HEADERS)
|
||||
# Stripping is a no-op for headers
|
||||
add_custom_target(install-cxx-headers-stripped DEPENDS install-cxx-headers)
|
||||
|
||||
add_custom_target(libcxx-headers)
|
||||
add_custom_target(install-libcxx-headers DEPENDS install-cxx-headers)
|
||||
add_custom_target(install-libcxx-headers-stripped DEPENDS install-cxx-headers-stripped)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
874
include/__config
874
include/__config
File diff suppressed because it is too large
Load Diff
@@ -600,7 +600,10 @@ template<class _Rp>
|
||||
function<_Rp()>&
|
||||
function<_Rp()>::operator=(const function& __f)
|
||||
{
|
||||
function(__f).swap(*this);
|
||||
if (__f)
|
||||
function(__f).swap(*this);
|
||||
else
|
||||
*this = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -608,11 +611,12 @@ template<class _Rp>
|
||||
function<_Rp()>&
|
||||
function<_Rp()>::operator=(nullptr_t)
|
||||
{
|
||||
if (__f_ == (__base*)&__buf_)
|
||||
__f_->destroy();
|
||||
else if (__f_)
|
||||
__f_->destroy_deallocate();
|
||||
__base* __t = __f_;
|
||||
__f_ = 0;
|
||||
if (__t == (__base*)&__buf_)
|
||||
__t->destroy();
|
||||
else if (__t)
|
||||
__t->destroy_deallocate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -876,7 +880,10 @@ template<class _Rp, class _A0>
|
||||
function<_Rp(_A0)>&
|
||||
function<_Rp(_A0)>::operator=(const function& __f)
|
||||
{
|
||||
function(__f).swap(*this);
|
||||
if (__f)
|
||||
function(__f).swap(*this);
|
||||
else
|
||||
*this = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -884,11 +891,12 @@ template<class _Rp, class _A0>
|
||||
function<_Rp(_A0)>&
|
||||
function<_Rp(_A0)>::operator=(nullptr_t)
|
||||
{
|
||||
if (__f_ == (__base*)&__buf_)
|
||||
__f_->destroy();
|
||||
else if (__f_)
|
||||
__f_->destroy_deallocate();
|
||||
__base* __t = __f_;
|
||||
__f_ = 0;
|
||||
if (__t == (__base*)&__buf_)
|
||||
__t->destroy();
|
||||
else if (__t)
|
||||
__t->destroy_deallocate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1152,7 +1160,10 @@ template<class _Rp, class _A0, class _A1>
|
||||
function<_Rp(_A0, _A1)>&
|
||||
function<_Rp(_A0, _A1)>::operator=(const function& __f)
|
||||
{
|
||||
function(__f).swap(*this);
|
||||
if (__f)
|
||||
function(__f).swap(*this);
|
||||
else
|
||||
*this = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1160,11 +1171,12 @@ template<class _Rp, class _A0, class _A1>
|
||||
function<_Rp(_A0, _A1)>&
|
||||
function<_Rp(_A0, _A1)>::operator=(nullptr_t)
|
||||
{
|
||||
if (__f_ == (__base*)&__buf_)
|
||||
__f_->destroy();
|
||||
else if (__f_)
|
||||
__f_->destroy_deallocate();
|
||||
__base* __t = __f_;
|
||||
__f_ = 0;
|
||||
if (__t == (__base*)&__buf_)
|
||||
__t->destroy();
|
||||
else if (__t)
|
||||
__t->destroy_deallocate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1428,7 +1440,10 @@ template<class _Rp, class _A0, class _A1, class _A2>
|
||||
function<_Rp(_A0, _A1, _A2)>&
|
||||
function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
|
||||
{
|
||||
function(__f).swap(*this);
|
||||
if (__f)
|
||||
function(__f).swap(*this);
|
||||
else
|
||||
*this = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1436,11 +1451,12 @@ template<class _Rp, class _A0, class _A1, class _A2>
|
||||
function<_Rp(_A0, _A1, _A2)>&
|
||||
function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
|
||||
{
|
||||
if (__f_ == (__base*)&__buf_)
|
||||
__f_->destroy();
|
||||
else if (__f_)
|
||||
__f_->destroy_deallocate();
|
||||
__base* __t = __f_;
|
||||
__f_ = 0;
|
||||
if (__t == (__base*)&__buf_)
|
||||
__t->destroy();
|
||||
else if (__t)
|
||||
__t->destroy_deallocate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -646,16 +646,6 @@ void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, con
|
||||
new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
|
||||
}
|
||||
|
||||
// FIXME: Theis should have a version which takes a non-const alloc.
|
||||
template <class _Tp, class _Allocator, class... _Args>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args)
|
||||
{
|
||||
__user_alloc_construct_impl(
|
||||
__uses_alloc_ctor<_Tp, _Allocator>(),
|
||||
__storage, __a, _VSTD::forward<_Args>(__args)...
|
||||
);
|
||||
}
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
@@ -32,13 +32,8 @@ _LIBCPP_PUSH_MACROS
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
template <class _Key, class _Tp>
|
||||
union __hash_value_type;
|
||||
#else
|
||||
template <class _Key, class _Tp>
|
||||
struct __hash_value_type;
|
||||
#endif
|
||||
|
||||
template <class _Key, class _Cp, class _Hash,
|
||||
bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value>
|
||||
@@ -172,7 +167,7 @@ struct __hash_key_value_types {
|
||||
}
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static __container_value_type&& __move(__node_value_type& __v) {
|
||||
static __container_value_type&& __move(__node_value_type& __v) {
|
||||
return _VSTD::move(__v);
|
||||
}
|
||||
#endif
|
||||
@@ -184,7 +179,6 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
|
||||
typedef _Tp mapped_type;
|
||||
typedef __hash_value_type<_Key, _Tp> __node_value_type;
|
||||
typedef pair<const _Key, _Tp> __container_value_type;
|
||||
typedef pair<_Key, _Tp> __nc_value_type;
|
||||
typedef __container_value_type __map_value_type;
|
||||
static const bool __is_map = true;
|
||||
|
||||
@@ -198,7 +192,7 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
|
||||
static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value,
|
||||
__container_value_type const&>::type
|
||||
__get_value(_Up& __t) {
|
||||
return __t.__cc;
|
||||
return __t.__get_value();
|
||||
}
|
||||
|
||||
template <class _Up>
|
||||
@@ -211,12 +205,12 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static __container_value_type* __get_ptr(__node_value_type& __n) {
|
||||
return _VSTD::addressof(__n.__cc);
|
||||
return _VSTD::addressof(__n.__get_value());
|
||||
}
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static __nc_value_type&& __move(__node_value_type& __v) {
|
||||
return _VSTD::move(__v.__nc);
|
||||
static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
|
||||
return __v.__move();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -24,11 +24,7 @@
|
||||
#elif defined(_AIX)
|
||||
# include <support/ibm/xlocale.h>
|
||||
#elif defined(__ANDROID__)
|
||||
// Android gained the locale aware functions in L (API level 21)
|
||||
# include <android/api-level.h>
|
||||
# if __ANDROID_API__ <= 20
|
||||
# include <support/android/locale_bionic.h>
|
||||
# endif
|
||||
# include <support/android/locale_bionic.h>
|
||||
#elif defined(__sun__)
|
||||
# include <xlocale.h>
|
||||
# include <support/solaris/xlocale.h>
|
||||
|
||||
@@ -55,14 +55,14 @@ public:
|
||||
__allocated_ = true;
|
||||
return (pointer)&buf_;
|
||||
}
|
||||
return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));
|
||||
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type)
|
||||
{
|
||||
if (__p == (pointer)&buf_)
|
||||
__allocated_ = false;
|
||||
else
|
||||
_VSTD::__libcpp_deallocate(__p);
|
||||
_VSTD::__libcpp_deallocate(__p, __alignof(_Tp));
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
|
||||
|
||||
|
||||
@@ -31,6 +31,14 @@
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
|
||||
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
|
||||
defined(_LIBCPP_HAS_THREAD_API_WIN32)
|
||||
#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
|
||||
#else
|
||||
#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
|
||||
#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
|
||||
#else
|
||||
@@ -39,15 +47,7 @@ _LIBCPP_PUSH_MACROS
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
|
||||
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)
|
||||
|
||||
#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
|
||||
|
||||
#elif defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
||||
|
||||
#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
||||
// Mutex
|
||||
typedef pthread_mutex_t __libcpp_mutex_t;
|
||||
#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
@@ -75,9 +75,6 @@ typedef pthread_key_t __libcpp_tls_key;
|
||||
|
||||
#define _LIBCPP_TLS_DESTRUCTOR_CC
|
||||
#else
|
||||
|
||||
#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
|
||||
|
||||
// Mutex
|
||||
typedef void* __libcpp_mutex_t;
|
||||
#define _LIBCPP_MUTEX_INITIALIZER 0
|
||||
|
||||
@@ -37,13 +37,8 @@ template <class _Pointer> class __tree_end_node;
|
||||
template <class _VoidPtr> class __tree_node_base;
|
||||
template <class _Tp, class _VoidPtr> class __tree_node;
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
template <class _Key, class _Value>
|
||||
union __value_type;
|
||||
#else
|
||||
template <class _Key, class _Value>
|
||||
struct __value_type;
|
||||
#endif
|
||||
|
||||
template <class _Key, class _CP, class _Compare,
|
||||
bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
|
||||
@@ -569,10 +564,9 @@ struct __tree_key_value_types {
|
||||
static __container_value_type* __get_ptr(__node_value_type& __n) {
|
||||
return _VSTD::addressof(__n);
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static __container_value_type&& __move(__node_value_type& __v) {
|
||||
static __container_value_type&& __move(__node_value_type& __v) {
|
||||
return _VSTD::move(__v);
|
||||
}
|
||||
#endif
|
||||
@@ -584,14 +578,13 @@ struct __tree_key_value_types<__value_type<_Key, _Tp> > {
|
||||
typedef _Tp mapped_type;
|
||||
typedef __value_type<_Key, _Tp> __node_value_type;
|
||||
typedef pair<const _Key, _Tp> __container_value_type;
|
||||
typedef pair<_Key, _Tp> __nc_value_type;
|
||||
typedef __container_value_type __map_value_type;
|
||||
static const bool __is_map = true;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static key_type const&
|
||||
__get_key(__node_value_type const& __t) {
|
||||
return __t.__cc.first;
|
||||
return __t.__get_value().first;
|
||||
}
|
||||
|
||||
template <class _Up>
|
||||
@@ -605,7 +598,7 @@ struct __tree_key_value_types<__value_type<_Key, _Tp> > {
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static __container_value_type const&
|
||||
__get_value(__node_value_type const& __t) {
|
||||
return __t.__cc;
|
||||
return __t.__get_value();
|
||||
}
|
||||
|
||||
template <class _Up>
|
||||
@@ -618,13 +611,13 @@ struct __tree_key_value_types<__value_type<_Key, _Tp> > {
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static __container_value_type* __get_ptr(__node_value_type& __n) {
|
||||
return _VSTD::addressof(__n.__cc);
|
||||
return _VSTD::addressof(__n.__get_value());
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static __nc_value_type&& __move(__node_value_type& __v) {
|
||||
return _VSTD::move(__v.__nc);
|
||||
static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
|
||||
return __v.__move();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -72,6 +72,9 @@ struct array
|
||||
const T* data() const noexcept;
|
||||
};
|
||||
|
||||
template <class T, class... U>
|
||||
array(T, U...) -> array<T, 1 + sizeof...(U)>;
|
||||
|
||||
template <class T, size_t N>
|
||||
bool operator==(const array<T,N>& x, const array<T,N>& y);
|
||||
template <class T, size_t N>
|
||||
@@ -86,7 +89,7 @@ template <class T, size_t N>
|
||||
bool operator>=(const array<T,N>& x, const array<T,N>& y);
|
||||
|
||||
template <class T, size_t N >
|
||||
void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));
|
||||
void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // C++17
|
||||
|
||||
template <class T> class tuple_size;
|
||||
template <size_t I, class T> class tuple_element;
|
||||
@@ -244,10 +247,11 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
|
||||
typedef typename conditional<is_const<_Tp>::value, const char,
|
||||
char>::type _CharType;
|
||||
_ALIGNAS(alignment_of<_Tp[1]>::value) _CharType __elems_[sizeof(_Tp[1])];
|
||||
|
||||
struct _ArrayInStructT { _Tp __data_[1]; };
|
||||
_ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)];
|
||||
|
||||
// No explicit construct/copy/destroy for aggregate type
|
||||
_LIBCPP_INLINE_VISIBILITY void fill(const value_type&) {
|
||||
@@ -353,6 +357,14 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
|
||||
};
|
||||
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template<class _Tp, class... _Args,
|
||||
class = typename enable_if<(is_same_v<_Tp, _Args> && ...), void>::type
|
||||
>
|
||||
array(_Tp, _Args...)
|
||||
-> array<_Tp, 1 + sizeof...(_Args)>;
|
||||
#endif
|
||||
|
||||
template <class _Tp, size_t _Size>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
|
||||
@@ -555,6 +555,9 @@ void atomic_signal_fence(memory_order m) noexcept;
|
||||
#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
|
||||
#error <atomic> is not implemented
|
||||
#endif
|
||||
#ifdef kill_dependency
|
||||
#error C++ standard library is incompatible with <stdatomic.h>
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
# define __cpp_lib_atomic_is_always_lock_free 201603L
|
||||
@@ -695,7 +698,7 @@ static inline void __c11_atomic_store(_Atomic(_Tp)* __a, _Tp __val,
|
||||
}
|
||||
|
||||
template <typename _Tp>
|
||||
static inline _Tp __c11_atomic_load(volatile _Atomic(_Tp)* __a,
|
||||
static inline _Tp __c11_atomic_load(const volatile _Atomic(_Tp)* __a,
|
||||
memory_order __order) {
|
||||
_Tp __ret;
|
||||
__atomic_load(&__a->__a_value, &__ret,
|
||||
@@ -704,7 +707,7 @@ static inline _Tp __c11_atomic_load(volatile _Atomic(_Tp)* __a,
|
||||
}
|
||||
|
||||
template <typename _Tp>
|
||||
static inline _Tp __c11_atomic_load(_Atomic(_Tp)* __a, memory_order __order) {
|
||||
static inline _Tp __c11_atomic_load(const _Atomic(_Tp)* __a, memory_order __order) {
|
||||
_Tp __ret;
|
||||
__atomic_load(&__a->__a_value, &__ret,
|
||||
__gcc_atomic::__to_gcc_order(__order));
|
||||
@@ -1741,7 +1744,7 @@ typedef struct atomic_flag
|
||||
atomic_flag() _NOEXCEPT : __a_() {}
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||
atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
679
include/compare
Normal file
679
include/compare
Normal file
@@ -0,0 +1,679 @@
|
||||
// -*- C++ -*-
|
||||
//===-------------------------- compare -----------------------------------===//
|
||||
//
|
||||
// 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_COMPARE
|
||||
#define _LIBCPP_COMPARE
|
||||
|
||||
/*
|
||||
compare synopsis
|
||||
|
||||
namespace std {
|
||||
// [cmp.categories], comparison category types
|
||||
class weak_equality;
|
||||
class strong_equality;
|
||||
class partial_ordering;
|
||||
class weak_ordering;
|
||||
class strong_ordering;
|
||||
|
||||
// named comparison functions
|
||||
constexpr bool is_eq (weak_equality cmp) noexcept { return cmp == 0; }
|
||||
constexpr bool is_neq (weak_equality cmp) noexcept { return cmp != 0; }
|
||||
constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; }
|
||||
constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
|
||||
constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; }
|
||||
constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; }
|
||||
|
||||
// [cmp.common], common comparison category type
|
||||
template<class... Ts>
|
||||
struct common_comparison_category {
|
||||
using type = see below;
|
||||
};
|
||||
template<class... Ts>
|
||||
using common_comparison_category_t = typename common_comparison_category<Ts...>::type;
|
||||
|
||||
// [cmp.alg], comparison algorithms
|
||||
template<class T> constexpr strong_ordering strong_order(const T& a, const T& b);
|
||||
template<class T> constexpr weak_ordering weak_order(const T& a, const T& b);
|
||||
template<class T> constexpr partial_ordering partial_order(const T& a, const T& b);
|
||||
template<class T> constexpr strong_equality strong_equal(const T& a, const T& b);
|
||||
template<class T> constexpr weak_equality weak_equal(const T& a, const T& b);
|
||||
}
|
||||
*/
|
||||
|
||||
#include <__config>
|
||||
#include <type_traits>
|
||||
#include <array>
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
|
||||
// exposition only
|
||||
enum class _LIBCPP_ENUM_VIS _EqResult : unsigned char {
|
||||
__zero = 0,
|
||||
__equal = __zero,
|
||||
__equiv = __equal,
|
||||
__nonequal = 1,
|
||||
__nonequiv = __nonequal
|
||||
};
|
||||
|
||||
enum class _LIBCPP_ENUM_VIS _OrdResult : signed char {
|
||||
__less = -1,
|
||||
__greater = 1
|
||||
};
|
||||
|
||||
enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char {
|
||||
__unordered = -127
|
||||
};
|
||||
|
||||
struct _CmpUnspecifiedType;
|
||||
using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)();
|
||||
|
||||
class weak_equality {
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {}
|
||||
|
||||
public:
|
||||
static const weak_equality equivalent;
|
||||
static const weak_equality nonequivalent;
|
||||
|
||||
friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept;
|
||||
friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept;
|
||||
#endif
|
||||
|
||||
private:
|
||||
_EqResult __value_;
|
||||
};
|
||||
|
||||
_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv);
|
||||
_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ == _EqResult::__zero;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept {
|
||||
return __v.__value_ == _EqResult::__zero;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ != _EqResult::__zero;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept {
|
||||
return __v.__value_ != _EqResult::__zero;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept {
|
||||
return __v;
|
||||
}
|
||||
#endif
|
||||
|
||||
class strong_equality {
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {}
|
||||
|
||||
public:
|
||||
static const strong_equality equal;
|
||||
static const strong_equality nonequal;
|
||||
static const strong_equality equivalent;
|
||||
static const strong_equality nonequivalent;
|
||||
|
||||
// conversion
|
||||
constexpr operator weak_equality() const noexcept {
|
||||
return __value_ == _EqResult::__zero ? weak_equality::equivalent
|
||||
: weak_equality::nonequivalent;
|
||||
}
|
||||
|
||||
// comparisons
|
||||
friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept;
|
||||
friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept;
|
||||
#endif
|
||||
private:
|
||||
_EqResult __value_;
|
||||
};
|
||||
|
||||
_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal);
|
||||
_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal);
|
||||
_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv);
|
||||
_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ == _EqResult::__zero;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept {
|
||||
return __v.__value_ == _EqResult::__zero;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ != _EqResult::__zero;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept {
|
||||
return __v.__value_ != _EqResult::__zero;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept {
|
||||
return __v;
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
|
||||
class partial_ordering {
|
||||
using _ValueT = signed char;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit constexpr partial_ordering(_EqResult __v) noexcept
|
||||
: __value_(_ValueT(__v)) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit constexpr partial_ordering(_OrdResult __v) noexcept
|
||||
: __value_(_ValueT(__v)) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit constexpr partial_ordering(_NCmpResult __v) noexcept
|
||||
: __value_(_ValueT(__v)) {}
|
||||
|
||||
constexpr bool __is_ordered() const noexcept {
|
||||
return __value_ != _ValueT(_NCmpResult::__unordered);
|
||||
}
|
||||
public:
|
||||
// valid values
|
||||
static const partial_ordering less;
|
||||
static const partial_ordering equivalent;
|
||||
static const partial_ordering greater;
|
||||
static const partial_ordering unordered;
|
||||
|
||||
// conversion
|
||||
constexpr operator weak_equality() const noexcept {
|
||||
return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent;
|
||||
}
|
||||
|
||||
// comparisons
|
||||
friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
|
||||
friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
|
||||
friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
|
||||
friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
|
||||
friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept;
|
||||
friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
|
||||
#endif
|
||||
|
||||
private:
|
||||
_ValueT __value_;
|
||||
};
|
||||
|
||||
_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::less(_OrdResult::__less);
|
||||
_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::equivalent(_EqResult::__equiv);
|
||||
_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::greater(_OrdResult::__greater);
|
||||
_LIBCPP_INLINE_VAR constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__unordered);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__is_ordered() && __v.__value_ == 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__is_ordered() && __v.__value_ < 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__is_ordered() && __v.__value_ <= 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__is_ordered() && __v.__value_ > 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__is_ordered() && __v.__value_ >= 0;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
|
||||
return __v.__is_ordered() && 0 == __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
|
||||
return __v.__is_ordered() && 0 < __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
|
||||
return __v.__is_ordered() && 0 <= __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept {
|
||||
return __v.__is_ordered() && 0 > __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
|
||||
return __v.__is_ordered() && 0 >= __v.__value_;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return !__v.__is_ordered() || __v.__value_ != 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
|
||||
return !__v.__is_ordered() || __v.__value_ != 0;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept {
|
||||
return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v);
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
|
||||
class weak_ordering {
|
||||
using _ValueT = signed char;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit constexpr weak_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
|
||||
|
||||
public:
|
||||
static const weak_ordering less;
|
||||
static const weak_ordering equivalent;
|
||||
static const weak_ordering greater;
|
||||
|
||||
// conversions
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr operator weak_equality() const noexcept {
|
||||
return __value_ == 0 ? weak_equality::equivalent
|
||||
: weak_equality::nonequivalent;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr operator partial_ordering() const noexcept {
|
||||
return __value_ == 0 ? partial_ordering::equivalent
|
||||
: (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
|
||||
}
|
||||
|
||||
// comparisons
|
||||
friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
|
||||
friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
|
||||
friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
|
||||
friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
|
||||
friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept;
|
||||
friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
|
||||
#endif
|
||||
|
||||
private:
|
||||
_ValueT __value_;
|
||||
};
|
||||
|
||||
_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::less(_OrdResult::__less);
|
||||
_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::equivalent(_EqResult::__equiv);
|
||||
_LIBCPP_INLINE_VAR constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ == 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ != 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ < 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ <= 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ > 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ >= 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
|
||||
return 0 == __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
|
||||
return 0 != __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
|
||||
return 0 < __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
|
||||
return 0 <= __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept {
|
||||
return 0 > __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
|
||||
return 0 >= __v.__value_;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept {
|
||||
return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v);
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
|
||||
class strong_ordering {
|
||||
using _ValueT = signed char;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(_ValueT(__v)) {}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {}
|
||||
|
||||
public:
|
||||
static const strong_ordering less;
|
||||
static const strong_ordering equal;
|
||||
static const strong_ordering equivalent;
|
||||
static const strong_ordering greater;
|
||||
|
||||
// conversions
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr operator weak_equality() const noexcept {
|
||||
return __value_ == 0 ? weak_equality::equivalent
|
||||
: weak_equality::nonequivalent;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr operator strong_equality() const noexcept {
|
||||
return __value_ == 0 ? strong_equality::equal
|
||||
: strong_equality::nonequal;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr operator partial_ordering() const noexcept {
|
||||
return __value_ == 0 ? partial_ordering::equivalent
|
||||
: (__value_ < 0 ? partial_ordering::less : partial_ordering::greater);
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr operator weak_ordering() const noexcept {
|
||||
return __value_ == 0 ? weak_ordering::equivalent
|
||||
: (__value_ < 0 ? weak_ordering::less : weak_ordering::greater);
|
||||
}
|
||||
|
||||
// comparisons
|
||||
friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
|
||||
friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
|
||||
friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
|
||||
friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
|
||||
friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept;
|
||||
friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
|
||||
friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
|
||||
#endif
|
||||
|
||||
private:
|
||||
_ValueT __value_;
|
||||
};
|
||||
|
||||
_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::less(_OrdResult::__less);
|
||||
_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equal(_EqResult::__equal);
|
||||
_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv);
|
||||
_LIBCPP_INLINE_VAR constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ == 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ != 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ < 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ <= 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ > 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v.__value_ >= 0;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
|
||||
return 0 == __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
|
||||
return 0 != __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
|
||||
return 0 < __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
|
||||
return 0 <= __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept {
|
||||
return 0 > __v.__value_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
|
||||
return 0 >= __v.__value_;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept {
|
||||
return __v;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept {
|
||||
return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v);
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
|
||||
|
||||
// named comparison functions
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
|
||||
|
||||
namespace __comp_detail {
|
||||
|
||||
enum _ClassifyCompCategory : unsigned{
|
||||
_None,
|
||||
_WeakEq,
|
||||
_StrongEq,
|
||||
_PartialOrd,
|
||||
_WeakOrd,
|
||||
_StrongOrd,
|
||||
_CCC_Size
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr _ClassifyCompCategory __type_to_enum() noexcept {
|
||||
if (is_same_v<_Tp, weak_equality>)
|
||||
return _WeakEq;
|
||||
if (is_same_v<_Tp, strong_equality>)
|
||||
return _StrongEq;
|
||||
if (is_same_v<_Tp, partial_ordering>)
|
||||
return _PartialOrd;
|
||||
if (is_same_v<_Tp, weak_ordering>)
|
||||
return _WeakOrd;
|
||||
if (is_same_v<_Tp, strong_ordering>)
|
||||
return _StrongOrd;
|
||||
return _None;
|
||||
}
|
||||
|
||||
template <size_t _Size>
|
||||
constexpr _ClassifyCompCategory
|
||||
__compute_comp_type(std::array<_ClassifyCompCategory, _Size> __types) {
|
||||
std::array<int, _CCC_Size> __seen = {};
|
||||
for (auto __type : __types)
|
||||
++__seen[__type];
|
||||
if (__seen[_None])
|
||||
return _None;
|
||||
if (__seen[_WeakEq])
|
||||
return _WeakEq;
|
||||
if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd]))
|
||||
return _WeakEq;
|
||||
if (__seen[_StrongEq])
|
||||
return _StrongEq;
|
||||
if (__seen[_PartialOrd])
|
||||
return _PartialOrd;
|
||||
if (__seen[_WeakOrd])
|
||||
return _WeakOrd;
|
||||
return _StrongOrd;
|
||||
}
|
||||
|
||||
template <class ..._Ts>
|
||||
constexpr auto __get_comp_type() {
|
||||
using _CCC = _ClassifyCompCategory;
|
||||
constexpr array<_CCC, sizeof...(_Ts)> __type_kinds{{__comp_detail::__type_to_enum<_Ts>()...}};
|
||||
constexpr _CCC _Cat = sizeof...(_Ts) == 0 ? _StrongOrd
|
||||
: __compute_comp_type(__type_kinds);
|
||||
if constexpr (_Cat == _None)
|
||||
return void();
|
||||
else if constexpr (_Cat == _WeakEq)
|
||||
return weak_equality::equivalent;
|
||||
else if constexpr (_Cat == _StrongEq)
|
||||
return strong_equality::equivalent;
|
||||
else if constexpr (_Cat == _PartialOrd)
|
||||
return partial_ordering::equivalent;
|
||||
else if constexpr (_Cat == _WeakOrd)
|
||||
return weak_ordering::equivalent;
|
||||
else if constexpr (_Cat == _StrongOrd)
|
||||
return strong_ordering::equivalent;
|
||||
else
|
||||
static_assert(_Cat != _Cat, "unhandled case");
|
||||
}
|
||||
} // namespace __comp_detail
|
||||
|
||||
// [cmp.common], common comparison category type
|
||||
template<class... _Ts>
|
||||
struct _LIBCPP_TEMPLATE_VIS common_comparison_category {
|
||||
using type = decltype(__comp_detail::__get_comp_type<_Ts...>());
|
||||
};
|
||||
|
||||
template<class... _Ts>
|
||||
using common_comparison_category_t = typename common_comparison_category<_Ts...>::type;
|
||||
|
||||
// [cmp.alg], comparison algorithms
|
||||
// TODO: unimplemented
|
||||
template<class _Tp> constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs);
|
||||
template<class _Tp> constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs);
|
||||
template<class _Tp> constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs);
|
||||
template<class _Tp> constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs);
|
||||
template<class _Tp> constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs);
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_COMPARE
|
||||
@@ -1125,6 +1125,17 @@ pow(const _Tp& __x, const complex<_Up>& __y)
|
||||
return _VSTD::pow(result_type(__x), result_type(__y));
|
||||
}
|
||||
|
||||
// __sqr, computes pow(x, 2)
|
||||
|
||||
template<class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
complex<_Tp>
|
||||
__sqr(const complex<_Tp>& __x)
|
||||
{
|
||||
return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()),
|
||||
_Tp(2) * __x.real() * __x.imag());
|
||||
}
|
||||
|
||||
// asinh
|
||||
|
||||
template<class _Tp>
|
||||
@@ -1150,7 +1161,7 @@ asinh(const complex<_Tp>& __x)
|
||||
}
|
||||
if (__libcpp_isinf_or_builtin(__x.imag()))
|
||||
return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
|
||||
complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) + _Tp(1)));
|
||||
complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1)));
|
||||
return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
|
||||
}
|
||||
|
||||
@@ -1184,7 +1195,7 @@ acosh(const complex<_Tp>& __x)
|
||||
}
|
||||
if (__libcpp_isinf_or_builtin(__x.imag()))
|
||||
return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag()));
|
||||
complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1)));
|
||||
complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
|
||||
return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag()));
|
||||
}
|
||||
|
||||
@@ -1318,7 +1329,7 @@ acos(const complex<_Tp>& __x)
|
||||
return complex<_Tp>(__pi/_Tp(2), -__x.imag());
|
||||
if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag())))
|
||||
return complex<_Tp>(__pi/_Tp(2), -__x.imag());
|
||||
complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1)));
|
||||
complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
|
||||
if (signbit(__x.imag()))
|
||||
return complex<_Tp>(abs(__z.imag()), abs(__z.real()));
|
||||
return complex<_Tp>(abs(__z.imag()), -abs(__z.real()));
|
||||
|
||||
@@ -128,6 +128,10 @@ public:
|
||||
void clear() noexcept;
|
||||
};
|
||||
|
||||
template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
|
||||
deque(InputIterator, InputIterator, Allocator = Allocator())
|
||||
-> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
|
||||
|
||||
template <class T, class Allocator>
|
||||
bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
|
||||
template <class T, class Allocator>
|
||||
@@ -921,13 +925,14 @@ class __deque_base
|
||||
{
|
||||
__deque_base(const __deque_base& __c);
|
||||
__deque_base& operator=(const __deque_base& __c);
|
||||
protected:
|
||||
typedef _Tp value_type;
|
||||
public:
|
||||
typedef _Allocator allocator_type;
|
||||
typedef allocator_traits<allocator_type> __alloc_traits;
|
||||
typedef typename __alloc_traits::size_type size_type;
|
||||
protected:
|
||||
typedef _Tp value_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename __alloc_traits::size_type size_type;
|
||||
typedef typename __alloc_traits::difference_type difference_type;
|
||||
typedef typename __alloc_traits::pointer pointer;
|
||||
typedef typename __alloc_traits::const_pointer const_pointer;
|
||||
@@ -946,6 +951,7 @@ protected:
|
||||
typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
|
||||
difference_type> const_iterator;
|
||||
|
||||
protected:
|
||||
__map __map_;
|
||||
size_type __start_;
|
||||
__compressed_pair<size_type, allocator_type> __size_;
|
||||
@@ -1461,6 +1467,23 @@ private:
|
||||
void __move_assign(deque& __c, false_type);
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template<class _InputIterator,
|
||||
class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
|
||||
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
||||
>
|
||||
deque(_InputIterator, _InputIterator)
|
||||
-> deque<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
||||
|
||||
template<class _InputIterator,
|
||||
class _Alloc,
|
||||
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
||||
>
|
||||
deque(_InputIterator, _InputIterator, _Alloc)
|
||||
-> deque<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
||||
#endif
|
||||
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
deque<_Tp, _Allocator>::deque(size_type __n)
|
||||
{
|
||||
|
||||
@@ -54,4 +54,16 @@
|
||||
|
||||
#define _VSTD_FS ::std::experimental::filesystem::v1
|
||||
|
||||
#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD \
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 {
|
||||
|
||||
#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD \
|
||||
} _LIBCPP_END_NAMESPACE_EXPERIMENTAL
|
||||
|
||||
#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD_ABI \
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD namespace simd_abi {
|
||||
|
||||
#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI \
|
||||
} _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
|
||||
|
||||
#endif
|
||||
|
||||
@@ -93,28 +93,28 @@ class _LIBCPP_TEMPLATE_VIS coroutine_handle;
|
||||
template <>
|
||||
class _LIBCPP_TEMPLATE_VIS coroutine_handle<void> {
|
||||
public:
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR coroutine_handle() _NOEXCEPT : __handle_(nullptr) {}
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR coroutine_handle(nullptr_t) _NOEXCEPT : __handle_(nullptr) {}
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
coroutine_handle& operator=(nullptr_t) _NOEXCEPT {
|
||||
__handle_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR void* address() const _NOEXCEPT { return __handle_; }
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return __handle_; }
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void operator()() { resume(); }
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void resume() {
|
||||
_LIBCPP_ASSERT(__is_suspended(),
|
||||
"resume() can only be called on suspended coroutines");
|
||||
@@ -123,14 +123,14 @@ public:
|
||||
__builtin_coro_resume(__handle_);
|
||||
}
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void destroy() {
|
||||
_LIBCPP_ASSERT(__is_suspended(),
|
||||
"destroy() can only be called on suspended coroutines");
|
||||
__builtin_coro_destroy(__handle_);
|
||||
}
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool done() const {
|
||||
_LIBCPP_ASSERT(__is_suspended(),
|
||||
"done() can only be called on suspended coroutines");
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static coroutine_handle from_address(void* __addr) _NOEXCEPT {
|
||||
coroutine_handle __tmp;
|
||||
__tmp.__handle_ = __addr;
|
||||
@@ -146,7 +146,7 @@ public:
|
||||
}
|
||||
|
||||
// FIXME: Should from_address(nullptr) be allowed?
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
|
||||
return coroutine_handle(nullptr);
|
||||
}
|
||||
@@ -169,27 +169,27 @@ private:
|
||||
};
|
||||
|
||||
// 18.11.2.7 comparison operators:
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
|
||||
return __x.address() == __y.address();
|
||||
}
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
|
||||
return !(__x == __y);
|
||||
}
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator<(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
|
||||
return less<void*>()(__x.address(), __y.address());
|
||||
}
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator>(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
|
||||
return __y < __x;
|
||||
}
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator<=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
|
||||
return !(__x > __y);
|
||||
}
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator>=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
|
||||
return !(__x < __y);
|
||||
}
|
||||
@@ -202,8 +202,8 @@ public:
|
||||
// 18.11.2.1 construct/reset
|
||||
using coroutine_handle<>::coroutine_handle;
|
||||
#else
|
||||
_LIBCPP_ALWAYS_INLINE coroutine_handle() _NOEXCEPT : _Base() {}
|
||||
_LIBCPP_ALWAYS_INLINE coroutine_handle(nullptr_t) _NOEXCEPT : _Base(nullptr) {}
|
||||
_LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT : _Base() {}
|
||||
_LIBCPP_INLINE_VISIBILITY coroutine_handle(nullptr_t) _NOEXCEPT : _Base(nullptr) {}
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
coroutine_handle& operator=(nullptr_t) _NOEXCEPT {
|
||||
@@ -213,12 +213,12 @@ public:
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Promise& promise() const {
|
||||
return *reinterpret_cast<_Promise*>(
|
||||
return *static_cast<_Promise*>(
|
||||
__builtin_coro_promise(this->__handle_, __alignof(_Promise), false));
|
||||
}
|
||||
|
||||
public:
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static coroutine_handle from_address(void* __addr) _NOEXCEPT {
|
||||
coroutine_handle __tmp;
|
||||
__tmp.__handle_ = __addr;
|
||||
@@ -229,7 +229,7 @@ public:
|
||||
// the deleted _Promise* overload doesn't make from_address(nullptr)
|
||||
// ambiguous.
|
||||
// FIXME: should from_address work with nullptr?
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
|
||||
return coroutine_handle(nullptr);
|
||||
}
|
||||
@@ -248,7 +248,7 @@ public:
|
||||
"pointers to the coroutine's promise type; use 'from_promise' instead");
|
||||
}
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
|
||||
typedef typename remove_cv<_Promise>::type _RawPromise;
|
||||
coroutine_handle __tmp;
|
||||
@@ -259,21 +259,60 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if __has_builtin(__builtin_coro_noop)
|
||||
struct noop_coroutine_promise {};
|
||||
|
||||
template <>
|
||||
class _LIBCPP_TEMPLATE_VIS coroutine_handle<noop_coroutine_promise>
|
||||
: public coroutine_handle<> {
|
||||
using _Base = coroutine_handle<>;
|
||||
using _Promise = noop_coroutine_promise;
|
||||
public:
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Promise& promise() const {
|
||||
return *static_cast<_Promise*>(
|
||||
__builtin_coro_promise(this->__handle_, __alignof(_Promise), false));
|
||||
}
|
||||
|
||||
_LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; }
|
||||
_LIBCPP_CONSTEXPR bool done() const _NOEXCEPT { return false; }
|
||||
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void operator()() const _NOEXCEPT {}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void resume() const _NOEXCEPT {}
|
||||
_LIBCPP_CONSTEXPR_AFTER_CXX17 void destroy() const _NOEXCEPT {}
|
||||
|
||||
private:
|
||||
friend coroutine_handle<noop_coroutine_promise> noop_coroutine() _NOEXCEPT;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT {
|
||||
this->__handle_ = __builtin_coro_noop();
|
||||
}
|
||||
};
|
||||
|
||||
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
noop_coroutine_handle noop_coroutine() _NOEXCEPT {
|
||||
return noop_coroutine_handle();
|
||||
}
|
||||
#endif // __has_builtin(__builtin_coro_noop)
|
||||
|
||||
struct _LIBCPP_TYPE_VIS suspend_never {
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool await_ready() const _NOEXCEPT { return true; }
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void await_suspend(coroutine_handle<>) const _NOEXCEPT {}
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void await_resume() const _NOEXCEPT {}
|
||||
};
|
||||
|
||||
struct _LIBCPP_TYPE_VIS suspend_always {
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool await_ready() const _NOEXCEPT { return false; }
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void await_suspend(coroutine_handle<>) const _NOEXCEPT {}
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void await_resume() const _NOEXCEPT {}
|
||||
};
|
||||
|
||||
|
||||
@@ -135,17 +135,18 @@ private:
|
||||
value_type * __base_;
|
||||
_LIBCPP_ALWAYS_INLINE dynarray () noexcept : __size_(0), __base_(nullptr) {}
|
||||
|
||||
static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count )
|
||||
{
|
||||
if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count )
|
||||
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::__allocate (sizeof(value_type) * count));
|
||||
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));
|
||||
static inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __deallocate_value(value_type* __ptr ) noexcept {
|
||||
_VSTD::__libcpp_deallocate(static_cast<void *>(__ptr), __alignof(value_type));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
|
||||
enum class file_type;
|
||||
enum class perms;
|
||||
enum class perm_options;
|
||||
enum class copy_options;
|
||||
enum class directory_options;
|
||||
|
||||
@@ -75,11 +76,11 @@
|
||||
|
||||
// operational functions
|
||||
|
||||
path absolute(const path& p, const path& base=current_path());
|
||||
path absolute(const path& p);
|
||||
path absolute(const path& p, error_code &ec);
|
||||
|
||||
path canonical(const path& p, const path& base = current_path());
|
||||
path canonical(const path& p);
|
||||
path canonical(const path& p, error_code& ec);
|
||||
path canonical(const path& p, const path& base, error_code& ec);
|
||||
|
||||
void copy(const path& from, const path& to);
|
||||
void copy(const path& from, const path& to, error_code& ec);
|
||||
@@ -178,12 +179,23 @@
|
||||
void last_write_time(const path& p, file_time_type new_time,
|
||||
error_code& ec) _NOEXCEPT;
|
||||
|
||||
void permissions(const path& p, perms prms);
|
||||
void permissions(const path& p, perms prms, error_code& ec) _NOEXCEPT;
|
||||
void permissions(const path& p, perms prms,
|
||||
perm_options opts=perm_options::replace);
|
||||
void permissions(const path& p, perms prms, error_code& ec) noexcept;
|
||||
void permissions(const path& p, perms prms, perm_options opts,
|
||||
error_code& ec);
|
||||
|
||||
path proximate(const path& p, error_code& ec);
|
||||
path proximate(const path& p, const path& base = current_path());
|
||||
path proximate(const path& p, const path& base, error_code &ec);
|
||||
|
||||
path read_symlink(const path& p);
|
||||
path read_symlink(const path& p, error_code& ec);
|
||||
|
||||
path relative(const path& p, error_code& ec);
|
||||
path relative(const path& p, const path& base=current_path());
|
||||
path relative(const path& p, const path& base, error_code& ec);
|
||||
|
||||
bool remove(const path& p);
|
||||
bool remove(const path& p, error_code& ec) _NOEXCEPT;
|
||||
|
||||
@@ -207,12 +219,13 @@
|
||||
file_status symlink_status(const path& p);
|
||||
file_status symlink_status(const path& p, error_code& ec) _NOEXCEPT;
|
||||
|
||||
path system_complete(const path& p);
|
||||
path system_complete(const path& p, error_code& ec);
|
||||
|
||||
path temp_directory_path();
|
||||
path temp_directory_path(error_code& ec);
|
||||
|
||||
path weakly_canonical(path const& p);
|
||||
path weakly_canonical(path const& p, error_code& ec);
|
||||
|
||||
|
||||
} } } } // namespaces std::experimental::filesystem::v1
|
||||
|
||||
*/
|
||||
@@ -290,10 +303,6 @@ enum class _LIBCPP_ENUM_VIS perms : unsigned
|
||||
sticky_bit = 01000,
|
||||
mask = 07777,
|
||||
unknown = 0xFFFF,
|
||||
|
||||
add_perms = 0x10000,
|
||||
remove_perms = 0x20000,
|
||||
symlink_nofollow = 0x40000
|
||||
};
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@@ -324,6 +333,41 @@ _LIBCPP_INLINE_VISIBILITY
|
||||
inline perms& operator^=(perms& _LHS, perms _RHS)
|
||||
{ return _LHS = _LHS ^ _RHS; }
|
||||
|
||||
enum class _LIBCPP_ENUM_VIS perm_options : unsigned char {
|
||||
replace = 1,
|
||||
add = 2,
|
||||
remove = 4,
|
||||
nofollow = 8
|
||||
};
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_CONSTEXPR perm_options operator&(perm_options _LHS, perm_options _RHS)
|
||||
{ return static_cast<perm_options>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_CONSTEXPR perm_options operator|(perm_options _LHS, perm_options _RHS)
|
||||
{ return static_cast<perm_options>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_CONSTEXPR perm_options operator^(perm_options _LHS, perm_options _RHS)
|
||||
{ return static_cast<perm_options>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline _LIBCPP_CONSTEXPR perm_options operator~(perm_options _LHS)
|
||||
{ return static_cast<perm_options>(~static_cast<unsigned>(_LHS)); }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline perm_options& operator&=(perm_options& _LHS, perm_options _RHS)
|
||||
{ return _LHS = _LHS & _RHS; }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline perm_options& operator|=(perm_options& _LHS, perm_options _RHS)
|
||||
{ return _LHS = _LHS | _RHS; }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
inline perm_options& operator^=(perm_options& _LHS, perm_options _RHS)
|
||||
{ return _LHS = _LHS ^ _RHS; }
|
||||
|
||||
enum class _LIBCPP_ENUM_VIS copy_options : unsigned short
|
||||
{
|
||||
none = 0,
|
||||
@@ -677,24 +721,31 @@ public:
|
||||
typedef _VSTD::string_view __string_view;
|
||||
static _LIBCPP_CONSTEXPR value_type preferred_separator = '/';
|
||||
|
||||
enum class _LIBCPP_ENUM_VIS format : unsigned char {
|
||||
auto_format,
|
||||
native_format,
|
||||
generic_format
|
||||
};
|
||||
|
||||
// constructors and destructor
|
||||
_LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {}
|
||||
_LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {}
|
||||
_LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
path(string_type&& __s) _NOEXCEPT : __pn_(_VSTD::move(__s)) {}
|
||||
path(string_type&& __s, format = format::auto_format) _NOEXCEPT
|
||||
: __pn_(_VSTD::move(__s)) {}
|
||||
|
||||
template <
|
||||
class _Source,
|
||||
class = _EnableIfPathable<_Source, void>
|
||||
>
|
||||
path(const _Source& __src) {
|
||||
path(const _Source& __src, format = format::auto_format) {
|
||||
_SourceCVT<_Source>::__append_source(__pn_, __src);
|
||||
}
|
||||
|
||||
template <class _InputIt>
|
||||
path(_InputIt __first, _InputIt __last) {
|
||||
path(_InputIt __first, _InputIt __last, format = format::auto_format) {
|
||||
typedef typename iterator_traits<_InputIt>::value_type _ItVal;
|
||||
_PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
|
||||
}
|
||||
@@ -703,9 +754,11 @@ public:
|
||||
template <class _Source,
|
||||
class = _EnableIfPathable<_Source, void>
|
||||
>
|
||||
path(const _Source& __src, const locale& __loc);
|
||||
path(const _Source& __src, const locale& __loc,
|
||||
format = format::auto_format);
|
||||
template <class _InputIt>
|
||||
path(_InputIt __first, _InputIt _last, const locale& __loc);
|
||||
path(_InputIt __first, _InputIt _last, const locale& __loc,
|
||||
format = format::auto_format);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
~path() = default;
|
||||
@@ -761,26 +814,26 @@ public:
|
||||
|
||||
private:
|
||||
template <class _ECharT>
|
||||
void __append_sep_if_needed(_ECharT __first_or_null) {
|
||||
const _ECharT __null_val = {};
|
||||
bool __append_sep = !empty() &&
|
||||
!__is_separator(__pn_.back()) &&
|
||||
__first_or_null != __null_val && // non-empty
|
||||
!__is_separator(__first_or_null);
|
||||
if (__append_sep)
|
||||
__pn_ += preferred_separator;
|
||||
static bool __source_is_absolute(_ECharT __first_or_null) {
|
||||
return __is_separator(__first_or_null);
|
||||
}
|
||||
|
||||
public:
|
||||
// appends
|
||||
path& operator/=(const path& __p) {
|
||||
_LIBCPP_ASSERT(!__p.has_root_name(),
|
||||
"cannot append to a path with a root name");
|
||||
__append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]);
|
||||
if (__p.is_absolute()) {
|
||||
__pn_ = __p.__pn_;
|
||||
return *this;
|
||||
}
|
||||
if (has_filename())
|
||||
__pn_ += preferred_separator;
|
||||
__pn_ += __p.native();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// FIXME: Use _LIBCPP_DIAGNOSE_WARNING to produce a diagnostic when __src
|
||||
// is known at compile time to be "/' since the user almost certainly intended
|
||||
// to append a separator instead of overwriting the path with "/"
|
||||
template <class _Source>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_EnableIfPathable<_Source>
|
||||
@@ -793,7 +846,10 @@ public:
|
||||
append(const _Source& __src) {
|
||||
using _Traits = __is_pathable<_Source>;
|
||||
using _CVT = _PathCVT<_SourceChar<_Source>>;
|
||||
__append_sep_if_needed(_Traits::__first_or_null(__src));
|
||||
if (__source_is_absolute(_Traits::__first_or_null(__src)))
|
||||
__pn_.clear();
|
||||
else if (has_filename())
|
||||
__pn_ += preferred_separator;
|
||||
_CVT::__append_source(__pn_, __src);
|
||||
return *this;
|
||||
}
|
||||
@@ -803,10 +859,11 @@ public:
|
||||
typedef typename iterator_traits<_InputIt>::value_type _ItVal;
|
||||
static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
|
||||
using _CVT = _PathCVT<_ItVal>;
|
||||
if (__first != __last) {
|
||||
__append_sep_if_needed(*__first);
|
||||
_CVT::__append_range(__pn_, __first, __last);
|
||||
}
|
||||
if (__first != __last && __source_is_absolute(*__first))
|
||||
__pn_.clear();
|
||||
else if (has_filename())
|
||||
__pn_ += preferred_separator;
|
||||
_CVT::__append_range(__pn_, __first, __last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -881,10 +938,9 @@ public:
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
path& remove_filename() {
|
||||
if (__pn_.size() == __root_path_raw().size())
|
||||
clear();
|
||||
else
|
||||
__pn_ = __parent_path();
|
||||
auto __fname = __filename();
|
||||
if (!__fname.empty())
|
||||
__pn_.erase(__fname.data() - __pn_.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -900,6 +956,10 @@ public:
|
||||
__pn_.swap(__rhs.__pn_);
|
||||
}
|
||||
|
||||
// private helper to allow reserving memory in the path
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void __reserve(size_t __s) { __pn_.reserve(__s); }
|
||||
|
||||
// native format observers
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const string_type& native() const _NOEXCEPT {
|
||||
@@ -988,6 +1048,17 @@ public:
|
||||
_LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); }
|
||||
_LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); }
|
||||
|
||||
// relative paths
|
||||
path lexically_normal() const;
|
||||
path lexically_relative(const path& __base) const;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY path lexically_proximate(const path& __base) const {
|
||||
path __result = this->lexically_relative(__base);
|
||||
if (__result.native().empty())
|
||||
return *this;
|
||||
return __result;
|
||||
}
|
||||
|
||||
// iterators
|
||||
class _LIBCPP_TYPE_VIS iterator;
|
||||
typedef iterator const_iterator;
|
||||
@@ -1069,7 +1140,9 @@ bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path operator/(const path& __lhs, const path& __rhs) {
|
||||
return path(__lhs) /= __rhs;
|
||||
path __result(__lhs);
|
||||
__result /= __rhs;
|
||||
return __result;
|
||||
}
|
||||
|
||||
template <class _Source>
|
||||
@@ -1242,7 +1315,9 @@ void __throw_filesystem_error(_Args&&...)
|
||||
// operational functions
|
||||
|
||||
_LIBCPP_FUNC_VIS
|
||||
path __canonical(const path&, const path&, error_code *__ec=nullptr);
|
||||
path __absolute(const path&, error_code *__ec=nullptr);
|
||||
_LIBCPP_FUNC_VIS
|
||||
path __canonical(const path&, error_code *__ec=nullptr);
|
||||
_LIBCPP_FUNC_VIS
|
||||
void __copy(const path& __from, const path& __to, copy_options __opt,
|
||||
error_code *__ec=nullptr);
|
||||
@@ -1286,7 +1361,7 @@ _LIBCPP_FUNC_VIS
|
||||
void __last_write_time(const path& p, file_time_type new_time,
|
||||
error_code *ec=nullptr);
|
||||
_LIBCPP_FUNC_VIS
|
||||
void __permissions(const path& p, perms prms, error_code *ec=nullptr);
|
||||
void __permissions(const path&, perms, perm_options, error_code* = nullptr);
|
||||
_LIBCPP_FUNC_VIS
|
||||
path __read_symlink(const path& p, error_code *ec=nullptr);
|
||||
_LIBCPP_FUNC_VIS
|
||||
@@ -1307,6 +1382,8 @@ _LIBCPP_FUNC_VIS
|
||||
path __system_complete(const path&, error_code *__ec=nullptr);
|
||||
_LIBCPP_FUNC_VIS
|
||||
path __temp_directory_path(error_code *__ec=nullptr);
|
||||
_LIBCPP_FUNC_VIS
|
||||
path __weakly_canonical(path const& __p, error_code *__ec=nullptr);
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path current_path() {
|
||||
@@ -1328,24 +1405,24 @@ void current_path(const path& __p, error_code& __ec) _NOEXCEPT {
|
||||
__current_path(__p, &__ec);
|
||||
}
|
||||
|
||||
_LIBCPP_FUNC_VIS
|
||||
path absolute(const path&, const path& __p2 = current_path());
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path absolute(const path& __p) {
|
||||
return __absolute(__p);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path canonical(const path& __p, const path& __base = current_path()) {
|
||||
return __canonical(__p, __base);
|
||||
path absolute(const path& __p, error_code &__ec) {
|
||||
return __absolute(__p, &__ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path canonical(const path& __p) {
|
||||
return __canonical(__p);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path canonical(const path& __p, error_code& __ec) {
|
||||
path __base = __current_path(&__ec);
|
||||
if (__ec) return {};
|
||||
return __canonical(__p, __base, &__ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path canonical(const path& __p, const path& __base, error_code& __ec) {
|
||||
return __canonical(__p, __base, &__ec);
|
||||
return __canonical(__p, &__ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
@@ -1457,7 +1534,8 @@ void create_symlink(const path& __to, const path& __new) {
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT {
|
||||
void create_symlink(const path& __to, const path& __new,
|
||||
error_code& __ec) _NOEXCEPT {
|
||||
return __create_symlink(__to, __new, &__ec);
|
||||
}
|
||||
|
||||
@@ -1664,13 +1742,41 @@ void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOE
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void permissions(const path& __p, perms __prms) {
|
||||
__permissions(__p, __prms);
|
||||
void permissions(const path& __p, perms __prms,
|
||||
perm_options __opts = perm_options::replace) {
|
||||
__permissions(__p, __prms, __opts);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void permissions(const path& __p, perms __prms, error_code& __ec) {
|
||||
__permissions(__p, __prms, &__ec);
|
||||
void permissions(const path& __p, perms __prms, error_code& __ec) _NOEXCEPT {
|
||||
__permissions(__p, __prms, perm_options::replace, &__ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void permissions(const path& __p, perms __prms, perm_options __opts,
|
||||
error_code& __ec) {
|
||||
__permissions(__p, __prms, __opts, &__ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path proximate(const path& __p, const path& __base, error_code& __ec) {
|
||||
path __tmp = __weakly_canonical(__p, &__ec);
|
||||
if (__ec)
|
||||
return {};
|
||||
path __tmp_base = __weakly_canonical(__base, &__ec);
|
||||
if (__ec)
|
||||
return {};
|
||||
return __tmp.lexically_proximate(__tmp_base);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path proximate(const path& __p, error_code& __ec) {
|
||||
return proximate(__p, current_path(), __ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path proximate(const path& __p, const path& __base = current_path()) {
|
||||
return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base));
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
@@ -1683,6 +1789,29 @@ path read_symlink(const path& __p, error_code& __ec) {
|
||||
return __read_symlink(__p, &__ec);
|
||||
}
|
||||
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path relative(const path& __p, const path& __base, error_code& __ec) {
|
||||
path __tmp = __weakly_canonical(__p, &__ec);
|
||||
if (__ec)
|
||||
return path();
|
||||
path __tmpbase = __weakly_canonical(__base, &__ec);
|
||||
if (__ec)
|
||||
return path();
|
||||
return __tmp.lexically_relative(__tmpbase);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path relative(const path& __p, error_code& __ec) {
|
||||
return relative(__p, current_path(), __ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path relative(const path& __p, const path& __base=current_path()) {
|
||||
return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base));
|
||||
}
|
||||
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool remove(const path& __p) {
|
||||
return __remove(__p);
|
||||
@@ -1753,16 +1882,6 @@ file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT {
|
||||
return __symlink_status(__p, &__ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path system_complete(const path& __p) {
|
||||
return __system_complete(__p);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path system_complete(const path& __p, error_code& __ec) {
|
||||
return __system_complete(__p, &__ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path temp_directory_path() {
|
||||
return __temp_directory_path();
|
||||
@@ -1773,6 +1892,16 @@ path temp_directory_path(error_code& __ec) {
|
||||
return __temp_directory_path(&__ec);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path weakly_canonical(path const& __p) {
|
||||
return __weakly_canonical(__p);
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
path weakly_canonical(path const& __p, error_code& __ec) {
|
||||
return __weakly_canonical(__p, &__ec);
|
||||
}
|
||||
|
||||
|
||||
class directory_entry
|
||||
{
|
||||
|
||||
@@ -241,8 +241,8 @@ public:
|
||||
operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
|
||||
{
|
||||
static_assert ( std::is_same<
|
||||
typename std::decay<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type,
|
||||
typename std::decay<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
|
||||
typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type,
|
||||
typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
|
||||
>::value,
|
||||
"Corpus and Pattern iterators must point to the same type" );
|
||||
|
||||
@@ -394,8 +394,8 @@ public:
|
||||
operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
|
||||
{
|
||||
static_assert ( std::is_same<
|
||||
typename std::decay<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type,
|
||||
typename std::decay<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
|
||||
typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type,
|
||||
typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
|
||||
>::value,
|
||||
"Corpus and Pattern iterators must point to the same type" );
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace pmr {
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <__tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
@@ -96,7 +96,7 @@ size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT
|
||||
}
|
||||
|
||||
// 8.5, memory.resource
|
||||
class _LIBCPP_TEMPLATE_VIS memory_resource
|
||||
class _LIBCPP_TYPE_VIS memory_resource
|
||||
{
|
||||
static const size_t __max_align = alignof(max_align_t);
|
||||
|
||||
@@ -206,7 +206,7 @@ public:
|
||||
void construct(_Tp* __p, _Ts &&... __args)
|
||||
{
|
||||
_VSTD_LFTS::__lfts_user_alloc_construct(
|
||||
__p, resource(), _VSTD::forward<_Ts>(__args)...
|
||||
__p, *this, _VSTD::forward<_Ts>(__args)...
|
||||
);
|
||||
}
|
||||
|
||||
@@ -218,14 +218,14 @@ public:
|
||||
::new ((void*)__p) pair<_T1, _T2>(piecewise_construct
|
||||
, __transform_tuple(
|
||||
typename __lfts_uses_alloc_ctor<
|
||||
_T1, memory_resource*, _Args1...
|
||||
_T1, polymorphic_allocator&, _Args1...
|
||||
>::type()
|
||||
, _VSTD::move(__x)
|
||||
, typename __make_tuple_indices<sizeof...(_Args1)>::type{}
|
||||
)
|
||||
, __transform_tuple(
|
||||
typename __lfts_uses_alloc_ctor<
|
||||
_T2, memory_resource*, _Args2...
|
||||
_T2, polymorphic_allocator&, _Args2...
|
||||
>::type()
|
||||
, _VSTD::move(__y)
|
||||
, typename __make_tuple_indices<sizeof...(_Args2)>::type{}
|
||||
@@ -289,23 +289,23 @@ private:
|
||||
|
||||
template <class ..._Args, size_t ..._Idx>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
tuple<allocator_arg_t const&, memory_resource*, _Args&&...>
|
||||
tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>
|
||||
__transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
|
||||
__tuple_indices<_Idx...>) const
|
||||
__tuple_indices<_Idx...>)
|
||||
{
|
||||
using _Tup = tuple<allocator_arg_t const&, memory_resource*, _Args&&...>;
|
||||
return _Tup(allocator_arg, resource(),
|
||||
using _Tup = tuple<allocator_arg_t const&, polymorphic_allocator&, _Args&&...>;
|
||||
return _Tup(allocator_arg, *this,
|
||||
_VSTD::get<_Idx>(_VSTD::move(__t))...);
|
||||
}
|
||||
|
||||
template <class ..._Args, size_t ..._Idx>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
tuple<_Args&&..., memory_resource*>
|
||||
tuple<_Args&&..., polymorphic_allocator&>
|
||||
__transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
|
||||
__tuple_indices<_Idx...>) const
|
||||
__tuple_indices<_Idx...>)
|
||||
{
|
||||
using _Tup = tuple<_Args&&..., memory_resource*>;
|
||||
return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., resource());
|
||||
using _Tup = tuple<_Args&&..., polymorphic_allocator&>;
|
||||
return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., *this);
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
||||
@@ -463,8 +463,7 @@ template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
|
||||
{
|
||||
using _VSTD::swap;
|
||||
swap(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
|
||||
__pc1.swap(__pc2);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
|
||||
1285
include/experimental/simd
Normal file
1285
include/experimental/simd
Normal file
File diff suppressed because it is too large
Load Diff
@@ -134,6 +134,11 @@ public:
|
||||
void reverse() noexcept;
|
||||
};
|
||||
|
||||
|
||||
template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
|
||||
forward_list(InputIterator, InputIterator, Allocator = Allocator())
|
||||
-> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
|
||||
|
||||
template <class T, class Allocator>
|
||||
bool operator==(const forward_list<T, Allocator>& x,
|
||||
const forward_list<T, Allocator>& y);
|
||||
@@ -452,6 +457,10 @@ protected:
|
||||
typedef typename allocator_traits<__begin_node_allocator>::pointer
|
||||
__begin_node_pointer;
|
||||
|
||||
static_assert((!is_same<allocator_type, __node_allocator>::value),
|
||||
"internal allocator type must differ from user-specified "
|
||||
"type; otherwise overload resolution breaks");
|
||||
|
||||
__compressed_pair<__begin_node, __node_allocator> __before_begin_;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@@ -476,9 +485,11 @@ protected:
|
||||
_NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
|
||||
: __before_begin_(__begin_node()) {}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__forward_list_base(const allocator_type& __a)
|
||||
explicit __forward_list_base(const allocator_type& __a)
|
||||
: __before_begin_(__begin_node(), __node_allocator(__a)) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit __forward_list_base(const __node_allocator& __a)
|
||||
: __before_begin_(__begin_node(), __a) {}
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@@ -845,6 +856,23 @@ private:
|
||||
__sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
|
||||
};
|
||||
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template<class _InputIterator,
|
||||
class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
|
||||
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
||||
>
|
||||
forward_list(_InputIterator, _InputIterator)
|
||||
-> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
||||
|
||||
template<class _InputIterator,
|
||||
class _Alloc,
|
||||
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
||||
>
|
||||
forward_list(_InputIterator, _InputIterator, _Alloc)
|
||||
-> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
inline
|
||||
forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
|
||||
@@ -932,12 +960,9 @@ forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
|
||||
: base(allocator_type(
|
||||
__node_traits::select_on_container_copy_construction(__x.__alloc())
|
||||
)
|
||||
)
|
||||
{
|
||||
insert_after(cbefore_begin(), __x.begin(), __x.end());
|
||||
: base(
|
||||
__node_traits::select_on_container_copy_construction(__x.__alloc())) {
|
||||
insert_after(cbefore_begin(), __x.begin(), __x.end());
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
|
||||
@@ -1818,11 +1818,7 @@ template<class _Rp, class ..._ArgTypes>
|
||||
function<_Rp(_ArgTypes...)>&
|
||||
function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
|
||||
{
|
||||
if ((void *)__f_ == &__buf_)
|
||||
__f_->destroy();
|
||||
else if (__f_)
|
||||
__f_->destroy_deallocate();
|
||||
__f_ = 0;
|
||||
*this = nullptr;
|
||||
if (__f.__f_ == 0)
|
||||
__f_ = 0;
|
||||
else if ((void *)__f.__f_ == &__f.__buf_)
|
||||
@@ -1842,11 +1838,12 @@ template<class _Rp, class ..._ArgTypes>
|
||||
function<_Rp(_ArgTypes...)>&
|
||||
function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
|
||||
{
|
||||
if ((void *)__f_ == &__buf_)
|
||||
__f_->destroy();
|
||||
else if (__f_)
|
||||
__f_->destroy_deallocate();
|
||||
__base* __t = __f_;
|
||||
__f_ = 0;
|
||||
if ((void *)__t == &__buf_)
|
||||
__t->destroy();
|
||||
else if (__t)
|
||||
__t->destroy_deallocate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -2497,8 +2494,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
|
||||
|
||||
// default searcher
|
||||
template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
|
||||
_LIBCPP_TYPE_VIS
|
||||
class default_searcher {
|
||||
class _LIBCPP_TYPE_VIS default_searcher {
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
default_searcher(_ForwardIterator __f, _ForwardIterator __l,
|
||||
|
||||
@@ -2021,7 +2021,7 @@ public:
|
||||
class = typename enable_if
|
||||
<
|
||||
!is_same<
|
||||
typename decay<_Fp>::type,
|
||||
typename __uncvref<_Fp>::type,
|
||||
packaged_task
|
||||
>::value
|
||||
>::type
|
||||
@@ -2032,7 +2032,7 @@ public:
|
||||
class = typename enable_if
|
||||
<
|
||||
!is_same<
|
||||
typename decay<_Fp>::type,
|
||||
typename __uncvref<_Fp>::type,
|
||||
packaged_task
|
||||
>::value
|
||||
>::type
|
||||
@@ -2150,7 +2150,7 @@ public:
|
||||
class = typename enable_if
|
||||
<
|
||||
!is_same<
|
||||
typename decay<_Fp>::type,
|
||||
typename __uncvref<_Fp>::type,
|
||||
packaged_task
|
||||
>::value
|
||||
>::type
|
||||
@@ -2161,7 +2161,7 @@ public:
|
||||
class = typename enable_if
|
||||
<
|
||||
!is_same<
|
||||
typename decay<_Fp>::type,
|
||||
typename __uncvref<_Fp>::type,
|
||||
packaged_task
|
||||
>::value
|
||||
>::type
|
||||
|
||||
@@ -670,7 +670,7 @@ protected:
|
||||
void set_rdbuf(basic_streambuf<char_type, traits_type>* __sb);
|
||||
private:
|
||||
basic_ostream<char_type, traits_type>* __tie_;
|
||||
mutable int_type __fill_;
|
||||
mutable int_type __fill_;
|
||||
};
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
|
||||
61
include/list
61
include/list
@@ -147,6 +147,11 @@ public:
|
||||
void reverse() noexcept;
|
||||
};
|
||||
|
||||
|
||||
template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
|
||||
list(InputIterator, InputIterator, Allocator = Allocator())
|
||||
-> list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
|
||||
|
||||
template <class T, class Alloc>
|
||||
bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y);
|
||||
template <class T, class Alloc>
|
||||
@@ -527,11 +532,12 @@ class __list_imp
|
||||
{
|
||||
__list_imp(const __list_imp&);
|
||||
__list_imp& operator=(const __list_imp&);
|
||||
protected:
|
||||
typedef _Tp value_type;
|
||||
public:
|
||||
typedef _Alloc allocator_type;
|
||||
typedef allocator_traits<allocator_type> __alloc_traits;
|
||||
typedef typename __alloc_traits::size_type size_type;
|
||||
protected:
|
||||
typedef _Tp value_type;
|
||||
typedef typename __alloc_traits::void_pointer __void_pointer;
|
||||
typedef __list_iterator<value_type, __void_pointer> iterator;
|
||||
typedef __list_const_iterator<value_type, __void_pointer> const_iterator;
|
||||
@@ -550,6 +556,9 @@ protected:
|
||||
|
||||
typedef typename __rebind_alloc_helper<__alloc_traits, __node_base>::type __node_base_allocator;
|
||||
typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer;
|
||||
static_assert((!is_same<allocator_type, __node_allocator>::value),
|
||||
"internal allocator type must differ from user-specified "
|
||||
"type; otherwise overload resolution breaks");
|
||||
|
||||
__node_base __end_;
|
||||
__compressed_pair<size_type, __node_allocator> __size_alloc_;
|
||||
@@ -584,6 +593,11 @@ protected:
|
||||
_NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value);
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__list_imp(const allocator_type& __a);
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__list_imp(const __node_allocator& __a);
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
__list_imp(__node_allocator&& __a) _NOEXCEPT;
|
||||
#endif
|
||||
~__list_imp();
|
||||
void clear() _NOEXCEPT;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@@ -707,9 +721,18 @@ __list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
__list_imp<_Tp, _Alloc>::~__list_imp()
|
||||
{
|
||||
clear();
|
||||
inline __list_imp<_Tp, _Alloc>::__list_imp(const __node_allocator& __a)
|
||||
: __size_alloc_(0, __a) {}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
template <class _Tp, class _Alloc>
|
||||
inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT
|
||||
: __size_alloc_(0, std::move(__a)) {}
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
__list_imp<_Tp, _Alloc>::~__list_imp() {
|
||||
clear();
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
__get_db()->__erase_c(this);
|
||||
#endif
|
||||
@@ -1106,6 +1129,22 @@ private:
|
||||
void __move_assign(list& __c, false_type);
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template<class _InputIterator,
|
||||
class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
|
||||
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
||||
>
|
||||
list(_InputIterator, _InputIterator)
|
||||
-> list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
||||
|
||||
template<class _InputIterator,
|
||||
class _Alloc,
|
||||
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
||||
>
|
||||
list(_InputIterator, _InputIterator, _Alloc)
|
||||
-> list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
||||
#endif
|
||||
|
||||
// Link in nodes [__f, __l] just prior to __p
|
||||
template <class _Tp, class _Alloc>
|
||||
inline
|
||||
@@ -1226,10 +1265,8 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a,
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
list<_Tp, _Alloc>::list(const list& __c)
|
||||
: base(allocator_type(
|
||||
__node_alloc_traits::select_on_container_copy_construction(
|
||||
__c.__node_alloc())))
|
||||
{
|
||||
: base(__node_alloc_traits::select_on_container_copy_construction(
|
||||
__c.__node_alloc())) {
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
__get_db()->__insert_c(this);
|
||||
#endif
|
||||
@@ -1274,11 +1311,9 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il)
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
inline
|
||||
list<_Tp, _Alloc>::list(list&& __c)
|
||||
inline list<_Tp, _Alloc>::list(list&& __c)
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
|
||||
: base(allocator_type(_VSTD::move(__c.__node_alloc())))
|
||||
{
|
||||
: base(_VSTD::move(__c.__node_alloc())) {
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
__get_db()->__insert_c(this);
|
||||
#endif
|
||||
|
||||
@@ -768,10 +768,10 @@ __num_get_unsigned_integral(const char* __a, const char* __a_end,
|
||||
{
|
||||
if (__a != __a_end)
|
||||
{
|
||||
if (*__a == '-')
|
||||
{
|
||||
__err = ios_base::failbit;
|
||||
return 0;
|
||||
const bool __negate = *__a == '-';
|
||||
if (__negate && ++__a == __a_end) {
|
||||
__err = ios_base::failbit;
|
||||
return 0;
|
||||
}
|
||||
typename remove_reference<decltype(errno)>::type __save_errno = errno;
|
||||
errno = 0;
|
||||
@@ -785,13 +785,14 @@ __num_get_unsigned_integral(const char* __a, const char* __a_end,
|
||||
__err = ios_base::failbit;
|
||||
return 0;
|
||||
}
|
||||
else if (__current_errno == ERANGE ||
|
||||
numeric_limits<_Tp>::max() < __ll)
|
||||
else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll)
|
||||
{
|
||||
__err = ios_base::failbit;
|
||||
return numeric_limits<_Tp>::max();
|
||||
}
|
||||
return static_cast<_Tp>(__ll);
|
||||
_Tp __res = static_cast<_Tp>(__ll);
|
||||
if (__negate) __res = -__res;
|
||||
return __res;
|
||||
}
|
||||
__err = ios_base::failbit;
|
||||
return 0;
|
||||
|
||||
125
include/map
125
include/map
@@ -470,13 +470,13 @@ public:
|
||||
const _Compare& key_comp() const _NOEXCEPT {return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _CP& __x, const _CP& __y) const
|
||||
{return static_cast<const _Compare&>(*this)(__x.__cc.first, __y.__cc.first);}
|
||||
{return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y.__get_value().first);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _CP& __x, const _Key& __y) const
|
||||
{return static_cast<const _Compare&>(*this)(__x.__cc.first, __y);}
|
||||
{return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _Key& __x, const _CP& __y) const
|
||||
{return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);}
|
||||
{return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);}
|
||||
void swap(__map_value_compare&__y)
|
||||
_NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
|
||||
{
|
||||
@@ -489,13 +489,13 @@ public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
|
||||
operator () ( const _K2& __x, const _CP& __y ) const
|
||||
{return static_cast<const _Compare&>(*this) (__x, __y.__cc.first);}
|
||||
{return static_cast<const _Compare&>(*this) (__x, __y.__get_value().first);}
|
||||
|
||||
template <typename _K2>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
|
||||
operator () (const _CP& __x, const _K2& __y) const
|
||||
{return static_cast<const _Compare&>(*this) (__x.__cc.first, __y);}
|
||||
{return static_cast<const _Compare&>(*this) (__x.__get_value().first, __y);}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -518,13 +518,13 @@ public:
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _CP& __x, const _CP& __y) const
|
||||
{return comp(__x.__cc.first, __y.__cc.first);}
|
||||
{return comp(__x.__get_value().first, __y.__get_value().first);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _CP& __x, const _Key& __y) const
|
||||
{return comp(__x.__cc.first, __y);}
|
||||
{return comp(__x.__get_value().first, __y);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _Key& __x, const _CP& __y) const
|
||||
{return comp(__x, __y.__cc.first);}
|
||||
{return comp(__x, __y.__get_value().first);}
|
||||
void swap(__map_value_compare&__y)
|
||||
_NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
|
||||
{
|
||||
@@ -537,13 +537,13 @@ public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
|
||||
operator () ( const _K2& __x, const _CP& __y ) const
|
||||
{return comp (__x, __y.__cc.first);}
|
||||
{return comp (__x, __y.__get_value().first);}
|
||||
|
||||
template <typename _K2>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
|
||||
operator () (const _CP& __x, const _K2& __y) const
|
||||
{return comp (__x.__cc.first, __y);}
|
||||
{return comp (__x.__get_value().first, __y);}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -597,9 +597,9 @@ public:
|
||||
void operator()(pointer __p) _NOEXCEPT
|
||||
{
|
||||
if (__second_constructed)
|
||||
__alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));
|
||||
__alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().second));
|
||||
if (__first_constructed)
|
||||
__alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));
|
||||
__alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().first));
|
||||
if (__p)
|
||||
__alloc_traits::deallocate(__na_, __p, 1);
|
||||
}
|
||||
@@ -614,23 +614,67 @@ template <class _TreeIterator> class __map_const_iterator;
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
template <class _Key, class _Tp>
|
||||
union __value_type
|
||||
struct __value_type
|
||||
{
|
||||
typedef _Key key_type;
|
||||
typedef _Tp mapped_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
typedef pair<key_type, mapped_type> __nc_value_type;
|
||||
typedef pair<key_type&, mapped_type&> __nc_ref_pair_type;
|
||||
typedef pair<key_type&&, mapped_type&&> __nc_rref_pair_type;
|
||||
|
||||
private:
|
||||
value_type __cc;
|
||||
__nc_value_type __nc;
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
value_type& __get_value()
|
||||
{
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
return *_VSTD::launder(_VSTD::addressof(__cc));
|
||||
#else
|
||||
return __cc;
|
||||
#endif
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const value_type& __get_value() const
|
||||
{
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
return *_VSTD::launder(_VSTD::addressof(__cc));
|
||||
#else
|
||||
return __cc;
|
||||
#endif
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__nc_ref_pair_type __ref()
|
||||
{
|
||||
value_type& __v = __get_value();
|
||||
return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second);
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__nc_rref_pair_type __move()
|
||||
{
|
||||
value_type& __v = __get_value();
|
||||
return __nc_rref_pair_type(
|
||||
_VSTD::move(const_cast<key_type&>(__v.first)),
|
||||
_VSTD::move(__v.second));
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__value_type& operator=(const __value_type& __v)
|
||||
{__nc = __v.__cc; return *this;}
|
||||
{
|
||||
__ref() = __v.__get_value();
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__value_type& operator=(__value_type&& __v)
|
||||
{__nc = _VSTD::move(__v.__nc); return *this;}
|
||||
{
|
||||
__ref() = __v.__move();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class _ValueTp,
|
||||
class = typename enable_if<
|
||||
@@ -638,8 +682,10 @@ union __value_type
|
||||
>::type
|
||||
>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__value_type& operator=(_ValueTp&& __v) {
|
||||
__nc = _VSTD::forward<_ValueTp>(__v); return *this;
|
||||
__value_type& operator=(_ValueTp&& __v)
|
||||
{
|
||||
__ref() = _VSTD::forward<_ValueTp>(__v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -658,8 +704,15 @@ struct __value_type
|
||||
typedef _Tp mapped_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
|
||||
private:
|
||||
value_type __cc;
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
value_type& __get_value() { return __cc; }
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const value_type& __get_value() const { return __cc; }
|
||||
|
||||
private:
|
||||
__value_type();
|
||||
__value_type(__value_type const&);
|
||||
@@ -701,9 +754,9 @@ public:
|
||||
__map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
reference operator*() const {return __i_->__cc;}
|
||||
reference operator*() const {return __i_->__get_value();}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
|
||||
pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__map_iterator& operator++() {++__i_; return *this;}
|
||||
@@ -764,9 +817,9 @@ public:
|
||||
: __i_(__i.__i_) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
reference operator*() const {return __i_->__cc;}
|
||||
reference operator*() const {return __i_->__get_value();}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
|
||||
pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__map_const_iterator& operator++() {++__i_; return *this;}
|
||||
@@ -809,7 +862,6 @@ public:
|
||||
typedef _Key key_type;
|
||||
typedef _Tp mapped_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
typedef pair<key_type, mapped_type> __nc_value_type;
|
||||
typedef _Compare key_compare;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef value_type& reference;
|
||||
@@ -1228,7 +1280,7 @@ public:
|
||||
template <typename _K2>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
|
||||
count(const _K2& __k) const {return __tree_.__count_unique(__k);}
|
||||
count(const _K2& __k) const {return __tree_.__count_multi(__k);}
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
iterator lower_bound(const key_type& __k)
|
||||
@@ -1275,11 +1327,11 @@ public:
|
||||
template <typename _K2>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
|
||||
equal_range(const _K2& __k) {return __tree_.__equal_range_unique(__k);}
|
||||
equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
|
||||
template <typename _K2>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
|
||||
equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}
|
||||
equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -1308,7 +1360,7 @@ map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
|
||||
const_iterator __e = cend();
|
||||
while (!__m.empty())
|
||||
__tree_.__insert_unique(__e.__i_,
|
||||
_VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc));
|
||||
__m.__tree_.remove(__m.begin().__i_)->__value_.__move());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1319,7 +1371,7 @@ map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
|
||||
return __tree_.__emplace_unique_key_args(__k,
|
||||
_VSTD::piecewise_construct,
|
||||
_VSTD::forward_as_tuple(__k),
|
||||
_VSTD::forward_as_tuple()).first->__cc.second;
|
||||
_VSTD::forward_as_tuple()).first->__get_value().second;
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _Compare, class _Allocator>
|
||||
@@ -1329,7 +1381,7 @@ map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k)
|
||||
return __tree_.__emplace_unique_key_args(__k,
|
||||
_VSTD::piecewise_construct,
|
||||
_VSTD::forward_as_tuple(_VSTD::move(__k)),
|
||||
_VSTD::forward_as_tuple()).first->__cc.second;
|
||||
_VSTD::forward_as_tuple()).first->__get_value().second;
|
||||
}
|
||||
|
||||
#else // _LIBCPP_CXX03_LANG
|
||||
@@ -1340,9 +1392,9 @@ map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type&
|
||||
{
|
||||
__node_allocator& __na = __tree_.__node_alloc();
|
||||
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
|
||||
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);
|
||||
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().first), __k);
|
||||
__h.get_deleter().__first_constructed = true;
|
||||
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
|
||||
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().second));
|
||||
__h.get_deleter().__second_constructed = true;
|
||||
return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03
|
||||
}
|
||||
@@ -1360,7 +1412,7 @@ map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
|
||||
__tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
|
||||
__r = __h.release();
|
||||
}
|
||||
return __r->__value_.__cc.second;
|
||||
return __r->__value_.__get_value().second;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
@@ -1375,7 +1427,7 @@ map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k)
|
||||
if (__child == nullptr)
|
||||
throw out_of_range("map::at: key not found");
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
return static_cast<__node_pointer>(__child)->__value_.__cc.second;
|
||||
return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _Compare, class _Allocator>
|
||||
@@ -1388,7 +1440,7 @@ map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const
|
||||
if (__child == nullptr)
|
||||
throw out_of_range("map::at: key not found");
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
return static_cast<__node_pointer>(__child)->__value_.__cc.second;
|
||||
return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
|
||||
}
|
||||
|
||||
|
||||
@@ -1465,7 +1517,6 @@ public:
|
||||
typedef _Key key_type;
|
||||
typedef _Tp mapped_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
typedef pair<key_type, mapped_type> __nc_value_type;
|
||||
typedef _Compare key_compare;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef value_type& reference;
|
||||
@@ -1852,7 +1903,7 @@ multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const alloca
|
||||
const_iterator __e = cend();
|
||||
while (!__m.empty())
|
||||
__tree_.__insert_multi(__e.__i_,
|
||||
_VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc));
|
||||
_VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__move()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -8,16 +8,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// This include lives outside the header guard in order to support an MSVC
|
||||
// extension which allows users to do:
|
||||
//
|
||||
// #define _USE_MATH_DEFINES
|
||||
// #include <math.h>
|
||||
//
|
||||
// and receive the definitions of mathematical constants, even if <math.h>
|
||||
// has previously been included.
|
||||
#include_next <math.h>
|
||||
|
||||
#ifndef _LIBCPP_MATH_H
|
||||
#define _LIBCPP_MATH_H
|
||||
|
||||
@@ -308,6 +298,8 @@ long double truncl(long double x);
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#include_next <math.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
// We support including .h headers inside 'extern "C"' contexts, so switch
|
||||
@@ -491,6 +483,20 @@ typename std::enable_if<
|
||||
isinf(_A1) _NOEXCEPT
|
||||
{ return false; }
|
||||
|
||||
#ifdef _LIBCPP_PREFERRED_OVERLOAD
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
isinf(float __lcpp_x) _NOEXCEPT { return __libcpp_isinf(__lcpp_x); }
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD
|
||||
bool
|
||||
isinf(double __lcpp_x) _NOEXCEPT { return __libcpp_isinf(__lcpp_x); }
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
isinf(long double __lcpp_x) _NOEXCEPT { return __libcpp_isinf(__lcpp_x); }
|
||||
#endif
|
||||
|
||||
#endif // isinf
|
||||
|
||||
// isnan
|
||||
@@ -521,6 +527,20 @@ typename std::enable_if<std::is_integral<_A1>::value, bool>::type
|
||||
isnan(_A1) _NOEXCEPT
|
||||
{ return false; }
|
||||
|
||||
#ifdef _LIBCPP_PREFERRED_OVERLOAD
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
isnan(float __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); }
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD
|
||||
bool
|
||||
isnan(double __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); }
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
isnan(long double __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); }
|
||||
#endif
|
||||
|
||||
#endif // isnan
|
||||
|
||||
// isnormal
|
||||
@@ -1494,4 +1514,18 @@ trunc(_A1 __lcpp_x) _NOEXCEPT {return ::trunc((double)__lcpp_x);}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#else // _LIBCPP_MATH_H
|
||||
|
||||
// This include lives outside the header guard in order to support an MSVC
|
||||
// extension which allows users to do:
|
||||
//
|
||||
// #define _USE_MATH_DEFINES
|
||||
// #include <math.h>
|
||||
//
|
||||
// and receive the definitions of mathematical constants, even if <math.h>
|
||||
// has previously been included.
|
||||
#if defined(_LIBCPP_MSVCRT) && defined(_USE_MATH_DEFINES)
|
||||
#include_next <math.h>
|
||||
#endif
|
||||
|
||||
#endif // _LIBCPP_MATH_H
|
||||
|
||||
@@ -126,9 +126,10 @@ public:
|
||||
|
||||
template <class U> struct rebind {typedef allocator<U> other;};
|
||||
|
||||
allocator() noexcept;
|
||||
allocator(const allocator&) noexcept;
|
||||
template <class U> allocator(const allocator<U>&) noexcept;
|
||||
constexpr allocator() noexcept; // constexpr in C++20
|
||||
constexpr allocator(const allocator&) noexcept; // constexpr in C++20
|
||||
template <class U>
|
||||
constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
|
||||
~allocator();
|
||||
pointer address(reference x) const noexcept;
|
||||
const_pointer address(const_reference x) const noexcept;
|
||||
@@ -1778,8 +1779,13 @@ public:
|
||||
|
||||
template <class _Up> struct rebind {typedef allocator<_Up> other;};
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}
|
||||
template <class _Up> _LIBCPP_INLINE_VISIBILITY allocator(const allocator<_Up>&) _NOEXCEPT {}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
allocator() _NOEXCEPT {}
|
||||
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
allocator(const allocator<_Up>&) _NOEXCEPT {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT
|
||||
{return _VSTD::addressof(__x);}
|
||||
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
|
||||
@@ -1790,10 +1796,10 @@ public:
|
||||
if (__n > max_size())
|
||||
__throw_length_error("allocator<T>::allocate(size_t n)"
|
||||
" 'n' exceeds maximum supported size");
|
||||
return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));
|
||||
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
|
||||
{_VSTD::__libcpp_deallocate((void*)__p);}
|
||||
{_VSTD::__libcpp_deallocate((void*)__p, __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)
|
||||
@@ -1877,8 +1883,13 @@ public:
|
||||
|
||||
template <class _Up> struct rebind {typedef allocator<_Up> other;};
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}
|
||||
template <class _Up> _LIBCPP_INLINE_VISIBILITY allocator(const allocator<_Up>&) _NOEXCEPT {}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
allocator() _NOEXCEPT {}
|
||||
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
allocator(const allocator<_Up>&) _NOEXCEPT {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
|
||||
{return _VSTD::addressof(__x);}
|
||||
_LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
|
||||
@@ -1886,10 +1897,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::__allocate(__n * sizeof(_Tp)));
|
||||
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
|
||||
{_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p));}
|
||||
{_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __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)
|
||||
@@ -2005,12 +2016,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
|
||||
while (__n > 0)
|
||||
{
|
||||
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
|
||||
#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
|
||||
if (std::alignment_of<_Tp>::value > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
|
||||
#else
|
||||
if (std::alignment_of<_Tp>::value >
|
||||
std::alignment_of<std::max_align_t>::value)
|
||||
#endif
|
||||
if (__is_overaligned_for_new(__alignof(_Tp)))
|
||||
{
|
||||
std::align_val_t __al =
|
||||
std::align_val_t(std::alignment_of<_Tp>::value);
|
||||
@@ -2021,12 +2027,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
|
||||
__n * sizeof(_Tp), nothrow));
|
||||
}
|
||||
#else
|
||||
#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
|
||||
if (std::alignment_of<_Tp>::value > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
|
||||
#else
|
||||
if (std::alignment_of<_Tp>::value >
|
||||
std::alignment_of<std::max_align_t>::value)
|
||||
#endif
|
||||
if (__is_overaligned_for_new(__alignof(_Tp)))
|
||||
{
|
||||
// Since aligned operator new is unavailable, return an empty
|
||||
// buffer rather than one with invalid alignment.
|
||||
@@ -2050,20 +2051,7 @@ template <class _Tp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void return_temporary_buffer(_Tp* __p) _NOEXCEPT
|
||||
{
|
||||
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
|
||||
#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
|
||||
if (std::alignment_of<_Tp>::value > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
|
||||
#else
|
||||
if (std::alignment_of<_Tp>::value >
|
||||
std::alignment_of<std::max_align_t>::value)
|
||||
#endif
|
||||
{
|
||||
std::align_val_t __al = std::align_val_t(std::alignment_of<_Tp>::value);
|
||||
::operator delete(__p, __al);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
::operator delete(__p);
|
||||
_VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp));
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
|
||||
@@ -4805,8 +4793,13 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
|
||||
{
|
||||
#if _LIBCPP_STD_VER <= 11
|
||||
typedef typename common_type<_Tp*, _Up*>::type _Vp;
|
||||
return less<_Vp>()(__x.get(), __y.get());
|
||||
#else
|
||||
return less<>()(__x.get(), __y.get());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template<class _Tp, class _Up>
|
||||
|
||||
@@ -243,6 +243,10 @@ module std [system] {
|
||||
header "codecvt"
|
||||
export *
|
||||
}
|
||||
module compare {
|
||||
header "compare"
|
||||
export *
|
||||
}
|
||||
module complex {
|
||||
header "complex"
|
||||
export *
|
||||
@@ -470,6 +474,10 @@ module std [system] {
|
||||
export initializer_list
|
||||
export *
|
||||
}
|
||||
module version {
|
||||
header "version"
|
||||
export *
|
||||
}
|
||||
|
||||
// FIXME: These should be private.
|
||||
module __bit_reference { header "__bit_reference" export * }
|
||||
@@ -542,6 +550,10 @@ module std [system] {
|
||||
header "experimental/regex"
|
||||
export *
|
||||
}
|
||||
module simd {
|
||||
header "experimental/simd"
|
||||
export *
|
||||
}
|
||||
module set {
|
||||
header "experimental/set"
|
||||
export *
|
||||
|
||||
53
include/new
53
include/new
@@ -89,6 +89,7 @@ void operator delete[](void* ptr, void*) noexcept;
|
||||
|
||||
#include <__config>
|
||||
#include <exception>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
#ifdef _LIBCPP_NO_EXCEPTIONS
|
||||
#include <cstdlib>
|
||||
@@ -113,6 +114,14 @@ void operator delete[](void* ptr, void*) noexcept;
|
||||
# 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
|
||||
#endif
|
||||
|
||||
namespace std // purposefully not using versioning namespace
|
||||
{
|
||||
|
||||
@@ -160,6 +169,7 @@ public:
|
||||
|
||||
#endif // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
|
||||
|
||||
#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME)
|
||||
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || _LIBCPP_STD_VER > 14
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
enum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
|
||||
@@ -167,6 +177,7 @@ enum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
|
||||
enum align_val_t { __zero = 0, __max = (size_t)-1 };
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} // std
|
||||
|
||||
@@ -221,7 +232,27 @@ inline _LIBCPP_INLINE_VISIBILITY void operator delete[](void*, void*) _NOEXCEPT
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY void *__allocate(size_t __size) {
|
||||
_LIBCPP_CONSTEXPR inline _LIBCPP_INLINE_VISIBILITY bool __is_overaligned_for_new(size_t __align) _NOEXCEPT {
|
||||
#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
|
||||
return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__;
|
||||
#else
|
||||
return __align > alignment_of<max_align_t>::value;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, 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 new(__size, __align_val);
|
||||
# else
|
||||
return __builtin_operator_new(__size, __align_val);
|
||||
# endif
|
||||
}
|
||||
#else
|
||||
((void)__align);
|
||||
#endif
|
||||
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
|
||||
return ::operator new(__size);
|
||||
#else
|
||||
@@ -229,11 +260,23 @@ inline _LIBCPP_INLINE_VISIBILITY void *__allocate(size_t __size) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void *__ptr) {
|
||||
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
|
||||
::operator delete(__ptr);
|
||||
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
|
||||
}
|
||||
#else
|
||||
__builtin_operator_delete(__ptr);
|
||||
((void)__align);
|
||||
#endif
|
||||
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
|
||||
return ::operator delete(__ptr);
|
||||
#else
|
||||
return __builtin_operator_delete(__ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,10 @@ namespace std {
|
||||
private:
|
||||
T *val; // exposition only
|
||||
};
|
||||
|
||||
template<class T>
|
||||
optional(T) -> optional<T>;
|
||||
|
||||
} // namespace std
|
||||
|
||||
*/
|
||||
@@ -1003,6 +1007,11 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template<class T>
|
||||
optional(T) -> optional<T>;
|
||||
#endif
|
||||
|
||||
// Comparisons between optionals
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr
|
||||
|
||||
@@ -1071,19 +1071,17 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p)
|
||||
return __os << __p.get();
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DECLTYPE
|
||||
template<class _CharT, class _Traits, class _Yp, class _Dp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_same<void, typename __void_t<decltype(declval<basic_ostream<_CharT, _Traits>&>() << declval<_Yp>())>::type>::value,
|
||||
is_same<void, typename __void_t<decltype((declval<basic_ostream<_CharT, _Traits>&>() << declval<typename unique_ptr<_Yp, _Dp>::pointer>()))>::type>::value,
|
||||
basic_ostream<_CharT, _Traits>&
|
||||
>::type
|
||||
operator<<(basic_ostream<_CharT, _Traits>& __os, unique_ptr<_Yp, _Dp> const& __p)
|
||||
{
|
||||
return __os << __p.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class _CharT, class _Traits, size_t _Size>
|
||||
basic_ostream<_CharT, _Traits>&
|
||||
|
||||
@@ -69,6 +69,12 @@ public:
|
||||
void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
|
||||
};
|
||||
|
||||
template<class Container>
|
||||
queue(Container) -> queue<typename Container::value_type, Container>; // C++17
|
||||
|
||||
template<class Container, class Allocator>
|
||||
queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17
|
||||
|
||||
template <class T, class Container>
|
||||
bool operator==(const queue<T, Container>& x,const queue<T, Container>& y);
|
||||
|
||||
@@ -157,6 +163,20 @@ public:
|
||||
is_nothrow_swappable_v<Comp>)
|
||||
};
|
||||
|
||||
template <class Compare, class Container>
|
||||
priority_queue(Compare, Container)
|
||||
-> priority_queue<typename Container::value_type, Container, Compare>; // C++17
|
||||
|
||||
template<class InputIterator,
|
||||
class Compare = less<typename iterator_traits<InputIterator>::value_type>,
|
||||
class Container = vector<typename iterator_traits<InputIterator>::value_type>>
|
||||
priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
|
||||
-> priority_queue<typename iterator_traits<InputIterator>::value_type, Container, Compare>; // C++17
|
||||
|
||||
template<class Compare, class Container, class Allocator>
|
||||
priority_queue(Compare, Container, Allocator)
|
||||
-> priority_queue<typename Container::value_type, Container, Compare>; // C++17
|
||||
|
||||
template <class T, class Container, class Compare>
|
||||
void swap(priority_queue<T, Container, Compare>& x,
|
||||
priority_queue<T, Container, Compare>& y)
|
||||
@@ -321,6 +341,22 @@ public:
|
||||
operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template<class _Container,
|
||||
class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type
|
||||
>
|
||||
queue(_Container)
|
||||
-> queue<typename _Container::value_type, _Container>;
|
||||
|
||||
template<class _Container,
|
||||
class _Alloc,
|
||||
class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type,
|
||||
class = typename enable_if< __is_allocator<_Alloc>::value, nullptr_t>::type
|
||||
>
|
||||
queue(_Container, _Alloc)
|
||||
-> queue<typename _Container::value_type, _Container>;
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Container>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
@@ -515,6 +551,36 @@ public:
|
||||
__is_nothrow_swappable<value_compare>::value);
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template <class _Compare,
|
||||
class _Container,
|
||||
class = typename enable_if<!__is_allocator<_Compare>::value, nullptr_t>::type,
|
||||
class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type
|
||||
>
|
||||
priority_queue(_Compare, _Container)
|
||||
-> priority_queue<typename _Container::value_type, _Container, _Compare>;
|
||||
|
||||
template<class _InputIterator,
|
||||
class _Compare = less<typename iterator_traits<_InputIterator>::value_type>,
|
||||
class _Container = vector<typename iterator_traits<_InputIterator>::value_type>,
|
||||
class = typename enable_if< __is_input_iterator<_InputIterator>::value, nullptr_t>::type,
|
||||
class = typename enable_if<!__is_allocator<_Compare>::value, nullptr_t>::type,
|
||||
class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type
|
||||
>
|
||||
priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(), _Container = _Container())
|
||||
-> priority_queue<typename iterator_traits<_InputIterator>::value_type, _Container, _Compare>;
|
||||
|
||||
template<class _Compare,
|
||||
class _Container,
|
||||
class _Alloc,
|
||||
class = typename enable_if<!__is_allocator<_Compare>::value, nullptr_t>::type,
|
||||
class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type,
|
||||
class = typename enable_if< __is_allocator<_Alloc>::value, nullptr_t>::type
|
||||
>
|
||||
priority_queue(_Compare, _Container, _Alloc)
|
||||
-> priority_queue<typename _Container::value_type, _Container, _Compare>;
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Container, class _Compare>
|
||||
inline
|
||||
priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp,
|
||||
|
||||
@@ -192,6 +192,11 @@ public:
|
||||
void swap(basic_regex&);
|
||||
};
|
||||
|
||||
template<class ForwardIterator>
|
||||
basic_regex(ForwardIterator, ForwardIterator,
|
||||
regex_constants::syntax_option_type = regex_constants::ECMAScript)
|
||||
-> basic_regex<typename iterator_traits<ForwardIterator>::value_type>; // C++17
|
||||
|
||||
typedef basic_regex<char> regex;
|
||||
typedef basic_regex<wchar_t> wregex;
|
||||
|
||||
@@ -2928,6 +2933,15 @@ private:
|
||||
template <class, class> friend class __lookahead;
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template <class _ForwardIterator,
|
||||
class = typename enable_if<__is_forward_iterator<_ForwardIterator>::value, nullptr_t>::type
|
||||
>
|
||||
basic_regex(_ForwardIterator, _ForwardIterator,
|
||||
regex_constants::syntax_option_type = regex_constants::ECMAScript)
|
||||
-> basic_regex<typename iterator_traits<_ForwardIterator>::value_type>;
|
||||
#endif
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::icase;
|
||||
template <class _CharT, class _Traits>
|
||||
|
||||
@@ -668,7 +668,7 @@ public:
|
||||
template <typename _K2>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
|
||||
count(const _K2& __k) const {return __tree_.__count_unique(__k);}
|
||||
count(const _K2& __k) const {return __tree_.__count_multi(__k);}
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
iterator lower_bound(const key_type& __k)
|
||||
@@ -715,11 +715,11 @@ public:
|
||||
template <typename _K2>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
|
||||
equal_range(const _K2& __k) {return __tree_.__equal_range_unique(__k);}
|
||||
equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
|
||||
template <typename _K2>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
|
||||
equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}
|
||||
equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -61,6 +61,12 @@ public:
|
||||
void swap(stack& c) noexcept(is_nothrow_swappable_v<Container>)
|
||||
};
|
||||
|
||||
template<class Container>
|
||||
stack(Container) -> stack<typename Container::value_type, Container>; // C++17
|
||||
|
||||
template<class Container, class Allocator>
|
||||
stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17
|
||||
|
||||
template <class T, class Container>
|
||||
bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
|
||||
template <class T, class Container>
|
||||
@@ -229,6 +235,22 @@ public:
|
||||
operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template<class _Container,
|
||||
class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type
|
||||
>
|
||||
stack(_Container)
|
||||
-> stack<typename _Container::value_type, _Container>;
|
||||
|
||||
template<class _Container,
|
||||
class _Alloc,
|
||||
class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type,
|
||||
class = typename enable_if< __is_allocator<_Alloc>::value, nullptr_t>::type
|
||||
>
|
||||
stack(_Container, _Alloc)
|
||||
-> stack<typename _Container::value_type, _Container>;
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Container>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
|
||||
@@ -311,6 +311,13 @@ public:
|
||||
bool __invariants() const;
|
||||
};
|
||||
|
||||
template<class InputIterator,
|
||||
class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
|
||||
basic_string(InputIterator, InputIterator, Allocator = Allocator())
|
||||
-> basic_string<typename iterator_traits<InputIterator>::value_type,
|
||||
char_traits<typename iterator_traits<InputIterator>::value_type>,
|
||||
Allocator>; // C++17
|
||||
|
||||
template<class charT, class traits, class Allocator>
|
||||
basic_string<charT, traits, Allocator>
|
||||
operator+(const basic_string<charT, traits, Allocator>& lhs,
|
||||
@@ -651,10 +658,12 @@ public:
|
||||
typedef typename __alloc_traits::pointer pointer;
|
||||
typedef typename __alloc_traits::const_pointer const_pointer;
|
||||
|
||||
static_assert(is_trivial<value_type>::value, "Character type of basic_string must be trivial");
|
||||
static_assert((is_same<_CharT, typename traits_type::char_type>::value),
|
||||
static_assert((!is_array<value_type>::value), "Character type of basic_string must not be an array");
|
||||
static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string must be standard-layout");
|
||||
static_assert(( is_trivial<value_type>::value), "Character type of basic_string must be trivial");
|
||||
static_assert(( is_same<_CharT, typename traits_type::char_type>::value),
|
||||
"traits_type::char_type must be the same type as CharT");
|
||||
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
|
||||
static_assert(( is_same<typename allocator_type::value_type, value_type>::value),
|
||||
"Allocator::value_type must be same type as value_type");
|
||||
#if defined(_LIBCPP_RAW_ITERATORS)
|
||||
typedef pointer iterator;
|
||||
@@ -1250,6 +1259,8 @@ public:
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY bool __invariants() const;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY void __clear_and_shrink() _NOEXCEPT;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool __is_long() const _NOEXCEPT
|
||||
{return bool(__r_.first().__s.__size_ & __short_mask);}
|
||||
@@ -1419,16 +1430,14 @@ private:
|
||||
{
|
||||
if (!__str.__is_long())
|
||||
{
|
||||
clear();
|
||||
shrink_to_fit();
|
||||
__clear_and_shrink();
|
||||
__alloc() = __str.__alloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
allocator_type __a = __str.__alloc();
|
||||
pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap());
|
||||
clear();
|
||||
shrink_to_fit();
|
||||
__clear_and_shrink();
|
||||
__alloc() = _VSTD::move(__a);
|
||||
__set_long_pointer(__p);
|
||||
__set_long_cap(__str.__get_long_cap());
|
||||
@@ -1485,6 +1494,18 @@ private:
|
||||
friend basic_string operator+<>(const basic_string&, value_type);
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template<class _InputIterator,
|
||||
class _CharT = typename iterator_traits<_InputIterator>::value_type,
|
||||
class _Allocator = allocator<_CharT>,
|
||||
class = typename enable_if<__is_input_iterator<_InputIterator>::value, void>::type,
|
||||
class = typename enable_if<__is_allocator<_Allocator>::value, void>::type
|
||||
>
|
||||
basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
|
||||
-> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
|
||||
#endif
|
||||
|
||||
|
||||
template <class _CharT, class _Traits, class _Allocator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
@@ -2106,8 +2127,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
|
||||
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
||||
#endif
|
||||
{
|
||||
clear();
|
||||
shrink_to_fit();
|
||||
__clear_and_shrink();
|
||||
__r_.first() = __str.__r_.first();
|
||||
__move_assign_alloc(__str);
|
||||
__str.__zero();
|
||||
@@ -3560,6 +3580,22 @@ basic_string<_CharT, _Traits, _Allocator>::__invariants() const
|
||||
return true;
|
||||
}
|
||||
|
||||
// __clear_and_shrink
|
||||
|
||||
template<class _CharT, class _Traits, class _Allocator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
|
||||
{
|
||||
clear();
|
||||
if(__is_long())
|
||||
{
|
||||
__alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
|
||||
__set_long_cap(0);
|
||||
__set_short_size(0);
|
||||
}
|
||||
}
|
||||
|
||||
// operator==
|
||||
|
||||
template<class _CharT, class _Traits, class _Allocator>
|
||||
|
||||
@@ -208,7 +208,9 @@ public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
|
||||
|
||||
static_assert(is_trivial<value_type>::value, "Character type of basic_string_view must be trivial");
|
||||
static_assert((!is_array<value_type>::value), "Character type of basic_string_view must not be an array");
|
||||
static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string_view must be standard-layout");
|
||||
static_assert(( is_trivial<value_type>::value), "Character type of basic_string_view must be trivial");
|
||||
static_assert((is_same<_CharT, typename traits_type::char_type>::value),
|
||||
"traits_type::char_type must be the same type as CharT");
|
||||
|
||||
|
||||
@@ -24,7 +24,45 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
#include <android/api-level.h>
|
||||
#include <android/ndk-version.h>
|
||||
#include <support/xlocale/__posix_l_fallback.h>
|
||||
// In NDK versions later than 16, locale-aware functions are provided by
|
||||
// legacy_stdlib_inlines.h
|
||||
#if __NDK_MAJOR__ <= 16
|
||||
#if __ANDROID_API__ < 21
|
||||
#include <support/xlocale/__strtonum_fallback.h>
|
||||
#elif __ANDROID_API__ < 26
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE float strtof_l(const char* __nptr, char** __endptr,
|
||||
locale_t) {
|
||||
return ::strtof(__nptr, __endptr);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE double strtod_l(const char* __nptr,
|
||||
char** __endptr, locale_t) {
|
||||
return ::strtod(__nptr, __endptr);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE long strtol_l(const char* __nptr, char** __endptr,
|
||||
int __base, locale_t) {
|
||||
return ::strtol(__nptr, __endptr, __base);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __ANDROID_API__ < 26
|
||||
|
||||
#endif // __NDK_MAJOR__ <= 16
|
||||
#endif // defined(__ANDROID__)
|
||||
|
||||
#endif // defined(__BIONIC__)
|
||||
#endif // _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H
|
||||
|
||||
@@ -14,16 +14,24 @@
|
||||
/*
|
||||
tgmath.h synopsis
|
||||
|
||||
#include <complex.h>
|
||||
#include <math.h>
|
||||
#include <ctgmath>
|
||||
|
||||
*/
|
||||
|
||||
#include <complex.h>
|
||||
#include <math.h>
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <ctgmath>
|
||||
|
||||
#else // __cplusplus
|
||||
|
||||
#include_next <tgmath.h>
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // _LIBCPP_TGMATH_H
|
||||
|
||||
@@ -298,7 +298,7 @@ public:
|
||||
template <class _Fp, class ..._Args,
|
||||
class = typename enable_if
|
||||
<
|
||||
!is_same<typename decay<_Fp>::type, thread>::value
|
||||
!is_same<typename __uncvref<_Fp>::type, thread>::value
|
||||
>::type
|
||||
>
|
||||
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||
|
||||
@@ -733,6 +733,12 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v
|
||||
// is_floating_point
|
||||
|
||||
template <class _Tp> struct __libcpp_is_floating_point : public false_type {};
|
||||
#ifdef __clang__
|
||||
template <> struct __libcpp_is_floating_point<__fp16> : public true_type {};
|
||||
#endif
|
||||
#ifdef __FLT16_MANT_DIG__
|
||||
template <> struct __libcpp_is_floating_point<_Float16> : public true_type {};
|
||||
#endif
|
||||
template <> struct __libcpp_is_floating_point<float> : public true_type {};
|
||||
template <> struct __libcpp_is_floating_point<double> : public true_type {};
|
||||
template <> struct __libcpp_is_floating_point<long double> : public true_type {};
|
||||
@@ -4168,147 +4174,6 @@ template <class _Tp> struct __is_reference_wrapper
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
// Check for complete types
|
||||
|
||||
template <class ..._Tp> struct __check_complete;
|
||||
|
||||
template <>
|
||||
struct __check_complete<>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Hp, class _T0, class ..._Tp>
|
||||
struct __check_complete<_Hp, _T0, _Tp...>
|
||||
: private __check_complete<_Hp>,
|
||||
private __check_complete<_T0, _Tp...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Hp>
|
||||
struct __check_complete<_Hp, _Hp>
|
||||
: private __check_complete<_Hp>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __check_complete<_Tp>
|
||||
{
|
||||
static_assert(sizeof(_Tp) > 0, "Type must be complete.");
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __check_complete<_Tp&>
|
||||
: private __check_complete<_Tp>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __check_complete<_Tp&&>
|
||||
: private __check_complete<_Tp>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class ..._Param>
|
||||
struct __check_complete<_Rp (*)(_Param...)>
|
||||
: private __check_complete<_Rp>
|
||||
{
|
||||
};
|
||||
|
||||
template <class ..._Param>
|
||||
struct __check_complete<void (*)(_Param...)>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class ..._Param>
|
||||
struct __check_complete<_Rp (_Param...)>
|
||||
: private __check_complete<_Rp>
|
||||
{
|
||||
};
|
||||
|
||||
template <class ..._Param>
|
||||
struct __check_complete<void (_Param...)>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...)>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) const>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) volatile>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) const volatile>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) &>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) const&>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) volatile&>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) &&>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) const&&>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) volatile&&>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class, class ..._Param>
|
||||
struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&&>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _Rp, class _Class>
|
||||
struct __check_complete<_Rp _Class::*>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <class _Fp, class _A0,
|
||||
class _DecayFp = typename decay<_Fp>::type,
|
||||
class _DecayA0 = typename decay<_A0>::type,
|
||||
@@ -4491,8 +4356,9 @@ _LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)
|
||||
|
||||
template <class _Ret, class _Fp, class ..._Args>
|
||||
struct __invokable_r
|
||||
: private __check_complete<_Fp>
|
||||
{
|
||||
// FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
|
||||
// or incomplete array types as required by the standard.
|
||||
using _Result = decltype(
|
||||
_VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...));
|
||||
|
||||
|
||||
@@ -396,7 +396,7 @@ public:
|
||||
const _Hash& hash_function() const _NOEXCEPT {return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(const _Cp& __x) const
|
||||
{return static_cast<const _Hash&>(*this)(__x.__cc.first);}
|
||||
{return static_cast<const _Hash&>(*this)(__x.__get_value().first);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(const _Key& __x) const
|
||||
{return static_cast<const _Hash&>(*this)(__x);}
|
||||
@@ -425,7 +425,7 @@ public:
|
||||
const _Hash& hash_function() const _NOEXCEPT {return __hash_;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(const _Cp& __x) const
|
||||
{return __hash_(__x.__cc.first);}
|
||||
{return __hash_(__x.__get_value().first);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(const _Key& __x) const
|
||||
{return __hash_(__x);}
|
||||
@@ -464,13 +464,13 @@ public:
|
||||
const _Pred& key_eq() const _NOEXCEPT {return *this;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _Cp& __x, const _Cp& __y) const
|
||||
{return static_cast<const _Pred&>(*this)(__x.__cc.first, __y.__cc.first);}
|
||||
{return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y.__get_value().first);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _Cp& __x, const _Key& __y) const
|
||||
{return static_cast<const _Pred&>(*this)(__x.__cc.first, __y);}
|
||||
{return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _Key& __x, const _Cp& __y) const
|
||||
{return static_cast<const _Pred&>(*this)(__x, __y.__cc.first);}
|
||||
{return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);}
|
||||
void swap(__unordered_map_equal&__y)
|
||||
_NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)
|
||||
{
|
||||
@@ -496,13 +496,13 @@ public:
|
||||
const _Pred& key_eq() const _NOEXCEPT {return __pred_;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _Cp& __x, const _Cp& __y) const
|
||||
{return __pred_(__x.__cc.first, __y.__cc.first);}
|
||||
{return __pred_(__x.__get_value().first, __y.__get_value().first);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _Cp& __x, const _Key& __y) const
|
||||
{return __pred_(__x.__cc.first, __y);}
|
||||
{return __pred_(__x.__get_value().first, __y);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator()(const _Key& __x, const _Cp& __y) const
|
||||
{return __pred_(__x, __y.__cc.first);}
|
||||
{return __pred_(__x, __y.__get_value().first);}
|
||||
void swap(__unordered_map_equal&__y)
|
||||
_NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)
|
||||
{
|
||||
@@ -572,9 +572,9 @@ public:
|
||||
void operator()(pointer __p) _NOEXCEPT
|
||||
{
|
||||
if (__second_constructed)
|
||||
__alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));
|
||||
__alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().second));
|
||||
if (__first_constructed)
|
||||
__alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));
|
||||
__alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().first));
|
||||
if (__p)
|
||||
__alloc_traits::deallocate(__na_, __p, 1);
|
||||
}
|
||||
@@ -582,23 +582,67 @@ public:
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
template <class _Key, class _Tp>
|
||||
union __hash_value_type
|
||||
struct __hash_value_type
|
||||
{
|
||||
typedef _Key key_type;
|
||||
typedef _Tp mapped_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
typedef pair<key_type, mapped_type> __nc_value_type;
|
||||
typedef pair<key_type&, mapped_type&> __nc_ref_pair_type;
|
||||
typedef pair<key_type&&, mapped_type&&> __nc_rref_pair_type;
|
||||
|
||||
private:
|
||||
value_type __cc;
|
||||
__nc_value_type __nc;
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
value_type& __get_value()
|
||||
{
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
return *_VSTD::launder(_VSTD::addressof(__cc));
|
||||
#else
|
||||
return __cc;
|
||||
#endif
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const value_type& __get_value() const
|
||||
{
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
return *_VSTD::launder(_VSTD::addressof(__cc));
|
||||
#else
|
||||
return __cc;
|
||||
#endif
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__nc_ref_pair_type __ref()
|
||||
{
|
||||
value_type& __v = __get_value();
|
||||
return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second);
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__nc_rref_pair_type __move()
|
||||
{
|
||||
value_type& __v = __get_value();
|
||||
return __nc_rref_pair_type(
|
||||
_VSTD::move(const_cast<key_type&>(__v.first)),
|
||||
_VSTD::move(__v.second));
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__hash_value_type& operator=(const __hash_value_type& __v)
|
||||
{__nc = __v.__cc; return *this;}
|
||||
{
|
||||
__ref() = __v.__get_value();
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__hash_value_type& operator=(__hash_value_type&& __v)
|
||||
{__nc = _VSTD::move(__v.__nc); return *this;}
|
||||
{
|
||||
__ref() = __v.__move();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class _ValueTp,
|
||||
class = typename enable_if<
|
||||
@@ -606,8 +650,10 @@ union __hash_value_type
|
||||
>::type
|
||||
>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__hash_value_type& operator=(_ValueTp&& __v) {
|
||||
__nc = _VSTD::forward<_ValueTp>(__v); return *this;
|
||||
__hash_value_type& operator=(_ValueTp&& __v)
|
||||
{
|
||||
__ref() = _VSTD::forward<_ValueTp>(__v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -628,8 +674,15 @@ struct __hash_value_type
|
||||
typedef _Tp mapped_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
|
||||
private:
|
||||
value_type __cc;
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
value_type& __get_value() { return __cc; }
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const value_type& __get_value() const { return __cc; }
|
||||
|
||||
private:
|
||||
~__hash_value_type();
|
||||
};
|
||||
@@ -657,9 +710,9 @@ public:
|
||||
__hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
reference operator*() const {return __i_->__cc;}
|
||||
reference operator*() const {return __i_->__get_value();}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
|
||||
pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__hash_map_iterator& operator++() {++__i_; return *this;}
|
||||
@@ -711,9 +764,9 @@ public:
|
||||
: __i_(__i.__i_) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
reference operator*() const {return __i_->__cc;}
|
||||
reference operator*() const {return __i_->__get_value();}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
|
||||
pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__hash_map_const_iterator& operator++() {++__i_; return *this;}
|
||||
@@ -750,7 +803,6 @@ public:
|
||||
typedef _Pred key_equal;
|
||||
typedef _Alloc allocator_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
typedef pair<key_type, mapped_type> __nc_value_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
|
||||
@@ -1298,8 +1350,8 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
|
||||
{
|
||||
iterator __i = __u.begin();
|
||||
while (__u.size() != 0) {
|
||||
__table_.__emplace_unique(_VSTD::move(
|
||||
__u.__table_.remove((__i++).__i_)->__value_.__nc));
|
||||
__table_.__emplace_unique(
|
||||
__u.__table_.remove((__i++).__i_)->__value_.__move());
|
||||
}
|
||||
}
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
@@ -1385,7 +1437,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
|
||||
{
|
||||
return __table_.__emplace_unique_key_args(__k,
|
||||
std::piecewise_construct, std::forward_as_tuple(__k),
|
||||
std::forward_as_tuple()).first->__cc.second;
|
||||
std::forward_as_tuple()).first->__get_value().second;
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
|
||||
@@ -1394,7 +1446,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k)
|
||||
{
|
||||
return __table_.__emplace_unique_key_args(__k,
|
||||
std::piecewise_construct, std::forward_as_tuple(std::move(__k)),
|
||||
std::forward_as_tuple()).first->__cc.second;
|
||||
std::forward_as_tuple()).first->__get_value().second;
|
||||
}
|
||||
#else // _LIBCPP_CXX03_LANG
|
||||
|
||||
@@ -1404,9 +1456,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const
|
||||
{
|
||||
__node_allocator& __na = __table_.__node_alloc();
|
||||
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
|
||||
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);
|
||||
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().first), __k);
|
||||
__h.get_deleter().__first_constructed = true;
|
||||
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
|
||||
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().second));
|
||||
__h.get_deleter().__second_constructed = true;
|
||||
return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03
|
||||
}
|
||||
@@ -1500,7 +1552,6 @@ public:
|
||||
typedef _Pred key_equal;
|
||||
typedef _Alloc allocator_type;
|
||||
typedef pair<const key_type, mapped_type> value_type;
|
||||
typedef pair<key_type, mapped_type> __nc_value_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
|
||||
@@ -1915,8 +1966,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
|
||||
while (__u.size() != 0)
|
||||
{
|
||||
__table_.__insert_multi(
|
||||
_VSTD::move(__u.__table_.remove((__i++).__i_)->__value_.__nc)
|
||||
);
|
||||
__u.__table_.remove((__i++).__i_)->__value_.__move());
|
||||
}
|
||||
}
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
|
||||
@@ -52,7 +52,7 @@ template <class T>
|
||||
>::type
|
||||
move_if_noexcept(T& x) noexcept; // constexpr in C++14
|
||||
|
||||
template <class T> constexpr add_const<T>_t& as_const(T& t) noexcept; // C++17
|
||||
template <class T> constexpr add_const_t<T>& as_const(T& t) noexcept; // C++17
|
||||
template <class T> void as_const(const T&&) = delete; // C++17
|
||||
|
||||
template <class T> typename add_rvalue_reference<T>::type declval() noexcept;
|
||||
|
||||
133
include/valarray
133
include/valarray
@@ -1053,6 +1053,9 @@ private:
|
||||
friend
|
||||
const _Up*
|
||||
end(const valarray<_Up>& __v);
|
||||
|
||||
void __clear();
|
||||
valarray& __assign_range(const value_type* __f, const value_type* __l);
|
||||
};
|
||||
|
||||
_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t))
|
||||
@@ -2735,7 +2738,8 @@ __val_expr<_ValExpr>::operator valarray<__val_expr::result_type>() const
|
||||
{
|
||||
__r.__begin_ =
|
||||
__r.__end_ =
|
||||
static_cast<result_type*>(_VSTD::__allocate(__n * sizeof(result_type)));
|
||||
static_cast<result_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(result_type), __alignof(result_type)));
|
||||
for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i)
|
||||
::new (__r.__end_) result_type(__expr_[__i]);
|
||||
}
|
||||
@@ -2750,7 +2754,25 @@ valarray<_Tp>::valarray(size_t __n)
|
||||
: __begin_(0),
|
||||
__end_(0)
|
||||
{
|
||||
resize(__n);
|
||||
if (__n)
|
||||
{
|
||||
__begin_ = __end_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
for (; __n; --__n, ++__end_)
|
||||
::new (__end_) value_type();
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
__clear();
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
@@ -2769,7 +2791,8 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n)
|
||||
{
|
||||
if (__n)
|
||||
{
|
||||
__begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
__begin_ = __end_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
@@ -2780,7 +2803,7 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
@@ -2794,7 +2817,8 @@ valarray<_Tp>::valarray(const valarray& __v)
|
||||
{
|
||||
if (__v.size())
|
||||
{
|
||||
__begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__v.size() * sizeof(value_type)));
|
||||
__begin_ = __end_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), __alignof(value_type)));
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
@@ -2805,7 +2829,7 @@ valarray<_Tp>::valarray(const valarray& __v)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
@@ -2831,7 +2855,8 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il)
|
||||
size_t __n = __il.size();
|
||||
if (__n)
|
||||
{
|
||||
__begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
__begin_ = __end_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
@@ -2842,7 +2867,7 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
@@ -2859,7 +2884,8 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
|
||||
size_t __n = __sa.__size_;
|
||||
if (__n)
|
||||
{
|
||||
__begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
__begin_ = __end_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
@@ -2870,7 +2896,7 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
@@ -2885,7 +2911,8 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
|
||||
size_t __n = __ga.__1d_.size();
|
||||
if (__n)
|
||||
{
|
||||
__begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
__begin_ = __end_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
@@ -2899,7 +2926,7 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
@@ -2914,7 +2941,8 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
|
||||
size_t __n = __ma.__1d_.size();
|
||||
if (__n)
|
||||
{
|
||||
__begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
__begin_ = __end_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
@@ -2928,7 +2956,7 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
@@ -2943,7 +2971,8 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
|
||||
size_t __n = __ia.__1d_.size();
|
||||
if (__n)
|
||||
{
|
||||
__begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
__begin_ = __end_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
@@ -2957,7 +2986,7 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
@@ -2968,7 +2997,25 @@ template <class _Tp>
|
||||
inline
|
||||
valarray<_Tp>::~valarray()
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
valarray<_Tp>&
|
||||
valarray<_Tp>::__assign_range(const value_type* __f, const value_type* __l)
|
||||
{
|
||||
size_t __n = __l - __f;
|
||||
if (size() != __n)
|
||||
{
|
||||
__clear();
|
||||
__begin_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
__end_ = __begin_ + __n;
|
||||
_VSTD::uninitialized_copy(__f, __l, __begin_);
|
||||
} else {
|
||||
_VSTD::copy(__f, __l, __begin_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
@@ -2976,11 +3023,7 @@ valarray<_Tp>&
|
||||
valarray<_Tp>::operator=(const valarray& __v)
|
||||
{
|
||||
if (this != &__v)
|
||||
{
|
||||
if (size() != __v.size())
|
||||
resize(__v.size());
|
||||
_VSTD::copy(__v.__begin_, __v.__end_, __begin_);
|
||||
}
|
||||
return __assign_range(__v.__begin_, __v.__end_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -2991,7 +3034,7 @@ inline
|
||||
valarray<_Tp>&
|
||||
valarray<_Tp>::operator=(valarray&& __v) _NOEXCEPT
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
__begin_ = __v.__begin_;
|
||||
__end_ = __v.__end_;
|
||||
__v.__begin_ = nullptr;
|
||||
@@ -3004,10 +3047,7 @@ inline
|
||||
valarray<_Tp>&
|
||||
valarray<_Tp>::operator=(initializer_list<value_type> __il)
|
||||
{
|
||||
if (size() != __il.size())
|
||||
resize(__il.size());
|
||||
_VSTD::copy(__il.begin(), __il.end(), __begin_);
|
||||
return *this;
|
||||
return __assign_range(__il.begin(), __il.end());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
@@ -3224,7 +3264,8 @@ valarray<_Tp>::operator+() const
|
||||
{
|
||||
__r.__begin_ =
|
||||
__r.__end_ =
|
||||
static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
|
||||
::new (__r.__end_) value_type(+*__p);
|
||||
}
|
||||
@@ -3241,7 +3282,8 @@ valarray<_Tp>::operator-() const
|
||||
{
|
||||
__r.__begin_ =
|
||||
__r.__end_ =
|
||||
static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
|
||||
::new (__r.__end_) value_type(-*__p);
|
||||
}
|
||||
@@ -3258,7 +3300,8 @@ valarray<_Tp>::operator~() const
|
||||
{
|
||||
__r.__begin_ =
|
||||
__r.__end_ =
|
||||
static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
|
||||
::new (__r.__end_) value_type(~*__p);
|
||||
}
|
||||
@@ -3275,7 +3318,7 @@ valarray<_Tp>::operator!() const
|
||||
{
|
||||
__r.__begin_ =
|
||||
__r.__end_ =
|
||||
static_cast<bool*>(_VSTD::__allocate(__n * sizeof(bool)));
|
||||
static_cast<bool*>(_VSTD::__libcpp_allocate(__n * sizeof(bool), __alignof(bool)));
|
||||
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
|
||||
::new (__r.__end_) bool(!*__p);
|
||||
}
|
||||
@@ -3595,7 +3638,8 @@ valarray<_Tp>::shift(int __i) const
|
||||
{
|
||||
__r.__begin_ =
|
||||
__r.__end_ =
|
||||
static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
const value_type* __sb;
|
||||
value_type* __tb;
|
||||
value_type* __te;
|
||||
@@ -3633,7 +3677,8 @@ valarray<_Tp>::cshift(int __i) const
|
||||
{
|
||||
__r.__begin_ =
|
||||
__r.__end_ =
|
||||
static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
__i %= static_cast<int>(__n);
|
||||
const value_type* __m = __i >= 0 ? __begin_ + __i : __end_ + __i;
|
||||
for (const value_type* __s = __m; __s != __end_; ++__r.__end_, ++__s)
|
||||
@@ -3654,7 +3699,8 @@ valarray<_Tp>::apply(value_type __f(value_type)) const
|
||||
{
|
||||
__r.__begin_ =
|
||||
__r.__end_ =
|
||||
static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
|
||||
::new (__r.__end_) value_type(__f(*__p));
|
||||
}
|
||||
@@ -3671,7 +3717,8 @@ valarray<_Tp>::apply(value_type __f(const value_type&)) const
|
||||
{
|
||||
__r.__begin_ =
|
||||
__r.__end_ =
|
||||
static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
|
||||
::new (__r.__end_) value_type(__f(*__p));
|
||||
}
|
||||
@@ -3680,18 +3727,26 @@ valarray<_Tp>::apply(value_type __f(const value_type&)) const
|
||||
|
||||
template <class _Tp>
|
||||
void
|
||||
valarray<_Tp>::resize(size_t __n, value_type __x)
|
||||
valarray<_Tp>::__clear()
|
||||
{
|
||||
if (__begin_ != nullptr)
|
||||
{
|
||||
while (__end_ != __begin_)
|
||||
(--__end_)->~value_type();
|
||||
_VSTD::__libcpp_deallocate(__begin_);
|
||||
_VSTD::__libcpp_deallocate(__begin_, __alignof(value_type));
|
||||
__begin_ = __end_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
void
|
||||
valarray<_Tp>::resize(size_t __n, value_type __x)
|
||||
{
|
||||
__clear();
|
||||
if (__n)
|
||||
{
|
||||
__begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
|
||||
__begin_ = __end_ = static_cast<value_type*>(
|
||||
_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
@@ -3702,7 +3757,7 @@ valarray<_Tp>::resize(size_t __n, value_type __x)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
resize(0);
|
||||
__clear();
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
|
||||
@@ -476,8 +476,8 @@ private:
|
||||
template <class... _Fs>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
static constexpr auto __make_farray(_Fs&&... __fs) {
|
||||
__std_visit_visitor_return_type_check<decay_t<_Fs>...>();
|
||||
using __result = array<common_type_t<decay_t<_Fs>...>, sizeof...(_Fs)>;
|
||||
__std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
|
||||
using __result = array<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
|
||||
return __result{{_VSTD::forward<_Fs>(__fs)...}};
|
||||
}
|
||||
|
||||
@@ -514,8 +514,8 @@ private:
|
||||
template <class _Fp, class _Vp, class... _Vs>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
static constexpr auto __make_fdiagonal() {
|
||||
constexpr size_t _Np = decay_t<_Vp>::__size();
|
||||
static_assert(__all<(_Np == decay_t<_Vs>::__size())...>::value);
|
||||
constexpr size_t _Np = __uncvref_t<_Vp>::__size();
|
||||
static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value);
|
||||
return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});
|
||||
}
|
||||
|
||||
@@ -538,7 +538,7 @@ private:
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
static constexpr auto __make_fmatrix() {
|
||||
return __make_fmatrix_impl<_Fp, _Vs...>(
|
||||
index_sequence<>{}, make_index_sequence<decay_t<_Vs>::__size()>{}...);
|
||||
index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -756,7 +756,7 @@ _LIBCPP_VARIANT_DESTRUCTOR(
|
||||
if (!this->valueless_by_exception()) {
|
||||
__visitation::__base::__visit_alt(
|
||||
[](auto& __alt) noexcept {
|
||||
using __alt_type = decay_t<decltype(__alt)>;
|
||||
using __alt_type = __uncvref_t<decltype(__alt)>;
|
||||
__alt.~__alt_type();
|
||||
},
|
||||
*this);
|
||||
@@ -1564,7 +1564,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<
|
||||
? 299792458 // Random value chosen by the universe upon creation
|
||||
: __variant::__visit_alt(
|
||||
[](const auto& __alt) {
|
||||
using __alt_type = decay_t<decltype(__alt)>;
|
||||
using __alt_type = __uncvref_t<decltype(__alt)>;
|
||||
using __value_type = remove_const_t<
|
||||
typename __alt_type::__value_type>;
|
||||
return hash<__value_type>{}(__alt.__value);
|
||||
|
||||
139
include/vector
139
include/vector
@@ -244,6 +244,10 @@ public:
|
||||
bool __invariants() const;
|
||||
};
|
||||
|
||||
template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
|
||||
vector(InputIterator, InputIterator, Allocator = Allocator())
|
||||
-> vector<typename iterator_traits<InputIterator>::value_type, Allocator>;
|
||||
|
||||
template <class Allocator> struct hash<std::vector<bool, Allocator>>;
|
||||
|
||||
template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
|
||||
@@ -316,13 +320,14 @@ template <class _Tp, class _Allocator>
|
||||
class __vector_base
|
||||
: protected __vector_base_common<true>
|
||||
{
|
||||
protected:
|
||||
typedef _Tp value_type;
|
||||
public:
|
||||
typedef _Allocator allocator_type;
|
||||
typedef allocator_traits<allocator_type> __alloc_traits;
|
||||
typedef typename __alloc_traits::size_type size_type;
|
||||
protected:
|
||||
typedef _Tp value_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename __alloc_traits::size_type size_type;
|
||||
typedef typename __alloc_traits::difference_type difference_type;
|
||||
typedef typename __alloc_traits::pointer pointer;
|
||||
typedef typename __alloc_traits::const_pointer const_pointer;
|
||||
@@ -350,6 +355,9 @@ protected:
|
||||
__vector_base()
|
||||
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
|
||||
_LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a);
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
_LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT;
|
||||
#endif
|
||||
~__vector_base();
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@@ -433,6 +441,15 @@ __vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a)
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
template <class _Tp, class _Allocator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
__vector_base<_Tp, _Allocator>::__vector_base(allocator_type&& __a) _NOEXCEPT
|
||||
: __begin_(nullptr),
|
||||
__end_(nullptr),
|
||||
__end_cap_(nullptr, std::move(__a)) {}
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
__vector_base<_Tp, _Allocator>::~__vector_base()
|
||||
{
|
||||
@@ -492,8 +509,8 @@ public:
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
explicit vector(size_type __n, const allocator_type& __a);
|
||||
#endif
|
||||
vector(size_type __n, const_reference __x);
|
||||
vector(size_type __n, const_reference __x, const allocator_type& __a);
|
||||
vector(size_type __n, const value_type& __x);
|
||||
vector(size_type __n, const value_type& __x, const allocator_type& __a);
|
||||
template <class _InputIterator>
|
||||
vector(_InputIterator __first,
|
||||
typename enable_if<__is_input_iterator <_InputIterator>::value &&
|
||||
@@ -776,8 +793,8 @@ public:
|
||||
private:
|
||||
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
|
||||
_LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(pointer __new_last);
|
||||
void allocate(size_type __n);
|
||||
void deallocate() _NOEXCEPT;
|
||||
void __vallocate(size_type __n);
|
||||
void __vdeallocate() _NOEXCEPT;
|
||||
_LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;
|
||||
void __construct_at_end(size_type __n);
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@@ -890,6 +907,22 @@ private:
|
||||
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
|
||||
template<class _InputIterator,
|
||||
class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
|
||||
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
||||
>
|
||||
vector(_InputIterator, _InputIterator)
|
||||
-> vector<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
||||
|
||||
template<class _InputIterator,
|
||||
class _Alloc,
|
||||
class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
|
||||
>
|
||||
vector(_InputIterator, _InputIterator, _Alloc)
|
||||
-> vector<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
void
|
||||
vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v)
|
||||
@@ -930,7 +963,7 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
|
||||
// Postcondition: size() == 0
|
||||
template <class _Tp, class _Allocator>
|
||||
void
|
||||
vector<_Tp, _Allocator>::allocate(size_type __n)
|
||||
vector<_Tp, _Allocator>::__vallocate(size_type __n)
|
||||
{
|
||||
if (__n > max_size())
|
||||
this->__throw_length_error();
|
||||
@@ -941,7 +974,7 @@ vector<_Tp, _Allocator>::allocate(size_type __n)
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
void
|
||||
vector<_Tp, _Allocator>::deallocate() _NOEXCEPT
|
||||
vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT
|
||||
{
|
||||
if (this->__begin_ != nullptr)
|
||||
{
|
||||
@@ -1077,7 +1110,7 @@ vector<_Tp, _Allocator>::vector(size_type __n)
|
||||
#endif
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n);
|
||||
}
|
||||
}
|
||||
@@ -1092,27 +1125,27 @@ vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
|
||||
#endif
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
vector<_Tp, _Allocator>::vector(size_type __n, const_reference __x)
|
||||
vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
|
||||
{
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
__get_db()->__insert_c(this);
|
||||
#endif
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n, __x);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
vector<_Tp, _Allocator>::vector(size_type __n, const_reference __x, const allocator_type& __a)
|
||||
vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a)
|
||||
: __base(__a)
|
||||
{
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
@@ -1120,7 +1153,7 @@ vector<_Tp, _Allocator>::vector(size_type __n, const_reference __x, const alloca
|
||||
#endif
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n, __x);
|
||||
}
|
||||
}
|
||||
@@ -1174,7 +1207,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first,
|
||||
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__first, __last, __n);
|
||||
}
|
||||
}
|
||||
@@ -1194,7 +1227,7 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las
|
||||
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__first, __last, __n);
|
||||
}
|
||||
}
|
||||
@@ -1209,7 +1242,7 @@ vector<_Tp, _Allocator>::vector(const vector& __x)
|
||||
size_type __n = __x.size();
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__x.__begin_, __x.__end_, __n);
|
||||
}
|
||||
}
|
||||
@@ -1224,7 +1257,7 @@ vector<_Tp, _Allocator>::vector(const vector& __x, const allocator_type& __a)
|
||||
size_type __n = __x.size();
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__x.__begin_, __x.__end_, __n);
|
||||
}
|
||||
}
|
||||
@@ -1285,7 +1318,7 @@ vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
|
||||
#endif
|
||||
if (__il.size() > 0)
|
||||
{
|
||||
allocate(__il.size());
|
||||
__vallocate(__il.size());
|
||||
__construct_at_end(__il.begin(), __il.end(), __il.size());
|
||||
}
|
||||
}
|
||||
@@ -1300,7 +1333,7 @@ vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocat
|
||||
#endif
|
||||
if (__il.size() > 0)
|
||||
{
|
||||
allocate(__il.size());
|
||||
__vallocate(__il.size());
|
||||
__construct_at_end(__il.begin(), __il.end(), __il.size());
|
||||
}
|
||||
}
|
||||
@@ -1335,7 +1368,7 @@ void
|
||||
vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
|
||||
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
||||
{
|
||||
deallocate();
|
||||
__vdeallocate();
|
||||
__base::__move_assign_alloc(__c); // this can throw
|
||||
this->__begin_ = __c.__begin_;
|
||||
this->__end_ = __c.__end_;
|
||||
@@ -1410,8 +1443,8 @@ vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __las
|
||||
}
|
||||
else
|
||||
{
|
||||
deallocate();
|
||||
allocate(__recommend(__new_size));
|
||||
__vdeallocate();
|
||||
__vallocate(__recommend(__new_size));
|
||||
__construct_at_end(__first, __last, __new_size);
|
||||
}
|
||||
__invalidate_all_iterators();
|
||||
@@ -1432,8 +1465,8 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u)
|
||||
}
|
||||
else
|
||||
{
|
||||
deallocate();
|
||||
allocate(__recommend(static_cast<size_type>(__n)));
|
||||
__vdeallocate();
|
||||
__vallocate(__recommend(static_cast<size_type>(__n)));
|
||||
__construct_at_end(__n, __u);
|
||||
}
|
||||
__invalidate_all_iterators();
|
||||
@@ -2416,8 +2449,8 @@ public:
|
||||
|
||||
private:
|
||||
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
|
||||
void allocate(size_type __n);
|
||||
void deallocate() _NOEXCEPT;
|
||||
void __vallocate(size_type __n);
|
||||
void __vdeallocate() _NOEXCEPT;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static size_type __align_it(size_type __new_size) _NOEXCEPT
|
||||
{return __new_size + (__bits_per_word-1) & ~((size_type)__bits_per_word-1);};
|
||||
@@ -2455,7 +2488,7 @@ private:
|
||||
void __copy_assign_alloc(const vector& __c, true_type)
|
||||
{
|
||||
if (__alloc() != __c.__alloc())
|
||||
deallocate();
|
||||
__vdeallocate();
|
||||
__alloc() = __c.__alloc();
|
||||
}
|
||||
|
||||
@@ -2511,7 +2544,7 @@ vector<bool, _Allocator>::__invalidate_all_iterators()
|
||||
// Postcondition: size() == 0
|
||||
template <class _Allocator>
|
||||
void
|
||||
vector<bool, _Allocator>::allocate(size_type __n)
|
||||
vector<bool, _Allocator>::__vallocate(size_type __n)
|
||||
{
|
||||
if (__n > max_size())
|
||||
this->__throw_length_error();
|
||||
@@ -2523,7 +2556,7 @@ vector<bool, _Allocator>::allocate(size_type __n)
|
||||
|
||||
template <class _Allocator>
|
||||
void
|
||||
vector<bool, _Allocator>::deallocate() _NOEXCEPT
|
||||
vector<bool, _Allocator>::__vdeallocate() _NOEXCEPT
|
||||
{
|
||||
if (this->__begin_ != nullptr)
|
||||
{
|
||||
@@ -2620,7 +2653,7 @@ vector<bool, _Allocator>::vector(size_type __n)
|
||||
{
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n, false);
|
||||
}
|
||||
}
|
||||
@@ -2634,7 +2667,7 @@ vector<bool, _Allocator>::vector(size_type __n, const allocator_type& __a)
|
||||
{
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n, false);
|
||||
}
|
||||
}
|
||||
@@ -2648,7 +2681,7 @@ vector<bool, _Allocator>::vector(size_type __n, const value_type& __x)
|
||||
{
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n, __x);
|
||||
}
|
||||
}
|
||||
@@ -2661,7 +2694,7 @@ vector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const all
|
||||
{
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n, __x);
|
||||
}
|
||||
}
|
||||
@@ -2731,7 +2764,7 @@ vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __la
|
||||
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__first, __last);
|
||||
}
|
||||
}
|
||||
@@ -2747,7 +2780,7 @@ vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __la
|
||||
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__first, __last);
|
||||
}
|
||||
}
|
||||
@@ -2763,7 +2796,7 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il)
|
||||
size_type __n = static_cast<size_type>(__il.size());
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__il.begin(), __il.end());
|
||||
}
|
||||
}
|
||||
@@ -2777,7 +2810,7 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const alloca
|
||||
size_type __n = static_cast<size_type>(__il.size());
|
||||
if (__n > 0)
|
||||
{
|
||||
allocate(__n);
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__il.begin(), __il.end());
|
||||
}
|
||||
}
|
||||
@@ -2800,7 +2833,7 @@ vector<bool, _Allocator>::vector(const vector& __v)
|
||||
{
|
||||
if (__v.size() > 0)
|
||||
{
|
||||
allocate(__v.size());
|
||||
__vallocate(__v.size());
|
||||
__construct_at_end(__v.begin(), __v.end());
|
||||
}
|
||||
}
|
||||
@@ -2813,7 +2846,7 @@ vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a)
|
||||
{
|
||||
if (__v.size() > 0)
|
||||
{
|
||||
allocate(__v.size());
|
||||
__vallocate(__v.size());
|
||||
__construct_at_end(__v.begin(), __v.end());
|
||||
}
|
||||
}
|
||||
@@ -2829,8 +2862,8 @@ vector<bool, _Allocator>::operator=(const vector& __v)
|
||||
{
|
||||
if (__v.__size_ > capacity())
|
||||
{
|
||||
deallocate();
|
||||
allocate(__v.__size_);
|
||||
__vdeallocate();
|
||||
__vallocate(__v.__size_);
|
||||
}
|
||||
_VSTD::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.__size_), __begin_);
|
||||
}
|
||||
@@ -2842,17 +2875,15 @@ vector<bool, _Allocator>::operator=(const vector& __v)
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
template <class _Allocator>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
vector<bool, _Allocator>::vector(vector&& __v)
|
||||
inline _LIBCPP_INLINE_VISIBILITY vector<bool, _Allocator>::vector(vector&& __v)
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
_NOEXCEPT
|
||||
_NOEXCEPT
|
||||
#else
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
|
||||
#endif
|
||||
: __begin_(__v.__begin_),
|
||||
__size_(__v.__size_),
|
||||
__cap_alloc_(__v.__cap_alloc_)
|
||||
{
|
||||
__cap_alloc_(std::move(__v.__cap_alloc_)) {
|
||||
__v.__begin_ = nullptr;
|
||||
__v.__size_ = 0;
|
||||
__v.__cap() = 0;
|
||||
@@ -2874,7 +2905,7 @@ vector<bool, _Allocator>::vector(vector&& __v, const allocator_type& __a)
|
||||
}
|
||||
else if (__v.size() > 0)
|
||||
{
|
||||
allocate(__v.size());
|
||||
__vallocate(__v.size());
|
||||
__construct_at_end(__v.begin(), __v.end());
|
||||
}
|
||||
}
|
||||
@@ -2905,7 +2936,7 @@ void
|
||||
vector<bool, _Allocator>::__move_assign(vector& __c, true_type)
|
||||
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
||||
{
|
||||
deallocate();
|
||||
__vdeallocate();
|
||||
__move_assign_alloc(__c);
|
||||
this->__begin_ = __c.__begin_;
|
||||
this->__size_ = __c.__size_;
|
||||
@@ -2970,8 +3001,8 @@ vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __la
|
||||
{
|
||||
if (__n > capacity())
|
||||
{
|
||||
deallocate();
|
||||
allocate(__n);
|
||||
__vdeallocate();
|
||||
__vallocate(__n);
|
||||
}
|
||||
__construct_at_end(__first, __last);
|
||||
}
|
||||
@@ -2984,7 +3015,7 @@ vector<bool, _Allocator>::reserve(size_type __n)
|
||||
if (__n > capacity())
|
||||
{
|
||||
vector __v(this->__alloc());
|
||||
__v.allocate(__n);
|
||||
__v.__vallocate(__n);
|
||||
__v.__construct_at_end(this->begin(), this->end());
|
||||
swap(__v);
|
||||
__invalidate_all_iterators();
|
||||
|
||||
25
include/version
Normal file
25
include/version
Normal file
@@ -0,0 +1,25 @@
|
||||
// -*- C++ -*-
|
||||
//===--------------------------- version ----------------------------------===//
|
||||
//
|
||||
// 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_VERSIONH
|
||||
#define _LIBCPP_VERSIONH
|
||||
|
||||
/*
|
||||
version synopsis
|
||||
|
||||
*/
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#endif // _LIBCPP_VERSIONH
|
||||
@@ -189,6 +189,9 @@ split_list(LIBCXX_LINK_FLAGS)
|
||||
|
||||
# Add an object library that contains the compiled source files.
|
||||
add_library(cxx_objects OBJECT ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
|
||||
if(LIBCXX_CXX_ABI_HEADER_TARGET)
|
||||
add_dependencies(cxx_objects ${LIBCXX_CXX_ABI_HEADER_TARGET})
|
||||
endif()
|
||||
if(WIN32 AND NOT MINGW)
|
||||
target_compile_definitions(cxx_objects
|
||||
PRIVATE
|
||||
@@ -283,7 +286,7 @@ if (LIBCXX_ENABLE_STATIC)
|
||||
endif()
|
||||
|
||||
# Add a meta-target for both libraries.
|
||||
add_custom_target(cxx DEPENDS ${LIBCXX_TARGETS})
|
||||
add_custom_target(cxx DEPENDS cxx_headers ${LIBCXX_TARGETS})
|
||||
|
||||
if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY)
|
||||
file(GLOB LIBCXX_EXPERIMENTAL_SOURCES ../src/experimental/*.cpp)
|
||||
|
||||
1883
lib/abi/5.0/x86_64-unknown-linux-gnu.abilist
Normal file
1883
lib/abi/5.0/x86_64-unknown-linux-gnu.abilist
Normal file
File diff suppressed because it is too large
Load Diff
2378
lib/abi/6.0/x86_64-apple-darwin16.abilist
Normal file
2378
lib/abi/6.0/x86_64-apple-darwin16.abilist
Normal file
File diff suppressed because it is too large
Load Diff
1883
lib/abi/6.0/x86_64-unknown-linux-gnu.abilist
Normal file
1883
lib/abi/6.0/x86_64-unknown-linux-gnu.abilist
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,24 @@ Afterwards the ABI list should be updated to include the new changes.
|
||||
|
||||
New entries should be added directly below the "Version" header.
|
||||
|
||||
-----------
|
||||
Version 7.0
|
||||
-----------
|
||||
|
||||
* r333467 - Fix embarrasing typo in uncaught_exceptions.
|
||||
|
||||
This bug caused __uncaught_exception to be ODR used instead of
|
||||
__uncaught_exceptions. This change is non-ABI breaking because the symbols
|
||||
for std::uncaught_exception and std::uncaught_exceptions haven't changed,
|
||||
and because users shouldn't be depending directly on libc++ exporting
|
||||
__uncaught_exception/__uncaught_exceptions.
|
||||
|
||||
All Platforms
|
||||
----------------
|
||||
SYMBOL REMOVED: __cxa_uncaught_exception
|
||||
Symbol added: __cxa_uncaught_exceptions
|
||||
|
||||
|
||||
-----------
|
||||
Version 5.0
|
||||
-----------
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
if (DEFINED TARGET_TRIPLE)
|
||||
# Ignore the minor and patchlevel versions of the darwin
|
||||
# Ignore the major, minor, and patchlevel versions of the darwin
|
||||
# target.
|
||||
string(REGEX REPLACE "darwin16\\.[0-9]\\.[0-9]" "darwin16"
|
||||
string(REGEX REPLACE "darwin([0-9]+)\\.([0-9]+)\\.([0-9]+)" "darwin"
|
||||
GENERIC_TARGET_TRIPLE "${TARGET_TRIPLE}")
|
||||
endif()
|
||||
|
||||
|
||||
2378
lib/abi/x86_64-apple-darwin.abilist
Normal file
2378
lib/abi/x86_64-apple-darwin.abilist
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -10,8 +10,10 @@
|
||||
#include "experimental/filesystem"
|
||||
#include "iterator"
|
||||
#include "fstream"
|
||||
#include "type_traits"
|
||||
#include "random" /* for unique_path */
|
||||
#include "string_view"
|
||||
#include "type_traits"
|
||||
#include "vector"
|
||||
#include "cstdlib"
|
||||
#include "climits"
|
||||
|
||||
@@ -57,6 +59,250 @@ _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
|
||||
filesystem_error::~filesystem_error() {}
|
||||
|
||||
|
||||
namespace { namespace parser
|
||||
{
|
||||
|
||||
using string_view_t = path::__string_view;
|
||||
using string_view_pair = pair<string_view_t, string_view_t>;
|
||||
using PosPtr = path::value_type const*;
|
||||
|
||||
struct PathParser {
|
||||
enum ParserState : unsigned char {
|
||||
// Zero is a special sentinel value used by default constructed iterators.
|
||||
PS_BeforeBegin = 1,
|
||||
PS_InRootName,
|
||||
PS_InRootDir,
|
||||
PS_InFilenames,
|
||||
PS_InTrailingSep,
|
||||
PS_AtEnd
|
||||
};
|
||||
|
||||
const string_view_t Path;
|
||||
string_view_t RawEntry;
|
||||
ParserState State;
|
||||
|
||||
private:
|
||||
PathParser(string_view_t P, ParserState State) noexcept
|
||||
: Path(P), State(State) {}
|
||||
|
||||
public:
|
||||
PathParser(string_view_t P, string_view_t E, unsigned char S)
|
||||
: Path(P), RawEntry(E), State(static_cast<ParserState>(S)) {
|
||||
// S cannot be '0' or PS_BeforeBegin.
|
||||
}
|
||||
|
||||
static PathParser CreateBegin(string_view_t P) noexcept {
|
||||
PathParser PP(P, PS_BeforeBegin);
|
||||
PP.increment();
|
||||
return PP;
|
||||
}
|
||||
|
||||
static PathParser CreateEnd(string_view_t P) noexcept {
|
||||
PathParser PP(P, PS_AtEnd);
|
||||
return PP;
|
||||
}
|
||||
|
||||
PosPtr peek() const noexcept {
|
||||
auto TkEnd = getNextTokenStartPos();
|
||||
auto End = getAfterBack();
|
||||
return TkEnd == End ? nullptr : TkEnd;
|
||||
}
|
||||
|
||||
void increment() noexcept {
|
||||
const PosPtr End = getAfterBack();
|
||||
const PosPtr Start = getNextTokenStartPos();
|
||||
if (Start == End)
|
||||
return makeState(PS_AtEnd);
|
||||
|
||||
switch (State) {
|
||||
case PS_BeforeBegin: {
|
||||
PosPtr TkEnd = consumeSeparator(Start, End);
|
||||
if (TkEnd)
|
||||
return makeState(PS_InRootDir, Start, TkEnd);
|
||||
else
|
||||
return makeState(PS_InFilenames, Start, consumeName(Start, End));
|
||||
}
|
||||
case PS_InRootDir:
|
||||
return makeState(PS_InFilenames, Start, consumeName(Start, End));
|
||||
|
||||
case PS_InFilenames: {
|
||||
PosPtr SepEnd = consumeSeparator(Start, End);
|
||||
if (SepEnd != End) {
|
||||
PosPtr TkEnd = consumeName(SepEnd, End);
|
||||
if (TkEnd)
|
||||
return makeState(PS_InFilenames, SepEnd, TkEnd);
|
||||
}
|
||||
return makeState(PS_InTrailingSep, Start, SepEnd);
|
||||
}
|
||||
|
||||
case PS_InTrailingSep:
|
||||
return makeState(PS_AtEnd);
|
||||
|
||||
case PS_InRootName:
|
||||
case PS_AtEnd:
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void decrement() noexcept {
|
||||
const PosPtr REnd = getBeforeFront();
|
||||
const PosPtr RStart = getCurrentTokenStartPos() - 1;
|
||||
if (RStart == REnd) // we're decrementing the begin
|
||||
return makeState(PS_BeforeBegin);
|
||||
|
||||
switch (State) {
|
||||
case PS_AtEnd: {
|
||||
// Try to consume a trailing separator or root directory first.
|
||||
if (PosPtr SepEnd = consumeSeparator(RStart, REnd)) {
|
||||
if (SepEnd == REnd)
|
||||
return makeState(PS_InRootDir, Path.data(), RStart + 1);
|
||||
return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1);
|
||||
} else {
|
||||
PosPtr TkStart = consumeName(RStart, REnd);
|
||||
return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
|
||||
}
|
||||
}
|
||||
case PS_InTrailingSep:
|
||||
return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1, RStart + 1);
|
||||
case PS_InFilenames: {
|
||||
PosPtr SepEnd = consumeSeparator(RStart, REnd);
|
||||
if (SepEnd == REnd)
|
||||
return makeState(PS_InRootDir, Path.data(), RStart + 1);
|
||||
PosPtr TkEnd = consumeName(SepEnd, REnd);
|
||||
return makeState(PS_InFilenames, TkEnd + 1, SepEnd + 1);
|
||||
}
|
||||
case PS_InRootDir:
|
||||
// return makeState(PS_InRootName, Path.data(), RStart + 1);
|
||||
case PS_InRootName:
|
||||
case PS_BeforeBegin:
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Return a view with the "preferred representation" of the current
|
||||
/// element. For example trailing separators are represented as a '.'
|
||||
string_view_t operator*() const noexcept {
|
||||
switch (State) {
|
||||
case PS_BeforeBegin:
|
||||
case PS_AtEnd:
|
||||
return "";
|
||||
case PS_InRootDir:
|
||||
return "/";
|
||||
case PS_InTrailingSep:
|
||||
return "";
|
||||
case PS_InRootName:
|
||||
case PS_InFilenames:
|
||||
return RawEntry;
|
||||
}
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
return State != PS_BeforeBegin && State != PS_AtEnd;
|
||||
}
|
||||
|
||||
PathParser& operator++() noexcept {
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
PathParser& operator--() noexcept {
|
||||
decrement();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool inRootPath() const noexcept {
|
||||
return State == PS_InRootDir || State == PS_InRootName;
|
||||
}
|
||||
|
||||
private:
|
||||
void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept {
|
||||
State = NewState;
|
||||
RawEntry = string_view_t(Start, End - Start);
|
||||
}
|
||||
void makeState(ParserState NewState) noexcept {
|
||||
State = NewState;
|
||||
RawEntry = {};
|
||||
}
|
||||
|
||||
PosPtr getAfterBack() const noexcept {
|
||||
return Path.data() + Path.size();
|
||||
}
|
||||
|
||||
PosPtr getBeforeFront() const noexcept {
|
||||
return Path.data() - 1;
|
||||
}
|
||||
|
||||
/// \brief Return a pointer to the first character after the currently
|
||||
/// lexed element.
|
||||
PosPtr getNextTokenStartPos() const noexcept {
|
||||
switch (State) {
|
||||
case PS_BeforeBegin:
|
||||
return Path.data();
|
||||
case PS_InRootName:
|
||||
case PS_InRootDir:
|
||||
case PS_InFilenames:
|
||||
return &RawEntry.back() + 1;
|
||||
case PS_InTrailingSep:
|
||||
case PS_AtEnd:
|
||||
return getAfterBack();
|
||||
}
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
|
||||
/// \brief Return a pointer to the first character in the currently lexed
|
||||
/// element.
|
||||
PosPtr getCurrentTokenStartPos() const noexcept {
|
||||
switch (State) {
|
||||
case PS_BeforeBegin:
|
||||
case PS_InRootName:
|
||||
return &Path.front();
|
||||
case PS_InRootDir:
|
||||
case PS_InFilenames:
|
||||
case PS_InTrailingSep:
|
||||
return &RawEntry.front();
|
||||
case PS_AtEnd:
|
||||
return &Path.back() + 1;
|
||||
}
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
|
||||
PosPtr consumeSeparator(PosPtr P, PosPtr End) const noexcept {
|
||||
if (P == End || *P != '/')
|
||||
return nullptr;
|
||||
const int Inc = P < End ? 1 : -1;
|
||||
P += Inc;
|
||||
while (P != End && *P == '/')
|
||||
P += Inc;
|
||||
return P;
|
||||
}
|
||||
|
||||
PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
|
||||
if (P == End || *P == '/')
|
||||
return nullptr;
|
||||
const int Inc = P < End ? 1 : -1;
|
||||
P += Inc;
|
||||
while (P != End && *P != '/')
|
||||
P += Inc;
|
||||
return P;
|
||||
}
|
||||
};
|
||||
|
||||
string_view_pair separate_filename(string_view_t const & s) {
|
||||
if (s == "." || s == ".." || s.empty()) return string_view_pair{s, ""};
|
||||
auto pos = s.find_last_of('.');
|
||||
if (pos == string_view_t::npos || pos == 0)
|
||||
return string_view_pair{s, string_view_t{}};
|
||||
return string_view_pair{s.substr(0, pos), s.substr(pos)};
|
||||
}
|
||||
|
||||
string_view_t createView(PosPtr S, PosPtr E) noexcept {
|
||||
return {S, static_cast<size_t>(E - S) + 1};
|
||||
}
|
||||
|
||||
}} // namespace parser
|
||||
|
||||
|
||||
// POSIX HELPERS
|
||||
|
||||
namespace detail { namespace {
|
||||
@@ -178,7 +424,7 @@ bool copy_file_impl(const path& from, const path& to, perms from_perms,
|
||||
ec, "copy_file", from, to);
|
||||
return false;
|
||||
}
|
||||
__permissions(to, from_perms, ec);
|
||||
__permissions(to, from_perms, perm_options::replace, ec);
|
||||
// TODO what if permissions fails?
|
||||
return true;
|
||||
}
|
||||
@@ -186,14 +432,33 @@ bool copy_file_impl(const path& from, const path& to, perms from_perms,
|
||||
}} // end namespace detail
|
||||
|
||||
using detail::set_or_throw;
|
||||
using parser::string_view_t;
|
||||
using parser::PathParser;
|
||||
using parser::createView;
|
||||
|
||||
path __canonical(path const & orig_p, const path& base, std::error_code *ec)
|
||||
static path __do_absolute(const path& p, path *cwd, std::error_code *ec) {
|
||||
if (ec) ec->clear();
|
||||
if (p.is_absolute())
|
||||
return p;
|
||||
*cwd = __current_path(ec);
|
||||
if (ec && *ec)
|
||||
return {};
|
||||
return (*cwd) / p;
|
||||
}
|
||||
|
||||
path __absolute(const path& p, std::error_code *ec) {
|
||||
path cwd;
|
||||
return __do_absolute(p, &cwd, ec);
|
||||
}
|
||||
|
||||
path __canonical(path const & orig_p, std::error_code *ec)
|
||||
{
|
||||
path p = absolute(orig_p, base);
|
||||
path cwd;
|
||||
path p = __do_absolute(orig_p, &cwd, ec);
|
||||
char buff[PATH_MAX + 1];
|
||||
char *ret;
|
||||
if ((ret = ::realpath(p.c_str(), buff)) == nullptr) {
|
||||
set_or_throw(ec, "canonical", orig_p, base);
|
||||
set_or_throw(ec, "canonical", orig_p, cwd);
|
||||
return {};
|
||||
}
|
||||
if (ec) ec->clear();
|
||||
@@ -635,14 +900,17 @@ void __last_write_time(const path& p, file_time_type new_time,
|
||||
}
|
||||
|
||||
|
||||
void __permissions(const path& p, perms prms, std::error_code *ec)
|
||||
void __permissions(const path& p, perms prms, perm_options opts,
|
||||
std::error_code *ec)
|
||||
{
|
||||
|
||||
const bool resolve_symlinks = !bool(perms::symlink_nofollow & prms);
|
||||
const bool add_perms = bool(perms::add_perms & prms);
|
||||
const bool remove_perms = bool(perms::remove_perms & prms);
|
||||
_LIBCPP_ASSERT(!(add_perms && remove_perms),
|
||||
"Both add_perms and remove_perms are set");
|
||||
auto has_opt = [&](perm_options o) { return bool(o & opts); };
|
||||
const bool resolve_symlinks = !has_opt(perm_options::nofollow);
|
||||
const bool add_perms = has_opt(perm_options::add);
|
||||
const bool remove_perms = has_opt(perm_options::remove);
|
||||
_LIBCPP_ASSERT(
|
||||
(add_perms + remove_perms + has_opt(perm_options::replace)) == 1,
|
||||
"One and only one of the perm_options constants replace, add, or remove "
|
||||
"is present in opts");
|
||||
|
||||
bool set_sym_perms = false;
|
||||
prms &= perms::mask;
|
||||
@@ -788,11 +1056,6 @@ file_status __symlink_status(const path& p, std::error_code *ec) {
|
||||
return detail::posix_lstat(p, ec);
|
||||
}
|
||||
|
||||
path __system_complete(const path& p, std::error_code *ec) {
|
||||
if (ec) ec->clear();
|
||||
return absolute(p, current_path());
|
||||
}
|
||||
|
||||
path __temp_directory_path(std::error_code* ec) {
|
||||
const char* env_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
|
||||
const char* ret = nullptr;
|
||||
@@ -817,34 +1080,393 @@ path __temp_directory_path(std::error_code* ec) {
|
||||
return p;
|
||||
}
|
||||
|
||||
// An absolute path is composed according to the table in [fs.op.absolute].
|
||||
path absolute(const path& p, const path& base) {
|
||||
auto root_name = p.root_name();
|
||||
auto root_dir = p.root_directory();
|
||||
|
||||
if (!root_name.empty() && !root_dir.empty())
|
||||
return p;
|
||||
path __weakly_canonical(const path& p, std::error_code *ec) {
|
||||
if (p.empty())
|
||||
return __canonical("", ec);
|
||||
|
||||
auto abs_base = base.is_absolute() ? base : absolute(base);
|
||||
path result;
|
||||
path tmp;
|
||||
tmp.__reserve(p.native().size());
|
||||
auto PP = PathParser::CreateEnd(p.native());
|
||||
--PP;
|
||||
std::vector<string_view_t> DNEParts;
|
||||
|
||||
/* !has_root_name && !has_root_dir */
|
||||
if (root_name.empty() && root_dir.empty())
|
||||
{
|
||||
return abs_base / p;
|
||||
while (PP.State != PathParser::PS_BeforeBegin) {
|
||||
tmp.assign(createView(p.native().data(), &PP.RawEntry.back()));
|
||||
std::error_code m_ec;
|
||||
file_status st = __status(tmp, &m_ec);
|
||||
if (!status_known(st)) {
|
||||
set_or_throw(m_ec, ec, "weakly_canonical", p);
|
||||
return {};
|
||||
} else if (exists(st)) {
|
||||
result = __canonical(tmp, ec);
|
||||
break;
|
||||
}
|
||||
else if (!root_name.empty()) /* has_root_name && !has_root_dir */
|
||||
{
|
||||
return root_name / abs_base.root_directory()
|
||||
/
|
||||
abs_base.relative_path() / p.relative_path();
|
||||
}
|
||||
else /* !has_root_name && has_root_dir */
|
||||
{
|
||||
if (abs_base.has_root_name())
|
||||
return abs_base.root_name() / p;
|
||||
// else p is absolute, return outside of block
|
||||
}
|
||||
return p;
|
||||
DNEParts.push_back(*PP);
|
||||
--PP;
|
||||
}
|
||||
if (PP.State == PathParser::PS_BeforeBegin)
|
||||
result = __canonical("", ec);
|
||||
if (ec) ec->clear();
|
||||
if (DNEParts.empty())
|
||||
return result;
|
||||
for (auto It=DNEParts.rbegin(); It != DNEParts.rend(); ++It)
|
||||
result /= *It;
|
||||
return result.lexically_normal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// path definitions
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
constexpr path::value_type path::preferred_separator;
|
||||
|
||||
path & path::replace_extension(path const & replacement)
|
||||
{
|
||||
path p = extension();
|
||||
if (not p.empty()) {
|
||||
__pn_.erase(__pn_.size() - p.native().size());
|
||||
}
|
||||
if (!replacement.empty()) {
|
||||
if (replacement.native()[0] != '.') {
|
||||
__pn_ += ".";
|
||||
}
|
||||
__pn_.append(replacement.__pn_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// path.decompose
|
||||
|
||||
string_view_t path::__root_name() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
if (PP.State == PathParser::PS_InRootName)
|
||||
return *PP;
|
||||
return {};
|
||||
}
|
||||
|
||||
string_view_t path::__root_directory() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
if (PP.State == PathParser::PS_InRootName)
|
||||
++PP;
|
||||
if (PP.State == PathParser::PS_InRootDir)
|
||||
return *PP;
|
||||
return {};
|
||||
}
|
||||
|
||||
string_view_t path::__root_path_raw() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
if (PP.State == PathParser::PS_InRootName) {
|
||||
auto NextCh = PP.peek();
|
||||
if (NextCh && *NextCh == '/') {
|
||||
++PP;
|
||||
return createView(__pn_.data(), &PP.RawEntry.back());
|
||||
}
|
||||
return PP.RawEntry;
|
||||
}
|
||||
if (PP.State == PathParser::PS_InRootDir)
|
||||
return *PP;
|
||||
return {};
|
||||
}
|
||||
|
||||
static bool ConsumeRootDir(PathParser* PP) {
|
||||
while (PP->State <= PathParser::PS_InRootDir)
|
||||
++(*PP);
|
||||
return PP->State == PathParser::PS_AtEnd;
|
||||
}
|
||||
|
||||
string_view_t path::__relative_path() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
if (ConsumeRootDir(&PP))
|
||||
return {};
|
||||
return createView(PP.RawEntry.data(), &__pn_.back());
|
||||
}
|
||||
|
||||
string_view_t path::__parent_path() const
|
||||
{
|
||||
if (empty())
|
||||
return {};
|
||||
// Determine if we have a root path but not a relative path. In that case
|
||||
// return *this.
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
if (ConsumeRootDir(&PP))
|
||||
return __pn_;
|
||||
}
|
||||
// Otherwise remove a single element from the end of the path, and return
|
||||
// a string representing that path
|
||||
{
|
||||
auto PP = PathParser::CreateEnd(__pn_);
|
||||
--PP;
|
||||
if (PP.RawEntry.data() == __pn_.data())
|
||||
return {};
|
||||
--PP;
|
||||
return createView(__pn_.data(), &PP.RawEntry.back());
|
||||
}
|
||||
}
|
||||
|
||||
string_view_t path::__filename() const
|
||||
{
|
||||
if (empty()) return {};
|
||||
{
|
||||
PathParser PP = PathParser::CreateBegin(__pn_);
|
||||
if (ConsumeRootDir(&PP))
|
||||
return {};
|
||||
}
|
||||
return *(--PathParser::CreateEnd(__pn_));
|
||||
}
|
||||
|
||||
string_view_t path::__stem() const
|
||||
{
|
||||
return parser::separate_filename(__filename()).first;
|
||||
}
|
||||
|
||||
string_view_t path::__extension() const
|
||||
{
|
||||
return parser::separate_filename(__filename()).second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// path.gen
|
||||
|
||||
|
||||
enum PathPartKind : unsigned char {
|
||||
PK_None,
|
||||
PK_RootSep,
|
||||
PK_Filename,
|
||||
PK_Dot,
|
||||
PK_DotDot,
|
||||
PK_TrailingSep
|
||||
};
|
||||
|
||||
static PathPartKind ClassifyPathPart(string_view_t Part) {
|
||||
if (Part.empty())
|
||||
return PK_TrailingSep;
|
||||
if (Part == ".")
|
||||
return PK_Dot;
|
||||
if (Part == "..")
|
||||
return PK_DotDot;
|
||||
if (Part == "/")
|
||||
return PK_RootSep;
|
||||
return PK_Filename;
|
||||
}
|
||||
|
||||
path path::lexically_normal() const {
|
||||
if (__pn_.empty())
|
||||
return *this;
|
||||
|
||||
using PartKindPair = std::pair<string_view_t, PathPartKind>;
|
||||
std::vector<PartKindPair> Parts;
|
||||
// Guess as to how many elements the path has to avoid reallocating.
|
||||
Parts.reserve(32);
|
||||
|
||||
// Track the total size of the parts as we collect them. This allows the
|
||||
// resulting path to reserve the correct amount of memory.
|
||||
size_t NewPathSize = 0;
|
||||
auto AddPart = [&](PathPartKind K, string_view_t P) {
|
||||
NewPathSize += P.size();
|
||||
Parts.emplace_back(P, K);
|
||||
};
|
||||
auto LastPartKind = [&]() {
|
||||
if (Parts.empty())
|
||||
return PK_None;
|
||||
return Parts.back().second;
|
||||
};
|
||||
|
||||
bool MaybeNeedTrailingSep = false;
|
||||
// Build a stack containing the remaining elements of the path, popping off
|
||||
// elements which occur before a '..' entry.
|
||||
for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) {
|
||||
auto Part = *PP;
|
||||
PathPartKind Kind = ClassifyPathPart(Part);
|
||||
switch (Kind) {
|
||||
case PK_Filename:
|
||||
case PK_RootSep: {
|
||||
// Add all non-dot and non-dot-dot elements to the stack of elements.
|
||||
AddPart(Kind, Part);
|
||||
MaybeNeedTrailingSep = false;
|
||||
break;
|
||||
}
|
||||
case PK_DotDot: {
|
||||
// Only push a ".." element if there are no elements preceding the "..",
|
||||
// or if the preceding element is itself "..".
|
||||
auto LastKind = LastPartKind();
|
||||
if (LastKind == PK_Filename) {
|
||||
NewPathSize -= Parts.back().first.size();
|
||||
Parts.pop_back();
|
||||
} else if (LastKind != PK_RootSep)
|
||||
AddPart(PK_DotDot, "..");
|
||||
MaybeNeedTrailingSep = LastKind == PK_Filename;
|
||||
break;
|
||||
}
|
||||
case PK_Dot:
|
||||
case PK_TrailingSep: {
|
||||
MaybeNeedTrailingSep = true;
|
||||
break;
|
||||
}
|
||||
case PK_None:
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
// [fs.path.generic]p6.8: If the path is empty, add a dot.
|
||||
if (Parts.empty())
|
||||
return ".";
|
||||
|
||||
// [fs.path.generic]p6.7: If the last filename is dot-dot, remove any
|
||||
// trailing directory-separator.
|
||||
bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename;
|
||||
|
||||
path Result;
|
||||
Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep);
|
||||
for (auto &PK : Parts)
|
||||
Result /= PK.first;
|
||||
|
||||
if (NeedTrailingSep)
|
||||
Result /= "";
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static int DetermineLexicalElementCount(PathParser PP) {
|
||||
int Count = 0;
|
||||
for (; PP; ++PP) {
|
||||
auto Elem = *PP;
|
||||
if (Elem == "..")
|
||||
--Count;
|
||||
else if (Elem != ".")
|
||||
++Count;
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
|
||||
path path::lexically_relative(const path& base) const {
|
||||
{ // perform root-name/root-directory mismatch checks
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
auto PPBase = PathParser::CreateBegin(base.__pn_);
|
||||
auto CheckIterMismatchAtBase = [&]() {
|
||||
return PP.State != PPBase.State && (
|
||||
PP.inRootPath() || PPBase.inRootPath());
|
||||
};
|
||||
if (PP.State == PathParser::PS_InRootName &&
|
||||
PPBase.State == PathParser::PS_InRootName) {
|
||||
if (*PP != *PPBase)
|
||||
return {};
|
||||
} else if (CheckIterMismatchAtBase())
|
||||
return {};
|
||||
|
||||
if (PP.inRootPath()) ++PP;
|
||||
if (PPBase.inRootPath()) ++PPBase;
|
||||
if (CheckIterMismatchAtBase())
|
||||
return {};
|
||||
}
|
||||
|
||||
// Find the first mismatching element
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
auto PPBase = PathParser::CreateBegin(base.__pn_);
|
||||
while (PP && PPBase && PP.State == PPBase.State &&
|
||||
*PP == *PPBase) {
|
||||
++PP;
|
||||
++PPBase;
|
||||
}
|
||||
|
||||
// If there is no mismatch, return ".".
|
||||
if (!PP && !PPBase)
|
||||
return ".";
|
||||
|
||||
// Otherwise, determine the number of elements, 'n', which are not dot or
|
||||
// dot-dot minus the number of dot-dot elements.
|
||||
int ElemCount = DetermineLexicalElementCount(PPBase);
|
||||
if (ElemCount < 0)
|
||||
return {};
|
||||
|
||||
// return a path constructed with 'n' dot-dot elements, followed by the the
|
||||
// elements of '*this' after the mismatch.
|
||||
path Result;
|
||||
// FIXME: Reserve enough room in Result that it won't have to re-allocate.
|
||||
while (ElemCount--)
|
||||
Result /= "..";
|
||||
for (; PP; ++PP)
|
||||
Result /= *PP;
|
||||
return Result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// path.comparisons
|
||||
int path::__compare(string_view_t __s) const {
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
auto PP2 = PathParser::CreateBegin(__s);
|
||||
while (PP && PP2) {
|
||||
int res = (*PP).compare(*PP2);
|
||||
if (res != 0) return res;
|
||||
++PP; ++PP2;
|
||||
}
|
||||
if (PP.State == PP2.State && !PP)
|
||||
return 0;
|
||||
if (!PP)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// path.nonmembers
|
||||
size_t hash_value(const path& __p) noexcept {
|
||||
auto PP = PathParser::CreateBegin(__p.native());
|
||||
size_t hash_value = 0;
|
||||
std::hash<string_view_t> hasher;
|
||||
while (PP) {
|
||||
hash_value = __hash_combine(hash_value, hasher(*PP));
|
||||
++PP;
|
||||
}
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// path.itr
|
||||
path::iterator path::begin() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
iterator it;
|
||||
it.__path_ptr_ = this;
|
||||
it.__state_ = PP.State;
|
||||
it.__entry_ = PP.RawEntry;
|
||||
it.__stashed_elem_.__assign_view(*PP);
|
||||
return it;
|
||||
}
|
||||
|
||||
path::iterator path::end() const
|
||||
{
|
||||
iterator it{};
|
||||
it.__state_ = PathParser::PS_AtEnd;
|
||||
it.__path_ptr_ = this;
|
||||
return it;
|
||||
}
|
||||
|
||||
path::iterator& path::iterator::__increment() {
|
||||
static_assert(__at_end == PathParser::PS_AtEnd, "");
|
||||
PathParser PP(__path_ptr_->native(), __entry_, __state_);
|
||||
++PP;
|
||||
__state_ = PP.State;
|
||||
__entry_ = PP.RawEntry;
|
||||
__stashed_elem_.__assign_view(*PP);
|
||||
return *this;
|
||||
}
|
||||
|
||||
path::iterator& path::iterator::__decrement() {
|
||||
PathParser PP(__path_ptr_->native(), __entry_, __state_);
|
||||
--PP;
|
||||
__state_ = PP.State;
|
||||
__entry_ = PP.RawEntry;
|
||||
__stashed_elem_.__assign_view(*PP);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
|
||||
|
||||
@@ -1,448 +0,0 @@
|
||||
//===--------------------- filesystem/path.cpp ----------------------------===//
|
||||
//
|
||||
// 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 "experimental/filesystem"
|
||||
#include "string_view"
|
||||
#include "utility"
|
||||
|
||||
namespace { namespace parser
|
||||
{
|
||||
using namespace std;
|
||||
using namespace std::experimental::filesystem;
|
||||
|
||||
using string_view_t = path::__string_view;
|
||||
using string_view_pair = pair<string_view_t, string_view_t>;
|
||||
using PosPtr = path::value_type const*;
|
||||
|
||||
struct PathParser {
|
||||
enum ParserState : unsigned char {
|
||||
// Zero is a special sentinel value used by default constructed iterators.
|
||||
PS_BeforeBegin = 1,
|
||||
PS_InRootName,
|
||||
PS_InRootDir,
|
||||
PS_InFilenames,
|
||||
PS_InTrailingSep,
|
||||
PS_AtEnd
|
||||
};
|
||||
|
||||
const string_view_t Path;
|
||||
string_view_t RawEntry;
|
||||
ParserState State;
|
||||
|
||||
private:
|
||||
PathParser(string_view_t P, ParserState State) noexcept
|
||||
: Path(P), State(State) {}
|
||||
|
||||
public:
|
||||
PathParser(string_view_t P, string_view_t E, unsigned char S)
|
||||
: Path(P), RawEntry(E), State(static_cast<ParserState>(S)) {
|
||||
// S cannot be '0' or PS_BeforeBegin.
|
||||
}
|
||||
|
||||
static PathParser CreateBegin(string_view_t P) noexcept {
|
||||
PathParser PP(P, PS_BeforeBegin);
|
||||
PP.increment();
|
||||
return PP;
|
||||
}
|
||||
|
||||
static PathParser CreateEnd(string_view_t P) noexcept {
|
||||
PathParser PP(P, PS_AtEnd);
|
||||
return PP;
|
||||
}
|
||||
|
||||
PosPtr peek() const noexcept {
|
||||
auto TkEnd = getNextTokenStartPos();
|
||||
auto End = getAfterBack();
|
||||
return TkEnd == End ? nullptr : TkEnd;
|
||||
}
|
||||
|
||||
void increment() noexcept {
|
||||
const PosPtr End = getAfterBack();
|
||||
const PosPtr Start = getNextTokenStartPos();
|
||||
if (Start == End)
|
||||
return makeState(PS_AtEnd);
|
||||
|
||||
switch (State) {
|
||||
case PS_BeforeBegin: {
|
||||
PosPtr TkEnd = consumeSeparator(Start, End);
|
||||
// If we consumed exactly two separators we have a root name.
|
||||
if (TkEnd && TkEnd == Start + 2) {
|
||||
// FIXME Do we need to consume a name or is '//' a root name on its own?
|
||||
// what about '//.', '//..', '//...'?
|
||||
auto NameEnd = consumeName(TkEnd, End);
|
||||
if (NameEnd)
|
||||
TkEnd = NameEnd;
|
||||
return makeState(PS_InRootName, Start, TkEnd);
|
||||
}
|
||||
else if (TkEnd)
|
||||
return makeState(PS_InRootDir, Start, TkEnd);
|
||||
else
|
||||
return makeState(PS_InFilenames, Start, consumeName(Start, End));
|
||||
}
|
||||
|
||||
case PS_InRootName:
|
||||
return makeState(PS_InRootDir, Start, consumeSeparator(Start, End));
|
||||
case PS_InRootDir:
|
||||
return makeState(PS_InFilenames, Start, consumeName(Start, End));
|
||||
|
||||
case PS_InFilenames: {
|
||||
PosPtr SepEnd = consumeSeparator(Start, End);
|
||||
if (SepEnd != End) {
|
||||
PosPtr TkEnd = consumeName(SepEnd, End);
|
||||
if (TkEnd)
|
||||
return makeState(PS_InFilenames, SepEnd, TkEnd);
|
||||
}
|
||||
return makeState(PS_InTrailingSep, Start, SepEnd);
|
||||
}
|
||||
|
||||
case PS_InTrailingSep:
|
||||
return makeState(PS_AtEnd);
|
||||
|
||||
case PS_AtEnd:
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void decrement() noexcept {
|
||||
const PosPtr REnd = getBeforeFront();
|
||||
const PosPtr RStart = getCurrentTokenStartPos() - 1;
|
||||
|
||||
switch (State) {
|
||||
case PS_AtEnd: {
|
||||
// Try to consume a trailing separator or root directory first.
|
||||
if (PosPtr SepEnd = consumeSeparator(RStart, REnd)) {
|
||||
if (SepEnd == REnd)
|
||||
return makeState((RStart == REnd + 2) ? PS_InRootName : PS_InRootDir,
|
||||
Path.data(), RStart + 1);
|
||||
// Check if we're seeing the root directory separator
|
||||
auto PP = CreateBegin(Path);
|
||||
bool InRootDir = PP.State == PS_InRootName &&
|
||||
&PP.RawEntry.back() == SepEnd;
|
||||
return makeState(InRootDir ? PS_InRootDir : PS_InTrailingSep,
|
||||
SepEnd + 1, RStart + 1);
|
||||
} else {
|
||||
PosPtr TkStart = consumeName(RStart, REnd);
|
||||
if (TkStart == REnd + 2 && consumeSeparator(TkStart, REnd) == REnd)
|
||||
return makeState(PS_InRootName, Path.data(), RStart + 1);
|
||||
else
|
||||
return makeState(PS_InFilenames, TkStart + 1, RStart + 1);
|
||||
}
|
||||
}
|
||||
case PS_InTrailingSep:
|
||||
return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1, RStart + 1);
|
||||
case PS_InFilenames: {
|
||||
PosPtr SepEnd = consumeSeparator(RStart, REnd);
|
||||
if (SepEnd == REnd)
|
||||
return makeState((RStart == REnd + 2) ? PS_InRootName : PS_InRootDir,
|
||||
Path.data(), RStart + 1);
|
||||
PosPtr TkEnd = consumeName(SepEnd, REnd);
|
||||
if (TkEnd == REnd + 2 && consumeSeparator(TkEnd, REnd) == REnd)
|
||||
return makeState(PS_InRootDir, SepEnd + 1, RStart + 1);
|
||||
return makeState(PS_InFilenames, TkEnd + 1, SepEnd + 1);
|
||||
}
|
||||
case PS_InRootDir:
|
||||
return makeState(PS_InRootName, Path.data(), RStart + 1);
|
||||
case PS_InRootName:
|
||||
case PS_BeforeBegin:
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Return a view with the "preferred representation" of the current
|
||||
/// element. For example trailing separators are represented as a '.'
|
||||
string_view_t operator*() const noexcept {
|
||||
switch (State) {
|
||||
case PS_BeforeBegin:
|
||||
case PS_AtEnd:
|
||||
return "";
|
||||
case PS_InRootDir:
|
||||
return "/";
|
||||
case PS_InTrailingSep:
|
||||
return ".";
|
||||
case PS_InRootName:
|
||||
case PS_InFilenames:
|
||||
return RawEntry;
|
||||
}
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
return State != PS_BeforeBegin && State != PS_AtEnd;
|
||||
}
|
||||
|
||||
PathParser& operator++() noexcept {
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
PathParser& operator--() noexcept {
|
||||
decrement();
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept {
|
||||
State = NewState;
|
||||
RawEntry = string_view_t(Start, End - Start);
|
||||
}
|
||||
void makeState(ParserState NewState) noexcept {
|
||||
State = NewState;
|
||||
RawEntry = {};
|
||||
}
|
||||
|
||||
PosPtr getAfterBack() const noexcept {
|
||||
return Path.data() + Path.size();
|
||||
}
|
||||
|
||||
PosPtr getBeforeFront() const noexcept {
|
||||
return Path.data() - 1;
|
||||
}
|
||||
|
||||
/// \brief Return a pointer to the first character after the currently
|
||||
/// lexed element.
|
||||
PosPtr getNextTokenStartPos() const noexcept {
|
||||
switch (State) {
|
||||
case PS_BeforeBegin:
|
||||
return Path.data();
|
||||
case PS_InRootName:
|
||||
case PS_InRootDir:
|
||||
case PS_InFilenames:
|
||||
return &RawEntry.back() + 1;
|
||||
case PS_InTrailingSep:
|
||||
case PS_AtEnd:
|
||||
return getAfterBack();
|
||||
}
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
|
||||
/// \brief Return a pointer to the first character in the currently lexed
|
||||
/// element.
|
||||
PosPtr getCurrentTokenStartPos() const noexcept {
|
||||
switch (State) {
|
||||
case PS_BeforeBegin:
|
||||
case PS_InRootName:
|
||||
return &Path.front();
|
||||
case PS_InRootDir:
|
||||
case PS_InFilenames:
|
||||
case PS_InTrailingSep:
|
||||
return &RawEntry.front();
|
||||
case PS_AtEnd:
|
||||
return &Path.back() + 1;
|
||||
}
|
||||
_LIBCPP_UNREACHABLE();
|
||||
}
|
||||
|
||||
PosPtr consumeSeparator(PosPtr P, PosPtr End) const noexcept {
|
||||
if (P == End || *P != '/')
|
||||
return nullptr;
|
||||
const int Inc = P < End ? 1 : -1;
|
||||
P += Inc;
|
||||
while (P != End && *P == '/')
|
||||
P += Inc;
|
||||
return P;
|
||||
}
|
||||
|
||||
PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
|
||||
if (P == End || *P == '/')
|
||||
return nullptr;
|
||||
const int Inc = P < End ? 1 : -1;
|
||||
P += Inc;
|
||||
while (P != End && *P != '/')
|
||||
P += Inc;
|
||||
return P;
|
||||
}
|
||||
};
|
||||
|
||||
string_view_pair separate_filename(string_view_t const & s) {
|
||||
if (s == "." || s == ".." || s.empty()) return string_view_pair{s, ""};
|
||||
auto pos = s.find_last_of('.');
|
||||
if (pos == string_view_t::npos)
|
||||
return string_view_pair{s, string_view_t{}};
|
||||
return string_view_pair{s.substr(0, pos), s.substr(pos)};
|
||||
}
|
||||
|
||||
string_view_t createView(PosPtr S, PosPtr E) noexcept {
|
||||
return {S, static_cast<size_t>(E - S) + 1};
|
||||
}
|
||||
|
||||
}} // namespace parser
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM
|
||||
|
||||
using parser::string_view_t;
|
||||
using parser::string_view_pair;
|
||||
using parser::PathParser;
|
||||
using parser::createView;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// path definitions
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
constexpr path::value_type path::preferred_separator;
|
||||
|
||||
path & path::replace_extension(path const & replacement)
|
||||
{
|
||||
path p = extension();
|
||||
if (not p.empty()) {
|
||||
__pn_.erase(__pn_.size() - p.native().size());
|
||||
}
|
||||
if (!replacement.empty()) {
|
||||
if (replacement.native()[0] != '.') {
|
||||
__pn_ += ".";
|
||||
}
|
||||
__pn_.append(replacement.__pn_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// path.decompose
|
||||
|
||||
string_view_t path::__root_name() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
if (PP.State == PathParser::PS_InRootName)
|
||||
return *PP;
|
||||
return {};
|
||||
}
|
||||
|
||||
string_view_t path::__root_directory() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
if (PP.State == PathParser::PS_InRootName)
|
||||
++PP;
|
||||
if (PP.State == PathParser::PS_InRootDir)
|
||||
return *PP;
|
||||
return {};
|
||||
}
|
||||
|
||||
string_view_t path::__root_path_raw() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
if (PP.State == PathParser::PS_InRootName) {
|
||||
auto NextCh = PP.peek();
|
||||
if (NextCh && *NextCh == '/') {
|
||||
++PP;
|
||||
return createView(__pn_.data(), &PP.RawEntry.back());
|
||||
}
|
||||
return PP.RawEntry;
|
||||
}
|
||||
if (PP.State == PathParser::PS_InRootDir)
|
||||
return *PP;
|
||||
return {};
|
||||
}
|
||||
|
||||
string_view_t path::__relative_path() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
while (PP.State <= PathParser::PS_InRootDir)
|
||||
++PP;
|
||||
if (PP.State == PathParser::PS_AtEnd)
|
||||
return {};
|
||||
return createView(PP.RawEntry.data(), &__pn_.back());
|
||||
}
|
||||
|
||||
string_view_t path::__parent_path() const
|
||||
{
|
||||
if (empty())
|
||||
return {};
|
||||
auto PP = PathParser::CreateEnd(__pn_);
|
||||
--PP;
|
||||
if (PP.RawEntry.data() == __pn_.data())
|
||||
return {};
|
||||
--PP;
|
||||
return createView(__pn_.data(), &PP.RawEntry.back());
|
||||
}
|
||||
|
||||
string_view_t path::__filename() const
|
||||
{
|
||||
if (empty()) return {};
|
||||
return *(--PathParser::CreateEnd(__pn_));
|
||||
}
|
||||
|
||||
string_view_t path::__stem() const
|
||||
{
|
||||
return parser::separate_filename(__filename()).first;
|
||||
}
|
||||
|
||||
string_view_t path::__extension() const
|
||||
{
|
||||
return parser::separate_filename(__filename()).second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// path.comparisons
|
||||
int path::__compare(string_view_t __s) const {
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
auto PP2 = PathParser::CreateBegin(__s);
|
||||
while (PP && PP2) {
|
||||
int res = (*PP).compare(*PP2);
|
||||
if (res != 0) return res;
|
||||
++PP; ++PP2;
|
||||
}
|
||||
if (PP.State == PP2.State && PP.State == PathParser::PS_AtEnd)
|
||||
return 0;
|
||||
if (PP.State == PathParser::PS_AtEnd)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// path.nonmembers
|
||||
size_t hash_value(const path& __p) noexcept {
|
||||
auto PP = PathParser::CreateBegin(__p.native());
|
||||
size_t hash_value = 0;
|
||||
std::hash<string_view_t> hasher;
|
||||
while (PP) {
|
||||
hash_value = __hash_combine(hash_value, hasher(*PP));
|
||||
++PP;
|
||||
}
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// path.itr
|
||||
path::iterator path::begin() const
|
||||
{
|
||||
auto PP = PathParser::CreateBegin(__pn_);
|
||||
iterator it;
|
||||
it.__path_ptr_ = this;
|
||||
it.__state_ = PP.State;
|
||||
it.__entry_ = PP.RawEntry;
|
||||
it.__stashed_elem_.__assign_view(*PP);
|
||||
return it;
|
||||
}
|
||||
|
||||
path::iterator path::end() const
|
||||
{
|
||||
iterator it{};
|
||||
it.__state_ = PathParser::PS_AtEnd;
|
||||
it.__path_ptr_ = this;
|
||||
return it;
|
||||
}
|
||||
|
||||
path::iterator& path::iterator::__increment() {
|
||||
static_assert(__at_end == PathParser::PS_AtEnd, "");
|
||||
PathParser PP(__path_ptr_->native(), __entry_, __state_);
|
||||
++PP;
|
||||
__state_ = PP.State;
|
||||
__entry_ = PP.RawEntry;
|
||||
__stashed_elem_.__assign_view(*PP);
|
||||
return *this;
|
||||
}
|
||||
|
||||
path::iterator& path::iterator::__decrement() {
|
||||
PathParser PP(__path_ptr_->native(), __entry_, __state_);
|
||||
--PP;
|
||||
__state_ = PP.State;
|
||||
__entry_ = PP.RawEntry;
|
||||
__stashed_elem_.__assign_view(*PP);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM
|
||||
@@ -31,10 +31,10 @@ public:
|
||||
|
||||
protected:
|
||||
virtual void* do_allocate(size_t __size, size_t __align)
|
||||
{ return __allocate(__size); }
|
||||
{ return _VSTD::__libcpp_allocate(__size, __align); /* FIXME */}
|
||||
|
||||
virtual void do_deallocate(void * __p, size_t, size_t)
|
||||
{ _VSTD::__libcpp_deallocate(__p); }
|
||||
virtual void do_deallocate(void * __p, size_t, size_t __align)
|
||||
{ _VSTD::__libcpp_deallocate(__p, __align); /* FIXME */ }
|
||||
|
||||
virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
|
||||
{ return &__other == this; }
|
||||
|
||||
@@ -4240,6 +4240,7 @@ static bool checked_string_to_char_convert(char& dest,
|
||||
// FIXME: Work around specific multibyte sequences that we can reasonable
|
||||
// translate into a different single byte.
|
||||
switch (wout) {
|
||||
case L'\u202F': // narrow non-breaking space
|
||||
case L'\u00A0': // non-breaking space
|
||||
dest = ' ';
|
||||
return true;
|
||||
|
||||
@@ -18,7 +18,7 @@ bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
|
||||
|
||||
int uncaught_exceptions() _NOEXCEPT
|
||||
{
|
||||
# if _LIBCPPABI_VERSION > 1101
|
||||
# if _LIBCPPABI_VERSION > 1001
|
||||
return __cxa_uncaught_exceptions();
|
||||
# else
|
||||
return __cxa_uncaught_exception() ? 1 : 0;
|
||||
|
||||
@@ -9,6 +9,11 @@ endmacro()
|
||||
set(LIBCXX_LIT_VARIANT "libcxx" CACHE STRING
|
||||
"Configuration variant to use for LIT.")
|
||||
|
||||
set(LIBCXX_TEST_LINKER_FLAGS "" CACHE STRING
|
||||
"Additonal linker flags to pass when compiling the tests")
|
||||
set(LIBCXX_TEST_COMPILER_FLAGS "" CACHE STRING
|
||||
"Additonal linker flags to pass when compiling the tests")
|
||||
|
||||
# The tests shouldn't link to any ABI library when it has been linked into
|
||||
# libc++ statically or via a linker script.
|
||||
if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY OR LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
|
||||
|
||||
@@ -18,8 +18,21 @@
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
// Ensure that static initialization happens; this is PR#37226
|
||||
extern std::atomic_flag global;
|
||||
struct X { X() { global.test_and_set(); }};
|
||||
X x;
|
||||
std::atomic_flag global = ATOMIC_FLAG_INIT;
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if TEST_STD_VER >= 11
|
||||
assert(global.test_and_set() == 1);
|
||||
#endif
|
||||
{
|
||||
std::atomic_flag f(false);
|
||||
assert(f.test_and_set() == 0);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <clocale>
|
||||
#include <cmath>
|
||||
#include <codecvt>
|
||||
#include <compare>
|
||||
#include <complex>
|
||||
#include <complex.h>
|
||||
#include <condition_variable>
|
||||
@@ -129,6 +130,7 @@
|
||||
#include <valarray>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
#include <version>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
@@ -149,6 +151,7 @@
|
||||
#include <experimental/memory_resource>
|
||||
#include <experimental/propagate_const>
|
||||
#include <experimental/regex>
|
||||
#include <experimental/simd>
|
||||
#include <experimental/set>
|
||||
#include <experimental/string>
|
||||
#include <experimental/type_traits>
|
||||
|
||||
@@ -10,13 +10,15 @@
|
||||
// UNSUPPORTED: c++98, c++03
|
||||
// UNSUPPORTED: libcpp-no-exceptions
|
||||
|
||||
// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
|
||||
// MODULES_DEFINES: _LIBCPP_DEBUG=0
|
||||
|
||||
// <experimental/filesystem>
|
||||
|
||||
// class path
|
||||
|
||||
#define _LIBCPP_DEBUG 0
|
||||
#define _LIBCPP_ASSERT(cond, msg) ((cond) ? ((void)0) : throw 42)
|
||||
|
||||
#define _LIBCPP_DEBUG_USE_EXCEPTIONS
|
||||
#include <experimental/filesystem>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
@@ -29,17 +31,18 @@ namespace fs = std::experimental::filesystem;
|
||||
|
||||
int main() {
|
||||
using namespace fs;
|
||||
using ExType = std::__libcpp_debug_exception;
|
||||
// Test incrementing/decrementing a singular iterator
|
||||
{
|
||||
path::iterator singular;
|
||||
try {
|
||||
++singular;
|
||||
assert(false);
|
||||
} catch (int) {}
|
||||
} catch (ExType const&) {}
|
||||
try {
|
||||
--singular;
|
||||
assert(false);
|
||||
} catch (int) {}
|
||||
} catch (ExType const&) {}
|
||||
}
|
||||
// Test decrementing the begin iterator
|
||||
{
|
||||
@@ -48,13 +51,13 @@ int main() {
|
||||
try {
|
||||
--it;
|
||||
assert(false);
|
||||
} catch (int) {}
|
||||
} catch (ExType const&) {}
|
||||
++it;
|
||||
++it;
|
||||
try {
|
||||
++it;
|
||||
assert(false);
|
||||
} catch (int) {}
|
||||
} catch (ExType const&) {}
|
||||
}
|
||||
// Test incrementing the end iterator
|
||||
{
|
||||
@@ -63,12 +66,12 @@ int main() {
|
||||
try {
|
||||
++it;
|
||||
assert(false);
|
||||
} catch (int) {}
|
||||
} catch (ExType const&) {}
|
||||
--it;
|
||||
--it;
|
||||
try {
|
||||
--it;
|
||||
assert(false);
|
||||
} catch (int) {}
|
||||
} catch (ExType const&) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03
|
||||
|
||||
// <experimental/filesystem>
|
||||
|
||||
// class path
|
||||
|
||||
// path& operator/=(path const&)
|
||||
// path operator/(path const&, path const&)
|
||||
|
||||
|
||||
#define _LIBCPP_DEBUG 0
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (void)::AssertCount++)
|
||||
int AssertCount = 0;
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <type_traits>
|
||||
#include <string_view>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "count_new.hpp"
|
||||
#include "filesystem_test_helper.hpp"
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace fs;
|
||||
{
|
||||
path lhs("//foo");
|
||||
path rhs("/bar");
|
||||
assert(AssertCount == 0);
|
||||
lhs /= rhs;
|
||||
assert(AssertCount == 0);
|
||||
}
|
||||
{
|
||||
path lhs("//foo");
|
||||
path rhs("/bar");
|
||||
assert(AssertCount == 0);
|
||||
(void)(lhs / rhs);
|
||||
assert(AssertCount == 0);
|
||||
}
|
||||
{
|
||||
path lhs("//foo");
|
||||
path rhs("//bar");
|
||||
assert(AssertCount == 0);
|
||||
lhs /= rhs;
|
||||
assert(AssertCount == 1);
|
||||
AssertCount = 0;
|
||||
}
|
||||
{
|
||||
path lhs("//foo");
|
||||
path rhs("//bar");
|
||||
assert(AssertCount == 0);
|
||||
(void)(lhs / rhs);
|
||||
assert(AssertCount == 1);
|
||||
}
|
||||
// FIXME The same error is not diagnosed for the append(Source) and
|
||||
// append(It, It) overloads.
|
||||
}
|
||||
@@ -79,12 +79,12 @@ struct CountCopies {
|
||||
};
|
||||
|
||||
struct CountCopiesAllocV1 {
|
||||
typedef ex::memory_resource* allocator_type;
|
||||
allocator_type alloc;
|
||||
typedef ex::polymorphic_allocator<char> allocator_type;
|
||||
ex::memory_resource *alloc;
|
||||
int count;
|
||||
CountCopiesAllocV1() : alloc(nullptr), count(0) {}
|
||||
CountCopiesAllocV1(std::allocator_arg_t, allocator_type const& a,
|
||||
CountCopiesAllocV1 const& o) : alloc(a), count(o.count + 1)
|
||||
CountCopiesAllocV1 const& o) : alloc(a.resource()), count(o.count + 1)
|
||||
{}
|
||||
|
||||
CountCopiesAllocV1(CountCopiesAllocV1 const& o) : count(o.count + 1) {}
|
||||
@@ -92,12 +92,12 @@ struct CountCopiesAllocV1 {
|
||||
|
||||
|
||||
struct CountCopiesAllocV2 {
|
||||
typedef ex::memory_resource* allocator_type;
|
||||
allocator_type alloc;
|
||||
typedef ex::polymorphic_allocator<char> allocator_type;
|
||||
ex::memory_resource *alloc;
|
||||
int count;
|
||||
CountCopiesAllocV2() : alloc(nullptr), count(0) {}
|
||||
CountCopiesAllocV2(CountCopiesAllocV2 const& o, allocator_type const& a)
|
||||
: alloc(a), count(o.count + 1)
|
||||
: alloc(a.resource()), count(o.count + 1)
|
||||
{ }
|
||||
|
||||
CountCopiesAllocV2(CountCopiesAllocV2 const& o) : count(o.count + 1) {}
|
||||
|
||||
32
test/libcxx/iterators/failed.pass.cpp
Normal file
32
test/libcxx/iterators/failed.pass.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <iterator>
|
||||
|
||||
// class ostreambuf_iterator
|
||||
|
||||
// bool failed() const throw();
|
||||
//
|
||||
// Extension: constructing from NULL is UB; we just make it a failed iterator
|
||||
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::ostreambuf_iterator<char> i(nullptr);
|
||||
assert(i.failed());
|
||||
}
|
||||
{
|
||||
std::ostreambuf_iterator<wchar_t> i(nullptr);
|
||||
assert(i.failed());
|
||||
}
|
||||
}
|
||||
20
test/libcxx/language.support/cmp/version.pass.cpp
Normal file
20
test/libcxx/language.support/cmp/version.pass.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <compare>
|
||||
|
||||
#include <compare>
|
||||
|
||||
#ifndef _LIBCPP_VERSION
|
||||
#error _LIBCPP_VERSION not defined
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
20
test/libcxx/language.support/support.limits/version.pass.cpp
Normal file
20
test/libcxx/language.support/support.limits/version.pass.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <version>
|
||||
|
||||
#include <version>
|
||||
|
||||
#if !defined(_LIBCPP_VERSION)
|
||||
#error "_LIBCPP_VERSION must be defined after including <version>"
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
template <typename T>
|
||||
void test_allocators()
|
||||
{
|
||||
static_assert(!std::__is_allocator<T>::value, "" );
|
||||
static_assert( std::__is_allocator<std::allocator<T>>::value, "" );
|
||||
static_assert( std::__is_allocator<test_allocator<T>>::value, "" );
|
||||
static_assert( std::__is_allocator<min_allocator<T>>::value, "" );
|
||||
|
||||
81
test/libcxx/numerics/complex.number/__sqr.pass.cpp
Normal file
81
test/libcxx/numerics/complex.number/__sqr.pass.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <complex>
|
||||
|
||||
// template<class T>
|
||||
// complex<T>
|
||||
// __sqr(const complex<T>& x);
|
||||
|
||||
#include <complex>
|
||||
#include <cassert>
|
||||
|
||||
template <class T>
|
||||
void
|
||||
test()
|
||||
{
|
||||
const T tolerance = std::is_same<T, float>::value ? 1.e-6 : 1.e-14;
|
||||
|
||||
typedef std::complex<T> cplx;
|
||||
struct test_case
|
||||
{
|
||||
cplx value;
|
||||
cplx expected;
|
||||
};
|
||||
|
||||
const test_case cases[] = {
|
||||
{cplx( 0, 0), cplx( 0, 0)},
|
||||
{cplx( 1, 0), cplx( 1, 0)},
|
||||
{cplx( 2, 0), cplx( 4, 0)},
|
||||
{cplx(-1, 0), cplx( 1, 0)},
|
||||
{cplx( 0, 1), cplx(-1, 0)},
|
||||
{cplx( 0, 2), cplx(-4, 0)},
|
||||
{cplx( 0, -1), cplx(-1, 0)},
|
||||
{cplx( 1, 1), cplx( 0, 2)},
|
||||
{cplx( 1, -1), cplx( 0, -2)},
|
||||
{cplx(-1, -1), cplx( 0, 2)},
|
||||
{cplx(0.5, 0), cplx(0.25, 0)},
|
||||
};
|
||||
|
||||
const unsigned num_cases = sizeof(cases) / sizeof(test_case);
|
||||
for (unsigned i = 0; i < num_cases; ++i)
|
||||
{
|
||||
const test_case& test = cases[i];
|
||||
const std::complex<T> actual = std::__sqr(test.value);
|
||||
assert(std::abs(actual.real() - test.expected.real()) < tolerance);
|
||||
assert(std::abs(actual.imag() - test.expected.imag()) < tolerance);
|
||||
}
|
||||
|
||||
const cplx nan1 = std::__sqr(cplx(NAN, 0));
|
||||
assert(std::isnan(nan1.real()));
|
||||
assert(std::isnan(nan1.imag()));
|
||||
|
||||
const cplx nan2 = std::__sqr(cplx(0, NAN));
|
||||
assert(std::isnan(nan2.real()));
|
||||
assert(std::isnan(nan2.imag()));
|
||||
|
||||
const cplx nan3 = std::__sqr(cplx(NAN, NAN));
|
||||
assert(std::isnan(nan3.real()));
|
||||
assert(std::isnan(nan3.imag()));
|
||||
|
||||
const cplx inf1 = std::__sqr(cplx(INFINITY, 0));
|
||||
assert(std::isinf(inf1.real()));
|
||||
assert(inf1.real() > 0);
|
||||
|
||||
const cplx inf2 = std::__sqr(cplx(0, INFINITY));
|
||||
assert(std::isinf(inf2.real()));
|
||||
assert(inf2.real() < 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test<float>();
|
||||
test<double>();
|
||||
test<long double>();
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <string>
|
||||
|
||||
// Call __clear_and_shrink() and ensure string invariants hold
|
||||
|
||||
#if _LIBCPP_DEBUG >= 1
|
||||
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
|
||||
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string l = "Long string so that allocation definitely, for sure, absolutely happens. Probably.";
|
||||
std::string s = "short";
|
||||
|
||||
assert(l.__invariants());
|
||||
assert(s.__invariants());
|
||||
|
||||
s.__clear_and_shrink();
|
||||
assert(s.__invariants());
|
||||
assert(s.size() == 0);
|
||||
|
||||
{
|
||||
std::string::size_type cap = l.capacity();
|
||||
l.__clear_and_shrink();
|
||||
assert(l.__invariants());
|
||||
assert(l.size() == 0);
|
||||
assert(l.capacity() < cap);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -11,6 +11,12 @@
|
||||
// UNSUPPORTED: libcpp-has-no-threads
|
||||
// UNSUPPORTED: c++98, c++03
|
||||
|
||||
// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
|
||||
// MODULES_DEFINES: _LIBCPP_DEBUG=0
|
||||
|
||||
// Can't test the system lib because this test enables debug mode
|
||||
// UNSUPPORTED: with_system_cxx_lib
|
||||
|
||||
// <future>
|
||||
|
||||
// class promise<R>
|
||||
@@ -18,9 +24,8 @@
|
||||
// void set_exception(exception_ptr p);
|
||||
// Test that a null exception_ptr is diagnosed.
|
||||
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? ((void)0) : throw 42)
|
||||
|
||||
#define _LIBCPP_DEBUG 0
|
||||
#define _LIBCPP_DEBUG_USE_EXCEPTIONS
|
||||
#include <future>
|
||||
#include <exception>
|
||||
#include <cstdlib>
|
||||
@@ -29,14 +34,14 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef std::__libcpp_debug_exception ExType;
|
||||
{
|
||||
typedef int T;
|
||||
std::promise<T> p;
|
||||
try {
|
||||
p.set_exception(std::exception_ptr());
|
||||
assert(false);
|
||||
} catch (int const& value) {
|
||||
assert(value == 42);
|
||||
} catch (ExType const&) {
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -45,8 +50,7 @@ int main()
|
||||
try {
|
||||
p.set_exception(std::exception_ptr());
|
||||
assert(false);
|
||||
} catch (int const& value) {
|
||||
assert(value == 42);
|
||||
} catch (ExType const&) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
// UNSUPPORTED: libcpp-has-no-threads
|
||||
// UNSUPPORTED: c++98, c++03
|
||||
|
||||
// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
|
||||
// MODULES_DEFINES: _LIBCPP_DEBUG=0
|
||||
|
||||
// Can't test the system lib because this test enables debug mode
|
||||
// UNSUPPORTED: with_system_cxx_lib
|
||||
|
||||
// <future>
|
||||
|
||||
// class promise<R>
|
||||
@@ -18,9 +24,8 @@
|
||||
// void set_exception_on_thread_exit(exception_ptr p);
|
||||
// Test that a null exception_ptr is diagnosed.
|
||||
|
||||
#define _LIBCPP_ASSERT(x, m) ((x) ? ((void)0) : throw 42)
|
||||
|
||||
#define _LIBCPP_DEBUG 0
|
||||
#define _LIBCPP_DEBUG_USE_EXCEPTIONS
|
||||
#include <future>
|
||||
#include <exception>
|
||||
#include <cstdlib>
|
||||
@@ -29,14 +34,14 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef std::__libcpp_debug_exception ExType;
|
||||
{
|
||||
typedef int T;
|
||||
std::promise<T> p;
|
||||
try {
|
||||
p.set_exception_at_thread_exit(std::exception_ptr());
|
||||
assert(false);
|
||||
} catch (int const& value) {
|
||||
assert(value == 42);
|
||||
} catch (ExType const& value) {
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -45,8 +50,7 @@ int main()
|
||||
try {
|
||||
p.set_exception_at_thread_exit(std::exception_ptr());
|
||||
assert(false);
|
||||
} catch (int const& value) {
|
||||
assert(value == 42);
|
||||
} catch (ExType const& value) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
test/libcxx/type_traits/is_floating_point.pass.cpp
Normal file
24
test/libcxx/type_traits/is_floating_point.pass.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// <type_traits>
|
||||
//
|
||||
// Test that is_floating_point<T>::value is true when T=__fp16 or T=_Float16.
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
int main() {
|
||||
#ifdef __clang__
|
||||
static_assert(std::is_floating_point<__fp16>::value, "");
|
||||
#endif
|
||||
#ifdef __FLT16_MANT_DIG__
|
||||
static_assert(std::is_floating_point<_Float16>::value, "");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -21,58 +21,22 @@
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "archetypes.hpp"
|
||||
|
||||
// Clang warns about missing braces when initializing std::array.
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
#endif
|
||||
|
||||
struct CountingType {
|
||||
static int constructed;
|
||||
static int copy_constructed;
|
||||
static int move_constructed;
|
||||
static int assigned;
|
||||
static int copy_assigned;
|
||||
static int move_assigned;
|
||||
static void reset() {
|
||||
constructed = copy_constructed = move_constructed = 0;
|
||||
assigned = copy_assigned = move_assigned = 0;
|
||||
}
|
||||
CountingType() : value(0) { ++constructed; }
|
||||
CountingType(int v) : value(v) { ++constructed; }
|
||||
CountingType(CountingType const& o) : value(o.value) { ++constructed; ++copy_constructed; }
|
||||
CountingType(CountingType&& o) : value(o.value) { ++constructed; ++move_constructed; o.value = -1;}
|
||||
|
||||
CountingType& operator=(CountingType const& o) {
|
||||
++assigned;
|
||||
++copy_assigned;
|
||||
value = o.value;
|
||||
return *this;
|
||||
}
|
||||
CountingType& operator=(CountingType&& o) {
|
||||
++assigned;
|
||||
++move_assigned;
|
||||
value = o.value;
|
||||
o.value = -1;
|
||||
return *this;
|
||||
}
|
||||
int value;
|
||||
};
|
||||
int CountingType::constructed;
|
||||
int CountingType::copy_constructed;
|
||||
int CountingType::move_constructed;
|
||||
int CountingType::assigned;
|
||||
int CountingType::copy_assigned;
|
||||
int CountingType::move_assigned;
|
||||
|
||||
int main()
|
||||
{
|
||||
using C = CountingType;
|
||||
using C = TestTypes::TestType;
|
||||
{
|
||||
using P = std::pair<int, C>;
|
||||
using T = std::tuple<int, C>;
|
||||
T t(42, C{42});
|
||||
P p(101, C{101});
|
||||
C::reset();
|
||||
C::reset_constructors();
|
||||
p = t;
|
||||
assert(C::constructed == 0);
|
||||
assert(C::assigned == 1);
|
||||
@@ -86,7 +50,7 @@ int main()
|
||||
using T = std::tuple<int, C>;
|
||||
T t(42, -42);
|
||||
P p(101, 101);
|
||||
C::reset();
|
||||
C::reset_constructors();
|
||||
p = std::move(t);
|
||||
assert(C::constructed == 0);
|
||||
assert(C::assigned == 1);
|
||||
@@ -100,7 +64,7 @@ int main()
|
||||
using T = std::array<C, 2>;
|
||||
T t = {42, -42};
|
||||
P p{101, 101};
|
||||
C::reset();
|
||||
C::reset_constructors();
|
||||
p = t;
|
||||
assert(C::constructed == 0);
|
||||
assert(C::assigned == 2);
|
||||
@@ -114,7 +78,7 @@ int main()
|
||||
using T = std::array<C, 2>;
|
||||
T t = {42, -42};
|
||||
P p{101, 101};
|
||||
C::reset();
|
||||
C::reset_constructors();
|
||||
p = t;
|
||||
assert(C::constructed == 0);
|
||||
assert(C::assigned == 2);
|
||||
@@ -128,7 +92,7 @@ int main()
|
||||
using T = std::array<C, 2>;
|
||||
T t = {42, -42};
|
||||
P p{101, 101};
|
||||
C::reset();
|
||||
C::reset_constructors();
|
||||
p = std::move(t);
|
||||
assert(C::constructed == 0);
|
||||
assert(C::assigned == 2);
|
||||
@@ -22,6 +22,9 @@ config.sysroot = "@LIBCXX_SYSROOT@"
|
||||
config.gcc_toolchain = "@LIBCXX_GCC_TOOLCHAIN@"
|
||||
config.generate_coverage = "@LIBCXX_GENERATE_COVERAGE@"
|
||||
config.target_info = "@LIBCXX_TARGET_INFO@"
|
||||
config.test_linker_flags = "@LIBCXX_TEST_LINKER_FLAGS@"
|
||||
config.test_compiler_flags = "@LIBCXX_TEST_COMPILER_FLAGS@"
|
||||
|
||||
config.executor = "@LIBCXX_EXECUTOR@"
|
||||
config.llvm_unwinder = "@LIBCXXABI_USE_LLVM_UNWINDER@"
|
||||
config.compiler_rt = "@LIBCXX_USE_COMPILER_RT@"
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
// int ia[] = {1, 2, 3, 4, 5};
|
||||
// int ic[] = {6, 6, 6, 6, 6, 6, 6};
|
||||
//
|
||||
// auto p = std::copy(std::begin(ia), std::end(ia), std::begin(ic));
|
||||
// return std::equal(std::begin(ia), std::end(ia), std::begin(ic), p)
|
||||
// && std::all_of(p, std::end(ic), [](int a){return a == 6;})
|
||||
// ;
|
||||
// auto p = std::copy(std::begin(ia), std::end(ia), std::begin(ic));
|
||||
// return std::equal(std::begin(ia), std::end(ia), std::begin(ic), p)
|
||||
// && std::all_of(p, std::end(ic), [](int a){return a == 6;})
|
||||
// ;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
// int ia[] = {1, 2, 3, 4, 5};
|
||||
// int ic[] = {6, 6, 6, 6, 6, 6, 6};
|
||||
//
|
||||
// size_t N = std::size(ia);
|
||||
// auto p = std::copy_backward(std::begin(ia), std::end(ia), std::begin(ic) + N);
|
||||
// return std::equal(std::begin(ic), p, std::begin(ia))
|
||||
// && std::all_of(p, std::end(ic), [](int a){return a == 6;})
|
||||
// ;
|
||||
// size_t N = std::size(ia);
|
||||
// auto p = std::copy_backward(std::begin(ia), std::end(ia), std::begin(ic) + N);
|
||||
// return std::equal(std::begin(ic), p, std::begin(ia))
|
||||
// && std::all_of(p, std::end(ic), [](int a){return a == 6;})
|
||||
// ;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
// int ia[] = {2, 4, 6, 8, 6};
|
||||
// int ic[] = {0, 0, 0, 0, 0, 0};
|
||||
//
|
||||
// auto p = std::copy_if(std::begin(ia), std::end(ia), std::begin(ic), is6);
|
||||
// return std::all_of(std::begin(ic), p, [](int a){return a == 6;})
|
||||
// && std::all_of(p, std::end(ic), [](int a){return a == 0;})
|
||||
// ;
|
||||
// auto p = std::copy_if(std::begin(ia), std::end(ia), std::begin(ic), is6);
|
||||
// return std::all_of(std::begin(ic), p, [](int a){return a == 6;})
|
||||
// && std::all_of(p, std::end(ic), [](int a){return a == 0;})
|
||||
// ;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
// int ia[] = {1, 2, 3, 4, 5};
|
||||
// int ic[] = {6, 6, 6, 6, 6, 6, 6};
|
||||
//
|
||||
// auto p = std::copy_n(std::begin(ia), 4, std::begin(ic));
|
||||
// return std::equal(std::begin(ic), p, std::begin(ia))
|
||||
// && std::all_of(p, std::end(ic), [](int a){return a == 6;})
|
||||
// ;
|
||||
// auto p = std::copy_n(std::begin(ia), 4, std::begin(ic));
|
||||
// return std::equal(std::begin(ic), p, std::begin(ia))
|
||||
// && std::all_of(p, std::end(ic), [](int a){return a == 6;})
|
||||
// ;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
|
||||
@@ -15,14 +15,15 @@
|
||||
// constexpr void // constexpr after c++17
|
||||
// generate_n(Iter first, Size n, Generator gen);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "test_macros.h"
|
||||
|
||||
#ifdef TEST_COMPILER_C1XX
|
||||
#pragma warning(disable: 4244) // conversion from 'const double' to 'int', possible loss of data
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "user_defined_integral.hpp"
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
TEST_CONSTEXPR bool test_constexpr() {
|
||||
int ia[] = {0, 1, 1, 3, 4};
|
||||
const int expected[] = {0, 1, 3, 4};
|
||||
const size_t N = 4;
|
||||
const size_t N = 4;
|
||||
|
||||
auto it = std::unique(std::begin(ia), std::end(ia));
|
||||
return it == (std::begin(ia) + N)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
TEST_CONSTEXPR bool test_constexpr() {
|
||||
int ia[] = {0, 1, 1, 3, 4};
|
||||
const int expected[] = {0, 1, 3, 4};
|
||||
const size_t N = 4;
|
||||
const size_t N = 4;
|
||||
|
||||
auto it = std::unique(std::begin(ia), std::end(ia), [](int a, int b) {return a == b; });
|
||||
return it == (std::begin(ia) + N)
|
||||
|
||||
@@ -35,7 +35,7 @@ int main()
|
||||
assert(m.size() == 0);
|
||||
assert(distance(m.begin(), m.end()) == 0);
|
||||
|
||||
assert(mo.get_allocator() == A(7));
|
||||
assert(mo.get_allocator() == A(test_alloc_base::moved_value));
|
||||
assert(mo.key_comp() == C(5));
|
||||
assert(mo.size() == 0);
|
||||
assert(distance(mo.begin(), mo.end()) == 0);
|
||||
@@ -65,7 +65,7 @@ int main()
|
||||
assert(*next(m.begin()) == V(2, 1));
|
||||
assert(*next(m.begin(), 2) == V(3, 1));
|
||||
|
||||
assert(mo.get_allocator() == A(7));
|
||||
assert(mo.get_allocator() == A(test_alloc_base::moved_value));
|
||||
assert(mo.key_comp() == C(5));
|
||||
assert(mo.size() == 0);
|
||||
assert(distance(mo.begin(), mo.end()) == 0);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user