diff options
author | 2019-02-04 16:55:44 +0000 | |
---|---|---|
committer | 2019-02-04 16:55:44 +0000 | |
commit | 76c648e7a477ffb2a882ad5ffe523269bd9a3f6a (patch) | |
tree | 29d319d598650bab04e4f58e5e8769567e33091e /lib/libcxx/include | |
parent | Import libc++abi 7.0.1. (diff) | |
download | wireguard-openbsd-76c648e7a477ffb2a882ad5ffe523269bd9a3f6a.tar.xz wireguard-openbsd-76c648e7a477ffb2a882ad5ffe523269bd9a3f6a.zip |
Import libc++ 7.0.1.
Diffstat (limited to 'lib/libcxx/include')
96 files changed, 10810 insertions, 7240 deletions
diff --git a/lib/libcxx/include/CMakeLists.txt b/lib/libcxx/include/CMakeLists.txt index b98e09260ca..d9def18d725 100644 --- a/lib/libcxx/include/CMakeLists.txt +++ b/lib/libcxx/include/CMakeLists.txt @@ -1,58 +1,264 @@ -if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS) - set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE) -endif() - -set(LIBCXX_HEADER_PATTERN - PATTERN "*" - PATTERN "CMakeLists.txt" EXCLUDE - PATTERN ".svn" EXCLUDE - PATTERN "__config_site.in" EXCLUDE - ${LIBCXX_SUPPORT_HEADER_PATTERN} +set(files + __bit_reference + __bsd_locale_defaults.h + __bsd_locale_fallbacks.h + __errc + __debug + __functional_03 + __functional_base + __functional_base_03 + __hash_table + __libcpp_version + __locale + __mutex_base + __node_handle + __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 + charconv + 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 + filesystem + 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 + span + 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(NOT LIBCXX_USING_INSTALLED_LLVM AND LLVM_BINARY_DIR) - file(COPY . - DESTINATION "${LLVM_BINARY_DIR}/include/c++/v1" - FILES_MATCHING - ${LIBCXX_HEADER_PATTERN} +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() -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 +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 LIBCXX_HEADER_DIR) + set(output_dir ${LIBCXX_HEADER_DIR}/include/c++/v1) + + 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_HEADER_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 + DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1 PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ RENAME __config COMPONENT cxx-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 +267,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() diff --git a/lib/libcxx/include/__bsd_locale_fallbacks.h b/lib/libcxx/include/__bsd_locale_fallbacks.h index 5e9e0948307..3097b01410d 100644 --- a/lib/libcxx/include/__bsd_locale_fallbacks.h +++ b/lib/libcxx/include/__bsd_locale_fallbacks.h @@ -24,28 +24,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) { __libcpp_locale_guard __current(__l); return MB_CUR_MAX; } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_btowc_l(int __c, locale_t __l) { __libcpp_locale_guard __current(__l); return btowc(__c); } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY int __libcpp_wctob_l(wint_t __c, locale_t __l) { __libcpp_locale_guard __current(__l); return wctob(__c); } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, size_t __len, mbstate_t *__ps, locale_t __l) { @@ -53,14 +53,14 @@ size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, return wcsnrtombs(__dest, __src, __nwc, __len, __ps); } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) { __libcpp_locale_guard __current(__l); return wcrtomb(__s, __wc, __ps); } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, size_t __len, mbstate_t *__ps, locale_t __l) { @@ -68,7 +68,7 @@ size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, return mbsnrtowcs(__dest, __src, __nms, __len, __ps); } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) { @@ -76,28 +76,28 @@ size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, return mbrtowc(__pwc, __s, __n, __ps); } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) { __libcpp_locale_guard __current(__l); return mbtowc(__pwc, __pmb, __max); } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) { __libcpp_locale_guard __current(__l); return mbrlen(__s, __n, __ps); } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY lconv *__libcpp_localeconv_l(locale_t __l) { __libcpp_locale_guard __current(__l); return localeconv(); } -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, mbstate_t *__ps, locale_t __l) { diff --git a/lib/libcxx/include/__config_site.in b/lib/libcxx/include/__config_site.in index 86418a3e17b..7c7c226c492 100644 --- a/lib/libcxx/include/__config_site.in +++ b/lib/libcxx/include/__config_site.in @@ -14,6 +14,7 @@ #cmakedefine _LIBCPP_ABI_UNSTABLE #cmakedefine _LIBCPP_ABI_FORCE_ITANIUM #cmakedefine _LIBCPP_ABI_FORCE_MICROSOFT +#cmakedefine _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT #cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE #cmakedefine _LIBCPP_HAS_NO_STDIN #cmakedefine _LIBCPP_HAS_NO_STDOUT @@ -23,6 +24,7 @@ #cmakedefine _LIBCPP_HAS_MUSL_LIBC #cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD #cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL +#cmakedefine _LIBCPP_HAS_THREAD_API_WIN32 #cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL #cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS #cmakedefine _LIBCPP_NO_VCRUNTIME diff --git a/lib/libcxx/include/__errc b/lib/libcxx/include/__errc new file mode 100644 index 00000000000..d0f00b7f0be --- /dev/null +++ b/lib/libcxx/include/__errc @@ -0,0 +1,218 @@ +// -*- C++ -*- +//===---------------------------- __errc ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ERRC +#define _LIBCPP___ERRC + +/* + system_error synopsis + +namespace std +{ + +enum class errc +{ + address_family_not_supported, // EAFNOSUPPORT + address_in_use, // EADDRINUSE + address_not_available, // EADDRNOTAVAIL + already_connected, // EISCONN + argument_list_too_long, // E2BIG + argument_out_of_domain, // EDOM + bad_address, // EFAULT + bad_file_descriptor, // EBADF + bad_message, // EBADMSG + broken_pipe, // EPIPE + connection_aborted, // ECONNABORTED + connection_already_in_progress, // EALREADY + connection_refused, // ECONNREFUSED + connection_reset, // ECONNRESET + cross_device_link, // EXDEV + destination_address_required, // EDESTADDRREQ + device_or_resource_busy, // EBUSY + directory_not_empty, // ENOTEMPTY + executable_format_error, // ENOEXEC + file_exists, // EEXIST + file_too_large, // EFBIG + filename_too_long, // ENAMETOOLONG + function_not_supported, // ENOSYS + host_unreachable, // EHOSTUNREACH + identifier_removed, // EIDRM + illegal_byte_sequence, // EILSEQ + inappropriate_io_control_operation, // ENOTTY + interrupted, // EINTR + invalid_argument, // EINVAL + invalid_seek, // ESPIPE + io_error, // EIO + is_a_directory, // EISDIR + message_size, // EMSGSIZE + network_down, // ENETDOWN + network_reset, // ENETRESET + network_unreachable, // ENETUNREACH + no_buffer_space, // ENOBUFS + no_child_process, // ECHILD + no_link, // ENOLINK + no_lock_available, // ENOLCK + no_message_available, // ENODATA + no_message, // ENOMSG + no_protocol_option, // ENOPROTOOPT + no_space_on_device, // ENOSPC + no_stream_resources, // ENOSR + no_such_device_or_address, // ENXIO + no_such_device, // ENODEV + no_such_file_or_directory, // ENOENT + no_such_process, // ESRCH + not_a_directory, // ENOTDIR + not_a_socket, // ENOTSOCK + not_a_stream, // ENOSTR + not_connected, // ENOTCONN + not_enough_memory, // ENOMEM + not_supported, // ENOTSUP + operation_canceled, // ECANCELED + operation_in_progress, // EINPROGRESS + operation_not_permitted, // EPERM + operation_not_supported, // EOPNOTSUPP + operation_would_block, // EWOULDBLOCK + owner_dead, // EOWNERDEAD + permission_denied, // EACCES + protocol_error, // EPROTO + protocol_not_supported, // EPROTONOSUPPORT + read_only_file_system, // EROFS + resource_deadlock_would_occur, // EDEADLK + resource_unavailable_try_again, // EAGAIN + result_out_of_range, // ERANGE + state_not_recoverable, // ENOTRECOVERABLE + stream_timeout, // ETIME + text_file_busy, // ETXTBSY + timed_out, // ETIMEDOUT + too_many_files_open_in_system, // ENFILE + too_many_files_open, // EMFILE + too_many_links, // EMLINK + too_many_symbolic_link_levels, // ELOOP + value_too_large, // EOVERFLOW + wrong_protocol_type // EPROTOTYPE +}; + +*/ + +#include <__config> +#include <cerrno> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Some error codes are not present on all platforms, so we provide equivalents +// for them: + +//enum class errc +_LIBCPP_DECLARE_STRONG_ENUM(errc) +{ + address_family_not_supported = EAFNOSUPPORT, + address_in_use = EADDRINUSE, + address_not_available = EADDRNOTAVAIL, + already_connected = EISCONN, + argument_list_too_long = E2BIG, + argument_out_of_domain = EDOM, + bad_address = EFAULT, + bad_file_descriptor = EBADF, + bad_message = EBADMSG, + broken_pipe = EPIPE, + connection_aborted = ECONNABORTED, + connection_already_in_progress = EALREADY, + connection_refused = ECONNREFUSED, + connection_reset = ECONNRESET, + cross_device_link = EXDEV, + destination_address_required = EDESTADDRREQ, + device_or_resource_busy = EBUSY, + directory_not_empty = ENOTEMPTY, + executable_format_error = ENOEXEC, + file_exists = EEXIST, + file_too_large = EFBIG, + filename_too_long = ENAMETOOLONG, + function_not_supported = ENOSYS, + host_unreachable = EHOSTUNREACH, + identifier_removed = EIDRM, + illegal_byte_sequence = EILSEQ, + inappropriate_io_control_operation = ENOTTY, + interrupted = EINTR, + invalid_argument = EINVAL, + invalid_seek = ESPIPE, + io_error = EIO, + is_a_directory = EISDIR, + message_size = EMSGSIZE, + network_down = ENETDOWN, + network_reset = ENETRESET, + network_unreachable = ENETUNREACH, + no_buffer_space = ENOBUFS, + no_child_process = ECHILD, + no_link = ENOLINK, + no_lock_available = ENOLCK, +#ifdef ENODATA + no_message_available = ENODATA, +#else + no_message_available = ENOMSG, +#endif + no_message = ENOMSG, + no_protocol_option = ENOPROTOOPT, + no_space_on_device = ENOSPC, +#ifdef ENOSR + no_stream_resources = ENOSR, +#else + no_stream_resources = ENOMEM, +#endif + no_such_device_or_address = ENXIO, + no_such_device = ENODEV, + no_such_file_or_directory = ENOENT, + no_such_process = ESRCH, + not_a_directory = ENOTDIR, + not_a_socket = ENOTSOCK, +#ifdef ENOSTR + not_a_stream = ENOSTR, +#else + not_a_stream = EINVAL, +#endif + not_connected = ENOTCONN, + not_enough_memory = ENOMEM, + not_supported = ENOTSUP, + operation_canceled = ECANCELED, + operation_in_progress = EINPROGRESS, + operation_not_permitted = EPERM, + operation_not_supported = EOPNOTSUPP, + operation_would_block = EWOULDBLOCK, + owner_dead = EOWNERDEAD, + permission_denied = EACCES, + protocol_error = EPROTO, + protocol_not_supported = EPROTONOSUPPORT, + read_only_file_system = EROFS, + resource_deadlock_would_occur = EDEADLK, + resource_unavailable_try_again = EAGAIN, + result_out_of_range = ERANGE, + state_not_recoverable = ENOTRECOVERABLE, +#ifdef ETIME + stream_timeout = ETIME, +#else + stream_timeout = ETIMEDOUT, +#endif + text_file_busy = ETXTBSY, + timed_out = ETIMEDOUT, + too_many_files_open_in_system = ENFILE, + too_many_files_open = EMFILE, + too_many_links = EMLINK, + too_many_symbolic_link_levels = ELOOP, + value_too_large = EOVERFLOW, + wrong_protocol_type = EPROTOTYPE +}; +_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ERRC diff --git a/lib/libcxx/include/__functional_03 b/lib/libcxx/include/__functional_03 index 13d8a3d9600..0a3bfbaa3d2 100644 --- a/lib/libcxx/include/__functional_03 +++ b/lib/libcxx/include/__functional_03 @@ -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; } diff --git a/lib/libcxx/include/__functional_base b/lib/libcxx/include/__functional_base index 12af4dc9675..57fdf2b9f66 100644 --- a/lib/libcxx/include/__functional_base +++ b/lib/libcxx/include/__functional_base @@ -561,7 +561,7 @@ struct __is_transparent<_Tp, _Up, struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { }; -#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_MEMORY) +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) extern const allocator_arg_t allocator_arg; #else /* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t(); @@ -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 diff --git a/lib/libcxx/include/__hash_table b/lib/libcxx/include/__hash_table index 3f430af1283..c77de961be6 100644 --- a/lib/libcxx/include/__hash_table +++ b/lib/libcxx/include/__hash_table @@ -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 @@ -865,6 +859,17 @@ public: template <class> friend class __hash_map_node_destructor; }; +#if _LIBCPP_STD_VER > 14 +template <class _NodeType, class _Alloc> +struct __generic_container_node_destructor; + +template <class _Tp, class _VoidPtr, class _Alloc> +struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> + : __hash_node_destructor<_Alloc> +{ + using __hash_node_destructor<_Alloc>::__hash_node_destructor; +}; +#endif #ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Hash, class _Equal, class _Alloc> @@ -1157,6 +1162,30 @@ public: return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); } +#if _LIBCPP_STD_VER > 14 + template <class _NodeHandle, class _InsertReturnType> + _LIBCPP_INLINE_VISIBILITY + _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_unique(const_iterator __hint, + _NodeHandle&& __nh); + + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(_NodeHandle&& __nh); + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); + + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(key_type const& __key); + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(const_iterator __it); +#endif + void clear() _NOEXCEPT; void rehash(size_type __n); _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) @@ -2132,6 +2161,91 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, #endif // _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 14 +template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _NodeHandle, class _InsertReturnType> +_LIBCPP_INLINE_VISIBILITY +_InsertReturnType +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( + _NodeHandle&& __nh) +{ + if (__nh.empty()) + return _InsertReturnType{end(), false, _NodeHandle()}; + pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release(); + return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)}; +} + +template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( + const_iterator, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release(); + return __result.first; +} + +template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( + key_type const& __key) +{ + iterator __i = find(__key); + if (__i == end()) + return _NodeHandle(); + return __node_handle_extract<_NodeHandle>(__i); +} + +template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( + const_iterator __p) +{ + allocator_type __alloc(__node_alloc()); + return _NodeHandle(remove(__p).release(), __alloc); +} + +template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( + _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__nh.__ptr_); + __nh.__release(); + return __result; +} + +template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( + const_iterator __hint, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__hint, __nh.__ptr_); + __nh.__release(); + return __result; +} + +#endif // _LIBCPP_STD_VER > 14 + template <class _Tp, class _Hash, class _Equal, class _Alloc> void __hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n) diff --git a/lib/libcxx/include/__libcpp_version b/lib/libcxx/include/__libcpp_version index a77fd92cf17..2bdc6533bec 100644 --- a/lib/libcxx/include/__libcpp_version +++ b/lib/libcxx/include/__libcpp_version @@ -1 +1 @@ -6000 +7000 diff --git a/lib/libcxx/include/__mutex_base b/lib/libcxx/include/__mutex_base index 402a52d945e..4659ca9298c 100644 --- a/lib/libcxx/include/__mutex_base +++ b/lib/libcxx/include/__mutex_base @@ -74,7 +74,7 @@ struct _LIBCPP_TYPE_VIS defer_lock_t {}; struct _LIBCPP_TYPE_VIS try_to_lock_t {}; struct _LIBCPP_TYPE_VIS adopt_lock_t {}; -#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_MUTEX) +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) extern const defer_lock_t defer_lock; extern const try_to_lock_t try_to_lock; diff --git a/lib/libcxx/include/__node_handle b/lib/libcxx/include/__node_handle new file mode 100644 index 00000000000..567f8b047a3 --- /dev/null +++ b/lib/libcxx/include/__node_handle @@ -0,0 +1,213 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___NODE_HANDLE +#define _LIBCPP___NODE_HANDLE + +#include <__config> +#include <memory> +#include <optional> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +// FIXME: Uncomment this when we support the 'merge' functionality. +// #define __cpp_lib_node_extract 201606L + +// Specialized in __tree & __hash_table for their _NodeType. +template <class _NodeType, class _Alloc> +struct __generic_container_node_destructor; + +template <class _NodeType, class _Alloc, + template <class, class> class _MapOrSetSpecifics> +class _LIBCPP_TEMPLATE_VIS __basic_node_handle + : public _MapOrSetSpecifics< + _NodeType, + __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>> +{ + template <class _Tp, class _Compare, class _Allocator> + friend class __tree; + template <class _Tp, class _Hash, class _Equal, class _Allocator> + friend class __hash_table; + friend struct _MapOrSetSpecifics< + _NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>; + + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_pointer<typename __alloc_traits::void_pointer, + _NodeType>::type + __node_pointer_type; + +public: + typedef _Alloc allocator_type; + +private: + __node_pointer_type __ptr_ = nullptr; + optional<allocator_type> __alloc_; + + _LIBCPP_INLINE_VISIBILITY + void __release() + { + __ptr_ = nullptr; + __alloc_ = _VSTD::nullopt; + } + + _LIBCPP_INLINE_VISIBILITY + void __destroy_node_pointer() + { + if (__ptr_ != nullptr) + { + typedef typename __allocator_traits_rebind< + allocator_type, _NodeType>::type __node_alloc_type; + __node_alloc_type __alloc(*__alloc_); + __generic_container_node_destructor<_NodeType, __node_alloc_type>( + __alloc, true)(__ptr_); + __ptr_ = nullptr; + } + } + + _LIBCPP_INLINE_VISIBILITY + __basic_node_handle(__node_pointer_type __ptr, + allocator_type const& __alloc) + : __ptr_(__ptr), __alloc_(__alloc) + { + } + +public: + _LIBCPP_INLINE_VISIBILITY + __basic_node_handle() = default; + + _LIBCPP_INLINE_VISIBILITY + __basic_node_handle(__basic_node_handle&& __other) noexcept + : __ptr_(__other.__ptr_), + __alloc_(_VSTD::move(__other.__alloc_)) + { + __other.__ptr_ = nullptr; + __other.__alloc_ = _VSTD::nullopt; + } + + _LIBCPP_INLINE_VISIBILITY + __basic_node_handle& operator=(__basic_node_handle&& __other) + { + _LIBCPP_ASSERT( + __alloc_ == _VSTD::nullopt || + __alloc_traits::propagate_on_container_move_assignment::value || + __alloc_ == __other.__alloc_, + "node_type with incompatible allocator passed to " + "node_type::operator=(node_type&&)"); + + __destroy_node_pointer(); + __ptr_ = __other.__ptr_; + + if (__alloc_traits::propagate_on_container_move_assignment::value || + __alloc_ == _VSTD::nullopt) + __alloc_ = _VSTD::move(__other.__alloc_); + + __other.__ptr_ = nullptr; + __other.__alloc_ = _VSTD::nullopt; + + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const { return *__alloc_; } + + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const { return __ptr_ != nullptr; } + + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + bool empty() const { return __ptr_ == nullptr; } + + _LIBCPP_INLINE_VISIBILITY + void swap(__basic_node_handle& __other) noexcept( + __alloc_traits::propagate_on_container_swap::value || + __alloc_traits::is_always_equal::value) + { + using _VSTD::swap; + swap(__ptr_, __other.__ptr_); + if (__alloc_traits::propagate_on_container_swap::value || + __alloc_ == _VSTD::nullopt || __other.__alloc_ == _VSTD::nullopt) + swap(__alloc_, __other.__alloc_); + } + + _LIBCPP_INLINE_VISIBILITY + friend void swap(__basic_node_handle& __a, __basic_node_handle& __b) + noexcept(noexcept(__a.swap(__b))) { __a.swap(__b); } + + _LIBCPP_INLINE_VISIBILITY + ~__basic_node_handle() + { + __destroy_node_pointer(); + } +}; + +template <class _NodeType, class _Derived> +struct __set_node_handle_specifics +{ + typedef typename _NodeType::__node_value_type value_type; + + _LIBCPP_INLINE_VISIBILITY + value_type& value() const + { + return static_cast<_Derived const*>(this)->__ptr_->__value_; + } +}; + +template <class _NodeType, class _Derived> +struct __map_node_handle_specifics +{ + typedef typename _NodeType::__node_value_type::key_type key_type; + typedef typename _NodeType::__node_value_type::mapped_type mapped_type; + + _LIBCPP_INLINE_VISIBILITY + key_type& key() const + { + return static_cast<_Derived const*>(this)-> + __ptr_->__value_.__ref().first; + } + + _LIBCPP_INLINE_VISIBILITY + mapped_type& mapped() const + { + return static_cast<_Derived const*>(this)-> + __ptr_->__value_.__ref().second; + } +}; + +template <class _NodeType, class _Alloc> +using __set_node_handle = + __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>; + +template <class _NodeType, class _Alloc> +using __map_node_handle = + __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>; + +template <class _Iterator, class _NodeType> +_LIBCPP_TEMPLATE_VIS +struct __insert_return_type +{ + _Iterator position; + bool inserted; + _NodeType node; +}; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + +#endif diff --git a/lib/libcxx/include/__nullptr b/lib/libcxx/include/__nullptr index a341234f5d1..aa3b4d2145a 100644 --- a/lib/libcxx/include/__nullptr +++ b/lib/libcxx/include/__nullptr @@ -27,24 +27,24 @@ struct _LIBCPP_TEMPLATE_VIS nullptr_t struct __nat {int __for_bool_;}; - _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {} - _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {} - _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;} template <class _Tp> - _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator _Tp* () const {return 0;} template <class _Tp, class _Up> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY operator _Tp _Up::* () const {return 0;} - friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;} - friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;} + friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;} + friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;} }; -inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);} #define nullptr _VSTD::__get_nullptr_t() diff --git a/lib/libcxx/include/__sso_allocator b/lib/libcxx/include/__sso_allocator index 8147e75ec2c..40027363a18 100644 --- a/lib/libcxx/include/__sso_allocator +++ b/lib/libcxx/include/__sso_allocator @@ -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);} diff --git a/lib/libcxx/include/__string b/lib/libcxx/include/__string index d30c7fddc8d..44c55987f9f 100644 --- a/lib/libcxx/include/__string +++ b/lib/libcxx/include/__string @@ -266,7 +266,7 @@ const char* char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT { if (__n == 0) - return NULL; + return nullptr; #if __has_feature(cxx_constexpr_string_builtins) return __builtin_char_memchr(__s, to_int_type(__a), __n); #elif _LIBCPP_STD_VER <= 14 @@ -278,7 +278,7 @@ char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) return __s; ++__s; } - return NULL; + return nullptr; #endif } @@ -372,9 +372,9 @@ const wchar_t* char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT { if (__n == 0) - return NULL; + return nullptr; #if __has_feature(cxx_constexpr_string_builtins) - return __builtin_wmemchr(__s, __a, __n); + return __builtin_wmemchr(__s, __a, __n); #elif _LIBCPP_STD_VER <= 14 return wmemchr(__s, __a, __n); #else @@ -384,7 +384,7 @@ char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __ return __s; ++__s; } - return NULL; + return nullptr; #endif } diff --git a/lib/libcxx/include/__threading_support b/lib/libcxx/include/__threading_support index 5d4c907966e..3c1eff22f53 100644 --- a/lib/libcxx/include/__threading_support +++ b/lib/libcxx/include/__threading_support @@ -26,18 +26,14 @@ #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) # include <pthread.h> # include <sched.h> -#elif defined(_LIBCPP_HAS_THREAD_API_WIN32) -#include <windows.h> -#include <process.h> -#include <fibersapi.h> #endif _LIBCPP_PUSH_MACROS #include <__undef_macros> - #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ - defined(_LIBCPP_BUILDING_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 @@ -80,31 +76,37 @@ typedef pthread_key_t __libcpp_tls_key; #define _LIBCPP_TLS_DESTRUCTOR_CC #else // Mutex -typedef SRWLOCK __libcpp_mutex_t; -#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT +typedef void* __libcpp_mutex_t; +#define _LIBCPP_MUTEX_INITIALIZER 0 -typedef CRITICAL_SECTION __libcpp_recursive_mutex_t; +#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) +typedef void* __libcpp_recursive_mutex_t[6]; +#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) +typedef void* __libcpp_recursive_mutex_t[5]; +#else +# error Unsupported architecture +#endif // Condition Variable -typedef CONDITION_VARIABLE __libcpp_condvar_t; -#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT +typedef void* __libcpp_condvar_t; +#define _LIBCPP_CONDVAR_INITIALIZER 0 // Execute Once -typedef INIT_ONCE __libcpp_exec_once_flag; -#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT +typedef void* __libcpp_exec_once_flag; +#define _LIBCPP_EXEC_ONCE_INITIALIZER 0 // Thread ID -typedef DWORD __libcpp_thread_id; +typedef long __libcpp_thread_id; // Thread #define _LIBCPP_NULL_THREAD 0U -typedef HANDLE __libcpp_thread_t; +typedef void* __libcpp_thread_t; // Thread Local Storage -typedef DWORD __libcpp_tls_key; +typedef long __libcpp_tls_key; -#define _LIBCPP_TLS_DESTRUCTOR_CC WINAPI +#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall #endif // Mutex @@ -201,10 +203,9 @@ void *__libcpp_tls_get(__libcpp_tls_key __key); _LIBCPP_THREAD_ABI_VISIBILITY int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); -#if !defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ - defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) - -#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ + defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \ + defined(_LIBCPP_HAS_THREAD_API_PTHREAD) int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) { @@ -390,244 +391,6 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) return pthread_setspecific(__key, __p); } -#elif defined(_LIBCPP_HAS_THREAD_API_WIN32) - -// Mutex -int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) -{ - InitializeCriticalSection(__m); - return 0; -} - -int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) -{ - EnterCriticalSection(__m); - return 0; -} - -bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) -{ - return TryEnterCriticalSection(__m) != 0; -} - -int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m) -{ - LeaveCriticalSection(__m); - return 0; -} - -int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) -{ - DeleteCriticalSection(__m); - return 0; -} - -int __libcpp_mutex_lock(__libcpp_mutex_t *__m) -{ - AcquireSRWLockExclusive(__m); - return 0; -} - -bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) -{ - return TryAcquireSRWLockExclusive(__m) != 0; -} - -int __libcpp_mutex_unlock(__libcpp_mutex_t *__m) -{ - ReleaseSRWLockExclusive(__m); - return 0; -} - -int __libcpp_mutex_destroy(__libcpp_mutex_t *__m) -{ - static_cast<void>(__m); - return 0; -} - -// Condition Variable -int __libcpp_condvar_signal(__libcpp_condvar_t *__cv) -{ - WakeConditionVariable(__cv); - return 0; -} - -int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) -{ - WakeAllConditionVariable(__cv); - return 0; -} - -int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) -{ - SleepConditionVariableSRW(__cv, __m, INFINITE, 0); - return 0; -} - -int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, - timespec *__ts) -{ - using namespace _VSTD::chrono; - - auto duration = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec); - auto abstime = - system_clock::time_point(duration_cast<system_clock::duration>(duration)); - auto timeout_ms = duration_cast<milliseconds>(abstime - system_clock::now()); - - if (!SleepConditionVariableSRW(__cv, __m, - timeout_ms.count() > 0 ? timeout_ms.count() - : 0, - 0)) - { - auto __ec = GetLastError(); - return __ec == ERROR_TIMEOUT ? ETIMEDOUT : __ec; - } - return 0; -} - -int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) -{ - static_cast<void>(__cv); - return 0; -} - -// Execute Once -static inline _LIBCPP_ALWAYS_INLINE BOOL CALLBACK -__libcpp_init_once_execute_once_thunk(PINIT_ONCE __init_once, PVOID __parameter, - PVOID *__context) -{ - static_cast<void>(__init_once); - static_cast<void>(__context); - - void (*init_routine)(void) = reinterpret_cast<void (*)(void)>(__parameter); - init_routine(); - return TRUE; -} - -int __libcpp_execute_once(__libcpp_exec_once_flag *__flag, - void (*__init_routine)(void)) -{ - if (!InitOnceExecuteOnce(__flag, __libcpp_init_once_execute_once_thunk, - reinterpret_cast<void *>(__init_routine), NULL)) - return GetLastError(); - return 0; -} - -// Thread ID -bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs, - __libcpp_thread_id __rhs) -{ - return __lhs == __rhs; -} - -bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs) -{ - return __lhs < __rhs; -} - -// Thread -struct __libcpp_beginthreadex_thunk_data -{ - void *(*__func)(void *); - void *__arg; -}; - -static inline _LIBCPP_ALWAYS_INLINE unsigned WINAPI -__libcpp_beginthreadex_thunk(void *__raw_data) -{ - auto *__data = - static_cast<__libcpp_beginthreadex_thunk_data *>(__raw_data); - auto *__func = __data->__func; - void *__arg = __data->__arg; - delete __data; - return static_cast<unsigned>(reinterpret_cast<uintptr_t>(__func(__arg))); -} - -bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { - return *__t == 0; -} - -int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), - void *__arg) -{ - auto *__data = new __libcpp_beginthreadex_thunk_data; - __data->__func = __func; - __data->__arg = __arg; - - *__t = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, - __libcpp_beginthreadex_thunk, - __data, 0, nullptr)); - - if (*__t) - return 0; - return GetLastError(); -} - -__libcpp_thread_id __libcpp_thread_get_current_id() -{ - return GetCurrentThreadId(); -} - -__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) -{ - return GetThreadId(*__t); -} - -int __libcpp_thread_join(__libcpp_thread_t *__t) -{ - if (WaitForSingleObjectEx(*__t, INFINITE, FALSE) == WAIT_FAILED) - return GetLastError(); - if (!CloseHandle(*__t)) - return GetLastError(); - return 0; -} - -int __libcpp_thread_detach(__libcpp_thread_t *__t) -{ - if (!CloseHandle(*__t)) - return GetLastError(); - return 0; -} - -void __libcpp_thread_yield() -{ - SwitchToThread(); -} - -void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) -{ - using namespace chrono; - // round-up to the nearest milisecond - milliseconds __ms = - duration_cast<milliseconds>(__ns + chrono::nanoseconds(999999)); - // FIXME(compnerd) this should be an alertable sleep (WFSO or SleepEx) - Sleep(__ms.count()); -} - -// Thread Local Storage -int __libcpp_tls_create(__libcpp_tls_key* __key, - void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)) -{ - *__key = FlsAlloc(__at_exit); - if (*__key == FLS_OUT_OF_INDEXES) - return GetLastError(); - return 0; -} - -void *__libcpp_tls_get(__libcpp_tls_key __key) -{ - return FlsGetValue(__key); -} - -int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) -{ - if (!FlsSetValue(__key, __p)) - return GetLastError(); - return 0; -} - -#endif // _LIBCPP_HAS_THREAD_API_PTHREAD - #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL _LIBCPP_END_NAMESPACE_STD diff --git a/lib/libcxx/include/__tree b/lib/libcxx/include/__tree index 3ccfcb70031..af9b9616df8 100644 --- a/lib/libcxx/include/__tree +++ b/lib/libcxx/include/__tree @@ -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 }; @@ -803,6 +796,16 @@ public: template <class> friend class __map_node_destructor; }; +#if _LIBCPP_STD_VER > 14 +template <class _NodeType, class _Alloc> +struct __generic_container_node_destructor; +template <class _Tp, class _VoidPtr, class _Alloc> +struct __generic_container_node_destructor<__tree_node<_Tp, _VoidPtr>, _Alloc> + : __tree_node_destructor<_Alloc> +{ + using __tree_node_destructor<_Alloc>::__tree_node_destructor; +}; +#endif template <class _Tp, class _NodePtr, class _DiffType> class _LIBCPP_TEMPLATE_VIS __tree_iterator @@ -1345,6 +1348,33 @@ public: iterator __node_insert_multi(__node_pointer __nd); iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); + + _LIBCPP_INLINE_VISIBILITY iterator __remove_node_pointer(__node_pointer); + +#if _LIBCPP_STD_VER > 14 + template <class _NodeHandle, class _InsertReturnType> + _LIBCPP_INLINE_VISIBILITY + _InsertReturnType __node_handle_insert_unique(_NodeHandle&&); + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&); + + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(_NodeHandle&&); + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&); + + + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(key_type const&); + template <class _NodeHandle> + _LIBCPP_INLINE_VISIBILITY + _NodeHandle __node_handle_extract(const_iterator); +#endif + iterator erase(const_iterator __p); iterator erase(const_iterator __f, const_iterator __l); template <class _Key> @@ -2354,17 +2384,138 @@ __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) +__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) { - __node_pointer __np = __p.__get_np(); - iterator __r(__p.__ptr_); + iterator __r(__ptr); ++__r; - if (__begin_node() == __p.__ptr_) + if (__begin_node() == __ptr) __begin_node() = __r.__ptr_; --size(); - __node_allocator& __na = __node_alloc(); __tree_remove(__end_node()->__left_, - static_cast<__node_base_pointer>(__np)); + static_cast<__node_base_pointer>(__ptr)); + return __r; +} + +#if _LIBCPP_STD_VER > 14 +template <class _Tp, class _Compare, class _Allocator> +template <class _NodeHandle, class _InsertReturnType> +_LIBCPP_INLINE_VISIBILITY +_InsertReturnType +__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique( + _NodeHandle&& __nh) +{ + if (__nh.empty()) + return _InsertReturnType{end(), false, _NodeHandle()}; + + __node_pointer __ptr = __nh.__ptr_; + __parent_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, + __ptr->__value_); + if (__child != nullptr) + return _InsertReturnType{ + iterator(static_cast<__node_pointer>(__child)), + false, _VSTD::move(__nh)}; + + __insert_node_at(__parent, __child, + static_cast<__node_base_pointer>(__ptr)); + __nh.__release(); + return _InsertReturnType{iterator(__ptr), true, _NodeHandle()}; +} + +template <class _Tp, class _Compare, class _Allocator> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique( + const_iterator __hint, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + + __node_pointer __ptr = __nh.__ptr_; + __parent_pointer __parent; + __node_base_pointer __dummy; + __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, + __ptr->__value_); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { + __insert_node_at(__parent, __child, + static_cast<__node_base_pointer>(__ptr)); + __r = __ptr; + __nh.__release(); + } + return iterator(__r); +} + +template <class _Tp, class _Compare, class _Allocator> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key) +{ + iterator __it = find(__key); + if (__it == end()) + return _NodeHandle(); + return __node_handle_extract<_NodeHandle>(__it); +} + +template <class _Tp, class _Compare, class _Allocator> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +_NodeHandle +__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p) +{ + __node_pointer __np = __p.__get_np(); + __remove_node_pointer(__np); + return _NodeHandle(__np, __alloc()); +} + +template <class _Tp, class _Compare, class _Allocator> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + __node_pointer __ptr = __nh.__ptr_; + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high( + __parent, _NodeTypes::__get_key(__ptr->__value_)); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); + __nh.__release(); + return iterator(__ptr); +} + +template <class _Tp, class _Compare, class _Allocator> +template <class _NodeHandle> +_LIBCPP_INLINE_VISIBILITY +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi( + const_iterator __hint, _NodeHandle&& __nh) +{ + if (__nh.empty()) + return end(); + + __node_pointer __ptr = __nh.__ptr_; + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__hint, __parent, + _NodeTypes::__get_key(__ptr->__value_)); + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr)); + __nh.__release(); + return iterator(__ptr); +} + +#endif // _LIBCPP_STD_VER > 14 + +template <class _Tp, class _Compare, class _Allocator> +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) +{ + __node_pointer __np = __p.__get_np(); + iterator __r = __remove_node_pointer(__np); + __node_allocator& __na = __node_alloc(); __node_traits::destroy(__na, _NodeTypes::__get_ptr( const_cast<__node_value_type&>(*__p))); __node_traits::deallocate(__na, __np, 1); diff --git a/lib/libcxx/include/algorithm b/lib/libcxx/include/algorithm index 35c6129ea50..90f1d246c63 100644 --- a/lib/libcxx/include/algorithm +++ b/lib/libcxx/include/algorithm @@ -20,149 +20,150 @@ namespace std { template <class InputIterator, class Predicate> - bool + constexpr bool // constexpr in C++20 all_of(InputIterator first, InputIterator last, Predicate pred); template <class InputIterator, class Predicate> - bool + constexpr bool // constexpr in C++20 any_of(InputIterator first, InputIterator last, Predicate pred); template <class InputIterator, class Predicate> - bool + constexpr bool // constexpr in C++20 none_of(InputIterator first, InputIterator last, Predicate pred); template <class InputIterator, class Function> - Function + constexpr Function // constexpr in C++20 for_each(InputIterator first, InputIterator last, Function f); template<class InputIterator, class Size, class Function> - InputIterator for_each_n(InputIterator first, Size n, Function f); // C++17 + constexpr InputIterator // constexpr in C++20 + for_each_n(InputIterator first, Size n, Function f); // C++17 template <class InputIterator, class T> - InputIterator + constexpr InputIterator // constexpr in C++20 find(InputIterator first, InputIterator last, const T& value); template <class InputIterator, class Predicate> - InputIterator + constexpr InputIterator // constexpr in C++20 find_if(InputIterator first, InputIterator last, Predicate pred); template<class InputIterator, class Predicate> - InputIterator + InputIterator // constexpr in C++20 find_if_not(InputIterator first, InputIterator last, Predicate pred); template <class ForwardIterator1, class ForwardIterator2> - ForwardIterator1 + ForwardIterator1 // constexpr in C++20 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> - ForwardIterator1 + ForwardIterator1 // constexpr in C++20 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); template <class ForwardIterator1, class ForwardIterator2> - ForwardIterator1 + constexpr ForwardIterator1 // constexpr in C++20 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> - ForwardIterator1 + constexpr ForwardIterator1 // constexpr in C++20 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); template <class ForwardIterator> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 adjacent_find(ForwardIterator first, ForwardIterator last); template <class ForwardIterator, class BinaryPredicate> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); template <class InputIterator, class T> - typename iterator_traits<InputIterator>::difference_type + constexpr typename iterator_traits<InputIterator>::difference_type // constexpr in C++20 count(InputIterator first, InputIterator last, const T& value); template <class InputIterator, class Predicate> - typename iterator_traits<InputIterator>::difference_type + constexpr typename iterator_traits<InputIterator>::difference_type // constexpr in C++20 count_if(InputIterator first, InputIterator last, Predicate pred); template <class InputIterator1, class InputIterator2> - pair<InputIterator1, InputIterator2> + constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); template <class InputIterator1, class InputIterator2> - pair<InputIterator1, InputIterator2> + constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); // **C++14** template <class InputIterator1, class InputIterator2, class BinaryPredicate> - pair<InputIterator1, InputIterator2> + constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); template <class InputIterator1, class InputIterator2, class BinaryPredicate> - pair<InputIterator1, InputIterator2> + constexpr pair<InputIterator1, InputIterator2> // constexpr in C++20 mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); // **C++14** template <class InputIterator1, class InputIterator2> - bool + constexpr bool // constexpr in C++20 equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); template <class InputIterator1, class InputIterator2> - bool + constexpr bool // constexpr in C++20 equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); // **C++14** template <class InputIterator1, class InputIterator2, class BinaryPredicate> - bool + constexpr bool // constexpr in C++20 equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); template <class InputIterator1, class InputIterator2, class BinaryPredicate> - bool + constexpr bool // constexpr in C++20 equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); // **C++14** template<class ForwardIterator1, class ForwardIterator2> - bool + constexpr bool // constexpr in C++20 is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template<class ForwardIterator1, class ForwardIterator2> - bool + constexpr bool // constexpr in C++20 is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); // **C++14** template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> - bool + constexpr bool // constexpr in C++20 is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred); template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> - bool + constexpr bool // constexpr in C++20 is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); // **C++14** template <class ForwardIterator1, class ForwardIterator2> - ForwardIterator1 + constexpr ForwardIterator1 // constexpr in C++20 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> - ForwardIterator1 + constexpr ForwardIterator1 // constexpr in C++20 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); template <class ForwardIterator, class Size, class T> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value); template <class ForwardIterator, class Size, class T, class BinaryPredicate> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value, BinaryPredicate pred); @@ -193,61 +194,61 @@ template <class ForwardIterator1, class ForwardIterator2> iter_swap(ForwardIterator1 a, ForwardIterator2 b); template <class InputIterator, class OutputIterator, class UnaryOperation> - OutputIterator + constexpr OutputIterator // constexpr in C++20 transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); template <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation> - OutputIterator + constexpr OutputIterator // constexpr in C++20 transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op); template <class ForwardIterator, class T> - void + constexpr void // constexpr in C++20 replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); template <class ForwardIterator, class Predicate, class T> - void + constexpr void // constexpr in C++20 replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); template <class InputIterator, class OutputIterator, class T> - OutputIterator + constexpr OutputIterator // constexpr in C++20 replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value); template <class InputIterator, class OutputIterator, class Predicate, class T> - OutputIterator + constexpr OutputIterator // constexpr in C++20 replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value); template <class ForwardIterator, class T> - void + constexpr void // constexpr in C++20 fill(ForwardIterator first, ForwardIterator last, const T& value); template <class OutputIterator, class Size, class T> - OutputIterator + constexpr OutputIterator // constexpr in C++20 fill_n(OutputIterator first, Size n, const T& value); template <class ForwardIterator, class Generator> - void + constexpr void // constexpr in C++20 generate(ForwardIterator first, ForwardIterator last, Generator gen); template <class OutputIterator, class Size, class Generator> - OutputIterator + constexpr OutputIterator // constexpr in C++20 generate_n(OutputIterator first, Size n, Generator gen); template <class ForwardIterator, class T> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 remove(ForwardIterator first, ForwardIterator last, const T& value); template <class ForwardIterator, class Predicate> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 remove_if(ForwardIterator first, ForwardIterator last, Predicate pred); template <class InputIterator, class OutputIterator, class T> - OutputIterator + constexpr OutputIterator // constexpr in C++20 remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); template <class InputIterator, class OutputIterator, class Predicate> - OutputIterator + constexpr OutputIterator // constexpr in C++20 remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); template <class ForwardIterator> @@ -271,7 +272,7 @@ template <class BidirectionalIterator> reverse(BidirectionalIterator first, BidirectionalIterator last); template <class BidirectionalIterator, class OutputIterator> - OutputIterator + constexpr OutputIterator // constexpr in C++20 reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); template <class ForwardIterator> @@ -302,7 +303,7 @@ template<class RandomAccessIterator, class UniformRandomNumberGenerator> UniformRandomNumberGenerator&& g); template <class InputIterator, class Predicate> - bool + constexpr bool // constexpr in C++20 is_partitioned(InputIterator first, InputIterator last, Predicate pred); template <class ForwardIterator, class Predicate> @@ -311,7 +312,7 @@ template <class ForwardIterator, class Predicate> template <class InputIterator, class OutputIterator1, class OutputIterator2, class Predicate> - pair<OutputIterator1, OutputIterator2> + constexpr pair<OutputIterator1, OutputIterator2> // constexpr in C++20 partition_copy(InputIterator first, InputIterator last, OutputIterator1 out_true, OutputIterator2 out_false, Predicate pred); @@ -321,11 +322,11 @@ template <class ForwardIterator, class Predicate> stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred); template<class ForwardIterator, class Predicate> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); template <class ForwardIterator> - bool + constexpr bool // constexpr in C++20 is_sorted(ForwardIterator first, ForwardIterator last); template <class ForwardIterator, class Compare> @@ -333,11 +334,11 @@ template <class ForwardIterator, class Compare> is_sorted(ForwardIterator first, ForwardIterator last, Compare comp); template<class ForwardIterator> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 is_sorted_until(ForwardIterator first, ForwardIterator last); template <class ForwardIterator, class Compare> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp); template <class RandomAccessIterator> @@ -383,35 +384,35 @@ template <class RandomAccessIterator, class Compare> nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); template <class ForwardIterator, class T> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 lower_bound(ForwardIterator first, ForwardIterator last, const T& value); template <class ForwardIterator, class T, class Compare> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); template <class ForwardIterator, class T> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 upper_bound(ForwardIterator first, ForwardIterator last, const T& value); template <class ForwardIterator, class T, class Compare> - ForwardIterator + constexpr ForwardIterator // constexpr in C++20 upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); template <class ForwardIterator, class T> - pair<ForwardIterator, ForwardIterator> + constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++20 equal_range(ForwardIterator first, ForwardIterator last, const T& value); template <class ForwardIterator, class T, class Compare> - pair<ForwardIterator, ForwardIterator> + constexpr pair<ForwardIterator, ForwardIterator> // constexpr in C++20 equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); template <class ForwardIterator, class T> - bool + constexpr bool // constexpr in C++20 binary_search(ForwardIterator first, ForwardIterator last, const T& value); template <class ForwardIterator, class T, class Compare> - bool + constexpr bool // constexpr in C++20 binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); template <class InputIterator1, class InputIterator2, class OutputIterator> @@ -433,11 +434,11 @@ template <class BidirectionalIterator, class Compare> inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); template <class InputIterator1, class InputIterator2> - bool + constexpr bool // constexpr in C++20 includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template <class InputIterator1, class InputIterator2, class Compare> - bool + constexpr bool // constexpr in C++20 includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); template <class InputIterator1, class InputIterator2, class OutputIterator> @@ -451,12 +452,12 @@ template <class InputIterator1, class InputIterator2, class OutputIterator, clas InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template <class InputIterator1, class InputIterator2, class OutputIterator> - OutputIterator + constexpr OutputIterator // constexpr in C++20 set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> - OutputIterator + constexpr OutputIterator // constexpr in C++20 set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); @@ -513,19 +514,19 @@ template <class RandomAccessIterator, class Compare> sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template <class RandomAccessIterator> - bool + constexpr bool // constexpr in C++20 is_heap(RandomAccessIterator first, RandomAccessiterator last); template <class RandomAccessIterator, class Compare> - bool + constexpr bool // constexpr in C++20 is_heap(RandomAccessIterator first, RandomAccessiterator last, Compare comp); template <class RandomAccessIterator> - RandomAccessIterator + constexpr RandomAccessIterator // constexpr in C++20 is_heap_until(RandomAccessIterator first, RandomAccessiterator last); template <class RandomAccessIterator, class Compare> - RandomAccessIterator + constexpr RandomAccessIterator // constexpr in C++20 is_heap_until(RandomAccessIterator first, RandomAccessiterator last, Compare comp); template <class ForwardIterator> @@ -607,11 +608,11 @@ template<class T, class Compare> minmax(initializer_list<T> t, Compare comp); // constexpr in C++14 template <class InputIterator1, class InputIterator2> - bool + constexpr bool // constexpr in C++20 lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template <class InputIterator1, class InputIterator2, class Compare> - bool + constexpr bool // constexpr in C++20 lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); @@ -641,6 +642,7 @@ template <class BidirectionalIterator, class Compare> #include <cstring> #include <utility> // needed to provide swap_ranges. #include <memory> +#include <functional> #include <iterator> #include <cstddef> @@ -669,10 +671,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _T1, class _T2 = _T1> struct __equal_to { - _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} - _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;} - _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;} - _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;} }; template <class _T1> @@ -918,7 +920,7 @@ inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long long __x) { // all_of template <class _InputIterator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { @@ -931,7 +933,7 @@ all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) // any_of template <class _InputIterator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { @@ -944,7 +946,7 @@ any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) // none_of template <class _InputIterator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { @@ -957,7 +959,7 @@ none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) // for_each template <class _InputIterator, class _Function> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Function for_each(_InputIterator __first, _InputIterator __last, _Function __f) { @@ -970,7 +972,7 @@ for_each(_InputIterator __first, _InputIterator __last, _Function __f) // for_each_n template <class _InputIterator, class _Size, class _Function> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { @@ -989,7 +991,7 @@ for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) // find template <class _InputIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator find(_InputIterator __first, _InputIterator __last, const _Tp& __value_) { @@ -1002,7 +1004,7 @@ find(_InputIterator __first, _InputIterator __last, const _Tp& __value_) // find_if template <class _InputIterator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { @@ -1015,7 +1017,7 @@ find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) // find_if_not template<class _InputIterator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _InputIterator find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { @@ -1028,7 +1030,7 @@ find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) // find_end template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> -_ForwardIterator1 +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) @@ -1070,7 +1072,7 @@ __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2> -_BidirectionalIterator1 +_LIBCPP_CONSTEXPR_AFTER_CXX17 _BidirectionalIterator1 __find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BinaryPredicate __pred, bidirectional_iterator_tag, bidirectional_iterator_tag) @@ -1150,7 +1152,7 @@ __find_end(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, } template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) @@ -1162,7 +1164,7 @@ find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template <class _ForwardIterator1, class _ForwardIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) @@ -1188,7 +1190,7 @@ __find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) @@ -1197,7 +1199,7 @@ find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template <class _ForwardIterator1, class _ForwardIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) @@ -1210,7 +1212,7 @@ find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, // adjacent_find template <class _ForwardIterator, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { @@ -1228,7 +1230,7 @@ adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicat } template <class _ForwardIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { @@ -1239,7 +1241,7 @@ adjacent_find(_ForwardIterator __first, _ForwardIterator __last) // count template <class _InputIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename iterator_traits<_InputIterator>::difference_type count(_InputIterator __first, _InputIterator __last, const _Tp& __value_) { @@ -1253,7 +1255,7 @@ count(_InputIterator __first, _InputIterator __last, const _Tp& __value_) // count_if template <class _InputIterator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename iterator_traits<_InputIterator>::difference_type count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { @@ -1267,7 +1269,7 @@ count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) // mismatch template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) @@ -1279,7 +1281,7 @@ mismatch(_InputIterator1 __first1, _InputIterator1 __last1, } template <class _InputIterator1, class _InputIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { @@ -1290,7 +1292,7 @@ mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fi #if _LIBCPP_STD_VER > 11 template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, @@ -1303,7 +1305,7 @@ mismatch(_InputIterator1 __first1, _InputIterator1 __last1, } template <class _InputIterator1, class _InputIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) @@ -1317,7 +1319,7 @@ mismatch(_InputIterator1 __first1, _InputIterator1 __last1, // equal template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { @@ -1328,7 +1330,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first } template <class _InputIterator1, class _InputIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { @@ -1339,7 +1341,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first #if _LIBCPP_STD_VER > 11 template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred, @@ -1352,7 +1354,7 @@ __equal(_InputIterator1 __first1, _InputIterator1 __last1, } template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, @@ -1366,7 +1368,7 @@ __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, } template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred ) @@ -1378,7 +1380,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, } template <class _InputIterator1, class _InputIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) @@ -1394,17 +1396,18 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, // is_permutation template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { - // shorten sequences as much as possible by lopping of any equal parts +// shorten sequences as much as possible by lopping of any equal prefix for (; __first1 != __last1; ++__first1, (void) ++__first2) if (!__pred(*__first1, *__first2)) - goto __not_done; - return true; -__not_done: - // __first1 != __last1 && *__first1 != *__first2 + break; + if (__first1 == __last1) + return true; + +// __first1 != __last1 && *__first1 != *__first2 typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; _D1 __l1 = _VSTD::distance(__first1, __last1); if (__l1 == _D1(1)) @@ -1414,11 +1417,12 @@ __not_done: // equal elements in [f2, l2) for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) { - // Have we already counted the number of *__i in [f1, l1)? - for (_ForwardIterator1 __j = __first1; __j != __i; ++__j) - if (__pred(*__j, *__i)) - goto __next_iter; - { + // Have we already counted the number of *__i in [f1, l1)? + _ForwardIterator1 __match = __first1; + for (; __match != __i; ++__match) + if (__pred(*__match, *__i)) + break; + if (__match == __i) { // Count number of *__i in [f2, l2) _D1 __c2 = 0; for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) @@ -1434,13 +1438,12 @@ __not_done: if (__c1 != __c2) return false; } -__next_iter:; } return true; } template<class _ForwardIterator1, class _ForwardIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) @@ -1452,19 +1455,21 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, #if _LIBCPP_STD_VER > 11 template<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag ) { - // shorten sequences as much as possible by lopping of any equal parts +// shorten sequences as much as possible by lopping of any equal prefix for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2) if (!__pred(*__first1, *__first2)) - goto __not_done; - return __first1 == __last1 && __first2 == __last2; -__not_done: - // __first1 != __last1 && __first2 != __last2 && *__first1 != *__first2 + break; + if (__first1 == __last1) + return __first2 == __last2; + else if (__first2 == __last2) + return false; + typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1; _D1 __l1 = _VSTD::distance(__first1, __last1); @@ -1477,11 +1482,12 @@ __not_done: // equal elements in [f2, l2) for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) { - // Have we already counted the number of *__i in [f1, l1)? - for (_ForwardIterator1 __j = __first1; __j != __i; ++__j) - if (__pred(*__j, *__i)) - goto __next_iter; - { + // Have we already counted the number of *__i in [f1, l1)? + _ForwardIterator1 __match = __first1; + for (; __match != __i; ++__match) + if (__pred(*__match, *__i)) + break; + if (__match == __i) { // Count number of *__i in [f2, l2) _D1 __c2 = 0; for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) @@ -1497,13 +1503,12 @@ __not_done: if (__c1 != __c2) return false; } -__next_iter:; } return true; } template<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1, _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, @@ -1517,7 +1522,7 @@ __is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1 } template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, @@ -1530,7 +1535,7 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template<class _ForwardIterator1, class _ForwardIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) @@ -1545,91 +1550,10 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, #endif // search - -template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> -pair<_ForwardIterator1, _ForwardIterator1> -__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, - forward_iterator_tag, forward_iterator_tag) -{ - if (__first2 == __last2) - return make_pair(__first1, __first1); // Everything matches an empty sequence - while (true) - { - // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks - while (true) - { - if (__first1 == __last1) // return __last1 if no element matches *__first2 - return make_pair(__last1, __last1); - if (__pred(*__first1, *__first2)) - break; - ++__first1; - } - // *__first1 matches *__first2, now match elements after here - _ForwardIterator1 __m1 = __first1; - _ForwardIterator2 __m2 = __first2; - while (true) - { - if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) - return make_pair(__first1, __m1); - if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found - return make_pair(__last1, __last1); - if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 - { - ++__first1; - break; - } // else there is a match, check next elements - } - } -} - -template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> -_LIBCPP_CONSTEXPR_AFTER_CXX11 -pair<_RandomAccessIterator1, _RandomAccessIterator1> -__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, - random_access_iterator_tag, random_access_iterator_tag) -{ - typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; - typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; - // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern - const _D2 __len2 = __last2 - __first2; - if (__len2 == 0) - return make_pair(__first1, __first1); - const _D1 __len1 = __last1 - __first1; - if (__len1 < __len2) - return make_pair(__last1, __last1); - const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here - - while (true) - { - while (true) - { - if (__first1 == __s) - return make_pair(__last1, __last1); - if (__pred(*__first1, *__first2)) - break; - ++__first1; - } - - _RandomAccessIterator1 __m1 = __first1; - _RandomAccessIterator2 __m2 = __first2; - while (true) - { - if (++__m2 == __last2) - return make_pair(__first1, __first1 + __len2); - ++__m1; // no need to check range on __m1 because __s guarantees we have enough source - if (!__pred(*__m1, *__m2)) - { - ++__first1; - break; - } - } - } -} +// __search is in <functional> template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) @@ -1642,7 +1566,7 @@ search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template <class _ForwardIterator1, class _ForwardIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) @@ -1652,10 +1576,18 @@ search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); } + +#if _LIBCPP_STD_VER > 14 +template <class _ForwardIterator, class _Searcher> +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s) +{ return __s(__f, __l).first; } +#endif + // search_n template <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp> -_ForwardIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_, _BinaryPredicate __pred, forward_iterator_tag) { @@ -1692,7 +1624,7 @@ __search_n(_ForwardIterator __first, _ForwardIterator __last, } template <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp> -_RandomAccessIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator __search_n(_RandomAccessIterator __first, _RandomAccessIterator __last, _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag) { @@ -1732,7 +1664,7 @@ __search_n(_RandomAccessIterator __first, _RandomAccessIterator __last, } template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_, _BinaryPredicate __pred) @@ -1743,7 +1675,7 @@ search_n(_ForwardIterator __first, _ForwardIterator __last, } template <class _ForwardIterator, class _Size, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_) { @@ -1776,7 +1708,7 @@ __unwrap_iter(move_iterator<_Tp*> __i) #if _LIBCPP_DEBUG_LEVEL < 2 template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1790,7 +1722,7 @@ __unwrap_iter(__wrap_iter<_Tp*> __i) #else template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -2023,7 +1955,7 @@ move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, // transform template <class _InputIterator, class _OutputIterator, class _UnaryOperation> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) { @@ -2033,7 +1965,7 @@ transform(_InputIterator __first, _InputIterator __last, _OutputIterator __resul } template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _OutputIterator __result, _BinaryOperation __binary_op) @@ -2046,7 +1978,7 @@ transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __f // replace template <class _ForwardIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) { @@ -2058,7 +1990,7 @@ replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_valu // replace_if template <class _ForwardIterator, class _Predicate, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) { @@ -2070,7 +2002,7 @@ replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, // replace_copy template <class _InputIterator, class _OutputIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __old_value, const _Tp& __new_value) @@ -2086,7 +2018,7 @@ replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __re // replace_copy_if template <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred, const _Tp& __new_value) @@ -2102,7 +2034,7 @@ replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator _ // fill_n template <class _OutputIterator, class _Size, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) { @@ -2111,24 +2043,8 @@ __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) return __first; } -template <class _Tp, class _Size, class _Up> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value && sizeof(_Tp) == 1 && - !is_same<_Tp, bool>::value && - is_integral<_Up>::value && sizeof(_Up) == 1, - _Tp* ->::type -__fill_n(_Tp* __first, _Size __n,_Up __value_) -{ - if (__n > 0) - _VSTD::memset(__first, (unsigned char)__value_, (size_t)(__n)); - return __first + __n; -} - template <class _OutputIterator, class _Size, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) { @@ -2138,7 +2054,7 @@ fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_) // fill template <class _ForwardIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag) { @@ -2147,7 +2063,7 @@ __fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, f } template <class _RandomAccessIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag) { @@ -2155,7 +2071,7 @@ __fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& _ } template <class _ForwardIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) { @@ -2165,7 +2081,7 @@ fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) // generate template <class _ForwardIterator, class _Generator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { @@ -2176,7 +2092,7 @@ generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) // generate_n template <class _OutputIterator, class _Size, class _Generator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) { @@ -2190,7 +2106,7 @@ generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) // remove template <class _ForwardIterator, class _Tp> -_ForwardIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) { __first = _VSTD::find(__first, __last, __value_); @@ -2212,7 +2128,7 @@ remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) // remove_if template <class _ForwardIterator, class _Predicate> -_ForwardIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type> @@ -2235,7 +2151,7 @@ remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) // remove_copy template <class _InputIterator, class _OutputIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_) { @@ -2253,7 +2169,7 @@ remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __res // remove_copy_if template <class _InputIterator, class _OutputIterator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { @@ -2271,7 +2187,7 @@ remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __ // unique template <class _ForwardIterator, class _BinaryPredicate> -_ForwardIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type> @@ -2290,7 +2206,7 @@ unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pre } template <class _ForwardIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last) { @@ -2301,7 +2217,7 @@ unique(_ForwardIterator __first, _ForwardIterator __last) // unique_copy template <class _BinaryPredicate, class _InputIterator, class _OutputIterator> -_OutputIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator __unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred, input_iterator_tag, output_iterator_tag) { @@ -2324,7 +2240,7 @@ __unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __r } template <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator> -_OutputIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator __unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, forward_iterator_tag, output_iterator_tag) { @@ -2347,7 +2263,7 @@ __unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator } template <class _BinaryPredicate, class _InputIterator, class _ForwardIterator> -_ForwardIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred, input_iterator_tag, forward_iterator_tag) { @@ -2363,7 +2279,7 @@ __unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __ } template <class _InputIterator, class _OutputIterator, class _BinaryPredicate> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) { @@ -2374,7 +2290,7 @@ unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __res } template <class _InputIterator, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { @@ -2419,7 +2335,7 @@ reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) // reverse_copy template <class _BidirectionalIterator, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) { @@ -3303,7 +3219,7 @@ template<class _RandomAccessIterator, class _UniformRandomNumberGenerator> } template <class _InputIterator, class _Predicate> -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) @@ -3381,7 +3297,7 @@ partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) template <class _InputIterator, class _OutputIterator1, class _OutputIterator2, class _Predicate> -pair<_OutputIterator1, _OutputIterator2> +_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_OutputIterator1, _OutputIterator2> partition_copy(_InputIterator __first, _InputIterator __last, _OutputIterator1 __out_true, _OutputIterator2 __out_false, _Predicate __pred) @@ -3405,7 +3321,7 @@ partition_copy(_InputIterator __first, _InputIterator __last, // partition_point template<class _ForwardIterator, class _Predicate> -_ForwardIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; @@ -3711,7 +3627,7 @@ stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate _ // is_sorted_until template <class _ForwardIterator, class _Compare> -_ForwardIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { if (__first != __last) @@ -3728,7 +3644,7 @@ is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __co } template<class _ForwardIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) { @@ -3738,7 +3654,7 @@ is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) // is_sorted template <class _ForwardIterator, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { @@ -3746,7 +3662,7 @@ is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) } template<class _ForwardIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool is_sorted(_ForwardIterator __first, _ForwardIterator __last) { @@ -4272,7 +4188,7 @@ _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, // lower_bound template <class _Compare, class _ForwardIterator, class _Tp> -_ForwardIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; @@ -4294,7 +4210,7 @@ __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va } template <class _ForwardIterator, class _Tp, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { @@ -4309,7 +4225,7 @@ lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template <class _ForwardIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) { @@ -4320,7 +4236,7 @@ lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu // upper_bound template <class _Compare, class _ForwardIterator, class _Tp> -_ForwardIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator __upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; @@ -4342,7 +4258,7 @@ __upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va } template <class _ForwardIterator, class _Tp, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { @@ -4357,7 +4273,7 @@ upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template <class _ForwardIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) { @@ -4368,7 +4284,7 @@ upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu // equal_range template <class _Compare, class _ForwardIterator, class _Tp> -pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; @@ -4402,7 +4318,7 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va } template <class _ForwardIterator, class _Tp, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { @@ -4417,7 +4333,7 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template <class _ForwardIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) { @@ -4428,7 +4344,7 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu // binary_search template <class _Compare, class _ForwardIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { @@ -4437,7 +4353,7 @@ __binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __ } template <class _ForwardIterator, class _Tp, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { @@ -4452,7 +4368,7 @@ binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va } template <class _ForwardIterator, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_) { @@ -4787,9 +4703,9 @@ __stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1 ::new(__first2) value_type(_VSTD::move(*__first1)); return; case 2: - __destruct_n __d(0); + __destruct_n __d(0); unique_ptr<value_type, __destruct_n&> __h2(__first2, __d); - if (__comp(*--__last1, *__first1)) + if (__comp(*--__last1, *__first1)) { ::new(__first2) value_type(_VSTD::move(*__last1)); __d.__incr((value_type*)0); @@ -4906,7 +4822,7 @@ stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) // is_heap_until template <class _RandomAccessIterator, class _Compare> -_RandomAccessIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::difference_type difference_type; @@ -4933,7 +4849,7 @@ is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp } template<class _RandomAccessIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) { @@ -4943,7 +4859,7 @@ is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) // is_heap template <class _RandomAccessIterator, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { @@ -4951,7 +4867,7 @@ is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __ } template<class _RandomAccessIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { @@ -5489,7 +5405,7 @@ nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomA // includes template <class _Compare, class _InputIterator1, class _InputIterator2> -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { @@ -5504,7 +5420,7 @@ __includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __ } template <class _InputIterator1, class _InputIterator2, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) @@ -5520,7 +5436,7 @@ includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fi } template <class _InputIterator1, class _InputIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { @@ -5586,7 +5502,7 @@ set_union(_InputIterator1 __first1, _InputIterator1 __last1, // set_intersection template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator> -_OutputIterator +_LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator __set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { @@ -5609,7 +5525,7 @@ __set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, } template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) @@ -5625,7 +5541,7 @@ set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, } template <class _InputIterator1, class _InputIterator2, class _OutputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) @@ -5751,7 +5667,7 @@ set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, // lexicographical_compare template <class _Compare, class _InputIterator1, class _InputIterator2> -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool __lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { @@ -5766,7 +5682,7 @@ __lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, } template <class _InputIterator1, class _InputIterator2, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) @@ -5782,7 +5698,7 @@ lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, } template <class _InputIterator1, class _InputIterator2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) diff --git a/lib/libcxx/include/any b/lib/libcxx/include/any index d7161b0d6f4..9bd2f53c560 100644 --- a/lib/libcxx/include/any +++ b/lib/libcxx/include/any @@ -104,7 +104,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_bad_any_cast() { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -304,7 +304,7 @@ private: __any_imp::_Buffer __buf; }; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void * __call(_Action __a, any * __other = nullptr, type_info const * __info = nullptr, const void* __fallback_info = nullptr) const @@ -312,7 +312,7 @@ private: return __h(__a, this, __other, __info, __fallback_info); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void * __call(_Action __a, any * __other = nullptr, type_info const * __info = nullptr, const void* __fallback_info = nullptr) diff --git a/lib/libcxx/include/array b/lib/libcxx/include/array index 4eb2fe6fc62..1e6a650198b 100644 --- a/lib/libcxx/include/array +++ b/lib/libcxx/include/array @@ -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; @@ -108,6 +111,8 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce #include <iterator> #include <algorithm> #include <stdexcept> +#include <cstdlib> // for _LIBCPP_UNREACHABLE +#include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -117,6 +122,7 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce _LIBCPP_BEGIN_NAMESPACE_STD + template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array { @@ -134,31 +140,27 @@ struct _LIBCPP_TEMPLATE_VIS array typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - value_type __elems_[_Size > 0 ? _Size : 1]; + _Tp __elems_[_Size]; // No explicit construct/copy/destroy for aggregate type - _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) - {_VSTD::fill_n(__elems_, _Size, __u);} - _LIBCPP_INLINE_VISIBILITY - void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) - { __swap_dispatch((std::integral_constant<bool, _Size == 0>()), __a); } - - _LIBCPP_INLINE_VISIBILITY - void __swap_dispatch(std::true_type, array&) {} + _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) { + _VSTD::fill_n(__elems_, _Size, __u); + } _LIBCPP_INLINE_VISIBILITY - void __swap_dispatch(std::false_type, array& __a) - { _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} + void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { + std::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_); + } // iterators: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - iterator begin() _NOEXCEPT {return iterator(__elems_);} + iterator begin() _NOEXCEPT {return iterator(data());} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);} + const_iterator begin() const _NOEXCEPT {return const_iterator(data());} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);} + iterator end() _NOEXCEPT {return iterator(data() + _Size);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);} + const_iterator end() const _NOEXCEPT {return const_iterator(data() + _Size);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} @@ -184,7 +186,7 @@ struct _LIBCPP_TEMPLATE_VIS array _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;} _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;} + _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return false; } // element access: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -197,8 +199,8 @@ struct _LIBCPP_TEMPLATE_VIS array _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference front() {return __elems_[0];} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back() {return __elems_[_Size > 0 ? _Size-1 : 0];} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const {return __elems_[_Size > 0 ? _Size-1 : 0];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back() {return __elems_[_Size - 1];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const {return __elems_[_Size - 1];} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 value_type* data() _NOEXCEPT {return __elems_;} @@ -206,6 +208,7 @@ struct _LIBCPP_TEMPLATE_VIS array const value_type* data() const _NOEXCEPT {return __elems_;} }; + template <class _Tp, size_t _Size> _LIBCPP_CONSTEXPR_AFTER_CXX14 typename array<_Tp, _Size>::reference @@ -227,12 +230,147 @@ array<_Tp, _Size>::at(size_type __n) const return __elems_[__n]; } +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> +{ + // types: + typedef array __self; + typedef _Tp value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + typedef typename conditional<is_const<_Tp>::value, const char, + char>::type _CharType; + + 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&) { + static_assert(!is_const<_Tp>::value, + "cannot fill zero-sized array of type 'const T'"); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(array&) _NOEXCEPT { + static_assert(!is_const<_Tp>::value, + "cannot swap zero-sized array of type 'const T'"); + } + + // iterators: + _LIBCPP_INLINE_VISIBILITY + iterator begin() _NOEXCEPT {return iterator(data());} + _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT {return const_iterator(data());} + _LIBCPP_INLINE_VISIBILITY + iterator end() _NOEXCEPT {return iterator(data());} + _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT {return const_iterator(data());} + + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} + _LIBCPP_INLINE_VISIBILITY + reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} + + _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT {return begin();} + _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT {return end();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT {return rend();} + + // capacity: + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return 0; } + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return 0;} + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return true;} + + // element access: + _LIBCPP_INLINE_VISIBILITY + reference operator[](size_type) { + _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + const_reference operator[](size_type) const { + _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + reference at(size_type) { + __throw_out_of_range("array<T, 0>::at"); + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + const_reference at(size_type) const { + __throw_out_of_range("array<T, 0>::at"); + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + reference front() { + _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array"); + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + const_reference front() const { + _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array"); + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + reference back() { + _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array"); + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + const_reference back() const { + _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array"); + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + value_type* data() _NOEXCEPT {return reinterpret_cast<value_type*>(__elems_);} + _LIBCPP_INLINE_VISIBILITY + const value_type* data() const _NOEXCEPT {return reinterpret_cast<const value_type*>(__elems_);} +}; + + +#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 operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { - return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_); + return _VSTD::equal(__x.begin(), __x.end(), __y.begin()); } template <class _Tp, size_t _Size> @@ -248,7 +386,8 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { - return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size); + return _VSTD::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } template <class _Tp, size_t _Size> diff --git a/lib/libcxx/include/atomic b/lib/libcxx/include/atomic index f55e28ff5e9..809f78a06d3 100644 --- a/lib/libcxx/include/atomic +++ b/lib/libcxx/include/atomic @@ -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 diff --git a/lib/libcxx/include/cfloat b/lib/libcxx/include/cfloat index 176fa9de3ce..0abe84bf175 100644 --- a/lib/libcxx/include/cfloat +++ b/lib/libcxx/include/cfloat @@ -20,11 +20,18 @@ Macros: FLT_EVAL_METHOD // C99 FLT_RADIX + FLT_HAS_SUBNORM // C11 + DBL_HAS_SUBNORM // C11 + LDBL_HAS_SUBNORM // C11 + FLT_MANT_DIG DBL_MANT_DIG LDBL_MANT_DIG DECIMAL_DIG // C99 + FLT_DECIMAL_DIG // C11 + DBL_DECIMAL_DIG // C11 + LDBL_DECIMAL_DIG // C11 FLT_DIG DBL_DIG @@ -58,6 +65,9 @@ Macros: DBL_MIN LDBL_MIN + FLT_TRUE_MIN // C11 + DBL_TRUE_MIN // C11 + LDBL_TRUE_MIN // C11 */ #include <__config> diff --git a/lib/libcxx/include/charconv b/lib/libcxx/include/charconv new file mode 100644 index 00000000000..7cb790e1bee --- /dev/null +++ b/lib/libcxx/include/charconv @@ -0,0 +1,610 @@ +// -*- C++ -*- +//===------------------------------ charconv ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CHARCONV +#define _LIBCPP_CHARCONV + +/* + charconv synopsis + +namespace std { + + // floating-point format for primitive numerical conversion + enum class chars_format { + scientific = unspecified, + fixed = unspecified, + hex = unspecified, + general = fixed | scientific + }; + + // 23.20.2, primitive numerical output conversion + struct to_chars_result { + char* ptr; + errc ec; + }; + + to_chars_result to_chars(char* first, char* last, see below value, + int base = 10); + + to_chars_result to_chars(char* first, char* last, float value); + to_chars_result to_chars(char* first, char* last, double value); + to_chars_result to_chars(char* first, char* last, long double value); + + to_chars_result to_chars(char* first, char* last, float value, + chars_format fmt); + to_chars_result to_chars(char* first, char* last, double value, + chars_format fmt); + to_chars_result to_chars(char* first, char* last, long double value, + chars_format fmt); + + to_chars_result to_chars(char* first, char* last, float value, + chars_format fmt, int precision); + to_chars_result to_chars(char* first, char* last, double value, + chars_format fmt, int precision); + to_chars_result to_chars(char* first, char* last, long double value, + chars_format fmt, int precision); + + // 23.20.3, primitive numerical input conversion + struct from_chars_result { + const char* ptr; + errc ec; + }; + + from_chars_result from_chars(const char* first, const char* last, + see below& value, int base = 10); + + from_chars_result from_chars(const char* first, const char* last, + float& value, + chars_format fmt = chars_format::general); + from_chars_result from_chars(const char* first, const char* last, + double& value, + chars_format fmt = chars_format::general); + from_chars_result from_chars(const char* first, const char* last, + long double& value, + chars_format fmt = chars_format::general); + +} // namespace std + +*/ + +#include <__errc> +#include <type_traits> +#include <limits> +#include <stdint.h> +#include <string.h> +#include <math.h> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 11 + +enum class _LIBCPP_ENUM_VIS chars_format +{ + scientific = 0x1, + fixed = 0x2, + hex = 0x4, + general = fixed | scientific +}; + +struct _LIBCPP_TYPE_VIS to_chars_result +{ + char* ptr; + errc ec; +}; + +struct _LIBCPP_TYPE_VIS from_chars_result +{ + const char* ptr; + errc ec; +}; + +void to_chars(char*, char*, bool, int = 10) = delete; +void from_chars(const char*, const char*, bool, int = 10) = delete; + +namespace __itoa +{ + +static constexpr uint64_t __pow10_64[] = { + UINT64_C(0), + UINT64_C(10), + UINT64_C(100), + UINT64_C(1000), + UINT64_C(10000), + UINT64_C(100000), + UINT64_C(1000000), + UINT64_C(10000000), + UINT64_C(100000000), + UINT64_C(1000000000), + UINT64_C(10000000000), + UINT64_C(100000000000), + UINT64_C(1000000000000), + UINT64_C(10000000000000), + UINT64_C(100000000000000), + UINT64_C(1000000000000000), + UINT64_C(10000000000000000), + UINT64_C(100000000000000000), + UINT64_C(1000000000000000000), + UINT64_C(10000000000000000000), +}; + +static constexpr uint32_t __pow10_32[] = { + UINT32_C(0), UINT32_C(10), UINT32_C(100), + UINT32_C(1000), UINT32_C(10000), UINT32_C(100000), + UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), + UINT32_C(1000000000), +}; + +_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer); +_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer); + +template <typename _Tp, typename = void> +struct _LIBCPP_HIDDEN __traits_base +{ + using type = uint64_t; + +#if !defined(_LIBCPP_COMPILER_MSVC) + static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v) + { + auto __t = (64 - __builtin_clzll(__v | 1)) * 1233 >> 12; + return __t - (__v < __pow10_64[__t]) + 1; + } +#endif + + static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p) + { + return __u64toa(__v, __p); + } + + static _LIBCPP_INLINE_VISIBILITY auto& __pow() { return __pow10_64; } +}; + +template <typename _Tp> +struct _LIBCPP_HIDDEN + __traits_base<_Tp, decltype(void(uint32_t{declval<_Tp>()}))> +{ + using type = uint32_t; + +#if !defined(_LIBCPP_COMPILER_MSVC) + static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v) + { + auto __t = (32 - __builtin_clz(__v | 1)) * 1233 >> 12; + return __t - (__v < __pow10_32[__t]) + 1; + } +#endif + + static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p) + { + return __u32toa(__v, __p); + } + + static _LIBCPP_INLINE_VISIBILITY auto& __pow() { return __pow10_32; } +}; + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY bool +__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) +{ + auto __c = __a * __b; + __r = __c; + return __c > (numeric_limits<unsigned char>::max)(); +} + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY bool +__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) +{ + auto __c = __a * __b; + __r = __c; + return __c > (numeric_limits<unsigned short>::max)(); +} + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY bool +__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) +{ + static_assert(is_unsigned<_Tp>::value, ""); +#if !defined(_LIBCPP_COMPILER_MSVC) + return __builtin_mul_overflow(__a, __b, &__r); +#else + bool __did = __b && ((numeric_limits<_Tp>::max)() / __b) < __a; + __r = __a * __b; + return __did; +#endif +} + +template <typename _Tp, typename _Up> +inline _LIBCPP_INLINE_VISIBILITY bool +__mul_overflowed(_Tp __a, _Up __b, _Tp& __r) +{ + return __mul_overflowed(__a, static_cast<_Tp>(__b), __r); +} + +template <typename _Tp> +struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> +{ + static constexpr int digits = numeric_limits<_Tp>::digits10 + 1; + using __traits_base<_Tp>::__pow; + using typename __traits_base<_Tp>::type; + + // precondition: at least one non-zero character available + static _LIBCPP_INLINE_VISIBILITY char const* + __read(char const* __p, char const* __ep, type& __a, type& __b) + { + type __cprod[digits]; + int __j = digits - 1; + int __i = digits; + do + { + if (!('0' <= *__p && *__p <= '9')) + break; + __cprod[--__i] = *__p++ - '0'; + } while (__p != __ep && __i != 0); + + __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1, + __cprod[__i]); + if (__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b)) + --__p; + return __p; + } + + template <typename _It1, typename _It2, class _Up> + static _LIBCPP_INLINE_VISIBILITY _Up + __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) + { + for (; __first1 < __last1; ++__first1, ++__first2) + __init = __init + *__first1 * *__first2; + return __init; + } +}; + +} // namespace __itoa + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY _Tp +__complement(_Tp __x) +{ + static_assert(is_unsigned<_Tp>::value, "cast to unsigned first"); + return _Tp(~__x + 1); +} + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY auto +__to_unsigned(_Tp __x) +{ + return static_cast<make_unsigned_t<_Tp>>(__x); +} + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY to_chars_result +__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) +{ + auto __x = __to_unsigned(__value); + if (__value < 0 && __first != __last) + { + *__first++ = '-'; + __x = __complement(__x); + } + + return __to_chars_itoa(__first, __last, __x, false_type()); +} + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY to_chars_result +__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) +{ + using __tx = __itoa::__traits<_Tp>; + auto __diff = __last - __first; + +#if !defined(_LIBCPP_COMPILER_MSVC) + if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) + return {__tx::__convert(__value, __first), {}}; + else + return {__last, errc::value_too_large}; +#else + if (__tx::digits <= __diff) + return {__tx::__convert(__value, __first), {}}; + else + { + char __buf[__tx::digits]; + auto __p = __tx::__convert(__value, __buf); + auto __len = __p - __buf; + if (__len <= __diff) + { + memcpy(__first, __buf, __len); + return {__first + __len, {}}; + } + else + return {__last, errc::value_too_large}; + } +#endif +} + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY to_chars_result +__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, + true_type) +{ + auto __x = __to_unsigned(__value); + if (__value < 0 && __first != __last) + { + *__first++ = '-'; + __x = __complement(__x); + } + + return __to_chars_integral(__first, __last, __x, __base, false_type()); +} + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY to_chars_result +__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, + false_type) +{ + if (__base == 10) + return __to_chars_itoa(__first, __last, __value, false_type()); + + auto __p = __last; + while (__p != __first) + { + auto __c = __value % __base; + __value /= __base; + *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c]; + if (__value == 0) + break; + } + + auto __len = __last - __p; + if (__value != 0 || !__len) + return {__last, errc::value_too_large}; + else + { + memmove(__first, __p, __len); + return {__first + __len, {}}; + } +} + +template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0> +inline _LIBCPP_INLINE_VISIBILITY to_chars_result +to_chars(char* __first, char* __last, _Tp __value) +{ + return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>()); +} + +template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0> +inline _LIBCPP_INLINE_VISIBILITY to_chars_result +to_chars(char* __first, char* __last, _Tp __value, int __base) +{ + _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); + return __to_chars_integral(__first, __last, __value, __base, + is_signed<_Tp>()); +} + +template <typename _It, typename _Tp, typename _Fn, typename... _Ts> +inline _LIBCPP_INLINE_VISIBILITY from_chars_result +__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) +{ + using __tl = numeric_limits<_Tp>; + decltype(__to_unsigned(__value)) __x; + + bool __neg = (__first != __last && *__first == '-'); + auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...); + switch (__r.ec) + { + case errc::invalid_argument: + return {__first, __r.ec}; + case errc::result_out_of_range: + return __r; + default: + break; + } + + if (__neg) + { + if (__x <= __complement(__to_unsigned(__tl::min()))) + { + __x = __complement(__x); + memcpy(&__value, &__x, sizeof(__x)); + return __r; + } + } + else + { + if (__x <= (__tl::max)()) + { + __value = __x; + return __r; + } + } + + return {__r.ptr, errc::result_out_of_range}; +} + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY bool +__in_pattern(_Tp __c) +{ + return '0' <= __c && __c <= '9'; +} + +struct _LIBCPP_HIDDEN __in_pattern_result +{ + bool __ok; + int __val; + + explicit _LIBCPP_INLINE_VISIBILITY operator bool() const { return __ok; } +}; + +template <typename _Tp> +inline _LIBCPP_INLINE_VISIBILITY __in_pattern_result +__in_pattern(_Tp __c, int __base) +{ + if (__base <= 10) + return {'0' <= __c && __c < '0' + __base, __c - '0'}; + else if (__in_pattern(__c)) + return {true, __c - '0'}; + else if ('a' <= __c && __c < 'a' + __base - 10) + return {true, __c - 'a' + 10}; + else + return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10}; +} + +template <typename _It, typename _Tp, typename _Fn, typename... _Ts> +inline _LIBCPP_INLINE_VISIBILITY from_chars_result +__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, + _Ts... __args) +{ + auto __find_non_zero = [](_It __first, _It __last) { + for (; __first != __last; ++__first) + if (*__first != '0') + break; + return __first; + }; + + auto __p = __find_non_zero(__first, __last); + if (__p == __last || !__in_pattern(*__p, __args...)) + { + if (__p == __first) + return {__first, errc::invalid_argument}; + else + { + __value = 0; + return {__p, {}}; + } + } + + auto __r = __f(__p, __last, __value, __args...); + if (__r.ec == errc::result_out_of_range) + { + for (; __r.ptr != __last; ++__r.ptr) + { + if (!__in_pattern(*__r.ptr, __args...)) + break; + } + } + + return __r; +} + +template <typename _Tp, enable_if_t<is_unsigned<_Tp>::value, int> = 0> +inline _LIBCPP_INLINE_VISIBILITY from_chars_result +__from_chars_atoi(const char* __first, const char* __last, _Tp& __value) +{ + using __tx = __itoa::__traits<_Tp>; + using __output_type = typename __tx::type; + + return __subject_seq_combinator( + __first, __last, __value, + [](const char* __first, const char* __last, + _Tp& __value) -> from_chars_result { + __output_type __a, __b; + auto __p = __tx::__read(__first, __last, __a, __b); + if (__p == __last || !__in_pattern(*__p)) + { + __output_type __m = (numeric_limits<_Tp>::max)(); + if (__m >= __a && __m - __a >= __b) + { + __value = __a + __b; + return {__p, {}}; + } + } + return {__p, errc::result_out_of_range}; + }); +} + +template <typename _Tp, enable_if_t<is_signed<_Tp>::value, int> = 0> +inline _LIBCPP_INLINE_VISIBILITY from_chars_result +__from_chars_atoi(const char* __first, const char* __last, _Tp& __value) +{ + using __t = decltype(__to_unsigned(__value)); + return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>); +} + +template <typename _Tp, enable_if_t<is_unsigned<_Tp>::value, int> = 0> +inline _LIBCPP_INLINE_VISIBILITY from_chars_result +__from_chars_integral(const char* __first, const char* __last, _Tp& __value, + int __base) +{ + if (__base == 10) + return __from_chars_atoi(__first, __last, __value); + + return __subject_seq_combinator( + __first, __last, __value, + [](const char* __p, const char* __last, _Tp& __value, + int __base) -> from_chars_result { + using __tl = numeric_limits<_Tp>; + auto __digits = __tl::digits / log2f(float(__base)); + _Tp __a = __in_pattern(*__p++, __base).__val, __b = 0; + + for (int __i = 1; __p != __last; ++__i, ++__p) + { + if (auto __c = __in_pattern(*__p, __base)) + { + if (__i < __digits - 1) + __a = __a * __base + __c.__val; + else + { + if (!__itoa::__mul_overflowed(__a, __base, __a)) + ++__p; + __b = __c.__val; + break; + } + } + else + break; + } + + if (__p == __last || !__in_pattern(*__p, __base)) + { + if ((__tl::max)() - __a >= __b) + { + __value = __a + __b; + return {__p, {}}; + } + } + return {__p, errc::result_out_of_range}; + }, + __base); +} + +template <typename _Tp, enable_if_t<is_signed<_Tp>::value, int> = 0> +inline _LIBCPP_INLINE_VISIBILITY from_chars_result +__from_chars_integral(const char* __first, const char* __last, _Tp& __value, + int __base) +{ + using __t = decltype(__to_unsigned(__value)); + return __sign_combinator(__first, __last, __value, + __from_chars_integral<__t>, __base); +} + +template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0> +inline _LIBCPP_INLINE_VISIBILITY from_chars_result +from_chars(const char* __first, const char* __last, _Tp& __value) +{ + return __from_chars_atoi(__first, __last, __value); +} + +template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0> +inline _LIBCPP_INLINE_VISIBILITY from_chars_result +from_chars(const char* __first, const char* __last, _Tp& __value, int __base) +{ + _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); + return __from_chars_integral(__first, __last, __value, __base); +} + +#endif // _LIBCPP_STD_VER > 11 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_CHARCONV diff --git a/lib/libcxx/include/chrono b/lib/libcxx/include/chrono index 809f773b6c6..f6a6f4b2434 100644 --- a/lib/libcxx/include/chrono +++ b/lib/libcxx/include/chrono @@ -147,6 +147,11 @@ template <class Clock, class Duration1, class Duration2> namespace chrono { + +template<class T> struct is_clock; // C++20 +template<class T> inline constexpr bool is_clock_v = is_clock<T>::value; // C++20 + + // duration arithmetic template <class Rep1, class Period1, class Rep2, class Period2> constexpr @@ -204,6 +209,8 @@ template <class ToDuration, class Rep, class Period> template <class ToDuration, class Rep, class Period> constexpr ToDuration round(const duration<Rep, Period>& d); // C++17 +// duration I/O is elsewhere + // time_point arithmetic (all constexpr in C++14) template <class Clock, class Duration1, class Rep2, class Period2> time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type> @@ -251,6 +258,7 @@ template <class ToDuration, class Clock, class Duration> template <class Rep, class Period> constexpr duration<Rep, Period> abs(duration<Rep, Period> d); // C++17 + // Clocks class system_clock @@ -267,6 +275,28 @@ public: static time_point from_time_t(time_t __t) noexcept; }; +template <class Duration> + using sys_time = time_point<system_clock, Duration>; // C++20 +using sys_seconds = sys_time<seconds>; // C++20 +using sys_days = sys_time<days>; // C++20 + +class utc_clock; // C++20 + +template <class Duration> + using utc_time = time_point<utc_clock, Duration>; // C++20 +using utc_seconds = utc_time<seconds>; // C++20 + +class tai_clock; // C++20 + +template <class Duration> + using tai_time = time_point<tai_clock, Duration>; // C++20 +using tai_seconds = tai_time<seconds>; // C++20 + +class file_clock; // C++20 + +template<class Duration> + using file_time = time_point<file_clock, Duration>; // C++20 + class steady_clock { public: @@ -281,8 +311,466 @@ public: typedef steady_clock high_resolution_clock; +// 25.7.8, local time // C++20 +struct local_t {}; +template<class Duration> + using local_time = time_point<local_t, Duration>; +using local_seconds = local_time<seconds>; +using local_days = local_time<days>; + +// 25.7.9, time_point conversions template<class DestClock, class SourceClock> // C++20 +struct clock_time_conversion; + +template<class DestClock, class SourceClock, class Duration> + auto clock_cast(const time_point<SourceClock, Duration>& t); + +// 25.8.2, class last_spec // C++20 +struct last_spec; + +// 25.8.3, class day // C++20 + +class day; +constexpr bool operator==(const day& x, const day& y) noexcept; +constexpr bool operator!=(const day& x, const day& y) noexcept; +constexpr bool operator< (const day& x, const day& y) noexcept; +constexpr bool operator> (const day& x, const day& y) noexcept; +constexpr bool operator<=(const day& x, const day& y) noexcept; +constexpr bool operator>=(const day& x, const day& y) noexcept; +constexpr day operator+(const day& x, const days& y) noexcept; +constexpr day operator+(const days& x, const day& y) noexcept; +constexpr day operator-(const day& x, const days& y) noexcept; +constexpr days operator-(const day& x, const day& y) noexcept; + +// 25.8.4, class month // C++20 +class month; +constexpr bool operator==(const month& x, const month& y) noexcept; +constexpr bool operator!=(const month& x, const month& y) noexcept; +constexpr bool operator< (const month& x, const month& y) noexcept; +constexpr bool operator> (const month& x, const month& y) noexcept; +constexpr bool operator<=(const month& x, const month& y) noexcept; +constexpr bool operator>=(const month& x, const month& y) noexcept; +constexpr month operator+(const month& x, const months& y) noexcept; +constexpr month operator+(const months& x, const month& y) noexcept; +constexpr month operator-(const month& x, const months& y) noexcept; +constexpr months operator-(const month& x, const month& y) noexcept; + +// 25.8.5, class year // C++20 +class year; +constexpr bool operator==(const year& x, const year& y) noexcept; +constexpr bool operator!=(const year& x, const year& y) noexcept; +constexpr bool operator< (const year& x, const year& y) noexcept; +constexpr bool operator> (const year& x, const year& y) noexcept; +constexpr bool operator<=(const year& x, const year& y) noexcept; +constexpr bool operator>=(const year& x, const year& y) noexcept; +constexpr year operator+(const year& x, const years& y) noexcept; +constexpr year operator+(const years& x, const year& y) noexcept; +constexpr year operator-(const year& x, const years& y) noexcept; +constexpr years operator-(const year& x, const year& y) noexcept; + +// 25.8.6, class weekday // C++20 +class weekday; + +constexpr bool operator==(const weekday& x, const weekday& y) noexcept; +constexpr bool operator!=(const weekday& x, const weekday& y) noexcept; +constexpr weekday operator+(const weekday& x, const days& y) noexcept; +constexpr weekday operator+(const days& x, const weekday& y) noexcept; +constexpr weekday operator-(const weekday& x, const days& y) noexcept; +constexpr days operator-(const weekday& x, const weekday& y) noexcept; + +// 25.8.7, class weekday_indexed // C++20 + +class weekday_indexed; +constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; +constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept; + +// 25.8.8, class weekday_last // C++20 +class weekday_last; + +constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; +constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept; + +// 25.8.9, class month_day // C++20 +class month_day; + +constexpr bool operator==(const month_day& x, const month_day& y) noexcept; +constexpr bool operator!=(const month_day& x, const month_day& y) noexcept; +constexpr bool operator< (const month_day& x, const month_day& y) noexcept; +constexpr bool operator> (const month_day& x, const month_day& y) noexcept; +constexpr bool operator<=(const month_day& x, const month_day& y) noexcept; +constexpr bool operator>=(const month_day& x, const month_day& y) noexcept; + + +// 25.8.10, class month_day_last // C++20 +class month_day_last; + +constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept; +constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept; + +// 25.8.11, class month_weekday // C++20 +class month_weekday; + +constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; +constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept; + +// 25.8.12, class month_weekday_last // C++20 +class month_weekday_last; + +constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; +constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept; + + +// 25.8.13, class year_month // C++20 +class year_month; + +constexpr bool operator==(const year_month& x, const year_month& y) noexcept; +constexpr bool operator!=(const year_month& x, const year_month& y) noexcept; +constexpr bool operator< (const year_month& x, const year_month& y) noexcept; +constexpr bool operator> (const year_month& x, const year_month& y) noexcept; +constexpr bool operator<=(const year_month& x, const year_month& y) noexcept; +constexpr bool operator>=(const year_month& x, const year_month& y) noexcept; + +constexpr year_month operator+(const year_month& ym, const months& dm) noexcept; +constexpr year_month operator+(const months& dm, const year_month& ym) noexcept; +constexpr year_month operator-(const year_month& ym, const months& dm) noexcept; +constexpr months operator-(const year_month& x, const year_month& y) noexcept; +constexpr year_month operator+(const year_month& ym, const years& dy) noexcept; +constexpr year_month operator+(const years& dy, const year_month& ym) noexcept; +constexpr year_month operator-(const year_month& ym, const years& dy) noexcept; + +// 25.8.14, class year_month_day class // C++20 +year_month_day; + +constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept; +constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept; + +constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; +constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; +constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; +constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; +constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; +constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; + + +// 25.8.15, class year_month_day_last // C++20 +class year_month_day_last; + +constexpr bool operator==(const year_month_day_last& x, + const year_month_day_last& y) noexcept; +constexpr bool operator!=(const year_month_day_last& x, + const year_month_day_last& y) noexcept; +constexpr bool operator< (const year_month_day_last& x, + const year_month_day_last& y) noexcept; +constexpr bool operator> (const year_month_day_last& x, + const year_month_day_last& y) noexcept; +constexpr bool operator<=(const year_month_day_last& x, + const year_month_day_last& y) noexcept; +constexpr bool operator>=(const year_month_day_last& x, + const year_month_day_last& y) noexcept; + +constexpr year_month_day_last + operator+(const year_month_day_last& ymdl, const months& dm) noexcept; +constexpr year_month_day_last + operator+(const months& dm, const year_month_day_last& ymdl) noexcept; +constexpr year_month_day_last + operator+(const year_month_day_last& ymdl, const years& dy) noexcept; +constexpr year_month_day_last + operator+(const years& dy, const year_month_day_last& ymdl) noexcept; +constexpr year_month_day_last + operator-(const year_month_day_last& ymdl, const months& dm) noexcept; +constexpr year_month_day_last + operator-(const year_month_day_last& ymdl, const years& dy) noexcept; + +// 25.8.16, class year_month_weekday // C++20 +class year_month_weekday; + +constexpr bool operator==(const year_month_weekday& x, + const year_month_weekday& y) noexcept; +constexpr bool operator!=(const year_month_weekday& x, + const year_month_weekday& y) noexcept; + +constexpr year_month_weekday + operator+(const year_month_weekday& ymwd, const months& dm) noexcept; +constexpr year_month_weekday + operator+(const months& dm, const year_month_weekday& ymwd) noexcept; +constexpr year_month_weekday + operator+(const year_month_weekday& ymwd, const years& dy) noexcept; +constexpr year_month_weekday + operator+(const years& dy, const year_month_weekday& ymwd) noexcept; +constexpr year_month_weekday + operator-(const year_month_weekday& ymwd, const months& dm) noexcept; +constexpr year_month_weekday + operator-(const year_month_weekday& ymwd, const years& dy) noexcept; + +// 25.8.17, class year_month_weekday_last // C++20 +class year_month_weekday_last; + +constexpr bool operator==(const year_month_weekday_last& x, + const year_month_weekday_last& y) noexcept; +constexpr bool operator!=(const year_month_weekday_last& x, + const year_month_weekday_last& y) noexcept; +constexpr year_month_weekday_last + operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; +constexpr year_month_weekday_last + operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept; +constexpr year_month_weekday_last + operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept; +constexpr year_month_weekday_last + operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept; +constexpr year_month_weekday_last + operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; +constexpr year_month_weekday_last + operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; + +// 25.8.18, civil calendar conventional syntax operators // C++20 +constexpr year_month + operator/(const year& y, const month& m) noexcept; +constexpr year_month + operator/(const year& y, int m) noexcept; +constexpr month_day + operator/(const month& m, const day& d) noexcept; +constexpr month_day + operator/(const month& m, int d) noexcept; +constexpr month_day + operator/(int m, const day& d) noexcept; +constexpr month_day + operator/(const day& d, const month& m) noexcept; +constexpr month_day + operator/(const day& d, int m) noexcept; +constexpr month_day_last + operator/(const month& m, last_spec) noexcept; +constexpr month_day_last + operator/(int m, last_spec) noexcept; +constexpr month_day_last + operator/(last_spec, const month& m) noexcept; +constexpr month_day_last + operator/(last_spec, int m) noexcept; +constexpr month_weekday + operator/(const month& m, const weekday_indexed& wdi) noexcept; +constexpr month_weekday + operator/(int m, const weekday_indexed& wdi) noexcept; +constexpr month_weekday + operator/(const weekday_indexed& wdi, const month& m) noexcept; +constexpr month_weekday + operator/(const weekday_indexed& wdi, int m) noexcept; +constexpr month_weekday_last + operator/(const month& m, const weekday_last& wdl) noexcept; +constexpr month_weekday_last + operator/(int m, const weekday_last& wdl) noexcept; +constexpr month_weekday_last + operator/(const weekday_last& wdl, const month& m) noexcept; +constexpr month_weekday_last + operator/(const weekday_last& wdl, int m) noexcept; +constexpr year_month_day + operator/(const year_month& ym, const day& d) noexcept; +constexpr year_month_day + operator/(const year_month& ym, int d) noexcept; +constexpr year_month_day + operator/(const year& y, const month_day& md) noexcept; +constexpr year_month_day + operator/(int y, const month_day& md) noexcept; +constexpr year_month_day + operator/(const month_day& md, const year& y) noexcept; +constexpr year_month_day + operator/(const month_day& md, int y) noexcept; +constexpr year_month_day_last + operator/(const year_month& ym, last_spec) noexcept; +constexpr year_month_day_last + operator/(const year& y, const month_day_last& mdl) noexcept; +constexpr year_month_day_last + operator/(int y, const month_day_last& mdl) noexcept; +constexpr year_month_day_last + operator/(const month_day_last& mdl, const year& y) noexcept; +constexpr year_month_day_last + operator/(const month_day_last& mdl, int y) noexcept; +constexpr year_month_weekday + operator/(const year_month& ym, const weekday_indexed& wdi) noexcept; +constexpr year_month_weekday + operator/(const year& y, const month_weekday& mwd) noexcept; +constexpr year_month_weekday + operator/(int y, const month_weekday& mwd) noexcept; +constexpr year_month_weekday + operator/(const month_weekday& mwd, const year& y) noexcept; +constexpr year_month_weekday + operator/(const month_weekday& mwd, int y) noexcept; +constexpr year_month_weekday_last + operator/(const year_month& ym, const weekday_last& wdl) noexcept; +constexpr year_month_weekday_last + operator/(const year& y, const month_weekday_last& mwdl) noexcept; +constexpr year_month_weekday_last + operator/(int y, const month_weekday_last& mwdl) noexcept; +constexpr year_month_weekday_last + operator/(const month_weekday_last& mwdl, const year& y) noexcept; +constexpr year_month_weekday_last + operator/(const month_weekday_last& mwdl, int y) noexcept; + +// 25.9, class template time_of_day // C++20 +template<class Duration> class time_of_day; + +template<> class time_of_day<hours>; +template<> class time_of_day<minutes>; +template<> class time_of_day<seconds>; +template<class Rep, class Period> class time_of_day<duration<Rep, Period>>; + +// 25.10.2, time zone database // C++20 +struct tzdb; +class tzdb_list; + +// 25.10.2.3, time zone database access // C++20 +const tzdb& get_tzdb(); +tzdb_list& get_tzdb_list(); +const time_zone* locate_zone(string_view tz_name); +const time_zone* current_zone(); + +// 25.10.2.4, remote time zone database support // C++20 +const tzdb& reload_tzdb(); +string remote_version(); + +// 25.10.3, exception classes // C++20 +class nonexistent_local_time; +class ambiguous_local_time; + +// 25.10.4, information classes // C++20 +struct sys_info; +struct local_info; + +// 25.10.5, class time_zone // C++20 +enum class choose {earliest, latest}; +class time_zone; +bool operator==(const time_zone& x, const time_zone& y) noexcept; +bool operator!=(const time_zone& x, const time_zone& y) noexcept; +bool operator<(const time_zone& x, const time_zone& y) noexcept; +bool operator>(const time_zone& x, const time_zone& y) noexcept; +bool operator<=(const time_zone& x, const time_zone& y) noexcept; +bool operator>=(const time_zone& x, const time_zone& y) noexcept; + +// 25.10.6, class template zoned_traits // C++20 +template<class T> struct zoned_traits; + +// 25.10.7, class template zoned_time // C++20 +template<class Duration, class TimeZonePtr = const time_zone*> class zoned_time; +using zoned_seconds = zoned_time<seconds>; + +template<class Duration1, class Duration2, class TimeZonePtr> + bool operator==(const zoned_time<Duration1, TimeZonePtr>& x, + const zoned_time<Duration2, TimeZonePtr>& y); +template<class Duration1, class Duration2, class TimeZonePtr> + bool operator!=(const zoned_time<Duration1, TimeZonePtr>& x, + const zoned_time<Duration2, TimeZonePtr>& y); + +// 25.10.8, leap second support // C++20 +class leap; + +bool operator==(const leap& x, const leap& y); +bool operator!=(const leap& x, const leap& y); +bool operator< (const leap& x, const leap& y); +bool operator> (const leap& x, const leap& y); +bool operator<=(const leap& x, const leap& y); +bool operator>=(const leap& x, const leap& y); +template<class Duration> + bool operator==(const leap& x, const sys_time<Duration>& y); +template<class Duration> + bool operator==(const sys_time<Duration>& x, const leap& y); +template<class Duration> + bool operator!=(const leap& x, const sys_time<Duration>& y); +template<class Duration> + bool operator!=(const sys_time<Duration>& x, const leap& y); +template<class Duration> + bool operator< (const leap& x, const sys_time<Duration>& y); +template<class Duration> + bool operator< (const sys_time<Duration>& x, const leap& y); +template<class Duration> + bool operator> (const leap& x, const sys_time<Duration>& y); +template<class Duration> + bool operator> (const sys_time<Duration>& x, const leap& y); +template<class Duration> + bool operator<=(const leap& x, const sys_time<Duration>& y); +template<class Duration> + bool operator<=(const sys_time<Duration>& x, const leap& y); +template<class Duration> + bool operator>=(const leap& x, const sys_time<Duration>& y); +template<class Duration> + bool operator>=(const sys_time<Duration>& x, const leap& y); + +// 25.10.9, class link // C++20 +class link; +bool operator==(const link& x, const link& y); +bool operator!=(const link& x, const link& y); +bool operator< (const link& x, const link& y); +bool operator> (const link& x, const link& y); +bool operator<=(const link& x, const link& y); +bool operator>=(const link& x, const link& y); + +// 25.11, formatting // C++20 +template<class charT, class Streamable> + basic_string<charT> + format(const charT* fmt, const Streamable& s); + +template<class charT, class Streamable> + basic_string<charT> + format(const locale& loc, const charT* fmt, const Streamable& s); + +template<class charT, class traits, class Alloc, class Streamable> + basic_string<charT, traits, Alloc> + format(const basic_string<charT, traits, Alloc>& fmt, const Streamable& s); + +template<class charT, class traits, class Alloc, class Streamable> + basic_string<charT, traits, Alloc> + format(const locale& loc, const basic_string<charT, traits, Alloc>& fmt, + const Streamable& s); + +// 25.12, parsing // C++20 +template<class charT, class traits, class Alloc, class Parsable> +unspecified + parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp); + +template<class charT, class traits, class Alloc, class Parsable> +unspecified + parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp, + basic_string<charT, traits, Alloc>& abbrev); + +template<class charT, class traits, class Alloc, class Parsable> +unspecified + parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp, + minutes& offset); + +template<class charT, class traits, class Alloc, class Parsable> +unspecified + parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp, + basic_string<charT, traits, Alloc>& abbrev, minutes& offset); + +inline constexpr last_spec last{}; // C++20 +inline constexpr chrono::weekday Sunday{0}; // C++20 +inline constexpr chrono::weekday Monday{1}; // C++20 +inline constexpr chrono::weekday Tuesday{2}; // C++20 +inline constexpr chrono::weekday Wednesday{3}; // C++20 +inline constexpr chrono::weekday Thursday{4}; // C++20 +inline constexpr chrono::weekday Friday{5}; // C++20 +inline constexpr chrono::weekday Saturday{6}; // C++20 + +inline constexpr chrono::month January{1}; // C++20 +inline constexpr chrono::month February{2}; // C++20 +inline constexpr chrono::month March{3}; // C++20 +inline constexpr chrono::month April{4}; // C++20 +inline constexpr chrono::month May{5}; // C++20 +inline constexpr chrono::month June{6}; // C++20 +inline constexpr chrono::month July{7}; // C++20 +inline constexpr chrono::month August{8}; // C++20 +inline constexpr chrono::month September{9}; // C++20 +inline constexpr chrono::month October{10}; // C++20 +inline constexpr chrono::month November{11}; // C++20 +inline constexpr chrono::month December{12}; // C++20 } // chrono +inline namespace literals { + inline namespace chrono_literals { constexpr chrono::hours operator ""h(unsigned long long); // C++14 constexpr chrono::duration<unspecified , ratio<3600,1>> operator ""h(long double); // C++14 constexpr chrono::minutes operator ""min(unsigned long long); // C++14 @@ -295,6 +783,10 @@ constexpr chrono::microseconds operator ""us(unsigned l constexpr chrono::duration<unspecified , micro> operator ""us(long double); // C++14 constexpr chrono::nanoseconds operator ""ns(unsigned long long); // C++14 constexpr chrono::duration<unspecified , nano> operator ""ns(long double); // C++14 +constexpr chrono::day operator ""d(unsigned long long d) noexcept; // C++20 +constexpr chrono::year operator ""y(unsigned long long y) noexcept; // C++20 +} // chrono_literals +} // literals } // std */ diff --git a/lib/libcxx/include/cmath b/lib/libcxx/include/cmath index 917928a1f42..ffb1c46c7b6 100644 --- a/lib/libcxx/include/cmath +++ b/lib/libcxx/include/cmath @@ -547,7 +547,7 @@ hypot(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT #endif template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type __libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT { @@ -559,7 +559,7 @@ __libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT } template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type __libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT { @@ -567,7 +567,7 @@ __libcpp_isnan_or_builtin(_A1 __lcpp_x) _NOEXCEPT } template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type __libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT { @@ -579,7 +579,7 @@ __libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT } template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type __libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT { @@ -587,7 +587,7 @@ __libcpp_isinf_or_builtin(_A1 __lcpp_x) _NOEXCEPT } template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type __libcpp_isfinite_or_builtin(_A1 __lcpp_x) _NOEXCEPT { @@ -599,7 +599,7 @@ __libcpp_isfinite_or_builtin(_A1 __lcpp_x) _NOEXCEPT } template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type __libcpp_isfinite_or_builtin(_A1 __lcpp_x) _NOEXCEPT { diff --git a/lib/libcxx/include/codecvt b/lib/libcxx/include/codecvt index 46f56acff71..5eb9d154911 100644 --- a/lib/libcxx/include/codecvt +++ b/lib/libcxx/include/codecvt @@ -86,7 +86,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -121,7 +121,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -156,7 +156,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -186,11 +186,11 @@ class _LIBCPP_TEMPLATE_VIS codecvt_utf8 : public __codecvt_utf8<_Elem> { public: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt_utf8(size_t __refs = 0) : __codecvt_utf8<_Elem>(__refs, _Maxcode, _Mode) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~codecvt_utf8() {} }; @@ -209,7 +209,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -244,7 +244,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -279,7 +279,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -314,7 +314,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -349,7 +349,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -384,7 +384,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -414,11 +414,11 @@ class _LIBCPP_TEMPLATE_VIS codecvt_utf16 : public __codecvt_utf16<_Elem, _Mode & little_endian> { public: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt_utf16(size_t __refs = 0) : __codecvt_utf16<_Elem, _Mode & little_endian>(__refs, _Maxcode, _Mode) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~codecvt_utf16() {} }; @@ -437,7 +437,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -472,7 +472,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -507,7 +507,7 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), @@ -537,11 +537,11 @@ class _LIBCPP_TEMPLATE_VIS codecvt_utf8_utf16 : public __codecvt_utf8_utf16<_Elem> { public: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt_utf8_utf16(size_t __refs = 0) : __codecvt_utf8_utf16<_Elem>(__refs, _Maxcode, _Mode) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~codecvt_utf8_utf16() {} }; diff --git a/lib/libcxx/include/compare b/lib/libcxx/include/compare new file mode 100644 index 00000000000..07f88f09cb3 --- /dev/null +++ b/lib/libcxx/include/compare @@ -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; + + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept; +#endif + +private: + _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 + _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept { + return __value_ == _EqResult::__zero ? weak_equality::equivalent + : weak_equality::nonequivalent; + } + + // comparisons + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept; +#endif +private: + _EqResult __value_; +}; + +_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 + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; +#endif + +private: + _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 + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; +#endif + +private: + _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 + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; + +#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; + _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; +#endif + +private: + _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 diff --git a/lib/libcxx/include/complex b/lib/libcxx/include/complex index 41a47cfba47..d692ee31920 100644 --- a/lib/libcxx/include/complex +++ b/lib/libcxx/include/complex @@ -203,7 +203,7 @@ template<class T> complex<T> proj(const complex<T>&); template<Integral T> complex<double> proj(T); complex<float> proj(float); -template<class T> complex<T> polar(const T&, const T& = 0); +template<class T> complex<T> polar(const T&, const T& = T()); // 26.3.8 transcendentals: template<class T> complex<T> acos(const complex<T>&); @@ -991,7 +991,7 @@ proj(_Tp __re) template<class _Tp> complex<_Tp> -polar(const _Tp& __rho, const _Tp& __theta = _Tp(0)) +polar(const _Tp& __rho, const _Tp& __theta = _Tp()) { if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho)) return complex<_Tp>(_Tp(NAN), _Tp(NAN)); @@ -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())); diff --git a/lib/libcxx/include/cstdlib b/lib/libcxx/include/cstdlib index 78c428403c3..00c604e6762 100644 --- a/lib/libcxx/include/cstdlib +++ b/lib/libcxx/include/cstdlib @@ -151,11 +151,11 @@ using ::mbtowc; using ::wctomb; using ::mbstowcs; using ::wcstombs; -#ifdef _LIBCPP_HAS_QUICK_EXIT +#if !defined(_LIBCPP_CXX03_LANG) && defined(_LIBCPP_HAS_QUICK_EXIT) using ::at_quick_exit; using ::quick_exit; #endif -#ifdef _LIBCPP_HAS_C11_FEATURES +#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES) using ::aligned_alloc; #endif diff --git a/lib/libcxx/include/ctime b/lib/libcxx/include/ctime index da9e3290bbb..8264fe33b96 100644 --- a/lib/libcxx/include/ctime +++ b/lib/libcxx/include/ctime @@ -18,7 +18,8 @@ Macros: NULL CLOCKS_PER_SEC - + TIME_UTC // C++17 + namespace std { @@ -28,7 +29,8 @@ Types: size_t time_t tm - + timespec // C++17 + clock_t clock(); double difftime(time_t time1, time_t time0); time_t mktime(tm* timeptr); @@ -39,7 +41,7 @@ tm* gmtime(const time_t* timer); tm* localtime(const time_t* timer); size_t strftime(char* restrict s, size_t maxsize, const char* restrict format, const tm* restrict timeptr); - +int timespec_get( struct timespec *ts, int base); // C++17 } // std */ @@ -57,6 +59,9 @@ using ::clock_t; using ::size_t; using ::time_t; using ::tm; +#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES) +using ::timespec; +#endif using ::clock; using ::difftime; using ::mktime; @@ -68,6 +73,9 @@ using ::gmtime; using ::localtime; #endif using ::strftime; +#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET) +using ::timespec_get; +#endif _LIBCPP_END_NAMESPACE_STD diff --git a/lib/libcxx/include/deque b/lib/libcxx/include/deque index 08cb295408b..bfbd3a5ef54 100644 --- a/lib/libcxx/include/deque +++ b/lib/libcxx/include/deque @@ -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) { diff --git a/lib/libcxx/include/exception b/lib/libcxx/include/exception index 79bd6ac2ae3..b517486b5a8 100644 --- a/lib/libcxx/include/exception +++ b/lib/libcxx/include/exception @@ -259,7 +259,7 @@ struct __throw_with_nested; template <class _Tp, class _Up> struct __throw_with_nested<_Tp, _Up, true> { - _LIBCPP_NORETURN static inline _LIBCPP_ALWAYS_INLINE void + _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void #ifndef _LIBCPP_CXX03_LANG __do_throw(_Tp&& __t) #else @@ -272,7 +272,7 @@ struct __throw_with_nested<_Tp, _Up, true> { template <class _Tp, class _Up> struct __throw_with_nested<_Tp, _Up, false> { - _LIBCPP_NORETURN static inline _LIBCPP_ALWAYS_INLINE void + _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void #ifndef _LIBCPP_CXX03_LANG __do_throw(_Tp&& __t) #else diff --git a/lib/libcxx/include/experimental/__config b/lib/libcxx/include/experimental/__config index 37f88c166dd..c6f17762022 100644 --- a/lib/libcxx/include/experimental/__config +++ b/lib/libcxx/include/experimental/__config @@ -52,6 +52,23 @@ #define _VSTD_CORO _VSTD_EXPERIMENTAL::coroutines_v1 -#define _VSTD_FS ::std::experimental::filesystem::v1 +#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD \ + _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 { + +#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 + +// TODO: support more targets +#if defined(__AVX__) +#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 32 +#else +#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 16 +#endif #endif diff --git a/lib/libcxx/include/experimental/algorithm b/lib/libcxx/include/experimental/algorithm index a6a28f07181..eb3bad6ef98 100644 --- a/lib/libcxx/include/experimental/algorithm +++ b/lib/libcxx/include/experimental/algorithm @@ -23,11 +23,8 @@ inline namespace fundamentals_v1 { template <class ForwardIterator, class Searcher> ForwardIterator search(ForwardIterator first, ForwardIterator last, const Searcher &searcher); -template <class PopulationIterator, class SampleIterator, class Distance, - class UniformRandomNumberGenerator> -SampleIterator sample(PopulationIterator first, PopulationIterator last, - SampleIterator out, Distance n, - UniformRandomNumberGenerator &&g); + +// sample removed because it's now part of C++17 } // namespace fundamentals_v1 } // namespace experimental @@ -56,16 +53,6 @@ _LIBCPP_INLINE_VISIBILITY _ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s) { return __s(__f, __l).first; } - -template <class _PopulationIterator, class _SampleIterator, class _Distance, - class _UniformRandomNumberGenerator> -inline _LIBCPP_INLINE_VISIBILITY -_SampleIterator sample(_PopulationIterator __first, _PopulationIterator __last, - _SampleIterator __output_iter, _Distance __n, - _UniformRandomNumberGenerator &&__g) { - return _VSTD::__sample(__first, __last, __output_iter, __n, __g); -} - _LIBCPP_END_NAMESPACE_LFTS _LIBCPP_POP_MACROS diff --git a/lib/libcxx/include/experimental/any b/lib/libcxx/include/experimental/any index 083a2909033..1dcdd0f25ec 100644 --- a/lib/libcxx/include/experimental/any +++ b/lib/libcxx/include/experimental/any @@ -8,585 +8,4 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL_ANY -#define _LIBCPP_EXPERIMENTAL_ANY - -/* - experimental/any synopsis - -namespace std { -namespace experimental { -inline namespace fundamentals_v1 { - - class bad_any_cast : public bad_cast - { - public: - virtual const char* what() const noexcept; - }; - - class any - { - public: - - // 6.3.1 any construct/destruct - any() noexcept; - - any(const any& other); - any(any&& other) noexcept; - - template <class ValueType> - any(ValueType&& value); - - ~any(); - - // 6.3.2 any assignments - any& operator=(const any& rhs); - any& operator=(any&& rhs) noexcept; - - template <class ValueType> - any& operator=(ValueType&& rhs); - - // 6.3.3 any modifiers - void clear() noexcept; - void swap(any& rhs) noexcept; - - // 6.3.4 any observers - bool empty() const noexcept; - const type_info& type() const noexcept; - }; - - // 6.4 Non-member functions - void swap(any& x, any& y) noexcept; - - template<class ValueType> - ValueType any_cast(const any& operand); - template<class ValueType> - ValueType any_cast(any& operand); - template<class ValueType> - ValueType any_cast(any&& operand); - - template<class ValueType> - const ValueType* any_cast(const any* operand) noexcept; - template<class ValueType> - ValueType* any_cast(any* operand) noexcept; - -} // namespace fundamentals_v1 -} // namespace experimental -} // namespace std - -*/ - -#include <experimental/__config> -#include <memory> -#include <new> -#include <typeinfo> -#include <type_traits> -#include <cstdlib> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_LFTS - -class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast -{ -public: - virtual const char* what() const _NOEXCEPT; -}; - -#if _LIBCPP_STD_VER > 11 // C++ > 11 - -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE -_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST -void __throw_bad_any_cast() -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - throw bad_any_cast(); -#else - _VSTD::abort(); -#endif -} - -// Forward declarations -class any; - -template <class _ValueType> -typename add_pointer<typename add_const<_ValueType>::type>::type -_LIBCPP_INLINE_VISIBILITY -any_cast(any const *) _NOEXCEPT; - -template <class _ValueType> -typename add_pointer<_ValueType>::type -_LIBCPP_INLINE_VISIBILITY -any_cast(any *) _NOEXCEPT; - -namespace __any_imp -{ - typedef typename aligned_storage<3*sizeof(void*), alignment_of<void*>::value>::type - _Buffer; - - template <class _Tp> - struct _IsSmallObject - : public integral_constant<bool - , sizeof(_Tp) <= sizeof(_Buffer) - && alignment_of<_Buffer>::value - % alignment_of<_Tp>::value == 0 - && is_nothrow_move_constructible<_Tp>::value - > - {}; - - enum class _Action - { - _Destroy, - _Copy, - _Move, - _Get, - _TypeInfo - }; - - template <class _Tp> - struct _SmallHandler; - - template <class _Tp> - struct _LargeHandler; - - template <class _Tp> - using _Handler = typename conditional<_IsSmallObject<_Tp>::value - , _SmallHandler<_Tp> - , _LargeHandler<_Tp> - >::type; - template <class _ValueType> - using _EnableIfNotAny = typename - enable_if< - !is_same<typename decay<_ValueType>::type, any>::value - >::type; - -} // namespace __any_imp - -class any -{ -public: - // 6.3.1 any construct/destruct - _LIBCPP_INLINE_VISIBILITY - any() _NOEXCEPT : __h(nullptr) {} - - _LIBCPP_INLINE_VISIBILITY - any(any const & __other) : __h(nullptr) - { - if (__other.__h) __other.__call(_Action::_Copy, this); - } - - _LIBCPP_INLINE_VISIBILITY - any(any && __other) _NOEXCEPT : __h(nullptr) - { - if (__other.__h) __other.__call(_Action::_Move, this); - } - - template < - class _ValueType - , class = __any_imp::_EnableIfNotAny<_ValueType> - > - _LIBCPP_INLINE_VISIBILITY - any(_ValueType && __value); - - _LIBCPP_INLINE_VISIBILITY - ~any() - { - this->clear(); - } - - // 6.3.2 any assignments - _LIBCPP_INLINE_VISIBILITY - any & operator=(any const & __rhs) - { - any(__rhs).swap(*this); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - any & operator=(any && __rhs) _NOEXCEPT - { - any(_VSTD::move(__rhs)).swap(*this); - return *this; - } - - template < - class _ValueType - , class = __any_imp::_EnableIfNotAny<_ValueType> - > - _LIBCPP_INLINE_VISIBILITY - any & operator=(_ValueType && __rhs); - - // 6.3.3 any modifiers - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT - { - if (__h) this->__call(_Action::_Destroy); - } - - _LIBCPP_INLINE_VISIBILITY - void swap(any & __rhs) _NOEXCEPT; - - // 6.3.4 any observers - _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT - { - return __h == nullptr; - } - -#if !defined(_LIBCPP_NO_RTTI) - _LIBCPP_INLINE_VISIBILITY - const type_info & type() const _NOEXCEPT - { - if (__h) { - return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo)); - } else { - return typeid(void); - } - } -#endif - -private: - typedef __any_imp::_Action _Action; - - typedef void* (*_HandleFuncPtr)(_Action, any const *, any *, const type_info *); - - union _Storage - { - void * __ptr; - __any_imp::_Buffer __buf; - }; - - _LIBCPP_ALWAYS_INLINE - void * __call(_Action __a, any * __other = nullptr, - type_info const * __info = nullptr) const - { - return __h(__a, this, __other, __info); - } - - _LIBCPP_ALWAYS_INLINE - void * __call(_Action __a, any * __other = nullptr, - type_info const * __info = nullptr) - { - return __h(__a, this, __other, __info); - } - - template <class> - friend struct __any_imp::_SmallHandler; - template <class> - friend struct __any_imp::_LargeHandler; - - template <class _ValueType> - friend typename add_pointer<typename add_const<_ValueType>::type>::type - any_cast(any const *) _NOEXCEPT; - - template <class _ValueType> - friend typename add_pointer<_ValueType>::type - any_cast(any *) _NOEXCEPT; - - _HandleFuncPtr __h; - _Storage __s; -}; - -namespace __any_imp -{ - - template <class _Tp> - struct _LIBCPP_TEMPLATE_VIS _SmallHandler - { - _LIBCPP_INLINE_VISIBILITY - static void* __handle(_Action __act, any const * __this, any * __other, - type_info const * __info) - { - switch (__act) - { - case _Action::_Destroy: - __destroy(const_cast<any &>(*__this)); - return nullptr; - case _Action::_Copy: - __copy(*__this, *__other); - return nullptr; - case _Action::_Move: - __move(const_cast<any &>(*__this), *__other); - return nullptr; - case _Action::_Get: - return __get(const_cast<any &>(*__this), __info); - case _Action::_TypeInfo: - return __type_info(); - } - } - - template <class _Up> - _LIBCPP_INLINE_VISIBILITY - static void __create(any & __dest, _Up && __v) - { - ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Up>(__v)); - __dest.__h = &_SmallHandler::__handle; - } - - private: - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void __destroy(any & __this) - { - _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf)); - __value.~_Tp(); - __this.__h = nullptr; - } - - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void __copy(any const & __this, any & __dest) - { - _SmallHandler::__create(__dest, *static_cast<_Tp const *>( - static_cast<void const *>(&__this.__s.__buf))); - } - - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void __move(any & __this, any & __dest) - { - _SmallHandler::__create(__dest, _VSTD::move( - *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf)))); - __destroy(__this); - } - - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void* __get(any & __this, type_info const * __info) - { -#if !defined(_LIBCPP_NO_RTTI) - if (typeid(_Tp) == *__info) { - return static_cast<void*>(&__this.__s.__buf); - } - return nullptr; -#else - return static_cast<void*>(&__this.__s.__buf); -#endif - } - - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void* __type_info() - { -#if !defined(_LIBCPP_NO_RTTI) - return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); -#else - return nullptr; -#endif - } - }; - - template <class _Tp> - struct _LIBCPP_TEMPLATE_VIS _LargeHandler - { - _LIBCPP_INLINE_VISIBILITY - static void* __handle(_Action __act, any const * __this, any * __other, - type_info const * __info) - { - switch (__act) - { - case _Action::_Destroy: - __destroy(const_cast<any &>(*__this)); - return nullptr; - case _Action::_Copy: - __copy(*__this, *__other); - return nullptr; - case _Action::_Move: - __move(const_cast<any &>(*__this), *__other); - return nullptr; - case _Action::_Get: - return __get(const_cast<any &>(*__this), __info); - case _Action::_TypeInfo: - return __type_info(); - } - } - - template <class _Up> - _LIBCPP_INLINE_VISIBILITY - static void __create(any & __dest, _Up && __v) - { - typedef allocator<_Tp> _Alloc; - typedef __allocator_destructor<_Alloc> _Dp; - _Alloc __a; - unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Up>(__v)); - __dest.__s.__ptr = __hold.release(); - __dest.__h = &_LargeHandler::__handle; - } - - private: - - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void __destroy(any & __this) - { - delete static_cast<_Tp*>(__this.__s.__ptr); - __this.__h = nullptr; - } - - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void __copy(any const & __this, any & __dest) - { - _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr)); - } - - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void __move(any & __this, any & __dest) - { - __dest.__s.__ptr = __this.__s.__ptr; - __dest.__h = &_LargeHandler::__handle; - __this.__h = nullptr; - } - - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void* __get(any & __this, type_info const * __info) - { -#if !defined(_LIBCPP_NO_RTTI) - if (typeid(_Tp) == *__info) { - return static_cast<void*>(__this.__s.__ptr); - } - return nullptr; -#else - return static_cast<void*>(__this.__s.__ptr); -#endif - } - - _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY - static void* __type_info() - { -#if !defined(_LIBCPP_NO_RTTI) - return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); -#else - return nullptr; -#endif - } - }; - -} // namespace __any_imp - - -template <class _ValueType, class> -any::any(_ValueType && __v) : __h(nullptr) -{ - typedef typename decay<_ValueType>::type _Tp; - static_assert(is_copy_constructible<_Tp>::value, - "_ValueType must be CopyConstructible."); - typedef __any_imp::_Handler<_Tp> _HandlerType; - _HandlerType::__create(*this, _VSTD::forward<_ValueType>(__v)); -} - -template <class _ValueType, class> -any & any::operator=(_ValueType && __v) -{ - typedef typename decay<_ValueType>::type _Tp; - static_assert(is_copy_constructible<_Tp>::value, - "_ValueType must be CopyConstructible."); - any(_VSTD::forward<_ValueType>(__v)).swap(*this); - return *this; -} - -inline -void any::swap(any & __rhs) _NOEXCEPT -{ - if (__h && __rhs.__h) { - any __tmp; - __rhs.__call(_Action::_Move, &__tmp); - this->__call(_Action::_Move, &__rhs); - __tmp.__call(_Action::_Move, this); - } - else if (__h) { - this->__call(_Action::_Move, &__rhs); - } - else if (__rhs.__h) { - __rhs.__call(_Action::_Move, this); - } -} - -// 6.4 Non-member functions - -inline _LIBCPP_INLINE_VISIBILITY -void swap(any & __lhs, any & __rhs) _NOEXCEPT -{ - __lhs.swap(__rhs); -} - -template <class _ValueType> -_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST -_ValueType any_cast(any const & __v) -{ - static_assert( - is_reference<_ValueType>::value - || is_copy_constructible<_ValueType>::value, - "_ValueType is required to be a reference or a CopyConstructible type."); - typedef typename add_const<typename remove_reference<_ValueType>::type>::type - _Tp; - _Tp * __tmp = any_cast<_Tp>(&__v); - if (__tmp == nullptr) - __throw_bad_any_cast(); - return *__tmp; -} - -template <class _ValueType> -_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST -_ValueType any_cast(any & __v) -{ - static_assert( - is_reference<_ValueType>::value - || is_copy_constructible<_ValueType>::value, - "_ValueType is required to be a reference or a CopyConstructible type."); - typedef typename remove_reference<_ValueType>::type _Tp; - _Tp * __tmp = any_cast<_Tp>(&__v); - if (__tmp == nullptr) - __throw_bad_any_cast(); - return *__tmp; -} - -template <class _ValueType> -_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST -_ValueType any_cast(any && __v) -{ - static_assert( - is_reference<_ValueType>::value - || is_copy_constructible<_ValueType>::value, - "_ValueType is required to be a reference or a CopyConstructible type."); - typedef typename remove_reference<_ValueType>::type _Tp; - _Tp * __tmp = any_cast<_Tp>(&__v); - if (__tmp == nullptr) - __throw_bad_any_cast(); - return *__tmp; -} - -template <class _ValueType> -inline -typename add_pointer<typename add_const<_ValueType>::type>::type -any_cast(any const * __any) _NOEXCEPT -{ - static_assert(!is_reference<_ValueType>::value, - "_ValueType may not be a reference."); - return any_cast<_ValueType>(const_cast<any *>(__any)); -} - -template <class _ValueType> -typename add_pointer<_ValueType>::type -any_cast(any * __any) _NOEXCEPT -{ - using __any_imp::_Action; - static_assert(!is_reference<_ValueType>::value, - "_ValueType may not be a reference."); - typedef typename add_pointer<_ValueType>::type _ReturnType; - if (__any && __any->__h) { - - return static_cast<_ReturnType>( - __any->__call(_Action::_Get, nullptr, -#if !defined(_LIBCPP_NO_RTTI) - &typeid(_ValueType) -#else - nullptr -#endif - )); - - } - return nullptr; -} - -#endif // _LIBCPP_STD_VER > 11 - -_LIBCPP_END_NAMESPACE_LFTS - -#endif // _LIBCPP_EXPERIMENTAL_ANY +#error "<experimental/any> has been removed. Use <any> instead." diff --git a/lib/libcxx/include/experimental/chrono b/lib/libcxx/include/experimental/chrono index ca9e5f852ea..591cf7160c1 100644 --- a/lib/libcxx/include/experimental/chrono +++ b/lib/libcxx/include/experimental/chrono @@ -8,52 +8,4 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL_CHRONO -#define _LIBCPP_EXPERIMENTAL_CHRONO - -/** - experimental/chrono synopsis - -// C++1y - -#include <chrono> - -namespace std { -namespace chrono { -namespace experimental { -inline namespace fundamentals_v1 { - - // See C++14 20.12.4, customization traits - template <class Rep> constexpr bool treat_as_floating_point_v - = treat_as_floating_point<Rep>::value; - -} // namespace fundamentals_v1 -} // namespace experimental -} // namespace chrono -} // namespace std - - */ - -#include <experimental/__config> -#include <chrono> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -#if _LIBCPP_STD_VER > 11 - -_LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS - -#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES - -template <class _Rep> _LIBCPP_CONSTEXPR bool treat_as_floating_point_v - = treat_as_floating_point<_Rep>::value; - -#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */ - -_LIBCPP_END_NAMESPACE_CHRONO_LFTS - -#endif /* _LIBCPP_STD_VER > 11 */ - -#endif /* _LIBCPP_EXPERIMENTAL_CHRONO */ +#error "<experimental/chrono> has been removed. Use <chrono> instead." diff --git a/lib/libcxx/include/experimental/coroutine b/lib/libcxx/include/experimental/coroutine index ce795ad452c..1eb224a535a 100644 --- a/lib/libcxx/include/experimental/coroutine +++ b/lib/libcxx/include/experimental/coroutine @@ -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,61 @@ 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: + _LIBCPP_INLINE_VISIBILITY + 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 {} }; diff --git a/lib/libcxx/include/experimental/dynarray b/lib/libcxx/include/experimental/dynarray index 16193317ad2..a60c87c3f97 100644 --- a/lib/libcxx/include/experimental/dynarray +++ b/lib/libcxx/include/experimental/dynarray @@ -133,19 +133,20 @@ public: private: size_t __size_; value_type * __base_; - _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __size_(0), __base_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY dynarray () noexcept : __size_(0), __base_(nullptr) {} - static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count ) - { - if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count ) + 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: diff --git a/lib/libcxx/include/experimental/filesystem b/lib/libcxx/include/experimental/filesystem index 674490f6038..28d8dcf4fc1 100644 --- a/lib/libcxx/include/experimental/filesystem +++ b/lib/libcxx/include/experimental/filesystem @@ -16,24 +16,25 @@ class path; - void swap(path& lhs, path& rhs) _NOEXCEPT; - size_t hash_value(const path& p) _NOEXCEPT; + void swap(path& lhs, path& rhs) noexcept; + size_t hash_value(const path& p) noexcept; - bool operator==(const path& lhs, const path& rhs) _NOEXCEPT; - bool operator!=(const path& lhs, const path& rhs) _NOEXCEPT; - bool operator< (const path& lhs, const path& rhs) _NOEXCEPT; - bool operator<=(const path& lhs, const path& rhs) _NOEXCEPT; - bool operator> (const path& lhs, const path& rhs) _NOEXCEPT; - bool operator>=(const path& lhs, const path& rhs) _NOEXCEPT; + bool operator==(const path& lhs, const path& rhs) noexcept; + bool operator!=(const path& lhs, const path& rhs) noexcept; + bool operator< (const path& lhs, const path& rhs) noexcept; + bool operator<=(const path& lhs, const path& rhs) noexcept; + bool operator> (const path& lhs, const path& rhs) noexcept; + bool operator>=(const path& lhs, const path& rhs) noexcept; path operator/ (const path& lhs, const path& rhs); + // fs.path.io operators are friends of path. template <class charT, class traits> - basic_ostream<charT, traits>& + friend basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const path& p); template <class charT, class traits> - basic_istream<charT, traits>& + friend basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, path& p); template <class Source> @@ -67,6 +68,7 @@ enum class file_type; enum class perms; + enum class perm_options; enum class copy_options; enum class directory_options; @@ -74,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); @@ -87,2054 +89,169 @@ error_code& ec); bool copy_file(const path& from, const path& to); - bool copy_file(const path& from, const path& to, error_code& ec) _NOEXCEPT; + bool copy_file(const path& from, const path& to, error_code& ec); bool copy_file(const path& from, const path& to, copy_options option); bool copy_file(const path& from, const path& to, copy_options option, - error_code& ec) _NOEXCEPT; + error_code& ec); void copy_symlink(const path& existing_symlink, const path& new_symlink); void copy_symlink(const path& existing_symlink, const path& new_symlink, - error_code& ec) _NOEXCEPT; + error_code& ec) noexcept; bool create_directories(const path& p); - bool create_directories(const path& p, error_code& ec) _NOEXCEPT; + bool create_directories(const path& p, error_code& ec); bool create_directory(const path& p); - bool create_directory(const path& p, error_code& ec) _NOEXCEPT; + bool create_directory(const path& p, error_code& ec) noexcept; bool create_directory(const path& p, const path& attributes); bool create_directory(const path& p, const path& attributes, - error_code& ec) _NOEXCEPT; + error_code& ec) noexcept; void create_directory_symlink(const path& to, const path& new_symlink); void create_directory_symlink(const path& to, const path& new_symlink, - error_code& ec) _NOEXCEPT; + error_code& ec) noexcept; void create_hard_link(const path& to, const path& new_hard_link); void create_hard_link(const path& to, const path& new_hard_link, - error_code& ec) _NOEXCEPT; + error_code& ec) noexcept; void create_symlink(const path& to, const path& new_symlink); void create_symlink(const path& to, const path& new_symlink, - error_code& ec) _NOEXCEPT; + error_code& ec) noexcept; path current_path(); path current_path(error_code& ec); void current_path(const path& p); - void current_path(const path& p, error_code& ec) _NOEXCEPT; + void current_path(const path& p, error_code& ec) noexcept; - bool exists(file_status s) _NOEXCEPT; + bool exists(file_status s) noexcept; bool exists(const path& p); - bool exists(const path& p, error_code& ec) _NOEXCEPT; + bool exists(const path& p, error_code& ec) noexcept; bool equivalent(const path& p1, const path& p2); - bool equivalent(const path& p1, const path& p2, error_code& ec) _NOEXCEPT; + bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept; uintmax_t file_size(const path& p); - uintmax_t file_size(const path& p, error_code& ec) _NOEXCEPT; + uintmax_t file_size(const path& p, error_code& ec) noexcept; uintmax_t hard_link_count(const path& p); - uintmax_t hard_link_count(const path& p, error_code& ec) _NOEXCEPT; + uintmax_t hard_link_count(const path& p, error_code& ec) noexcept; - bool is_block_file(file_status s) _NOEXCEPT; + bool is_block_file(file_status s) noexcept; bool is_block_file(const path& p); - bool is_block_file(const path& p, error_code& ec) _NOEXCEPT; + bool is_block_file(const path& p, error_code& ec) noexcept; - bool is_character_file(file_status s) _NOEXCEPT; + bool is_character_file(file_status s) noexcept; bool is_character_file(const path& p); - bool is_character_file(const path& p, error_code& ec) _NOEXCEPT; + bool is_character_file(const path& p, error_code& ec) noexcept; - bool is_directory(file_status s) _NOEXCEPT; + bool is_directory(file_status s) noexcept; bool is_directory(const path& p); - bool is_directory(const path& p, error_code& ec) _NOEXCEPT; + bool is_directory(const path& p, error_code& ec) noexcept; bool is_empty(const path& p); - bool is_empty(const path& p, error_code& ec) _NOEXCEPT; + bool is_empty(const path& p, error_code& ec) noexcept; - bool is_fifo(file_status s) _NOEXCEPT; + bool is_fifo(file_status s) noexcept; bool is_fifo(const path& p); - bool is_fifo(const path& p, error_code& ec) _NOEXCEPT; + bool is_fifo(const path& p, error_code& ec) noexcept; - bool is_other(file_status s) _NOEXCEPT; + bool is_other(file_status s) noexcept; bool is_other(const path& p); - bool is_other(const path& p, error_code& ec) _NOEXCEPT; + bool is_other(const path& p, error_code& ec) noexcept; - bool is_regular_file(file_status s) _NOEXCEPT; + bool is_regular_file(file_status s) noexcept; bool is_regular_file(const path& p); - bool is_regular_file(const path& p, error_code& ec) _NOEXCEPT; + bool is_regular_file(const path& p, error_code& ec) noexcept; - bool is_socket(file_status s) _NOEXCEPT; + bool is_socket(file_status s) noexcept; bool is_socket(const path& p); - bool is_socket(const path& p, error_code& ec) _NOEXCEPT; + bool is_socket(const path& p, error_code& ec) noexcept; - bool is_symlink(file_status s) _NOEXCEPT; + bool is_symlink(file_status s) noexcept; bool is_symlink(const path& p); - bool is_symlink(const path& p, error_code& ec) _NOEXCEPT; + bool is_symlink(const path& p, error_code& ec) noexcept; file_time_type last_write_time(const path& p); - file_time_type last_write_time(const path& p, error_code& ec) _NOEXCEPT; + file_time_type last_write_time(const path& p, error_code& ec) noexcept; void last_write_time(const path& p, file_time_type new_time); void last_write_time(const path& p, file_time_type new_time, - error_code& ec) _NOEXCEPT; + 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; + bool remove(const path& p, error_code& ec) noexcept; uintmax_t remove_all(const path& p); - uintmax_t remove_all(const path& p, error_code& ec) _NOEXCEPT; + uintmax_t remove_all(const path& p, error_code& ec); void rename(const path& from, const path& to); - void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT; + void rename(const path& from, const path& to, error_code& ec) noexcept; void resize_file(const path& p, uintmax_t size); - void resize_file(const path& p, uintmax_t size, error_code& ec) _NOEXCEPT; + void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept; space_info space(const path& p); - space_info space(const path& p, error_code& ec) _NOEXCEPT; + space_info space(const path& p, error_code& ec) noexcept; file_status status(const path& p); - file_status status(const path& p, error_code& ec) _NOEXCEPT; + file_status status(const path& p, error_code& ec) noexcept; - bool status_known(file_status s) _NOEXCEPT; + bool status_known(file_status s) noexcept; 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); + file_status symlink_status(const path& p, error_code& ec) noexcept; 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 */ #include <experimental/__config> -#include <cstddef> -#include <chrono> -#include <iterator> -#include <iosfwd> -#include <locale> -#include <memory> -#include <stack> -#include <string> -#include <system_error> -#include <utility> -#include <iomanip> // for quoted -#include <string_view> - -#include <__debug> +#include <filesystem> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#ifndef _LIBCPP_CXX03_LANG + #define __cpp_lib_experimental_filesystem 201406 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM -typedef chrono::time_point<std::chrono::system_clock> file_time_type; - -struct _LIBCPP_TYPE_VIS space_info -{ - uintmax_t capacity; - uintmax_t free; - uintmax_t available; -}; - -enum class _LIBCPP_ENUM_VIS file_type : signed char -{ - none = 0, - not_found = -1, - regular = 1, - directory = 2, - symlink = 3, - block = 4, - character = 5, - fifo = 6, - socket = 7, - unknown = 8 -}; - -enum class _LIBCPP_ENUM_VIS perms : unsigned -{ - none = 0, - - owner_read = 0400, - owner_write = 0200, - owner_exec = 0100, - owner_all = 0700, - - group_read = 040, - group_write = 020, - group_exec = 010, - group_all = 070, - - others_read = 04, - others_write = 02, - others_exec = 01, - others_all = 07, - - all = 0777, - - set_uid = 04000, - set_gid = 02000, - sticky_bit = 01000, - mask = 07777, - unknown = 0xFFFF, - - add_perms = 0x10000, - remove_perms = 0x20000, - symlink_nofollow = 0x40000 -}; - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS) -{ return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS) -{ return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS) -{ return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS) -{ return static_cast<perms>(~static_cast<unsigned>(_LHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline perms& operator&=(perms& _LHS, perms _RHS) -{ return _LHS = _LHS & _RHS; } - -_LIBCPP_INLINE_VISIBILITY -inline perms& operator|=(perms& _LHS, perms _RHS) -{ return _LHS = _LHS | _RHS; } - -_LIBCPP_INLINE_VISIBILITY -inline perms& operator^=(perms& _LHS, perms _RHS) -{ return _LHS = _LHS ^ _RHS; } - -enum class _LIBCPP_ENUM_VIS copy_options : unsigned short -{ - none = 0, - skip_existing = 1, - overwrite_existing = 2, - update_existing = 4, - recursive = 8, - copy_symlinks = 16, - skip_symlinks = 32, - directories_only = 64, - create_symlinks = 128, - create_hard_links = 256, - __in_recursive_copy = 512, -}; - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS) -{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS) -{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS) -{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS) -{ return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) -{ return _LHS = _LHS & _RHS; } - -_LIBCPP_INLINE_VISIBILITY -inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) -{ return _LHS = _LHS | _RHS; } - -_LIBCPP_INLINE_VISIBILITY -inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) -{ return _LHS = _LHS ^ _RHS; } - - -enum class _LIBCPP_ENUM_VIS directory_options : unsigned char -{ - none = 0, - follow_directory_symlink = 1, - skip_permission_denied = 2 -}; - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS) -{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS) -{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS) -{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS) -{ return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); } - -_LIBCPP_INLINE_VISIBILITY -inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS) -{ return _LHS = _LHS & _RHS; } - -_LIBCPP_INLINE_VISIBILITY -inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS) -{ return _LHS = _LHS | _RHS; } - -_LIBCPP_INLINE_VISIBILITY -inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS) -{ return _LHS = _LHS ^ _RHS; } - - -class _LIBCPP_TYPE_VIS file_status -{ -public: - // constructors - _LIBCPP_INLINE_VISIBILITY - file_status() _NOEXCEPT : file_status(file_type::none) {} - _LIBCPP_INLINE_VISIBILITY - explicit file_status(file_type __ft, - perms __prms = perms::unknown) _NOEXCEPT - : __ft_(__ft), __prms_(__prms) - {} - - file_status(const file_status&) _NOEXCEPT = default; - file_status(file_status&&) _NOEXCEPT = default; - - _LIBCPP_INLINE_VISIBILITY - ~file_status() {} - - file_status& operator=(const file_status&) _NOEXCEPT = default; - file_status& operator=(file_status&&) _NOEXCEPT = default; - - // observers - _LIBCPP_ALWAYS_INLINE - file_type type() const _NOEXCEPT { - return __ft_; - } - - _LIBCPP_ALWAYS_INLINE - perms permissions() const _NOEXCEPT { - return __prms_; - } - - // modifiers - _LIBCPP_ALWAYS_INLINE - void type(file_type __ft) _NOEXCEPT { - __ft_ = __ft; - } - - _LIBCPP_ALWAYS_INLINE - void permissions(perms __p) _NOEXCEPT { - __prms_ = __p; - } -private: - file_type __ft_; - perms __prms_; -}; - -class _LIBCPP_TYPE_VIS directory_entry; - -template <class _Tp> struct __can_convert_char { - static const bool value = false; -}; -template <class _Tp> struct __can_convert_char<const _Tp> - : public __can_convert_char<_Tp> { -}; -template <> struct __can_convert_char<char> { - static const bool value = true; - using __char_type = char; -}; -template <> struct __can_convert_char<wchar_t> { - static const bool value = true; - using __char_type = wchar_t; -}; -template <> struct __can_convert_char<char16_t> { - static const bool value = true; - using __char_type = char16_t; -}; -template <> struct __can_convert_char<char32_t> { - static const bool value = true; - using __char_type = char32_t; -}; - -template <class _ECharT> -typename enable_if<__can_convert_char<_ECharT>::value, bool>::type -__is_separator(_ECharT __e) { - return __e == _ECharT('/'); -}; - -struct _NullSentinal {}; - -template <class _Tp> -using _Void = void; - -template <class _Tp, class = void> -struct __is_pathable_string : public false_type {}; - -template <class _ECharT, class _Traits, class _Alloc> -struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>, - _Void<typename __can_convert_char<_ECharT>::__char_type>> -: public __can_convert_char<_ECharT> -{ - using _Str = basic_string<_ECharT, _Traits, _Alloc>; - using _Base = __can_convert_char<_ECharT>; - static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } - static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } - static _ECharT __first_or_null(_Str const& __s) { - return __s.empty() ? _ECharT{} : __s[0]; - } -}; - - -template <class _ECharT, class _Traits> -struct __is_pathable_string<basic_string_view<_ECharT, _Traits>, - _Void<typename __can_convert_char<_ECharT>::__char_type>> -: public __can_convert_char<_ECharT> -{ - using _Str = basic_string_view<_ECharT, _Traits>; - using _Base = __can_convert_char<_ECharT>; - static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } - static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } - static _ECharT __first_or_null(_Str const& __s) { - return __s.empty() ? _ECharT{} : __s[0]; - } -}; - -template <class _Source, - class _DS = typename decay<_Source>::type, - class _UnqualPtrType = typename remove_const< - typename remove_pointer<_DS>::type>::type, - bool _IsCharPtr = is_pointer<_DS>::value && - __can_convert_char<_UnqualPtrType>::value - > -struct __is_pathable_char_array : false_type {}; - -template <class _Source, class _ECharT, class _UPtr> -struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> - : __can_convert_char<typename remove_const<_ECharT>::type> -{ - using _Base = __can_convert_char<typename remove_const<_ECharT>::type>; - - static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } - static _ECharT const* __range_end(const _ECharT* __b) - { - using _Iter = const _ECharT*; - const _ECharT __sentinal = _ECharT{}; - _Iter __e = __b; - for (; *__e != __sentinal; ++__e) - ; - return __e; - } - - static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } -}; - -template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void> -struct __is_pathable_iter : false_type {}; - -template <class _Iter> -struct __is_pathable_iter<_Iter, true, - _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>> - : __can_convert_char<typename iterator_traits<_Iter>::value_type> -{ - using _ECharT = typename iterator_traits<_Iter>::value_type; - using _Base = __can_convert_char<_ECharT>; - - static _Iter __range_begin(_Iter __b) { return __b; } - static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; } - - static _ECharT __first_or_null(_Iter __b) { return *__b; } -}; - -template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value, - bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, - bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value - > -struct __is_pathable : false_type { - static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); -}; - -template <class _Tp> -struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; - - -template <class _Tp> -struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {}; - - -template <class _Tp> -struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; - - -template <class _ECharT> -struct _PathCVT { - static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible"); - - typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower; - - static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e) { - _Narrower()(back_inserter(__dest), __b, __e); - } - - template <class _Iter> - static void __append_range(string& __dest, _Iter __b, _Iter __e) { - static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); - if (__b == __e) return; - basic_string<_ECharT> __tmp(__b, __e); - _Narrower()(back_inserter(__dest), __tmp.data(), - __tmp.data() + __tmp.length()); - } - - template <class _Iter> - static void __append_range(string& __dest, _Iter __b, _NullSentinal) { - static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); - const _ECharT __sentinal = _ECharT{}; - if (*__b == __sentinal) return; - basic_string<_ECharT> __tmp; - for (; *__b != __sentinal; ++__b) - __tmp.push_back(*__b); - _Narrower()(back_inserter(__dest), __tmp.data(), - __tmp.data() + __tmp.length()); - } - - template <class _Source> - static void __append_source(string& __dest, _Source const& __s) - { - using _Traits = __is_pathable<_Source>; - __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); - } -}; - -template <> -struct _PathCVT<char> { - - template <class _Iter> - static typename enable_if< - __is_exactly_input_iterator<_Iter>::value - >::type __append_range(string& __dest, _Iter __b, _Iter __e) { - for (; __b != __e; ++__b) - __dest.push_back(*__b); - } - - template <class _Iter> - static typename enable_if< - __is_forward_iterator<_Iter>::value - >::type __append_range(string& __dest, _Iter __b, _Iter __e) { - __dest.__append_forward_unsafe(__b, __e); - } - - template <class _Iter> - static void __append_range(string& __dest, _Iter __b, _NullSentinal) { - const char __sentinal = char{}; - for (; *__b != __sentinal; ++__b) - __dest.push_back(*__b); - } - - template <class _Source> - static void __append_source(string& __dest, _Source const& __s) - { - using _Traits = __is_pathable<_Source>; - __append_range(__dest, _Traits::__range_begin(__s), - _Traits::__range_end(__s)); - } -}; - - -class _LIBCPP_TYPE_VIS path -{ - template <class _SourceOrIter, class _Tp = path&> - using _EnableIfPathable = typename - enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; - - template <class _Tp> - using _SourceChar = typename __is_pathable<_Tp>::__char_type; - - template <class _Tp> - using _SourceCVT = _PathCVT<_SourceChar<_Tp>>; - -public: - typedef char value_type; - typedef basic_string<value_type> string_type; - typedef _VSTD::string_view __string_view; - static _LIBCPP_CONSTEXPR value_type preferred_separator = '/'; - - // 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)) {} - - template < - class _Source, - class = _EnableIfPathable<_Source, void> - > - path(const _Source& __src) { - _SourceCVT<_Source>::__append_source(__pn_, __src); - } - - template <class _InputIt> - path(_InputIt __first, _InputIt __last) { - typedef typename iterator_traits<_InputIt>::value_type _ItVal; - _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); - } - - // TODO Implement locale conversions. - template <class _Source, - class = _EnableIfPathable<_Source, void> - > - path(const _Source& __src, const locale& __loc); - template <class _InputIt> - path(_InputIt __first, _InputIt _last, const locale& __loc); - - _LIBCPP_INLINE_VISIBILITY - ~path() = default; - - // assignments - _LIBCPP_INLINE_VISIBILITY - path& operator=(const path& __p) { - __pn_ = __p.__pn_; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - path& operator=(path&& __p) _NOEXCEPT { - __pn_ = _VSTD::move(__p.__pn_); - return *this; - } - - template <class = void> - _LIBCPP_INLINE_VISIBILITY - path& operator=(string_type&& __s) _NOEXCEPT { - __pn_ = _VSTD::move(__s); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - path& assign(string_type&& __s) _NOEXCEPT { - __pn_ = _VSTD::move(__s); - return *this; - } - - template <class _Source> - _LIBCPP_INLINE_VISIBILITY - _EnableIfPathable<_Source> - operator=(const _Source& __src) - { return this->assign(__src); } - - - template <class _Source> - _EnableIfPathable<_Source> - assign(const _Source& __src) { - __pn_.clear(); - _SourceCVT<_Source>::__append_source(__pn_, __src); - return *this; - } - - template <class _InputIt> - path& assign(_InputIt __first, _InputIt __last) { - typedef typename iterator_traits<_InputIt>::value_type _ItVal; - __pn_.clear(); - _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); - return *this; - } - -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; - } - -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]); - __pn_ += __p.native(); - return *this; - } - - template <class _Source> - _LIBCPP_INLINE_VISIBILITY - _EnableIfPathable<_Source> - operator/=(const _Source& __src) { - return this->append(__src); - } - - template <class _Source> - _EnableIfPathable<_Source> - append(const _Source& __src) { - using _Traits = __is_pathable<_Source>; - using _CVT = _PathCVT<_SourceChar<_Source>>; - __append_sep_if_needed(_Traits::__first_or_null(__src)); - _CVT::__append_source(__pn_, __src); - return *this; - } - - template <class _InputIt> - path& append(_InputIt __first, _InputIt __last) { - 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); - } - return *this; - } - - // concatenation - _LIBCPP_INLINE_VISIBILITY - path& operator+=(const path& __x) { - __pn_ += __x.__pn_; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - path& operator+=(const string_type& __x) { - __pn_ += __x; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - path& operator+=(__string_view __x) { - __pn_ += __x; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - path& operator+=(const value_type* __x) { - __pn_ += __x; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - path& operator+=(value_type __x) { - __pn_ += __x; - return *this; - } - - template <class _ECharT> - typename enable_if<__can_convert_char<_ECharT>::value, path&>::type - operator+=(_ECharT __x) - { - basic_string<_ECharT> __tmp; - __tmp += __x; - _PathCVT<_ECharT>::__append_source(__pn_, __tmp); - return *this; - } - - template <class _Source> - _EnableIfPathable<_Source> - operator+=(const _Source& __x) { - return this->concat(__x); - } - - template <class _Source> - _EnableIfPathable<_Source> - concat(const _Source& __x) { - _SourceCVT<_Source>::__append_source(__pn_, __x); - return *this; - } - - template <class _InputIt> - path& concat(_InputIt __first, _InputIt __last) { - typedef typename iterator_traits<_InputIt>::value_type _ItVal; - _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); - return *this; - } - - // modifiers - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT { - __pn_.clear(); - } - - path& make_preferred() { return *this; } - - _LIBCPP_INLINE_VISIBILITY - path& remove_filename() { - if (__pn_.size() == __root_path_raw().size()) - clear(); - else - __pn_ = __parent_path(); - return *this; - } - - path& replace_filename(const path& __replacement) { - remove_filename(); - return (*this /= __replacement); - } - - path& replace_extension(const path& __replacement = path()); - - _LIBCPP_INLINE_VISIBILITY - void swap(path& __rhs) _NOEXCEPT { - __pn_.swap(__rhs.__pn_); - } - - // native format observers - _LIBCPP_INLINE_VISIBILITY - const string_type& native() const _NOEXCEPT { - return __pn_; - } - - _LIBCPP_INLINE_VISIBILITY - const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); } - - _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; } - - template <class _ECharT, class _Traits = char_traits<_ECharT>, - class _Allocator = allocator<_ECharT> > - basic_string<_ECharT, _Traits, _Allocator> - string(const _Allocator& __a = _Allocator()) const { - using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>; - using _Str = basic_string<_ECharT, _Traits, _Allocator>; - _Str __s(__a); - __s.reserve(__pn_.size()); - _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); - return __s; - } - - _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; } - _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { return string<wchar_t>(); } - _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; } - _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); } - _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); } - - // generic format observers - template <class _ECharT, class _Traits = char_traits<_ECharT>, - class _Allocator = allocator<_ECharT> - > - basic_string<_ECharT, _Traits, _Allocator> - generic_string(const _Allocator& __a = _Allocator()) const { - return string<_ECharT, _Traits, _Allocator>(__a); - } - - std::string generic_string() const { return __pn_; } - std::wstring generic_wstring() const { return string<wchar_t>(); } - std::string generic_u8string() const { return __pn_; } - std::u16string generic_u16string() const { return string<char16_t>(); } - std::u32string generic_u32string() const { return string<char32_t>(); } - -private: - int __compare(__string_view) const; - __string_view __root_name() const; - __string_view __root_directory() const; - __string_view __root_path_raw() const; - __string_view __relative_path() const; - __string_view __parent_path() const; - __string_view __filename() const; - __string_view __stem() const; - __string_view __extension() const; - -public: - // compare - _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.__pn_);} - _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s); } - _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { return __compare(__s); } - _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); } - - // decomposition - _LIBCPP_INLINE_VISIBILITY path root_name() const { return string_type(__root_name()); } - _LIBCPP_INLINE_VISIBILITY path root_directory() const { return string_type(__root_directory()); } - _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(string_type(__root_directory())); } - _LIBCPP_INLINE_VISIBILITY path relative_path() const { return string_type(__relative_path()); } - _LIBCPP_INLINE_VISIBILITY path parent_path() const { return string_type(__parent_path()); } - _LIBCPP_INLINE_VISIBILITY path filename() const { return string_type(__filename()); } - _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem());} - _LIBCPP_INLINE_VISIBILITY path extension() const { return string_type(__extension()); } - - // query - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT { return __pn_.empty(); } - - _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { return !__root_name().empty(); } - _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); } - _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !__root_path_raw().empty(); } - _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { return !__relative_path().empty(); } - _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { return !__parent_path().empty(); } - _LIBCPP_INLINE_VISIBILITY bool has_filename() const { return !__filename().empty(); } - _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); } - _LIBCPP_INLINE_VISIBILITY bool has_extension() const { return !__extension().empty(); } - - _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); } - _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); } - - // iterators - class _LIBCPP_TYPE_VIS iterator; - typedef iterator const_iterator; - - iterator begin() const; - iterator end() const; - -private: - inline _LIBCPP_INLINE_VISIBILITY - path& __assign_view(__string_view const& __s) noexcept { __pn_ = string_type(__s); return *this; } - string_type __pn_; -}; - -inline _LIBCPP_ALWAYS_INLINE -void swap(path& __lhs, path& __rhs) _NOEXCEPT { - __lhs.swap(__rhs); -} - -_LIBCPP_FUNC_VIS -size_t hash_value(const path& __p) _NOEXCEPT; - -inline _LIBCPP_INLINE_VISIBILITY -bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT -{ return __lhs.compare(__rhs) == 0; } - -inline _LIBCPP_INLINE_VISIBILITY -bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT -{ return __lhs.compare(__rhs) != 0; } - -inline _LIBCPP_INLINE_VISIBILITY -bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT -{ return __lhs.compare(__rhs) < 0; } - -inline _LIBCPP_INLINE_VISIBILITY -bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT -{ return __lhs.compare(__rhs) <= 0; } - -inline _LIBCPP_INLINE_VISIBILITY -bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT -{ return __lhs.compare(__rhs) > 0; } - -inline _LIBCPP_INLINE_VISIBILITY -bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT -{ return __lhs.compare(__rhs) >= 0; } - -inline _LIBCPP_INLINE_VISIBILITY -path operator/(const path& __lhs, const path& __rhs) { - return path(__lhs) /= __rhs; -} - -template <class _CharT, class _Traits> -_LIBCPP_INLINE_VISIBILITY -typename enable_if<is_same<_CharT, char>::value && - is_same<_Traits, char_traits<char>>::value, - basic_ostream<_CharT, _Traits>& ->::type -operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { - __os << std::__quoted(__p.native()); - return __os; -} - -template <class _CharT, class _Traits> -_LIBCPP_INLINE_VISIBILITY -typename enable_if<!is_same<_CharT, char>::value || - !is_same<_Traits, char_traits<char>>::value, - basic_ostream<_CharT, _Traits>& ->::type -operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { - __os << std::__quoted(__p.string<_CharT, _Traits>()); - return __os; -} - -template <class _CharT, class _Traits> -_LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) -{ - basic_string<_CharT, _Traits> __tmp; - __is >> __quoted(__tmp); - __p = __tmp; - return __is; -} - -template <class _Source> -_LIBCPP_INLINE_VISIBILITY -typename enable_if<__is_pathable<_Source>::value, path>::type -u8path(const _Source& __s){ - static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value, - "u8path(Source const&) requires Source have a character type of type 'char'"); - return path(__s); -} - -template <class _InputIt> -_LIBCPP_INLINE_VISIBILITY -typename enable_if<__is_pathable<_InputIt>::value, path>::type -u8path(_InputIt __f, _InputIt __l) { - static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, - "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"); - return path(__f, __l); -} - -class _LIBCPP_TYPE_VIS path::iterator -{ -public: - typedef bidirectional_iterator_tag iterator_category; - - typedef path value_type; - typedef std::ptrdiff_t difference_type; - typedef const path* pointer; - typedef const path& reference; - - typedef void __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator -public: - _LIBCPP_INLINE_VISIBILITY - iterator() : __stashed_elem_(), __path_ptr_(nullptr), - __entry_(), __state_(__singular) {} - - iterator(const iterator&) = default; - ~iterator() = default; - - iterator& operator=(const iterator&) = default; - - _LIBCPP_INLINE_VISIBILITY - reference operator*() const { - return __stashed_elem_; - } - - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const { - return &__stashed_elem_; - } - - _LIBCPP_INLINE_VISIBILITY - iterator& operator++() { - _LIBCPP_ASSERT(__state_ != __singular, - "attempting to increment a singular iterator"); - _LIBCPP_ASSERT(__state_ != __at_end, - "attempting to increment the end iterator"); - return __increment(); - } - - _LIBCPP_INLINE_VISIBILITY - iterator operator++(int) { - iterator __it(*this); - this->operator++(); - return __it; - } - - _LIBCPP_INLINE_VISIBILITY - iterator& operator--() { - _LIBCPP_ASSERT(__state_ != __singular, - "attempting to decrement a singular iterator"); - _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), - "attempting to decrement the begin iterator"); - return __decrement(); - } - - _LIBCPP_INLINE_VISIBILITY - iterator operator--(int) { - iterator __it(*this); - this->operator--(); - return __it; - } - -private: - friend class path; - - static constexpr unsigned char __singular = 0; - static constexpr unsigned char __at_end = 6; - - inline _LIBCPP_INLINE_VISIBILITY - friend bool operator==(const iterator&, const iterator&); - - iterator& __increment(); - iterator& __decrement(); - - path __stashed_elem_; - const path* __path_ptr_; - path::__string_view __entry_; - unsigned char __state_; -}; - -inline _LIBCPP_INLINE_VISIBILITY -bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) { - return __lhs.__path_ptr_ == __rhs.__path_ptr_ && - __lhs.__entry_.data() == __rhs.__entry_.data(); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) { - return !(__lhs == __rhs); -} - -class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error -{ -public: - _LIBCPP_INLINE_VISIBILITY - filesystem_error(const string& __what, error_code __ec) - : system_error(__ec, __what), - __paths_(make_shared<_Storage>(path(), path())) - {} - - _LIBCPP_INLINE_VISIBILITY - filesystem_error(const string& __what, const path& __p1, error_code __ec) - : system_error(__ec, __what), - __paths_(make_shared<_Storage>(__p1, path())) - {} - - _LIBCPP_INLINE_VISIBILITY - filesystem_error(const string& __what, const path& __p1, const path& __p2, - error_code __ec) - : system_error(__ec, __what), - __paths_(make_shared<_Storage>(__p1, __p2)) - {} - - _LIBCPP_INLINE_VISIBILITY - const path& path1() const _NOEXCEPT { - return __paths_->first; - } - - _LIBCPP_INLINE_VISIBILITY - const path& path2() const _NOEXCEPT { - return __paths_->second; - } - - ~filesystem_error() override; // key function - - // TODO(ericwf): Create a custom error message. - //const char* what() const _NOEXCEPT; - -private: - typedef pair<path, path> _Storage; - shared_ptr<_Storage> __paths_; -}; - -template <class... _Args> -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE -#ifndef _LIBCPP_NO_EXCEPTIONS -void __throw_filesystem_error(_Args && ...__args) -{ - throw filesystem_error(std::forward<_Args>(__args)...); -} -#else -void __throw_filesystem_error(_Args&&...) -{ - _VSTD::abort(); -} -#endif +using namespace _VSTD_FS; +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM -// operational functions - -_LIBCPP_FUNC_VIS -path __canonical(const path&, const path&, error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -void __copy(const path& __from, const path& __to, copy_options __opt, - error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -bool __copy_file(const path& __from, const path& __to, copy_options __opt, - error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, - error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -bool __create_directories(const path& p, error_code *ec=nullptr); -_LIBCPP_FUNC_VIS -bool __create_directory(const path& p, error_code *ec=nullptr); -_LIBCPP_FUNC_VIS -bool __create_directory(const path& p, const path & attributes, - error_code *ec=nullptr); -_LIBCPP_FUNC_VIS -void __create_directory_symlink(const path& __to, const path& __new_symlink, - error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -void __create_hard_link(const path& __to, const path& __new_hard_link, - error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -void __create_symlink(const path& __to, const path& __new_symlink, - error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -path __current_path(error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -void __current_path(const path&, error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -bool __equivalent(const path&, const path&, error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -uintmax_t __file_size(const path&, error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -bool __fs_is_empty(const path& p, error_code *ec=nullptr); -_LIBCPP_FUNC_VIS -file_time_type __last_write_time(const path& p, error_code *ec=nullptr); -_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); -_LIBCPP_FUNC_VIS -path __read_symlink(const path& p, error_code *ec=nullptr); -_LIBCPP_FUNC_VIS -bool __remove(const path& p, error_code *ec=nullptr); -_LIBCPP_FUNC_VIS -uintmax_t __remove_all(const path& p, error_code *ec=nullptr); -_LIBCPP_FUNC_VIS -void __rename(const path& from, const path& to, error_code *ec=nullptr); -_LIBCPP_FUNC_VIS -void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr); -_LIBCPP_FUNC_VIS -space_info __space(const path&, error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -file_status __status(const path&, error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -file_status __symlink_status(const path&, error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -path __system_complete(const path&, error_code *__ec=nullptr); -_LIBCPP_FUNC_VIS -path __temp_directory_path(error_code *__ec=nullptr); - -inline _LIBCPP_INLINE_VISIBILITY -path current_path() { - return __current_path(); -} - -inline _LIBCPP_INLINE_VISIBILITY -path current_path(error_code& __ec) { - return __current_path(&__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void current_path(const path& __p) { - __current_path(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -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 canonical(const path& __p, const path& __base = current_path()) { - return __canonical(__p, __base); -} - -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); -} - -inline _LIBCPP_INLINE_VISIBILITY -void copy(const path& __from, const path& __to) { - __copy(__from, __to, copy_options::none); -} - -inline _LIBCPP_INLINE_VISIBILITY -void copy(const path& __from, const path& __to, error_code& __ec) { - __copy(__from, __to, copy_options::none, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void copy(const path& __from, const path& __to, copy_options __opt) { - __copy(__from, __to, __opt); -} - -inline _LIBCPP_INLINE_VISIBILITY -void copy(const path& __from, const path& __to, - copy_options __opt, error_code& __ec) { - __copy(__from, __to, __opt, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool copy_file(const path& __from, const path& __to) { - return __copy_file(__from, __to, copy_options::none); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool copy_file(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { - return __copy_file(__from, __to, copy_options::none, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool copy_file(const path& __from, const path& __to, copy_options __opt) { - return __copy_file(__from, __to, __opt); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool copy_file(const path& __from, const path& __to, - copy_options __opt, error_code& __ec) _NOEXCEPT { - return __copy_file(__from, __to, __opt, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void copy_symlink(const path& __existing, const path& __new) { - __copy_symlink(__existing, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY -void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT { - __copy_symlink(__ext, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool create_directories(const path& __p) { - return __create_directories(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool create_directories(const path& __p, error_code& __ec) _NOEXCEPT { - return __create_directories(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool create_directory(const path& __p) { - return __create_directory(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT { - return __create_directory(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool create_directory(const path& __p, const path& __attrs) { - return __create_directory(__p, __attrs); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT { - return __create_directory(__p, __attrs, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void create_directory_symlink(const path& __to, const path& __new) { - __create_directory_symlink(__to, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY -void create_directory_symlink(const path& __to, const path& __new, - error_code& __ec) _NOEXCEPT { - __create_directory_symlink(__to, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void create_hard_link(const path& __to, const path& __new) { - __create_hard_link(__to, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY -void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT { - __create_hard_link(__to, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void create_symlink(const path& __to, const path& __new) { - __create_symlink(__to, __new); -} - -inline _LIBCPP_INLINE_VISIBILITY -void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT { - return __create_symlink(__to, __new, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool status_known(file_status __s) _NOEXCEPT { - return __s.type() != file_type::none; -} - -inline _LIBCPP_INLINE_VISIBILITY -bool exists(file_status __s) _NOEXCEPT { - return status_known(__s) && __s.type() != file_type::not_found; -} - -inline _LIBCPP_INLINE_VISIBILITY -bool exists(const path& __p) { - return exists(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool exists(const path& __p, error_code& __ec) _NOEXCEPT { - auto __s = __status(__p, &__ec); - if (status_known(__s)) __ec.clear(); - return exists(__s); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool equivalent(const path& __p1, const path& __p2) { - return __equivalent(__p1, __p2); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT { - return __equivalent(__p1, __p2, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -uintmax_t file_size(const path& __p) { - return __file_size(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT { - return __file_size(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -uintmax_t hard_link_count(const path& __p) { - return __hard_link_count(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT { - return __hard_link_count(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_block_file(file_status __s) _NOEXCEPT { - return __s.type() == file_type::block; -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_block_file(const path& __p) { - return is_block_file(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT { - return is_block_file(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_character_file(file_status __s) _NOEXCEPT { - return __s.type() == file_type::character; -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_character_file(const path& __p) { - return is_character_file(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT { - return is_character_file(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_directory(file_status __s) _NOEXCEPT { - return __s.type() == file_type::directory; -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_directory(const path& __p) { - return is_directory(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT { - return is_directory(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_empty(const path& __p) { - return __fs_is_empty(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_empty(const path& __p, error_code& __ec) { - return __fs_is_empty(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_fifo(file_status __s) _NOEXCEPT { - return __s.type() == file_type::fifo; -} -inline _LIBCPP_INLINE_VISIBILITY -bool is_fifo(const path& __p) { - return is_fifo(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT { - return is_fifo(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_regular_file(file_status __s) _NOEXCEPT { - return __s.type() == file_type::regular; -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_regular_file(const path& __p) { - return is_regular_file(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT { - return is_regular_file(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_socket(file_status __s) _NOEXCEPT { - return __s.type() == file_type::socket; -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_socket(const path& __p) { - return is_socket(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT { - return is_socket(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_symlink(file_status __s) _NOEXCEPT { - return __s.type() == file_type::symlink; -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_symlink(const path& __p) { - return is_symlink(__symlink_status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT { - return is_symlink(__symlink_status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_other(file_status __s) _NOEXCEPT { - return exists(__s) - && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_other(const path& __p) { - return is_other(__status(__p)); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool is_other(const path& __p, error_code& __ec) _NOEXCEPT { - return is_other(__status(__p, &__ec)); -} - -inline _LIBCPP_INLINE_VISIBILITY -file_time_type last_write_time(const path& __p) { - return __last_write_time(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT { - return __last_write_time(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void last_write_time(const path& __p, file_time_type __t) { - __last_write_time(__p, __t); -} - -inline _LIBCPP_INLINE_VISIBILITY -void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT { - __last_write_time(__p, __t, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void permissions(const path& __p, perms __prms) { - __permissions(__p, __prms); -} - -inline _LIBCPP_INLINE_VISIBILITY -void permissions(const path& __p, perms __prms, error_code& __ec) { - __permissions(__p, __prms, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -path read_symlink(const path& __p) { - return __read_symlink(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -path read_symlink(const path& __p, error_code& __ec) { - return __read_symlink(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool remove(const path& __p) { - return __remove(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -bool remove(const path& __p, error_code& __ec) _NOEXCEPT { - return __remove(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -uintmax_t remove_all(const path& __p) { - return __remove_all(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -uintmax_t remove_all(const path& __p, error_code& __ec) _NOEXCEPT { - return __remove_all(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void rename(const path& __from, const path& __to) { - return __rename(__from, __to); -} - -inline _LIBCPP_INLINE_VISIBILITY -void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { - return __rename(__from, __to, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -void resize_file(const path& __p, uintmax_t __ns) { - return __resize_file(__p, __ns); -} - -inline _LIBCPP_INLINE_VISIBILITY -void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT { - return __resize_file(__p, __ns, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -space_info space(const path& __p) { - return __space(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -space_info space(const path& __p, error_code& __ec) _NOEXCEPT { - return __space(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -file_status status(const path& __p) { - return __status(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -file_status status(const path& __p, error_code& __ec) _NOEXCEPT { - return __status(__p, &__ec); -} - -inline _LIBCPP_INLINE_VISIBILITY -file_status symlink_status(const path& __p) { - return __symlink_status(__p); -} - -inline _LIBCPP_INLINE_VISIBILITY -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(); -} - -inline _LIBCPP_INLINE_VISIBILITY -path temp_directory_path(error_code& __ec) { - return __temp_directory_path(&__ec); -} - - -class directory_entry -{ - typedef _VSTD_FS::path _Path; - -public: - // constructors and destructors - directory_entry() _NOEXCEPT = default; - directory_entry(directory_entry const&) = default; - directory_entry(directory_entry&&) _NOEXCEPT = default; - - _LIBCPP_INLINE_VISIBILITY - explicit directory_entry(_Path const& __p) : __p_(__p) {} - - ~directory_entry() {} - - directory_entry& operator=(directory_entry const&) = default; - directory_entry& operator=(directory_entry&&) _NOEXCEPT = default; - - _LIBCPP_INLINE_VISIBILITY - void assign(_Path const& __p) { - __p_ = __p; - } - - _LIBCPP_INLINE_VISIBILITY - void replace_filename(_Path const& __p) { - __p_ = __p_.parent_path() / __p; - } - - _LIBCPP_INLINE_VISIBILITY - _Path const& path() const _NOEXCEPT { - return __p_; - } - - _LIBCPP_INLINE_VISIBILITY - operator const _Path&() const _NOEXCEPT { - return __p_; - } - - _LIBCPP_INLINE_VISIBILITY - file_status status() const { - return _VSTD_FS::status(__p_); - } - - _LIBCPP_INLINE_VISIBILITY - file_status status(error_code& __ec) const _NOEXCEPT { - return _VSTD_FS::status(__p_, __ec); - } - - _LIBCPP_INLINE_VISIBILITY - file_status symlink_status() const { - return _VSTD_FS::symlink_status(__p_); - } - - _LIBCPP_INLINE_VISIBILITY - file_status symlink_status(error_code& __ec) const _NOEXCEPT { - return _VSTD_FS::symlink_status(__p_, __ec); - } - - _LIBCPP_INLINE_VISIBILITY - bool operator< (directory_entry const& __rhs) const _NOEXCEPT { - return __p_ < __rhs.__p_; - } - - _LIBCPP_INLINE_VISIBILITY - bool operator==(directory_entry const& __rhs) const _NOEXCEPT { - return __p_ == __rhs.__p_; - } - - _LIBCPP_INLINE_VISIBILITY - bool operator!=(directory_entry const& __rhs) const _NOEXCEPT { - return __p_ != __rhs.__p_; - } - - _LIBCPP_INLINE_VISIBILITY - bool operator<=(directory_entry const& __rhs) const _NOEXCEPT { - return __p_ <= __rhs.__p_; - } - - _LIBCPP_INLINE_VISIBILITY - bool operator> (directory_entry const& __rhs) const _NOEXCEPT { - return __p_ > __rhs.__p_; - } - - _LIBCPP_INLINE_VISIBILITY - bool operator>=(directory_entry const& __rhs) const _NOEXCEPT { - return __p_ >= __rhs.__p_; - } -private: - _Path __p_; -}; - - -class directory_iterator; -class recursive_directory_iterator; -class __dir_stream; - -class __dir_element_proxy { -public: - - inline _LIBCPP_INLINE_VISIBILITY - directory_entry operator*() { return _VSTD::move(__elem_); } - -private: - friend class directory_iterator; - friend class recursive_directory_iterator; - explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} - __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {} - directory_entry __elem_; -}; - -class directory_iterator -{ -public: - typedef directory_entry value_type; - typedef ptrdiff_t difference_type; - typedef value_type const* pointer; - typedef value_type const& reference; - typedef input_iterator_tag iterator_category; - -public: - //ctor & dtor - directory_iterator() _NOEXCEPT - { } - - explicit directory_iterator(const path& __p) - : directory_iterator(__p, nullptr) - { } - - directory_iterator(const path& __p, directory_options __opts) - : directory_iterator(__p, nullptr, __opts) - { } - - directory_iterator(const path& __p, error_code& __ec) - : directory_iterator(__p, &__ec) - { } - - directory_iterator(const path& __p, directory_options __opts, - error_code& __ec) - : directory_iterator(__p, &__ec, __opts) - { } - - directory_iterator(const directory_iterator&) = default; - directory_iterator(directory_iterator&&) = default; - directory_iterator& operator=(const directory_iterator&) = default; - - directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT { - // non-default implementation provided to support self-move assign. - if (this != &__o) { - __imp_ = _VSTD::move(__o.__imp_); - } - return *this; - } - - ~directory_iterator() = default; - - const directory_entry& operator*() const { - _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); - return __dereference(); - } - - const directory_entry* operator->() const - { return &**this; } - - directory_iterator& operator++() - { return __increment(); } - - __dir_element_proxy operator++(int) { - __dir_element_proxy __p(**this); - __increment(); - return __p; - } - - directory_iterator& increment(error_code& __ec) - { return __increment(&__ec); } - -private: - inline _LIBCPP_INLINE_VISIBILITY - friend bool operator==(const directory_iterator& __lhs, - const directory_iterator& __rhs) _NOEXCEPT; - - // construct the dir_stream - _LIBCPP_FUNC_VIS - directory_iterator(const path&, error_code *, - directory_options = directory_options::none); - - _LIBCPP_FUNC_VIS - directory_iterator& __increment(error_code * __ec = nullptr); - - _LIBCPP_FUNC_VIS - const directory_entry& __dereference() const; - -private: - shared_ptr<__dir_stream> __imp_; -}; - - -inline _LIBCPP_INLINE_VISIBILITY -bool operator==(const directory_iterator& __lhs, - const directory_iterator& __rhs) _NOEXCEPT { - return __lhs.__imp_ == __rhs.__imp_; -} - -inline _LIBCPP_INLINE_VISIBILITY -bool operator!=(const directory_iterator& __lhs, - const directory_iterator& __rhs) _NOEXCEPT { - return !(__lhs == __rhs); -} - -// enable directory_iterator range-based for statements -inline _LIBCPP_INLINE_VISIBILITY -directory_iterator begin(directory_iterator __iter) _NOEXCEPT { - return __iter; -} - -inline _LIBCPP_INLINE_VISIBILITY -directory_iterator end(const directory_iterator&) _NOEXCEPT { - return directory_iterator(); -} - -class recursive_directory_iterator { -public: - using value_type = directory_entry; - using difference_type = std::ptrdiff_t; - using pointer = directory_entry const *; - using reference = directory_entry const &; - using iterator_category = std::input_iterator_tag; - -public: - // constructors and destructor - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator() _NOEXCEPT - : __rec_(false) - {} - - _LIBCPP_INLINE_VISIBILITY - explicit recursive_directory_iterator(const path& __p, - directory_options __xoptions = directory_options::none) - : recursive_directory_iterator(__p, __xoptions, nullptr) - { } - - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator(const path& __p, - directory_options __xoptions, error_code& __ec) - : recursive_directory_iterator(__p, __xoptions, &__ec) - { } - - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator(const path& __p, error_code& __ec) - : recursive_directory_iterator(__p, directory_options::none, &__ec) - { } - - recursive_directory_iterator(const recursive_directory_iterator&) = default; - recursive_directory_iterator(recursive_directory_iterator&&) = default; - - recursive_directory_iterator & - operator=(const recursive_directory_iterator&) = default; - - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator & - operator=(recursive_directory_iterator&& __o) noexcept { - // non-default implementation provided to support self-move assign. - if (this != &__o) { - __imp_ = _VSTD::move(__o.__imp_); - __rec_ = __o.__rec_; - } - return *this; - } - - ~recursive_directory_iterator() = default; - - _LIBCPP_INLINE_VISIBILITY - const directory_entry& operator*() const - { return __dereference(); } - - _LIBCPP_INLINE_VISIBILITY - const directory_entry* operator->() const - { return &__dereference(); } - - recursive_directory_iterator& operator++() - { return __increment(); } - - _LIBCPP_INLINE_VISIBILITY - __dir_element_proxy operator++(int) { - __dir_element_proxy __p(**this); - __increment(); - return __p; - } - - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator& increment(error_code& __ec) - { return __increment(&__ec); } - - _LIBCPP_FUNC_VIS directory_options options() const; - _LIBCPP_FUNC_VIS int depth() const; - - _LIBCPP_INLINE_VISIBILITY - void pop() { __pop(); } - - _LIBCPP_INLINE_VISIBILITY - void pop(error_code& __ec) - { __pop(&__ec); } - - _LIBCPP_INLINE_VISIBILITY - bool recursion_pending() const - { return __rec_; } - - _LIBCPP_INLINE_VISIBILITY - void disable_recursion_pending() - { __rec_ = false; } - -private: - recursive_directory_iterator(const path& __p, directory_options __opt, - error_code *__ec); - - _LIBCPP_FUNC_VIS - const directory_entry& __dereference() const; - - _LIBCPP_FUNC_VIS - bool __try_recursion(error_code* __ec); - - _LIBCPP_FUNC_VIS - void __advance(error_code* __ec=nullptr); - - _LIBCPP_FUNC_VIS - recursive_directory_iterator& __increment(error_code *__ec=nullptr); - - _LIBCPP_FUNC_VIS - void __pop(error_code* __ec=nullptr); - - inline _LIBCPP_INLINE_VISIBILITY - friend bool operator==(const recursive_directory_iterator&, - const recursive_directory_iterator&) _NOEXCEPT; - - struct __shared_imp; - shared_ptr<__shared_imp> __imp_; - bool __rec_; -}; // class recursive_directory_iterator - - -inline _LIBCPP_INLINE_VISIBILITY -bool operator==(const recursive_directory_iterator& __lhs, - const recursive_directory_iterator& __rhs) _NOEXCEPT -{ - return __lhs.__imp_ == __rhs.__imp_; -} - -_LIBCPP_INLINE_VISIBILITY -inline bool operator!=(const recursive_directory_iterator& __lhs, - const recursive_directory_iterator& __rhs) _NOEXCEPT -{ - return !(__lhs == __rhs); -} -// enable recursive_directory_iterator range-based for statements -inline _LIBCPP_INLINE_VISIBILITY -recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT { - return __iter; -} - -inline _LIBCPP_INLINE_VISIBILITY -recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT { - return recursive_directory_iterator(); -} +#endif // !_LIBCPP_CXX03_LANG -_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM +_LIBCPP_POP_MACROS #endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM diff --git a/lib/libcxx/include/experimental/functional b/lib/libcxx/include/experimental/functional index a136cbb57c8..f63dfb07bb0 100644 --- a/lib/libcxx/include/experimental/functional +++ b/lib/libcxx/include/experimental/functional @@ -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" ); diff --git a/lib/libcxx/include/experimental/memory_resource b/lib/libcxx/include/experimental/memory_resource index d101f3e0811..221ce5b8eac 100644 --- a/lib/libcxx/include/experimental/memory_resource +++ b/lib/libcxx/include/experimental/memory_resource @@ -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 diff --git a/lib/libcxx/include/experimental/numeric b/lib/libcxx/include/experimental/numeric index d784c08f0fe..14a664011b5 100644 --- a/lib/libcxx/include/experimental/numeric +++ b/lib/libcxx/include/experimental/numeric @@ -8,112 +8,4 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL_NUMERIC -#define _LIBCPP_EXPERIMENTAL_NUMERIC -/* - experimental/numeric synopsis - -// C++1z -namespace std { -namespace experimental { -inline namespace fundamentals_v2 { - - // 13.1.2, Greatest common divisor - template<class M, class N> - constexpr common_type_t<M,N> gcd(M m, N n); - - // 13.1.3, Least common multiple - template<class M, class N> - constexpr common_type_t<M,N> lcm(M m, N n); - -} // namespace fundamentals_v2 -} // namespace experimental -} // namespace std - - */ - -#include <experimental/__config> -#include <numeric> -#include <type_traits> // is_integral -#include <limits> // numeric_limits - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -#if _LIBCPP_STD_VER > 11 - -_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 - -template <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value> struct __abs; - -template <typename _Result, typename _Source> -struct __abs<_Result, _Source, true> { - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - _Result operator()(_Source __t) const noexcept - { - if (__t >= 0) return __t; - if (__t == numeric_limits<_Source>::min()) return -static_cast<_Result>(__t); - return -__t; - } -}; - -template <typename _Result, typename _Source> -struct __abs<_Result, _Source, false> { - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - _Result operator()(_Source __t) const noexcept { return __t; } -}; - - -template<class _Tp> -_LIBCPP_CONSTEXPR _LIBCPP_HIDDEN -inline _Tp __gcd(_Tp __m, _Tp __n) -{ - static_assert((!is_signed<_Tp>::value), "" ); - return __n == 0 ? __m : _VSTD_LFTS_V2::__gcd<_Tp>(__n, __m % __n); -} - - -template<class _Tp, class _Up> -_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY -common_type_t<_Tp,_Up> -gcd(_Tp __m, _Up __n) -{ - static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to gcd must be integer types"); - static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to gcd cannot be bool" ); - static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to gcd cannot be bool" ); - using _Rp = common_type_t<_Tp,_Up>; - using _Wp = make_unsigned_t<_Rp>; - return static_cast<_Rp>(_VSTD_LFTS_V2::__gcd( - static_cast<_Wp>(__abs<_Rp, _Tp>()(__m)), - static_cast<_Wp>(__abs<_Rp, _Up>()(__n)))); -} - -template<class _Tp, class _Up> -_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY -common_type_t<_Tp,_Up> -lcm(_Tp __m, _Up __n) -{ - static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to lcm must be integer types"); - static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to lcm cannot be bool" ); - static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to lcm cannot be bool" ); - if (__m == 0 || __n == 0) - return 0; - - using _Rp = common_type_t<_Tp,_Up>; - _Rp __val1 = __abs<_Rp, _Tp>()(__m) / _VSTD_LFTS_V2::gcd(__m, __n); - _Rp __val2 = __abs<_Rp, _Up>()(__n); - _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm"); - return __val1 * __val2; -} - -_LIBCPP_END_NAMESPACE_LFTS_V2 - -#endif /* _LIBCPP_STD_VER > 11 */ - -_LIBCPP_POP_MACROS - -#endif /* _LIBCPP_EXPERIMENTAL_NUMERIC */ +#error "<experimental/numeric> has been removed. Use <numeric> instead." diff --git a/lib/libcxx/include/experimental/optional b/lib/libcxx/include/experimental/optional index b251748fbf3..d68cefdf6c1 100644 --- a/lib/libcxx/include/experimental/optional +++ b/lib/libcxx/include/experimental/optional @@ -8,915 +8,4 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL_OPTIONAL -#define _LIBCPP_EXPERIMENTAL_OPTIONAL - -/* - optional synopsis - -// C++1y - -namespace std { namespace experimental { inline namespace fundamentals_v1 { - - // 5.3, optional for object types - template <class T> class optional; - - // 5.4, In-place construction - struct in_place_t{}; - constexpr in_place_t in_place{}; - - // 5.5, No-value state indicator - struct nullopt_t{see below}; - constexpr nullopt_t nullopt(unspecified); - - // 5.6, Class bad_optional_access - class bad_optional_access; - - // 5.7, Relational operators - template <class T> - constexpr bool operator==(const optional<T>&, const optional<T>&); - template <class T> - constexpr bool operator!=(const optional<T>&, const optional<T>&); - template <class T> - constexpr bool operator<(const optional<T>&, const optional<T>&); - template <class T> - constexpr bool operator>(const optional<T>&, const optional<T>&); - template <class T> - constexpr bool operator<=(const optional<T>&, const optional<T>&); - template <class T> - constexpr bool operator>=(const optional<T>&, const optional<T>&); - - // 5.8, Comparison with nullopt - template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; - template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; - template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; - template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; - template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; - template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; - template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; - template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; - template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; - template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; - template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; - template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; - - // 5.9, Comparison with T - template <class T> constexpr bool operator==(const optional<T>&, const T&); - template <class T> constexpr bool operator==(const T&, const optional<T>&); - template <class T> constexpr bool operator!=(const optional<T>&, const T&); - template <class T> constexpr bool operator!=(const T&, const optional<T>&); - template <class T> constexpr bool operator<(const optional<T>&, const T&); - template <class T> constexpr bool operator<(const T&, const optional<T>&); - template <class T> constexpr bool operator<=(const optional<T>&, const T&); - template <class T> constexpr bool operator<=(const T&, const optional<T>&); - template <class T> constexpr bool operator>(const optional<T>&, const T&); - template <class T> constexpr bool operator>(const T&, const optional<T>&); - template <class T> constexpr bool operator>=(const optional<T>&, const T&); - template <class T> constexpr bool operator>=(const T&, const optional<T>&); - - // 5.10, Specialized algorithms - template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below); - template <class T> constexpr optional<see below> make_optional(T&&); - - template <class T> - class optional - { - public: - typedef T value_type; - - // 5.3.1, Constructors - constexpr optional() noexcept; - constexpr optional(nullopt_t) noexcept; - optional(const optional&); - optional(optional&&) noexcept(see below); - constexpr optional(const T&); - constexpr optional(T&&); - template <class... Args> constexpr explicit optional(in_place_t, Args&&...); - template <class U, class... Args> - constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...); - - // 5.3.2, Destructor - ~optional(); - - // 5.3.3, Assignment - optional& operator=(nullopt_t) noexcept; - optional& operator=(const optional&); - optional& operator=(optional&&) noexcept(see below); - template <class U> optional& operator=(U&&); - template <class... Args> void emplace(Args&&...); - template <class U, class... Args> - void emplace(initializer_list<U>, Args&&...); - - // 5.3.4, Swap - void swap(optional&) noexcept(see below); - - // 5.3.5, Observers - constexpr T const* operator ->() const; - constexpr T* operator ->(); - constexpr T const& operator *() const &; - constexpr T& operator *() &; - constexpr T&& operator *() &&; - constexpr const T&& operator *() const &&; - constexpr explicit operator bool() const noexcept; - constexpr T const& value() const &; - constexpr T& value() &; - constexpr T&& value() &&; - constexpr const T&& value() const &&; - template <class U> constexpr T value_or(U&&) const &; - template <class U> constexpr T value_or(U&&) &&; - - private: - T* val; // exposition only - }; - - } // namespace fundamentals_v1 - } // namespace experimental - - // 5.11, Hash support - template <class T> struct hash; - template <class T> struct hash<experimental::optional<T>>; - -} // namespace std - -*/ - -#include <experimental/__config> -#include <functional> -#include <stdexcept> -#if _LIBCPP_STD_VER > 11 -#include <initializer_list> -#include <type_traits> -#include <new> -#include <__functional_base> -#include <__debug> -#endif - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - - -_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL -class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access - : public std::logic_error -{ -public: - bad_optional_access() : std::logic_error("Bad optional Access") {} - -// Get the key function ~bad_optional_access() into the dylib - virtual ~bad_optional_access() _NOEXCEPT; -}; - -_LIBCPP_END_NAMESPACE_EXPERIMENTAL - - -#if _LIBCPP_STD_VER > 11 - -_LIBCPP_BEGIN_NAMESPACE_LFTS - -struct in_place_t {}; -constexpr in_place_t in_place{}; - -struct nullopt_t -{ - explicit constexpr nullopt_t(int) noexcept {} -}; - -constexpr nullopt_t nullopt{0}; - -template <class _Tp, bool = is_trivially_destructible<_Tp>::value> -class __optional_storage -{ -protected: - typedef _Tp value_type; - union - { - char __null_state_; - value_type __val_; - }; - bool __engaged_ = false; - - _LIBCPP_INLINE_VISIBILITY - ~__optional_storage() - { - if (__engaged_) - __val_.~value_type(); - } - - _LIBCPP_INLINE_VISIBILITY - constexpr __optional_storage() noexcept - : __null_state_('\0') {} - - _LIBCPP_INLINE_VISIBILITY - __optional_storage(const __optional_storage& __x) - : __engaged_(__x.__engaged_) - { - if (__engaged_) - ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_); - } - - _LIBCPP_INLINE_VISIBILITY - __optional_storage(__optional_storage&& __x) - noexcept(is_nothrow_move_constructible<value_type>::value) - : __engaged_(__x.__engaged_) - { - if (__engaged_) - ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); - } - - _LIBCPP_INLINE_VISIBILITY - constexpr __optional_storage(const value_type& __v) - : __val_(__v), - __engaged_(true) {} - - _LIBCPP_INLINE_VISIBILITY - constexpr __optional_storage(value_type&& __v) - : __val_(_VSTD::move(__v)), - __engaged_(true) {} - - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - constexpr - explicit __optional_storage(in_place_t, _Args&&... __args) - : __val_(_VSTD::forward<_Args>(__args)...), - __engaged_(true) {} -}; - -template <class _Tp> -class __optional_storage<_Tp, true> -{ -protected: - typedef _Tp value_type; - union - { - char __null_state_; - value_type __val_; - }; - bool __engaged_ = false; - - _LIBCPP_INLINE_VISIBILITY - constexpr __optional_storage() noexcept - : __null_state_('\0') {} - - _LIBCPP_INLINE_VISIBILITY - __optional_storage(const __optional_storage& __x) - : __engaged_(__x.__engaged_) - { - if (__engaged_) - ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_); - } - - _LIBCPP_INLINE_VISIBILITY - __optional_storage(__optional_storage&& __x) - noexcept(is_nothrow_move_constructible<value_type>::value) - : __engaged_(__x.__engaged_) - { - if (__engaged_) - ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); - } - - _LIBCPP_INLINE_VISIBILITY - constexpr __optional_storage(const value_type& __v) - : __val_(__v), - __engaged_(true) {} - - _LIBCPP_INLINE_VISIBILITY - constexpr __optional_storage(value_type&& __v) - : __val_(_VSTD::move(__v)), - __engaged_(true) {} - - template <class... _Args> - _LIBCPP_INLINE_VISIBILITY - constexpr - explicit __optional_storage(in_place_t, _Args&&... __args) - : __val_(_VSTD::forward<_Args>(__args)...), - __engaged_(true) {} -}; - -template <class _Tp> -class optional - : private __optional_storage<_Tp> -{ - typedef __optional_storage<_Tp> __base; -public: - typedef _Tp value_type; - - static_assert(!is_reference<value_type>::value, - "Instantiation of optional with a reference type is ill-formed."); - static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value, - "Instantiation of optional with a in_place_t type is ill-formed."); - static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value, - "Instantiation of optional with a nullopt_t type is ill-formed."); - static_assert(is_object<value_type>::value, - "Instantiation of optional with a non-object type is undefined behavior."); - static_assert(is_nothrow_destructible<value_type>::value, - "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior."); - - _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} - _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default; - _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default; - _LIBCPP_INLINE_VISIBILITY ~optional() = default; - _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} - _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v) - : __base(__v) {} - _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v) - : __base(_VSTD::move(__v)) {} - - template <class... _Args, - class = typename enable_if - < - is_constructible<value_type, _Args...>::value - >::type - > - _LIBCPP_INLINE_VISIBILITY - constexpr - explicit optional(in_place_t, _Args&&... __args) - : __base(in_place, _VSTD::forward<_Args>(__args)...) {} - - template <class _Up, class... _Args, - class = typename enable_if - < - is_constructible<value_type, initializer_list<_Up>&, _Args...>::value - >::type - > - _LIBCPP_INLINE_VISIBILITY - constexpr - explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) - : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} - - _LIBCPP_INLINE_VISIBILITY - optional& operator=(nullopt_t) noexcept - { - if (this->__engaged_) - { - this->__val_.~value_type(); - this->__engaged_ = false; - } - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - optional& - operator=(const optional& __opt) - { - if (this->__engaged_ == __opt.__engaged_) - { - if (this->__engaged_) - this->__val_ = __opt.__val_; - } - else - { - if (this->__engaged_) - this->__val_.~value_type(); - else - ::new((void*)_VSTD::addressof(this->__val_)) value_type(__opt.__val_); - this->__engaged_ = __opt.__engaged_; - } - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - optional& - operator=(optional&& __opt) - noexcept(is_nothrow_move_assignable<value_type>::value && - is_nothrow_move_constructible<value_type>::value) - { - if (this->__engaged_ == __opt.__engaged_) - { - if (this->__engaged_) - this->__val_ = _VSTD::move(__opt.__val_); - } - else - { - if (this->__engaged_) - this->__val_.~value_type(); - else - ::new((void*)_VSTD::addressof(this->__val_)) - value_type(_VSTD::move(__opt.__val_)); - this->__engaged_ = __opt.__engaged_; - } - return *this; - } - - template <class _Up, - class = typename enable_if - < - is_same<typename remove_reference<_Up>::type, value_type>::value && - is_constructible<value_type, _Up>::value && - is_assignable<value_type&, _Up>::value - >::type - > - _LIBCPP_INLINE_VISIBILITY - optional& - operator=(_Up&& __v) - { - if (this->__engaged_) - this->__val_ = _VSTD::forward<_Up>(__v); - else - { - ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v)); - this->__engaged_ = true; - } - return *this; - } - - template <class... _Args, - class = typename enable_if - < - is_constructible<value_type, _Args...>::value - >::type - > - _LIBCPP_INLINE_VISIBILITY - void - emplace(_Args&&... __args) - { - *this = nullopt; - ::new((void*)_VSTD::addressof(this->__val_)) - value_type(_VSTD::forward<_Args>(__args)...); - this->__engaged_ = true; - } - - template <class _Up, class... _Args, - class = typename enable_if - < - is_constructible<value_type, initializer_list<_Up>&, _Args...>::value - >::type - > - _LIBCPP_INLINE_VISIBILITY - void - emplace(initializer_list<_Up> __il, _Args&&... __args) - { - *this = nullopt; - ::new((void*)_VSTD::addressof(this->__val_)) - value_type(__il, _VSTD::forward<_Args>(__args)...); - this->__engaged_ = true; - } - - _LIBCPP_INLINE_VISIBILITY - void - swap(optional& __opt) - noexcept(is_nothrow_move_constructible<value_type>::value && - __is_nothrow_swappable<value_type>::value) - { - using _VSTD::swap; - if (this->__engaged_ == __opt.__engaged_) - { - if (this->__engaged_) - swap(this->__val_, __opt.__val_); - } - else - { - if (this->__engaged_) - { - ::new((void*)_VSTD::addressof(__opt.__val_)) - value_type(_VSTD::move(this->__val_)); - this->__val_.~value_type(); - } - else - { - ::new((void*)_VSTD::addressof(this->__val_)) - value_type(_VSTD::move(__opt.__val_)); - __opt.__val_.~value_type(); - } - swap(this->__engaged_, __opt.__engaged_); - } - } - - _LIBCPP_INLINE_VISIBILITY - constexpr - value_type const* - operator->() const - { - _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); -#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF - return __builtin_addressof(this->__val_); -#else - return __operator_arrow(__has_operator_addressof<value_type>{}); -#endif - } - - _LIBCPP_INLINE_VISIBILITY - value_type* - operator->() - { - _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); - return _VSTD::addressof(this->__val_); - } - - _LIBCPP_INLINE_VISIBILITY - constexpr - const value_type& - operator*() const - { - _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); - return this->__val_; - } - - _LIBCPP_INLINE_VISIBILITY - value_type& - operator*() - { - _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); - return this->__val_; - } - - _LIBCPP_INLINE_VISIBILITY - constexpr explicit operator bool() const noexcept {return this->__engaged_;} - - _LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_NO_EXCEPTIONS -_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -#endif - constexpr void __throw_bad_optional_access() const - { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw bad_optional_access(); -#else - _VSTD::abort(); -#endif - } - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS - constexpr value_type const& value() const - { - if (!this->__engaged_) - __throw_bad_optional_access(); - return this->__val_; - } - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS - value_type& value() - { - if (!this->__engaged_) - __throw_bad_optional_access(); - return this->__val_; - } - - template <class _Up> - _LIBCPP_INLINE_VISIBILITY - constexpr value_type value_or(_Up&& __v) const& - { - static_assert(is_copy_constructible<value_type>::value, - "optional<T>::value_or: T must be copy constructible"); - static_assert(is_convertible<_Up, value_type>::value, - "optional<T>::value_or: U must be convertible to T"); - return this->__engaged_ ? this->__val_ : - static_cast<value_type>(_VSTD::forward<_Up>(__v)); - } - - template <class _Up> - _LIBCPP_INLINE_VISIBILITY - value_type value_or(_Up&& __v) && - { - static_assert(is_move_constructible<value_type>::value, - "optional<T>::value_or: T must be move constructible"); - static_assert(is_convertible<_Up, value_type>::value, - "optional<T>::value_or: U must be convertible to T"); - return this->__engaged_ ? _VSTD::move(this->__val_) : - static_cast<value_type>(_VSTD::forward<_Up>(__v)); - } - -private: - _LIBCPP_INLINE_VISIBILITY - value_type const* - __operator_arrow(true_type) const - { - return _VSTD::addressof(this->__val_); - } - - _LIBCPP_INLINE_VISIBILITY - constexpr - value_type const* - __operator_arrow(false_type) const - { - return &this->__val_; - } -}; - -// Comparisons between optionals -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) -{ - if (static_cast<bool>(__x) != static_cast<bool>(__y)) - return false; - if (!static_cast<bool>(__x)) - return true; - return *__x == *__y; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) -{ - return !(__x == __y); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) -{ - if (!static_cast<bool>(__y)) - return false; - if (!static_cast<bool>(__x)) - return true; - return *__x < *__y; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) -{ - return __y < __x; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) -{ - return !(__y < __x); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) -{ - return !(__x < __y); -} - - -// Comparisons with nullopt -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator==(const optional<_Tp>& __x, nullopt_t) noexcept -{ - return !static_cast<bool>(__x); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator==(nullopt_t, const optional<_Tp>& __x) noexcept -{ - return !static_cast<bool>(__x); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator!=(const optional<_Tp>& __x, nullopt_t) noexcept -{ - return static_cast<bool>(__x); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator!=(nullopt_t, const optional<_Tp>& __x) noexcept -{ - return static_cast<bool>(__x); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<(const optional<_Tp>&, nullopt_t) noexcept -{ - return false; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<(nullopt_t, const optional<_Tp>& __x) noexcept -{ - return static_cast<bool>(__x); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<=(const optional<_Tp>& __x, nullopt_t) noexcept -{ - return !static_cast<bool>(__x); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<=(nullopt_t, const optional<_Tp>&) noexcept -{ - return true; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>(const optional<_Tp>& __x, nullopt_t) noexcept -{ - return static_cast<bool>(__x); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>(nullopt_t, const optional<_Tp>&) noexcept -{ - return false; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>=(const optional<_Tp>&, nullopt_t) noexcept -{ - return true; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>=(nullopt_t, const optional<_Tp>& __x) noexcept -{ - return !static_cast<bool>(__x); -} - -// Comparisons with T -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator==(const optional<_Tp>& __x, const _Tp& __v) -{ - return static_cast<bool>(__x) ? *__x == __v : false; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator==(const _Tp& __v, const optional<_Tp>& __x) -{ - return static_cast<bool>(__x) ? *__x == __v : false; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator!=(const optional<_Tp>& __x, const _Tp& __v) -{ - return static_cast<bool>(__x) ? !(*__x == __v) : true; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator!=(const _Tp& __v, const optional<_Tp>& __x) -{ - return static_cast<bool>(__x) ? !(*__x == __v) : true; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<(const optional<_Tp>& __x, const _Tp& __v) -{ - return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<(const _Tp& __v, const optional<_Tp>& __x) -{ - return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<=(const optional<_Tp>& __x, const _Tp& __v) -{ - return !(__x > __v); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator<=(const _Tp& __v, const optional<_Tp>& __x) -{ - return !(__v > __x); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>(const optional<_Tp>& __x, const _Tp& __v) -{ - return static_cast<bool>(__x) ? __v < __x : false; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>(const _Tp& __v, const optional<_Tp>& __x) -{ - return static_cast<bool>(__x) ? __x < __v : true; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>=(const optional<_Tp>& __x, const _Tp& __v) -{ - return !(__x < __v); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -bool -operator>=(const _Tp& __v, const optional<_Tp>& __x) -{ - return !(__v < __x); -} - - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -void -swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) -{ - __x.swap(__y); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -constexpr -optional<typename decay<_Tp>::type> -make_optional(_Tp&& __v) -{ - return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v)); -} - -_LIBCPP_END_NAMESPACE_LFTS - -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class _Tp> -struct _LIBCPP_TEMPLATE_VIS hash<std::experimental::optional<_Tp> > -{ - typedef std::experimental::optional<_Tp> argument_type; - typedef size_t result_type; - - _LIBCPP_INLINE_VISIBILITY - result_type operator()(const argument_type& __opt) const _NOEXCEPT - { - return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0; - } -}; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_STD_VER > 11 - -_LIBCPP_POP_MACROS - -#endif // _LIBCPP_EXPERIMENTAL_OPTIONAL +#error "<experimental/optional> has been removed. Use <optional> instead." diff --git a/lib/libcxx/include/experimental/propagate_const b/lib/libcxx/include/experimental/propagate_const index e7f7e9fc683..188548596b8 100644 --- a/lib/libcxx/include/experimental/propagate_const +++ b/lib/libcxx/include/experimental/propagate_const @@ -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> diff --git a/lib/libcxx/include/experimental/ratio b/lib/libcxx/include/experimental/ratio index 757f24e0861..9c2bf2e4624 100644 --- a/lib/libcxx/include/experimental/ratio +++ b/lib/libcxx/include/experimental/ratio @@ -8,70 +8,4 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL_RATIO -#define _LIBCPP_EXPERIMENTAL_RATIO - -/** - experimental/ratio synopsis - C++1y -#include <ratio> - -namespace std { -namespace experimental { -inline namespace fundamentals_v1 { - - // See C++14 20.11.5, ratio comparison - template <class R1, class R2> constexpr bool ratio_equal_v - = ratio_equal<R1, R2>::value; - template <class R1, class R2> constexpr bool ratio_not_equal_v - = ratio_not_equal<R1, R2>::value; - template <class R1, class R2> constexpr bool ratio_less_v - = ratio_less<R1, R2>::value; - template <class R1, class R2> constexpr bool ratio_less_equal_v - = ratio_less_equal<R1, R2>::value; - template <class R1, class R2> constexpr bool ratio_greater_v - = ratio_greater<R1, R2>::value; - template <class R1, class R2> constexpr bool ratio_greater_equal_v - = ratio_greater_equal<R1, R2>::value; - -} // namespace fundamentals_v1 -} // namespace experimental -} // namespace std - -*/ - -#include <experimental/__config> - -#if _LIBCPP_STD_VER > 11 - -#include <ratio> - -_LIBCPP_BEGIN_NAMESPACE_LFTS - -#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES - -template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_equal_v - = ratio_equal<_R1, _R2>::value; - -template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_not_equal_v - = ratio_not_equal<_R1, _R2>::value; - -template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_less_v - = ratio_less<_R1, _R2>::value; - -template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_less_equal_v - = ratio_less_equal<_R1, _R2>::value; - -template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_v - = ratio_greater<_R1, _R2>::value; - -template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_equal_v - = ratio_greater_equal<_R1, _R2>::value; - -#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */ - -_LIBCPP_END_NAMESPACE_LFTS - -#endif /* _LIBCPP_STD_VER > 11 */ - -#endif // _LIBCPP_EXPERIMENTAL_RATIO +#error "<experimental/ratio> has been removed. Use <ratio> instead." diff --git a/lib/libcxx/include/experimental/simd b/lib/libcxx/include/experimental/simd new file mode 100644 index 00000000000..6580443f7b0 --- /dev/null +++ b/lib/libcxx/include/experimental/simd @@ -0,0 +1,1570 @@ +// -*- C++ -*- +//===------------------------------- simd ---------------------------------===// +// +// 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_EXPERIMENTAL_SIMD +#define _LIBCPP_EXPERIMENTAL_SIMD + +/* + experimental/simd synopsis + +namespace std::experimental { + +inline namespace parallelism_v2 { + +namespace simd_abi { + +struct scalar {}; +template <int N> struct fixed_size {}; +template <typename T> inline constexpr int max_fixed_size = implementation-defined; +template <typename T> using compatible = implementation-defined; +template <typename T> using native = implementation-defined; + +} // simd_abi + +struct element_aligned_tag {}; +struct vector_aligned_tag {}; +template <size_t> struct overaligned_tag {}; +inline constexpr element_aligned_tag element_aligned{}; +inline constexpr vector_aligned_tag vector_aligned{}; +template <size_t N> inline constexpr overaligned_tag<N> overaligned{}; + +// traits [simd.traits] +template <class T> struct is_abi_tag; +template <class T> inline constexpr bool is_abi_tag_v = is_abi_tag<T>::value; + +template <class T> struct is_simd; +template <class T> inline constexpr bool is_simd_v = is_simd<T>::value; + +template <class T> struct is_simd_mask; +template <class T> inline constexpr bool is_simd_mask_v = is_simd_mask<T>::value; + +template <class T> struct is_simd_flag_type; +template <class T> inline constexpr bool is_simd_flag_type_v = is_simd_flag_type<T>::value; + +template <class T, size_t N> struct abi_for_size { using type = see below; }; +template <class T, size_t N> using abi_for_size_t = typename abi_for_size<T, N>::type; + +template <class T, class Abi = simd_abi::compatible<T>> struct simd_size; +template <class T, class Abi = simd_abi::compatible<T>> +inline constexpr size_t simd_size_v = simd_size<T, Abi>::value; + +template <class T, class U = typename T::value_type> struct memory_alignment; +template <class T, class U = typename T::value_type> +inline constexpr size_t memory_alignment_v = memory_alignment<T, U>::value; + +// class template simd [simd.class] +template <class T, class Abi = simd_abi::compatible<T>> class simd; +template <class T> using native_simd = simd<T, simd_abi::native<T>>; +template <class T, int N> using fixed_size_simd = simd<T, simd_abi::fixed_size<N>>; + +// class template simd_mask [simd.mask.class] +template <class T, class Abi = simd_abi::compatible<T>> class simd_mask; +template <class T> using native_simd_mask = simd_mask<T, simd_abi::native<T>>; +template <class T, int N> using fixed_size_simd_mask = simd_mask<T, simd_abi::fixed_size<N>>; + +// casts [simd.casts] +template <class T, class U, class Abi> see below simd_cast(const simd<U, Abi>&); +template <class T, class U, class Abi> see below static_simd_cast(const simd<U, Abi>&); + +template <class T, class Abi> +fixed_size_simd<T, simd_size_v<T, Abi>> to_fixed_size(const simd<T, Abi>&) noexcept; +template <class T, class Abi> +fixed_size_simd_mask<T, simd_size_v<T, Abi>> to_fixed_size(const simd_mask<T, Abi>&) noexcept; +template <class T, size_t N> native_simd<T> to_native(const fixed_size_simd<T, N>&) noexcept; +template <class T, size_t N> +native_simd_mask<T> to_native(const fixed_size_simd_mask<T, N>> &) noexcept; +template <class T, size_t N> simd<T> to_compatible(const fixed_size_simd<T, N>&) noexcept; +template <class T, size_t N> simd_mask<T> to_compatible(const fixed_size_simd_mask<T, N>&) noexcept; + +template <size_t... Sizes, class T, class Abi> +tuple<simd<T, abi_for_size_t<Sizes>>...> split(const simd<T, Abi>&); +template <size_t... Sizes, class T, class Abi> +tuple<simd_mask<T, abi_for_size_t<Sizes>>...> split(const simd_mask<T, Abi>&); +template <class V, class Abi> +array<V, simd_size_v<typename V::value_type, Abi> / V::size()> split( +const simd<typename V::value_type, Abi>&); +template <class V, class Abi> +array<V, simd_size_v<typename V::value_type, Abi> / V::size()> split( +const simd_mask<typename V::value_type, Abi>&); + +template <class T, class... Abis> +simd<T, abi_for_size_t<T, (simd_size_v<T, Abis> + ...)>> concat(const simd<T, Abis>&...); +template <class T, class... Abis> +simd_mask<T, abi_for_size_t<T, (simd_size_v<T, Abis> + ...)>> concat(const simd_mask<T, Abis>&...); + +// reductions [simd.mask.reductions] +template <class T, class Abi> bool all_of(const simd_mask<T, Abi>&) noexcept; +template <class T, class Abi> bool any_of(const simd_mask<T, Abi>&) noexcept; +template <class T, class Abi> bool none_of(const simd_mask<T, Abi>&) noexcept; +template <class T, class Abi> bool some_of(const simd_mask<T, Abi>&) noexcept; +template <class T, class Abi> int popcount(const simd_mask<T, Abi>&) noexcept; +template <class T, class Abi> int find_first_set(const simd_mask<T, Abi>&); +template <class T, class Abi> int find_last_set(const simd_mask<T, Abi>&); + +bool all_of(see below) noexcept; +bool any_of(see below) noexcept; +bool none_of(see below) noexcept; +bool some_of(see below) noexcept; +int popcount(see below) noexcept; +int find_first_set(see below) noexcept; +int find_last_set(see below) noexcept; + +// masked assignment [simd.whereexpr] +template <class M, class T> class const_where_expression; +template <class M, class T> class where_expression; + +// masked assignment [simd.mask.where] +template <class T> struct nodeduce { using type = T; }; // exposition only + +template <class T> using nodeduce_t = typename nodeduce<T>::type; // exposition only + +template <class T, class Abi> +where_expression<simd_mask<T, Abi>, simd<T, Abi>> +where(const typename simd<T, Abi>::mask_type&, simd<T, Abi>&) noexcept; + +template <class T, class Abi> +const_where_expression<simd_mask<T, Abi>, const simd<T, Abi>> +where(const typename simd<T, Abi>::mask_type&, const simd<T, Abi>&) noexcept; + +template <class T, class Abi> +where_expression<simd_mask<T, Abi>, simd_mask<T, Abi>> +where(const nodeduce_t<simd_mask<T, Abi>>&, simd_mask<T, Abi>&) noexcept; + +template <class T, class Abi> +const_where_expression<simd_mask<T, Abi>, const simd_mask<T, Abi>> +where(const nodeduce_t<simd_mask<T, Abi>>&, const simd_mask<T, Abi>&) noexcept; + +template <class T> where_expression<bool, T> where(see below k, T& d) noexcept; + +template <class T> +const_where_expression<bool, const T> where(see below k, const T& d) noexcept; + +// reductions [simd.reductions] +template <class T, class Abi, class BinaryOperation = std::plus<>> +T reduce(const simd<T, Abi>&, BinaryOperation = BinaryOperation()); + +template <class M, class V, class BinaryOperation> +typename V::value_type reduce(const const_where_expression<M, V>& x, +typename V::value_type neutral_element, BinaryOperation binary_op); + +template <class M, class V> +typename V::value_type reduce(const const_where_expression<M, V>& x, plus<> binary_op = plus<>()); + +template <class M, class V> +typename V::value_type reduce(const const_where_expression<M, V>& x, multiplies<> binary_op); + +template <class M, class V> +typename V::value_type reduce(const const_where_expression<M, V>& x, bit_and<> binary_op); + +template <class M, class V> +typename V::value_type reduce(const const_where_expression<M, V>& x, bit_or<> binary_op); + +template <class M, class V> +typename V::value_type reduce(const const_where_expression<M, V>& x, bit_xor<> binary_op); + +template <class T, class Abi> T hmin(const simd<T, Abi>&); +template <class M, class V> T hmin(const const_where_expression<M, V>&); +template <class T, class Abi> T hmax(const simd<T, Abi>&); +template <class M, class V> T hmax(const const_where_expression<M, V>&); + +// algorithms [simd.alg] +template <class T, class Abi> simd<T, Abi> min(const simd<T, Abi>&, const simd<T, Abi>&) noexcept; + +template <class T, class Abi> simd<T, Abi> max(const simd<T, Abi>&, const simd<T, Abi>&) noexcept; + +template <class T, class Abi> +std::pair<simd<T, Abi>, simd<T, Abi>> minmax(const simd<T, Abi>&, const simd<T, Abi>&) noexcept; + +template <class T, class Abi> +simd<T, Abi> clamp(const simd<T, Abi>& v, const simd<T, Abi>& lo, const simd<T, Abi>& hi); + +// [simd.whereexpr] +template <class M, class T> +class const_where_expression { + const M& mask; // exposition only + T& data; // exposition only +public: + const_where_expression(const const_where_expression&) = delete; + const_where_expression& operator=(const const_where_expression&) = delete; + remove_const_t<T> operator-() const &&; + template <class U, class Flags> void copy_to(U* mem, Flags f) const &&; +}; + +template <class M, class T> +class where_expression : public const_where_expression<M, T> { +public: + where_expression(const where_expression&) = delete; + where_expression& operator=(const where_expression&) = delete; + template <class U> void operator=(U&& x); + template <class U> void operator+=(U&& x); + template <class U> void operator-=(U&& x); + template <class U> void operator*=(U&& x); + template <class U> void operator/=(U&& x); + template <class U> void operator%=(U&& x); + template <class U> void operator&=(U&& x); + template <class U> void operator|=(U&& x); + template <class U> void operator^=(U&& x); + template <class U> void operator<<=(U&& x); + template <class U> void operator>>=(U&& x); + void operator++(); + void operator++(int); + void operator--(); + void operator--(int); + template <class U, class Flags> void copy_from(const U* mem, Flags); +}; + +// [simd.class] +template <class T, class Abi> class simd { +public: + using value_type = T; + using reference = see below; + using mask_type = simd_mask<T, Abi>; + + using abi_type = Abi; + static constexpr size_t size() noexcept; + simd() = default; + + // implicit type conversion constructor + template <class U> simd(const simd<U, simd_abi::fixed_size<size()>>&); + + // implicit broadcast constructor (see below for constraints) + template <class U> simd(U&& value); + + // generator constructor (see below for constraints) + template <class G> explicit simd(G&& gen); + + // load constructor + template <class U, class Flags> simd(const U* mem, Flags f); + + // loads [simd.load] + template <class U, class Flags> void copy_from(const U* mem, Flags f); + + // stores [simd.store] + template <class U, class Flags> void copy_to(U* mem, Flags f) const; + + // scalar access [simd.subscr] + reference operator[](size_t); + value_type operator[](size_t) const; + + // unary operators [simd.unary] + simd& operator++(); + simd operator++(int); + simd& operator--(); + simd operator--(int); + mask_type operator!() const; + simd operator~() const; // see below + simd operator+() const; + simd operator-() const; + + // binary operators [simd.binary] + friend simd operator+ (const simd&, const simd&); + friend simd operator- (const simd&, const simd&); + friend simd operator* (const simd&, const simd&); + friend simd operator/ (const simd&, const simd&); + friend simd operator% (const simd&, const simd&); + friend simd operator& (const simd&, const simd&); + friend simd operator| (const simd&, const simd&); + friend simd operator^ (const simd&, const simd&); + friend simd operator<<(const simd&, const simd&); + friend simd operator>>(const simd&, const simd&); + friend simd operator<<(const simd&, int); + friend simd operator>>(const simd&, int); + + // compound assignment [simd.cassign] + friend simd& operator+= (simd&, const simd&); + friend simd& operator-= (simd&, const simd&); + friend simd& operator*= (simd&, const simd&); + friend simd& operator/= (simd&, const simd&); + friend simd& operator%= (simd&, const simd&); + + friend simd& operator&= (simd&, const simd&); + friend simd& operator|= (simd&, const simd&); + friend simd& operator^= (simd&, const simd&); + friend simd& operator<<=(simd&, const simd&); + friend simd& operator>>=(simd&, const simd&); + friend simd& operator<<=(simd&, int); + friend simd& operator>>=(simd&, int); + + // compares [simd.comparison] + friend mask_type operator==(const simd&, const simd&); + friend mask_type operator!=(const simd&, const simd&); + friend mask_type operator>=(const simd&, const simd&); + friend mask_type operator<=(const simd&, const simd&); + friend mask_type operator> (const simd&, const simd&); + friend mask_type operator< (const simd&, const simd&); +}; + +// [simd.math] +template <class Abi> using scharv = simd<signed char, Abi>; // exposition only +template <class Abi> using shortv = simd<short, Abi>; // exposition only +template <class Abi> using intv = simd<int, Abi>; // exposition only +template <class Abi> using longv = simd<long int, Abi>; // exposition only +template <class Abi> using llongv = simd<long long int, Abi>; // exposition only +template <class Abi> using floatv = simd<float, Abi>; // exposition only +template <class Abi> using doublev = simd<double, Abi>; // exposition only +template <class Abi> using ldoublev = simd<long double, Abi>; // exposition only +template <class T, class V> using samesize = fixed_size_simd<T, V::size()>; // exposition only + +template <class Abi> floatv<Abi> acos(floatv<Abi> x); +template <class Abi> doublev<Abi> acos(doublev<Abi> x); +template <class Abi> ldoublev<Abi> acos(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> asin(floatv<Abi> x); +template <class Abi> doublev<Abi> asin(doublev<Abi> x); +template <class Abi> ldoublev<Abi> asin(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> atan(floatv<Abi> x); +template <class Abi> doublev<Abi> atan(doublev<Abi> x); +template <class Abi> ldoublev<Abi> atan(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> atan2(floatv<Abi> y, floatv<Abi> x); +template <class Abi> doublev<Abi> atan2(doublev<Abi> y, doublev<Abi> x); +template <class Abi> ldoublev<Abi> atan2(ldoublev<Abi> y, ldoublev<Abi> x); + +template <class Abi> floatv<Abi> cos(floatv<Abi> x); +template <class Abi> doublev<Abi> cos(doublev<Abi> x); +template <class Abi> ldoublev<Abi> cos(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> sin(floatv<Abi> x); +template <class Abi> doublev<Abi> sin(doublev<Abi> x); +template <class Abi> ldoublev<Abi> sin(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> tan(floatv<Abi> x); +template <class Abi> doublev<Abi> tan(doublev<Abi> x); +template <class Abi> ldoublev<Abi> tan(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> acosh(floatv<Abi> x); +template <class Abi> doublev<Abi> acosh(doublev<Abi> x); +template <class Abi> ldoublev<Abi> acosh(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> asinh(floatv<Abi> x); +template <class Abi> doublev<Abi> asinh(doublev<Abi> x); +template <class Abi> ldoublev<Abi> asinh(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> atanh(floatv<Abi> x); +template <class Abi> doublev<Abi> atanh(doublev<Abi> x); +template <class Abi> ldoublev<Abi> atanh(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> cosh(floatv<Abi> x); +template <class Abi> doublev<Abi> cosh(doublev<Abi> x); +template <class Abi> ldoublev<Abi> cosh(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> sinh(floatv<Abi> x); +template <class Abi> doublev<Abi> sinh(doublev<Abi> x); +template <class Abi> ldoublev<Abi> sinh(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> tanh(floatv<Abi> x); +template <class Abi> doublev<Abi> tanh(doublev<Abi> x); +template <class Abi> ldoublev<Abi> tanh(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> exp(floatv<Abi> x); +template <class Abi> doublev<Abi> exp(doublev<Abi> x); +template <class Abi> ldoublev<Abi> exp(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> exp2(floatv<Abi> x); +template <class Abi> doublev<Abi> exp2(doublev<Abi> x); +template <class Abi> ldoublev<Abi> exp2(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> expm1(floatv<Abi> x); +template <class Abi> doublev<Abi> expm1(doublev<Abi> x); +template <class Abi> ldoublev<Abi> expm1(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> frexp(floatv<Abi> value, samesize<int, floatv<Abi>>* exp); +template <class Abi> doublev<Abi> frexp(doublev<Abi> value, samesize<int, doublev<Abi>>* exp); +template <class Abi> ldoublev<Abi> frexp(ldoublev<Abi> value, samesize<int, ldoublev<Abi>>* exp); + +template <class Abi> samesize<int, floatv<Abi>> ilogb(floatv<Abi> x); +template <class Abi> samesize<int, doublev<Abi>> ilogb(doublev<Abi> x); +template <class Abi> samesize<int, ldoublev<Abi>> ilogb(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> ldexp(floatv<Abi> x, samesize<int, floatv<Abi>> exp); +template <class Abi> doublev<Abi> ldexp(doublev<Abi> x, samesize<int, doublev<Abi>> exp); +template <class Abi> ldoublev<Abi> ldexp(ldoublev<Abi> x, samesize<int, ldoublev<Abi>> exp); + +template <class Abi> floatv<Abi> log(floatv<Abi> x); +template <class Abi> doublev<Abi> log(doublev<Abi> x); +template <class Abi> ldoublev<Abi> log(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> log10(floatv<Abi> x); +template <class Abi> doublev<Abi> log10(doublev<Abi> x); +template <class Abi> ldoublev<Abi> log10(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> log1p(floatv<Abi> x); +template <class Abi> doublev<Abi> log1p(doublev<Abi> x); +template <class Abi> ldoublev<Abi> log1p(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> log2(floatv<Abi> x); +template <class Abi> doublev<Abi> log2(doublev<Abi> x); +template <class Abi> ldoublev<Abi> log2(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> logb(floatv<Abi> x); +template <class Abi> doublev<Abi> logb(doublev<Abi> x); +template <class Abi> ldoublev<Abi> logb(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> modf(floatv<Abi> value, floatv<Abi>* iptr); +template <class Abi> doublev<Abi> modf(doublev<Abi> value, doublev<Abi>* iptr); +template <class Abi> ldoublev<Abi> modf(ldoublev<Abi> value, ldoublev<Abi>* iptr); + +template <class Abi> floatv<Abi> scalbn(floatv<Abi> x, samesize<int, floatv<Abi>> n); +template <class Abi> doublev<Abi> scalbn(doublev<Abi> x, samesize<int, doublev<Abi>> n); +template <class Abi> ldoublev<Abi> scalbn(ldoublev<Abi> x, samesize<int, ldoublev<Abi>> n); +template <class Abi> floatv<Abi> scalbln(floatv<Abi> x, samesize<long int, floatv<Abi>> n); +template <class Abi> doublev<Abi> scalbln(doublev<Abi> x, samesize<long int, doublev<Abi>> n); +template <class Abi> ldoublev<Abi> scalbln(ldoublev<Abi> x, samesize<long int, ldoublev<Abi>> n); + +template <class Abi> floatv<Abi> cbrt(floatv<Abi> x); +template <class Abi> doublev<Abi> cbrt(doublev<Abi> x); +template <class Abi> ldoublev<Abi> cbrt(ldoublev<Abi> x); + +template <class Abi> scharv<Abi> abs(scharv<Abi> j); +template <class Abi> shortv<Abi> abs(shortv<Abi> j); +template <class Abi> intv<Abi> abs(intv<Abi> j); +template <class Abi> longv<Abi> abs(longv<Abi> j); +template <class Abi> llongv<Abi> abs(llongv<Abi> j); +template <class Abi> floatv<Abi> abs(floatv<Abi> j); +template <class Abi> doublev<Abi> abs(doublev<Abi> j); +template <class Abi> ldoublev<Abi> abs(ldoublev<Abi> j); + +template <class Abi> floatv<Abi> hypot(floatv<Abi> x, floatv<Abi> y); +template <class Abi> doublev<Abi> hypot(doublev<Abi> x, doublev<Abi> y); +template <class Abi> ldoublev<Abi> hypot(doublev<Abi> x, doublev<Abi> y); +template <class Abi> floatv<Abi> hypot(floatv<Abi> x, floatv<Abi> y, floatv<Abi> z); +template <class Abi> doublev<Abi> hypot(doublev<Abi> x, doublev<Abi> y, doublev<Abi> z); +template <class Abi> ldoublev<Abi> hypot(ldoublev<Abi> x, ldoublev<Abi> y, ldoublev<Abi> z); + +template <class Abi> floatv<Abi> pow(floatv<Abi> x, floatv<Abi> y); +template <class Abi> doublev<Abi> pow(doublev<Abi> x, doublev<Abi> y); +template <class Abi> ldoublev<Abi> pow(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> floatv<Abi> sqrt(floatv<Abi> x); +template <class Abi> doublev<Abi> sqrt(doublev<Abi> x); +template <class Abi> ldoublev<Abi> sqrt(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> erf(floatv<Abi> x); +template <class Abi> doublev<Abi> erf(doublev<Abi> x); +template <class Abi> ldoublev<Abi> erf(ldoublev<Abi> x); +template <class Abi> floatv<Abi> erfc(floatv<Abi> x); +template <class Abi> doublev<Abi> erfc(doublev<Abi> x); +template <class Abi> ldoublev<Abi> erfc(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> lgamma(floatv<Abi> x); +template <class Abi> doublev<Abi> lgamma(doublev<Abi> x); +template <class Abi> ldoublev<Abi> lgamma(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> tgamma(floatv<Abi> x); +template <class Abi> doublev<Abi> tgamma(doublev<Abi> x); +template <class Abi> ldoublev<Abi> tgamma(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> ceil(floatv<Abi> x); +template <class Abi> doublev<Abi> ceil(doublev<Abi> x); +template <class Abi> ldoublev<Abi> ceil(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> floor(floatv<Abi> x); +template <class Abi> doublev<Abi> floor(doublev<Abi> x); +template <class Abi> ldoublev<Abi> floor(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> nearbyint(floatv<Abi> x); +template <class Abi> doublev<Abi> nearbyint(doublev<Abi> x); +template <class Abi> ldoublev<Abi> nearbyint(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> rint(floatv<Abi> x); +template <class Abi> doublev<Abi> rint(doublev<Abi> x); +template <class Abi> ldoublev<Abi> rint(ldoublev<Abi> x); + +template <class Abi> samesize<long int, floatv<Abi>> lrint(floatv<Abi> x); +template <class Abi> samesize<long int, doublev<Abi>> lrint(doublev<Abi> x); +template <class Abi> samesize<long int, ldoublev<Abi>> lrint(ldoublev<Abi> x); +template <class Abi> samesize<long long int, floatv<Abi>> llrint(floatv<Abi> x); +template <class Abi> samesize<long long int, doublev<Abi>> llrint(doublev<Abi> x); +template <class Abi> samesize<long long int, ldoublev<Abi>> llrint(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> round(floatv<Abi> x); +template <class Abi> doublev<Abi> round(doublev<Abi> x); +template <class Abi> ldoublev<Abi> round(ldoublev<Abi> x); +template <class Abi> samesize<long int, floatv<Abi>> lround(floatv<Abi> x); +template <class Abi> samesize<long int, doublev<Abi>> lround(doublev<Abi> x); +template <class Abi> samesize<long int, ldoublev<Abi>> lround(ldoublev<Abi> x); +template <class Abi> samesize<long long int, floatv<Abi>> llround(floatv<Abi> x); +template <class Abi> samesize<long long int, doublev<Abi>> llround(doublev<Abi> x); +template <class Abi> samesize<long long int, ldoublev<Abi>> llround(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> trunc(floatv<Abi> x); +template <class Abi> doublev<Abi> trunc(doublev<Abi> x); +template <class Abi> ldoublev<Abi> trunc(ldoublev<Abi> x); + +template <class Abi> floatv<Abi> fmod(floatv<Abi> x, floatv<Abi> y); +template <class Abi> doublev<Abi> fmod(doublev<Abi> x, doublev<Abi> y); +template <class Abi> ldoublev<Abi> fmod(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> floatv<Abi> remainder(floatv<Abi> x, floatv<Abi> y); +template <class Abi> doublev<Abi> remainder(doublev<Abi> x, doublev<Abi> y); +template <class Abi> ldoublev<Abi> remainder(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> floatv<Abi> remquo(floatv<Abi> x, floatv<Abi> y, samesize<int, floatv<Abi>>* quo); +template <class Abi> doublev<Abi> remquo(doublev<Abi> x, doublev<Abi> y, samesize<int, doublev<Abi>>* quo); +template <class Abi> ldoublev<Abi> remquo(ldoublev<Abi> x, ldoublev<Abi> y, samesize<int, ldoublev<Abi>>* quo); + +template <class Abi> floatv<Abi> copysign(floatv<Abi> x, floatv<Abi> y); +template <class Abi> doublev<Abi> copysign(doublev<Abi> x, doublev<Abi> y); +template <class Abi> ldoublev<Abi> copysign(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> doublev<Abi> nan(const char* tagp); +template <class Abi> floatv<Abi> nanf(const char* tagp); +template <class Abi> ldoublev<Abi> nanl(const char* tagp); + +template <class Abi> floatv<Abi> nextafter(floatv<Abi> x, floatv<Abi> y); +template <class Abi> doublev<Abi> nextafter(doublev<Abi> x, doublev<Abi> y); +template <class Abi> ldoublev<Abi> nextafter(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> floatv<Abi> nexttoward(floatv<Abi> x, ldoublev<Abi> y); +template <class Abi> doublev<Abi> nexttoward(doublev<Abi> x, ldoublev<Abi> y); +template <class Abi> ldoublev<Abi> nexttoward(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> floatv<Abi> fdim(floatv<Abi> x, floatv<Abi> y); +template <class Abi> doublev<Abi> fdim(doublev<Abi> x, doublev<Abi> y); +template <class Abi> ldoublev<Abi> fdim(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> floatv<Abi> fmax(floatv<Abi> x, floatv<Abi> y); +template <class Abi> doublev<Abi> fmax(doublev<Abi> x, doublev<Abi> y); +template <class Abi> ldoublev<Abi> fmax(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> floatv<Abi> fmin(floatv<Abi> x, floatv<Abi> y); +template <class Abi> doublev<Abi> fmin(doublev<Abi> x, doublev<Abi> y); +template <class Abi> ldoublev<Abi> fmin(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> floatv<Abi> fma(floatv<Abi> x, floatv<Abi> y, floatv<Abi> z); +template <class Abi> doublev<Abi> fma(doublev<Abi> x, doublev<Abi> y, doublev<Abi> z); +template <class Abi> ldoublev<Abi> fma(ldoublev<Abi> x, ldoublev<Abi> y, ldoublev<Abi> z); + +template <class Abi> samesize<int, floatv<Abi>> fpclassify(floatv<Abi> x); +template <class Abi> samesize<int, doublev<Abi>> fpclassify(doublev<Abi> x); +template <class Abi> samesize<int, ldoublev<Abi>> fpclassify(ldoublev<Abi> x); + +template <class Abi> simd_mask<float, Abi> isfinite(floatv<Abi> x); +template <class Abi> simd_mask<double, Abi> isfinite(doublev<Abi> x); +template <class Abi> simd_mask<long double, Abi> isfinite(ldoublev<Abi> x); + +template <class Abi> simd_mask<float, Abi> isinf(floatv<Abi> x); +template <class Abi> simd_mask<double, Abi> isinf(doublev<Abi> x); +template <class Abi> simd_mask<long double, Abi> isinf(ldoublev<Abi> x); + +template <class Abi> simd_mask<float, Abi> isnan(floatv<Abi> x); +template <class Abi> simd_mask<double, Abi> isnan(doublev<Abi> x); +template <class Abi> simd_mask<long double, Abi> isnan(ldoublev<Abi> x); + +template <class Abi> simd_mask<float, Abi> isnormal(floatv<Abi> x); +template <class Abi> simd_mask<double, Abi> isnormal(doublev<Abi> x); +template <class Abi> simd_mask<long double, Abi> isnormal(ldoublev<Abi> x); + +template <class Abi> simd_mask<float, Abi> signbit(floatv<Abi> x); +template <class Abi> simd_mask<double, Abi> signbit(doublev<Abi> x); +template <class Abi> simd_mask<long double, Abi> signbit(ldoublev<Abi> x); + +template <class Abi> simd_mask<float, Abi> isgreater(floatv<Abi> x, floatv<Abi> y); +template <class Abi> simd_mask<double, Abi> isgreater(doublev<Abi> x, doublev<Abi> y); +template <class Abi> simd_mask<long double, Abi> isgreater(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> simd_mask<float, Abi> isgreaterequal(floatv<Abi> x, floatv<Abi> y); +template <class Abi> simd_mask<double, Abi> isgreaterequal(doublev<Abi> x, doublev<Abi> y); +template <class Abi> simd_mask<long double, Abi> isgreaterequal(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> simd_mask<float, Abi> isless(floatv<Abi> x, floatv<Abi> y); +template <class Abi> simd_mask<double, Abi> isless(doublev<Abi> x, doublev<Abi> y); +template <class Abi> simd_mask<long double, Abi> isless(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> simd_mask<float, Abi> islessequal(floatv<Abi> x, floatv<Abi> y); +template <class Abi> simd_mask<double, Abi> islessequal(doublev<Abi> x, doublev<Abi> y); +template <class Abi> simd_mask<long double, Abi> islessequal(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> simd_mask<float, Abi> islessgreater(floatv<Abi> x, floatv<Abi> y); +template <class Abi> simd_mask<double, Abi> islessgreater(doublev<Abi> x, doublev<Abi> y); +template <class Abi> simd_mask<long double, Abi> islessgreater(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class Abi> simd_mask<float, Abi> isunordered(floatv<Abi> x, floatv<Abi> y); +template <class Abi> simd_mask<double, Abi> isunordered(doublev<Abi> x, doublev<Abi> y); +template <class Abi> simd_mask<long double, Abi> isunordered(ldoublev<Abi> x, ldoublev<Abi> y); + +template <class V> struct simd_div_t { V quot, rem; }; +template <class Abi> simd_div_t<scharv<Abi>> div(scharv<Abi> numer, scharv<Abi> denom); +template <class Abi> simd_div_t<shortv<Abi>> div(shortv<Abi> numer, shortv<Abi> denom); +template <class Abi> simd_div_t<intv<Abi>> div(intv<Abi> numer, intv<Abi> denom); +template <class Abi> simd_div_t<longv<Abi>> div(longv<Abi> numer, longv<Abi> denom); +template <class Abi> simd_div_t<llongv<Abi>> div(llongv<Abi> numer, llongv<Abi> denom); + +// [simd.mask.class] +template <class T, class Abi> +class simd_mask { +public: + using value_type = bool; + using reference = see below; + using simd_type = simd<T, Abi>; + using abi_type = Abi; + static constexpr size_t size() noexcept; + simd_mask() = default; + + // broadcast constructor + explicit simd_mask(value_type) noexcept; + + // implicit type conversion constructor + template <class U> simd_mask(const simd_mask<U, simd_abi::fixed_size<size()>>&) noexcept; + + // load constructor + template <class Flags> simd_mask(const value_type* mem, Flags); + + // loads [simd.mask.copy] + template <class Flags> void copy_from(const value_type* mem, Flags); + template <class Flags> void copy_to(value_type* mem, Flags) const; + + // scalar access [simd.mask.subscr] + reference operator[](size_t); + value_type operator[](size_t) const; + + // unary operators [simd.mask.unary] + simd_mask operator!() const noexcept; + + // simd_mask binary operators [simd.mask.binary] + friend simd_mask operator&&(const simd_mask&, const simd_mask&) noexcept; + friend simd_mask operator||(const simd_mask&, const simd_mask&) noexcept; + friend simd_mask operator& (const simd_mask&, const simd_mask&) noexcept; + friend simd_mask operator| (const simd_mask&, const simd_mask&) noexcept; + friend simd_mask operator^ (const simd_mask&, const simd_mask&) noexcept; + + // simd_mask compound assignment [simd.mask.cassign] + friend simd_mask& operator&=(simd_mask&, const simd_mask&) noexcept; + friend simd_mask& operator|=(simd_mask&, const simd_mask&) noexcept; + friend simd_mask& operator^=(simd_mask&, const simd_mask&) noexcept; + + // simd_mask compares [simd.mask.comparison] + friend simd_mask operator==(const simd_mask&, const simd_mask&) noexcept; + friend simd_mask operator!=(const simd_mask&, const simd_mask&) noexcept; +}; + +} // parallelism_v2 +} // std::experimental + +*/ + +#include <experimental/__config> +#include <algorithm> +#include <array> +#include <cstddef> +#include <functional> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD + +#if _LIBCPP_STD_VER >= 17 + +enum class _StorageKind { + _Scalar, + _Array, + _VecExt, +}; + +template <_StorageKind __kind, int _Np> +struct __simd_abi {}; + +template <class _Tp, class _Abi> +class __simd_storage {}; + +template <class _Tp, int __num_element> +class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> { + std::array<_Tp, __num_element> __storage_; + + template <class, class> + friend struct simd; + + template <class, class> + friend struct simd_mask; + +public: + _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }; + void __set(size_t __index, _Tp __val) noexcept { + __storage_[__index] = __val; + } +}; + +template <class _Tp> +class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> { + _Tp __storage_; + + template <class, class> + friend struct simd; + + template <class, class> + friend struct simd_mask; + +public: + _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; }; + void __set(size_t __index, _Tp __val) noexcept { + (&__storage_)[__index] = __val; + } +}; + +#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION + +constexpr size_t __floor_pow_of_2(size_t __val) { + return ((__val - 1) & __val) == 0 ? __val + : __floor_pow_of_2((__val - 1) & __val); +} + +constexpr size_t __ceil_pow_of_2(size_t __val) { + return __val == 1 ? 1 : __floor_pow_of_2(__val - 1) << 1; +} + +template <class _Tp, size_t __bytes> +struct __vec_ext_traits { +#if !defined(_LIBCPP_COMPILER_CLANG) + typedef _Tp type __attribute__((vector_size(__ceil_pow_of_2(__bytes)))); +#endif +}; + +#if defined(_LIBCPP_COMPILER_CLANG) +#define _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT) \ + template <> \ + struct __vec_ext_traits<_TYPE, sizeof(_TYPE) * _NUM_ELEMENT> { \ + using type = \ + _TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT))); \ + } + +#define _LIBCPP_SPECIALIZE_VEC_EXT_32(_TYPE) \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 1); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 2); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 3); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 4); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 5); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 6); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 7); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 8); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 9); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 10); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 11); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 12); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 13); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 14); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 15); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 16); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 17); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 18); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 19); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 20); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 21); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 22); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 23); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 24); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 25); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 26); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 27); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 28); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 29); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 30); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 31); \ + _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 32); + +_LIBCPP_SPECIALIZE_VEC_EXT_32(char); +_LIBCPP_SPECIALIZE_VEC_EXT_32(char16_t); +_LIBCPP_SPECIALIZE_VEC_EXT_32(char32_t); +_LIBCPP_SPECIALIZE_VEC_EXT_32(wchar_t); +_LIBCPP_SPECIALIZE_VEC_EXT_32(signed char); +_LIBCPP_SPECIALIZE_VEC_EXT_32(signed short); +_LIBCPP_SPECIALIZE_VEC_EXT_32(signed int); +_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long); +_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long long); +_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned char); +_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned short); +_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned int); +_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long); +_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long long); +_LIBCPP_SPECIALIZE_VEC_EXT_32(float); +_LIBCPP_SPECIALIZE_VEC_EXT_32(double); +_LIBCPP_SPECIALIZE_VEC_EXT_32(long double); + +#undef _LIBCPP_SPECIALIZE_VEC_EXT_32 +#undef _LIBCPP_SPECIALIZE_VEC_EXT +#endif + +template <class _Tp, int __num_element> +class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> { + using _StorageType = + typename __vec_ext_traits<_Tp, sizeof(_Tp) * __num_element>::type; + + _StorageType __storage_; + + template <class, class> + friend struct simd; + + template <class, class> + friend struct simd_mask; + +public: + _Tp __get(size_t __index) const noexcept { return __storage_[__index]; }; + void __set(size_t __index, _Tp __val) noexcept { + __storage_[__index] = __val; + } +}; + +#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION + +template <class _Vp, class _Tp, class _Abi> +class __simd_reference { + static_assert(std::is_same<_Vp, _Tp>::value, ""); + + template <class, class> + friend struct simd; + + template <class, class> + friend struct simd_mask; + + __simd_storage<_Tp, _Abi>* __ptr_; + size_t __index_; + + __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index) + : __ptr_(__ptr), __index_(__index) {} + + __simd_reference(const __simd_reference&) = default; + +public: + __simd_reference() = delete; + __simd_reference& operator=(const __simd_reference&) = delete; + + operator _Vp() const { return __ptr_->__get(__index_); } + + __simd_reference operator=(_Vp __value) && { + __ptr_->__set(__index_, __value); + return *this; + } + + __simd_reference operator++() && { + return std::move(*this) = __ptr_->__get(__index_) + 1; + } + + _Vp operator++(int) && { + auto __val = __ptr_->__get(__index_); + __ptr_->__set(__index_, __val + 1); + return __val; + } + + __simd_reference operator--() && { + return std::move(*this) = __ptr_->__get(__index_) - 1; + } + + _Vp operator--(int) && { + auto __val = __ptr_->__get(__index_); + __ptr_->__set(__index_, __val - 1); + return __val; + } + + __simd_reference operator+=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) + __value; + } + + __simd_reference operator-=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) - __value; + } + + __simd_reference operator*=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) * __value; + } + + __simd_reference operator/=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) / __value; + } + + __simd_reference operator%=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) % __value; + } + + __simd_reference operator>>=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) >> __value; + } + + __simd_reference operator<<=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) << __value; + } + + __simd_reference operator&=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) & __value; + } + + __simd_reference operator|=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) | __value; + } + + __simd_reference operator^=(_Vp __value) && { + return std::move(*this) = __ptr_->__get(__index_) ^ __value; + } +}; + +template <class _To, class _From> +constexpr decltype(_To{std::declval<_From>()}, true) +__is_non_narrowing_convertible_impl(_From) { + return true; +} + +template <class _To> +constexpr bool __is_non_narrowing_convertible_impl(...) { + return false; +} + +template <class _From, class _To> +constexpr typename std::enable_if<std::is_arithmetic<_To>::value && + std::is_arithmetic<_From>::value, + bool>::type +__is_non_narrowing_arithmetic_convertible() { + return __is_non_narrowing_convertible_impl<_To>(_From{}); +} + +template <class _From, class _To> +constexpr typename std::enable_if<!(std::is_arithmetic<_To>::value && + std::is_arithmetic<_From>::value), + bool>::type +__is_non_narrowing_arithmetic_convertible() { + return false; +} + +template <class _Tp> +constexpr _Tp __variadic_sum() { + return _Tp{}; +} + +template <class _Tp, class _Up, class... _Args> +constexpr _Tp __variadic_sum(_Up __first, _Args... __rest) { + return static_cast<_Tp>(__first) + __variadic_sum<_Tp>(__rest...); +} + +template <class _Tp> +struct __nodeduce { + using type = _Tp; +}; + +template <class _Tp> +constexpr bool __vectorizable() { + return std::is_arithmetic<_Tp>::value && !std::is_const<_Tp>::value && + !std::is_volatile<_Tp>::value && !std::is_same<_Tp, bool>::value; +} + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD_ABI + +using scalar = __simd_abi<_StorageKind::_Scalar, 1>; + +template <int _Np> +using fixed_size = __simd_abi<_StorageKind::_Array, _Np>; + +template <class _Tp> +_LIBCPP_INLINE_VAR constexpr size_t max_fixed_size = 32; + +template <class _Tp> +using compatible = fixed_size<16 / sizeof(_Tp)>; + +#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION +template <class _Tp> +using native = __simd_abi<_StorageKind::_VecExt, + _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>; +#else +template <class _Tp> +using native = + fixed_size<_Tp, _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>; +#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD + +template <class _Tp, class _Abi = simd_abi::compatible<_Tp>> +class simd; +template <class _Tp, class _Abi = simd_abi::compatible<_Tp>> +class simd_mask; + +struct element_aligned_tag {}; +struct vector_aligned_tag {}; +template <size_t> +struct overaligned_tag {}; +_LIBCPP_INLINE_VAR constexpr element_aligned_tag element_aligned{}; +_LIBCPP_INLINE_VAR constexpr vector_aligned_tag vector_aligned{}; +template <size_t _Np> +_LIBCPP_INLINE_VAR constexpr overaligned_tag<_Np> overaligned{}; + +// traits [simd.traits] +template <class _Tp> +struct is_abi_tag : std::integral_constant<bool, false> {}; + +template <_StorageKind __kind, int _Np> +struct is_abi_tag<__simd_abi<__kind, _Np>> + : std::integral_constant<bool, true> {}; + +template <class _Tp> +struct is_simd : std::integral_constant<bool, false> {}; + +template <class _Tp, class _Abi> +struct is_simd<simd<_Tp, _Abi>> : std::integral_constant<bool, true> {}; + +template <class _Tp> +struct is_simd_mask : std::integral_constant<bool, false> {}; + +template <class _Tp, class _Abi> +struct is_simd_mask<simd_mask<_Tp, _Abi>> : std::integral_constant<bool, true> { +}; + +template <class _Tp> +struct is_simd_flag_type : std::integral_constant<bool, false> {}; + +template <> +struct is_simd_flag_type<element_aligned_tag> + : std::integral_constant<bool, true> {}; + +template <> +struct is_simd_flag_type<vector_aligned_tag> + : std::integral_constant<bool, true> {}; + +template <size_t _Align> +struct is_simd_flag_type<overaligned_tag<_Align>> + : std::integral_constant<bool, true> {}; + +template <class _Tp> +_LIBCPP_INLINE_VAR constexpr bool is_abi_tag_v = is_abi_tag<_Tp>::value; +template <class _Tp> +_LIBCPP_INLINE_VAR constexpr bool is_simd_v = is_simd<_Tp>::value; +template <class _Tp> +_LIBCPP_INLINE_VAR constexpr bool is_simd_mask_v = is_simd_mask<_Tp>::value; +template <class _Tp> +_LIBCPP_INLINE_VAR constexpr bool is_simd_flag_type_v = + is_simd_flag_type<_Tp>::value; +template <class _Tp, size_t _Np> +struct abi_for_size { + using type = simd_abi::fixed_size<_Np>; +}; +template <class _Tp, size_t _Np> +using abi_for_size_t = typename abi_for_size<_Tp, _Np>::type; + +template <class _Tp, class _Abi = simd_abi::compatible<_Tp>> +struct simd_size; + +template <class _Tp, _StorageKind __kind, int _Np> +struct simd_size<_Tp, __simd_abi<__kind, _Np>> + : std::integral_constant<size_t, _Np> { + static_assert( + std::is_arithmetic<_Tp>::value && + !std::is_same<typename std::remove_const<_Tp>::type, bool>::value, + "Element type should be vectorizable"); +}; + +// TODO: implement it. +template <class _Tp, class _Up = typename _Tp::value_type> +struct memory_alignment; + +template <class _Tp, class _Abi = simd_abi::compatible<_Tp>> +_LIBCPP_INLINE_VAR constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value; + +template <class _Tp, class _Up = typename _Tp::value_type> +_LIBCPP_INLINE_VAR constexpr size_t memory_alignment_v = + memory_alignment<_Tp, _Up>::value; + +// class template simd [simd.class] +template <class _Tp> +using native_simd = simd<_Tp, simd_abi::native<_Tp>>; +template <class _Tp, int _Np> +using fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>; + +// class template simd_mask [simd.mask.class] +template <class _Tp> +using native_simd_mask = simd_mask<_Tp, simd_abi::native<_Tp>>; + +template <class _Tp, int _Np> +using fixed_size_simd_mask = simd_mask<_Tp, simd_abi::fixed_size<_Np>>; + +// casts [simd.casts] +template <class _Tp> +struct __static_simd_cast_traits { + template <class _Up, class _Abi> + static simd<_Tp, _Abi> __apply(const simd<_Up, _Abi>& __v); +}; + +template <class _Tp, class _NewAbi> +struct __static_simd_cast_traits<simd<_Tp, _NewAbi>> { + template <class _Up, class _Abi> + static typename std::enable_if<simd<_Up, _Abi>::size() == + simd<_Tp, _NewAbi>::size(), + simd<_Tp, _NewAbi>>::type + __apply(const simd<_Up, _Abi>& __v); +}; + +template <class _Tp> +struct __simd_cast_traits { + template <class _Up, class _Abi> + static typename std::enable_if< + __is_non_narrowing_arithmetic_convertible<_Up, _Tp>(), + simd<_Tp, _Abi>>::type + __apply(const simd<_Up, _Abi>& __v); +}; + +template <class _Tp, class _NewAbi> +struct __simd_cast_traits<simd<_Tp, _NewAbi>> { + template <class _Up, class _Abi> + static typename std::enable_if< + __is_non_narrowing_arithmetic_convertible<_Up, _Tp>() && + simd<_Up, _Abi>::size() == simd<_Tp, _NewAbi>::size(), + simd<_Tp, _NewAbi>>::type + __apply(const simd<_Up, _Abi>& __v); +}; + +template <class _Tp, class _Up, class _Abi> +auto simd_cast(const simd<_Up, _Abi>& __v) + -> decltype(__simd_cast_traits<_Tp>::__apply(__v)) { + return __simd_cast_traits<_Tp>::__apply(__v); +} + +template <class _Tp, class _Up, class _Abi> +auto static_simd_cast(const simd<_Up, _Abi>& __v) + -> decltype(__static_simd_cast_traits<_Tp>::__apply(__v)) { + return __static_simd_cast_traits<_Tp>::__apply(__v); +} + +template <class _Tp, class _Abi> +fixed_size_simd<_Tp, simd_size<_Tp, _Abi>::value> +to_fixed_size(const simd<_Tp, _Abi>&) noexcept; + +template <class _Tp, class _Abi> +fixed_size_simd_mask<_Tp, simd_size<_Tp, _Abi>::value> +to_fixed_size(const simd_mask<_Tp, _Abi>&) noexcept; + +template <class _Tp, size_t _Np> +native_simd<_Tp> to_native(const fixed_size_simd<_Tp, _Np>&) noexcept; + +template <class _Tp, size_t _Np> +native_simd_mask<_Tp> to_native(const fixed_size_simd_mask<_Tp, _Np>&) noexcept; + +template <class _Tp, size_t _Np> +simd<_Tp> to_compatible(const fixed_size_simd<_Tp, _Np>&) noexcept; + +template <class _Tp, size_t _Np> +simd_mask<_Tp> to_compatible(const fixed_size_simd_mask<_Tp, _Np>&) noexcept; + +template <size_t... __sizes, class _Tp, class _Abi> +tuple<simd<_Tp, abi_for_size_t<_Tp, __sizes>>...> split(const simd<_Tp, _Abi>&); + +template <size_t... __sizes, class _Tp, class _Abi> +tuple<simd_mask<_Tp, abi_for_size_t<_Tp, __sizes>>...> +split(const simd_mask<_Tp, _Abi>&); + +template <class _SimdType, class _Abi> +array<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value / + _SimdType::size()> +split(const simd<typename _SimdType::value_type, _Abi>&); + +template <class _SimdType, class _Abi> +array<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value / + _SimdType::size()> +split(const simd_mask<typename _SimdType::value_type, _Abi>&); + +template <class _Tp, class... _Abis> +simd<_Tp, abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>> +concat(const simd<_Tp, _Abis>&...); + +template <class _Tp, class... _Abis> +simd_mask<_Tp, + abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>> +concat(const simd_mask<_Tp, _Abis>&...); + +// reductions [simd.mask.reductions] +template <class _Tp, class _Abi> +bool all_of(const simd_mask<_Tp, _Abi>&) noexcept; +template <class _Tp, class _Abi> +bool any_of(const simd_mask<_Tp, _Abi>&) noexcept; +template <class _Tp, class _Abi> +bool none_of(const simd_mask<_Tp, _Abi>&) noexcept; +template <class _Tp, class _Abi> +bool some_of(const simd_mask<_Tp, _Abi>&) noexcept; +template <class _Tp, class _Abi> +int popcount(const simd_mask<_Tp, _Abi>&) noexcept; +template <class _Tp, class _Abi> +int find_first_set(const simd_mask<_Tp, _Abi>&); +template <class _Tp, class _Abi> +int find_last_set(const simd_mask<_Tp, _Abi>&); +bool all_of(bool) noexcept; +bool any_of(bool) noexcept; +bool none_of(bool) noexcept; +bool some_of(bool) noexcept; +int popcount(bool) noexcept; +int find_first_set(bool) noexcept; +int find_last_set(bool) noexcept; + +// masked assignment [simd.whereexpr] +template <class _MaskType, class _Tp> +class const_where_expression; +template <class _MaskType, class _Tp> +class where_expression; + +// masked assignment [simd.mask.where] +template <class _Tp, class _Abi> +where_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>> +where(const typename simd<_Tp, _Abi>::mask_type&, simd<_Tp, _Abi>&) noexcept; + +template <class _Tp, class _Abi> +const_where_expression<simd_mask<_Tp, _Abi>, const simd<_Tp, _Abi>> +where(const typename simd<_Tp, _Abi>::mask_type&, + const simd<_Tp, _Abi>&) noexcept; + +template <class _Tp, class _Abi> +where_expression<simd_mask<_Tp, _Abi>, simd_mask<_Tp, _Abi>> +where(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&, + simd_mask<_Tp, _Abi>&) noexcept; + +template <class _Tp, class _Abi> +const_where_expression<simd_mask<_Tp, _Abi>, const simd_mask<_Tp, _Abi>> +where(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&, + const simd_mask<_Tp, _Abi>&) noexcept; + +template <class _Tp> +where_expression<bool, _Tp> where(bool, _Tp&) noexcept; + +template <class _Tp> +const_where_expression<bool, const _Tp> where(bool, const _Tp&) noexcept; + +// reductions [simd.reductions] +template <class _Tp, class _Abi, class _BinaryOp = std::plus<_Tp>> +_Tp reduce(const simd<_Tp, _Abi>&, _BinaryOp = _BinaryOp()); + +template <class _MaskType, class _SimdType, class _BinaryOp> +typename _SimdType::value_type +reduce(const const_where_expression<_MaskType, _SimdType>&, + typename _SimdType::value_type neutral_element, _BinaryOp binary_op); + +template <class _MaskType, class _SimdType> +typename _SimdType::value_type +reduce(const const_where_expression<_MaskType, _SimdType>&, + plus<typename _SimdType::value_type> binary_op = {}); + +template <class _MaskType, class _SimdType> +typename _SimdType::value_type +reduce(const const_where_expression<_MaskType, _SimdType>&, + multiplies<typename _SimdType::value_type> binary_op); + +template <class _MaskType, class _SimdType> +typename _SimdType::value_type +reduce(const const_where_expression<_MaskType, _SimdType>&, + bit_and<typename _SimdType::value_type> binary_op); + +template <class _MaskType, class _SimdType> +typename _SimdType::value_type +reduce(const const_where_expression<_MaskType, _SimdType>&, + bit_or<typename _SimdType::value_type> binary_op); + +template <class _MaskType, class _SimdType> +typename _SimdType::value_type +reduce(const const_where_expression<_MaskType, _SimdType>&, + bit_xor<typename _SimdType::value_type> binary_op); + +template <class _Tp, class _Abi> +_Tp hmin(const simd<_Tp, _Abi>&); +template <class _MaskType, class _SimdType> +typename _SimdType::value_type +hmin(const const_where_expression<_MaskType, _SimdType>&); +template <class _Tp, class _Abi> +_Tp hmax(const simd<_Tp, _Abi>&); +template <class _MaskType, class _SimdType> +typename _SimdType::value_type +hmax(const const_where_expression<_MaskType, _SimdType>&); + +// algorithms [simd.alg] +template <class _Tp, class _Abi> +simd<_Tp, _Abi> min(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept; + +template <class _Tp, class _Abi> +simd<_Tp, _Abi> max(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept; + +template <class _Tp, class _Abi> +std::pair<simd<_Tp, _Abi>, simd<_Tp, _Abi>> +minmax(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept; + +template <class _Tp, class _Abi> +simd<_Tp, _Abi> clamp(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&, + const simd<_Tp, _Abi>&); + +// [simd.whereexpr] +// TODO implement where expressions. +template <class _MaskType, class _Tp> +class const_where_expression { +public: + const_where_expression(const const_where_expression&) = delete; + const_where_expression& operator=(const const_where_expression&) = delete; + typename remove_const<_Tp>::type operator-() const&&; + template <class _Up, class _Flags> + void copy_to(_Up*, _Flags) const&&; +}; + +template <class _MaskType, class _Tp> +class where_expression : public const_where_expression<_MaskType, _Tp> { +public: + where_expression(const where_expression&) = delete; + where_expression& operator=(const where_expression&) = delete; + template <class _Up> + void operator=(_Up&&); + template <class _Up> + void operator+=(_Up&&); + template <class _Up> + void operator-=(_Up&&); + template <class _Up> + void operator*=(_Up&&); + template <class _Up> + void operator/=(_Up&&); + template <class _Up> + void operator%=(_Up&&); + template <class _Up> + void operator&=(_Up&&); + template <class _Up> + void operator|=(_Up&&); + template <class _Up> + void operator^=(_Up&&); + template <class _Up> + void operator<<=(_Up&&); + template <class _Up> + void operator>>=(_Up&&); + void operator++(); + void operator++(int); + void operator--(); + void operator--(int); + template <class _Up, class _Flags> + void copy_from(const _Up*, _Flags); +}; + +// [simd.class] +// TODO: implement simd +template <class _Tp, class _Abi> +class simd { +public: + using value_type = _Tp; + using reference = __simd_reference<_Tp, _Tp, _Abi>; + using mask_type = simd_mask<_Tp, _Abi>; + using abi_type = _Abi; + + simd() = default; + simd(const simd&) = default; + simd& operator=(const simd&) = default; + + static constexpr size_t size() noexcept { + return simd_size<_Tp, _Abi>::value; + } + +private: + __simd_storage<_Tp, _Abi> __s_; + + template <class _Up> + static constexpr bool __can_broadcast() { + return (std::is_arithmetic<_Up>::value && + __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()) || + (!std::is_arithmetic<_Up>::value && + std::is_convertible<_Up, _Tp>::value) || + std::is_same<typename std::remove_const<_Up>::type, int>::value || + (std::is_same<typename std::remove_const<_Up>::type, + unsigned int>::value && + std::is_unsigned<_Tp>::value); + } + + template <class _Generator, size_t... __indicies> + static constexpr decltype( + std::forward_as_tuple(std::declval<_Generator>()( + std::integral_constant<size_t, __indicies>())...), + bool()) + __can_generate(std::index_sequence<__indicies...>) { + return !__variadic_sum<bool>( + !__can_broadcast<decltype(std::declval<_Generator>()( + std::integral_constant<size_t, __indicies>()))>()...); + } + + template <class _Generator> + static bool __can_generate(...) { + return false; + } + + template <class _Generator, size_t... __indicies> + void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) { + int __not_used[]{((*this)[__indicies] = + __g(std::integral_constant<size_t, __indicies>()), + 0)...}; + (void)__not_used; + } + +public: + // implicit type conversion constructor + template <class _Up, + class = typename std::enable_if< + std::is_same<_Abi, simd_abi::fixed_size<size()>>::value && + __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()>::type> + simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) { + for (size_t __i = 0; __i < size(); __i++) { + (*this)[__i] = static_cast<_Tp>(__v[__i]); + } + } + + // implicit broadcast constructor + template <class _Up, + class = typename std::enable_if<__can_broadcast<_Up>()>::type> + simd(_Up&& __rv) { + auto __v = static_cast<_Tp>(__rv); + for (size_t __i = 0; __i < size(); __i++) { + (*this)[__i] = __v; + } + } + + // generator constructor + template <class _Generator, + int = typename std::enable_if< + __can_generate<_Generator>(std::make_index_sequence<size()>()), + int>::type()> + explicit simd(_Generator&& __g) { + __generator_init(std::forward<_Generator>(__g), + std::make_index_sequence<size()>()); + } + + // load constructor + template < + class _Up, class _Flags, + class = typename std::enable_if<__vectorizable<_Up>()>::type, + class = typename std::enable_if<is_simd_flag_type<_Flags>::value>::type> + simd(const _Up* __buffer, _Flags) { + // TODO: optimize for overaligned flags + for (size_t __i = 0; __i < size(); __i++) { + (*this)[__i] = static_cast<_Tp>(__buffer[__i]); + } + } + + // loads [simd.load] + template <class _Up, class _Flags> + typename std::enable_if<__vectorizable<_Up>() && + is_simd_flag_type<_Flags>::value>::type + copy_from(const _Up* __buffer, _Flags) { + *this = simd(__buffer, _Flags()); + } + + // stores [simd.store] + template <class _Up, class _Flags> + typename std::enable_if<__vectorizable<_Up>() && + is_simd_flag_type<_Flags>::value>::type + copy_to(_Up* __buffer, _Flags) const { + // TODO: optimize for overaligned flags + for (size_t __i = 0; __i < size(); __i++) { + __buffer[__i] = static_cast<_Up>((*this)[__i]); + } + } + + // scalar access [simd.subscr] + reference operator[](size_t __i) { return reference(&__s_, __i); } + + value_type operator[](size_t __i) const { return __s_.__get(__i); } + + // unary operators [simd.unary] + simd& operator++(); + simd operator++(int); + simd& operator--(); + simd operator--(int); + mask_type operator!() const; + simd operator~() const; + simd operator+() const; + simd operator-() const; + + // binary operators [simd.binary] + friend simd operator+(const simd&, const simd&); + friend simd operator-(const simd&, const simd&); + friend simd operator*(const simd&, const simd&); + friend simd operator/(const simd&, const simd&); + friend simd operator%(const simd&, const simd&); + friend simd operator&(const simd&, const simd&); + friend simd operator|(const simd&, const simd&); + friend simd operator^(const simd&, const simd&); + friend simd operator<<(const simd&, const simd&); + friend simd operator>>(const simd&, const simd&); + friend simd operator<<(const simd&, int); + friend simd operator>>(const simd&, int); + + // compound assignment [simd.cassign] + friend simd& operator+=(simd&, const simd&); + friend simd& operator-=(simd&, const simd&); + friend simd& operator*=(simd&, const simd&); + friend simd& operator/=(simd&, const simd&); + friend simd& operator%=(simd&, const simd&); + + friend simd& operator&=(simd&, const simd&); + friend simd& operator|=(simd&, const simd&); + friend simd& operator^=(simd&, const simd&); + friend simd& operator<<=(simd&, const simd&); + friend simd& operator>>=(simd&, const simd&); + friend simd& operator<<=(simd&, int); + friend simd& operator>>=(simd&, int); + + // compares [simd.comparison] + friend mask_type operator==(const simd&, const simd&); + friend mask_type operator!=(const simd&, const simd&); + friend mask_type operator>=(const simd&, const simd&); + friend mask_type operator<=(const simd&, const simd&); + friend mask_type operator>(const simd&, const simd&); + friend mask_type operator<(const simd&, const simd&); +}; + +// [simd.mask.class] +template <class _Tp, class _Abi> +// TODO: implement simd_mask +class simd_mask { +public: + using value_type = bool; + // TODO: this is strawman implementation. Turn it into a proxy type. + using reference = bool&; + using simd_type = simd<_Tp, _Abi>; + using abi_type = _Abi; + static constexpr size_t size() noexcept; + simd_mask() = default; + + // broadcast constructor + explicit simd_mask(value_type) noexcept; + + // implicit type conversion constructor + template <class _Up> + simd_mask(const simd_mask<_Up, simd_abi::fixed_size<size()>>&) noexcept; + + // load constructor + template <class _Flags> + simd_mask(const value_type*, _Flags); + + // loads [simd.mask.copy] + template <class _Flags> + void copy_from(const value_type*, _Flags); + template <class _Flags> + void copy_to(value_type*, _Flags) const; + + // scalar access [simd.mask.subscr] + reference operator[](size_t); + value_type operator[](size_t) const; + + // unary operators [simd.mask.unary] + simd_mask operator!() const noexcept; + + // simd_mask binary operators [simd.mask.binary] + friend simd_mask operator&&(const simd_mask&, const simd_mask&) noexcept; + friend simd_mask operator||(const simd_mask&, const simd_mask&) noexcept; + friend simd_mask operator&(const simd_mask&, const simd_mask&)noexcept; + friend simd_mask operator|(const simd_mask&, const simd_mask&) noexcept; + friend simd_mask operator^(const simd_mask&, const simd_mask&) noexcept; + + // simd_mask compound assignment [simd.mask.cassign] + friend simd_mask& operator&=(simd_mask&, const simd_mask&) noexcept; + friend simd_mask& operator|=(simd_mask&, const simd_mask&) noexcept; + friend simd_mask& operator^=(simd_mask&, const simd_mask&) noexcept; + + // simd_mask compares [simd.mask.comparison] + friend simd_mask operator==(const simd_mask&, const simd_mask&) noexcept; + friend simd_mask operator!=(const simd_mask&, const simd_mask&) noexcept; +}; + +#endif // _LIBCPP_STD_VER >= 17 + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD + +#endif /* _LIBCPP_EXPERIMENTAL_SIMD */ diff --git a/lib/libcxx/include/experimental/string_view b/lib/libcxx/include/experimental/string_view index da104f9a121..f13bff54d53 100644 --- a/lib/libcxx/include/experimental/string_view +++ b/lib/libcxx/include/experimental/string_view @@ -8,811 +8,4 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_LFTS_STRING_VIEW -#define _LIBCPP_LFTS_STRING_VIEW - -/* -string_view synopsis - -namespace std { - namespace experimental { - inline namespace library_fundamentals_v1 { - - // 7.2, Class template basic_string_view - template<class charT, class traits = char_traits<charT>> - class basic_string_view; - - // 7.9, basic_string_view non-member comparison functions - template<class charT, class traits> - constexpr bool operator==(basic_string_view<charT, traits> x, - basic_string_view<charT, traits> y) noexcept; - template<class charT, class traits> - constexpr bool operator!=(basic_string_view<charT, traits> x, - basic_string_view<charT, traits> y) noexcept; - template<class charT, class traits> - constexpr bool operator< (basic_string_view<charT, traits> x, - basic_string_view<charT, traits> y) noexcept; - template<class charT, class traits> - constexpr bool operator> (basic_string_view<charT, traits> x, - basic_string_view<charT, traits> y) noexcept; - template<class charT, class traits> - constexpr bool operator<=(basic_string_view<charT, traits> x, - basic_string_view<charT, traits> y) noexcept; - template<class charT, class traits> - constexpr bool operator>=(basic_string_view<charT, traits> x, - basic_string_view<charT, traits> y) noexcept; - // see below, sufficient additional overloads of comparison functions - - // 7.10, Inserters and extractors - template<class charT, class traits> - basic_ostream<charT, traits>& - operator<<(basic_ostream<charT, traits>& os, - basic_string_view<charT, traits> str); - - // basic_string_view typedef names - typedef basic_string_view<char> string_view; - typedef basic_string_view<char16_t> u16string_view; - typedef basic_string_view<char32_t> u32string_view; - typedef basic_string_view<wchar_t> wstring_view; - - template<class charT, class traits = char_traits<charT>> - class basic_string_view { - public: - // types - typedef traits traits_type; - typedef charT value_type; - typedef charT* pointer; - typedef const charT* const_pointer; - typedef charT& reference; - typedef const charT& const_reference; - typedef implementation-defined const_iterator; - typedef const_iterator iterator; - typedef reverse_iterator<const_iterator> const_reverse_iterator; - typedef const_reverse_iterator reverse_iterator; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - static constexpr size_type npos = size_type(-1); - - // 7.3, basic_string_view constructors and assignment operators - constexpr basic_string_view() noexcept; - constexpr basic_string_view(const basic_string_view&) noexcept = default; - basic_string_view& operator=(const basic_string_view&) noexcept = default; - template<class Allocator> - basic_string_view(const basic_string<charT, traits, Allocator>& str) noexcept; - constexpr basic_string_view(const charT* str); - constexpr basic_string_view(const charT* str, size_type len); - - // 7.4, basic_string_view iterator support - constexpr const_iterator begin() const noexcept; - constexpr const_iterator end() const noexcept; - constexpr const_iterator cbegin() const noexcept; - constexpr const_iterator cend() const noexcept; - const_reverse_iterator rbegin() const noexcept; - const_reverse_iterator rend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; - - // 7.5, basic_string_view capacity - constexpr size_type size() const noexcept; - constexpr size_type length() const noexcept; - constexpr size_type max_size() const noexcept; - constexpr bool empty() const noexcept; - - // 7.6, basic_string_view element access - constexpr const_reference operator[](size_type pos) const; - constexpr const_reference at(size_type pos) const; - constexpr const_reference front() const; - constexpr const_reference back() const; - constexpr const_pointer data() const noexcept; - - // 7.7, basic_string_view modifiers - constexpr void clear() noexcept; - constexpr void remove_prefix(size_type n); - constexpr void remove_suffix(size_type n); - constexpr void swap(basic_string_view& s) noexcept; - - // 7.8, basic_string_view string operations - template<class Allocator> - explicit operator basic_string<charT, traits, Allocator>() const; - template<class Allocator = allocator<charT>> - basic_string<charT, traits, Allocator> to_string( - const Allocator& a = Allocator()) const; - - size_type copy(charT* s, size_type n, size_type pos = 0) const; - - constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; - constexpr int compare(basic_string_view s) const noexcept; - constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const; - constexpr int compare(size_type pos1, size_type n1, - basic_string_view s, size_type pos2, size_type n2) const; - constexpr int compare(const charT* s) const; - constexpr int compare(size_type pos1, size_type n1, const charT* s) const; - constexpr int compare(size_type pos1, size_type n1, - const charT* s, size_type n2) const; - constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept; - constexpr size_type find(charT c, size_type pos = 0) const noexcept; - constexpr size_type find(const charT* s, size_type pos, size_type n) const; - constexpr size_type find(const charT* s, size_type pos = 0) const; - constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept; - constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; - constexpr size_type rfind(const charT* s, size_type pos, size_type n) const; - constexpr size_type rfind(const charT* s, size_type pos = npos) const; - constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept; - constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; - constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const; - constexpr size_type find_first_of(const charT* s, size_type pos = 0) const; - constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept; - constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; - constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const; - constexpr size_type find_last_of(const charT* s, size_type pos = npos) const; - constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept; - constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; - constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; - constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const; - constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept; - constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; - constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; - constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; - - private: - const_pointer data_; // exposition only - size_type size_; // exposition only - }; - - } // namespace fundamentals_v1 - } // namespace experimental - - // 7.11, Hash support - template <class T> struct hash; - template <> struct hash<experimental::string_view>; - template <> struct hash<experimental::u16string_view>; - template <> struct hash<experimental::u32string_view>; - template <> struct hash<experimental::wstring_view>; - -} // namespace std - - -*/ - -#include <experimental/__config> - -#include <string> -#include <algorithm> -#include <iterator> -#include <ostream> -#include <stdexcept> -#include <iomanip> - -#include <__debug> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -_LIBCPP_BEGIN_NAMESPACE_LFTS - - template<class _CharT, class _Traits = _VSTD::char_traits<_CharT> > - class _LIBCPP_TEMPLATE_VIS basic_string_view { - public: - // types - typedef _Traits traits_type; - typedef _CharT value_type; - typedef const _CharT* pointer; - typedef const _CharT* const_pointer; - typedef const _CharT& reference; - typedef const _CharT& const_reference; - typedef const_pointer const_iterator; // See [string.view.iterators] - typedef const_iterator iterator; - typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; - typedef const_reverse_iterator reverse_iterator; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1); - - // [string.view.cons], construct/copy - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {} - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - basic_string_view(const basic_string_view&) _NOEXCEPT = default; - - _LIBCPP_INLINE_VISIBILITY - basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default; - - template<class _Allocator> - _LIBCPP_INLINE_VISIBILITY - basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& __str) _NOEXCEPT - : __data (__str.data()), __size(__str.size()) {} - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - basic_string_view(const _CharT* __s, size_type __len) - : __data(__s), __size(__len) - { -// _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr"); - } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - basic_string_view(const _CharT* __s) - : __data(__s), __size(_Traits::length(__s)) {} - - // [string.view.iterators], iterators - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT { return cbegin(); } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT { return cend(); } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT { return __data; } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT { return __data + __size; } - - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } - - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } - - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } - - _LIBCPP_INLINE_VISIBILITY - const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } - - // [string.view.capacity], capacity - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT { return __size; } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - size_type length() const _NOEXCEPT { return __size; } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT { return _VSTD::numeric_limits<size_type>::max(); } - - _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY - empty() const _NOEXCEPT { return __size == 0; } - - // [string.view.access], element access - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - const_reference operator[](size_type __pos) const { return __data[__pos]; } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - const_reference at(size_type __pos) const - { - return __pos >= size() - ? (__throw_out_of_range("string_view::at"), __data[0]) - : __data[__pos]; - } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - const_reference front() const - { - return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0]; - } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - const_reference back() const - { - return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1]; - } - - _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - const_pointer data() const _NOEXCEPT { return __data; } - - // [string.view.modifiers], modifiers: - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT - { - __data = nullptr; - __size = 0; - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - void remove_prefix(size_type __n) _NOEXCEPT - { - _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()"); - __data += __n; - __size -= __n; - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - void remove_suffix(size_type __n) _NOEXCEPT - { - _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()"); - __size -= __n; - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - void swap(basic_string_view& __other) _NOEXCEPT - { - const value_type *__p = __data; - __data = __other.__data; - __other.__data = __p; - - size_type __sz = __size; - __size = __other.__size; - __other.__size = __sz; -// _VSTD::swap( __data, __other.__data ); -// _VSTD::swap( __size, __other.__size ); - } - - // [string.view.ops], string operations: - template<class _Allocator> - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator basic_string<_CharT, _Traits, _Allocator>() const - { return basic_string<_CharT, _Traits, _Allocator>( begin(), end()); } - - template<class _Allocator = allocator<_CharT> > - _LIBCPP_INLINE_VISIBILITY - basic_string<_CharT, _Traits, _Allocator> - to_string( const _Allocator& __a = _Allocator()) const - { return basic_string<_CharT, _Traits, _Allocator> ( begin(), end(), __a ); } - - size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const - { - if ( __pos > size()) - __throw_out_of_range("string_view::copy"); - size_type __rlen = _VSTD::min( __n, size() - __pos ); - _VSTD::copy_n(begin() + __pos, __rlen, __s ); - return __rlen; - } - - _LIBCPP_CONSTEXPR - basic_string_view substr(size_type __pos = 0, size_type __n = npos) const - { -// if (__pos > size()) -// __throw_out_of_range("string_view::substr"); -// size_type __rlen = _VSTD::min( __n, size() - __pos ); -// return basic_string_view(data() + __pos, __rlen); - return __pos > size() - ? (__throw_out_of_range("string_view::substr"), basic_string_view()) - : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT - { - size_type __rlen = _VSTD::min( size(), __sv.size()); - int __retval = _Traits::compare(data(), __sv.data(), __rlen); - if ( __retval == 0 ) // first __rlen chars matched - __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 ); - return __retval; - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const - { - return substr(__pos1, __n1).compare(__sv); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - int compare( size_type __pos1, size_type __n1, - basic_string_view _sv, size_type __pos2, size_type __n2) const - { - return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2)); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - int compare(const _CharT* __s) const - { - return compare(basic_string_view(__s)); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - int compare(size_type __pos1, size_type __n1, const _CharT* __s) const - { - return substr(__pos1, __n1).compare(basic_string_view(__s)); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const - { - return substr(__pos1, __n1).compare(basic_string_view(__s, __n2)); - } - - // find - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT - { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); - return _VSTD::__str_find<value_type, size_type, traits_type, npos> - (data(), size(), __s.data(), __pos, __s.size()); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT - { - return _VSTD::__str_find<value_type, size_type, traits_type, npos> - (data(), size(), __c, __pos); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find(const _CharT* __s, size_type __pos, size_type __n) const - { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); - return _VSTD::__str_find<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, __n); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find(const _CharT* __s, size_type __pos = 0) const - { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); - return _VSTD::__str_find<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, traits_type::length(__s)); - } - - // rfind - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT - { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> - (data(), size(), __s.data(), __pos, __s.size()); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT - { - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> - (data(), size(), __c, __pos); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const - { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, __n); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type rfind(const _CharT* __s, size_type __pos=npos) const - { - _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr"); - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, traits_type::length(__s)); - } - - // find_first_of - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT - { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr"); - return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> - (data(), size(), __s.data(), __pos, __s.size()); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT - { return find(__c, __pos); } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const - { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); - return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, __n); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_first_of(const _CharT* __s, size_type __pos=0) const - { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr"); - return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, traits_type::length(__s)); - } - - // find_last_of - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT - { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr"); - return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> - (data(), size(), __s.data(), __pos, __s.size()); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT - { return rfind(__c, __pos); } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const - { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); - return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, __n); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_last_of(const _CharT* __s, size_type __pos=npos) const - { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr"); - return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, traits_type::length(__s)); - } - - // find_first_not_of - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT - { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr"); - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> - (data(), size(), __s.data(), __pos, __s.size()); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT - { - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> - (data(), size(), __c, __pos); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const - { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, __n); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const - { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, traits_type::length(__s)); - } - - // find_last_not_of - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT - { - _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr"); - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> - (data(), size(), __s.data(), __pos, __s.size()); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT - { - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> - (data(), size(), __c, __pos); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const - { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, __n); - } - - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const - { - _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> - (data(), size(), __s, __pos, traits_type::length(__s)); - } - - private: - const value_type* __data; - size_type __size; - }; - - - // [string.view.comparison] - // operator == - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator==(basic_string_view<_CharT, _Traits> __lhs, - basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - if ( __lhs.size() != __rhs.size()) return false; - return __lhs.compare(__rhs) == 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator==(basic_string_view<_CharT, _Traits> __lhs, - typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT - { - if ( __lhs.size() != __rhs.size()) return false; - return __lhs.compare(__rhs) == 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator==(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, - basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - if ( __lhs.size() != __rhs.size()) return false; - return __lhs.compare(__rhs) == 0; - } - - - // operator != - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - if ( __lhs.size() != __rhs.size()) - return true; - return __lhs.compare(__rhs) != 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator!=(basic_string_view<_CharT, _Traits> __lhs, - typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT - { - if ( __lhs.size() != __rhs.size()) - return true; - return __lhs.compare(__rhs) != 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator!=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, - basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - if ( __lhs.size() != __rhs.size()) - return true; - return __lhs.compare(__rhs) != 0; - } - - - // operator < - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) < 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator<(basic_string_view<_CharT, _Traits> __lhs, - typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) < 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator<(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, - basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) < 0; - } - - - // operator > - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) > 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator>(basic_string_view<_CharT, _Traits> __lhs, - typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) > 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator>(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, - basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) > 0; - } - - - // operator <= - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) <= 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator<=(basic_string_view<_CharT, _Traits> __lhs, - typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) <= 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator<=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, - basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) <= 0; - } - - - // operator >= - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) >= 0; - } - - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator>=(basic_string_view<_CharT, _Traits> __lhs, - typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) >= 0; - } - - template<class _CharT, class _Traits> - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY - bool operator>=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, - basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT - { - return __lhs.compare(__rhs) >= 0; - } - - - // [string.view.io] - template<class _CharT, class _Traits> - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv) - { - return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size()); - } - - typedef basic_string_view<char> string_view; - typedef basic_string_view<char16_t> u16string_view; - typedef basic_string_view<char32_t> u32string_view; - typedef basic_string_view<wchar_t> wstring_view; - -_LIBCPP_END_NAMESPACE_LFTS -_LIBCPP_BEGIN_NAMESPACE_STD - -// [string.view.hash] -// Shamelessly stolen from <string> -template<class _CharT, class _Traits> -struct _LIBCPP_TEMPLATE_VIS hash<std::experimental::basic_string_view<_CharT, _Traits> > - : public unary_function<std::experimental::basic_string_view<_CharT, _Traits>, size_t> -{ - size_t operator()(const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT; -}; - -template<class _CharT, class _Traits> -size_t -hash<std::experimental::basic_string_view<_CharT, _Traits> >::operator()( - const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT -{ - return __do_string_hash(__val.data(), __val.data() + __val.size()); -} - -#if _LIBCPP_STD_VER > 11 -template <class _CharT, class _Traits> -__quoted_output_proxy<_CharT, const _CharT *, _Traits> -quoted ( std::experimental::basic_string_view <_CharT, _Traits> __sv, - _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) -{ - return __quoted_output_proxy<_CharT, const _CharT *, _Traits> - ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape ); -} -#endif - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS - -#endif // _LIBCPP_LFTS_STRING_VIEW +#error "<experimental/string_view> has been removed. Use <string_view> instead." diff --git a/lib/libcxx/include/experimental/system_error b/lib/libcxx/include/experimental/system_error index 2ec23854461..7937357fa14 100644 --- a/lib/libcxx/include/experimental/system_error +++ b/lib/libcxx/include/experimental/system_error @@ -8,56 +8,4 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR -#define _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR - -/** - experimental/system_error synopsis - -// C++1y - -#include <system_error> - -namespace std { -namespace experimental { -inline namespace fundamentals_v1 { - - // See C++14 19.5, System error support - template <class T> constexpr bool is_error_code_enum_v - = is_error_code_enum<T>::value; - template <class T> constexpr bool is_error_condition_enum_v - = is_error_condition_enum<T>::value; - -} // namespace fundamentals_v1 -} // namespace experimental -} // namespace std - -*/ - -#include <experimental/__config> - -#if _LIBCPP_STD_VER > 11 - -#include <system_error> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_LFTS - -#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_error_code_enum_v - = is_error_code_enum<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_error_condition_enum_v - = is_error_condition_enum<_Tp>::value; - -#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */ - -_LIBCPP_END_NAMESPACE_LFTS - -#endif /* _LIBCPP_STD_VER > 11 */ - -#endif /* _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR */ +#error "<experimental/system_error> has been removed. Use <system_error> instead." diff --git a/lib/libcxx/include/experimental/tuple b/lib/libcxx/include/experimental/tuple index e00d2ec1a92..1f37a6293ba 100644 --- a/lib/libcxx/include/experimental/tuple +++ b/lib/libcxx/include/experimental/tuple @@ -8,75 +8,4 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL_TUPLE -#define _LIBCPP_EXPERIMENTAL_TUPLE - -/* - experimental/tuple synopsis - -// C++1y - -#include <tuple> - -namespace std { -namespace experimental { -inline namespace fundamentals_v1 { - - // See C++14 20.4.2.5, tuple helper classes - template <class T> constexpr size_t tuple_size_v - = tuple_size<T>::value; - - // 3.2.2, Calling a function with a tuple of arguments - template <class F, class Tuple> - constexpr decltype(auto) apply(F&& f, Tuple&& t); - -} // namespace fundamentals_v1 -} // namespace experimental -} // namespace std - - */ - -# include <experimental/__config> - -#if _LIBCPP_STD_VER > 11 - -# include <tuple> -# include <utility> -# include <__functional_base> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_LFTS - -#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES -template <class _Tp> -_LIBCPP_CONSTEXPR size_t tuple_size_v = tuple_size<_Tp>::value; -#endif - -template <class _Fn, class _Tuple, size_t ..._Id> -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX11 -decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, - integer_sequence<size_t, _Id...>) { - return _VSTD::__invoke_constexpr( - _VSTD::forward<_Fn>(__f), - _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))... - ); -} - -template <class _Fn, class _Tuple> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -decltype(auto) apply(_Fn && __f, _Tuple && __t) { - return _VSTD_LFTS::__apply_tuple_impl( - _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t), - make_index_sequence<tuple_size<typename decay<_Tuple>::type>::value>() - ); -} - -_LIBCPP_END_NAMESPACE_LFTS - -#endif /* _LIBCPP_STD_VER > 11 */ - -#endif /* _LIBCPP_EXPERIMENTAL_TUPLE */ +#error "<experimental/tuple> has been removed. Use <tuple> instead." diff --git a/lib/libcxx/include/experimental/type_traits b/lib/libcxx/include/experimental/type_traits index 3a7593620a7..afe491567ce 100644 --- a/lib/libcxx/include/experimental/type_traits +++ b/lib/libcxx/include/experimental/type_traits @@ -21,146 +21,6 @@ namespace std { namespace experimental { inline namespace fundamentals_v1 { - // See C++14 20.10.4.1, primary type categories - template <class T> constexpr bool is_void_v - = is_void<T>::value; - template <class T> constexpr bool is_null_pointer_v - = is_null_pointer<T>::value; - template <class T> constexpr bool is_integral_v - = is_integral<T>::value; - template <class T> constexpr bool is_floating_point_v - = is_floating_point<T>::value; - template <class T> constexpr bool is_array_v - = is_array<T>::value; - template <class T> constexpr bool is_pointer_v - = is_pointer<T>::value; - template <class T> constexpr bool is_lvalue_reference_v - = is_lvalue_reference<T>::value; - template <class T> constexpr bool is_rvalue_reference_v - = is_rvalue_reference<T>::value; - template <class T> constexpr bool is_member_object_pointer_v - = is_member_object_pointer<T>::value; - template <class T> constexpr bool is_member_function_pointer_v - = is_member_function_pointer<T>::value; - template <class T> constexpr bool is_enum_v - = is_enum<T>::value; - template <class T> constexpr bool is_union_v - = is_union<T>::value; - template <class T> constexpr bool is_class_v - = is_class<T>::value; - template <class T> constexpr bool is_function_v - = is_function<T>::value; - - // See C++14 20.10.4.2, composite type categories - template <class T> constexpr bool is_reference_v - = is_reference<T>::value; - template <class T> constexpr bool is_arithmetic_v - = is_arithmetic<T>::value; - template <class T> constexpr bool is_fundamental_v - = is_fundamental<T>::value; - template <class T> constexpr bool is_object_v - = is_object<T>::value; - template <class T> constexpr bool is_scalar_v - = is_scalar<T>::value; - template <class T> constexpr bool is_compound_v - = is_compound<T>::value; - template <class T> constexpr bool is_member_pointer_v - = is_member_pointer<T>::value; - - // See C++14 20.10.4.3, type properties - template <class T> constexpr bool is_const_v - = is_const<T>::value; - template <class T> constexpr bool is_volatile_v - = is_volatile<T>::value; - template <class T> constexpr bool is_trivial_v - = is_trivial<T>::value; - template <class T> constexpr bool is_trivially_copyable_v - = is_trivially_copyable<T>::value; - template <class T> constexpr bool is_standard_layout_v - = is_standard_layout<T>::value; - template <class T> constexpr bool is_pod_v - = is_pod<T>::value; - template <class T> constexpr bool is_literal_type_v - = is_literal_type<T>::value; - template <class T> constexpr bool is_empty_v - = is_empty<T>::value; - template <class T> constexpr bool is_polymorphic_v - = is_polymorphic<T>::value; - template <class T> constexpr bool is_abstract_v - = is_abstract<T>::value; - template <class T> constexpr bool is_final_v - = is_final<T>::value; - template <class T> constexpr bool is_signed_v - = is_signed<T>::value; - template <class T> constexpr bool is_unsigned_v - = is_unsigned<T>::value; - template <class T, class... Args> constexpr bool is_constructible_v - = is_constructible<T, Args...>::value; - template <class T> constexpr bool is_default_constructible_v - = is_default_constructible<T>::value; - template <class T> constexpr bool is_copy_constructible_v - = is_copy_constructible<T>::value; - template <class T> constexpr bool is_move_constructible_v - = is_move_constructible<T>::value; - template <class T, class U> constexpr bool is_assignable_v - = is_assignable<T, U>::value; - template <class T> constexpr bool is_copy_assignable_v - = is_copy_assignable<T>::value; - template <class T> constexpr bool is_move_assignable_v - = is_move_assignable<T>::value; - template <class T> constexpr bool is_destructible_v - = is_destructible<T>::value; - template <class T, class... Args> constexpr bool is_trivially_constructible_v - = is_trivially_constructible<T, Args...>::value; - template <class T> constexpr bool is_trivially_default_constructible_v - = is_trivially_default_constructible<T>::value; - template <class T> constexpr bool is_trivially_copy_constructible_v - = is_trivially_copy_constructible<T>::value; - template <class T> constexpr bool is_trivially_move_constructible_v - = is_trivially_move_constructible<T>::value; - template <class T, class U> constexpr bool is_trivially_assignable_v - = is_trivially_assignable<T, U>::value; - template <class T> constexpr bool is_trivially_copy_assignable_v - = is_trivially_copy_assignable<T>::value; - template <class T> constexpr bool is_trivially_move_assignable_v - = is_trivially_move_assignable<T>::value; - template <class T> constexpr bool is_trivially_destructible_v - = is_trivially_destructible<T>::value; - template <class T, class... Args> constexpr bool is_nothrow_constructible_v - = is_nothrow_constructible<T, Args...>::value; - template <class T> constexpr bool is_nothrow_default_constructible_v - = is_nothrow_default_constructible<T>::value; - template <class T> constexpr bool is_nothrow_copy_constructible_v - = is_nothrow_copy_constructible<T>::value; - template <class T> constexpr bool is_nothrow_move_constructible_v - = is_nothrow_move_constructible<T>::value; - template <class T, class U> constexpr bool is_nothrow_assignable_v - = is_nothrow_assignable<T, U>::value; - template <class T> constexpr bool is_nothrow_copy_assignable_v - = is_nothrow_copy_assignable<T>::value; - template <class T> constexpr bool is_nothrow_move_assignable_v - = is_nothrow_move_assignable<T>::value; - template <class T> constexpr bool is_nothrow_destructible_v - = is_nothrow_destructible<T>::value; - template <class T> constexpr bool has_virtual_destructor_v - = has_virtual_destructor<T>::value; - - // See C++14 20.10.5, type property queries - template <class T> constexpr size_t alignment_of_v - = alignment_of<T>::value; - template <class T> constexpr size_t rank_v - = rank<T>::value; - template <class T, unsigned I = 0> constexpr size_t extent_v - = extent<T, I>::value; - - // See C++14 20.10.6, type relations - template <class T, class U> constexpr bool is_same_v - = is_same<T, U>::value; - template <class Base, class Derived> constexpr bool is_base_of_v - = is_base_of<Base, Derived>::value; - template <class From, class To> constexpr bool is_convertible_v - = is_convertible<From, To>::value; - // 3.3.2, Other type transformations template <class> class invocation_type; // not defined template <class F, class... ArgTypes> class invocation_type<F(ArgTypes...)>; @@ -172,14 +32,6 @@ inline namespace fundamentals_v1 { template <class T> using raw_invocation_type_t = typename raw_invocation_type<T>::type; - // 3.3.3, Logical operator traits - template<class... B> struct conjunction; - template<class... B> constexpr bool conjunction_v = conjunction<B...>::value; - template<class... B> struct disjunction; - template<class... B> constexpr bool disjunction_v = disjunction<B...>::value; - template<class B> struct negation; - template<class B> constexpr bool negation_v = negation<B>::value; - // 3.3.4, Detection idiom template <class...> using void_t = void; @@ -229,215 +81,6 @@ inline namespace fundamentals_v1 { _LIBCPP_BEGIN_NAMESPACE_LFTS -#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES - -// C++14 20.10.4.1, primary type categories - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_void_v - = is_void<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_null_pointer_v - = is_null_pointer<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_integral_v - = is_integral<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_floating_point_v - = is_floating_point<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_array_v - = is_array<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_pointer_v - = is_pointer<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_lvalue_reference_v - = is_lvalue_reference<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_rvalue_reference_v - = is_rvalue_reference<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_member_object_pointer_v - = is_member_object_pointer<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_member_function_pointer_v - = is_member_function_pointer<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_enum_v - = is_enum<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_union_v - = is_union<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_class_v - = is_class<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_function_v - = is_function<_Tp>::value; - -// C++14 20.10.4.2, composite type categories - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_reference_v - = is_reference<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_arithmetic_v - = is_arithmetic<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_fundamental_v - = is_fundamental<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_object_v - = is_object<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_scalar_v - = is_scalar<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_compound_v - = is_compound<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_member_pointer_v - = is_member_pointer<_Tp>::value; - -// C++14 20.10.4.3, type properties - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_const_v - = is_const<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_volatile_v - = is_volatile<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivial_v - = is_trivial<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copyable_v - = is_trivially_copyable<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_standard_layout_v - = is_standard_layout<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_pod_v - = is_pod<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_literal_type_v - = is_literal_type<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_empty_v - = is_empty<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_polymorphic_v - = is_polymorphic<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_abstract_v - = is_abstract<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_final_v - = is_final<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_signed_v - = is_signed<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_unsigned_v - = is_unsigned<_Tp>::value; - -template <class _Tp, class ..._Ts> _LIBCPP_CONSTEXPR bool is_constructible_v - = is_constructible<_Tp, _Ts...>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_default_constructible_v - = is_default_constructible<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_copy_constructible_v - = is_copy_constructible<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_move_constructible_v - = is_move_constructible<_Tp>::value; - -template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_assignable_v - = is_assignable<_Tp, _Up>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_copy_assignable_v - = is_copy_assignable<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_move_assignable_v - = is_move_assignable<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_destructible_v - = is_destructible<_Tp>::value; - -template <class _Tp, class ..._Ts> _LIBCPP_CONSTEXPR bool is_trivially_constructible_v - = is_trivially_constructible<_Tp, _Ts...>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_default_constructible_v - = is_trivially_default_constructible<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copy_constructible_v - = is_trivially_copy_constructible<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_move_constructible_v - = is_trivially_move_constructible<_Tp>::value; - -template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_trivially_assignable_v - = is_trivially_assignable<_Tp, _Up>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_copy_assignable_v - = is_trivially_copy_assignable<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_move_assignable_v - = is_trivially_move_assignable<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivially_destructible_v - = is_trivially_destructible<_Tp>::value; - -template <class _Tp, class ..._Ts> _LIBCPP_CONSTEXPR bool is_nothrow_constructible_v - = is_nothrow_constructible<_Tp, _Ts...>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_default_constructible_v - = is_nothrow_default_constructible<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_copy_constructible_v - = is_nothrow_copy_constructible<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_move_constructible_v - = is_nothrow_move_constructible<_Tp>::value; - -template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_nothrow_assignable_v - = is_nothrow_assignable<_Tp, _Up>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_copy_assignable_v - = is_nothrow_copy_assignable<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_move_assignable_v - = is_nothrow_move_assignable<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool is_nothrow_destructible_v - = is_nothrow_destructible<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR bool has_virtual_destructor_v - = has_virtual_destructor<_Tp>::value; - -// C++14 20.10.5, type properties queries - -template <class _Tp> _LIBCPP_CONSTEXPR size_t alignment_of_v - = alignment_of<_Tp>::value; - -template <class _Tp> _LIBCPP_CONSTEXPR size_t rank_v - = rank<_Tp>::value; - -template <class _Tp, unsigned _Id = 0> _LIBCPP_CONSTEXPR size_t extent_v - = extent<_Tp, _Id>::value; - -// C++14 20.10.6, type relations - -template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_same_v - = is_same<_Tp, _Up>::value; - -template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_base_of_v - = is_base_of<_Tp, _Up>::value; - -template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_convertible_v - = is_convertible<_Tp, _Up>::value; - -#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */ - // 3.3.2, Other type transformations /* template <class> @@ -459,24 +102,6 @@ template <class _Tp> using raw_invocation_type_t = typename raw_invocation_type<_Tp>::type; */ -// 3.3.3, Logical operator traits -template <class...> using void_t = void; - -template <class... _Args> -struct conjunction : _VSTD::__and_<_Args...> {}; -template <class... _Args> -_LIBCPP_CONSTEXPR bool conjunction_v = conjunction<_Args...>::value; - -template <class... _Args> -struct disjunction : _VSTD::__or_<_Args...> {}; -template <class... _Args> -_LIBCPP_CONSTEXPR bool disjunction_v = disjunction<_Args...>::value; - -template <class _Tp> -struct negation : _VSTD::__not_<_Tp> {}; -template<class _Tp> -_LIBCPP_CONSTEXPR bool negation_v = negation<_Tp>::value; - // 3.3.4, Detection idiom template <class...> using void_t = void; diff --git a/lib/libcxx/include/filesystem b/lib/libcxx/include/filesystem new file mode 100644 index 00000000000..aa1d7180072 --- /dev/null +++ b/lib/libcxx/include/filesystem @@ -0,0 +1,2682 @@ +// -*- C++ -*- +//===--------------------------- filesystem -------------------------------===// +// +// 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_FILESYSTEM +#define _LIBCPP_FILESYSTEM +/* + filesystem synopsis + + namespace std { namespace filesystem { + + class path; + + void swap(path& lhs, path& rhs) noexcept; + size_t hash_value(const path& p) noexcept; + + bool operator==(const path& lhs, const path& rhs) noexcept; + bool operator!=(const path& lhs, const path& rhs) noexcept; + bool operator< (const path& lhs, const path& rhs) noexcept; + bool operator<=(const path& lhs, const path& rhs) noexcept; + bool operator> (const path& lhs, const path& rhs) noexcept; + bool operator>=(const path& lhs, const path& rhs) noexcept; + + path operator/ (const path& lhs, const path& rhs); + + // fs.path.io operators are friends of path. + template <class charT, class traits> + friend basic_ostream<charT, traits>& + operator<<(basic_ostream<charT, traits>& os, const path& p); + + template <class charT, class traits> + friend basic_istream<charT, traits>& + operator>>(basic_istream<charT, traits>& is, path& p); + + template <class Source> + path u8path(const Source& source); + template <class InputIterator> + path u8path(InputIterator first, InputIterator last); + + class filesystem_error; + class directory_entry; + + class directory_iterator; + + // enable directory_iterator range-based for statements + directory_iterator begin(directory_iterator iter) noexcept; + directory_iterator end(const directory_iterator&) noexcept; + + class recursive_directory_iterator; + + // enable recursive_directory_iterator range-based for statements + recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; + recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; + + class file_status; + + struct space_info + { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; + }; + + enum class file_type; + enum class perms; + enum class perm_options; + enum class copy_options; + enum class directory_options; + + typedef chrono::time_point<trivial-clock> file_time_type; + + // operational functions + + path absolute(const path& p); + path absolute(const path& p, error_code &ec); + + path canonical(const path& p); + path canonical(const path& p, error_code& ec); + + void copy(const path& from, const path& to); + void copy(const path& from, const path& to, error_code& ec); + void copy(const path& from, const path& to, copy_options options); + void copy(const path& from, const path& to, copy_options options, + error_code& ec); + + bool copy_file(const path& from, const path& to); + bool copy_file(const path& from, const path& to, error_code& ec); + bool copy_file(const path& from, const path& to, copy_options option); + bool copy_file(const path& from, const path& to, copy_options option, + error_code& ec); + + void copy_symlink(const path& existing_symlink, const path& new_symlink); + void copy_symlink(const path& existing_symlink, const path& new_symlink, + error_code& ec) noexcept; + + bool create_directories(const path& p); + bool create_directories(const path& p, error_code& ec); + + bool create_directory(const path& p); + bool create_directory(const path& p, error_code& ec) noexcept; + + bool create_directory(const path& p, const path& attributes); + bool create_directory(const path& p, const path& attributes, + error_code& ec) noexcept; + + void create_directory_symlink(const path& to, const path& new_symlink); + void create_directory_symlink(const path& to, const path& new_symlink, + error_code& ec) noexcept; + + void create_hard_link(const path& to, const path& new_hard_link); + void create_hard_link(const path& to, const path& new_hard_link, + error_code& ec) noexcept; + + void create_symlink(const path& to, const path& new_symlink); + void create_symlink(const path& to, const path& new_symlink, + error_code& ec) noexcept; + + path current_path(); + path current_path(error_code& ec); + void current_path(const path& p); + void current_path(const path& p, error_code& ec) noexcept; + + bool exists(file_status s) noexcept; + bool exists(const path& p); + bool exists(const path& p, error_code& ec) noexcept; + + bool equivalent(const path& p1, const path& p2); + bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept; + + uintmax_t file_size(const path& p); + uintmax_t file_size(const path& p, error_code& ec) noexcept; + + uintmax_t hard_link_count(const path& p); + uintmax_t hard_link_count(const path& p, error_code& ec) noexcept; + + bool is_block_file(file_status s) noexcept; + bool is_block_file(const path& p); + bool is_block_file(const path& p, error_code& ec) noexcept; + + bool is_character_file(file_status s) noexcept; + bool is_character_file(const path& p); + bool is_character_file(const path& p, error_code& ec) noexcept; + + bool is_directory(file_status s) noexcept; + bool is_directory(const path& p); + bool is_directory(const path& p, error_code& ec) noexcept; + + bool is_empty(const path& p); + bool is_empty(const path& p, error_code& ec) noexcept; + + bool is_fifo(file_status s) noexcept; + bool is_fifo(const path& p); + bool is_fifo(const path& p, error_code& ec) noexcept; + + bool is_other(file_status s) noexcept; + bool is_other(const path& p); + bool is_other(const path& p, error_code& ec) noexcept; + + bool is_regular_file(file_status s) noexcept; + bool is_regular_file(const path& p); + bool is_regular_file(const path& p, error_code& ec) noexcept; + + bool is_socket(file_status s) noexcept; + bool is_socket(const path& p); + bool is_socket(const path& p, error_code& ec) noexcept; + + bool is_symlink(file_status s) noexcept; + bool is_symlink(const path& p); + bool is_symlink(const path& p, error_code& ec) noexcept; + + file_time_type last_write_time(const path& p); + file_time_type last_write_time(const path& p, error_code& ec) noexcept; + void last_write_time(const path& p, file_time_type new_time); + void last_write_time(const path& p, file_time_type new_time, + 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; + + uintmax_t remove_all(const path& p); + uintmax_t remove_all(const path& p, error_code& ec); + + void rename(const path& from, const path& to); + void rename(const path& from, const path& to, error_code& ec) noexcept; + + void resize_file(const path& p, uintmax_t size); + void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept; + + space_info space(const path& p); + space_info space(const path& p, error_code& ec) noexcept; + + file_status status(const path& p); + file_status status(const path& p, error_code& ec) noexcept; + + bool status_known(file_status s) noexcept; + + file_status symlink_status(const path& p); + file_status symlink_status(const path& p, error_code& ec) noexcept; + + 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::filesystem + +*/ + +#include <__config> +#include <cstddef> +#include <cstdlib> +#include <chrono> +#include <iterator> +#include <iosfwd> +#include <locale> +#include <memory> +#include <stack> +#include <string> +#include <system_error> +#include <utility> +#include <iomanip> // for quoted +#include <string_view> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#ifndef _LIBCPP_CXX03_LANG + +#if _LIBCPP_STD_VER >= 17 +#define __cpp_lib_filesystem 201703 +#endif + +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + +struct _FilesystemClock { +#if !defined(_LIBCPP_HAS_NO_INT128) + typedef __int128_t rep; + typedef nano period; +#else + typedef long long rep; + typedef nano period; +#endif + + typedef chrono::duration<rep, period> duration; + typedef chrono::time_point<_FilesystemClock> time_point; + + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + _LIBCPP_FUNC_VIS static time_point now() noexcept; + + _LIBCPP_INLINE_VISIBILITY + static time_t to_time_t(const time_point& __t) noexcept { + typedef chrono::duration<rep> __secs; + return time_t( + chrono::duration_cast<__secs>(__t.time_since_epoch()).count()); + } + + _LIBCPP_INLINE_VISIBILITY + static time_point from_time_t(time_t __t) noexcept { + typedef chrono::duration<rep> __secs; + return time_point(__secs(__t)); + } +}; + +typedef chrono::time_point<_FilesystemClock> file_time_type; + +struct _LIBCPP_TYPE_VIS space_info { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; +}; + +enum class _LIBCPP_ENUM_VIS file_type : signed char { + none = 0, + not_found = -1, + regular = 1, + directory = 2, + symlink = 3, + block = 4, + character = 5, + fifo = 6, + socket = 7, + unknown = 8 +}; + +enum class _LIBCPP_ENUM_VIS perms : unsigned { + none = 0, + + owner_read = 0400, + owner_write = 0200, + owner_exec = 0100, + owner_all = 0700, + + group_read = 040, + group_write = 020, + group_exec = 010, + group_all = 070, + + others_read = 04, + others_write = 02, + others_exec = 01, + others_all = 07, + + all = 0777, + + set_uid = 04000, + set_gid = 02000, + sticky_bit = 01000, + mask = 07777, + unknown = 0xFFFF, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator&(perms _LHS, perms _RHS) { + return static_cast<perms>(static_cast<unsigned>(_LHS) & + static_cast<unsigned>(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator|(perms _LHS, perms _RHS) { + return static_cast<perms>(static_cast<unsigned>(_LHS) | + static_cast<unsigned>(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator^(perms _LHS, perms _RHS) { + return static_cast<perms>(static_cast<unsigned>(_LHS) ^ + static_cast<unsigned>(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr perms operator~(perms _LHS) { + return static_cast<perms>(~static_cast<unsigned>(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator&=(perms& _LHS, perms _RHS) { return _LHS = _LHS & _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator|=(perms& _LHS, perms _RHS) { return _LHS = _LHS | _RHS; } + +_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 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 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 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 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, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256, + __in_recursive_copy = 512, +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator&(copy_options _LHS, copy_options _RHS) { + return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & + static_cast<unsigned short>(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator|(copy_options _LHS, copy_options _RHS) { + return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | + static_cast<unsigned short>(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator^(copy_options _LHS, copy_options _RHS) { + return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ + static_cast<unsigned short>(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr copy_options operator~(copy_options _LHS) { + return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) { + return _LHS = _LHS & _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) { + return _LHS = _LHS | _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) { + return _LHS = _LHS ^ _RHS; +} + +enum class _LIBCPP_ENUM_VIS directory_options : unsigned char { + none = 0, + follow_directory_symlink = 1, + skip_permission_denied = 2 +}; + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator&(directory_options _LHS, + directory_options _RHS) { + return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & + static_cast<unsigned char>(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator|(directory_options _LHS, + directory_options _RHS) { + return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | + static_cast<unsigned char>(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator^(directory_options _LHS, + directory_options _RHS) { + return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ + static_cast<unsigned char>(_RHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline constexpr directory_options operator~(directory_options _LHS) { + return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator&=(directory_options& _LHS, + directory_options _RHS) { + return _LHS = _LHS & _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator|=(directory_options& _LHS, + directory_options _RHS) { + return _LHS = _LHS | _RHS; +} + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator^=(directory_options& _LHS, + directory_options _RHS) { + return _LHS = _LHS ^ _RHS; +} + +class _LIBCPP_TYPE_VIS file_status { +public: + // constructors + _LIBCPP_INLINE_VISIBILITY + file_status() noexcept : file_status(file_type::none) {} + _LIBCPP_INLINE_VISIBILITY + explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept + : __ft_(__ft), + __prms_(__prms) {} + + file_status(const file_status&) noexcept = default; + file_status(file_status&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + ~file_status() {} + + file_status& operator=(const file_status&) noexcept = default; + file_status& operator=(file_status&&) noexcept = default; + + // observers + _LIBCPP_INLINE_VISIBILITY + file_type type() const noexcept { return __ft_; } + + _LIBCPP_INLINE_VISIBILITY + perms permissions() const noexcept { return __prms_; } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void type(file_type __ft) noexcept { __ft_ = __ft; } + + _LIBCPP_INLINE_VISIBILITY + void permissions(perms __p) noexcept { __prms_ = __p; } + +private: + file_type __ft_; + perms __prms_; +}; + +class _LIBCPP_TYPE_VIS directory_entry; + +template <class _Tp> +struct __can_convert_char { + static const bool value = false; +}; +template <class _Tp> +struct __can_convert_char<const _Tp> : public __can_convert_char<_Tp> {}; +template <> +struct __can_convert_char<char> { + static const bool value = true; + using __char_type = char; +}; +template <> +struct __can_convert_char<wchar_t> { + static const bool value = true; + using __char_type = wchar_t; +}; +template <> +struct __can_convert_char<char16_t> { + static const bool value = true; + using __char_type = char16_t; +}; +template <> +struct __can_convert_char<char32_t> { + static const bool value = true; + using __char_type = char32_t; +}; + +template <class _ECharT> +typename enable_if<__can_convert_char<_ECharT>::value, bool>::type +__is_separator(_ECharT __e) { + return __e == _ECharT('/'); +}; + +struct _NullSentinal {}; + +template <class _Tp> +using _Void = void; + +template <class _Tp, class = void> +struct __is_pathable_string : public false_type {}; + +template <class _ECharT, class _Traits, class _Alloc> +struct __is_pathable_string< + basic_string<_ECharT, _Traits, _Alloc>, + _Void<typename __can_convert_char<_ECharT>::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string<_ECharT, _Traits, _Alloc>; + using _Base = __can_convert_char<_ECharT>; + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template <class _ECharT, class _Traits> +struct __is_pathable_string< + basic_string_view<_ECharT, _Traits>, + _Void<typename __can_convert_char<_ECharT>::__char_type> > + : public __can_convert_char<_ECharT> { + using _Str = basic_string_view<_ECharT, _Traits>; + using _Base = __can_convert_char<_ECharT>; + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + static _ECharT const* __range_end(_Str const& __s) { + return __s.data() + __s.length(); + } + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + +template <class _Source, class _DS = typename decay<_Source>::type, + class _UnqualPtrType = + typename remove_const<typename remove_pointer<_DS>::type>::type, + bool _IsCharPtr = is_pointer<_DS>::value&& + __can_convert_char<_UnqualPtrType>::value> +struct __is_pathable_char_array : false_type {}; + +template <class _Source, class _ECharT, class _UPtr> +struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> + : __can_convert_char<typename remove_const<_ECharT>::type> { + using _Base = __can_convert_char<typename remove_const<_ECharT>::type>; + + static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } + static _ECharT const* __range_end(const _ECharT* __b) { + using _Iter = const _ECharT*; + const _ECharT __sentinal = _ECharT{}; + _Iter __e = __b; + for (; *__e != __sentinal; ++__e) + ; + return __e; + } + + static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } +}; + +template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, + class = void> +struct __is_pathable_iter : false_type {}; + +template <class _Iter> +struct __is_pathable_iter< + _Iter, true, + _Void<typename __can_convert_char< + typename iterator_traits<_Iter>::value_type>::__char_type> > + : __can_convert_char<typename iterator_traits<_Iter>::value_type> { + using _ECharT = typename iterator_traits<_Iter>::value_type; + using _Base = __can_convert_char<_ECharT>; + + static _Iter __range_begin(_Iter __b) { return __b; } + static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; } + + static _ECharT __first_or_null(_Iter __b) { return *__b; } +}; + +template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value, + bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, + bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> +struct __is_pathable : false_type { + static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); +}; + +template <class _Tp> +struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; + +template <class _Tp> +struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> { +}; + +template <class _Tp> +struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; + +template <class _ECharT> +struct _PathCVT { + static_assert(__can_convert_char<_ECharT>::value, + "Char type not convertible"); + + typedef __narrow_to_utf8<sizeof(_ECharT) * __CHAR_BIT__> _Narrower; + + static void __append_range(string& __dest, _ECharT const* __b, + _ECharT const* __e) { + _Narrower()(back_inserter(__dest), __b, __e); + } + + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _Iter __e) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + if (__b == __e) + return; + basic_string<_ECharT> __tmp(__b, __e); + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); + } + + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _NullSentinal) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + const _ECharT __sentinal = _ECharT{}; + if (*__b == __sentinal) + return; + basic_string<_ECharT> __tmp; + for (; *__b != __sentinal; ++__b) + __tmp.push_back(*__b); + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); + } + + template <class _Source> + static void __append_source(string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +template <> +struct _PathCVT<char> { + + template <class _Iter> + static typename enable_if<__is_exactly_input_iterator<_Iter>::value>::type + __append_range(string& __dest, _Iter __b, _Iter __e) { + for (; __b != __e; ++__b) + __dest.push_back(*__b); + } + + template <class _Iter> + static typename enable_if<__is_forward_iterator<_Iter>::value>::type + __append_range(string& __dest, _Iter __b, _Iter __e) { + __dest.__append_forward_unsafe(__b, __e); + } + + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _NullSentinal) { + const char __sentinal = char{}; + for (; *__b != __sentinal; ++__b) + __dest.push_back(*__b); + } + + template <class _Source> + static void __append_source(string& __dest, _Source const& __s) { + using _Traits = __is_pathable<_Source>; + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); + } +}; + +class _LIBCPP_TYPE_VIS path { + template <class _SourceOrIter, class _Tp = path&> + using _EnableIfPathable = + typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; + + template <class _Tp> + using _SourceChar = typename __is_pathable<_Tp>::__char_type; + + template <class _Tp> + using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; + +public: + typedef char value_type; + typedef basic_string<value_type> string_type; + typedef _VSTD::string_view __string_view; + static 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, format = format::auto_format) noexcept + : __pn_(_VSTD::move(__s)) {} + + template <class _Source, class = _EnableIfPathable<_Source, void> > + path(const _Source& __src, format = format::auto_format) { + _SourceCVT<_Source>::__append_source(__pn_, __src); + } + + template <class _InputIt> + path(_InputIt __first, _InputIt __last, format = format::auto_format) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + } + + // TODO Implement locale conversions. + template <class _Source, class = _EnableIfPathable<_Source, void> > + path(const _Source& __src, const locale& __loc, format = format::auto_format); + template <class _InputIt> + path(_InputIt __first, _InputIt _last, const locale& __loc, + format = format::auto_format); + + _LIBCPP_INLINE_VISIBILITY + ~path() = default; + + // assignments + _LIBCPP_INLINE_VISIBILITY + path& operator=(const path& __p) { + __pn_ = __p.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator=(path&& __p) noexcept { + __pn_ = _VSTD::move(__p.__pn_); + return *this; + } + + template <class = void> + _LIBCPP_INLINE_VISIBILITY path& operator=(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& assign(string_type&& __s) noexcept { + __pn_ = _VSTD::move(__s); + return *this; + } + + template <class _Source> + _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> + operator=(const _Source& __src) { + return this->assign(__src); + } + + template <class _Source> + _EnableIfPathable<_Source> assign(const _Source& __src) { + __pn_.clear(); + _SourceCVT<_Source>::__append_source(__pn_, __src); + return *this; + } + + template <class _InputIt> + path& assign(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + __pn_.clear(); + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + +private: + template <class _ECharT> + static bool __source_is_absolute(_ECharT __first_or_null) { + return __is_separator(__first_or_null); + } + +public: + // appends + path& operator/=(const path& __p) { + 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> + operator/=(const _Source& __src) { + return this->append(__src); + } + + template <class _Source> + _EnableIfPathable<_Source> append(const _Source& __src) { + using _Traits = __is_pathable<_Source>; + using _CVT = _PathCVT<_SourceChar<_Source> >; + 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; + } + + template <class _InputIt> + path& append(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); + using _CVT = _PathCVT<_ItVal>; + if (__first != __last && __source_is_absolute(*__first)) + __pn_.clear(); + else if (has_filename()) + __pn_ += preferred_separator; + _CVT::__append_range(__pn_, __first, __last); + return *this; + } + + // concatenation + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const path& __x) { + __pn_ += __x.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const string_type& __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(__string_view __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const value_type* __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(value_type __x) { + __pn_ += __x; + return *this; + } + + template <class _ECharT> + typename enable_if<__can_convert_char<_ECharT>::value, path&>::type + operator+=(_ECharT __x) { + basic_string<_ECharT> __tmp; + __tmp += __x; + _PathCVT<_ECharT>::__append_source(__pn_, __tmp); + return *this; + } + + template <class _Source> + _EnableIfPathable<_Source> operator+=(const _Source& __x) { + return this->concat(__x); + } + + template <class _Source> + _EnableIfPathable<_Source> concat(const _Source& __x) { + _SourceCVT<_Source>::__append_source(__pn_, __x); + return *this; + } + + template <class _InputIt> + path& concat(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void clear() noexcept { __pn_.clear(); } + + path& make_preferred() { return *this; } + + _LIBCPP_INLINE_VISIBILITY + path& remove_filename() { + auto __fname = __filename(); + if (!__fname.empty()) + __pn_.erase(__fname.data() - __pn_.data()); + return *this; + } + + path& replace_filename(const path& __replacement) { + remove_filename(); + return (*this /= __replacement); + } + + path& replace_extension(const path& __replacement = path()); + + _LIBCPP_INLINE_VISIBILITY + void swap(path& __rhs) noexcept { __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 { return __pn_; } + + _LIBCPP_INLINE_VISIBILITY + const value_type* c_str() const noexcept { return __pn_.c_str(); } + + _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; } + + template <class _ECharT, class _Traits = char_traits<_ECharT>, + class _Allocator = allocator<_ECharT> > + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _CVT = __widen_from_utf8<sizeof(_ECharT) * __CHAR_BIT__>; + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + + _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; } + _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { + return string<wchar_t>(); + } + _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; } + _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { + return string<char16_t>(); + } + _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { + return string<char32_t>(); + } + + // generic format observers + template <class _ECharT, class _Traits = char_traits<_ECharT>, + class _Allocator = allocator<_ECharT> > + basic_string<_ECharT, _Traits, _Allocator> + generic_string(const _Allocator& __a = _Allocator()) const { + return string<_ECharT, _Traits, _Allocator>(__a); + } + + std::string generic_string() const { return __pn_; } + std::wstring generic_wstring() const { return string<wchar_t>(); } + std::string generic_u8string() const { return __pn_; } + std::u16string generic_u16string() const { return string<char16_t>(); } + std::u32string generic_u32string() const { return string<char32_t>(); } + +private: + int __compare(__string_view) const; + __string_view __root_name() const; + __string_view __root_directory() const; + __string_view __root_path_raw() const; + __string_view __relative_path() const; + __string_view __parent_path() const; + __string_view __filename() const; + __string_view __stem() const; + __string_view __extension() const; + +public: + // compare + _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const noexcept { + return __compare(__p.__pn_); + } + _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { + return __compare(__s); + } + _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { + return __compare(__s); + } + _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { + return __compare(__s); + } + + // decomposition + _LIBCPP_INLINE_VISIBILITY path root_name() const { + return string_type(__root_name()); + } + _LIBCPP_INLINE_VISIBILITY path root_directory() const { + return string_type(__root_directory()); + } + _LIBCPP_INLINE_VISIBILITY path root_path() const { + return root_name().append(string_type(__root_directory())); + } + _LIBCPP_INLINE_VISIBILITY path relative_path() const { + return string_type(__relative_path()); + } + _LIBCPP_INLINE_VISIBILITY path parent_path() const { + return string_type(__parent_path()); + } + _LIBCPP_INLINE_VISIBILITY path filename() const { + return string_type(__filename()); + } + _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem()); } + _LIBCPP_INLINE_VISIBILITY path extension() const { + return string_type(__extension()); + } + + // query + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool + empty() const noexcept { + return __pn_.empty(); + } + + _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { + return !__root_name().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { + return !__root_directory().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { + return !__root_path_raw().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { + return !__relative_path().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { + return !__parent_path().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_filename() const { + return !__filename().empty(); + } + _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_extension() const { + return !__extension().empty(); + } + + _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; + + iterator begin() const; + iterator end() const; + + template <class _CharT, class _Traits> + _LIBCPP_INLINE_VISIBILITY friend + typename enable_if<is_same<_CharT, char>::value && + is_same<_Traits, char_traits<char> >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.native()); + return __os; + } + + template <class _CharT, class _Traits> + _LIBCPP_INLINE_VISIBILITY friend + typename enable_if<!is_same<_CharT, char>::value || + !is_same<_Traits, char_traits<char> >::value, + basic_ostream<_CharT, _Traits>&>::type + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.string<_CharT, _Traits>()); + return __os; + } + + template <class _CharT, class _Traits> + _LIBCPP_INLINE_VISIBILITY friend basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { + basic_string<_CharT, _Traits> __tmp; + __is >> __quoted(__tmp); + __p = __tmp; + return __is; + } + +private: + inline _LIBCPP_INLINE_VISIBILITY path& + __assign_view(__string_view const& __s) noexcept { + __pn_ = string_type(__s); + return *this; + } + string_type __pn_; +}; + +inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept { + __lhs.swap(__rhs); +} + +_LIBCPP_FUNC_VIS +size_t hash_value(const path& __p) noexcept; + +inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, + const path& __rhs) noexcept { + return __lhs.compare(__rhs) == 0; +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, + const path& __rhs) noexcept { + return __lhs.compare(__rhs) != 0; +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, + const path& __rhs) noexcept { + return __lhs.compare(__rhs) < 0; +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, + const path& __rhs) noexcept { + return __lhs.compare(__rhs) <= 0; +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, + const path& __rhs) noexcept { + return __lhs.compare(__rhs) > 0; +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, + const path& __rhs) noexcept { + return __lhs.compare(__rhs) >= 0; +} + +inline _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, + const path& __rhs) { + path __result(__lhs); + __result /= __rhs; + return __result; +} + +template <class _Source> +_LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_pathable<_Source>::value, path>::type + u8path(const _Source& __s) { + static_assert( + is_same<typename __is_pathable<_Source>::__char_type, char>::value, + "u8path(Source const&) requires Source have a character type of type " + "'char'"); + return path(__s); +} + +template <class _InputIt> +_LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_pathable<_InputIt>::value, path>::type + u8path(_InputIt __f, _InputIt __l) { + static_assert( + is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"); + return path(__f, __l); +} + +class _LIBCPP_TYPE_VIS path::iterator { +public: + enum _ParserState : unsigned char { + _Singular, + _BeforeBegin, + _InRootName, + _InRootDir, + _InFilenames, + _InTrailingSep, + _AtEnd + }; + +public: + typedef bidirectional_iterator_tag iterator_category; + + typedef path value_type; + typedef std::ptrdiff_t difference_type; + typedef const path* pointer; + typedef const path& reference; + + typedef void + __stashing_iterator_tag; // See reverse_iterator and __is_stashing_iterator + +public: + _LIBCPP_INLINE_VISIBILITY + iterator() + : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), + __state_(_Singular) {} + + iterator(const iterator&) = default; + ~iterator() = default; + + iterator& operator=(const iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { return __stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { return &__stashed_elem_; } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator++() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to increment a singular iterator"); + _LIBCPP_ASSERT(__state_ != _AtEnd, + "attempting to increment the end iterator"); + return __increment(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator++(int) { + iterator __it(*this); + this->operator++(); + return __it; + } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator--() { + _LIBCPP_ASSERT(__state_ != _Singular, + "attempting to decrement a singular iterator"); + _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), + "attempting to decrement the begin iterator"); + return __decrement(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator--(int) { + iterator __it(*this); + this->operator--(); + return __it; + } + +private: + friend class path; + + inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&, + const iterator&); + + iterator& __increment(); + iterator& __decrement(); + + path __stashed_elem_; + const path* __path_ptr_; + path::__string_view __entry_; + _ParserState __state_; +}; + +inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, + const path::iterator& __rhs) { + return __lhs.__path_ptr_ == __rhs.__path_ptr_ && + __lhs.__entry_.data() == __rhs.__entry_.data(); +} + +inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs, + const path::iterator& __rhs) { + return !(__lhs == __rhs); +} + +class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error { +public: + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(path(), path())) { + __create_what(0); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, path())) { + __create_what(1); + } + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, const path& __p2, + error_code __ec) + : system_error(__ec, __what), + __storage_(make_shared<_Storage>(__p1, __p2)) { + __create_what(2); + } + + _LIBCPP_INLINE_VISIBILITY + const path& path1() const noexcept { return __storage_->__p1_; } + + _LIBCPP_INLINE_VISIBILITY + const path& path2() const noexcept { return __storage_->__p2_; } + + ~filesystem_error() override; // key function + + _LIBCPP_INLINE_VISIBILITY + const char* what() const noexcept override { + return __storage_->__what_.c_str(); + } + + _LIBCPP_FUNC_VIS + void __create_what(int __num_paths); + +private: + struct _Storage { + _LIBCPP_INLINE_VISIBILITY + _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} + + path __p1_; + path __p2_; + string __what_; + }; + shared_ptr<_Storage> __storage_; +}; + +template <class... _Args> +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +#ifndef _LIBCPP_NO_EXCEPTIONS + void + __throw_filesystem_error(_Args&&... __args) { + throw filesystem_error(std::forward<_Args>(__args)...); +} +#else + void + __throw_filesystem_error(_Args&&...) { + _VSTD::abort(); +} +#endif + +// operational functions + +_LIBCPP_FUNC_VIS +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); +_LIBCPP_FUNC_VIS +bool __copy_file(const path& __from, const path& __to, copy_options __opt, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +bool __create_directories(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +bool __create_directory(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +bool __create_directory(const path& p, const path& attributes, + error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +void __create_directory_symlink(const path& __to, const path& __new_symlink, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +void __create_hard_link(const path& __to, const path& __new_hard_link, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +void __create_symlink(const path& __to, const path& __new_symlink, + error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +path __current_path(error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +void __current_path(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +bool __equivalent(const path&, const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __file_size(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +bool __fs_is_empty(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +file_time_type __last_write_time(const path& p, error_code* ec = nullptr); +_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&, perms, perm_options, error_code* = nullptr); +_LIBCPP_FUNC_VIS +path __read_symlink(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +bool __remove(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __remove_all(const path& p, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +void __rename(const path& from, const path& to, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +void __resize_file(const path& p, uintmax_t size, error_code* ec = nullptr); +_LIBCPP_FUNC_VIS +space_info __space(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +file_status __status(const path&, error_code* __ec = nullptr); +_LIBCPP_FUNC_VIS +file_status __symlink_status(const path&, error_code* __ec = nullptr); +_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() { + return __current_path(); +} + +inline _LIBCPP_INLINE_VISIBILITY path current_path(error_code& __ec) { + return __current_path(&__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p) { + __current_path(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY void current_path(const path& __p, + error_code& __ec) noexcept { + __current_path(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path absolute(const path& __p) { + return __absolute(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY 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) { + return __canonical(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, + const path& __to) { + __copy(__from, __to, copy_options::none); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, + error_code& __ec) { + __copy(__from, __to, copy_options::none, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, + copy_options __opt) { + __copy(__from, __to, __opt); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy(const path& __from, const path& __to, + copy_options __opt, + error_code& __ec) { + __copy(__from, __to, __opt, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, + const path& __to) { + return __copy_file(__from, __to, copy_options::none); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +copy_file(const path& __from, const path& __to, error_code& __ec) { + return __copy_file(__from, __to, copy_options::none, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +copy_file(const path& __from, const path& __to, copy_options __opt) { + return __copy_file(__from, __to, __opt); +} + +inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, + const path& __to, + copy_options __opt, + error_code& __ec) { + return __copy_file(__from, __to, __opt, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void copy_symlink(const path& __existing, + const path& __new) { + __copy_symlink(__existing, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY void +copy_symlink(const path& __ext, const path& __new, error_code& __ec) noexcept { + __copy_symlink(__ext, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p) { + return __create_directories(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY bool create_directories(const path& __p, + error_code& __ec) { + return __create_directories(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p) { + return __create_directory(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +create_directory(const path& __p, error_code& __ec) noexcept { + return __create_directory(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool create_directory(const path& __p, + const path& __attrs) { + return __create_directory(__p, __attrs); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +create_directory(const path& __p, const path& __attrs, + error_code& __ec) noexcept { + return __create_directory(__p, __attrs, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void +create_directory_symlink(const path& __to, const path& __new) { + __create_directory_symlink(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY void +create_directory_symlink(const path& __to, const path& __new, + error_code& __ec) noexcept { + __create_directory_symlink(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void create_hard_link(const path& __to, + const path& __new) { + __create_hard_link(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY void +create_hard_link(const path& __to, const path& __new, + error_code& __ec) noexcept { + __create_hard_link(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void create_symlink(const path& __to, + const path& __new) { + __create_symlink(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY void +create_symlink(const path& __to, const path& __new, error_code& __ec) noexcept { + return __create_symlink(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool status_known(file_status __s) noexcept { + return __s.type() != file_type::none; +} + +inline _LIBCPP_INLINE_VISIBILITY bool exists(file_status __s) noexcept { + return status_known(__s) && __s.type() != file_type::not_found; +} + +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p) { + return exists(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, + error_code& __ec) noexcept { + auto __s = __status(__p, &__ec); + if (status_known(__s)) + __ec.clear(); + return exists(__s); +} + +inline _LIBCPP_INLINE_VISIBILITY bool equivalent(const path& __p1, + const path& __p2) { + return __equivalent(__p1, __p2); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { + return __equivalent(__p1, __p2, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t file_size(const path& __p) { + return __file_size(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t +file_size(const path& __p, error_code& __ec) noexcept { + return __file_size(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t hard_link_count(const path& __p) { + return __hard_link_count(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t +hard_link_count(const path& __p, error_code& __ec) noexcept { + return __hard_link_count(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(file_status __s) noexcept { + return __s.type() == file_type::block; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p) { + return is_block_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_block_file(const path& __p, + error_code& __ec) noexcept { + return is_block_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +is_character_file(file_status __s) noexcept { + return __s.type() == file_type::character; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_character_file(const path& __p) { + return is_character_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +is_character_file(const path& __p, error_code& __ec) noexcept { + return is_character_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(file_status __s) noexcept { + return __s.type() == file_type::directory; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p) { + return is_directory(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_directory(const path& __p, + error_code& __ec) noexcept { + return is_directory(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p) { + return __fs_is_empty(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_empty(const path& __p, + error_code& __ec) { + return __fs_is_empty(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(file_status __s) noexcept { + return __s.type() == file_type::fifo; +} +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p) { + return is_fifo(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_fifo(const path& __p, + error_code& __ec) noexcept { + return is_fifo(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +is_regular_file(file_status __s) noexcept { + return __s.type() == file_type::regular; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_regular_file(const path& __p) { + return is_regular_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool +is_regular_file(const path& __p, error_code& __ec) noexcept { + return is_regular_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(file_status __s) noexcept { + return __s.type() == file_type::socket; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p) { + return is_socket(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_socket(const path& __p, + error_code& __ec) noexcept { + return is_socket(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(file_status __s) noexcept { + return __s.type() == file_type::symlink; +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p) { + return is_symlink(__symlink_status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_symlink(const path& __p, + error_code& __ec) noexcept { + return is_symlink(__symlink_status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_other(file_status __s) noexcept { + return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && + !is_symlink(__s); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p) { + return is_other(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY bool is_other(const path& __p, + error_code& __ec) noexcept { + return is_other(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY file_time_type +last_write_time(const path& __p) { + return __last_write_time(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY file_time_type +last_write_time(const path& __p, error_code& __ec) noexcept { + return __last_write_time(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void last_write_time(const path& __p, + file_time_type __t) { + __last_write_time(__p, __t); +} + +inline _LIBCPP_INLINE_VISIBILITY void +last_write_time(const path& __p, file_time_type __t, + error_code& __ec) noexcept { + __last_write_time(__p, __t, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY 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) 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 path read_symlink(const path& __p) { + return __read_symlink(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY 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); +} + +inline _LIBCPP_INLINE_VISIBILITY bool remove(const path& __p, + error_code& __ec) noexcept { + return __remove(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p) { + return __remove_all(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY uintmax_t remove_all(const path& __p, + error_code& __ec) { + return __remove_all(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void rename(const path& __from, + const path& __to) { + return __rename(__from, __to); +} + +inline _LIBCPP_INLINE_VISIBILITY void +rename(const path& __from, const path& __to, error_code& __ec) noexcept { + return __rename(__from, __to, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY void resize_file(const path& __p, + uintmax_t __ns) { + return __resize_file(__p, __ns); +} + +inline _LIBCPP_INLINE_VISIBILITY void +resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { + return __resize_file(__p, __ns, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p) { + return __space(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY space_info space(const path& __p, + error_code& __ec) noexcept { + return __space(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p) { + return __status(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY file_status status(const path& __p, + error_code& __ec) noexcept { + return __status(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY file_status symlink_status(const path& __p) { + return __symlink_status(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY file_status +symlink_status(const path& __p, error_code& __ec) noexcept { + return __symlink_status(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY path temp_directory_path() { + return __temp_directory_path(); +} + +inline _LIBCPP_INLINE_VISIBILITY 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_iterator; +class recursive_directory_iterator; +class __dir_stream; + +class directory_entry { + typedef _VSTD_FS::path _Path; + +public: + // constructors and destructors + directory_entry() noexcept = default; + directory_entry(directory_entry const&) = default; + directory_entry(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + explicit directory_entry(_Path const& __p) : __p_(__p) { + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { + __refresh(&__ec); + } + + ~directory_entry() {} + + directory_entry& operator=(directory_entry const&) = default; + directory_entry& operator=(directory_entry&&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p) { + __p_ = __p; + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p, error_code& __ec) { + __p_ = __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p) { + __p_.replace_filename(__p); + error_code __ec; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p, error_code& __ec) { + __p_ = __p_.parent_path() / __p; + __refresh(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + void refresh() { __refresh(); } + + _LIBCPP_INLINE_VISIBILITY + void refresh(error_code& __ec) noexcept { __refresh(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + _Path const& path() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + operator const _Path&() const noexcept { return __p_; } + + _LIBCPP_INLINE_VISIBILITY + bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool exists(error_code& __ec) const noexcept { + return _VSTD_FS::exists(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file() const { return __get_ft() == file_type::block; } + + _LIBCPP_INLINE_VISIBILITY + bool is_block_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::block; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file() const { return __get_ft() == file_type::character; } + + _LIBCPP_INLINE_VISIBILITY + bool is_character_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::character; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory() const { return __get_ft() == file_type::directory; } + + _LIBCPP_INLINE_VISIBILITY + bool is_directory(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::directory; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo() const { return __get_ft() == file_type::fifo; } + + _LIBCPP_INLINE_VISIBILITY + bool is_fifo(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::fifo; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); } + + _LIBCPP_INLINE_VISIBILITY + bool is_other(error_code& __ec) const noexcept { + return _VSTD_FS::is_other(file_status{__get_ft(&__ec)}); + } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file() const { return __get_ft() == file_type::regular; } + + _LIBCPP_INLINE_VISIBILITY + bool is_regular_file(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::regular; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket() const { return __get_ft() == file_type::socket; } + + _LIBCPP_INLINE_VISIBILITY + bool is_socket(error_code& __ec) const noexcept { + return __get_ft(&__ec) == file_type::socket; + } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } + + _LIBCPP_INLINE_VISIBILITY + bool is_symlink(error_code& __ec) const noexcept { + return __get_sym_ft(&__ec) == file_type::symlink; + } + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size() const { return __get_size(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t file_size(error_code& __ec) const noexcept { + return __get_size(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count() const { return __get_nlink(); } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t hard_link_count(error_code& __ec) const noexcept { + return __get_nlink(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time() const { return __get_write_time(); } + + _LIBCPP_INLINE_VISIBILITY + file_time_type last_write_time(error_code& __ec) const noexcept { + return __get_write_time(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status status() const { return __get_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status status(error_code& __ec) const noexcept { + return __get_status(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status() const { return __get_symlink_status(); } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status(error_code& __ec) const noexcept { + return __get_symlink_status(&__ec); + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<(directory_entry const& __rhs) const noexcept { + return __p_ < __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator==(directory_entry const& __rhs) const noexcept { + return __p_ == __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator!=(directory_entry const& __rhs) const noexcept { + return __p_ != __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<=(directory_entry const& __rhs) const noexcept { + return __p_ <= __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>(directory_entry const& __rhs) const noexcept { + return __p_ > __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>=(directory_entry const& __rhs) const noexcept { + return __p_ >= __rhs.__p_; + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + friend class __dir_stream; + + enum _CacheType : unsigned char { + _Empty, + _IterSymlink, + _IterNonSymlink, + _RefreshSymlink, + _RefreshSymlinkUnresolved, + _RefreshNonSymlink + }; + + struct __cached_data { + uintmax_t __size_; + uintmax_t __nlink_; + file_time_type __write_time_; + perms __sym_perms_; + perms __non_sym_perms_; + file_type __type_; + _CacheType __cache_type_; + + _LIBCPP_INLINE_VISIBILITY + __cached_data() noexcept { __reset(); } + + _LIBCPP_INLINE_VISIBILITY + void __reset() { + __cache_type_ = _Empty; + __type_ = file_type::none; + __sym_perms_ = __non_sym_perms_ = perms::unknown; + __size_ = __nlink_ = uintmax_t(-1); + __write_time_ = file_time_type::min(); + } + }; + + _LIBCPP_INLINE_VISIBILITY + static __cached_data __create_iter_result(file_type __ft) { + __cached_data __data; + __data.__type_ = __ft; + __data.__cache_type_ = [&]() { + switch (__ft) { + case file_type::none: + return _Empty; + case file_type::symlink: + return _IterSymlink; + default: + return _IterNonSymlink; + } + }(); + return __data; + } + + _LIBCPP_INLINE_VISIBILITY + void __assign_iter_entry(_Path&& __p, __cached_data __dt) { + __p_ = std::move(__p); + __data_ = __dt; + } + + _LIBCPP_FUNC_VIS + error_code __do_refresh() noexcept; + + _LIBCPP_INLINE_VISIBILITY + static bool __is_dne_error(error_code const& __ec) { + if (!__ec) + return true; + switch (static_cast<errc>(__ec.value())) { + case errc::no_such_file_or_directory: + case errc::not_a_directory: + return true; + default: + return false; + } + } + + _LIBCPP_INLINE_VISIBILITY + void __handle_error(const char* __msg, error_code* __dest_ec, + error_code const& __ec, bool __allow_dne = false) const { + if (__dest_ec) { + *__dest_ec = __ec; + return; + } + if (__ec && (!__allow_dne || !__is_dne_error(__ec))) + __throw_filesystem_error(__msg, __p_, __ec); + } + + _LIBCPP_INLINE_VISIBILITY + void __refresh(error_code* __ec = nullptr) { + __handle_error("in directory_entry::refresh", __ec, __do_refresh(), + /*allow_dne*/ true); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_sym_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + return __symlink_status(__p_, __ec).type(); + case _IterSymlink: + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + if (__ec) + __ec->clear(); + return file_type::symlink; + case _IterNonSymlink: + case _RefreshNonSymlink: + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_type __get_ft(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec).type(); + case _IterNonSymlink: + case _RefreshNonSymlink: + case _RefreshSymlink: { + file_status __st(__data_.__type_); + if (__ec && !_VSTD_FS::exists(__st)) + *__ec = make_error_code(errc::no_such_file_or_directory); + else if (__ec) + __ec->clear(); + return __data_.__type_; + } + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return __status(__p_, __ec); + case _RefreshNonSymlink: + case _RefreshSymlink: + return file_status(__get_ft(__ec), __data_.__non_sym_perms_); + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_status __get_symlink_status(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + return __symlink_status(__p_, __ec); + case _RefreshNonSymlink: + return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_); + case _RefreshSymlink: + case _RefreshSymlinkUnresolved: + return file_status(__get_sym_ft(__ec), __data_.__sym_perms_); + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_size(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__file_size(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::file_size", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) { + errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory + : errc::not_supported; + __handle_error("in directory_entry::file_size", __ec, + make_error_code(__err_kind)); + } + return __data_.__size_; + } + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + uintmax_t __get_nlink(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__hard_link_count(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + (void)__get_ft(&__m_ec); + __handle_error("in directory_entry::hard_link_count", __ec, __m_ec); + return __data_.__nlink_; + } + } + _LIBCPP_UNREACHABLE(); + } + + _LIBCPP_INLINE_VISIBILITY + file_time_type __get_write_time(error_code* __ec = nullptr) const { + switch (__data_.__cache_type_) { + case _Empty: + case _IterNonSymlink: + case _IterSymlink: + case _RefreshSymlinkUnresolved: + return _VSTD_FS::__last_write_time(__p_, __ec); + case _RefreshSymlink: + case _RefreshNonSymlink: { + error_code __m_ec; + file_status __st(__get_ft(&__m_ec)); + __handle_error("in directory_entry::last_write_time", __ec, __m_ec); + if (_VSTD_FS::exists(__st) && + __data_.__write_time_ == file_time_type::min()) + __handle_error("in directory_entry::last_write_time", __ec, + make_error_code(errc::value_too_large)); + return __data_.__write_time_; + } + } + _LIBCPP_UNREACHABLE(); + } + +private: + _Path __p_; + __cached_data __data_; +}; + +class __dir_element_proxy { +public: + inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() { + return _VSTD::move(__elem_); + } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} + __dir_element_proxy(__dir_element_proxy&& __o) + : __elem_(_VSTD::move(__o.__elem_)) {} + directory_entry __elem_; +}; + +class directory_iterator { +public: + typedef directory_entry value_type; + typedef ptrdiff_t difference_type; + typedef value_type const* pointer; + typedef value_type const& reference; + typedef input_iterator_tag iterator_category; + +public: + //ctor & dtor + directory_iterator() noexcept {} + + explicit directory_iterator(const path& __p) + : directory_iterator(__p, nullptr) {} + + directory_iterator(const path& __p, directory_options __opts) + : directory_iterator(__p, nullptr, __opts) {} + + directory_iterator(const path& __p, error_code& __ec) + : directory_iterator(__p, &__ec) {} + + directory_iterator(const path& __p, directory_options __opts, + error_code& __ec) + : directory_iterator(__p, &__ec, __opts) {} + + directory_iterator(const directory_iterator&) = default; + directory_iterator(directory_iterator&&) = default; + directory_iterator& operator=(const directory_iterator&) = default; + + directory_iterator& operator=(directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + } + return *this; + } + + ~directory_iterator() = default; + + const directory_entry& operator*() const { + _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); + return __dereference(); + } + + const directory_entry* operator->() const { return &**this; } + + directory_iterator& operator++() { return __increment(); } + + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } + +private: + inline _LIBCPP_INLINE_VISIBILITY friend bool + operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept; + + // construct the dir_stream + _LIBCPP_FUNC_VIS + directory_iterator(const path&, error_code*, + directory_options = directory_options::none); + + _LIBCPP_FUNC_VIS + directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + +private: + shared_ptr<__dir_stream> __imp_; +}; + +inline _LIBCPP_INLINE_VISIBILITY bool +operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +inline _LIBCPP_INLINE_VISIBILITY bool +operator!=(const directory_iterator& __lhs, + const directory_iterator& __rhs) noexcept { + return !(__lhs == __rhs); +} + +// enable directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY directory_iterator +begin(directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY directory_iterator +end(const directory_iterator&) noexcept { + return directory_iterator(); +} + +class recursive_directory_iterator { +public: + using value_type = directory_entry; + using difference_type = std::ptrdiff_t; + using pointer = directory_entry const*; + using reference = directory_entry const&; + using iterator_category = std::input_iterator_tag; + +public: + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator() noexcept : __rec_(false) {} + + _LIBCPP_INLINE_VISIBILITY + explicit recursive_directory_iterator( + const path& __p, directory_options __xoptions = directory_options::none) + : recursive_directory_iterator(__p, __xoptions, nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, directory_options __xoptions, + error_code& __ec) + : recursive_directory_iterator(__p, __xoptions, &__ec) {} + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, error_code& __ec) + : recursive_directory_iterator(__p, directory_options::none, &__ec) {} + + recursive_directory_iterator(const recursive_directory_iterator&) = default; + recursive_directory_iterator(recursive_directory_iterator&&) = default; + + recursive_directory_iterator& + operator=(const recursive_directory_iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& + operator=(recursive_directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + __rec_ = __o.__rec_; + } + return *this; + } + + ~recursive_directory_iterator() = default; + + _LIBCPP_INLINE_VISIBILITY + const directory_entry& operator*() const { return __dereference(); } + + _LIBCPP_INLINE_VISIBILITY + const directory_entry* operator->() const { return &__dereference(); } + + recursive_directory_iterator& operator++() { return __increment(); } + + _LIBCPP_INLINE_VISIBILITY + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& increment(error_code& __ec) { + return __increment(&__ec); + } + + _LIBCPP_FUNC_VIS directory_options options() const; + _LIBCPP_FUNC_VIS int depth() const; + + _LIBCPP_INLINE_VISIBILITY + void pop() { __pop(); } + + _LIBCPP_INLINE_VISIBILITY + void pop(error_code& __ec) { __pop(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + bool recursion_pending() const { return __rec_; } + + _LIBCPP_INLINE_VISIBILITY + void disable_recursion_pending() { __rec_ = false; } + +private: + recursive_directory_iterator(const path& __p, directory_options __opt, + error_code* __ec); + + _LIBCPP_FUNC_VIS + const directory_entry& __dereference() const; + + _LIBCPP_FUNC_VIS + bool __try_recursion(error_code* __ec); + + _LIBCPP_FUNC_VIS + void __advance(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + recursive_directory_iterator& __increment(error_code* __ec = nullptr); + + _LIBCPP_FUNC_VIS + void __pop(error_code* __ec = nullptr); + + inline _LIBCPP_INLINE_VISIBILITY friend bool + operator==(const recursive_directory_iterator&, + const recursive_directory_iterator&) noexcept; + + struct __shared_imp; + shared_ptr<__shared_imp> __imp_; + bool __rec_; +}; // class recursive_directory_iterator + +inline _LIBCPP_INLINE_VISIBILITY bool +operator==(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return __lhs.__imp_ == __rhs.__imp_; +} + +_LIBCPP_INLINE_VISIBILITY +inline bool operator!=(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) noexcept { + return !(__lhs == __rhs); +} +// enable recursive_directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +begin(recursive_directory_iterator __iter) noexcept { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator +end(const recursive_directory_iterator&) noexcept { + return recursive_directory_iterator(); +} + +_LIBCPP_END_NAMESPACE_FILESYSTEM + +#endif // !_LIBCPP_CXX03_LANG + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_FILESYSTEM diff --git a/lib/libcxx/include/float.h b/lib/libcxx/include/float.h index 1acfdc6188f..759ac8e7954 100644 --- a/lib/libcxx/include/float.h +++ b/lib/libcxx/include/float.h @@ -24,7 +24,14 @@ Macros: DBL_MANT_DIG LDBL_MANT_DIG + FLT_HAS_SUBNORM // C11 + DBL_HAS_SUBNORM // C11 + LDBL_HAS_SUBNORM // C11 + DECIMAL_DIG // C99 + FLT_DECIMAL_DIG // C11 + DBL_DECIMAL_DIG // C11 + LDBL_DECIMAL_DIG // C11 FLT_DIG DBL_DIG @@ -58,6 +65,10 @@ Macros: DBL_MIN LDBL_MIN + FLT_TRUE_MIN // C11 + DBL_TRUE_MIN // C11 + LDBL_TRUE_MIN // C11 + */ #include <__config> diff --git a/lib/libcxx/include/forward_list b/lib/libcxx/include/forward_list index 7b820413720..571afdc925b 100644 --- a/lib/libcxx/include/forward_list +++ b/lib/libcxx/include/forward_list @@ -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> diff --git a/lib/libcxx/include/fstream b/lib/libcxx/include/fstream index f57908c8dfa..332b4747c1a 100644 --- a/lib/libcxx/include/fstream +++ b/lib/libcxx/include/fstream @@ -38,6 +38,7 @@ public: bool is_open() const; basic_filebuf* open(const char* s, ios_base::openmode mode); basic_filebuf* open(const string& s, ios_base::openmode mode); + basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17 basic_filebuf* close(); protected: @@ -77,6 +78,8 @@ public: basic_ifstream(); explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); + explicit basic_ifstream(const filesystem::path& p, + ios_base::openmode mode = ios_base::in); // C++17 basic_ifstream(basic_ifstream&& rhs); basic_ifstream& operator=(basic_ifstream&& rhs); @@ -86,6 +89,8 @@ public: bool is_open() const; void open(const char* s, ios_base::openmode mode = ios_base::in); void open(const string& s, ios_base::openmode mode = ios_base::in); + void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17 + void close(); }; @@ -110,6 +115,8 @@ public: basic_ofstream(); explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); + explicit basic_ofstream(const filesystem::path& p, + ios_base::openmode mode = ios_base::out); // C++17 basic_ofstream(basic_ofstream&& rhs); basic_ofstream& operator=(basic_ofstream&& rhs); @@ -119,6 +126,9 @@ public: bool is_open() const; void open(const char* s, ios_base::openmode mode = ios_base::out); void open(const string& s, ios_base::openmode mode = ios_base::out); + void open(const filesystem::path& p, + ios_base::openmode mode = ios_base::out); // C++17 + void close(); }; @@ -143,6 +153,8 @@ public: basic_fstream(); explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); + explicit basic_fstream(const filesystem::path& p, + ios_base::openmode mode = ios_base::in|ios_base::out); C++17 basic_fstream(basic_fstream&& rhs); basic_fstream& operator=(basic_fstream&& rhs); @@ -152,6 +164,9 @@ public: bool is_open() const; void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out); void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out); + void open(const filesystem::path& s, + ios_base::openmode mode = ios_base::in|ios_base::out); // C++17 + void close(); }; @@ -170,6 +185,8 @@ typedef basic_fstream<wchar_t> wfstream; #include <istream> #include <__locale> #include <cstdio> +#include <cstdlib> +#include <filesystem> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -212,12 +229,28 @@ public: bool is_open() const; #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE basic_filebuf* open(const char* __s, ios_base::openmode __mode); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode); +#endif _LIBCPP_INLINE_VISIBILITY basic_filebuf* open(const string& __s, ios_base::openmode __mode); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_INLINE_VISIBILITY + basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) { + return open(__p.c_str(), __mode); + } +#endif + _LIBCPP_INLINE_VISIBILITY + basic_filebuf* __open(int __fd, ios_base::openmode __mode); #endif basic_filebuf* close(); -protected: + _LIBCPP_INLINE_VISIBILITY + inline static const char* + __make_mdstring(ios_base::openmode __mode) _NOEXCEPT; + + protected: // 27.9.1.5 Overridden virtual functions: virtual int_type underflow(); virtual int_type pbackfail(int_type __c = traits_type::eof()); @@ -231,25 +264,25 @@ protected: virtual void imbue(const locale& __loc); private: - char* __extbuf_; - const char* __extbufnext_; - const char* __extbufend_; - char __extbuf_min_[8]; - size_t __ebs_; - char_type* __intbuf_; - size_t __ibs_; - FILE* __file_; - const codecvt<char_type, char, state_type>* __cv_; - state_type __st_; - state_type __st_last_; - ios_base::openmode __om_; - ios_base::openmode __cm_; - bool __owns_eb_; - bool __owns_ib_; - bool __always_noconv_; - - bool __read_mode(); - void __write_mode(); + char* __extbuf_; + const char* __extbufnext_; + const char* __extbufend_; + char __extbuf_min_[8]; + size_t __ebs_; + char_type* __intbuf_; + size_t __ibs_; + FILE* __file_; + const codecvt<char_type, char, state_type>* __cv_; + state_type __st_; + state_type __st_last_; + ios_base::openmode __om_; + ios_base::openmode __cm_; + bool __owns_eb_; + bool __owns_ib_; + bool __always_noconv_; + + bool __read_mode(); + void __write_mode(); }; template <class _CharT, class _Traits> @@ -470,6 +503,46 @@ basic_filebuf<_CharT, _Traits>::is_open() const return __file_ != 0; } +template <class _CharT, class _Traits> +const char* basic_filebuf<_CharT, _Traits>::__make_mdstring( + ios_base::openmode __mode) _NOEXCEPT { + switch (__mode & ~ios_base::ate) { + case ios_base::out: + case ios_base::out | ios_base::trunc: + return "w"; + case ios_base::out | ios_base::app: + case ios_base::app: + return "a"; + case ios_base::in: + return "r"; + case ios_base::in | ios_base::out: + return "r+"; + case ios_base::in | ios_base::out | ios_base::trunc: + return "w+"; + case ios_base::in | ios_base::out | ios_base::app: + case ios_base::in | ios_base::app: + return "a+"; + case ios_base::out | ios_base::binary: + case ios_base::out | ios_base::trunc | ios_base::binary: + return "wb"; + case ios_base::out | ios_base::app | ios_base::binary: + case ios_base::app | ios_base::binary: + return "ab"; + case ios_base::in | ios_base::binary: + return "rb"; + case ios_base::in | ios_base::out | ios_base::binary: + return "r+b"; + case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: + return "w+b"; + case ios_base::in | ios_base::out | ios_base::app | ios_base::binary: + case ios_base::in | ios_base::app | ios_base::binary: + return "a+b"; + default: + return nullptr; + } + _LIBCPP_UNREACHABLE(); +} + #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE template <class _CharT, class _Traits> basic_filebuf<_CharT, _Traits>* @@ -478,51 +551,104 @@ basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) basic_filebuf<_CharT, _Traits>* __rt = 0; if (__file_ == 0) { + if (const char* __mdstr = __make_mdstring(__mode)) { __rt = this; - const char* __mdstr; + __file_ = fopen(__s, __mdstr); + if (__file_) { + __om_ = __mode; + if (__mode & ios_base::ate) { + if (fseek(__file_, 0, SEEK_END)) { + fclose(__file_); + __file_ = 0; + __rt = 0; + } + } + } else + __rt = 0; + } + } + return __rt; +} + +template <class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) { + basic_filebuf<_CharT, _Traits>* __rt = 0; + if (__file_ == 0) { + if (const char* __mdstr = __make_mdstring(__mode)) { + __rt = this; + __file_ = fdopen(__fd, __mdstr); + if (__file_) { + __om_ = __mode; + if (__mode & ios_base::ate) { + if (fseek(__file_, 0, SEEK_END)) { + fclose(__file_); + __file_ = 0; + __rt = 0; + } + } + } else + __rt = 0; + } + } + return __rt; +} + +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +// This is basically the same as the char* overload except that it uses _wfopen +// and long mode strings. +template <class _CharT, class _Traits> +basic_filebuf<_CharT, _Traits>* +basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) +{ + basic_filebuf<_CharT, _Traits>* __rt = 0; + if (__file_ == 0) + { + __rt = this; + const wchar_t* __mdstr; switch (__mode & ~ios_base::ate) { case ios_base::out: case ios_base::out | ios_base::trunc: - __mdstr = "w"; + __mdstr = L"w"; break; case ios_base::out | ios_base::app: case ios_base::app: - __mdstr = "a"; + __mdstr = L"a"; break; case ios_base::in: - __mdstr = "r"; + __mdstr = L"r"; break; case ios_base::in | ios_base::out: - __mdstr = "r+"; + __mdstr = L"r+"; break; case ios_base::in | ios_base::out | ios_base::trunc: - __mdstr = "w+"; + __mdstr = L"w+"; break; case ios_base::in | ios_base::out | ios_base::app: case ios_base::in | ios_base::app: - __mdstr = "a+"; + __mdstr = L"a+"; break; case ios_base::out | ios_base::binary: case ios_base::out | ios_base::trunc | ios_base::binary: - __mdstr = "wb"; + __mdstr = L"wb"; break; case ios_base::out | ios_base::app | ios_base::binary: case ios_base::app | ios_base::binary: - __mdstr = "ab"; + __mdstr = L"ab"; break; case ios_base::in | ios_base::binary: - __mdstr = "rb"; + __mdstr = L"rb"; break; case ios_base::in | ios_base::out | ios_base::binary: - __mdstr = "r+b"; + __mdstr = L"r+b"; break; case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: - __mdstr = "w+b"; + __mdstr = L"w+b"; break; case ios_base::in | ios_base::out | ios_base::app | ios_base::binary: case ios_base::in | ios_base::app | ios_base::binary: - __mdstr = "a+b"; + __mdstr = L"a+b"; break; default: __rt = 0; @@ -530,7 +656,7 @@ basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) } if (__rt) { - __file_ = fopen(__s, __mdstr); + __file_ = _wfopen(__s, __mdstr); if (__file_) { __om_ = __mode; @@ -550,6 +676,7 @@ basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) } return __rt; } +#endif template <class _CharT, class _Traits> inline @@ -1017,8 +1144,17 @@ public: #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE _LIBCPP_INLINE_VISIBILITY explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + _LIBCPP_INLINE_VISIBILITY + explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in); +#endif _LIBCPP_INLINE_VISIBILITY explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in); +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_INLINE_VISIBILITY + explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) + : basic_ifstream(__p.c_str(), __mode) {} +#endif // _LIBCPP_STD_VER >= 17 #endif #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY @@ -1036,7 +1172,20 @@ public: bool is_open() const; #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE void open(const char* __s, ios_base::openmode __mode = ios_base::in); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in); +#endif void open(const string& __s, ios_base::openmode __mode = ios_base::in); +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_INLINE_VISIBILITY + void open(const filesystem::path& __p, + ios_base::openmode __mode = ios_base::in) { + return open(__p.c_str(), __mode); + } +#endif // _LIBCPP_STD_VER >= 17 + + _LIBCPP_INLINE_VISIBILITY + void __open(int __fd, ios_base::openmode __mode); #endif _LIBCPP_INLINE_VISIBILITY void close(); @@ -1062,6 +1211,17 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openm this->setstate(ios_base::failbit); } +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template <class _CharT, class _Traits> +inline +basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode) + : basic_istream<char_type, traits_type>(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::in) == 0) + this->setstate(ios_base::failbit); +} +#endif + template <class _CharT, class _Traits> inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode) @@ -1139,6 +1299,18 @@ basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode this->setstate(ios_base::failbit); } +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template <class _CharT, class _Traits> +void +basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::in)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + template <class _CharT, class _Traits> void basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) @@ -1148,6 +1320,15 @@ basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo else this->setstate(ios_base::failbit); } + +template <class _CharT, class _Traits> +void basic_ifstream<_CharT, _Traits>::__open(int __fd, + ios_base::openmode __mode) { + if (__sb_.__open(__fd, __mode | ios_base::in)) + this->clear(); + else + this->setstate(ios_base::failbit); +} #endif template <class _CharT, class _Traits> @@ -1176,8 +1357,19 @@ public: basic_ofstream(); _LIBCPP_INLINE_VISIBILITY explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + _LIBCPP_INLINE_VISIBILITY + explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out); +#endif _LIBCPP_INLINE_VISIBILITY explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_INLINE_VISIBILITY + explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) + : basic_ofstream(__p.c_str(), __mode) {} +#endif // _LIBCPP_STD_VER >= 17 + #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY basic_ofstream(basic_ofstream&& __rhs); @@ -1194,7 +1386,19 @@ public: bool is_open() const; #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE void open(const char* __s, ios_base::openmode __mode = ios_base::out); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out); +#endif void open(const string& __s, ios_base::openmode __mode = ios_base::out); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_INLINE_VISIBILITY + void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) + { return open(__p.c_str(), __mode); } +#endif // _LIBCPP_STD_VER >= 17 + + _LIBCPP_INLINE_VISIBILITY + void __open(int __fd, ios_base::openmode __mode); #endif _LIBCPP_INLINE_VISIBILITY void close(); @@ -1220,6 +1424,17 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openm this->setstate(ios_base::failbit); } +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template <class _CharT, class _Traits> +inline +basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode) + : basic_ostream<char_type, traits_type>(&__sb_) +{ + if (__sb_.open(__s, __mode | ios_base::out) == 0) + this->setstate(ios_base::failbit); +} +#endif + template <class _CharT, class _Traits> inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode) @@ -1297,6 +1512,18 @@ basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode this->setstate(ios_base::failbit); } +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template <class _CharT, class _Traits> +void +basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode | ios_base::out)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + template <class _CharT, class _Traits> void basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) @@ -1306,6 +1533,15 @@ basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo else this->setstate(ios_base::failbit); } + +template <class _CharT, class _Traits> +void basic_ofstream<_CharT, _Traits>::__open(int __fd, + ios_base::openmode __mode) { + if (__sb_.__open(__fd, __mode | ios_base::out)) + this->clear(); + else + this->setstate(ios_base::failbit); +} #endif template <class _CharT, class _Traits> @@ -1335,8 +1571,19 @@ public: #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE _LIBCPP_INLINE_VISIBILITY explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + _LIBCPP_INLINE_VISIBILITY + explicit basic_fstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#endif _LIBCPP_INLINE_VISIBILITY explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_INLINE_VISIBILITY + explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) + : basic_fstream(__p.c_str(), __mode) {} +#endif // _LIBCPP_STD_VER >= 17 + #endif #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY @@ -1354,7 +1601,17 @@ public: bool is_open() const; #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR + void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); +#endif void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); + +#if _LIBCPP_STD_VER >= 17 + _LIBCPP_INLINE_VISIBILITY + void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in|ios_base::out) + { return open(__p.c_str(), __mode); } +#endif // _LIBCPP_STD_VER >= 17 + #endif _LIBCPP_INLINE_VISIBILITY void close(); @@ -1380,6 +1637,17 @@ basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmod this->setstate(ios_base::failbit); } +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template <class _CharT, class _Traits> +inline +basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode) + : basic_iostream<char_type, traits_type>(&__sb_) +{ + if (__sb_.open(__s, __mode) == 0) + this->setstate(ios_base::failbit); +} +#endif + template <class _CharT, class _Traits> inline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode) @@ -1457,6 +1725,18 @@ basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) this->setstate(ios_base::failbit); } +#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR +template <class _CharT, class _Traits> +void +basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) +{ + if (__sb_.open(__s, __mode)) + this->clear(); + else + this->setstate(ios_base::failbit); +} +#endif + template <class _CharT, class _Traits> void basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) diff --git a/lib/libcxx/include/functional b/lib/libcxx/include/functional index 3e5215b137b..6b70f731e1c 100644 --- a/lib/libcxx/include/functional +++ b/lib/libcxx/include/functional @@ -1399,7 +1399,7 @@ public: #endif }; -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_bad_function_call() { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -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; } @@ -2008,7 +2005,7 @@ namespace placeholders template <int _Np> struct __ph {}; -#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND) +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) _LIBCPP_FUNC_VIS extern const __ph<1> _1; _LIBCPP_FUNC_VIS extern const __ph<2> _2; _LIBCPP_FUNC_VIS extern const __ph<3> _3; @@ -2030,7 +2027,7 @@ _LIBCPP_FUNC_VIS extern const __ph<10> _10; /* _LIBCPP_INLINE_VAR */ constexpr __ph<8> _8{}; /* _LIBCPP_INLINE_VAR */ constexpr __ph<9> _9{}; /* _LIBCPP_INLINE_VAR */ constexpr __ph<10> _10{}; -#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND) +#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) } // placeholders @@ -2411,6 +2408,117 @@ __not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&& __fn) { // struct hash<T*> in <memory> +template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> +pair<_ForwardIterator1, _ForwardIterator1> _LIBCPP_CONSTEXPR_AFTER_CXX11 +__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, + forward_iterator_tag, forward_iterator_tag) +{ + if (__first2 == __last2) + return make_pair(__first1, __first1); // Everything matches an empty sequence + while (true) + { + // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks + while (true) + { + if (__first1 == __last1) // return __last1 if no element matches *__first2 + return make_pair(__last1, __last1); + if (__pred(*__first1, *__first2)) + break; + ++__first1; + } + // *__first1 matches *__first2, now match elements after here + _ForwardIterator1 __m1 = __first1; + _ForwardIterator2 __m2 = __first2; + while (true) + { + if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) + return make_pair(__first1, __m1); + if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found + return make_pair(__last1, __last1); + if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 + { + ++__first1; + break; + } // else there is a match, check next elements + } + } +} + +template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> +_LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_RandomAccessIterator1, _RandomAccessIterator1> +__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, + random_access_iterator_tag, random_access_iterator_tag) +{ + typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; + typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; + // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern + const _D2 __len2 = __last2 - __first2; + if (__len2 == 0) + return make_pair(__first1, __first1); + const _D1 __len1 = __last1 - __first1; + if (__len1 < __len2) + return make_pair(__last1, __last1); + const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here + + while (true) + { + while (true) + { + if (__first1 == __s) + return make_pair(__last1, __last1); + if (__pred(*__first1, *__first2)) + break; + ++__first1; + } + + _RandomAccessIterator1 __m1 = __first1; + _RandomAccessIterator2 __m2 = __first2; + while (true) + { + if (++__m2 == __last2) + return make_pair(__first1, __first1 + __len2); + ++__m1; // no need to check range on __m1 because __s guarantees we have enough source + if (!__pred(*__m1, *__m2)) + { + ++__first1; + break; + } + } + } +} + +#if _LIBCPP_STD_VER > 14 + +// default searcher +template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> +class _LIBCPP_TYPE_VIS default_searcher { +public: + _LIBCPP_INLINE_VISIBILITY + default_searcher(_ForwardIterator __f, _ForwardIterator __l, + _BinaryPredicate __p = _BinaryPredicate()) + : __first_(__f), __last_(__l), __pred_(__p) {} + + template <typename _ForwardIterator2> + _LIBCPP_INLINE_VISIBILITY + pair<_ForwardIterator2, _ForwardIterator2> + operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const + { + return _VSTD::__search(__f, __l, __first_, __last_, __pred_, + typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category(), + typename _VSTD::iterator_traits<_ForwardIterator2>::iterator_category()); + } + +private: + _ForwardIterator __first_; + _ForwardIterator __last_; + _BinaryPredicate __pred_; + }; + +#endif // _LIBCPP_STD_VER > 14 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_FUNCTIONAL diff --git a/lib/libcxx/include/future b/lib/libcxx/include/future index a7c28a4746c..0f6d42678ef 100644 --- a/lib/libcxx/include/future +++ b/lib/libcxx/include/future @@ -409,7 +409,7 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch) #ifndef _LIBCPP_HAS_NO_STRONG_ENUMS -#ifdef _LIBCXX_UNDERLYING_TYPE +#ifdef _LIBCPP_UNDERLYING_TYPE typedef underlying_type<launch>::type __launch_underlying_type; #else typedef int __launch_underlying_type; @@ -514,7 +514,7 @@ public: virtual ~future_error() _NOEXCEPT; }; -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_NO_EXCEPTIONS _LIBCPP_AVAILABILITY_FUTURE_ERROR #endif @@ -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 diff --git a/lib/libcxx/include/initializer_list b/lib/libcxx/include/initializer_list index 8c234aaaab2..b934637b83d 100644 --- a/lib/libcxx/include/initializer_list +++ b/lib/libcxx/include/initializer_list @@ -61,7 +61,7 @@ class _LIBCPP_TEMPLATE_VIS initializer_list const _Ep* __begin_; size_t __size_; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 initializer_list(const _Ep* __b, size_t __s) _NOEXCEPT : __begin_(__b), @@ -76,19 +76,19 @@ public: typedef const _Ep* iterator; typedef const _Ep* const_iterator; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 size_t size() const _NOEXCEPT {return __size_;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Ep* begin() const _NOEXCEPT {return __begin_;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Ep* end() const _NOEXCEPT {return __begin_ + __size_;} }; diff --git a/lib/libcxx/include/ios b/lib/libcxx/include/ios index 61d00b90ee0..040b2d4e04f 100644 --- a/lib/libcxx/include/ios +++ b/lib/libcxx/include/ios @@ -337,9 +337,9 @@ protected: } void init(void* __sb); - _LIBCPP_ALWAYS_INLINE void* rdbuf() const {return __rdbuf_;} + _LIBCPP_INLINE_VISIBILITY void* rdbuf() const {return __rdbuf_;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void rdbuf(void* __sb) { __rdbuf_ = __sb; @@ -351,7 +351,7 @@ protected: void move(ios_base&); void swap(ios_base&) _NOEXCEPT; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void set_rdbuf(void* __sb) { __rdbuf_ = __sb; @@ -592,30 +592,33 @@ public: typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; + static_assert((is_same<_CharT, typename traits_type::char_type>::value), + "traits_type::char_type must be the same type as CharT"); + // __true_value will generate undefined references when linking unless // we give it internal linkage. #if defined(_LIBCPP_CXX03_LANG) - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY operator __cxx03_bool::__bool_type() const { return !fail() ? &__cxx03_bool::__true_value : nullptr; } #else - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const {return !fail();} #endif - _LIBCPP_ALWAYS_INLINE bool operator!() const {return fail();} - _LIBCPP_ALWAYS_INLINE iostate rdstate() const {return ios_base::rdstate();} - _LIBCPP_ALWAYS_INLINE void clear(iostate __state = goodbit) {ios_base::clear(__state);} - _LIBCPP_ALWAYS_INLINE void setstate(iostate __state) {ios_base::setstate(__state);} - _LIBCPP_ALWAYS_INLINE bool good() const {return ios_base::good();} - _LIBCPP_ALWAYS_INLINE bool eof() const {return ios_base::eof();} - _LIBCPP_ALWAYS_INLINE bool fail() const {return ios_base::fail();} - _LIBCPP_ALWAYS_INLINE bool bad() const {return ios_base::bad();} + _LIBCPP_INLINE_VISIBILITY bool operator!() const {return fail();} + _LIBCPP_INLINE_VISIBILITY iostate rdstate() const {return ios_base::rdstate();} + _LIBCPP_INLINE_VISIBILITY void clear(iostate __state = goodbit) {ios_base::clear(__state);} + _LIBCPP_INLINE_VISIBILITY void setstate(iostate __state) {ios_base::setstate(__state);} + _LIBCPP_INLINE_VISIBILITY bool good() const {return ios_base::good();} + _LIBCPP_INLINE_VISIBILITY bool eof() const {return ios_base::eof();} + _LIBCPP_INLINE_VISIBILITY bool fail() const {return ios_base::fail();} + _LIBCPP_INLINE_VISIBILITY bool bad() const {return ios_base::bad();} - _LIBCPP_ALWAYS_INLINE iostate exceptions() const {return ios_base::exceptions();} - _LIBCPP_ALWAYS_INLINE void exceptions(iostate __iostate) {ios_base::exceptions(__iostate);} + _LIBCPP_INLINE_VISIBILITY iostate exceptions() const {return ios_base::exceptions();} + _LIBCPP_INLINE_VISIBILITY void exceptions(iostate __iostate) {ios_base::exceptions(__iostate);} // 27.5.4.1 Constructor/destructor: _LIBCPP_INLINE_VISIBILITY @@ -649,7 +652,7 @@ public: char_type widen(char __c) const; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY basic_ios() {// purposefully does no initialization } _LIBCPP_INLINE_VISIBILITY @@ -658,7 +661,7 @@ protected: _LIBCPP_INLINE_VISIBILITY void move(basic_ios& __rhs); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void move(basic_ios&& __rhs) {move(__rhs);} #endif _LIBCPP_INLINE_VISIBILITY @@ -667,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> diff --git a/lib/libcxx/include/istream b/lib/libcxx/include/istream index 5c73df38f65..71c162b0d41 100644 --- a/lib/libcxx/include/istream +++ b/lib/libcxx/include/istream @@ -358,381 +358,162 @@ basic_istream<_CharT, _Traits>::~basic_istream() { } -template <class _CharT, class _Traits> +template <class _Tp, class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n) -{ +__input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) { #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); + typename basic_istream<_CharT, _Traits>::sentry __s(__is); if (__s) { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; + typedef istreambuf_iterator<_CharT, _Traits> _Ip; + typedef num_get<_CharT, _Ip> _Fp; ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); + use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __err, __n); + __is.setstate(__err); } #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - this->__set_badbit_and_consider_rethrow(); + __is.__set_badbit_and_consider_rethrow(); } #endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return __is; +} + +template <class _CharT, class _Traits> +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n) +{ + return _VSTD::__input_arithmetic<unsigned short>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(unsigned int& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<unsigned int>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(long& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<long>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(unsigned long& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<unsigned long>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(long long& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<long long>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(unsigned long long& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<unsigned long long>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(float& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<float>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(double& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<double>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(long double& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<long double>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(bool& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<bool>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(void*& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic<void*>(*this, __n); } -template <class _CharT, class _Traits> +template <class _Tp, class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::operator>>(short& __n) -{ +__input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp& __n) { #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); + typename basic_istream<_CharT, _Traits>::sentry __s(__is); if (__s) { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; + typedef istreambuf_iterator<_CharT, _Traits> _Ip; + typedef num_get<_CharT, _Ip> _Fp; ios_base::iostate __err = ios_base::goodbit; long __temp; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp); - if (__temp < numeric_limits<short>::min()) + use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __err, __temp); + if (__temp < numeric_limits<_Tp>::min()) { __err |= ios_base::failbit; - __n = numeric_limits<short>::min(); + __n = numeric_limits<_Tp>::min(); } - else if (__temp > numeric_limits<short>::max()) + else if (__temp > numeric_limits<_Tp>::max()) { __err |= ios_base::failbit; - __n = numeric_limits<short>::max(); + __n = numeric_limits<_Tp>::max(); } else - __n = static_cast<short>(__temp); - this->setstate(__err); + __n = static_cast<_Tp>(__temp); + __is.setstate(__err); } #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - this->__set_badbit_and_consider_rethrow(); + __is.__set_badbit_and_consider_rethrow(); } #endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return __is; +} + +template <class _CharT, class _Traits> +basic_istream<_CharT, _Traits>& +basic_istream<_CharT, _Traits>::operator>>(short& __n) +{ + return _VSTD::__input_arithmetic_with_numeric_limits<short>(*this, __n); } template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(int& __n) { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - sentry __s(*this); - if (__s) - { - typedef istreambuf_iterator<char_type, traits_type> _Ip; - typedef num_get<char_type, _Ip> _Fp; - ios_base::iostate __err = ios_base::goodbit; - long __temp; - use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp); - if (__temp < numeric_limits<int>::min()) - { - __err |= ios_base::failbit; - __n = numeric_limits<int>::min(); - } - else if (__temp > numeric_limits<int>::max()) - { - __err |= ios_base::failbit; - __n = numeric_limits<int>::max(); - } - else - __n = static_cast<int>(__temp); - this->setstate(__err); - } -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - this->__set_badbit_and_consider_rethrow(); - } -#endif // _LIBCPP_NO_EXCEPTIONS - return *this; + return _VSTD::__input_arithmetic_with_numeric_limits<int>(*this, __n); } template<class _CharT, class _Traits> @@ -960,7 +741,6 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __ ++__gc_; this->rdbuf()->sbumpc(); } - *__s = char_type(); if (__gc_ == 0) __err |= ios_base::failbit; this->setstate(__err); @@ -968,10 +748,14 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __ else this->setstate(ios_base::failbit); } + if (__n > 0) + *__s = char_type(); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { + if (__n > 0) + *__s = char_type(); this->__set_badbit_and_consider_rethrow(); } #endif // _LIBCPP_NO_EXCEPTIONS diff --git a/lib/libcxx/include/iterator b/lib/libcxx/include/iterator index 8b887db037b..9415e0b8396 100644 --- a/lib/libcxx/include/iterator +++ b/lib/libcxx/include/iterator @@ -1217,38 +1217,38 @@ make_move_iterator(_Iter __i) template <class _Iter> class __wrap_iter; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG -> decltype(__x.base() - __y.base()); @@ -1260,7 +1260,7 @@ operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBU #endif template <class _Iter> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter<_Iter> operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT_DEBUG; @@ -1272,7 +1272,7 @@ template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, #if _LIBCPP_DEBUG_LEVEL < 2 template <class _Tp> -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1283,7 +1283,7 @@ __unwrap_iter(__wrap_iter<_Tp*>); #else template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1306,7 +1306,7 @@ public: private: iterator_type __i; public: - _LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT_DEBUG #if _LIBCPP_STD_VER > 11 : __i{} #endif @@ -1315,22 +1315,23 @@ public: __get_db()->__insert_i(this); #endif } - template <class _Up> _LIBCPP_INLINE_VISIBILITY __wrap_iter(const __wrap_iter<_Up>& __u, - typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT_DEBUG - : __i(__u.base()) + template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG + __wrap_iter(const __wrap_iter<_Up>& __u, + typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT_DEBUG + : __i(__u.base()) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__iterator_copy(this, &__u); #endif } #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const __wrap_iter& __x) : __i(__x.base()) { __get_db()->__iterator_copy(this, &__x); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator=(const __wrap_iter& __x) { if (this != &__x) @@ -1340,13 +1341,13 @@ public: } return *this; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG ~__wrap_iter() { __get_db()->__erase_i(this); } #endif - _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), @@ -1354,7 +1355,7 @@ public: #endif return *__i; } - _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer operator->() const _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), @@ -1362,7 +1363,7 @@ public: #endif return (pointer)_VSTD::addressof(*__i); } - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), @@ -1371,9 +1372,10 @@ public: ++__i; return *this; } - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator++(int) _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator++(int) _NOEXCEPT_DEBUG {__wrap_iter __tmp(*this); ++(*this); return __tmp;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT_DEBUG + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), @@ -1382,11 +1384,11 @@ public: --__i; return *this; } - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator--(int) _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator--(int) _NOEXCEPT_DEBUG {__wrap_iter __tmp(*this); --(*this); return __tmp;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator+ (difference_type __n) const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator+ (difference_type __n) const _NOEXCEPT_DEBUG {__wrap_iter __w(*this); __w += __n; return __w;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n), @@ -1395,11 +1397,11 @@ public: __i += __n; return *this; } - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator- (difference_type __n) const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter operator- (difference_type __n) const _NOEXCEPT_DEBUG {return *this + (-__n);} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT_DEBUG {*this += -__n; return *this;} - _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const _NOEXCEPT_DEBUG + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator[](difference_type __n) const _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n), @@ -1408,67 +1410,68 @@ public: return __i[__n]; } - _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT_DEBUG {return __i;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT_DEBUG {return __i;} private: #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(const void* __p, iterator_type __x) : __i(__x) { __get_db()->__insert_ic(this, __p); } #else - _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT_DEBUG : __i(__x) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT_DEBUG : __i(__x) {} #endif template <class _Up> friend class __wrap_iter; template <class _CharT, class _Traits, class _Alloc> friend class basic_string; template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector; + template <class _Tp, ptrdiff_t> friend class _LIBCPP_TEMPLATE_VIS span; template <class _Iter1, class _Iter2> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend bool operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend bool operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend bool operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend bool operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend bool operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG -> decltype(__x.base() - __y.base()); #else template <class _Iter1, class _Iter2> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #endif template <class _Iter1> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT_DEBUG; @@ -1479,7 +1482,7 @@ private: #if _LIBCPP_DEBUG_LEVEL < 2 template <class _Tp> - friend + _LIBCPP_CONSTEXPR_IF_NODEBUG friend typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1488,7 +1491,7 @@ private: __unwrap_iter(__wrap_iter<_Tp*>); #else template <class _Tp> - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1499,7 +1502,7 @@ private: }; template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1507,7 +1510,7 @@ operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1519,7 +1522,7 @@ operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1527,7 +1530,7 @@ operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1535,7 +1538,7 @@ operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1543,7 +1546,7 @@ operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1551,7 +1554,7 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX } template <class _Iter1> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { @@ -1559,7 +1562,7 @@ operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX } template <class _Iter1> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { @@ -1567,7 +1570,7 @@ operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXC } template <class _Iter1> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { @@ -1575,7 +1578,7 @@ operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX } template <class _Iter1> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { @@ -1584,7 +1587,7 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG auto operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG -> decltype(__x.base() - __y.base()) @@ -1597,7 +1600,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC } #else template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { @@ -1610,7 +1613,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC #endif template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter<_Iter> operator+(typename __wrap_iter<_Iter>::difference_type __n, __wrap_iter<_Iter> __x) _NOEXCEPT_DEBUG diff --git a/lib/libcxx/include/list b/lib/libcxx/include/list index 32e9a27bd2a..d2e78cd66af 100644 --- a/lib/libcxx/include/list +++ b/lib/libcxx/include/list @@ -147,6 +147,11 @@ public: void reverse() noexcept; }; + +template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> + list(InputIterator, InputIterator, Allocator = Allocator()) + -> list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 + template <class T, class Alloc> bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y); template <class T, class Alloc> @@ -527,11 +532,12 @@ class __list_imp { __list_imp(const __list_imp&); __list_imp& operator=(const __list_imp&); -protected: - typedef _Tp value_type; +public: typedef _Alloc allocator_type; typedef allocator_traits<allocator_type> __alloc_traits; typedef typename __alloc_traits::size_type size_type; +protected: + typedef _Tp value_type; typedef typename __alloc_traits::void_pointer __void_pointer; typedef __list_iterator<value_type, __void_pointer> iterator; typedef __list_const_iterator<value_type, __void_pointer> const_iterator; @@ -550,6 +556,9 @@ protected: typedef typename __rebind_alloc_helper<__alloc_traits, __node_base>::type __node_base_allocator; typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer; + static_assert((!is_same<allocator_type, __node_allocator>::value), + "internal allocator type must differ from user-specified " + "type; otherwise overload resolution breaks"); __node_base __end_; __compressed_pair<size_type, __node_allocator> __size_alloc_; @@ -584,6 +593,11 @@ protected: _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value); _LIBCPP_INLINE_VISIBILITY __list_imp(const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY + __list_imp(const __node_allocator& __a); +#ifndef _LIBCPP_CXX03_LANG + __list_imp(__node_allocator&& __a) _NOEXCEPT; +#endif ~__list_imp(); void clear() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY @@ -707,9 +721,18 @@ __list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a) } template <class _Tp, class _Alloc> -__list_imp<_Tp, _Alloc>::~__list_imp() -{ - clear(); +inline __list_imp<_Tp, _Alloc>::__list_imp(const __node_allocator& __a) + : __size_alloc_(0, __a) {} + +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp, class _Alloc> +inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT + : __size_alloc_(0, std::move(__a)) {} +#endif + +template <class _Tp, class _Alloc> +__list_imp<_Tp, _Alloc>::~__list_imp() { + clear(); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__erase_c(this); #endif @@ -1106,6 +1129,22 @@ private: void __move_assign(list& __c, false_type); }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template<class _InputIterator, + class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>, + class = typename enable_if<__is_allocator<_Alloc>::value, void>::type + > +list(_InputIterator, _InputIterator) + -> list<typename iterator_traits<_InputIterator>::value_type, _Alloc>; + +template<class _InputIterator, + class _Alloc, + class = typename enable_if<__is_allocator<_Alloc>::value, void>::type + > +list(_InputIterator, _InputIterator, _Alloc) + -> list<typename iterator_traits<_InputIterator>::value_type, _Alloc>; +#endif + // Link in nodes [__f, __l] just prior to __p template <class _Tp, class _Alloc> inline @@ -1226,10 +1265,8 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a, template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(const list& __c) - : base(allocator_type( - __node_alloc_traits::select_on_container_copy_construction( - __c.__node_alloc()))) -{ + : base(__node_alloc_traits::select_on_container_copy_construction( + __c.__node_alloc())) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif @@ -1274,11 +1311,9 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il) } template <class _Tp, class _Alloc> -inline -list<_Tp, _Alloc>::list(list&& __c) +inline list<_Tp, _Alloc>::list(list&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) - : base(allocator_type(_VSTD::move(__c.__node_alloc()))) -{ + : base(_VSTD::move(__c.__node_alloc())) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif @@ -2058,15 +2093,15 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con #endif if (__f != __l) { + __link_pointer __first = __f.__ptr_; + --__l; + __link_pointer __last = __l.__ptr_; if (this != &__c) { - size_type __s = _VSTD::distance(__f, __l); + size_type __s = _VSTD::distance(__f, __l) + 1; __c.__sz() -= __s; base::__sz() += __s; } - __link_pointer __first = __f.__ptr_; - --__l; - __link_pointer __last = __l.__ptr_; base::__unlink_nodes(__first, __last); __link_nodes(__p.__ptr_, __first, __last); #if _LIBCPP_DEBUG_LEVEL >= 2 diff --git a/lib/libcxx/include/locale b/lib/libcxx/include/locale index a86645d2cc4..e240799f383 100644 --- a/lib/libcxx/include/locale +++ b/lib/libcxx/include/locale @@ -573,81 +573,81 @@ public: typedef _CharT char_type; typedef _InputIterator iter_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit num_get(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long long& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned short& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned int& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, unsigned long long& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, float& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, double& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, long double& __v) const { return do_get(__b, __e, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const { @@ -657,7 +657,7 @@ public: static locale::id id; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~num_get() {} template <class _Fp> @@ -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; @@ -1260,60 +1261,60 @@ public: typedef _CharT char_type; typedef _OutputIterator iter_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit num_put(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, ios_base& __iob, char_type __fl, bool __v) const { return do_put(__s, __iob, __fl, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, ios_base& __iob, char_type __fl, long __v) const { return do_put(__s, __iob, __fl, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, ios_base& __iob, char_type __fl, long long __v) const { return do_put(__s, __iob, __fl, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long __v) const { return do_put(__s, __iob, __fl, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, ios_base& __iob, char_type __fl, unsigned long long __v) const { return do_put(__s, __iob, __fl, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, ios_base& __iob, char_type __fl, double __v) const { return do_put(__s, __iob, __fl, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, ios_base& __iob, char_type __fl, long double __v) const { return do_put(__s, __iob, __fl, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const void* __v) const { @@ -1323,7 +1324,7 @@ public: static locale::id id; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~num_put() {} virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, @@ -1737,7 +1738,7 @@ protected: virtual const string_type& __x() const; virtual const string_type& __X() const; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~__time_get_c_storage() {} }; @@ -1769,52 +1770,52 @@ public: typedef time_base::dateorder dateorder; typedef basic_string<char_type> string_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit time_get(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY dateorder date_order() const { return this->do_date_order(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { return do_get_time(__b, __e, __iob, __err, __tm); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { return do_get_date(__b, __e, __iob, __err, __tm); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { return do_get_weekday(__b, __e, __iob, __err, __tm); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { return do_get_monthname(__b, __e, __iob, __err, __tm); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { return do_get_year(__b, __e, __iob, __err, __tm); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm *__tm, char __fmt, char __mod = 0) const @@ -1829,7 +1830,7 @@ public: static locale::id id; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~time_get() {} virtual dateorder do_date_order() const; @@ -2398,7 +2399,7 @@ protected: explicit __time_get_storage(const char* __nm); explicit __time_get_storage(const string& __nm); - _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {} + _LIBCPP_INLINE_VISIBILITY ~__time_get_storage() {} time_base::dateorder __do_date_order() const; @@ -2457,7 +2458,7 @@ class _LIBCPP_TYPE_VIS __time_put { locale_t __loc_; protected: - _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} + _LIBCPP_INLINE_VISIBILITY __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} __time_put(const char* __nm); __time_put(const string& __nm); ~__time_put(); @@ -2476,14 +2477,14 @@ public: typedef _CharT char_type; typedef _OutputIterator iter_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit time_put(size_t __refs = 0) : locale::facet(__refs) {} iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe) const; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, char __fmt, char __mod = 0) const { @@ -2493,16 +2494,16 @@ public: static locale::id id; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~time_put() {} virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit time_put(const char* __nm, size_t __refs) : locale::facet(__refs), __time_put(__nm) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit time_put(const string& __nm, size_t __refs) : locale::facet(__refs), __time_put(__nm) {} @@ -2571,16 +2572,16 @@ class _LIBCPP_TEMPLATE_VIS time_put_byname : public time_put<_CharT, _OutputIterator> { public: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit time_put_byname(const char* __nm, size_t __refs = 0) : time_put<_CharT, _OutputIterator>(__nm, __refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit time_put_byname(const string& __nm, size_t __refs = 0) : time_put<_CharT, _OutputIterator>(__nm, __refs) {} protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~time_put_byname() {} }; @@ -2595,7 +2596,7 @@ public: enum part {none, space, symbol, sign, value}; struct pattern {char field[4];}; - _LIBCPP_ALWAYS_INLINE money_base() {} + _LIBCPP_INLINE_VISIBILITY money_base() {} }; // moneypunct @@ -2609,25 +2610,25 @@ public: typedef _CharT char_type; typedef basic_string<char_type> string_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit moneypunct(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} - _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} - _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} - _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();} - _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();} - _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();} - _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();} - _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();} - _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();} + _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} + _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} + _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} + _LIBCPP_INLINE_VISIBILITY string_type curr_symbol() const {return do_curr_symbol();} + _LIBCPP_INLINE_VISIBILITY string_type positive_sign() const {return do_positive_sign();} + _LIBCPP_INLINE_VISIBILITY string_type negative_sign() const {return do_negative_sign();} + _LIBCPP_INLINE_VISIBILITY int frac_digits() const {return do_frac_digits();} + _LIBCPP_INLINE_VISIBILITY pattern pos_format() const {return do_pos_format();} + _LIBCPP_INLINE_VISIBILITY pattern neg_format() const {return do_neg_format();} static locale::id id; static const bool intl = _International; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~moneypunct() {} virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();} @@ -2667,16 +2668,16 @@ public: typedef _CharT char_type; typedef basic_string<char_type> string_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit moneypunct_byname(const char* __nm, size_t __refs = 0) : moneypunct<_CharT, _International>(__refs) {init(__nm);} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit moneypunct_byname(const string& __nm, size_t __refs = 0) : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());} protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~moneypunct_byname() {} virtual char_type do_decimal_point() const {return __decimal_point_;} @@ -2722,7 +2723,7 @@ protected: typedef _CharT char_type; typedef basic_string<char_type> string_type; - _LIBCPP_ALWAYS_INLINE __money_get() {} + _LIBCPP_INLINE_VISIBILITY __money_get() {} static void __gather_info(bool __intl, const locale& __loc, money_base::pattern& __pat, char_type& __dp, @@ -2780,18 +2781,18 @@ public: typedef _InputIterator iter_type; typedef basic_string<char_type> string_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit money_get(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, long double& __v) const { return do_get(__b, __e, __intl, __iob, __err, __v); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, ios_base::iostate& __err, string_type& __v) const { @@ -2802,7 +2803,7 @@ public: protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~money_get() {} virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, @@ -3162,7 +3163,7 @@ protected: typedef _CharT char_type; typedef basic_string<char_type> string_type; - _LIBCPP_ALWAYS_INLINE __money_put() {} + _LIBCPP_INLINE_VISIBILITY __money_put() {} static void __gather_info(bool __intl, bool __neg, const locale& __loc, money_base::pattern& __pat, char_type& __dp, @@ -3338,18 +3339,18 @@ public: typedef _OutputIterator iter_type; typedef basic_string<char_type> string_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit money_put(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, long double __units) const { return do_put(__s, __intl, __iob, __fl, __units); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, const string_type& __digits) const { @@ -3359,7 +3360,7 @@ public: static locale::id id; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~money_put() {} virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, @@ -3488,7 +3489,7 @@ class _LIBCPP_TYPE_VIS messages_base public: typedef ptrdiff_t catalog; - _LIBCPP_ALWAYS_INLINE messages_base() {} + _LIBCPP_INLINE_VISIBILITY messages_base() {} }; template <class _CharT> @@ -3500,24 +3501,24 @@ public: typedef _CharT char_type; typedef basic_string<_CharT> string_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit messages(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY catalog open(const basic_string<char>& __nm, const locale& __loc) const { return do_open(__nm, __loc); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY string_type get(catalog __c, int __set, int __msgid, const string_type& __dflt) const { return do_get(__c, __set, __msgid, __dflt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void close(catalog __c) const { do_close(__c); @@ -3526,7 +3527,7 @@ public: static locale::id id; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~messages() {} virtual catalog do_open(const basic_string<char>&, const locale&) const; @@ -3599,16 +3600,16 @@ public: typedef messages_base::catalog catalog; typedef basic_string<_CharT> string_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit messages_byname(const char*, size_t __refs = 0) : messages<_CharT>(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit messages_byname(const string&, size_t __refs = 0) : messages<_CharT>(__refs) {} protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY ~messages_byname() {} }; @@ -3636,43 +3637,43 @@ private: wstring_convert(const wstring_convert& __wc); wstring_convert& operator=(const wstring_convert& __wc); public: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt); - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY wstring_convert(_Codecvt* __pcvt, state_type __state); _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err = wide_string()); #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY wstring_convert(wstring_convert&& __wc); #endif ~wstring_convert(); - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY wide_string from_bytes(char __byte) {return from_bytes(&__byte, &__byte+1);} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY wide_string from_bytes(const char* __ptr) {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY wide_string from_bytes(const byte_string& __str) {return from_bytes(__str.data(), __str.data() + __str.size());} wide_string from_bytes(const char* __first, const char* __last); - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY byte_string to_bytes(_Elem __wchar) {return to_bytes(&__wchar, &__wchar+1);} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY byte_string to_bytes(const _Elem* __wptr) {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY byte_string to_bytes(const wide_string& __wstr) {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());} byte_string to_bytes(const _Elem* __first, const _Elem* __last); - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY size_t converted() const _NOEXCEPT {return __cvtcount_;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY state_type state() const {return __cvtstate_;} }; diff --git a/lib/libcxx/include/map b/lib/libcxx/include/map index 95214938981..559ec484aca 100644 --- a/lib/libcxx/include/map +++ b/lib/libcxx/include/map @@ -40,6 +40,8 @@ public: typedef implementation-defined const_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef unspecified node_type; // C++17 + typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17 class value_compare : public binary_function<value_type, value_type, bool> @@ -137,6 +139,11 @@ public: void insert(InputIterator first, InputIterator last); void insert(initializer_list<value_type> il); + node_type extract(const_iterator position); // C++17 + node_type extract(const key_type& x); // C++17 + insert_return_type insert(node_type&& nh); // C++17 + iterator insert(const_iterator hint, node_type&& nh); // C++17 + template <class... Args> pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17 template <class... Args> @@ -260,6 +267,7 @@ public: typedef implementation-defined const_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef unspecified node_type; // C++17 class value_compare : public binary_function<value_type,value_type,bool> @@ -349,6 +357,11 @@ public: void insert(InputIterator first, InputIterator last); void insert(initializer_list<value_type> il); + node_type extract(const_iterator position); // C++17 + node_type extract(const key_type& x); // C++17 + iterator insert(node_type&& nh); // C++17 + iterator insert(const_iterator hint, node_type&& nh); // C++17 + iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); @@ -440,6 +453,7 @@ swap(multimap<Key, T, Compare, Allocator>& x, #include <__config> #include <__tree> +#include <__node_handle> #include <iterator> #include <memory> #include <utility> @@ -470,13 +484,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 +503,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 +532,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 +551,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 +611,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 +628,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 +696,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 +718,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 +768,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 +831,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 +876,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; @@ -854,6 +920,11 @@ public: typedef _VSTD::reverse_iterator<iterator> reverse_iterator; typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; +#if _LIBCPP_STD_VER > 14 + typedef __map_node_handle<typename __base::__node, allocator_type> node_type; + typedef __insert_return_type<iterator, node_type> insert_return_type; +#endif + _LIBCPP_INLINE_VISIBILITY map() _NOEXCEPT_( @@ -1201,6 +1272,35 @@ public: _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT {__tree_.clear();} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + insert_return_type insert(node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to map::insert()"); + return __tree_.template __node_handle_insert_unique< + node_type, insert_return_type>(_VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __hint, node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to map::insert()"); + return __tree_.template __node_handle_insert_unique<node_type>( + __hint.__i_, _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(key_type const& __key) + { + return __tree_.template __node_handle_extract<node_type>(__key); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(const_iterator __it) + { + return __tree_.template __node_handle_extract<node_type>(__it.__i_); + } +#endif + _LIBCPP_INLINE_VISIBILITY void swap(map& __m) _NOEXCEPT_(__is_nothrow_swappable<__base>::value) @@ -1228,7 +1328,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 +1375,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 +1408,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 +1419,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 +1429,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 +1440,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 +1460,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 +1475,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 +1488,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 +1565,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; @@ -1511,6 +1610,10 @@ public: typedef _VSTD::reverse_iterator<iterator> reverse_iterator; typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; +#if _LIBCPP_STD_VER > 14 + typedef __map_node_handle<typename __base::__node, allocator_type> node_type; +#endif + _LIBCPP_INLINE_VISIBILITY multimap() _NOEXCEPT_( @@ -1749,6 +1852,37 @@ public: _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __f, const_iterator __l) {return __tree_.erase(__f.__i_, __l.__i_);} + +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + iterator insert(node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to multimap::insert()"); + return __tree_.template __node_handle_insert_multi<node_type>( + _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __hint, node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to multimap::insert()"); + return __tree_.template __node_handle_insert_multi<node_type>( + __hint.__i_, _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(key_type const& __key) + { + return __tree_.template __node_handle_extract<node_type>(__key); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(const_iterator __it) + { + return __tree_.template __node_handle_extract<node_type>( + __it.__i_); + } +#endif + _LIBCPP_INLINE_VISIBILITY void clear() {__tree_.clear();} @@ -1852,7 +1986,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 diff --git a/lib/libcxx/include/math.h b/lib/libcxx/include/math.h index 8c30ba85d22..3cc72aa2791 100644 --- a/lib/libcxx/include/math.h +++ b/lib/libcxx/include/math.h @@ -314,7 +314,7 @@ extern "C++" { #ifdef signbit template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_signbit(_A1 __lcpp_x) _NOEXCEPT { @@ -376,7 +376,7 @@ signbit(_A1) _NOEXCEPT #ifdef fpclassify template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY int __libcpp_fpclassify(_A1 __lcpp_x) _NOEXCEPT { @@ -422,7 +422,7 @@ fpclassify(_A1 __lcpp_x) _NOEXCEPT #ifdef isfinite template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT { @@ -456,7 +456,7 @@ isfinite(_A1) _NOEXCEPT #ifdef isinf template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT { @@ -483,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 @@ -490,7 +504,7 @@ isinf(_A1) _NOEXCEPT #ifdef isnan template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT { @@ -513,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 @@ -520,7 +548,7 @@ isnan(_A1) _NOEXCEPT #ifdef isnormal template <class _A1> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_isnormal(_A1 __lcpp_x) _NOEXCEPT { @@ -550,7 +578,7 @@ isnormal(_A1 __lcpp_x) _NOEXCEPT #ifdef isgreater template <class _A1, class _A2> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT { @@ -580,7 +608,7 @@ isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT #ifdef isgreaterequal template <class _A1, class _A2> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT { @@ -610,7 +638,7 @@ isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT #ifdef isless template <class _A1, class _A2> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT { @@ -640,7 +668,7 @@ isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT #ifdef islessequal template <class _A1, class _A2> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT { @@ -670,7 +698,7 @@ islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT #ifdef islessgreater template <class _A1, class _A2> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT { @@ -700,7 +728,7 @@ islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT #ifdef isunordered template <class _A1, class _A2> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_INLINE_VISIBILITY bool __libcpp_isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT { @@ -1486,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 diff --git a/lib/libcxx/include/memory b/lib/libcxx/include/memory index d6b427b941b..adfe4f4fbbe 100644 --- a/lib/libcxx/include/memory +++ b/lib/libcxx/include/memory @@ -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; @@ -678,7 +679,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template <class _ValueType> -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY _ValueType __libcpp_relaxed_load(_ValueType const* __value) { #if !defined(_LIBCPP_HAS_NO_THREADS) && \ defined(__ATOMIC_RELAXED) && \ @@ -690,7 +691,7 @@ _ValueType __libcpp_relaxed_load(_ValueType const* __value) { } template <class _ValueType> -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY _ValueType __libcpp_acquire_load(_ValueType const* __value) { #if !defined(_LIBCPP_HAS_NO_THREADS) && \ defined(__ATOMIC_ACQUIRE) && \ @@ -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) @@ -1978,10 +1989,10 @@ public: _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {} _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;} _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element) - {::new(&*__x_) _Tp(__element); return *this;} + {::new(_VSTD::addressof(*__x_)) _Tp(__element); return *this;} #if _LIBCPP_STD_VER >= 14 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element) - {::new(&*__x_) _Tp(_VSTD::move(__element)); return *this;} + {::new(_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;} #endif _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;} _LIBCPP_INLINE_VISIBILITY raw_storage_iterator operator++(int) @@ -1992,6 +2003,7 @@ public: }; template <class _Tp> +_LIBCPP_NO_CFI pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { @@ -2003,7 +2015,28 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT __n = __m; while (__n > 0) { +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) + if (__is_overaligned_for_new(__alignof(_Tp))) + { + std::align_val_t __al = + std::align_val_t(std::alignment_of<_Tp>::value); + __r.first = static_cast<_Tp*>(::operator new( + __n * sizeof(_Tp), __al, nothrow)); + } else { + __r.first = static_cast<_Tp*>(::operator new( + __n * sizeof(_Tp), nothrow)); + } +#else + if (__is_overaligned_for_new(__alignof(_Tp))) + { + // Since aligned operator new is unavailable, return an empty + // buffer rather than one with invalid alignment. + return __r; + } + __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow)); +#endif + if (__r.first) { __r.second = __n; @@ -2016,7 +2049,10 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY -void return_temporary_buffer(_Tp* __p) _NOEXCEPT {::operator delete(__p);} +void return_temporary_buffer(_Tp* __p) _NOEXCEPT +{ + _VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp)); +} #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) template <class _Tp> @@ -3447,7 +3483,7 @@ public: virtual const char* what() const _NOEXCEPT; }; -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_bad_weak_ptr() { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -3475,7 +3511,7 @@ public: explicit __shared_count(long __refs = 0) _NOEXCEPT : __shared_owners_(__refs) {} -#if defined(_LIBCPP_BUILDING_MEMORY) && \ +#if defined(_LIBCPP_BUILDING_LIBRARY) && \ defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) void __add_shared() _NOEXCEPT; bool __release_shared() _NOEXCEPT; @@ -3513,7 +3549,7 @@ protected: virtual ~__shared_weak_count(); public: -#if defined(_LIBCPP_BUILDING_MEMORY) && \ +#if defined(_LIBCPP_BUILDING_LIBRARY) && \ defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) void __add_shared() _NOEXCEPT; void __add_weak() _NOEXCEPT; @@ -3646,7 +3682,7 @@ private: virtual void __on_zero_shared_weak() _NOEXCEPT; public: _LIBCPP_INLINE_VISIBILITY - _Tp* get() _NOEXCEPT {return &__data_.second();} + _Tp* get() _NOEXCEPT {return _VSTD::addressof(__data_.second());} }; template <class _Tp, class _Alloc> @@ -4757,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> @@ -5508,7 +5549,7 @@ struct _LIBCPP_TYPE_VIS pointer_safety #endif #if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \ - defined(_LIBCPP_BUILDING_MEMORY) + defined(_LIBCPP_BUILDING_LIBRARY) _LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT; #else // This function is only offered in C++03 under ABI v1. @@ -5597,6 +5638,16 @@ struct __temp_value { }; #endif +template<typename _Alloc, typename = void, typename = void> +struct __is_allocator : false_type {}; + +template<typename _Alloc> +struct __is_allocator<_Alloc, + typename __void_t<typename _Alloc::value_type>::type, + typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type + > + : true_type {}; + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/lib/libcxx/include/module.modulemap b/lib/libcxx/include/module.modulemap index 3194b5c9f2a..089505586fb 100644 --- a/lib/libcxx/include/module.modulemap +++ b/lib/libcxx/include/module.modulemap @@ -235,6 +235,10 @@ module std [system] { export * } // No submodule for cassert. It fundamentally needs repeated, textual inclusion. + module charconv { + header "charconv" + export * + } module chrono { header "chrono" export * @@ -243,6 +247,10 @@ module std [system] { header "codecvt" export * } + module compare { + header "compare" + export * + } module complex { header "complex" export * @@ -260,6 +268,10 @@ module std [system] { header "exception" export * } + module filesystem { + header "filesystem" + export * + } module forward_list { header "forward_list" export initializer_list @@ -470,10 +482,15 @@ module std [system] { export initializer_list export * } + module version { + header "version" + export * + } // FIXME: These should be private. module __bit_reference { header "__bit_reference" export * } module __debug { header "__debug" export * } + module __errc { header "__errc" export * } module __functional_base { header "__functional_base" export * } module __hash_table { header "__hash_table" export * } module __locale { header "__locale" export * } @@ -485,6 +502,7 @@ module std [system] { module __tree { header "__tree" export * } module __tuple { header "__tuple" export * } module __undef_macros { header "__undef_macros" export * } + module __node_handle { header "__node_handle" export * } module experimental { requires cplusplus11 @@ -493,14 +511,6 @@ module std [system] { header "experimental/algorithm" export * } - module any { - header "experimental/any" - export * - } - module chrono { - header "experimental/chrono" - export * - } module coroutine { requires coroutines header "experimental/coroutine" @@ -542,44 +552,28 @@ module std [system] { header "experimental/memory_resource" export * } - module numeric { - header "experimental/numeric" - export * - } - module optional { - header "experimental/optional" - export * - } module propagate_const { header "experimental/propagate_const" export * } - module ratio { - header "experimental/ratio" - export * - } module regex { header "experimental/regex" export * } - module set { - header "experimental/set" - export * - } - module string { - header "experimental/string" + module simd { + header "experimental/simd" export * } - module string_view { - header "experimental/string_view" + module set { + header "experimental/set" export * } - module system_error { - header "experimental/system_error" + module span { + header "span" export * } - module tuple { - header "experimental/tuple" + module string { + header "experimental/string" export * } module type_traits { diff --git a/lib/libcxx/include/new b/lib/libcxx/include/new index 4e527501b1e..5a658c7a2f2 100644 --- a/lib/libcxx/include/new +++ b/lib/libcxx/include/new @@ -89,6 +89,7 @@ void operator delete[](void* ptr, void*) noexcept; #include <__config> #include <exception> +#include <type_traits> #include <cstddef> #ifdef _LIBCPP_NO_EXCEPTIONS #include <cstdlib> @@ -102,15 +103,16 @@ void operator delete[](void* ptr, void*) noexcept; #pragma GCC system_header #endif -#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \ +#if !(defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_STD_VER >= 14 || \ (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)) # define _LIBCPP_HAS_NO_SIZED_DEALLOCATION #endif -#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \ - (!(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER > 14 || \ - (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606))) -# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#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 @@ -158,8 +160,9 @@ public: #define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED -#endif // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11) +#endif // defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11) +#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME) #if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || _LIBCPP_STD_VER > 14 #ifndef _LIBCPP_CXX03_LANG enum class _LIBCPP_ENUM_VIS align_val_t : size_t { }; @@ -167,6 +170,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 +225,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,16 +253,28 @@ inline _LIBCPP_INLINE_VISIBILITY void *__allocate(size_t __size) { #endif } -inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void *__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 + ((void)__align); +#endif #ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE - ::operator delete(__ptr); + return ::operator delete(__ptr); #else - __builtin_operator_delete(__ptr); + return __builtin_operator_delete(__ptr); #endif } #ifdef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_NO_EXCEPTIONS _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH #endif diff --git a/lib/libcxx/include/numeric b/lib/libcxx/include/numeric index 1b7d97c5be0..b33b6a398eb 100644 --- a/lib/libcxx/include/numeric +++ b/lib/libcxx/include/numeric @@ -51,7 +51,7 @@ template<class InputIterator1, class InputIterator2, class T> T transform_reduce(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); // C++17 - + template<class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2> T transform_reduce(InputIterator1 first1, InputIterator1 last1, @@ -75,10 +75,10 @@ template<class InputIterator, class OutputIterator, class T> OutputIterator exclusive_scan(InputIterator first, InputIterator last, OutputIterator result, T init); // C++17 - + template<class InputIterator, class OutputIterator, class T, class BinaryOperation> OutputIterator - exclusive_scan(InputIterator first, InputIterator last, + exclusive_scan(InputIterator first, InputIterator last, OutputIterator result, T init, BinaryOperation binary_op); // C++17 template<class InputIterator, class OutputIterator> @@ -108,7 +108,7 @@ template<class InputIterator, class OutputIterator, transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, UnaryOperation unary_op); // C++17 - + template<class InputIterator, class OutputIterator, class BinaryOperation, class UnaryOperation, class T> OutputIterator @@ -196,7 +196,7 @@ inline _LIBCPP_INLINE_VISIBILITY typename iterator_traits<_InputIterator>::value_type reduce(_InputIterator __first, _InputIterator __last) { - return _VSTD::reduce(__first, __last, + return _VSTD::reduce(__first, __last, typename iterator_traits<_InputIterator>::value_type{}); } #endif @@ -226,7 +226,7 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp> inline _LIBCPP_INLINE_VISIBILITY _Tp -transform_reduce(_InputIterator __first, _InputIterator __last, +transform_reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b, _UnaryOp __u) { for (; __first != __last; ++__first) @@ -234,7 +234,7 @@ transform_reduce(_InputIterator __first, _InputIterator __last, return __init; } -template <class _InputIterator1, class _InputIterator2, +template <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOp1, class _BinaryOp2> inline _LIBCPP_INLINE_VISIBILITY _Tp @@ -249,10 +249,10 @@ transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, template <class _InputIterator1, class _InputIterator2, class _Tp> inline _LIBCPP_INLINE_VISIBILITY _Tp -transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, +transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) { - return _VSTD::transform_reduce(__first1, __last1, __first2, __init, + return _VSTD::transform_reduce(__first1, __last1, __first2, _VSTD::move(__init), _VSTD::plus<>(), _VSTD::multiplies<>()); } #endif @@ -298,7 +298,7 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp> inline _LIBCPP_INLINE_VISIBILITY _OutputIterator -exclusive_scan(_InputIterator __first, _InputIterator __last, +exclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp __init, _BinaryOp __b) { if (__first != __last) @@ -318,14 +318,14 @@ exclusive_scan(_InputIterator __first, _InputIterator __last, template <class _InputIterator, class _OutputIterator, class _Tp> inline _LIBCPP_INLINE_VISIBILITY _OutputIterator -exclusive_scan(_InputIterator __first, _InputIterator __last, +exclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp __init) { return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>()); } template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp> -_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, +_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOp __b, _Tp __init) { for (; __first != __last; ++__first, (void) ++__result) { @@ -336,7 +336,7 @@ _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, } template <class _InputIterator, class _OutputIterator, class _BinaryOp> -_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, +_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOp __b) { if (__first != __last) { @@ -350,17 +350,17 @@ _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, } template <class _InputIterator, class _OutputIterator> -_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, +_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { return _VSTD::inclusive_scan(__first, __last, __result, std::plus<>()); } -template <class _InputIterator, class _OutputIterator, class _Tp, +template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp, class _UnaryOp> inline _LIBCPP_INLINE_VISIBILITY _OutputIterator -transform_exclusive_scan(_InputIterator __first, _InputIterator __last, +transform_exclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp __init, _BinaryOp __b, _UnaryOp __u) { @@ -379,7 +379,7 @@ transform_exclusive_scan(_InputIterator __first, _InputIterator __last, } template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp, class _UnaryOp> -_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last, +_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOp __b, _UnaryOp __u, _Tp __init) { for (; __first != __last; ++__first, (void) ++__result) { @@ -391,7 +391,7 @@ _OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator } template <class _InputIterator, class _OutputIterator, class _BinaryOp, class _UnaryOp> -_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last, +_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOp __b, _UnaryOp __u) { if (__first != __last) { @@ -400,7 +400,7 @@ _OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator if (++__first != __last) return _VSTD::transform_inclusive_scan(__first, __last, __result, __b, __u, __init); } - + return __result; } #endif diff --git a/lib/libcxx/include/optional b/lib/libcxx/include/optional index 88fd6b5aba2..a76f8d18976 100644 --- a/lib/libcxx/include/optional +++ b/lib/libcxx/include/optional @@ -139,6 +139,10 @@ namespace std { private: T *val; // exposition only }; + +template<class T> + optional(T) -> optional<T>; + } // namespace std */ @@ -612,8 +616,8 @@ private: }; template <class _Up> using _CheckOptionalArgsCtor = conditional_t< - !is_same_v<decay_t<_Up>, in_place_t> && - !is_same_v<decay_t<_Up>, optional>, + !is_same_v<__uncvref_t<_Up>, in_place_t> && + !is_same_v<__uncvref_t<_Up>, optional>, _CheckOptionalArgsConstructor, __check_tuple_constructor_fail >; @@ -761,7 +765,7 @@ public: class = enable_if_t <__lazy_and< integral_constant<bool, - !is_same_v<decay_t<_Up>, optional> && + !is_same_v<__uncvref_t<_Up>, optional> && !(is_same_v<_Up, value_type> && is_scalar_v<value_type>) >, is_constructible<value_type, _Up>, @@ -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 diff --git a/lib/libcxx/include/ostream b/lib/libcxx/include/ostream index f3250a7080d..5404e0dca6c 100644 --- a/lib/libcxx/include/ostream +++ b/lib/libcxx/include/ostream @@ -232,7 +232,7 @@ public: basic_ostream& seekp(off_type __off, ios_base::seekdir __dir); protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY basic_ostream() {} // extension, intentially does not initialize }; @@ -249,7 +249,7 @@ public: explicit sentry(basic_ostream<_CharT, _Traits>& __os); ~sentry(); - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const {return __ok_;} }; @@ -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>& diff --git a/lib/libcxx/include/queue b/lib/libcxx/include/queue index 670fbb722ee..4677e52ae3a 100644 --- a/lib/libcxx/include/queue +++ b/lib/libcxx/include/queue @@ -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) @@ -290,7 +310,7 @@ public: template <class... _Args> _LIBCPP_INLINE_VISIBILITY #if _LIBCPP_STD_VER > 14 - reference emplace(_Args&&... __args) + decltype(auto) emplace(_Args&&... __args) { return c.emplace_back(_VSTD::forward<_Args>(__args)...);} #else void emplace(_Args&&... __args) @@ -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, diff --git a/lib/libcxx/include/random b/lib/libcxx/include/random index 9073a5285b1..89664a6ca33 100644 --- a/lib/libcxx/include/random +++ b/lib/libcxx/include/random @@ -4673,7 +4673,7 @@ poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr double __py; if (__x < 10) { - const result_type __fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, + const double __fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; __px = -__pr.__mean_; __py = _VSTD::pow(__pr.__mean_, (double)__x) / __fac[__x]; diff --git a/lib/libcxx/include/regex b/lib/libcxx/include/regex index ff84b2738b7..dcdb14af9af 100644 --- a/lib/libcxx/include/regex +++ b/lib/libcxx/include/regex @@ -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; @@ -963,7 +968,7 @@ public: }; template <regex_constants::error_type _Ev> -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_regex_error() { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -2409,20 +2414,17 @@ __bracket_expression<_CharT, _Traits>::__exec(__state& __s) const goto __exit; } } - // set of "__found" chars = + // When there's at least one of __neg_chars_ and __neg_mask_, the set + // of "__found" chars is // union(complement(union(__neg_chars_, __neg_mask_)), // other cases...) // - // __neg_chars_ and __neg_mask_'d better be handled together, as there - // are no short circuit opportunities. - // - // In addition, when __neg_mask_/__neg_chars_ is empty, they should be - // treated as all ones/all chars. + // It doesn't make sense to check this when there are no __neg_chars_ + // and no __neg_mask_. + if (!(__neg_mask_ == 0 && __neg_chars_.empty())) { - const bool __in_neg_mask = (__neg_mask_ == 0) || - __traits_.isctype(__ch, __neg_mask_); + const bool __in_neg_mask = __traits_.isctype(__ch, __neg_mask_); const bool __in_neg_chars = - __neg_chars_.empty() || std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) != __neg_chars_.end(); if (!(__in_neg_mask || __in_neg_chars)) @@ -2922,6 +2924,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> @@ -4013,7 +4024,7 @@ basic_regex<_CharT, _Traits>::__parse_character_class(_ForwardIterator __first, char_class_type __class_type = __traits_.lookup_classname(__first, __temp, __flags_ & icase); if (__class_type == 0) - __throw_regex_error<regex_constants::error_brack>(); + __throw_regex_error<regex_constants::error_ctype>(); __ml->__add_class(__class_type); __first = _VSTD::next(__temp, 2); return __first; diff --git a/lib/libcxx/include/set b/lib/libcxx/include/set index b4c6b2ef8c5..108a9e97f88 100644 --- a/lib/libcxx/include/set +++ b/lib/libcxx/include/set @@ -40,6 +40,8 @@ public: typedef implementation-defined const_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef unspecified node_type; // C++17 + typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17 // construct/copy/destroy: set() @@ -115,6 +117,11 @@ public: void insert(InputIterator first, InputIterator last); void insert(initializer_list<value_type> il); + node_type extract(const_iterator position); // C++17 + node_type extract(const key_type& x); // C++17 + insert_return_type insert(node_type&& nh); // C++17 + iterator insert(const_iterator hint, node_type&& nh); // C++17 + iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); @@ -222,6 +229,7 @@ public: typedef implementation-defined const_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef unspecified node_type; // C++17 // construct/copy/destroy: multiset() @@ -297,6 +305,11 @@ public: void insert(InputIterator first, InputIterator last); void insert(initializer_list<value_type> il); + node_type extract(const_iterator position); // C++17 + node_type extract(const key_type& x); // C++17 + iterator insert(node_type&& nh); // C++17 + iterator insert(const_iterator hint, node_type&& nh); // C++17 + iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); @@ -387,6 +400,7 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y) #include <__config> #include <__tree> +#include <__node_handle> #include <functional> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -429,6 +443,11 @@ public: typedef _VSTD::reverse_iterator<iterator> reverse_iterator; typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; +#if _LIBCPP_STD_VER > 14 + typedef __set_node_handle<typename __base::__node, allocator_type> node_type; + typedef __insert_return_type<iterator, node_type> insert_return_type; +#endif + _LIBCPP_INLINE_VISIBILITY set() _NOEXCEPT_( @@ -634,6 +653,35 @@ public: _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT {__tree_.clear();} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + insert_return_type insert(node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to set::insert()"); + return __tree_.template __node_handle_insert_unique< + node_type, insert_return_type>(_VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __hint, node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to set::insert()"); + return __tree_.template __node_handle_insert_unique<node_type>( + __hint, _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(key_type const& __key) + { + return __tree_.template __node_handle_extract<node_type>(__key); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(const_iterator __it) + { + return __tree_.template __node_handle_extract<node_type>(__it); + } +#endif + _LIBCPP_INLINE_VISIBILITY void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable<__base>::value) {__tree_.swap(__s.__tree_);} @@ -668,7 +716,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 +763,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 }; @@ -838,6 +886,10 @@ public: typedef _VSTD::reverse_iterator<iterator> reverse_iterator; typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; +#if _LIBCPP_STD_VER > 14 + typedef __set_node_handle<typename __base::__node, allocator_type> node_type; +#endif + // construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY multiset() @@ -1042,6 +1094,35 @@ public: _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT {__tree_.clear();} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + iterator insert(node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to multiset::insert()"); + return __tree_.template __node_handle_insert_multi<node_type>( + _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __hint, node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to multiset::insert()"); + return __tree_.template __node_handle_insert_multi<node_type>( + __hint, _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(key_type const& __key) + { + return __tree_.template __node_handle_extract<node_type>(__key); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(const_iterator __it) + { + return __tree_.template __node_handle_extract<node_type>(__it); + } +#endif + _LIBCPP_INLINE_VISIBILITY void swap(multiset& __s) _NOEXCEPT_(__is_nothrow_swappable<__base>::value) @@ -1077,7 +1158,7 @@ public: template <typename _K2> _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type - count(const _K2& __k) {return __tree_.__count_multi(__k);} + count(const _K2& __k) const {return __tree_.__count_multi(__k);} #endif _LIBCPP_INLINE_VISIBILITY diff --git a/lib/libcxx/include/shared_mutex b/lib/libcxx/include/shared_mutex index 9cb81528cd9..a7735d6732c 100644 --- a/lib/libcxx/include/shared_mutex +++ b/lib/libcxx/include/shared_mutex @@ -129,7 +129,7 @@ _LIBCPP_PUSH_MACROS #include <__undef_macros> -#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_SHARED_MUTEX) +#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_LIBRARY) #include <__mutex_base> diff --git a/lib/libcxx/include/span b/lib/libcxx/include/span new file mode 100644 index 00000000000..db8f836f918 --- /dev/null +++ b/lib/libcxx/include/span @@ -0,0 +1,608 @@ +// -*- C++ -*- +//===------------------------------ span ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP_SPAN +#define _LIBCPP_SPAN + +/* + span synopsis + +namespace std { + +// constants +inline constexpr ptrdiff_t dynamic_extent = -1; + +// [views.span], class template span +template <class ElementType, ptrdiff_t Extent = dynamic_extent> + class span; + +// [span.comparison], span comparison operators +template <class T, ptrdiff_t X, class U, ptrdiff_t Y> + constexpr bool operator==(span<T, X> l, span<U, Y> r); +template <class T, ptrdiff_t X, class U, ptrdiff_t Y> + constexpr bool operator!=(span<T, X> l, span<U, Y> r); +template <class T, ptrdiff_t X, class U, ptrdiff_t Y> + constexpr bool operator<(span<T, X> l, span<U, Y> r); +template <class T, ptrdiff_t X, class U, ptrdiff_t Y> + constexpr bool operator<=(span<T, X> l, span<U, Y> r); +template <class T, ptrdiff_t X, class U, ptrdiff_t Y> + constexpr bool operator>(span<T, X> l, span<U, Y> r); +template <class T, ptrdiff_t X, class U, ptrdiff_t Y> + constexpr bool operator>=(span<T, X> l, span<U, Y> r); + +// [span.objectrep], views of object representation +template <class ElementType, ptrdiff_t Extent> + span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : + (static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept; + +template <class ElementType, ptrdiff_t Extent> + span< byte, ((Extent == dynamic_extent) ? dynamic_extent : + (static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept; + + +namespace std { +template <class ElementType, ptrdiff_t Extent = dynamic_extent> +class span { +public: + // constants and types + using element_type = ElementType; + using value_type = remove_cv_t<ElementType>; + using index_type = ptrdiff_t; + using difference_type = ptrdiff_t; + using pointer = element_type*; + using reference = element_type&; + using iterator = implementation-defined; + using const_iterator = implementation-defined; + using reverse_iterator = std::reverse_iterator<iterator>; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + static constexpr index_type extent = Extent; + + // [span.cons], span constructors, copy, assignment, and destructor + constexpr span() noexcept; + constexpr span(pointer ptr, index_type count); + constexpr span(pointer firstElem, pointer lastElem); + template <size_t N> + constexpr span(element_type (&arr)[N]) noexcept; + template <size_t N> + constexpr span(array<value_type, N>& arr) noexcept; + template <size_t N> + constexpr span(const array<value_type, N>& arr) noexcept; + template <class Container> + constexpr span(Container& cont); + template <class Container> + constexpr span(const Container& cont); + constexpr span(const span& other) noexcept = default; + template <class OtherElementType, ptrdiff_t OtherExtent> + constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept; + ~span() noexcept = default; + constexpr span& operator=(const span& other) noexcept = default; + + // [span.sub], span subviews + template <ptrdiff_t Count> + constexpr span<element_type, Count> first() const; + template <ptrdiff_t Count> + constexpr span<element_type, Count> last() const; + template <ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent> + constexpr span<element_type, see below> subspan() const; + + constexpr span<element_type, dynamic_extent> first(index_type count) const; + constexpr span<element_type, dynamic_extent> last(index_type count) const; + constexpr span<element_type, dynamic_extent> subspan(index_type offset, index_type count = dynamic_extent) const; + + // [span.obs], span observers + constexpr index_type size() const noexcept; + constexpr index_type size_bytes() const noexcept; + constexpr bool empty() const noexcept; + + // [span.elem], span element access + constexpr reference operator[](index_type idx) const; + constexpr reference operator()(index_type idx) const; + constexpr pointer data() const noexcept; + + // [span.iterators], span iterator support + constexpr iterator begin() const noexcept; + constexpr iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + +private: + pointer data_; // exposition only + index_type size_; // exposition only +}; + +template<class T, size_t N> + span(T (&)[N]) -> span<T, N>; + +template<class T, size_t N> + span(array<T, N>&) -> span<T, N>; + +template<class T, size_t N> + span(const array<T, N>&) -> span<const T, N>; + +template<class Container> + span(Container&) -> span<typename Container::value_type>; + +template<class Container> + span(const Container&) -> span<const typename Container::value_type>; + +} // namespace std + +*/ + +#include <__config> +#include <cstddef> // for ptrdiff_t +#include <iterator> // for iterators +#include <array> // for array +#include <type_traits> // for remove_cv, etc +#include <cstddef> // for byte + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +inline constexpr ptrdiff_t dynamic_extent = -1; +template <typename _Tp, ptrdiff_t _Extent = dynamic_extent> class span; + + +template <class _Tp> +struct __is_span_impl : public false_type {}; + +template <class _Tp, ptrdiff_t _Extent> +struct __is_span_impl<span<_Tp, _Extent>> : public true_type {}; + +template <class _Tp> +struct __is_span : public __is_span_impl<remove_cv_t<_Tp>> {}; + +template <class _Tp> +struct __is_std_array_impl : public false_type {}; + +template <class _Tp, size_t _Sz> +struct __is_std_array_impl<array<_Tp, _Sz>> : public true_type {}; + +template <class _Tp> +struct __is_std_array : public __is_std_array_impl<remove_cv_t<_Tp>> {}; + +template <class _Tp, class _ElementType, class = void> +struct __is_span_compatible_container : public false_type {}; + +template <class _Tp, class _ElementType> +struct __is_span_compatible_container<_Tp, _ElementType, + void_t< + // is not a specialization of span + typename enable_if<!__is_span<_Tp>::value, nullptr_t>::type, + // is not a specialization of array + typename enable_if<!__is_std_array<_Tp>::value, nullptr_t>::type, + // is_array_v<Container> is false, + typename enable_if<!is_array_v<_Tp>, nullptr_t>::type, + // data(cont) and size(cont) are well formed + decltype(data(declval<_Tp>())), + decltype(size(declval<_Tp>())), + // remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[] + typename enable_if< + is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[], + _ElementType(*)[]>, + nullptr_t>::type + >> + : public true_type {}; + + +template <typename _Tp, ptrdiff_t _Extent> +class _LIBCPP_TEMPLATE_VIS span { +public: +// constants and types + using element_type = _Tp; + using value_type = remove_cv_t<_Tp>; + using index_type = ptrdiff_t; + using difference_type = ptrdiff_t; + using pointer = _Tp *; + using const_pointer = const _Tp *; // not in standard + using reference = _Tp &; + using const_reference = const _Tp &; // not in standard + using iterator = __wrap_iter<pointer>; + using const_iterator = __wrap_iter<const_pointer>; + using reverse_iterator = _VSTD::reverse_iterator<iterator>; + using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>; + + static constexpr index_type extent = _Extent; + static_assert (_Extent >= 0, "Can't have a span with an extent < 0"); + +// [span.cons], span constructors, copy, assignment, and destructor + _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} + { static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); } + + constexpr span (const span&) noexcept = default; + constexpr span& operator=(const span&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr} + { (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); } + _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f} + { (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); } + + _LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {} + _LIBCPP_INLINE_VISIBILITY constexpr span( array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {} + _LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {} + + template <class _Container> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span( _Container& __c, + enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) + : __data{_VSTD::data(__c)} + { _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (container))"); } + + template <class _Container> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span(const _Container& __c, + enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr) + : __data{_VSTD::data(__c)} + { _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (const container)"); } + + template <class _OtherElementType> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span(const span<_OtherElementType, _Extent>& __other, + enable_if_t< + is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, + nullptr_t> = nullptr) + : __data{__other.data()} {} + + template <class _OtherElementType> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span(const span<_OtherElementType, dynamic_extent>& __other, + enable_if_t< + is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, + nullptr_t> = nullptr) noexcept + : __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } + + +// ~span() noexcept = default; + + template <ptrdiff_t _Count> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span<element_type, _Count> first() const noexcept + { + static_assert(_Count >= 0, "Count must be >= 0 in span::first()"); + static_assert(_Count <= _Extent, "Count out of range in span::first()"); + return {data(), _Count}; + } + + template <ptrdiff_t _Count> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span<element_type, _Count> last() const noexcept + { + static_assert(_Count >= 0, "Count must be >= 0 in span::last()"); + static_assert(_Count <= _Extent, "Count out of range in span::last()"); + return {data() + size() - _Count, _Count}; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept + { + _LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::first(count)"); + return {data(), __count}; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr span<element_type, dynamic_extent> last(index_type __count) const noexcept + { + _LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::last(count)"); + return {data() + size() - __count, __count}; + } + + template <ptrdiff_t _Offset, ptrdiff_t _Count = dynamic_extent> + inline _LIBCPP_INLINE_VISIBILITY + constexpr auto subspan() const noexcept + -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> + { + _LIBCPP_ASSERT(_Offset >= 0 && _Offset <= size(), "Offset out of range in span::subspan()"); + return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; + } + + + inline _LIBCPP_INLINE_VISIBILITY + constexpr span<element_type, dynamic_extent> + subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept + { + _LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)"); + _LIBCPP_ASSERT((__count >= 0 && __count <= size()) || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)"); + if (__count == dynamic_extent) + return {data() + __offset, size() - __offset}; + _LIBCPP_ASSERT(__offset + __count <= size(), "count + offset out of range in span::subspan(offset, count)"); + return {data() + __offset, __count}; + } + + _LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return _Extent; } + _LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } + _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } + + _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept + { + _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds"); + return __data[__idx]; + } + + _LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept + { + _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>() index out of bounds"); + return __data[__idx]; + } + + _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } + +// [span.iter], span iterator support + _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } + _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); } + _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } + _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } + + _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept + { + pointer __p = __data; + __data = __other.__data; + __other.__data = __p; + } + + _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept + { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } + + _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writeable_bytes() const noexcept + { return {reinterpret_cast<byte *>(data()), size_bytes()}; } + +private: + pointer __data; + +}; + + +template <typename _Tp> +class _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { +private: + +public: +// constants and types + using element_type = _Tp; + using value_type = remove_cv_t<_Tp>; + using index_type = ptrdiff_t; + using difference_type = ptrdiff_t; + using pointer = _Tp *; + using const_pointer = const _Tp *; // not in standard + using reference = _Tp &; + using const_reference = const _Tp &; // not in standard + using iterator = __wrap_iter<pointer>; + using const_iterator = __wrap_iter<const_pointer>; + using reverse_iterator = _VSTD::reverse_iterator<iterator>; + using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>; + + static constexpr index_type extent = dynamic_extent; + +// [span.cons], span constructors, copy, assignment, and destructor + _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {} + + constexpr span (const span&) noexcept = default; + constexpr span& operator=(const span&) noexcept = default; + + _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}, __size{__count} {} + _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{distance(__f, __l)} {} + + template <size_t _Sz> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} + + template <size_t _Sz> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} + + template <size_t _Sz> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} + + template <class _Container> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span( _Container& __c, + enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) + : __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {} + + template <class _Container> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span(const _Container& __c, + enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr) + : __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {} + + + template <class _OtherElementType, ptrdiff_t _OtherExtent> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span(const span<_OtherElementType, _OtherExtent>& __other, + enable_if_t< + is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, + nullptr_t> = nullptr) noexcept + : __data{__other.data()}, __size{__other.size()} {} + +// ~span() noexcept = default; + + template <ptrdiff_t _Count> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span<element_type, _Count> first() const noexcept + { + static_assert(_Count >= 0); + _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()"); + return {data(), _Count}; + } + + template <ptrdiff_t _Count> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span<element_type, _Count> last() const noexcept + { + static_assert(_Count >= 0); + _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()"); + return {data() + size() - _Count, _Count}; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept + { + _LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::first(count)"); + return {data(), __count}; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr span<element_type, dynamic_extent> last (index_type __count) const noexcept + { + _LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::last(count)"); + return {data() + size() - __count, __count}; + } + + template <ptrdiff_t _Offset, ptrdiff_t _Count = dynamic_extent> + inline _LIBCPP_INLINE_VISIBILITY + constexpr span<_Tp, dynamic_extent> subspan() const noexcept + { + _LIBCPP_ASSERT(_Offset >= 0 && _Offset <= size(), "Offset out of range in span::subspan()"); + _LIBCPP_ASSERT(_Count == dynamic_extent || _Offset + _Count <= size(), "Count out of range in span::subspan()"); + return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; + } + + constexpr span<element_type, dynamic_extent> + inline _LIBCPP_INLINE_VISIBILITY + subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept + { + _LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)"); + _LIBCPP_ASSERT((__count >= 0 && __count <= size()) || __count == dynamic_extent, "count out of range in span::subspan(offset, count)"); + if (__count == dynamic_extent) + return {data() + __offset, size() - __offset}; + _LIBCPP_ASSERT(__offset + __count <= size(), "Offset + count out of range in span::subspan(offset, count)"); + return {data() + __offset, __count}; + } + + _LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return __size; } + _LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return __size * sizeof(element_type); } + _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } + + _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept + { + _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds"); + return __data[__idx]; + } + + _LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept + { + _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>() index out of bounds"); + return __data[__idx]; + } + + _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } + +// [span.iter], span iterator support + _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } + _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); } + _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } + _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } + _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } + + _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept + { + pointer __p = __data; + __data = __other.__data; + __other.__data = __p; + + index_type __sz = __size; + __size = __other.__size; + __other.__size = __sz; + } + + _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept + { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } + + _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writeable_bytes() const noexcept + { return {reinterpret_cast<byte *>(data()), size_bytes()}; } + +private: + pointer __data; + index_type __size; +}; + +template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> + constexpr bool + operator==(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) + { return equal(__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); } + +template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> + constexpr bool + operator!=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) + { return !(__rhs == __lhs); } + +template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> + constexpr bool + operator< (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) + { return lexicographical_compare (__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); } + +template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> + constexpr bool + operator<=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) + { return !(__rhs < __lhs); } + +template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> + constexpr bool + operator> (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) + { return __rhs < __lhs; } + +template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> + constexpr bool + operator>=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) + { return !(__lhs < __rhs); } + +// as_bytes & as_writeable_bytes +template <class _Tp, ptrdiff_t _Extent> + auto as_bytes(span<_Tp, _Extent> __s) noexcept + -> decltype(__s.__as_bytes()) + { return __s.__as_bytes(); } + +template <class _Tp, ptrdiff_t _Extent> + auto as_writeable_bytes(span<_Tp, _Extent> __s) noexcept + -> typename enable_if<!is_const_v<_Tp>, decltype(__s.__as_writeable_bytes())>::type + { return __s.__as_writeable_bytes(); } + +template <class _Tp, ptrdiff_t _Extent> + constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept + { __lhs.swap(__rhs); } + + +// Deduction guides +template<class _Tp, size_t _Sz> + span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; + +template<class _Tp, size_t _Sz> + span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; + +template<class _Tp, size_t _Sz> + span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; + +template<class _Container> + span(_Container&) -> span<typename _Container::value_type>; + +template<class _Container> + span(const _Container&) -> span<const typename _Container::value_type>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_SPAN diff --git a/lib/libcxx/include/stack b/lib/libcxx/include/stack index 0cb4c6ca925..2b3f8aea19e 100644 --- a/lib/libcxx/include/stack +++ b/lib/libcxx/include/stack @@ -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> @@ -199,7 +205,7 @@ public: template <class... _Args> _LIBCPP_INLINE_VISIBILITY #if _LIBCPP_STD_VER > 14 - reference emplace(_Args&&... __args) + decltype(auto) emplace(_Args&&... __args) { return c.emplace_back(_VSTD::forward<_Args>(__args)...);} #else void emplace(_Args&&... __args) @@ -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 diff --git a/lib/libcxx/include/stdexcept b/lib/libcxx/include/stdexcept index 95a96cc0767..6533497e4ea 100644 --- a/lib/libcxx/include/stdexcept +++ b/lib/libcxx/include/stdexcept @@ -185,7 +185,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // in the dylib _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*); -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_logic_error(const char*__msg) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -196,7 +196,7 @@ void __throw_logic_error(const char*__msg) #endif } -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_domain_error(const char*__msg) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -207,7 +207,7 @@ void __throw_domain_error(const char*__msg) #endif } -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_invalid_argument(const char*__msg) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -218,7 +218,7 @@ void __throw_invalid_argument(const char*__msg) #endif } -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_length_error(const char*__msg) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -229,7 +229,7 @@ void __throw_length_error(const char*__msg) #endif } -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_out_of_range(const char*__msg) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -240,7 +240,7 @@ void __throw_out_of_range(const char*__msg) #endif } -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_range_error(const char*__msg) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -251,7 +251,7 @@ void __throw_range_error(const char*__msg) #endif } -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_overflow_error(const char*__msg) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -262,7 +262,7 @@ void __throw_overflow_error(const char*__msg) #endif } -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_underflow_error(const char*__msg) { #ifndef _LIBCPP_NO_EXCEPTIONS diff --git a/lib/libcxx/include/streambuf b/lib/libcxx/include/streambuf index ea64f578045..37a65323716 100644 --- a/lib/libcxx/include/streambuf +++ b/lib/libcxx/include/streambuf @@ -132,6 +132,9 @@ public: typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; + static_assert((is_same<_CharT, typename traits_type::char_type>::value), + "traits_type::char_type must be the same type as CharT"); + virtual ~basic_streambuf(); // 27.6.2.2.1 locales: @@ -233,9 +236,9 @@ protected: void swap(basic_streambuf& __rhs); // 27.6.2.3.2 Get area: - _LIBCPP_ALWAYS_INLINE char_type* eback() const {return __binp_;} - _LIBCPP_ALWAYS_INLINE char_type* gptr() const {return __ninp_;} - _LIBCPP_ALWAYS_INLINE char_type* egptr() const {return __einp_;} + _LIBCPP_INLINE_VISIBILITY char_type* eback() const {return __binp_;} + _LIBCPP_INLINE_VISIBILITY char_type* gptr() const {return __ninp_;} + _LIBCPP_INLINE_VISIBILITY char_type* egptr() const {return __einp_;} inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void gbump(int __n) { __ninp_ += __n; } @@ -248,14 +251,14 @@ protected: } // 27.6.2.3.3 Put area: - _LIBCPP_ALWAYS_INLINE char_type* pbase() const {return __bout_;} - _LIBCPP_ALWAYS_INLINE char_type* pptr() const {return __nout_;} - _LIBCPP_ALWAYS_INLINE char_type* epptr() const {return __eout_;} + _LIBCPP_INLINE_VISIBILITY char_type* pbase() const {return __bout_;} + _LIBCPP_INLINE_VISIBILITY char_type* pptr() const {return __nout_;} + _LIBCPP_INLINE_VISIBILITY char_type* epptr() const {return __eout_;} inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void pbump(int __n) { __nout_ += __n; } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void __pbump(streamsize __n) { __nout_ += __n; } inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY diff --git a/lib/libcxx/include/string b/lib/libcxx/include/string index f5d548965aa..162e54058c4 100644 --- a/lib/libcxx/include/string +++ b/lib/libcxx/include/string @@ -104,7 +104,8 @@ public: const Allocator& a = Allocator()); template<class T> basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17 - explicit basic_string(const basic_string_view<charT, traits> sv, const Allocator& a = Allocator()); + template <class T> + explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17 basic_string(const value_type* s, const allocator_type& a = allocator_type()); basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); @@ -120,7 +121,8 @@ public: operator basic_string_view<charT, traits>() const noexcept; basic_string& operator=(const basic_string& str); - basic_string& operator=(basic_string_view<charT, traits> sv); + template <class T> + basic_string& operator=(const T& t); // C++17 basic_string& operator=(basic_string&& str) noexcept( allocator_type::propagate_on_container_move_assignment::value || @@ -164,13 +166,15 @@ public: reference at(size_type n); basic_string& operator+=(const basic_string& str); - basic_string& operator+=(basic_string_view<charT, traits> sv); + template <class T> + basic_string& operator+=(const T& t); // C++17 basic_string& operator+=(const value_type* s); basic_string& operator+=(value_type c); basic_string& operator+=(initializer_list<value_type>); basic_string& append(const basic_string& str); - basic_string& append(basic_string_view<charT, traits> sv); + template <class T> + basic_string& append(const T& t); // C++17 basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14 template <class T> basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17 @@ -189,7 +193,8 @@ public: const_reference back() const; basic_string& assign(const basic_string& str); - basic_string& assign(basic_string_view<charT, traits> sv); + template <class T> + basic_string& assign(const T& t); // C++17 basic_string& assign(basic_string&& str); basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14 template <class T> @@ -202,7 +207,8 @@ public: basic_string& assign(initializer_list<value_type>); basic_string& insert(size_type pos1, const basic_string& str); - basic_string& insert(size_type pos1, basic_string_view<charT, traits> sv); + template <class T> + basic_string& insert(size_type pos1, const T& t); basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n); template <class T> @@ -221,7 +227,8 @@ public: iterator erase(const_iterator first, const_iterator last); basic_string& replace(size_type pos1, size_type n1, const basic_string& str); - basic_string& replace(size_type pos1, size_type n1, basic_string_view<charT, traits> sv); + template <class T> + basic_string& replace(size_type pos1, size_type n1, const T& t); // C++17 basic_string& replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2=npos); // C++14 template <class T> @@ -231,7 +238,8 @@ public: basic_string& replace(size_type pos, size_type n1, const value_type* s); basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); - basic_string& replace(const_iterator i1, const_iterator i2, basic_string_view<charT, traits> sv); + template <class T> + basic_string& replace(const_iterator i1, const_iterator i2, const T& t); // C++17 basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); @@ -253,45 +261,53 @@ public: allocator_type get_allocator() const noexcept; size_type find(const basic_string& str, size_type pos = 0) const noexcept; - size_type find(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; + template <class T> + size_type find(const T& t, size_type pos = 0) const; // C++17 size_type find(const value_type* s, size_type pos, size_type n) const noexcept; size_type find(const value_type* s, size_type pos = 0) const noexcept; size_type find(value_type c, size_type pos = 0) const noexcept; size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; - size_type rfind(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept; + template <class T> + size_type rfind(const T& t, size_type pos = npos) const; // C++17 size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; size_type rfind(const value_type* s, size_type pos = npos) const noexcept; size_type rfind(value_type c, size_type pos = npos) const noexcept; size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; - size_type find_first_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; + template <class T> + size_type find_first_of(const T& t, size_type pos = 0) const; // C++17 size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; size_type find_first_of(value_type c, size_type pos = 0) const noexcept; size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; - size_type find_last_of(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept; + template <class T> + size_type find_last_of(const T& t, size_type pos = npos) const noexcept; // C++17 size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; size_type find_last_of(value_type c, size_type pos = npos) const noexcept; size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; - size_type find_first_not_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; + template <class T> + size_type find_first_not_of(const T& t, size_type pos = 0) const; // C++17 size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; - size_type find_last_not_of(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept; + template <class T> + size_type find_last_not_of(const T& t, size_type pos = npos) const; // C++17 size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; int compare(const basic_string& str) const noexcept; - int compare(basic_string_view<charT, traits> sv) const noexcept; + template <class T> + int compare(const T& t) const noexcept; // C++17 int compare(size_type pos1, size_type n1, const basic_string& str) const; - int compare(size_type pos1, size_type n1, basic_string_view<charT, traits> sv) const; + template <class T> + int compare(size_type pos1, size_type n1, const T& t) const; // C++17 int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2=npos) const; // C++14 template <class T> @@ -311,6 +327,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,11 +674,14 @@ public: typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; - static_assert(is_pod<value_type>::value, "Character type of basic_string must be a POD"); - 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; typedef const_pointer const_iterator; @@ -779,31 +805,51 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s); + + template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type> _LIBCPP_INLINE_VISIBILITY - basic_string(const _CharT* __s, const _Allocator& __a); + basic_string(const _CharT* __s) { + _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); + __init(__s, traits_type::length(__s)); +# if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +# endif + } + + template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type> + _LIBCPP_INLINE_VISIBILITY + basic_string(const _CharT* __s, const _Allocator& __a); + _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s, size_type __n); _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s, size_type __n, const _Allocator& __a); _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, _CharT __c); - _LIBCPP_INLINE_VISIBILITY - basic_string(size_type __n, _CharT __c, const _Allocator& __a); + + template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type> + _LIBCPP_INLINE_VISIBILITY + basic_string(size_type __n, _CharT __c, const _Allocator& __a); + basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()); _LIBCPP_INLINE_VISIBILITY basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator()); - template<class _Tp> + + template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string(const _Tp& __t, size_type __pos, size_type __n, - const allocator_type& __a = allocator_type(), - typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0); - _LIBCPP_INLINE_VISIBILITY explicit - basic_string(__self_view __sv); - _LIBCPP_INLINE_VISIBILITY - basic_string(__self_view __sv, const _Allocator& __a); + const allocator_type& __a = allocator_type()); + + template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + explicit basic_string(const _Tp& __t); + + template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + explicit basic_string(const _Tp& __t, const allocator_type& __a); + template<class _InputIterator> _LIBCPP_INLINE_VISIBILITY basic_string(_InputIterator __first, _InputIterator __last); @@ -824,11 +870,10 @@ public: basic_string& operator=(const basic_string& __str); -#ifndef _LIBCPP_CXX03_LANG - template <class = void> -#endif - _LIBCPP_INLINE_VISIBILITY - basic_string& operator=(__self_view __sv) {return assign(__sv);} + template <class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type> + basic_string& operator=(const _Tp& __t) + {__self_view __sv = __t; return assign(__sv);} + #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY basic_string& operator=(basic_string&& __str) @@ -918,7 +963,15 @@ public: reference at(size_type __n); _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);} - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(__self_view __sv) {return append(__sv);} + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + operator+=(const _Tp& __t) {__self_view __sv = __t; return append(__sv);} _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);} _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;} #ifndef _LIBCPP_CXX03_LANG @@ -927,9 +980,17 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string& append(const basic_string& __str); - _LIBCPP_INLINE_VISIBILITY - basic_string& append(__self_view __sv) { return append(__sv.data(), __sv.size()); } + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); } basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); + template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if @@ -984,8 +1045,14 @@ public: _LIBCPP_INLINE_VISIBILITY reference back(); _LIBCPP_INLINE_VISIBILITY const_reference back() const; - _LIBCPP_INLINE_VISIBILITY - basic_string& assign(__self_view __sv) { return assign(__sv.data(), __sv.size()); } + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); } _LIBCPP_INLINE_VISIBILITY basic_string& assign(const basic_string& __str) { return *this = __str; } #ifndef _LIBCPP_CXX03_LANG @@ -1031,8 +1098,17 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string& insert(size_type __pos1, const basic_string& __str); - _LIBCPP_INLINE_VISIBILITY - basic_string& insert(size_type __pos1, __self_view __sv) { return insert(__pos1, __sv.data(), __sv.size()); } + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + insert(size_type __pos1, const _Tp& __t) + { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); } + template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if @@ -1080,8 +1156,15 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str); - _LIBCPP_INLINE_VISIBILITY - basic_string& replace(size_type __pos1, size_type __n1, __self_view __sv) { return replace(__pos1, __n1, __sv.data(), __sv.size()); } + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); } basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos); template <class _Tp> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS @@ -1096,8 +1179,16 @@ public: basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str); - _LIBCPP_INLINE_VISIBILITY - basic_string& replace(const_iterator __i1, const_iterator __i2, __self_view __sv) { return replace(__i1 - begin(), __i2 - __i1, __sv); } + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + basic_string& + >::type + replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); } + _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n); _LIBCPP_INLINE_VISIBILITY @@ -1145,8 +1236,15 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + size_type + >::type + find(const _Tp& __t, size_type __pos = 0) const; size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1154,8 +1252,15 @@ public: _LIBCPP_INLINE_VISIBILITY size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type rfind(__self_view __sv, size_type __pos = npos) const _NOEXCEPT; + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + size_type + >::type + rfind(const _Tp& __t, size_type __pos = npos) const; size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1163,8 +1268,15 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find_first_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + size_type + >::type + find_first_of(const _Tp& __t, size_type __pos = 0) const; size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1173,8 +1285,15 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find_last_of(__self_view __sv, size_type __pos = npos) const _NOEXCEPT; + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + size_type + >::type + find_last_of(const _Tp& __t, size_type __pos = npos) const; size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1183,8 +1302,15 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find_first_not_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + size_type + >::type + find_first_not_of(const _Tp &__t, size_type __pos = 0) const; size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1193,8 +1319,15 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - size_type find_last_not_of(__self_view __sv, size_type __pos = npos) const _NOEXCEPT; + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + size_type + >::type + find_last_not_of(const _Tp& __t, size_type __pos = npos) const; size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1203,13 +1336,29 @@ public: _LIBCPP_INLINE_VISIBILITY int compare(const basic_string& __str) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - int compare(__self_view __sv) const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - int compare(size_type __pos1, size_type __n1, __self_view __sv) const; + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + int + >::type + compare(const _Tp &__t) const; + + template <class _Tp> + _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + int + >::type + compare(size_type __pos1, size_type __n1, const _Tp& __t) const; + _LIBCPP_INLINE_VISIBILITY int compare(size_type __pos1, size_type __n1, const basic_string& __str) const; int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const; + template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -1250,6 +1399,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);} @@ -1363,9 +1514,13 @@ private: enum {__alignment = 16}; static _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __s) _NOEXCEPT - {return (__s < __min_cap ? static_cast<size_type>(__min_cap) : - __align_it<sizeof(value_type) < __alignment ? - __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;} + { + if (__s < __min_cap) return static_cast<size_type>(__min_cap) - 1; + size_type __guess = __align_it<sizeof(value_type) < __alignment ? + __alignment/sizeof(value_type) : 1 > (__s+1) - 1; + if (__guess == __min_cap) ++__guess; + return __guess; + } inline void __init(const value_type* __s, size_type __sz, size_type __reserve); @@ -1415,16 +1570,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()); @@ -1481,6 +1634,35 @@ 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>; + +template<class _CharT, + class _Traits, + class _Allocator = allocator<_CharT>, + class = typename enable_if<__is_allocator<_Allocator>::value, void>::type + > +explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) + -> basic_string<_CharT, _Traits, _Allocator>; + +template<class _CharT, + class _Traits, + class _Allocator = allocator<_CharT>, + class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, + class _Sz = typename allocator_traits<_Allocator>::size_type + > +basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator()) + -> basic_string<_CharT, _Traits, _Allocator>; +#endif + + template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY void @@ -1598,18 +1780,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s) -{ - _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); - __init(__s, traits_type::length(__s)); -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif -} - -template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +template <class> basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) : __r_(__second_tag(), __a) { @@ -1746,7 +1917,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __ } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +template <class> basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) : __r_(__second_tag(), __a) { @@ -1787,13 +1958,13 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st } template <class _CharT, class _Traits, class _Allocator> -template <class _Tp> +template <class _Tp, class> basic_string<_CharT, _Traits, _Allocator>::basic_string( - const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a, - typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type *) + const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) : __r_(__second_tag(), __a) { - __self_view __sv = __self_view(__t).substr(__pos, __n); + __self_view __sv0 = __t; + __self_view __sv = __sv0.substr(__pos, __n); __init(__sv.data(), __sv.size()); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1801,9 +1972,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv) +template <class _Tp, class> +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) { + __self_view __sv = __t; __init(__sv.data(), __sv.size()); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1811,10 +1983,11 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv) } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const _Allocator& __a) +template <class _Tp, class> +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) : __r_(__second_tag(), __a) { + __self_view __sv = __t; __init(__sv.data(), __sv.size()); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -2102,8 +2275,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(); @@ -3125,11 +3297,16 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find(__self_view __sv, - size_type __pos) const _NOEXCEPT +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + typename basic_string<_CharT, _Traits, _Allocator>::size_type +>::type +basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t, + size_type __pos) const { + __self_view __sv = __t; return __str_find<value_type, size_type, traits_type, npos> (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3178,11 +3355,16 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::rfind(__self_view __sv, - size_type __pos) const _NOEXCEPT +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + typename basic_string<_CharT, _Traits, _Allocator>::size_type +>::type +basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, + size_type __pos) const { + __self_view __sv = __t; return __str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3231,11 +3413,16 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find_first_of(__self_view __sv, - size_type __pos) const _NOEXCEPT +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + typename basic_string<_CharT, _Traits, _Allocator>::size_type +>::type +basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, + size_type __pos) const { + __self_view __sv = __t; return __str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3284,11 +3471,16 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find_last_of(__self_view __sv, - size_type __pos) const _NOEXCEPT +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + typename basic_string<_CharT, _Traits, _Allocator>::size_type +>::type +basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, + size_type __pos) const { + __self_view __sv = __t; return __str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3337,11 +3529,16 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(__self_view __sv, - size_type __pos) const _NOEXCEPT +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + typename basic_string<_CharT, _Traits, _Allocator>::size_type +>::type +basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, + size_type __pos) const { + __self_view __sv = __t; return __str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3391,11 +3588,16 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_string<_CharT, _Traits, _Allocator>::size_type -basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(__self_view __sv, - size_type __pos) const _NOEXCEPT +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + typename basic_string<_CharT, _Traits, _Allocator>::size_type +>::type +basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, + size_type __pos) const { + __self_view __sv = __t; return __str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __sv.data(), __pos, __sv.size()); } @@ -3424,10 +3626,15 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, // compare template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -int -basic_string<_CharT, _Traits, _Allocator>::compare(__self_view __sv) const _NOEXCEPT +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + int +>::type +basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const { + __self_view __sv = __t; size_t __lhs_sz = size(); size_t __rhs_sz = __sv.size(); int __result = traits_type::compare(data(), __sv.data(), @@ -3473,12 +3680,17 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -int +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, + int +>::type basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, - __self_view __sv) const + const _Tp& __t) const { + __self_view __sv = __t; return compare(__pos1, __n1, __sv.data(), __sv.size()); } @@ -3556,6 +3768,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> diff --git a/lib/libcxx/include/string_view b/lib/libcxx/include/string_view index 72cf816e8d5..6377aeb6d64 100644 --- a/lib/libcxx/include/string_view +++ b/lib/libcxx/include/string_view @@ -208,7 +208,9 @@ public: typedef ptrdiff_t difference_type; static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1); - static_assert(is_pod<value_type>::value, "Character type of basic_string_view must be a POD"); + 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"); diff --git a/lib/libcxx/include/support/android/locale_bionic.h b/lib/libcxx/include/support/android/locale_bionic.h index 482e2343358..50fcf5c36a7 100644 --- a/lib/libcxx/include/support/android/locale_bionic.h +++ b/lib/libcxx/include/support/android/locale_bionic.h @@ -24,8 +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_INLINE_VISIBILITY float strtof_l(const char* __nptr, char** __endptr, + locale_t) { + return ::strtof(__nptr, __endptr); +} + +inline _LIBCPP_INLINE_VISIBILITY double strtod_l(const char* __nptr, + char** __endptr, locale_t) { + return ::strtod(__nptr, __endptr); +} + +inline _LIBCPP_INLINE_VISIBILITY 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 diff --git a/lib/libcxx/include/support/win32/locale_win32.h b/lib/libcxx/include/support/win32/locale_win32.h index aebfff22ecf..68682c9624b 100644 --- a/lib/libcxx/include/support/win32/locale_win32.h +++ b/lib/libcxx/include/support/win32/locale_win32.h @@ -46,6 +46,10 @@ public: return __left.__locale == nullptr && __right == 0; } + friend bool operator==(const locale_t& __left, long long __right) { + return __left.__locale == nullptr && __right == 0; + } + friend bool operator==(const locale_t& __left, std::nullptr_t) { return __left.__locale == nullptr; } @@ -66,6 +70,10 @@ public: return !(__left == __right); } + friend bool operator!=(const locale_t& __left, long long __right) { + return !(__left == __right); + } + friend bool operator!=(const locale_t& __left, std::nullptr_t __right) { return !(__left == __right); } diff --git a/lib/libcxx/include/support/xlocale/__posix_l_fallback.h b/lib/libcxx/include/support/xlocale/__posix_l_fallback.h index c893a67313c..b9a0939f8fa 100644 --- a/lib/libcxx/include/support/xlocale/__posix_l_fallback.h +++ b/lib/libcxx/include/support/xlocale/__posix_l_fallback.h @@ -20,141 +20,141 @@ extern "C" { #endif -inline _LIBCPP_ALWAYS_INLINE int isalnum_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int isalnum_l(int c, locale_t) { return ::isalnum(c); } -inline _LIBCPP_ALWAYS_INLINE int isalpha_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int isalpha_l(int c, locale_t) { return ::isalpha(c); } -inline _LIBCPP_ALWAYS_INLINE int isblank_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int isblank_l(int c, locale_t) { return ::isblank(c); } -inline _LIBCPP_ALWAYS_INLINE int iscntrl_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iscntrl_l(int c, locale_t) { return ::iscntrl(c); } -inline _LIBCPP_ALWAYS_INLINE int isdigit_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int isdigit_l(int c, locale_t) { return ::isdigit(c); } -inline _LIBCPP_ALWAYS_INLINE int isgraph_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int isgraph_l(int c, locale_t) { return ::isgraph(c); } -inline _LIBCPP_ALWAYS_INLINE int islower_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int islower_l(int c, locale_t) { return ::islower(c); } -inline _LIBCPP_ALWAYS_INLINE int isprint_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int isprint_l(int c, locale_t) { return ::isprint(c); } -inline _LIBCPP_ALWAYS_INLINE int ispunct_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int ispunct_l(int c, locale_t) { return ::ispunct(c); } -inline _LIBCPP_ALWAYS_INLINE int isspace_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int isspace_l(int c, locale_t) { return ::isspace(c); } -inline _LIBCPP_ALWAYS_INLINE int isupper_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int isupper_l(int c, locale_t) { return ::isupper(c); } -inline _LIBCPP_ALWAYS_INLINE int isxdigit_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int isxdigit_l(int c, locale_t) { return ::isxdigit(c); } -inline _LIBCPP_ALWAYS_INLINE int iswalnum_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswalnum_l(wint_t c, locale_t) { return ::iswalnum(c); } -inline _LIBCPP_ALWAYS_INLINE int iswalpha_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswalpha_l(wint_t c, locale_t) { return ::iswalpha(c); } -inline _LIBCPP_ALWAYS_INLINE int iswblank_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswblank_l(wint_t c, locale_t) { return ::iswblank(c); } -inline _LIBCPP_ALWAYS_INLINE int iswcntrl_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswcntrl_l(wint_t c, locale_t) { return ::iswcntrl(c); } -inline _LIBCPP_ALWAYS_INLINE int iswdigit_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswdigit_l(wint_t c, locale_t) { return ::iswdigit(c); } -inline _LIBCPP_ALWAYS_INLINE int iswgraph_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswgraph_l(wint_t c, locale_t) { return ::iswgraph(c); } -inline _LIBCPP_ALWAYS_INLINE int iswlower_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswlower_l(wint_t c, locale_t) { return ::iswlower(c); } -inline _LIBCPP_ALWAYS_INLINE int iswprint_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswprint_l(wint_t c, locale_t) { return ::iswprint(c); } -inline _LIBCPP_ALWAYS_INLINE int iswpunct_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswpunct_l(wint_t c, locale_t) { return ::iswpunct(c); } -inline _LIBCPP_ALWAYS_INLINE int iswspace_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswspace_l(wint_t c, locale_t) { return ::iswspace(c); } -inline _LIBCPP_ALWAYS_INLINE int iswupper_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswupper_l(wint_t c, locale_t) { return ::iswupper(c); } -inline _LIBCPP_ALWAYS_INLINE int iswxdigit_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int iswxdigit_l(wint_t c, locale_t) { return ::iswxdigit(c); } -inline _LIBCPP_ALWAYS_INLINE int toupper_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int toupper_l(int c, locale_t) { return ::toupper(c); } -inline _LIBCPP_ALWAYS_INLINE int tolower_l(int c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int tolower_l(int c, locale_t) { return ::tolower(c); } -inline _LIBCPP_ALWAYS_INLINE wint_t towupper_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY wint_t towupper_l(wint_t c, locale_t) { return ::towupper(c); } -inline _LIBCPP_ALWAYS_INLINE wint_t towlower_l(wint_t c, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY wint_t towlower_l(wint_t c, locale_t) { return ::towlower(c); } -inline _LIBCPP_ALWAYS_INLINE int strcoll_l(const char *s1, const char *s2, - locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int strcoll_l(const char *s1, const char *s2, + locale_t) { return ::strcoll(s1, s2); } -inline _LIBCPP_ALWAYS_INLINE size_t strxfrm_l(char *dest, const char *src, - size_t n, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY size_t strxfrm_l(char *dest, const char *src, + size_t n, locale_t) { return ::strxfrm(dest, src, n); } -inline _LIBCPP_ALWAYS_INLINE size_t strftime_l(char *s, size_t max, - const char *format, - const struct tm *tm, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY size_t strftime_l(char *s, size_t max, + const char *format, + const struct tm *tm, locale_t) { return ::strftime(s, max, format, tm); } -inline _LIBCPP_ALWAYS_INLINE int wcscoll_l(const wchar_t *ws1, - const wchar_t *ws2, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY int wcscoll_l(const wchar_t *ws1, + const wchar_t *ws2, locale_t) { return ::wcscoll(ws1, ws2); } -inline _LIBCPP_ALWAYS_INLINE size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, - size_t n, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, + size_t n, locale_t) { return ::wcsxfrm(dest, src, n); } diff --git a/lib/libcxx/include/support/xlocale/__strtonum_fallback.h b/lib/libcxx/include/support/xlocale/__strtonum_fallback.h index 4ae3918b3d3..50b4db35427 100644 --- a/lib/libcxx/include/support/xlocale/__strtonum_fallback.h +++ b/lib/libcxx/include/support/xlocale/__strtonum_fallback.h @@ -20,43 +20,43 @@ extern "C" { #endif -inline _LIBCPP_ALWAYS_INLINE float strtof_l(const char *nptr, - char **endptr, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY 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) { +inline _LIBCPP_INLINE_VISIBILITY double strtod_l(const char *nptr, + char **endptr, locale_t) { return ::strtod(nptr, endptr); } -inline _LIBCPP_ALWAYS_INLINE long double strtold_l(const char *nptr, - char **endptr, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY long double strtold_l(const char *nptr, + char **endptr, locale_t) { return ::strtold(nptr, endptr); } -inline _LIBCPP_ALWAYS_INLINE long long +inline _LIBCPP_INLINE_VISIBILITY long long strtoll_l(const char *nptr, char **endptr, int base, locale_t) { return ::strtoll(nptr, endptr, base); } -inline _LIBCPP_ALWAYS_INLINE unsigned long long +inline _LIBCPP_INLINE_VISIBILITY unsigned long long strtoull_l(const char *nptr, char **endptr, int base, locale_t) { return ::strtoull(nptr, endptr, base); } -inline _LIBCPP_ALWAYS_INLINE long long +inline _LIBCPP_INLINE_VISIBILITY long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base, locale_t) { return ::wcstoll(nptr, endptr, base); } -inline _LIBCPP_ALWAYS_INLINE unsigned long long +inline _LIBCPP_INLINE_VISIBILITY unsigned long long wcstoull_l(const wchar_t *nptr, wchar_t **endptr, int base, locale_t) { return ::wcstoull(nptr, endptr, base); } -inline _LIBCPP_ALWAYS_INLINE long double wcstold_l(const wchar_t *nptr, - wchar_t **endptr, locale_t) { +inline _LIBCPP_INLINE_VISIBILITY long double wcstold_l(const wchar_t *nptr, + wchar_t **endptr, locale_t) { return ::wcstold(nptr, endptr); } diff --git a/lib/libcxx/include/system_error b/lib/libcxx/include/system_error index c577edceee8..6e2c8388f17 100644 --- a/lib/libcxx/include/system_error +++ b/lib/libcxx/include/system_error @@ -120,88 +120,6 @@ public: const char* what() const noexcept; }; -enum class errc -{ - address_family_not_supported, // EAFNOSUPPORT - address_in_use, // EADDRINUSE - address_not_available, // EADDRNOTAVAIL - already_connected, // EISCONN - argument_list_too_long, // E2BIG - argument_out_of_domain, // EDOM - bad_address, // EFAULT - bad_file_descriptor, // EBADF - bad_message, // EBADMSG - broken_pipe, // EPIPE - connection_aborted, // ECONNABORTED - connection_already_in_progress, // EALREADY - connection_refused, // ECONNREFUSED - connection_reset, // ECONNRESET - cross_device_link, // EXDEV - destination_address_required, // EDESTADDRREQ - device_or_resource_busy, // EBUSY - directory_not_empty, // ENOTEMPTY - executable_format_error, // ENOEXEC - file_exists, // EEXIST - file_too_large, // EFBIG - filename_too_long, // ENAMETOOLONG - function_not_supported, // ENOSYS - host_unreachable, // EHOSTUNREACH - identifier_removed, // EIDRM - illegal_byte_sequence, // EILSEQ - inappropriate_io_control_operation, // ENOTTY - interrupted, // EINTR - invalid_argument, // EINVAL - invalid_seek, // ESPIPE - io_error, // EIO - is_a_directory, // EISDIR - message_size, // EMSGSIZE - network_down, // ENETDOWN - network_reset, // ENETRESET - network_unreachable, // ENETUNREACH - no_buffer_space, // ENOBUFS - no_child_process, // ECHILD - no_link, // ENOLINK - no_lock_available, // ENOLCK - no_message_available, // ENODATA - no_message, // ENOMSG - no_protocol_option, // ENOPROTOOPT - no_space_on_device, // ENOSPC - no_stream_resources, // ENOSR - no_such_device_or_address, // ENXIO - no_such_device, // ENODEV - no_such_file_or_directory, // ENOENT - no_such_process, // ESRCH - not_a_directory, // ENOTDIR - not_a_socket, // ENOTSOCK - not_a_stream, // ENOSTR - not_connected, // ENOTCONN - not_enough_memory, // ENOMEM - not_supported, // ENOTSUP - operation_canceled, // ECANCELED - operation_in_progress, // EINPROGRESS - operation_not_permitted, // EPERM - operation_not_supported, // EOPNOTSUPP - operation_would_block, // EWOULDBLOCK - owner_dead, // EOWNERDEAD - permission_denied, // EACCES - protocol_error, // EPROTO - protocol_not_supported, // EPROTONOSUPPORT - read_only_file_system, // EROFS - resource_deadlock_would_occur, // EDEADLK - resource_unavailable_try_again, // EAGAIN - result_out_of_range, // ERANGE - state_not_recoverable, // ENOTRECOVERABLE - stream_timeout, // ETIME - text_file_busy, // ETXTBSY - timed_out, // ETIMEDOUT - too_many_files_open_in_system, // ENFILE - too_many_files_open, // EMFILE - too_many_links, // EMLINK - too_many_symbolic_link_levels, // ELOOP - value_too_large, // EOVERFLOW - wrong_protocol_type // EPROTOTYPE -}; - template <> struct is_error_condition_enum<errc> : true_type { } @@ -225,8 +143,7 @@ template <> struct hash<std::error_condition>; */ -#include <__config> -#include <cerrno> +#include <__errc> #include <type_traits> #include <stdexcept> #include <__functional_base> @@ -260,109 +177,6 @@ template <class _Tp> _LIBCPP_INLINE_VAR constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; #endif -// Some error codes are not present on all platforms, so we provide equivalents -// for them: - -//enum class errc -_LIBCPP_DECLARE_STRONG_ENUM(errc) -{ - address_family_not_supported = EAFNOSUPPORT, - address_in_use = EADDRINUSE, - address_not_available = EADDRNOTAVAIL, - already_connected = EISCONN, - argument_list_too_long = E2BIG, - argument_out_of_domain = EDOM, - bad_address = EFAULT, - bad_file_descriptor = EBADF, - bad_message = EBADMSG, - broken_pipe = EPIPE, - connection_aborted = ECONNABORTED, - connection_already_in_progress = EALREADY, - connection_refused = ECONNREFUSED, - connection_reset = ECONNRESET, - cross_device_link = EXDEV, - destination_address_required = EDESTADDRREQ, - device_or_resource_busy = EBUSY, - directory_not_empty = ENOTEMPTY, - executable_format_error = ENOEXEC, - file_exists = EEXIST, - file_too_large = EFBIG, - filename_too_long = ENAMETOOLONG, - function_not_supported = ENOSYS, - host_unreachable = EHOSTUNREACH, - identifier_removed = EIDRM, - illegal_byte_sequence = EILSEQ, - inappropriate_io_control_operation = ENOTTY, - interrupted = EINTR, - invalid_argument = EINVAL, - invalid_seek = ESPIPE, - io_error = EIO, - is_a_directory = EISDIR, - message_size = EMSGSIZE, - network_down = ENETDOWN, - network_reset = ENETRESET, - network_unreachable = ENETUNREACH, - no_buffer_space = ENOBUFS, - no_child_process = ECHILD, - no_link = ENOLINK, - no_lock_available = ENOLCK, -#ifdef ENODATA - no_message_available = ENODATA, -#else - no_message_available = ENOMSG, -#endif - no_message = ENOMSG, - no_protocol_option = ENOPROTOOPT, - no_space_on_device = ENOSPC, -#ifdef ENOSR - no_stream_resources = ENOSR, -#else - no_stream_resources = ENOMEM, -#endif - no_such_device_or_address = ENXIO, - no_such_device = ENODEV, - no_such_file_or_directory = ENOENT, - no_such_process = ESRCH, - not_a_directory = ENOTDIR, - not_a_socket = ENOTSOCK, -#ifdef ENOSTR - not_a_stream = ENOSTR, -#else - not_a_stream = EINVAL, -#endif - not_connected = ENOTCONN, - not_enough_memory = ENOMEM, - not_supported = ENOTSUP, - operation_canceled = ECANCELED, - operation_in_progress = EINPROGRESS, - operation_not_permitted = EPERM, - operation_not_supported = EOPNOTSUPP, - operation_would_block = EWOULDBLOCK, - owner_dead = EOWNERDEAD, - permission_denied = EACCES, - protocol_error = EPROTO, - protocol_not_supported = EPROTONOSUPPORT, - read_only_file_system = EROFS, - resource_deadlock_would_occur = EDEADLK, - resource_unavailable_try_again = EAGAIN, - result_out_of_range = ERANGE, - state_not_recoverable = ENOTRECOVERABLE, -#ifdef ETIME - stream_timeout = ETIME, -#else - stream_timeout = ETIMEDOUT, -#endif - text_file_busy = ETXTBSY, - timed_out = ETIMEDOUT, - too_many_files_open_in_system = ENFILE, - too_many_files_open = EMFILE, - too_many_links = EMLINK, - too_many_symbolic_link_levels = ELOOP, - value_too_large = EOVERFLOW, - wrong_protocol_type = EPROTOTYPE -}; -_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc) - template <> struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> : true_type { }; @@ -385,11 +199,11 @@ class _LIBCPP_TYPE_VIS error_category public: virtual ~error_category() _NOEXCEPT; -#if defined(_LIBCPP_BUILDING_SYSTEM_ERROR) && \ +#if defined(_LIBCPP_BUILDING_LIBRARY) && \ defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) error_category() _NOEXCEPT; #else - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT #endif private: @@ -403,13 +217,13 @@ public: virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; virtual string message(int __ev) const = 0; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;} friend class _LIBCPP_HIDDEN __do_message; @@ -430,21 +244,21 @@ class _LIBCPP_TYPE_VIS error_condition int __val_; const error_category* __cat_; public: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY error_condition(int __val, const error_category& __cat) _NOEXCEPT : __val_(__val), __cat_(&__cat) {} template <class _Ep> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY error_condition(_Ep __e, typename enable_if<is_error_condition_enum<_Ep>::value>::type* = 0 ) _NOEXCEPT {*this = make_error_condition(__e);} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void assign(int __val, const error_category& __cat) _NOEXCEPT { __val_ = __val; @@ -452,7 +266,7 @@ public: } template <class _Ep> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY typename enable_if < is_error_condition_enum<_Ep>::value, @@ -461,21 +275,21 @@ public: operator=(_Ep __e) _NOEXCEPT {*this = make_error_condition(__e); return *this;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT { __val_ = 0; __cat_ = &generic_category(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int value() const _NOEXCEPT {return __val_;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const error_category& category() const _NOEXCEPT {return *__cat_;} string message() const; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __val_ != 0;} }; @@ -502,21 +316,21 @@ class _LIBCPP_TYPE_VIS error_code int __val_; const error_category* __cat_; public: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY error_code(int __val, const error_category& __cat) _NOEXCEPT : __val_(__val), __cat_(&__cat) {} template <class _Ep> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY error_code(_Ep __e, typename enable_if<is_error_code_enum<_Ep>::value>::type* = 0 ) _NOEXCEPT {*this = make_error_code(__e);} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void assign(int __val, const error_category& __cat) _NOEXCEPT { __val_ = __val; @@ -524,7 +338,7 @@ public: } template <class _Ep> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY typename enable_if < is_error_code_enum<_Ep>::value, @@ -533,26 +347,26 @@ public: operator=(_Ep __e) _NOEXCEPT {*this = make_error_code(__e); return *this;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT { __val_ = 0; __cat_ = &system_category(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int value() const _NOEXCEPT {return __val_;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const error_category& category() const _NOEXCEPT {return *__cat_;} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY error_condition default_error_condition() const _NOEXCEPT {return __cat_->default_error_condition(__val_);} string message() const; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __val_ != 0;} }; @@ -658,7 +472,7 @@ public: system_error(int __ev, const error_category& __ecat); ~system_error() _NOEXCEPT; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const error_code& code() const _NOEXCEPT {return __ec_;} private: diff --git a/lib/libcxx/include/tgmath.h b/lib/libcxx/include/tgmath.h index fbe1e8248d7..aba87499c29 100644 --- a/lib/libcxx/include/tgmath.h +++ b/lib/libcxx/include/tgmath.h @@ -14,16 +14,24 @@ /* tgmath.h synopsis -#include <complex.h> -#include <math.h> +#include <ctgmath> */ -#include <complex.h> -#include <math.h> +#include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif +#ifdef __cplusplus + +#include <ctgmath> + +#else // __cplusplus + +#include_next <tgmath.h> + +#endif // __cplusplus + #endif // _LIBCPP_TGMATH_H diff --git a/lib/libcxx/include/thread b/lib/libcxx/include/thread index 1b8dca394aa..0629d70efda 100644 --- a/lib/libcxx/include/thread +++ b/lib/libcxx/include/thread @@ -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 diff --git a/lib/libcxx/include/tuple b/lib/libcxx/include/tuple index 31578d1557a..b3a17e7b735 100644 --- a/lib/libcxx/include/tuple +++ b/lib/libcxx/include/tuple @@ -173,16 +173,11 @@ class __tuple_leaf template <class _Tp> static constexpr bool __can_bind_reference() { - using _RawTp = typename remove_reference<_Tp>::type; - using _RawHp = typename remove_reference<_Hp>::type; - using _CheckLValueArg = integral_constant<bool, - is_lvalue_reference<_Tp>::value - || is_same<_RawTp, reference_wrapper<_RawHp>>::value - || is_same<_RawTp, reference_wrapper<typename remove_const<_RawHp>::type>>::value - >; - return !is_reference<_Hp>::value - || (is_lvalue_reference<_Hp>::value && _CheckLValueArg::value) - || (is_rvalue_reference<_Hp>::value && !is_lvalue_reference<_Tp>::value); +#if __has_keyword(__reference_binds_to_temporary) + return !__reference_binds_to_temporary(_Hp, _Tp); +#else + return true; +#endif } __tuple_leaf& operator=(const __tuple_leaf&); @@ -216,7 +211,7 @@ public: template <class _Tp, class = typename enable_if< __lazy_and< - __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>> + __lazy_not<is_same<typename __uncvref<_Tp>::type, __tuple_leaf>> , is_constructible<_Hp, _Tp> >::value >::type @@ -224,15 +219,15 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) : __value_(_VSTD::forward<_Tp>(__t)) - {static_assert(__can_bind_reference<_Tp>(), - "Attempted to construct a reference element in a tuple with an rvalue");} + {static_assert(__can_bind_reference<_Tp&&>(), + "Attempted construction of reference element binds to a temporary whose lifetime has ended");} template <class _Tp, class _Alloc> _LIBCPP_INLINE_VISIBILITY explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) : __value_(_VSTD::forward<_Tp>(__t)) - {static_assert(__can_bind_reference<_Tp>(), - "Attempted to construct a reference element in a tuple with an rvalue");} + {static_assert(__can_bind_reference<_Tp&&>(), + "Attempted construction of reference element binds to a temporary whose lifetime has ended");} template <class _Tp, class _Alloc> _LIBCPP_INLINE_VISIBILITY @@ -298,7 +293,7 @@ public: template <class _Tp, class = typename enable_if< __lazy_and< - __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>> + __lazy_not<is_same<typename __uncvref<_Tp>::type, __tuple_leaf>> , is_constructible<_Hp, _Tp> >::value >::type @@ -1388,7 +1383,7 @@ constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t) _LIBCPP_NOEXCEPT_RETURN( _VSTD::__apply_tuple_impl( _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t), - typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{}) + typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}) ) template <class _Tp, class _Tuple, size_t... _Idx> @@ -1403,7 +1398,7 @@ inline _LIBCPP_INLINE_VISIBILITY constexpr _Tp make_from_tuple(_Tuple&& __t) _LIBCPP_NOEXCEPT_RETURN( _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t), - typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{}) + typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}) ) #undef _LIBCPP_NOEXCEPT_RETURN diff --git a/lib/libcxx/include/type_traits b/lib/libcxx/include/type_traits index eb443ee0abd..30bfb161c0d 100644 --- a/lib/libcxx/include/type_traits +++ b/lib/libcxx/include/type_traits @@ -21,7 +21,7 @@ namespace std template <class T, T v> struct integral_constant; typedef integral_constant<bool, true> true_type; // C++11 typedef integral_constant<bool, false> false_type; // C++11 - + template <bool B> // C++14 using bool_constant = integral_constant<bool, B>; // C++14 typedef bool_constant<true> true_type; // C++14 @@ -172,7 +172,7 @@ namespace std using add_volatile_t = typename add_volatile<T>::type; // C++14 template <class T> using add_cv_t = typename add_cv<T>::type; // C++14 - + // reference modifications: template <class T> using remove_reference_t = typename remove_reference<T>::type; // C++14 @@ -180,13 +180,13 @@ namespace std using add_lvalue_reference_t = typename add_lvalue_reference<T>::type; // C++14 template <class T> using add_rvalue_reference_t = typename add_rvalue_reference<T>::type; // C++14 - + // sign modifications: template <class T> using make_signed_t = typename make_signed<T>::type; // C++14 template <class T> using make_unsigned_t = typename make_unsigned<T>::type; // C++14 - + // array modifications: template <class T> using remove_extent_t = typename remove_extent<T>::type; // C++14 @@ -223,7 +223,7 @@ namespace std template <class...> using void_t = void; // C++17 - + // See C++14 20.10.4.1, primary type categories template <class T> inline constexpr bool is_void_v = is_void<T>::value; // C++17 @@ -386,13 +386,13 @@ namespace std // [meta.logical], logical operator traits: template<class... B> struct conjunction; // C++17 - template<class... B> + template<class... B> inline constexpr bool conjunction_v = conjunction<B...>::value; // C++17 template<class... B> struct disjunction; // C++17 template<class... B> inline constexpr bool disjunction_v = disjunction<B...>::value; // C++17 template<class B> struct negation; // C++17 - template<class B> + template<class B> inline constexpr bool negation_v = negation<B>::value; // C++17 } @@ -595,7 +595,7 @@ template<class _B0, class _B1> struct __and_<_B0, _B1> : conditional<_B0::value, _B1, _B0>::type {}; template<class _B0, class _B1, class _B2, class... _Bn> -struct __and_<_B0, _B1, _B2, _Bn...> +struct __and_<_B0, _B1, _B2, _Bn...> : conditional<_B0::value, __and_<_B1, _B2, _Bn...>, _B0>::type {}; // __or_ @@ -608,11 +608,11 @@ template<class _B0, class _B1> struct __or_<_B0, _B1> : conditional<_B0::value, _B0, _B1>::type {}; template<class _B0, class _B1, class _B2, class... _Bn> -struct __or_<_B0, _B1, _B2, _Bn...> +struct __or_<_B0, _B1, _B2, _Bn...> : conditional<_B0::value, _B0, __or_<_B1, _B2, _Bn...> >::type {}; // __not_ -template<class _Tp> +template<class _Tp> struct __not_ : conditional<_Tp::value, false_type, true_type>::type {}; #endif // !defined(_LIBCPP_CXX03_LANG) @@ -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 {}; @@ -897,7 +903,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_function_v // template <class _Tp> struct __libcpp_is_member_function_pointer : public false_type {}; // template <class _Tp, class _Up> struct __libcpp_is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {}; -// +// template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr> struct __member_pointer_traits_imp @@ -1178,11 +1184,9 @@ struct __is_same_uncvref : is_same<typename __uncvref<_Tp>::type, typename __uncvref<_Up>::type> {}; #if _LIBCPP_STD_VER > 17 -// aligned_union - same as __uncvref +// remove_cvref - same as __uncvref template <class _Tp> -struct remove_cvref { - using type = remove_cv_t<remove_reference_t<_Tp>>; -}; +struct remove_cvref : public __uncvref<_Tp> {}; template <class _Tp> using remove_cvref_t = typename remove_cvref<_Tp>::type; #endif @@ -1207,12 +1211,12 @@ template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type // add_pointer -template <class _Tp, - bool = __is_referenceable<_Tp>::value || +template <class _Tp, + bool = __is_referenceable<_Tp>::value || is_same<typename remove_cv<_Tp>::type, void>::value> struct __add_pointer_impl {typedef typename remove_reference<_Tp>::type* type;}; -template <class _Tp> struct __add_pointer_impl<_Tp, false> +template <class _Tp> struct __add_pointer_impl<_Tp, false> {typedef _Tp type;}; template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_pointer @@ -1626,7 +1630,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool has_virtual_destructor_v #if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS) template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations - : public integral_constant<bool, + : public integral_constant<bool, __has_unique_object_representations(remove_cv_t<remove_all_extents_t<_Tp>>)> {}; #if !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) @@ -2237,7 +2241,7 @@ struct __is_destructor_wellformed { template <typename _Tp1> static __two __test (...); - + static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char); }; @@ -2245,8 +2249,8 @@ template <class _Tp, bool> struct __destructible_imp; template <class _Tp> -struct __destructible_imp<_Tp, false> - : public _VSTD::integral_constant<bool, +struct __destructible_imp<_Tp, false> + : public _VSTD::integral_constant<bool, __is_destructor_wellformed<typename _VSTD::remove_all_extents<_Tp>::type>::value> {}; template <class _Tp> @@ -3397,7 +3401,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_default_constructible_v template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_copy_constructible - : public is_constructible<_Tp, + : public is_constructible<_Tp, typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {}; #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) @@ -4105,7 +4109,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_literal_type is_reference<typename remove_all_extents<_Tp>::type>::value> #endif {}; - + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_literal_type_v @@ -4121,7 +4125,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_standard_layout : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value> #endif {}; - + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_standard_layout_v @@ -4139,7 +4143,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value> #endif {}; - + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_copyable_v @@ -4170,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, @@ -4493,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>()...)); @@ -4812,39 +4676,39 @@ struct __sfinae_underlying_type template <class _Tp> struct __sfinae_underlying_type<_Tp, false> {}; -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR int __convert_to_integral(int __val) { return __val; } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned __convert_to_integral(unsigned __val) { return __val; } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long __convert_to_integral(long __val) { return __val; } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long __convert_to_integral(unsigned long __val) { return __val; } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long long __convert_to_integral(long long __val) { return __val; } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long long __convert_to_integral(unsigned long long __val) {return __val; } template<typename _Fp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_Fp>::value, long long>::type __convert_to_integral(_Fp __val) { return __val; } #ifndef _LIBCPP_HAS_NO_INT128 -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __int128_t __convert_to_integral(__int128_t __val) { return __val; } -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __uint128_t __convert_to_integral(__uint128_t __val) { return __val; } #endif template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename __sfinae_underlying_type<_Tp>::__promoted_type __convert_to_integral(_Tp __val) { return __val; } @@ -4941,6 +4805,21 @@ struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> #endif +#if _LIBCPP_STD_VER > 17 +enum class endian +{ + little = 0xDEAD, + big = 0xFACE, +#if defined(_LIBCPP_LITTLE_ENDIAN) + native = little +#elif defined(_LIBCPP_BIG_ENDIAN) + native = big +#else + native = 0xCAFE +#endif +}; +#endif + _LIBCPP_END_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 @@ -4951,7 +4830,7 @@ template <class _Integer> constexpr typename enable_if<is_integral_v<_Integer>, byte>::type & operator<<=(byte& __lhs, _Integer __shift) noexcept { return __lhs = __lhs << __shift; } - + template <class _Integer> constexpr typename enable_if<is_integral_v<_Integer>, byte>::type operator<< (byte __lhs, _Integer __shift) noexcept @@ -4966,7 +4845,7 @@ template <class _Integer> constexpr typename enable_if<is_integral_v<_Integer>, byte>::type operator>> (byte __lhs, _Integer __shift) noexcept { return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) >> __shift)); } - + template <class _Integer> constexpr typename enable_if<is_integral_v<_Integer>, _Integer>::type to_integer(byte __b) noexcept { return static_cast<_Integer>(__b); } diff --git a/lib/libcxx/include/typeinfo b/lib/libcxx/include/typeinfo index 7e8d3990ed9..f32ea6e76f1 100644 --- a/lib/libcxx/include/typeinfo +++ b/lib/libcxx/include/typeinfo @@ -69,6 +69,10 @@ public: #pragma GCC system_header #endif +#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) +#include <vcruntime_typeinfo.h> +#else + #if !defined(_LIBCPP_ABI_MICROSOFT) #if defined(_LIBCPP_NONUNIQUE_RTTI_BIT) #define _LIBCPP_HAS_NONUNIQUE_TYPEINFO @@ -219,8 +223,10 @@ public: } // std +#endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) + _LIBCPP_BEGIN_NAMESPACE_STD -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_bad_cast() { #ifndef _LIBCPP_NO_EXCEPTIONS diff --git a/lib/libcxx/include/unordered_map b/lib/libcxx/include/unordered_map index 725cb6af275..348f57923b5 100644 --- a/lib/libcxx/include/unordered_map +++ b/lib/libcxx/include/unordered_map @@ -44,6 +44,9 @@ public: typedef /unspecified/ local_iterator; typedef /unspecified/ const_local_iterator; + typedef unspecified node_type; // C++17 + typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17 + unordered_map() noexcept( is_nothrow_default_constructible<hasher>::value && @@ -122,6 +125,11 @@ public: void insert(InputIterator first, InputIterator last); void insert(initializer_list<value_type>); + node_type extract(const_iterator position); // C++17 + node_type extract(const key_type& x); // C++17 + insert_return_type insert(node_type&& nh); // C++17 + iterator insert(const_iterator hint, node_type&& nh); // C++17 + template <class... Args> pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17 template <class... Args> @@ -226,6 +234,8 @@ public: typedef /unspecified/ local_iterator; typedef /unspecified/ const_local_iterator; + typedef unspecified node_type; // C++17 + unordered_multimap() noexcept( is_nothrow_default_constructible<hasher>::value && @@ -304,6 +314,11 @@ public: void insert(InputIterator first, InputIterator last); void insert(initializer_list<value_type>); + node_type extract(const_iterator position); // C++17 + node_type extract(const key_type& x); // C++17 + iterator insert(node_type&& nh); // C++17 + iterator insert(const_iterator hint, node_type&& nh); // C++17 + iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); @@ -367,6 +382,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc> #include <__config> #include <__hash_table> +#include <__node_handle> #include <functional> #include <stdexcept> #include <tuple> @@ -396,7 +412,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 +441,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 +480,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 +512,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 +588,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 +598,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 +666,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 +690,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 +726,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 +780,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 +819,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), @@ -791,6 +859,11 @@ public: typedef __hash_map_iterator<typename __table::local_iterator> local_iterator; typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator; +#if _LIBCPP_STD_VER > 14 + typedef __map_node_handle<__node, allocator_type> node_type; + typedef __insert_return_type<iterator, node_type> insert_return_type; +#endif + _LIBCPP_INLINE_VISIBILITY unordered_map() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) @@ -1084,7 +1157,37 @@ public: iterator erase(const_iterator __first, const_iterator __last) {return __table_.erase(__first.__i_, __last.__i_);} _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {__table_.clear();} + void clear() _NOEXCEPT {__table_.clear();} + +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + insert_return_type insert(node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to unordered_map::insert()"); + return __table_.template __node_handle_insert_unique< + node_type, insert_return_type>(_VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __hint, node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to unordered_map::insert()"); + return __table_.template __node_handle_insert_unique<node_type>( + __hint.__i_, _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(key_type const& __key) + { + return __table_.template __node_handle_extract<node_type>(__key); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(const_iterator __it) + { + return __table_.template __node_handle_extract<node_type>( + __it.__i_); + } +#endif _LIBCPP_INLINE_VISIBILITY void swap(unordered_map& __u) @@ -1298,8 +1401,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 +1488,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 +1497,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 +1507,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 +1603,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), @@ -1539,6 +1641,10 @@ public: typedef __hash_map_iterator<typename __table::local_iterator> local_iterator; typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator; +#if _LIBCPP_STD_VER > 14 + typedef __map_node_handle<__node, allocator_type> node_type; +#endif + _LIBCPP_INLINE_VISIBILITY unordered_multimap() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) @@ -1712,6 +1818,36 @@ public: _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT {__table_.clear();} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + iterator insert(node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to unordered_multimap::insert()"); + return __table_.template __node_handle_insert_multi<node_type>( + _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __hint, node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to unordered_multimap::insert()"); + return __table_.template __node_handle_insert_multi<node_type>( + __hint.__i_, _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(key_type const& __key) + { + return __table_.template __node_handle_extract<node_type>(__key); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(const_iterator __it) + { + return __table_.template __node_handle_extract<node_type>( + __it.__i_); + } +#endif + _LIBCPP_INLINE_VISIBILITY void swap(unordered_multimap& __u) _NOEXCEPT_(__is_nothrow_swappable<__table>::value) @@ -1915,8 +2051,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 diff --git a/lib/libcxx/include/unordered_set b/lib/libcxx/include/unordered_set index 3ae024a45ee..9b8560da494 100644 --- a/lib/libcxx/include/unordered_set +++ b/lib/libcxx/include/unordered_set @@ -43,6 +43,9 @@ public: typedef /unspecified/ local_iterator; typedef /unspecified/ const_local_iterator; + typedef unspecified node_type unspecified; // C++17 + typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17 + unordered_set() noexcept( is_nothrow_default_constructible<hasher>::value && @@ -113,6 +116,11 @@ public: void insert(InputIterator first, InputIterator last); void insert(initializer_list<value_type>); + node_type extract(const_iterator position); // C++17 + node_type extract(const key_type& x); // C++17 + insert_return_type insert(node_type&& nh); // C++17 + iterator insert(const_iterator hint, node_type&& nh); // C++17 + iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); @@ -191,6 +199,8 @@ public: typedef /unspecified/ local_iterator; typedef /unspecified/ const_local_iterator; + typedef unspecified node_type unspecified; // C++17 + unordered_multiset() noexcept( is_nothrow_default_constructible<hasher>::value && @@ -261,6 +271,11 @@ public: void insert(InputIterator first, InputIterator last); void insert(initializer_list<value_type>); + node_type extract(const_iterator position); // C++17 + node_type extract(const key_type& x); // C++17 + iterator insert(node_type&& nh); // C++17 + iterator insert(const_iterator hint, node_type&& nh); // C++17 + iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); @@ -321,6 +336,7 @@ template <class Value, class Hash, class Pred, class Alloc> #include <__config> #include <__hash_table> +#include <__node_handle> #include <functional> #include <__debug> @@ -363,6 +379,11 @@ public: typedef typename __table::const_local_iterator local_iterator; typedef typename __table::const_local_iterator const_local_iterator; +#if _LIBCPP_STD_VER > 14 + typedef __set_node_handle<typename __table::__node, allocator_type> node_type; + typedef __insert_return_type<iterator, node_type> insert_return_type; +#endif + _LIBCPP_INLINE_VISIBILITY unordered_set() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) @@ -541,6 +562,35 @@ public: _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT {__table_.clear();} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + insert_return_type insert(node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to unordered_set::insert()"); + return __table_.template __node_handle_insert_unique< + node_type, insert_return_type>(_VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __h, node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to unordered_set::insert()"); + return __table_.template __node_handle_insert_unique<node_type>( + __h, _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(key_type const& __key) + { + return __table_.template __node_handle_extract<node_type>(__key); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(const_iterator __it) + { + return __table_.template __node_handle_extract<node_type>(__it); + } +#endif + _LIBCPP_INLINE_VISIBILITY void swap(unordered_set& __u) _NOEXCEPT_(__is_nothrow_swappable<__table>::value) @@ -883,6 +933,10 @@ public: typedef typename __table::const_local_iterator local_iterator; typedef typename __table::const_local_iterator const_local_iterator; +#if _LIBCPP_STD_VER > 14 + typedef __set_node_handle<typename __table::__node, allocator_type> node_type; +#endif + _LIBCPP_INLINE_VISIBILITY unordered_multiset() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) @@ -1019,6 +1073,36 @@ public: _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + iterator insert(node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to unordered_multiset::insert()"); + return __table_.template __node_handle_insert_multi<node_type>( + _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __hint, node_type&& __nh) + { + _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + "node_type with incompatible allocator passed to unordered_multiset::insert()"); + return __table_.template __node_handle_insert_multi<node_type>( + __hint, _VSTD::move(__nh)); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(const_iterator __position) + { + return __table_.template __node_handle_extract<node_type>( + __position); + } + _LIBCPP_INLINE_VISIBILITY + node_type extract(key_type const& __key) + { + return __table_.template __node_handle_extract<node_type>(__key); + } +#endif + _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __table_.erase(__p);} _LIBCPP_INLINE_VISIBILITY diff --git a/lib/libcxx/include/utility b/lib/libcxx/include/utility index 6fa2e15d144..ed9bf030d49 100644 --- a/lib/libcxx/include/utility +++ b/lib/libcxx/include/utility @@ -14,6 +14,8 @@ /* utility synopsis +#include <initializer_list> + namespace std { @@ -52,7 +54,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; @@ -293,7 +295,7 @@ template <class _Tp> void as_const(const _Tp&&) = delete; #endif struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { }; -#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_UTILITY) +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t(); #else /* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); @@ -890,7 +892,7 @@ template<class... _Tp> #if _LIBCPP_STD_VER > 11 template<class _T1, class _T2 = _T1> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _T1 exchange(_T1& __obj, _T2 && __new_value) { _T1 __old_value = _VSTD::move(__obj); diff --git a/lib/libcxx/include/valarray b/lib/libcxx/include/valarray index ee61238a932..8d3892ad35d 100644 --- a/lib/libcxx/include/valarray +++ b/lib/libcxx/include/valarray @@ -1053,6 +1053,9 @@ private: friend const _Up* end(const valarray<_Up>& __v); + + void __clear(); + valarray& __assign_range(const value_type* __f, const value_type* __l); }; _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t)) @@ -2735,7 +2738,8 @@ __val_expr<_ValExpr>::operator valarray<__val_expr::result_type>() const { __r.__begin_ = __r.__end_ = - static_cast<result_type*>(_VSTD::__allocate(__n * sizeof(result_type))); + static_cast<result_type*>( + _VSTD::__libcpp_allocate(__n * sizeof(result_type), __alignof(result_type))); for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i) ::new (__r.__end_) result_type(__expr_[__i]); } @@ -2750,7 +2754,25 @@ valarray<_Tp>::valarray(size_t __n) : __begin_(0), __end_(0) { - resize(__n); + if (__n) + { + __begin_ = __end_ = static_cast<value_type*>( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + for (; __n; --__n, ++__end_) + ::new (__end_) value_type(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __clear(); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } } template <class _Tp> @@ -2769,7 +2791,8 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n) { if (__n) { - __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type))); + __begin_ = __end_ = static_cast<value_type*>( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2780,7 +2803,7 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n) } catch (...) { - resize(0); + __clear(); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2794,7 +2817,8 @@ valarray<_Tp>::valarray(const valarray& __v) { if (__v.size()) { - __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__v.size() * sizeof(value_type))); + __begin_ = __end_ = static_cast<value_type*>( + _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), __alignof(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2805,7 +2829,7 @@ valarray<_Tp>::valarray(const valarray& __v) } catch (...) { - resize(0); + __clear(); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2831,7 +2855,8 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il) size_t __n = __il.size(); if (__n) { - __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type))); + __begin_ = __end_ = static_cast<value_type*>( +_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2842,7 +2867,7 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il) } catch (...) { - resize(0); + __clear(); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2859,7 +2884,8 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa) size_t __n = __sa.__size_; if (__n) { - __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type))); + __begin_ = __end_ = static_cast<value_type*>( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2870,7 +2896,7 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa) } catch (...) { - resize(0); + __clear(); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2885,7 +2911,8 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga) size_t __n = __ga.__1d_.size(); if (__n) { - __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type))); + __begin_ = __end_ = static_cast<value_type*>( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2899,7 +2926,7 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga) } catch (...) { - resize(0); + __clear(); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2914,7 +2941,8 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma) size_t __n = __ma.__1d_.size(); if (__n) { - __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type))); + __begin_ = __end_ = static_cast<value_type*>( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2928,7 +2956,7 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma) } catch (...) { - resize(0); + __clear(); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2943,7 +2971,8 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia) size_t __n = __ia.__1d_.size(); if (__n) { - __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type))); + __begin_ = __end_ = static_cast<value_type*>( + _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2957,7 +2986,7 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia) } catch (...) { - resize(0); + __clear(); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2968,22 +2997,36 @@ template <class _Tp> inline valarray<_Tp>::~valarray() { - resize(0); + __clear(); } template <class _Tp> valarray<_Tp>& -valarray<_Tp>::operator=(const valarray& __v) +valarray<_Tp>::__assign_range(const value_type* __f, const value_type* __l) { - if (this != &__v) + size_t __n = __l - __f; + if (size() != __n) { - if (size() != __v.size()) - resize(__v.size()); - _VSTD::copy(__v.__begin_, __v.__end_, __begin_); + __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> +valarray<_Tp>& +valarray<_Tp>::operator=(const valarray& __v) +{ + if (this != &__v) + return __assign_range(__v.__begin_, __v.__end_); + return *this; +} + #ifndef _LIBCPP_CXX03_LANG template <class _Tp> @@ -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 diff --git a/lib/libcxx/include/variant b/lib/libcxx/include/variant index 987b8a7982d..f9098f42249 100644 --- a/lib/libcxx/include/variant +++ b/lib/libcxx/include/variant @@ -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); @@ -1143,9 +1143,9 @@ public: template < class _Arg, - enable_if_t<!is_same_v<decay_t<_Arg>, variant>, int> = 0, - enable_if_t<!__is_inplace_type<decay_t<_Arg>>::value, int> = 0, - enable_if_t<!__is_inplace_index<decay_t<_Arg>>::value, int> = 0, + enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0, + enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0, + enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0, class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, @@ -1215,7 +1215,7 @@ public: template < class _Arg, - enable_if_t<!is_same_v<decay_t<_Arg>, variant>, int> = 0, + enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0, class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, @@ -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); diff --git a/lib/libcxx/include/vector b/lib/libcxx/include/vector index 54b1e8831d5..0f5006f3756 100644 --- a/lib/libcxx/include/vector +++ b/lib/libcxx/include/vector @@ -244,6 +244,10 @@ public: bool __invariants() const; }; +template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> + vector(InputIterator, InputIterator, Allocator = Allocator()) + -> vector<typename iterator_traits<InputIterator>::value_type, Allocator>; + template <class Allocator> struct hash<std::vector<bool, Allocator>>; template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y); @@ -291,7 +295,7 @@ template <bool> class __vector_base_common { protected: - _LIBCPP_ALWAYS_INLINE __vector_base_common() {} + _LIBCPP_INLINE_VISIBILITY __vector_base_common() {} _LIBCPP_NORETURN void __throw_length_error() const; _LIBCPP_NORETURN void __throw_out_of_range() const; }; @@ -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(); diff --git a/lib/libcxx/include/version b/lib/libcxx/include/version new file mode 100644 index 00000000000..23a872ea85a --- /dev/null +++ b/lib/libcxx/include/version @@ -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 |