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:
Dan Albert
2018-06-21 15:12:15 -07:00
420 changed files with 22865 additions and 5227 deletions

View File

@@ -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)

View File

@@ -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.

View File

@@ -9,7 +9,7 @@ cd C:\projects\deps
:: Setup Compiler
::###########################################################################
if NOT EXIST llvm-installer.exe (
appveyor DownloadFile http://prereleases.llvm.org/win-snapshots/LLVM-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"

View File

@@ -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
)

View File

@@ -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());
}

View File

@@ -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();

View File

@@ -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)

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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()

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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);}

View File

@@ -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

View File

@@ -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
};

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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()));

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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 {}
};

View File

@@ -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:

View File

@@ -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
{

View File

@@ -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" );

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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>

View File

@@ -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,

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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 *

View File

@@ -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
}

View File

@@ -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

View File

@@ -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>&

View File

@@ -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,

View File

@@ -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>

View File

@@ -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
};

View File

@@ -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

View File

@@ -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>

View File

@@ -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");

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>()...));

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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
View 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

View File

@@ -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)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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
-----------

View File

@@ -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()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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>

View File

@@ -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&) {}
}
}

View File

@@ -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.
}

View File

@@ -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) {}

View 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());
}
}

View 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()
{
}

View 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()
{
}

View File

@@ -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, "" );

View 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>();
}

View File

@@ -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

View File

@@ -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&) {
}
}
}

View File

@@ -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) {
}
}
}

View 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;
}

View File

@@ -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);

View File

@@ -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@"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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)

View File

@@ -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)

View File

@@ -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